- Create another branch for networking fixes
[reactos.git] / base / applications / mscutils / servman / stop.c
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-2009 Ged Murphy <gedmurphy@reactos.org>
7 *
8 */
9
10 #include "precomp.h"
11
12
13 static BOOL
14 StopService(PSTOP_INFO pStopInfo,
15 SC_HANDLE hService)
16 {
17 SERVICE_STATUS_PROCESS ServiceStatus;
18 DWORD dwBytesNeeded;
19 DWORD dwStartTime;
20 DWORD dwTimeout;
21 HWND hProgDlg;
22 BOOL bRet = FALSE;
23
24 dwStartTime = GetTickCount();
25 dwTimeout = 30000; // 30 secs
26
27 hProgDlg = CreateProgressDialog(pStopInfo->pInfo->hMainWnd,
28 pStopInfo->pInfo->pCurrentService->lpServiceName,
29 IDS_PROGRESS_INFO_STOP);
30 if (hProgDlg)
31 {
32 IncrementProgressBar(hProgDlg);
33
34 if (ControlService(hService,
35 SERVICE_CONTROL_STOP,
36 (LPSERVICE_STATUS)&ServiceStatus))
37 {
38 while (ServiceStatus.dwCurrentState != SERVICE_STOPPED)
39 {
40 Sleep(ServiceStatus.dwWaitHint);
41
42 if (QueryServiceStatusEx(hService,
43 SC_STATUS_PROCESS_INFO,
44 (LPBYTE)&ServiceStatus,
45 sizeof(SERVICE_STATUS_PROCESS),
46 &dwBytesNeeded))
47 {
48 if (GetTickCount() - dwStartTime > dwTimeout)
49 {
50 /* We exceeded our max wait time, give up */
51 break;
52 }
53 }
54 }
55
56 if (ServiceStatus.dwCurrentState == SERVICE_STOPPED)
57 {
58 bRet = TRUE;
59 }
60 }
61
62 CompleteProgressBar(hProgDlg);
63 Sleep(500);
64 DestroyWindow(hProgDlg);
65 }
66
67 return bRet;
68 }
69
70 static BOOL
71 StopDependentServices(PSTOP_INFO pStopInfo,
72 SC_HANDLE hService)
73 {
74 LPENUM_SERVICE_STATUS lpDependencies;
75 SC_HANDLE hDepService;
76 DWORD dwCount;
77 BOOL bRet = FALSE;
78
79 lpDependencies = GetServiceDependents(hService, &dwCount);
80 if (lpDependencies)
81 {
82 LPENUM_SERVICE_STATUS lpEnumServiceStatus;
83 DWORD i;
84
85 for (i = 0; i < dwCount; i++)
86 {
87 lpEnumServiceStatus = &lpDependencies[i];
88
89 hDepService = OpenService(pStopInfo->hSCManager,
90 lpEnumServiceStatus->lpServiceName,
91 SERVICE_STOP | SERVICE_QUERY_STATUS);
92 if (hDepService)
93 {
94 bRet = StopService(pStopInfo, hDepService);
95
96 CloseServiceHandle(hDepService);
97
98 if (!bRet)
99 {
100 GetError();
101 break;
102 }
103 }
104 }
105
106 HeapFree(GetProcessHeap(),
107 0,
108 lpDependencies);
109 }
110
111 return bRet;
112 }
113
114
115 BOOL
116 DoStop(PMAIN_WND_INFO pInfo)
117 {
118 STOP_INFO stopInfo;
119 SC_HANDLE hSCManager;
120 SC_HANDLE hService;
121 BOOL bRet = FALSE;
122
123 if (pInfo)
124 {
125 stopInfo.pInfo = pInfo;
126
127 hSCManager = OpenSCManager(NULL,
128 NULL,
129 SC_MANAGER_ALL_ACCESS);
130 if (hSCManager)
131 {
132 hService = OpenService(hSCManager,
133 pInfo->pCurrentService->lpServiceName,
134 SERVICE_STOP | SERVICE_QUERY_STATUS | SERVICE_ENUMERATE_DEPENDENTS);
135 if (hService)
136 {
137 stopInfo.hSCManager = hSCManager;
138 stopInfo.hMainService = hService;
139
140 if (HasDependentServices(hService))
141 {
142 INT ret = DialogBoxParam(hInstance,
143 MAKEINTRESOURCE(IDD_DLG_DEPEND_STOP),
144 pInfo->hMainWnd,
145 StopDependsDialogProc,
146 (LPARAM)&stopInfo);
147 if (ret == IDOK)
148 {
149 if (StopDependentServices(&stopInfo, hService))
150 {
151 bRet = StopService(&stopInfo, hService);
152 }
153 }
154 }
155 else
156 {
157 bRet = StopService(&stopInfo, hService);
158 }
159
160 CloseServiceHandle(hService);
161 }
162
163 CloseServiceHandle(hSCManager);
164 }
165 }
166
167 return bRet;
168 }