[SERVMAN]
[reactos.git] / reactos / base / applications / mscutils / servman / query.c
1 /*
2 * PROJECT: ReactOS Services
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: base/applications/mscutils/servman/query.c
5 * PURPOSE: Query service information
6 * COPYRIGHT: Copyright 2006-2007 Ged Murphy <gedmurphy@reactos.org>
7 *
8 */
9
10 #include "precomp.h"
11
12 ENUM_SERVICE_STATUS_PROCESS*
13 GetSelectedService(PMAIN_WND_INFO Info)
14 {
15 LVITEM lvItem;
16
17 lvItem.mask = LVIF_PARAM;
18 lvItem.iItem = Info->SelectedItem;
19 SendMessage(Info->hListView,
20 LVM_GETITEM,
21 0,
22 (LPARAM)&lvItem);
23
24 /* return pointer to selected service */
25 return (ENUM_SERVICE_STATUS_PROCESS *)lvItem.lParam;
26 }
27
28 LPQUERY_SERVICE_CONFIG
29 GetServiceConfig(LPWSTR lpServiceName)
30 {
31 LPQUERY_SERVICE_CONFIGW lpServiceConfig = NULL;
32 SC_HANDLE hSCManager;
33 SC_HANDLE hService;
34 DWORD dwBytesNeeded;
35
36 hSCManager = OpenSCManagerW(NULL,
37 NULL,
38 SC_MANAGER_CONNECT);
39 if (hSCManager)
40 {
41 hService = OpenServiceW(hSCManager,
42 lpServiceName,
43 SERVICE_QUERY_CONFIG);
44 if (hService)
45 {
46 if (!QueryServiceConfigW(hService,
47 NULL,
48 0,
49 &dwBytesNeeded))
50 {
51 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
52 {
53 lpServiceConfig = (LPQUERY_SERVICE_CONFIG)HeapAlloc(GetProcessHeap(),
54 0,
55 dwBytesNeeded);
56 if (lpServiceConfig)
57 {
58 if (!QueryServiceConfigW(hService,
59 lpServiceConfig,
60 dwBytesNeeded,
61 &dwBytesNeeded))
62 {
63 HeapFree(GetProcessHeap(),
64 0,
65 lpServiceConfig);
66 lpServiceConfig = NULL;
67 }
68 }
69 }
70 }
71
72 CloseServiceHandle(hService);
73 }
74
75 CloseServiceHandle(hSCManager);
76 }
77
78 return lpServiceConfig;
79 }
80
81 BOOL
82 SetServiceConfig(LPQUERY_SERVICE_CONFIG pServiceConfig,
83 LPWSTR lpServiceName,
84 LPWSTR lpPassword)
85 {
86 SC_HANDLE hSCManager;
87 SC_HANDLE hSc;
88 SC_LOCK scLock;
89 BOOL bRet = FALSE;
90
91 hSCManager = OpenSCManagerW(NULL,
92 NULL,
93 SC_MANAGER_LOCK);
94 if (hSCManager)
95 {
96 scLock = LockServiceDatabase(hSCManager);
97 if (scLock)
98 {
99 hSc = OpenServiceW(hSCManager,
100 lpServiceName,
101 SERVICE_CHANGE_CONFIG);
102 if (hSc)
103 {
104 if (ChangeServiceConfigW(hSc,
105 pServiceConfig->dwServiceType,
106 pServiceConfig->dwStartType,
107 pServiceConfig->dwErrorControl,
108 pServiceConfig->lpBinaryPathName,
109 pServiceConfig->lpLoadOrderGroup,
110 pServiceConfig->dwTagId ? &pServiceConfig->dwTagId : NULL,
111 pServiceConfig->lpDependencies,
112 pServiceConfig->lpServiceStartName,
113 lpPassword,
114 pServiceConfig->lpDisplayName))
115 {
116 bRet = TRUE;
117 }
118
119 CloseServiceHandle(hSc);
120 }
121
122 UnlockServiceDatabase(scLock);
123 }
124
125 CloseServiceHandle(hSCManager);
126 }
127
128 if (!bRet)
129 GetError();
130
131 return bRet;
132 }
133
134 LPWSTR
135 GetServiceDescription(LPWSTR lpServiceName)
136 {
137 SC_HANDLE hSCManager = NULL;
138 SC_HANDLE hSc = NULL;
139 SERVICE_DESCRIPTIONW *pServiceDescription = NULL;
140 LPWSTR lpDescription = NULL;
141 DWORD BytesNeeded = 0;
142 DWORD dwSize;
143
144 hSCManager = OpenSCManagerW(NULL,
145 NULL,
146 SC_MANAGER_ENUMERATE_SERVICE);
147 if (hSCManager == NULL)
148 {
149 GetError();
150 return NULL;
151 }
152
153 hSc = OpenServiceW(hSCManager,
154 lpServiceName,
155 SERVICE_QUERY_CONFIG);
156 if (hSc)
157 {
158 if (!QueryServiceConfig2W(hSc,
159 SERVICE_CONFIG_DESCRIPTION,
160 NULL,
161 0,
162 &BytesNeeded))
163 {
164 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
165 {
166 pServiceDescription = (SERVICE_DESCRIPTION *) HeapAlloc(ProcessHeap,
167 0,
168 BytesNeeded);
169 if (pServiceDescription == NULL)
170 goto cleanup;
171
172 if (QueryServiceConfig2W(hSc,
173 SERVICE_CONFIG_DESCRIPTION,
174 (LPBYTE)pServiceDescription,
175 BytesNeeded,
176 &BytesNeeded))
177 {
178 if (pServiceDescription->lpDescription)
179 {
180 dwSize = wcslen(pServiceDescription->lpDescription) + 1;
181 lpDescription = HeapAlloc(ProcessHeap,
182 0,
183 dwSize * sizeof(WCHAR));
184 if (lpDescription)
185 {
186 StringCchCopyW(lpDescription,
187 dwSize,
188 pServiceDescription->lpDescription);
189 }
190 }
191 }
192 }
193 }
194 }
195
196 cleanup:
197 if (pServiceDescription)
198 HeapFree(ProcessHeap,
199 0,
200 pServiceDescription);
201 if (hSCManager != NULL)
202 CloseServiceHandle(hSCManager);
203 if (hSc != NULL)
204 CloseServiceHandle(hSc);
205
206 return lpDescription;
207 }
208
209 BOOL
210 SetServiceDescription(LPWSTR lpServiceName,
211 LPWSTR lpDescription)
212 {
213 SC_HANDLE hSCManager;
214 SC_HANDLE hSc;
215 SC_LOCK scLock;
216 SERVICE_DESCRIPTION ServiceDescription;
217 BOOL bRet = FALSE;
218
219 hSCManager = OpenSCManagerW(NULL,
220 NULL,
221 SC_MANAGER_LOCK);
222 if (hSCManager)
223 {
224 scLock = LockServiceDatabase(hSCManager);
225 if (scLock)
226 {
227 hSc = OpenServiceW(hSCManager,
228 lpServiceName,
229 SERVICE_CHANGE_CONFIG);
230 if (hSc)
231 {
232 ServiceDescription.lpDescription = lpDescription;
233
234 if (ChangeServiceConfig2W(hSc,
235 SERVICE_CONFIG_DESCRIPTION,
236 &ServiceDescription))
237 {
238 bRet = TRUE;
239 }
240
241 CloseServiceHandle(hSc);
242 }
243
244 UnlockServiceDatabase(scLock);
245 }
246
247 CloseServiceHandle(hSCManager);
248 }
249
250 if (!bRet)
251 GetError();
252
253 return bRet;
254 }
255
256 VOID
257 FreeServiceList(PMAIN_WND_INFO Info)
258 {
259 DWORD i;
260
261 if (Info->pAllServices != NULL)
262 {
263 for (i = 0; i < Info->NumServices; i++)
264 {
265 if (Info->pAllServices[i].lpServiceName)
266 HeapFree(ProcessHeap, 0, Info->pAllServices[i].lpServiceName);
267
268 if (Info->pAllServices[i].lpDisplayName)
269 HeapFree(ProcessHeap, 0, Info->pAllServices[i].lpDisplayName);
270 }
271
272 HeapFree(ProcessHeap, 0, Info->pAllServices);
273 Info->pAllServices = NULL;
274 Info->NumServices = 0;
275 }
276 }
277
278 BOOL
279 GetServiceList(PMAIN_WND_INFO Info)
280 {
281 ENUM_SERVICE_STATUS_PROCESS *pServices = NULL;
282 SC_HANDLE ScHandle;
283 BOOL bRet = FALSE;
284
285 DWORD BytesNeeded = 0;
286 DWORD ResumeHandle = 0;
287 DWORD NumServices = 0;
288 DWORD i;
289
290 FreeServiceList(Info);
291
292 ScHandle = OpenSCManagerW(NULL,
293 NULL,
294 SC_MANAGER_ENUMERATE_SERVICE);
295 if (ScHandle != NULL)
296 {
297 if (!EnumServicesStatusEx(ScHandle,
298 SC_ENUM_PROCESS_INFO,
299 SERVICE_WIN32,
300 SERVICE_STATE_ALL,
301 NULL,
302 0,
303 &BytesNeeded,
304 &NumServices,
305 &ResumeHandle,
306 0))
307 {
308 /* Call function again if required size was returned */
309 if (GetLastError() == ERROR_MORE_DATA)
310 {
311 /* reserve memory for service info array */
312 pServices = (ENUM_SERVICE_STATUS_PROCESS *)HeapAlloc(ProcessHeap,
313 0,
314 BytesNeeded);
315 if (pServices)
316 {
317 /* fill array with service info */
318 if (EnumServicesStatusEx(ScHandle,
319 SC_ENUM_PROCESS_INFO,
320 SERVICE_WIN32,
321 SERVICE_STATE_ALL,
322 (LPBYTE)pServices,
323 BytesNeeded,
324 &BytesNeeded,
325 &NumServices,
326 &ResumeHandle,
327 0))
328 {
329 bRet = TRUE;
330 }
331 }
332 }
333 }
334 }
335
336 if (ScHandle)
337 CloseServiceHandle(ScHandle);
338
339 Info->pAllServices = (ENUM_SERVICE_STATUS_PROCESS *)HeapAlloc(ProcessHeap,
340 HEAP_ZERO_MEMORY,
341 NumServices * sizeof(ENUM_SERVICE_STATUS_PROCESS));
342 if (Info->pAllServices != NULL)
343 {
344 Info->NumServices = NumServices;
345
346 for (i = 0; i < NumServices; i++)
347 {
348 Info->pAllServices[i].lpServiceName = HeapAlloc(ProcessHeap,
349 HEAP_ZERO_MEMORY,
350 (wcslen(pServices[i].lpServiceName) + 1) * sizeof(WCHAR));
351 if (Info->pAllServices[i].lpServiceName)
352 wcscpy(Info->pAllServices[i].lpServiceName, pServices[i].lpServiceName);
353
354 Info->pAllServices[i].lpDisplayName = HeapAlloc(ProcessHeap,
355 HEAP_ZERO_MEMORY,
356 (wcslen(pServices[i].lpDisplayName) + 1) * sizeof(WCHAR));
357 if (Info->pAllServices[i].lpDisplayName)
358 wcscpy(Info->pAllServices[i].lpDisplayName, pServices[i].lpDisplayName);
359
360 CopyMemory(&Info->pAllServices[i].ServiceStatusProcess,
361 &pServices[i].ServiceStatusProcess,
362 sizeof(SERVICE_STATUS_PROCESS));
363 }
364 }
365
366 if (pServices)
367 HeapFree(ProcessHeap, 0, pServices);
368
369 return bRet;
370 }
371
372 BOOL
373 UpdateServiceStatus(ENUM_SERVICE_STATUS_PROCESS* pService)
374 {
375 SC_HANDLE hScm;
376 BOOL bRet = FALSE;
377
378 hScm = OpenSCManagerW(NULL,
379 NULL,
380 SC_MANAGER_ENUMERATE_SERVICE);
381 if (hScm != NULL)
382 {
383 SC_HANDLE hService;
384
385 hService = OpenServiceW(hScm,
386 pService->lpServiceName,
387 SERVICE_QUERY_STATUS);
388 if (hService)
389 {
390 DWORD size;
391
392 QueryServiceStatusEx(hService,
393 SC_STATUS_PROCESS_INFO,
394 (LPBYTE)&pService->ServiceStatusProcess,
395 sizeof(SERVICE_STATUS_PROCESS),
396 &size);
397
398 CloseServiceHandle(hService);
399 bRet = TRUE;
400 }
401
402 CloseServiceHandle(hScm);
403 }
404
405 return bRet;
406 }