[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 BOOL
257 GetServiceList(PMAIN_WND_INFO Info,
258 DWORD *NumServices)
259 {
260 SC_HANDLE ScHandle;
261 BOOL bRet = FALSE;
262
263 DWORD BytesNeeded = 0;
264 DWORD ResumeHandle = 0;
265
266 *NumServices = 0;
267
268 if (Info->pAllServices != NULL)
269 {
270 HeapFree(ProcessHeap,
271 0,
272 Info->pAllServices);
273 Info->pAllServices = NULL;
274 }
275
276 ScHandle = OpenSCManagerW(NULL,
277 NULL,
278 SC_MANAGER_ENUMERATE_SERVICE);
279 if (ScHandle != NULL)
280 {
281 if (!EnumServicesStatusEx(ScHandle,
282 SC_ENUM_PROCESS_INFO,
283 SERVICE_WIN32,
284 SERVICE_STATE_ALL,
285 NULL,
286 0,
287 &BytesNeeded,
288 NumServices,
289 &ResumeHandle,
290 0))
291 {
292 /* Call function again if required size was returned */
293 if (GetLastError() == ERROR_MORE_DATA)
294 {
295 /* reserve memory for service info array */
296 Info->pAllServices = (ENUM_SERVICE_STATUS_PROCESS *) HeapAlloc(ProcessHeap,
297 0,
298 BytesNeeded);
299 if (Info->pAllServices)
300 {
301 /* fill array with service info */
302 if (EnumServicesStatusEx(ScHandle,
303 SC_ENUM_PROCESS_INFO,
304 SERVICE_WIN32,
305 SERVICE_STATE_ALL,
306 (LPBYTE)Info->pAllServices,
307 BytesNeeded,
308 &BytesNeeded,
309 NumServices,
310 &ResumeHandle,
311 0))
312 {
313 bRet = TRUE;
314 }
315 }
316 }
317 }
318 }
319
320 if (ScHandle)
321 CloseServiceHandle(ScHandle);
322
323 if (!bRet && Info->pAllServices)
324 {
325 HeapFree(ProcessHeap,
326 0,
327 Info->pAllServices);
328 }
329
330 return bRet;
331 }
332
333 BOOL
334 UpdateServiceStatus(ENUM_SERVICE_STATUS_PROCESS* pService)
335 {
336 SC_HANDLE hScm;
337 BOOL bRet = FALSE;
338
339 hScm = OpenSCManagerW(NULL,
340 NULL,
341 SC_MANAGER_ENUMERATE_SERVICE);
342 if (hScm != NULL)
343 {
344 SC_HANDLE hService;
345
346 hService = OpenServiceW(hScm,
347 pService->lpServiceName,
348 SERVICE_QUERY_STATUS);
349 if (hService)
350 {
351 DWORD size;
352
353 QueryServiceStatusEx(hService,
354 SC_STATUS_PROCESS_INFO,
355 (LPBYTE)&pService->ServiceStatusProcess,
356 sizeof(SERVICE_STATUS_PROCESS),
357 &size);
358
359 CloseServiceHandle(hService);
360 bRet = TRUE;
361 }
362
363 CloseServiceHandle(hScm);
364 }
365
366 return bRet;
367 }