- Create another branch for networking fixes
[reactos.git] / base / applications / mscutils / servman / dependencies.c
1 /*
2 * PROJECT: ReactOS Services
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: base/applications/mscutils/servman/dependencies.c
5 * PURPOSE: Helper functions for service dependents
6 * COPYRIGHT: Copyright 2006-2009 Ged Murphy <gedmurphy@reactos.org>
7 *
8 */
9
10 #include "precomp.h"
11
12
13 /*
14 * Services which depend on the given service.
15 * The return components depend on this service
16 */
17 LPTSTR
18 GetDependentServices(SC_HANDLE hService)
19 {
20 LPQUERY_SERVICE_CONFIG lpServiceConfig;
21 LPTSTR lpStr = NULL;
22 DWORD bytesNeeded;
23 DWORD bytes;
24
25 if (!QueryServiceConfig(hService,
26 NULL,
27 0,
28 &bytesNeeded) &&
29 GetLastError() == ERROR_INSUFFICIENT_BUFFER)
30 {
31 lpServiceConfig = HeapAlloc(ProcessHeap,
32 0,
33 bytesNeeded);
34 if (lpServiceConfig)
35 {
36 if (QueryServiceConfig(hService,
37 lpServiceConfig,
38 bytesNeeded,
39 &bytesNeeded))
40 {
41 if (lpServiceConfig)
42 {
43 lpStr = lpServiceConfig->lpDependencies;
44 bytes = 0;
45
46 while (TRUE)
47 {
48 bytes++;
49
50 if (!*lpStr && !*(lpStr + 1))
51 {
52 bytes++;
53 break;
54 }
55
56 lpStr++;
57 }
58
59 bytes *= sizeof(TCHAR);
60 lpStr = HeapAlloc(ProcessHeap,
61 0,
62 bytes);
63 if (lpStr)
64 {
65 CopyMemory(lpStr,
66 lpServiceConfig->lpDependencies,
67 bytes);
68 }
69 }
70 }
71 }
72 }
73
74 return lpStr;
75 }
76
77
78 /*
79 * Services which the given service depends on (1st treeview)
80 * The service depends on the return components
81 */
82 LPENUM_SERVICE_STATUS
83 GetServiceDependents(SC_HANDLE hService,
84 LPDWORD lpdwCount)
85 {
86 LPENUM_SERVICE_STATUS lpDependencies;
87 DWORD dwBytesNeeded;
88 DWORD dwCount;
89
90 if (EnumDependentServices(hService,
91 SERVICE_STATE_ALL,
92 NULL,
93 0,
94 &dwBytesNeeded,
95 &dwCount))
96 {
97 /* There are no dependent services */
98 return NULL;
99 }
100 else
101 {
102 if (GetLastError() != ERROR_MORE_DATA)
103 return NULL; /* Unexpected error */
104
105 lpDependencies = (LPENUM_SERVICE_STATUS)HeapAlloc(GetProcessHeap(),
106 0,
107 dwBytesNeeded);
108 if (lpDependencies)
109 {
110 if (EnumDependentServices(hService,
111 SERVICE_STATE_ALL,
112 lpDependencies,
113 dwBytesNeeded,
114 &dwBytesNeeded,
115 &dwCount))
116 {
117 *lpdwCount = dwCount;
118 }
119 else
120 {
121 HeapFree(ProcessHeap,
122 0,
123 lpDependencies);
124
125 lpDependencies = NULL;
126 }
127 }
128 }
129
130 return lpDependencies;
131
132 }
133
134
135 BOOL
136 HasDependentServices(SC_HANDLE hService)
137 {
138 DWORD dwBytesNeeded, dwCount;
139 BOOL bRet = FALSE;
140
141 if (hService)
142 {
143 if (!EnumDependentServices(hService,
144 SERVICE_STATE_ALL,
145 NULL,
146 0,
147 &dwBytesNeeded,
148 &dwCount))
149 {
150 if (GetLastError() == ERROR_MORE_DATA)
151 bRet = TRUE;
152 }
153 }
154
155 return bRet;
156 }
157
158 static BOOL
159 DoInitDependsDialog(PSTOP_INFO pStopInfo,
160 HWND hDlg)
161 {
162 LPENUM_SERVICE_STATUS lpDependencies;
163 DWORD dwCount;
164 LPTSTR lpPartialStr, lpStr;
165 DWORD fullLen;
166 HICON hIcon = NULL;
167 BOOL bRet = FALSE;
168
169 if (pStopInfo)
170 {
171 SetWindowLongPtr(hDlg,
172 GWLP_USERDATA,
173 (LONG_PTR)pStopInfo);
174
175 hIcon = (HICON)LoadImage(hInstance,
176 MAKEINTRESOURCE(IDI_SM_ICON),
177 IMAGE_ICON,
178 16,
179 16,
180 0);
181 if (hIcon)
182 {
183 SendMessage(hDlg,
184 WM_SETICON,
185 ICON_SMALL,
186 (LPARAM)hIcon);
187 DestroyIcon(hIcon);
188 }
189
190 /* Add the label */
191 if (AllocAndLoadString(&lpPartialStr,
192 hInstance,
193 IDS_STOP_DEPENDS))
194 {
195 fullLen = _tcslen(lpPartialStr) + _tcslen(pStopInfo->pInfo->pCurrentService->lpDisplayName) + 1;
196
197 lpStr = HeapAlloc(ProcessHeap,
198 0,
199 fullLen * sizeof(TCHAR));
200 if (lpStr)
201 {
202 _sntprintf(lpStr, fullLen, lpPartialStr, pStopInfo->pInfo->pCurrentService->lpDisplayName);
203
204 SendDlgItemMessage(hDlg,
205 IDC_STOP_DEPENDS,
206 WM_SETTEXT,
207 0,
208 (LPARAM)lpStr);
209
210 bRet = TRUE;
211
212 HeapFree(ProcessHeap,
213 0,
214 lpStr);
215 }
216
217 HeapFree(ProcessHeap,
218 0,
219 lpPartialStr);
220 }
221
222 /* Get the list of dependencies */
223 lpDependencies = GetServiceDependents(pStopInfo->hMainService, &dwCount);
224 if (lpDependencies)
225 {
226 LPENUM_SERVICE_STATUS lpEnumServiceStatus;
227 DWORD i;
228
229 for (i = 0; i < dwCount; i++)
230 {
231 lpEnumServiceStatus = &lpDependencies[i];
232
233 /* Add the service to the listbox */
234 SendDlgItemMessage(hDlg,
235 IDC_STOP_DEPENDS_LB,
236 LB_ADDSTRING,
237 0,
238 (LPARAM)lpEnumServiceStatus->lpDisplayName);
239 }
240
241 HeapFree(ProcessHeap,
242 0,
243 lpDependencies);
244 }
245 }
246
247 return bRet;
248 }
249
250
251 INT_PTR CALLBACK
252 StopDependsDialogProc(HWND hDlg,
253 UINT message,
254 WPARAM wParam,
255 LPARAM lParam)
256 {
257 PSTOP_INFO pStopInfo = NULL;
258
259 /* Get the window context */
260 pStopInfo = (PSTOP_INFO)GetWindowLongPtr(hDlg,
261 GWLP_USERDATA);
262 if (pStopInfo == NULL && message != WM_INITDIALOG)
263 {
264 return FALSE;
265 }
266
267 switch (message)
268 {
269 case WM_INITDIALOG:
270 {
271 BOOL bRet = FALSE;
272
273 pStopInfo = (PSTOP_INFO)lParam;
274 if (pStopInfo != NULL)
275 {
276 bRet = DoInitDependsDialog(pStopInfo, hDlg);
277 }
278
279 return bRet;
280 }
281
282 case WM_COMMAND:
283 {
284 switch (LOWORD(wParam))
285 {
286 case IDOK:
287 case IDCANCEL:
288 {
289 EndDialog(hDlg,
290 LOWORD(wParam));
291 return TRUE;
292 }
293 }
294 }
295 }
296
297 return FALSE;
298 }