Create a branch for network fixes.
[reactos.git] / 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 SC_HANDLE hSCManager = NULL;
34 SC_HANDLE hSc = NULL;
35 LPQUERY_SERVICE_CONFIG pServiceConfig = NULL;
36 DWORD BytesNeeded = 0;
37
38 hSCManager = OpenSCManager(NULL,
39 NULL,
40 SC_MANAGER_ENUMERATE_SERVICE);
41 if (hSCManager == NULL)
42 {
43 GetError();
44 return NULL;
45 }
46
47 hSc = OpenService(hSCManager,
48 lpServiceName,
49 SERVICE_QUERY_CONFIG);
50 if (hSc == NULL)
51 {
52 GetError();
53 goto cleanup;
54 }
55
56 if (!QueryServiceConfig(hSc,
57 pServiceConfig,
58 0,
59 &BytesNeeded))
60 {
61 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
62 {
63 pServiceConfig = (LPQUERY_SERVICE_CONFIG) HeapAlloc(ProcessHeap,
64 0,
65 BytesNeeded);
66 if (pServiceConfig == NULL)
67 goto cleanup;
68
69 if (!QueryServiceConfig(hSc,
70 pServiceConfig,
71 BytesNeeded,
72 &BytesNeeded))
73 {
74 HeapFree(ProcessHeap,
75 0,
76 pServiceConfig);
77
78 pServiceConfig = NULL;
79 }
80 }
81 }
82
83 cleanup:
84 if (hSCManager != NULL)
85 CloseServiceHandle(hSCManager);
86 if (hSc != NULL)
87 CloseServiceHandle(hSc);
88
89 return pServiceConfig;
90 }
91
92
93 BOOL
94 SetServiceConfig(LPQUERY_SERVICE_CONFIG pServiceConfig,
95 LPTSTR lpServiceName,
96 LPTSTR lpPassword)
97 {
98 SC_HANDLE hSCManager;
99 SC_HANDLE hSc;
100 SC_LOCK scLock;
101 BOOL bRet = FALSE;
102
103 hSCManager = OpenSCManager(NULL,
104 NULL,
105 SC_MANAGER_LOCK);
106 if (hSCManager)
107 {
108 scLock = LockServiceDatabase(hSCManager);
109 if (scLock)
110 {
111 hSc = OpenService(hSCManager,
112 lpServiceName,
113 SERVICE_CHANGE_CONFIG);
114 if (hSc)
115 {
116 if (ChangeServiceConfig(hSc,
117 pServiceConfig->dwServiceType,
118 pServiceConfig->dwStartType,
119 pServiceConfig->dwErrorControl,
120 pServiceConfig->lpBinaryPathName,
121 pServiceConfig->lpLoadOrderGroup,
122 pServiceConfig->dwTagId ? &pServiceConfig->dwTagId : NULL,
123 pServiceConfig->lpDependencies,
124 pServiceConfig->lpServiceStartName,
125 lpPassword,
126 pServiceConfig->lpDisplayName))
127 {
128 bRet = TRUE;
129 }
130 }
131
132 UnlockServiceDatabase(scLock);
133 }
134 }
135
136 if (!bRet)
137 GetError();
138
139 return bRet;
140 }
141
142
143 LPTSTR
144 GetServiceDescription(LPTSTR lpServiceName)
145 {
146 SC_HANDLE hSCManager = NULL;
147 SC_HANDLE hSc = NULL;
148 SERVICE_DESCRIPTION *pServiceDescription = NULL;
149 LPTSTR lpDescription = NULL;
150 DWORD BytesNeeded = 0;
151
152 hSCManager = OpenSCManager(NULL,
153 NULL,
154 SC_MANAGER_ENUMERATE_SERVICE);
155 if (hSCManager == NULL)
156 {
157 GetError();
158 return NULL;
159 }
160
161 hSc = OpenService(hSCManager,
162 lpServiceName,
163 SERVICE_QUERY_CONFIG);
164 if (hSc)
165 {
166 if (!QueryServiceConfig2(hSc,
167 SERVICE_CONFIG_DESCRIPTION,
168 NULL,
169 0,
170 &BytesNeeded))
171 {
172 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
173 {
174 pServiceDescription = (SERVICE_DESCRIPTION *) HeapAlloc(ProcessHeap,
175 0,
176 BytesNeeded);
177 if (pServiceDescription == NULL)
178 goto cleanup;
179
180 if (QueryServiceConfig2(hSc,
181 SERVICE_CONFIG_DESCRIPTION,
182 (LPBYTE)pServiceDescription,
183 BytesNeeded,
184 &BytesNeeded))
185 {
186 if (pServiceDescription->lpDescription)
187 {
188 lpDescription = HeapAlloc(ProcessHeap,
189 0,
190 (_tcslen(pServiceDescription->lpDescription) + 1) * sizeof(TCHAR));
191 if (lpDescription)
192 _tcscpy(lpDescription,
193 pServiceDescription->lpDescription);
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(*pService),
363 &size);
364
365 bRet = TRUE;
366 }
367 }
368
369 return bRet;
370 }