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 MAX_WAIT_TIME   30000
13 
14 BOOL
15 DoStopService(_In_z_ LPWSTR ServiceName,
16               _In_opt_ HANDLE hProgress)
17 {
18     SC_HANDLE hSCManager;
19     SC_HANDLE hService;
20     SERVICE_STATUS_PROCESS ServiceStatus;
21     DWORD BytesNeeded;
22     DWORD StartTime;
23     DWORD WaitTime;
24     DWORD Timeout;
25     BOOL bRet = FALSE;
26 
27 
28     hSCManager = OpenSCManagerW(NULL,
29                                 NULL,
30                                 SC_MANAGER_CONNECT);
31     if (!hSCManager) return FALSE;
32 
33     hService = OpenServiceW(hSCManager,
34                             ServiceName,
35                             SERVICE_STOP | SERVICE_QUERY_STATUS);
36     if (!hService)
37     {
38         CloseServiceHandle(hSCManager);
39         return FALSE;
40     }
41 
42     if (hProgress)
43     {
44         /* Increment the progress bar */
45         IncrementProgressBar(hProgress, DEFAULT_STEP);
46     }
47 
48     /* Set the start and max wait times */
49     StartTime = GetTickCount();
50     Timeout = MAX_WAIT_TIME;
51 
52     /* Send the service the stop code */
53     if (ControlService(hService,
54                         SERVICE_CONTROL_STOP,
55                         (LPSERVICE_STATUS)&ServiceStatus))
56     {
57         if (hProgress)
58         {
59             /* Increment the progress bar */
60             IncrementProgressBar(hProgress, DEFAULT_STEP);
61         }
62 
63         while (ServiceStatus.dwCurrentState != SERVICE_STOPPED)
64         {
65             int i;
66             /* Fixup the wait time */
67             WaitTime = ServiceStatus.dwWaitHint / 10;
68 
69             if (WaitTime < 1000) WaitTime = 1000;
70             else if (WaitTime > 10000) WaitTime = 10000;
71 
72             /* We don't wanna wait for up to 10 secs without incrementing */
73             for (i = WaitTime / 1000; i > 0; i--)
74             {
75                 Sleep(1000);
76                 if (hProgress)
77                 {
78                     /* Increment the progress bar */
79                     IncrementProgressBar(hProgress, DEFAULT_STEP);
80                 }
81             }
82 
83             if (QueryServiceStatusEx(hService,
84                                         SC_STATUS_PROCESS_INFO,
85                                         (LPBYTE)&ServiceStatus,
86                                         sizeof(SERVICE_STATUS_PROCESS),
87                                         &BytesNeeded))
88             {
89                 /* Have we exceeded our wait time? */
90                 if (GetTickCount() - StartTime > Timeout)
91                 {
92                     /* Yep, give up */
93                     break;
94                 }
95             }
96         }
97 
98         /* If the service is stopped, return TRUE */
99         if (ServiceStatus.dwCurrentState == SERVICE_STOPPED)
100         {
101             bRet = TRUE;
102         }
103     }
104 
105     CloseServiceHandle(hService);
106 
107     CloseServiceHandle(hSCManager);
108 
109     return bRet;
110 }
111