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