[BRANCHES]
[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(LPTSTR lpServiceName)
30 {
31 LPQUERY_SERVICE_CONFIG lpServiceConfig = NULL;
32 SC_HANDLE hSCManager;
33 SC_HANDLE hService;
34 DWORD dwBytesNeeded;
35
36 hSCManager = OpenSCManager(NULL,
37 NULL,
38 SC_MANAGER_ALL_ACCESS);
39 if (hSCManager)
40 {
41 hService = OpenService(hSCManager,
42 lpServiceName,
43 SERVICE_QUERY_STATUS | SERVICE_ENUMERATE_DEPENDENTS | SERVICE_QUERY_CONFIG);
44 if (hService)
45 {
46 if (!QueryServiceConfig(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 (!QueryServiceConfig(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 LPTSTR lpServiceName,
84 LPTSTR lpPassword)
85 {
86 SC_HANDLE hSCManager;
87 SC_HANDLE hSc;
88 SC_LOCK scLock;
89 BOOL bRet = FALSE;
90
91 hSCManager = OpenSCManager(NULL,
92 NULL,
93 SC_MANAGER_LOCK);
94 if (hSCManager)
95 {
96 scLock = LockServiceDatabase(hSCManager);
97 if (scLock)
98 {
99 hSc = OpenService(hSCManager,
100 lpServiceName,
101 SERVICE_CHANGE_CONFIG);
102 if (hSc)
103 {
104 if (ChangeServiceConfig(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 LPTSTR
135 GetServiceDescription(LPTSTR lpServiceName)
136 {
137 SC_HANDLE hSCManager = NULL;
138 SC_HANDLE hSc = NULL;
139 SERVICE_DESCRIPTION *pServiceDescription = NULL;
140 LPTSTR lpDescription = NULL;
141 DWORD BytesNeeded = 0;
142 DWORD dwSize;
143
144 hSCManager = OpenSCManager(NULL,
145 NULL,
146 SC_MANAGER_ENUMERATE_SERVICE);
147 if (hSCManager == NULL)
148 {
149 GetError();
150 return NULL;
151 }
152
153 hSc = OpenService(hSCManager,
154 lpServiceName,
155 SERVICE_QUERY_CONFIG);
156 if (hSc)
157 {
158 if (!QueryServiceConfig2(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 (QueryServiceConfig2(hSc,
173 SERVICE_CONFIG_DESCRIPTION,
174 (LPBYTE)pServiceDescription,
175 BytesNeeded,
176 &BytesNeeded))
177 {
178 if (pServiceDescription->lpDescription)
179 {
180 dwSize = _tcslen(pServiceDescription->lpDescription) + 1;
181 lpDescription = HeapAlloc(ProcessHeap,
182 0,
183 dwSize * sizeof(TCHAR));
184 if (lpDescription)
185 {
186 _tcscpy_s(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(LPTSTR lpServiceName,
211 LPTSTR 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 = OpenSCManager(NULL,
220 NULL,
221 SC_MANAGER_LOCK);
222 if (hSCManager)
223 {
224 scLock = LockServiceDatabase(hSCManager);
225 if (scLock)
226 {
227 hSc = OpenService(hSCManager,
228 lpServiceName,
229 SERVICE_CHANGE_CONFIG);
230 if (hSc)
231 {
232 ServiceDescription.lpDescription = lpDescription;
233
234 if (ChangeServiceConfig2(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 }
274
275 ScHandle = OpenSCManager(NULL,
276 NULL,
277 SC_MANAGER_ENUMERATE_SERVICE);
278 if (ScHandle != INVALID_HANDLE_VALUE)
279 {
280 if (!EnumServicesStatusEx(ScHandle,
281 SC_ENUM_PROCESS_INFO,
282 SERVICE_WIN32,
283 SERVICE_STATE_ALL,
284 NULL,
285 0,
286 &BytesNeeded,
287 NumServices,
288 &ResumeHandle,
289 0))
290 {
291 /* Call function again if required size was returned */
292 if (GetLastError() == ERROR_MORE_DATA)
293 {
294 /* reserve memory for service info array */
295 Info->pAllServices = (ENUM_SERVICE_STATUS_PROCESS *) HeapAlloc(ProcessHeap,
296 0,
297 BytesNeeded);
298 if (Info->pAllServices)
299 {
300 /* fill array with service info */
301 if (EnumServicesStatusEx(ScHandle,
302 SC_ENUM_PROCESS_INFO,
303 SERVICE_WIN32,
304 SERVICE_STATE_ALL,
305 (LPBYTE)Info->pAllServices,
306 BytesNeeded,
307 &BytesNeeded,
308 NumServices,
309 &ResumeHandle,
310 0))
311 {
312 bRet = TRUE;
313 }
314 }
315 }
316 }
317 }
318
319 if (ScHandle)
320 CloseServiceHandle(ScHandle);
321
322 if (!bRet)
323 {
324 HeapFree(ProcessHeap,
325 0,
326 Info->pAllServices);
327 }
328
329 return bRet;
330 }
331
332 BOOL
333 UpdateServiceStatus(ENUM_SERVICE_STATUS_PROCESS* pService)
334 {
335 SC_HANDLE hScm;
336 BOOL bRet = FALSE;
337
338 hScm = OpenSCManager(NULL,
339 NULL,
340 SC_MANAGER_ENUMERATE_SERVICE);
341 if (hScm != INVALID_HANDLE_VALUE)
342 {
343 SC_HANDLE hService;
344
345 hService = OpenService(hScm,
346 pService->lpServiceName,
347 SERVICE_QUERY_STATUS);
348 if (hService)
349 {
350 DWORD size;
351
352 QueryServiceStatusEx(hService,
353 SC_STATUS_PROCESS_INFO,
354 (LPBYTE)&pService->ServiceStatusProcess,
355 sizeof(SERVICE_STATUS_PROCESS),
356 &size);
357
358 CloseServiceHandle(hService);
359 bRet = TRUE;
360 }
361
362 CloseServiceHandle(hScm);
363 }
364
365 return bRet;
366 }