1d83b348a1eab05257581d08d05debbc3ce4940a
[reactos.git] / reactos / subsys / system / servman / query.c
1 /*
2 * PROJECT: ReactOS Services
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: subsys/system/servman/query.c
5 * PURPOSE: Query service information
6 * COPYRIGHT: Copyright 2005 Ged Murphy <gedmurphy@gmail.com>
7 *
8 */
9
10 #include "servman.h"
11
12 extern HINSTANCE hInstance;
13 extern HWND hListView;
14 extern HWND hStatus;
15
16 /* Stores the service array */
17 ENUM_SERVICE_STATUS_PROCESS *pServiceStatus = NULL;
18
19
20 /* free service array */
21 VOID FreeMemory(VOID)
22 {
23 HeapFree(GetProcessHeap(), 0, pServiceStatus);
24 }
25
26
27 BOOL
28 RefreshServiceList(VOID)
29 {
30 LVITEM item;
31 TCHAR szNumServices[32];
32 TCHAR szStatus[128];
33 DWORD NumServices = 0;
34 DWORD Index;
35 LPCTSTR Path = _T("System\\CurrentControlSet\\Services\\%s");
36
37 ListView_DeleteAllItems(hListView);
38
39 NumServices = GetServiceList();
40
41 if (NumServices)
42 {
43 HICON hiconItem; /* icon for list-view items */
44 HIMAGELIST hSmall; /* image list for other views */
45 TCHAR buf[300];
46
47 /* Create the icon image lists */
48 hSmall = ImageList_Create(GetSystemMetrics(SM_CXSMICON),
49 GetSystemMetrics(SM_CYSMICON), ILC_MASK, 1, 1);
50
51 /* Add an icon to each image list */
52 hiconItem = LoadImage(hInstance, MAKEINTRESOURCE(IDI_SM_ICON), IMAGE_ICON, 16, 16, 0);
53 ImageList_AddIcon(hSmall, hiconItem);
54
55 ListView_SetImageList(hListView, hSmall, LVSIL_SMALL);
56
57 /* set the number of services in the status bar */
58 LoadString(hInstance, IDS_SERVICES_NUM_SERVICES, szNumServices, 32);
59 _sntprintf(buf, 300, szNumServices, NumServices);
60 SendMessage(hStatus, SB_SETTEXT, 0, (LPARAM)buf);
61
62
63 for (Index = 0; Index < NumServices; Index++)
64 {
65 HKEY hKey = NULL;
66 LPTSTR Description = NULL;
67 LONG ret;
68 LPTSTR LogOnAs = NULL;
69 DWORD StartUp = 0;
70 DWORD dwValueSize;
71
72 /* open the registry key for the service */
73 _sntprintf(buf, 300, Path,
74 pServiceStatus[Index].lpServiceName);
75
76 if( RegOpenKeyEx(HKEY_LOCAL_MACHINE,
77 buf,
78 0,
79 KEY_READ,
80 &hKey) != ERROR_SUCCESS)
81 {
82 GetError();
83 return FALSE;
84 }
85
86
87 /* set the display name */
88
89 ZeroMemory(&item, sizeof(LV_ITEM));
90 item.mask = LVIF_TEXT;
91 item.pszText = pServiceStatus[Index].lpDisplayName;
92 item.iItem = ListView_GetItemCount(hListView);
93 item.iItem = ListView_InsertItem(hListView, &item);
94
95
96
97 /* set the description */
98 dwValueSize = 0;
99 ret = RegQueryValueEx(hKey,
100 _T("Description"),
101 NULL,
102 NULL,
103 NULL,
104 &dwValueSize);
105 if (ret != ERROR_SUCCESS && ret != ERROR_FILE_NOT_FOUND)
106 {
107 RegCloseKey(hKey);
108 return FALSE;
109 }
110
111 if (ret != ERROR_FILE_NOT_FOUND)
112 {
113 Description = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwValueSize);
114 if (Description == NULL)
115 {
116 RegCloseKey(hKey);
117 return FALSE;
118 }
119 if(RegQueryValueEx(hKey,
120 _T("Description"),
121 NULL,
122 NULL,
123 (LPBYTE)Description,
124 &dwValueSize))
125 {
126 HeapFree(GetProcessHeap(), 0, Description);
127 RegCloseKey(hKey);
128 return FALSE;
129 }
130
131 item.pszText = Description;
132 item.iSubItem = 1;
133 SendMessage(hListView, LVM_SETITEMTEXT, item.iItem, (LPARAM) &item);
134
135 HeapFree(GetProcessHeap(), 0, Description);
136 }
137 else
138 {
139 item.pszText = '\0';
140 item.iSubItem = 1;
141 SendMessage(hListView, LVM_SETITEMTEXT, item.iItem, (LPARAM) &item);
142 }
143
144
145 /* set the status */
146
147 if (pServiceStatus[Index].ServiceStatusProcess.dwCurrentState == SERVICE_RUNNING)
148 {
149 LoadString(hInstance, IDS_SERVICES_STATUS_RUNNING, szStatus, 128);
150 item.pszText = szStatus;
151 item.iSubItem = 2;
152 SendMessage(hListView, LVM_SETITEMTEXT, item.iItem, (LPARAM) &item);
153 }
154 else
155 {
156 item.pszText = '\0';
157 item.iSubItem = 2;
158 SendMessage(hListView, LVM_SETITEMTEXT, item.iItem, (LPARAM) &item);
159 }
160
161 /* set the startup type */
162
163 dwValueSize = sizeof(DWORD);
164 if (RegQueryValueEx(hKey,
165 _T("Start"),
166 NULL,
167 NULL,
168 (LPBYTE)&StartUp,
169 &dwValueSize))
170 {
171 RegCloseKey(hKey);
172 return FALSE;
173 }
174
175 if (StartUp == 0x02)
176 {
177 LoadString(hInstance, IDS_SERVICES_AUTO, szStatus, 128);
178 item.pszText = szStatus;
179 item.iSubItem = 3;
180 SendMessage(hListView, LVM_SETITEMTEXT, item.iItem, (LPARAM) &item);
181 }
182 else if (StartUp == 0x03)
183 {
184 LoadString(hInstance, IDS_SERVICES_MAN, szStatus, 128);
185 item.pszText = szStatus;
186 item.iSubItem = 3;
187 SendMessage(hListView, LVM_SETITEMTEXT, item.iItem, (LPARAM) &item);
188 }
189 else if (StartUp == 0x04)
190 {
191 LoadString(hInstance, IDS_SERVICES_DIS, szStatus, 128);
192 item.pszText = szStatus;
193 item.iSubItem = 3;
194 SendMessage(hListView, LVM_SETITEMTEXT, item.iItem, (LPARAM) &item);
195 }
196
197
198
199 /* set Log On As */
200
201 dwValueSize = 0;
202 if (RegQueryValueEx(hKey,
203 _T("ObjectName"),
204 NULL,
205 NULL,
206 NULL,
207 &dwValueSize))
208 {
209 RegCloseKey(hKey);
210 return FALSE;
211 }
212
213 LogOnAs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwValueSize);
214 if (LogOnAs == NULL)
215 {
216 RegCloseKey(hKey);
217 return FALSE;
218 }
219 if(RegQueryValueEx(hKey,
220 _T("ObjectName"),
221 NULL,
222 NULL,
223 (LPBYTE)LogOnAs,
224 &dwValueSize))
225 {
226 HeapFree(GetProcessHeap(), 0, LogOnAs);
227 RegCloseKey(hKey);
228 return FALSE;
229 }
230
231 item.pszText = LogOnAs;
232 item.iSubItem = 4;
233 SendMessage(hListView, LVM_SETITEMTEXT, item.iItem, (LPARAM) &item);
234
235 HeapFree(GetProcessHeap(), 0, LogOnAs);
236
237 RegCloseKey(hKey);
238
239 }
240 }
241
242 return TRUE;
243 }
244
245
246
247
248 DWORD
249 GetServiceList(VOID)
250 {
251 SC_HANDLE ScHandle;
252
253 DWORD BytesNeeded = 0;
254 DWORD ResumeHandle = 0;
255 DWORD NumServices = 0;
256
257 ScHandle = OpenSCManager(NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE);
258 if (ScHandle != INVALID_HANDLE_VALUE)
259 {
260 if (EnumServicesStatusEx(ScHandle,
261 SC_ENUM_PROCESS_INFO,
262 SERVICE_WIN32,
263 SERVICE_STATE_ALL,
264 (LPBYTE)pServiceStatus,
265 0, &BytesNeeded,
266 &NumServices,
267 &ResumeHandle,
268 0) == 0)
269 {
270 /* Call function again if required size was returned */
271 if (GetLastError() == ERROR_MORE_DATA)
272 {
273 /* reserve memory for service info array */
274 pServiceStatus = (ENUM_SERVICE_STATUS_PROCESS *) HeapAlloc(GetProcessHeap(), 0, BytesNeeded);
275 if (pServiceStatus == NULL)
276 return FALSE;
277
278 /* fill array with service info */
279 if (EnumServicesStatusEx(ScHandle,
280 SC_ENUM_PROCESS_INFO,
281 SERVICE_WIN32,
282 SERVICE_STATE_ALL,
283 (LPBYTE)pServiceStatus,
284 BytesNeeded,
285 &BytesNeeded,
286 &NumServices,
287 &ResumeHandle,
288 0) == 0)
289 {
290 HeapFree(GetProcessHeap(), 0, pServiceStatus);
291 return FALSE;
292 }
293 }
294 else /* exit on failure */
295 {
296 return FALSE;
297 }
298 }
299 }
300
301 CloseServiceHandle(ScHandle);
302
303 return NumServices;
304 }
305
306
307
308
309
310
311
312
313
314
315
316 /*
317 //WORD wCodePage;
318 //WORD wLangID;
319 //SC_HANDLE hService;
320 //DWORD dwHandle, dwLen;
321 //UINT BufLen;
322 //TCHAR* lpData;
323 //TCHAR* lpBuffer;
324 //TCHAR szStrFileInfo[80];
325 //TCHAR FileName[MAX_PATH];
326 //LPVOID pvData;
327
328 //LPSERVICE_FAILURE_ACTIONS pServiceFailureActions = NULL;
329 //LPQUERY_SERVICE_CONFIG pServiceConfig = NULL;
330
331 BytesNeeded = 0;
332 hService = OpenService(ScHandle,
333 pServiceStatus[Index].lpServiceName,
334 SC_MANAGER_CONNECT);
335 if (hService != INVALID_HANDLE_VALUE)
336 {
337 / * check if service is required by the system* /
338 if (!QueryServiceConfig2(hService,
339 SERVICE_CONFIG_FAILURE_ACTIONS,
340 (LPBYTE)pServiceFailureActions,
341 0,
342 &BytesNeeded))
343 {
344 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
345 {
346 pServiceFailureActions = (LPSERVICE_FAILURE_ACTIONS)
347 HeapAlloc(GetProcessHeap(), 0, BytesNeeded);
348 if (pServiceFailureActions == NULL)
349 return FALSE;
350
351 if (!QueryServiceConfig2(hService,
352 SERVICE_CONFIG_FAILURE_ACTIONS,
353 (LPBYTE)pServiceFailureActions,
354 BytesNeeded,
355 &BytesNeeded))
356 {
357 HeapFree(GetProcessHeap(), 0, pServiceFailureActions);
358 return FALSE;
359 }
360 }
361 else / * exit on failure * /
362 {
363 return FALSE;
364 }
365 }
366 if (pServiceFailureActions->cActions)
367 {
368 if (pServiceFailureActions->lpsaActions[0].Type == SC_ACTION_REBOOT)
369 {
370 LoadString(hInstance, IDS_SERVICES_YES, szStatus, 128);
371 item.pszText = szStatus;
372 item.iSubItem = 1;
373 SendMessage(hListView, LVM_SETITEMTEXT, item.iItem, (LPARAM) &item);
374 }
375 }
376
377 if (pServiceFailureActions != NULL)
378 {
379 HeapFree(GetProcessHeap(), 0, pServiceFailureActions);
380 pServiceFailureActions = NULL;
381 }
382
383 / * get vendor of service binary * /
384 BytesNeeded = 0;
385 if (!QueryServiceConfig(hService, pServiceConfig, 0, &BytesNeeded))
386 {
387 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
388 {
389 pServiceConfig = (LPQUERY_SERVICE_CONFIG)
390 HeapAlloc(GetProcessHeap(), 0, BytesNeeded);
391 if (pServiceConfig == NULL)
392 return FALSE;
393
394 if (!QueryServiceConfig(hService,
395 pServiceConfig,
396 BytesNeeded,
397 &BytesNeeded))
398 {
399 HeapFree(GetProcessHeap(), 0, pServiceConfig);
400 return FALSE;
401 }
402 }
403 else / * exit on failure * /
404 {
405 return FALSE;
406 }
407 }
408
409 memset(&FileName, 0, MAX_PATH);
410 if (_tcscspn(pServiceConfig->lpBinaryPathName, _T("\"")))
411 {
412 _tcsncpy(FileName, pServiceConfig->lpBinaryPathName,
413 _tcscspn(pServiceConfig->lpBinaryPathName, _T(" ")) );
414 }
415 else
416 {
417 _tcscpy(FileName, pServiceConfig->lpBinaryPathName);
418 }
419
420 HeapFree(GetProcessHeap(), 0, pServiceConfig);
421 pServiceConfig = NULL;
422
423 dwLen = GetFileVersionInfoSize(FileName, &dwHandle);
424 if (dwLen)
425 {
426 lpData = (TCHAR*) HeapAlloc(GetProcessHeap(), 0, dwLen);
427 if (lpData == NULL)
428 return FALSE;
429
430 if (!GetFileVersionInfo (FileName, dwHandle, dwLen, lpData)) {
431 HeapFree(GetProcessHeap(), 0, lpData);
432 return FALSE;
433 }
434
435 if (VerQueryValue(lpData, _T("\\VarFileInfo\\Translation"), &pvData, (PUINT) &BufLen))
436 {
437 wCodePage = LOWORD(*(DWORD*) pvData);
438 wLangID = HIWORD(*(DWORD*) pvData);
439 wsprintf(szStrFileInfo, _T("StringFileInfo\\%04X%04X\\CompanyName"), wCodePage, wLangID);
440 }
441
442 if (VerQueryValue (lpData, szStrFileInfo, (LPVOID) &lpBuffer, (PUINT) &BufLen)) {
443 item.pszText = lpBuffer;
444 item.iSubItem = 2;
445 SendMessage(hListView, LVM_SETITEMTEXT, item.iItem, (LPARAM) &item);
446 }
447 HeapFree(GetProcessHeap(), 0, lpData);
448 }
449 else
450 {
451 LoadString(hInstance, IDS_SERVICES_UNKNOWN, szStatus, 128);
452 item.pszText = szStatus;
453 item.iSubItem = 2;
454 SendMessage(hListView, LVM_SETITEMTEXT, item.iItem, (LPARAM) &item);
455 }
456 CloseServiceHandle(hService);
457 }
458 */