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