static BOOL StopService(PMAIN_WND_INFO pInfo, LPWSTR lpServiceName, HWND hProgress OPTIONAL) { SC_HANDLE hSCManager; SC_HANDLE hService; SERVICE_STATUS_PROCESS ServiceStatus; DWORD dwBytesNeeded; DWORD dwStartTime; DWORD dwTimeout; BOOL bRet = FALSE; if (hProgress) { /* Set the service name and reset the progress bag */ InitializeProgressDialog(hProgress, lpServiceName); } hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT); if (hSCManager) { hService = OpenService(hSCManager, lpServiceName, SERVICE_STOP | SERVICE_QUERY_STATUS); if (hService) { if (hProgress) { /* Increment the progress bar */ IncrementProgressBar(hProgress, DEFAULT_STEP); } /* Set the wait time to 30 secs */ dwStartTime = GetTickCount(); dwTimeout = 30000; /* Send the service the stop code */ if (ControlService(hService, SERVICE_CONTROL_STOP, (LPSERVICE_STATUS)&ServiceStatus)) { if (hProgress) { /* Increment the progress bar */ IncrementProgressBar(hProgress, DEFAULT_STEP); } while (ServiceStatus.dwCurrentState != SERVICE_STOPPED) { /* Don't sleep for more than 3 seconds */ if (ServiceStatus.dwWaitHint > 3000) ServiceStatus.dwWaitHint = 3000; Sleep(ServiceStatus.dwWaitHint); if (hProgress) { /* Increment the progress bar */ IncrementProgressBar(hProgress, DEFAULT_STEP); } if (QueryServiceStatusEx(hService, SC_STATUS_PROCESS_INFO, (LPBYTE)&ServiceStatus, sizeof(SERVICE_STATUS_PROCESS), &dwBytesNeeded)) { /* Have we exceeded our wait time? */ if (GetTickCount() - dwStartTime > dwTimeout) { /* Yep, give up */ break; } } } /* If the service is stopped, return TRUE */ if (ServiceStatus.dwCurrentState == SERVICE_STOPPED) { bRet = TRUE; } } CloseServiceHandle(hService); } CloseServiceHandle(hSCManager); } return bRet; }
static BOOL DoStartService(PMAIN_WND_INFO Info, HWND hProgress, LPWSTR lpStartParams) { SC_HANDLE hSCManager; SC_HANDLE hService; SERVICE_STATUS_PROCESS ServiceStatus; DWORD BytesNeeded = 0; DWORD dwStartTickCount; DWORD dwOldCheckPoint; DWORD dwWaitTime; DWORD dwMaxWait; BOOL bRet = FALSE; BOOL bWhiteSpace = TRUE; LPWSTR lpChar; DWORD dwArgsCount = 0; LPCWSTR *lpArgsVector = NULL; if (lpStartParams != NULL) { /* Count the number of arguments */ lpChar = lpStartParams; while (*lpChar != 0) { if (iswspace(*lpChar)) { bWhiteSpace = TRUE; } else { if (bWhiteSpace == TRUE) { dwArgsCount++; bWhiteSpace = FALSE; } } lpChar++; } /* Allocate the arguments vector and add one for the service name */ lpArgsVector = LocalAlloc(LMEM_FIXED, (dwArgsCount + 1) * sizeof(LPCWSTR)); if (!lpArgsVector) return FALSE; /* Make the service name the first argument */ lpArgsVector[0] = Info->pCurrentService->lpServiceName; /* Fill the arguments vector */ dwArgsCount = 1; bWhiteSpace = TRUE; lpChar = lpStartParams; while (*lpChar != 0) { if (iswspace(*lpChar)) { *lpChar = 0; bWhiteSpace = TRUE; } else { if (bWhiteSpace == TRUE) { lpArgsVector[dwArgsCount] = lpChar; dwArgsCount++; bWhiteSpace = FALSE; } } lpChar++; } } hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT); if (hSCManager) { hService = OpenService(hSCManager, Info->pCurrentService->lpServiceName, SERVICE_START | SERVICE_QUERY_STATUS); if (hService) { if (hProgress) { /* Increment the progress bar */ IncrementProgressBar(hProgress, DEFAULT_STEP); } /* Start the service */ bRet = StartService(hService, dwArgsCount, lpArgsVector); if (!bRet && GetLastError() == ERROR_SERVICE_ALREADY_RUNNING) { /* If it's already running, just return TRUE */ bRet = TRUE; } else if (bRet) { bRet = FALSE; /* Get the service status to check if it's running */ if (QueryServiceStatusEx(hService, SC_STATUS_PROCESS_INFO, (LPBYTE)&ServiceStatus, sizeof(SERVICE_STATUS_PROCESS), &BytesNeeded)) { /* We don't want to wait for more than 30 seconds */ dwMaxWait = 30000; dwStartTickCount = GetTickCount(); /* Loop until it's running */ while (ServiceStatus.dwCurrentState != SERVICE_RUNNING) { dwOldCheckPoint = ServiceStatus.dwCheckPoint; dwWaitTime = ServiceStatus.dwWaitHint / 10; /* Get the latest status info */ if (!QueryServiceStatusEx(hService, SC_STATUS_PROCESS_INFO, (LPBYTE)&ServiceStatus, sizeof(SERVICE_STATUS_PROCESS), &BytesNeeded)) { /* Something went wrong... */ break; } /* Is the service making progress? */ if (ServiceStatus.dwCheckPoint > dwOldCheckPoint) { /* It is, get the latest tickcount to reset the max wait time */ dwStartTickCount = GetTickCount(); dwOldCheckPoint = ServiceStatus.dwCheckPoint; IncrementProgressBar(hProgress, DEFAULT_STEP); } else { /* It's not, make sure we haven't exceeded our wait time */ if (GetTickCount() >= dwStartTickCount + dwMaxWait) { /* We have, give up */ break; } } /* Adjust the wait hint times */ if (dwWaitTime < 200) dwWaitTime = 200; else if (dwWaitTime > 10000) dwWaitTime = 10000; /* Wait before trying again */ Sleep(dwWaitTime); } } if (ServiceStatus.dwCurrentState == SERVICE_RUNNING) { bRet = TRUE; } } CloseServiceHandle(hService); } CloseServiceHandle(hSCManager); } if (lpArgsVector) LocalFree((LPVOID)lpArgsVector); return bRet; }
static BOOL DoControl(PMAIN_WND_INFO Info, HWND hProgress, DWORD Control) { SC_HANDLE hSCManager; SC_HANDLE hService; SERVICE_STATUS_PROCESS ServiceStatus = {0}; SERVICE_STATUS Status; DWORD BytesNeeded = 0; DWORD dwStartTickCount; DWORD dwOldCheckPoint; DWORD dwWaitTime; DWORD dwMaxWait; DWORD dwReqState; BOOL bRet = FALSE; /* Set the state we're interested in */ switch (Control) { case SERVICE_CONTROL_PAUSE: dwReqState = SERVICE_PAUSED; break; case SERVICE_CONTROL_CONTINUE: dwReqState = SERVICE_RUNNING; break; default: /* Unhandled control code */ return FALSE; } hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT); if (hSCManager) { hService = OpenService(hSCManager, Info->pCurrentService->lpServiceName, SERVICE_PAUSE_CONTINUE | SERVICE_INTERROGATE | SERVICE_QUERY_STATUS); if (hService) { if (hProgress) { /* Increment the progress bar */ IncrementProgressBar(hProgress, DEFAULT_STEP); } /* Send the control message to the service */ if (ControlService(hService, Control, &Status)) { /* Get the service status */ if (QueryServiceStatusEx(hService, SC_STATUS_PROCESS_INFO, (LPBYTE)&ServiceStatus, sizeof(SERVICE_STATUS_PROCESS), &BytesNeeded)) { /* We don't want to wait for more than 30 seconds */ dwMaxWait = 30000; dwStartTickCount = GetTickCount(); /* Loop until it's at the correct state */ while (ServiceStatus.dwCurrentState != dwReqState) { dwOldCheckPoint = ServiceStatus.dwCheckPoint; dwWaitTime = ServiceStatus.dwWaitHint / 10; /* Get the latest status info */ if (!QueryServiceStatusEx(hService, SC_STATUS_PROCESS_INFO, (LPBYTE)&ServiceStatus, sizeof(SERVICE_STATUS_PROCESS), &BytesNeeded)) { /* Something went wrong... */ break; } /* Is the service making progress? */ if (ServiceStatus.dwCheckPoint > dwOldCheckPoint) { /* It is, get the latest tickcount to reset the max wait time */ dwStartTickCount = GetTickCount(); dwOldCheckPoint = ServiceStatus.dwCheckPoint; IncrementProgressBar(hProgress, DEFAULT_STEP); } else { /* It's not, make sure we haven't exceeded our wait time */ if(GetTickCount() >= dwStartTickCount + dwMaxWait) { /* We have, give up */ break; } } /* Adjust the wait hint times */ if (dwWaitTime < 200) dwWaitTime = 200; else if (dwWaitTime > 10000) dwWaitTime = 10000; /* Wait before trying again */ Sleep(dwWaitTime); } } if (ServiceStatus.dwCurrentState == dwReqState) { bRet = TRUE; } } CloseServiceHandle(hService); } CloseServiceHandle(hSCManager); } return bRet; }