1 /* 2 * PROJECT: ReactOS Services 3 * LICENSE: GPL - See COPYING in the top level directory 4 * FILE: base/applications/mscutils/servman/stop.c 5 * PURPOSE: Stops running a service 6 * COPYRIGHT: Copyright 2006-2015 Ged Murphy <gedmurphy@reactos.org> 7 * 8 */ 9 10 #include "precomp.h" 11 12 #define NDEBUG 13 #include <debug.h> 14 15 #define MAX_WAIT_TIME 30000 16 17 DWORD 18 DoStopService(_In_z_ LPWSTR ServiceName, 19 _In_opt_ HANDLE hProgress) 20 { 21 SC_HANDLE hSCManager; 22 SC_HANDLE hService; 23 SERVICE_STATUS_PROCESS ServiceStatus; 24 DWORD BytesNeeded; 25 DWORD StartTime; 26 DWORD WaitTime; 27 DWORD Timeout; 28 DWORD dwResult = ERROR_SUCCESS; 29 30 hSCManager = OpenSCManagerW(NULL, 31 NULL, 32 SC_MANAGER_CONNECT); 33 if (!hSCManager) return GetLastError(); 34 35 hService = OpenServiceW(hSCManager, 36 ServiceName, 37 SERVICE_STOP | SERVICE_QUERY_STATUS); 38 if (!hService) 39 { 40 dwResult = GetLastError(); 41 CloseServiceHandle(hSCManager); 42 return dwResult; 43 } 44 45 if (hProgress) 46 { 47 /* Increment the progress bar */ 48 IncrementProgressBar(hProgress, DEFAULT_STEP); 49 } 50 51 /* Set the start and max wait times */ 52 StartTime = GetTickCount(); 53 Timeout = MAX_WAIT_TIME; 54 55 /* Send the service the stop code */ 56 if (ControlService(hService, 57 SERVICE_CONTROL_STOP, 58 (LPSERVICE_STATUS)&ServiceStatus)) 59 { 60 if (hProgress) 61 { 62 /* Increment the progress bar */ 63 IncrementProgressBar(hProgress, DEFAULT_STEP); 64 } 65 66 while (ServiceStatus.dwCurrentState != SERVICE_STOPPED) 67 { 68 int i; 69 /* Fixup the wait time */ 70 WaitTime = ServiceStatus.dwWaitHint / 10; 71 72 if (WaitTime < 1000) WaitTime = 1000; 73 else if (WaitTime > 10000) WaitTime = 10000; 74 75 /* We don't wanna wait for up to 10 secs without incrementing */ 76 for (i = WaitTime / 1000; i > 0; i--) 77 { 78 Sleep(1000); 79 if (hProgress) 80 { 81 /* Increment the progress bar */ 82 IncrementProgressBar(hProgress, DEFAULT_STEP); 83 } 84 } 85 86 if (QueryServiceStatusEx(hService, 87 SC_STATUS_PROCESS_INFO, 88 (LPBYTE)&ServiceStatus, 89 sizeof(SERVICE_STATUS_PROCESS), 90 &BytesNeeded)) 91 { 92 /* Have we exceeded our wait time? */ 93 if (GetTickCount() - StartTime > Timeout) 94 { 95 /* Yep, give up */ 96 DPRINT1("Timeout\n"); 97 dwResult = ERROR_SERVICE_REQUEST_TIMEOUT; 98 break; 99 } 100 } 101 else 102 { 103 dwResult = GetLastError(); 104 DPRINT1("QueryServiceStatusEx failed: %d\n", dwResult); 105 } 106 } 107 108 /* If the service is stopped, return TRUE */ 109 if (ServiceStatus.dwCurrentState == SERVICE_STOPPED) 110 { 111 dwResult = ERROR_SUCCESS; 112 } 113 } 114 else 115 { 116 dwResult = GetLastError(); 117 } 118 119 CloseServiceHandle(hService); 120 CloseServiceHandle(hSCManager); 121 122 return dwResult; 123 } 124