Merge trunk HEAD (46152)
[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
13 ENUM_SERVICE_STATUS_PROCESS*
14 GetSelectedService(PMAIN_WND_INFO Info)
15 {
16 LVITEM lvItem;
17
18 lvItem.mask = LVIF_PARAM;
19 lvItem.iItem = Info->SelectedItem;
20 SendMessage(Info->hListView,
21 LVM_GETITEM,
22 0,
23 (LPARAM)&lvItem);
24
25 /* return pointer to selected service */
26 return (ENUM_SERVICE_STATUS_PROCESS *)lvItem.lParam;
27 }
28
29
30 LPQUERY_SERVICE_CONFIG
31 GetServiceConfig(LPTSTR lpServiceName)
32 {
33 LPQUERY_SERVICE_CONFIG lpServiceConfig = NULL;
34 SC_HANDLE hSCManager;
35 SC_HANDLE hService;
36 DWORD dwBytesNeeded;
37
38 hSCManager = OpenSCManager(NULL,
39 NULL,
40 SC_MANAGER_ALL_ACCESS);
41 if (hSCManager)
42 {
43 hService = OpenService(hSCManager,
44 lpServiceName,
45 SERVICE_QUERY_STATUS | SERVICE_ENUMERATE_DEPENDENTS | SERVICE_QUERY_CONFIG);
46 if (hService)
47 {
48 if (!QueryServiceConfig(hService,
49 NULL,
50 0,
51 &dwBytesNeeded))
52 {
53 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
54 {
55 lpServiceConfig = (LPQUERY_SERVICE_CONFIG)HeapAlloc(GetProcessHeap(),
56 0,
57 dwBytesNeeded);
58 if (lpServiceConfig)
59 {
60 if (!QueryServiceConfig(hService,
61 lpServiceConfig,
62 dwBytesNeeded,
63 &dwBytesNeeded))
64 {
65 HeapFree(GetProcessHeap(),
66 0,
67 lpServiceConfig);
68 lpServiceConfig = NULL;
69 }
70 }
71 }
72 }
73
74 CloseServiceHandle(hService);
75 }
76
77 CloseServiceHandle(hSCManager);
78 }
79
80 return lpServiceConfig;
81 }
82
83
84 BOOL
85 SetServiceConfig(LPQUERY_SERVICE_CONFIG pServiceConfig,
86 LPTSTR lpServiceName,
87 LPTSTR lpPassword)
88 {
89 SC_HANDLE hSCManager;
90 SC_HANDLE hSc;
91 SC_LOCK scLock;
92 BOOL bRet = FALSE;
93
94 hSCManager = OpenSCManager(NULL,
95 NULL,
96 SC_MANAGER_LOCK);
97 if (hSCManager)
98 {
99 scLock = LockServiceDatabase(hSCManager);
100 if (scLock)
101 {
102 hSc = OpenService(hSCManager,
103 lpServiceName,
104 SERVICE_CHANGE_CONFIG);
105 if (hSc)
106 {
107 if (ChangeServiceConfig(hSc,
108 pServiceConfig->dwServiceType,
109 pServiceConfig->dwStartType,
110 pServiceConfig->dwErrorControl,
111 pServiceConfig->lpBinaryPathName,
112 pServiceConfig->lpLoadOrderGroup,
113 pServiceConfig->dwTagId ? &pServiceConfig->dwTagId : NULL,
114 pServiceConfig->lpDependencies,
115 pServiceConfig->lpServiceStartName,
116 lpPassword,
117 pServiceConfig->lpDisplayName))
118 {
119 bRet = TRUE;
120 }
121
122 CloseServiceHandle(hSc);
123 }
124
125 UnlockServiceDatabase(scLock);
126 }
127
128 CloseServiceHandle(hSCManager);
129 }
130
131 if (!bRet)
132 GetError();
133
134 return bRet;
135 }
136
137
138 LPTSTR
139 GetServiceDescription(LPTSTR lpServiceName)
140 {
141 SC_HANDLE hSCManager = NULL;
142 SC_HANDLE hSc = NULL;
143 SERVICE_DESCRIPTION *pServiceDescription = NULL;
144 LPTSTR lpDescription = NULL;
145 DWORD BytesNeeded = 0;
146 DWORD dwSize;
147
148 hSCManager = OpenSCManager(NULL,
149 NULL,
150 SC_MANAGER_ENUMERATE_SERVICE);
151 if (hSCManager == NULL)
152 {
153 GetError();
154 return NULL;
155 }
156
157 hSc = OpenService(hSCManager,
158 lpServiceName,
159 SERVICE_QUERY_CONFIG);
160 if (hSc)
161 {
162 if (!QueryServiceConfig2(hSc,
163 SERVICE_CONFIG_DESCRIPTION,
164 NULL,
165 0,
166 &BytesNeeded))
167 {
168 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
169 {
170 pServiceDescription = (SERVICE_DESCRIPTION *) HeapAlloc(ProcessHeap,
171 0,
172 BytesNeeded);
173 if (pServiceDescription == NULL)
174 goto cleanup;
175
176 if (QueryServiceConfig2(hSc,
177 SERVICE_CONFIG_DESCRIPTION,
178 (LPBYTE)pServiceDescription,
179 BytesNeeded,
180 &BytesNeeded))
181 {
182 if (pServiceDescription->lpDescription)
183 {
184 dwSize = _tcslen(pServiceDescription->lpDescription) + 1;
185 lpDescription = HeapAlloc(ProcessHeap,
186 0,
187 dwSize * sizeof(TCHAR));
188 if (lpDescription)
189 {
190 _tcscpy_s(lpDescription,
191 dwSize,
192 pServiceDescription->lpDescription);
193 }
194 }
195 }
196 }
197 }
198 }
199
200 cleanup:
201 if (pServiceDescription)
202 HeapFree(ProcessHeap,
203 0,
204 pServiceDescription);
205 if (hSCManager != NULL)
206 CloseServiceHandle(hSCManager);
207 if (hSc != NULL)
208 CloseServiceHandle(hSc);
209
210 return lpDescription;
211 }
212
213
214 BOOL
215 SetServiceDescription(LPTSTR lpServiceName,
216 LPTSTR lpDescription)
217 {
218 SC_HANDLE hSCManager;
219 SC_HANDLE hSc;
220 SC_LOCK scLock;
221 SERVICE_DESCRIPTION ServiceDescription;
222 BOOL bRet = FALSE;
223
224 hSCManager = OpenSCManager(NULL,
225 NULL,
226 SC_MANAGER_LOCK);
227 if (hSCManager)
228 {
229 scLock = LockServiceDatabase(hSCManager);
230 if (scLock)
231 {
232 hSc = OpenService(hSCManager,
233 lpServiceName,
234 SERVICE_CHANGE_CONFIG);
235 if (hSc)
236 {
237 ServiceDescription.lpDescription = lpDescription;
238
239 if (ChangeServiceConfig2(hSc,
240 SERVICE_CONFIG_DESCRIPTION,
241 &ServiceDescription))
242 {
243 bRet = TRUE;
244 }
245
246 CloseServiceHandle(hSc);
247 }
248
249 UnlockServiceDatabase(scLock);
250 }
251
252 CloseServiceHandle(hSCManager);
253 }
254
255 if (!bRet)
256 GetError();
257
258 return bRet;
259 }
260
261
262 BOOL
263 GetServiceList(PMAIN_WND_INFO Info,
264 DWORD *NumServices)
265 {
266 SC_HANDLE ScHandle;
267 BOOL bRet = FALSE;
268
269 DWORD BytesNeeded = 0;
270 DWORD ResumeHandle = 0;
271
272 *NumServices = 0;
273
274 if (Info->pAllServices != NULL)
275 {
276 HeapFree(ProcessHeap,
277 0,
278 Info->pAllServices);
279 }
280
281 ScHandle = OpenSCManager(NULL,
282 NULL,
283 SC_MANAGER_ENUMERATE_SERVICE);
284 if (ScHandle != INVALID_HANDLE_VALUE)
285 {
286 if (!EnumServicesStatusEx(ScHandle,
287 SC_ENUM_PROCESS_INFO,
288 SERVICE_WIN32,
289 SERVICE_STATE_ALL,
290 NULL,
291 0,
292 &BytesNeeded,
293 NumServices,
294 &ResumeHandle,
295 0))
296 {
297 /* Call function again if required size was returned */
298 if (GetLastError() == ERROR_MORE_DATA)
299 {
300 /* reserve memory for service info array */
301 Info->pAllServices = (ENUM_SERVICE_STATUS_PROCESS *) HeapAlloc(ProcessHeap,
302 0,
303 BytesNeeded);
304 if (Info->pAllServices)
305 {
306 /* fill array with service info */
307 if (EnumServicesStatusEx(ScHandle,
308 SC_ENUM_PROCESS_INFO,
309 SERVICE_WIN32,
310 SERVICE_STATE_ALL,
311 (LPBYTE)Info->pAllServices,
312 BytesNeeded,
313 &BytesNeeded,
314 NumServices,
315 &ResumeHandle,
316 0))
317 {
318 bRet = TRUE;
319 }
320 }
321 }
322 }
323 }
324
325 if (ScHandle)
326 CloseServiceHandle(ScHandle);
327
328 if (!bRet)
329 {
330 HeapFree(ProcessHeap,
331 0,
332 Info->pAllServices);
333 }
334
335 return bRet;
336 }
337
338
339 BOOL
340 UpdateServiceStatus(ENUM_SERVICE_STATUS_PROCESS* pService)
341 {
342 SC_HANDLE hScm;
343 BOOL bRet = FALSE;
344
345 hScm = OpenSCManager(NULL,
346 NULL,
347 SC_MANAGER_ENUMERATE_SERVICE);
348 if (hScm != INVALID_HANDLE_VALUE)
349 {
350 SC_HANDLE hService;
351
352 hService = OpenService(hScm,
353 pService->lpServiceName,
354 SERVICE_QUERY_STATUS);
355 if (hService)
356 {
357 DWORD size;
358
359 QueryServiceStatusEx(hService,
360 SC_STATUS_PROCESS_INFO,
361 (LPBYTE)&pService->ServiceStatusProcess,
362 sizeof(SERVICE_STATUS_PROCESS),
363 &size);
364
365 CloseServiceHandle(hService);
366 bRet = TRUE;
367 }
368
369 CloseServiceHandle(hScm);
370 }
371
372 return bRet;
373 }