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