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 - 2006 Ged Murphy <gedmurphy@gmail.com>
12 extern HINSTANCE hInstance
;
13 extern HWND hListView
;
16 /* Stores the complete services array */
17 ENUM_SERVICE_STATUS_PROCESS
*pServiceStatus
= NULL
;
20 /* Free service array */
23 HeapFree(GetProcessHeap(), 0, pServiceStatus
);
27 /* Retrives the service description from the registry */
28 BOOL
GetDescription(HKEY hKey
, LPTSTR
*retDescription
)
31 LPTSTR Description
= NULL
;
32 DWORD dwValueSize
= 0;
33 LONG ret
= RegQueryValueEx(hKey
,
39 if (ret
!= ERROR_SUCCESS
&& ret
!= ERROR_FILE_NOT_FOUND
&& ret
!= ERROR_INVALID_HANDLE
)
45 if (ret
!= ERROR_FILE_NOT_FOUND
)
47 Description
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, dwValueSize
);
48 if (Description
== NULL
)
54 if(RegQueryValueEx(hKey
,
61 HeapFree(GetProcessHeap(), 0, Description
);
67 /* copy pointer over */
68 *retDescription
= Description
;
74 /* get vendor of service binary */
75 BOOL
GetExecutablePath(LPTSTR
*ExePath
)
77 SC_HANDLE hSCManager
= NULL
;
79 LPQUERY_SERVICE_CONFIG pServiceConfig
= NULL
;
80 ENUM_SERVICE_STATUS_PROCESS
*Service
= NULL
;
82 DWORD BytesNeeded
= 0;
83 TCHAR FileName
[MAX_PATH
];
86 item
.mask
= LVIF_PARAM
;
87 item
.iItem
= GetSelectedItem();
88 SendMessage(hListView
, LVM_GETITEM
, 0, (LPARAM
)&item
);
90 /* copy pointer to selected service */
91 Service
= (ENUM_SERVICE_STATUS_PROCESS
*)item
.lParam
;
93 /* open handle to the SCM */
94 hSCManager
= OpenSCManager(NULL
, NULL
, SC_MANAGER_ENUMERATE_SERVICE
);
95 if (hSCManager
== NULL
)
101 /* get a handle to the service requested for starting */
102 hSc
= OpenService(hSCManager
, Service
->lpServiceName
, SERVICE_QUERY_CONFIG
);
110 if (!QueryServiceConfig(hSc
, pServiceConfig
, 0, &BytesNeeded
))
112 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER
)
114 pServiceConfig
= (LPQUERY_SERVICE_CONFIG
)
115 HeapAlloc(GetProcessHeap(), 0, BytesNeeded
);
116 if (pServiceConfig
== NULL
)
119 if (!QueryServiceConfig(hSc
,
124 HeapFree(GetProcessHeap(), 0, pServiceConfig
);
128 else /* exit on failure */
134 ZeroMemory(&FileName
, MAX_PATH
);
135 if (_tcscspn(pServiceConfig
->lpBinaryPathName
, _T("\"")))
137 _tcsncpy(FileName
, pServiceConfig
->lpBinaryPathName
,
138 _tcscspn(pServiceConfig
->lpBinaryPathName
, _T(" ")) );
142 _tcscpy(FileName
, pServiceConfig
->lpBinaryPathName
);
147 CloseServiceHandle(hSCManager
);
148 CloseServiceHandle(hSc
);
153 if (hSCManager
!= NULL
)
154 CloseServiceHandle(hSCManager
);
156 CloseServiceHandle(hSc
);
164 RefreshServiceList(VOID
)
167 TCHAR szNumServices
[32];
169 DWORD NumServices
= 0;
171 LPCTSTR Path
= _T("System\\CurrentControlSet\\Services\\%s");
173 ListView_DeleteAllItems(hListView
);
175 NumServices
= GetServiceList();
179 HICON hiconItem
; /* icon for list-view items */
180 HIMAGELIST hSmall
; /* image list for other views */
181 TCHAR buf
[300]; /* buffer to hold key path */
182 INT NumListedServ
= 0; /* how many services were listed */
184 /* Create the icon image lists */
185 hSmall
= ImageList_Create(GetSystemMetrics(SM_CXSMICON
),
186 GetSystemMetrics(SM_CYSMICON
), ILC_MASK
| ILC_COLOR16
, 1, 1);
188 /* Add an icon to each image list */
189 hiconItem
= LoadImage(hInstance
, MAKEINTRESOURCE(IDI_SM_ICON
),
190 IMAGE_ICON
, 16, 16, 0);
191 ImageList_AddIcon(hSmall
, hiconItem
);
193 /* assign the image to the list view */
194 ListView_SetImageList(hListView
, hSmall
, LVSIL_SMALL
);
196 for (Index
= 0; Index
< NumServices
; Index
++)
199 LPTSTR Description
= NULL
;
200 LPTSTR LogOnAs
= NULL
;
204 /* open the registry key for the service */
205 _sntprintf(buf
, 300, Path
,
206 pServiceStatus
[Index
].lpServiceName
);
208 RegOpenKeyEx(HKEY_LOCAL_MACHINE
,
215 /* set the display name */
217 ZeroMemory(&item
, sizeof(LVITEM
));
218 item
.mask
= LVIF_TEXT
| LVIF_PARAM
;
219 item
.pszText
= pServiceStatus
[Index
].lpDisplayName
;
221 /* Set a pointer for each service so we can query it later.
222 * Not all services are added to the list, so we can't query
223 * the item number as they become out of sync with the array */
224 item
.lParam
= (LPARAM
)&pServiceStatus
[Index
];
226 item
.iItem
= ListView_GetItemCount(hListView
);
227 item
.iItem
= ListView_InsertItem(hListView
, &item
);
232 /* set the description */
234 if (GetDescription(hKey
, &Description
))
236 item
.pszText
= Description
;
238 SendMessage(hListView
, LVM_SETITEMTEXT
, item
.iItem
, (LPARAM
) &item
);
240 HeapFree(GetProcessHeap(), 0, Description
);
246 if (pServiceStatus
[Index
].ServiceStatusProcess
.dwCurrentState
249 LoadString(hInstance
, IDS_SERVICES_STARTED
, szStatus
,
250 sizeof(szStatus
) / sizeof(TCHAR
));
251 item
.pszText
= szStatus
;
253 SendMessage(hListView
, LVM_SETITEMTEXT
, item
.iItem
, (LPARAM
) &item
);
258 /* set the startup type */
260 dwValueSize
= sizeof(DWORD
);
261 if (RegQueryValueEx(hKey
,
274 LoadString(hInstance
, IDS_SERVICES_AUTO
, szStatus
,
275 sizeof(szStatus
) / sizeof(TCHAR
));
276 item
.pszText
= szStatus
;
278 SendMessage(hListView
, LVM_SETITEMTEXT
, item
.iItem
, (LPARAM
) &item
);
280 else if (StartUp
== 0x03)
282 LoadString(hInstance
, IDS_SERVICES_MAN
, szStatus
,
283 sizeof(szStatus
) / sizeof(TCHAR
));
284 item
.pszText
= szStatus
;
286 SendMessage(hListView
, LVM_SETITEMTEXT
, item
.iItem
, (LPARAM
) &item
);
288 else if (StartUp
== 0x04)
290 LoadString(hInstance
, IDS_SERVICES_DIS
, szStatus
,
291 sizeof(szStatus
) / sizeof(TCHAR
));
292 item
.pszText
= szStatus
;
294 SendMessage(hListView
, LVM_SETITEMTEXT
, item
.iItem
, (LPARAM
) &item
);
302 if (RegQueryValueEx(hKey
,
313 LogOnAs
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, dwValueSize
);
319 if(RegQueryValueEx(hKey
,
326 HeapFree(GetProcessHeap(), 0, LogOnAs
);
331 item
.pszText
= LogOnAs
;
333 SendMessage(hListView
, LVM_SETITEMTEXT
, item
.iItem
, (LPARAM
) &item
);
335 HeapFree(GetProcessHeap(), 0, LogOnAs
);
341 NumListedServ
= ListView_GetItemCount(hListView
);
343 /* set the number of listed services in the status bar */
344 LoadString(hInstance
, IDS_NUM_SERVICES
, szNumServices
,
345 sizeof(szNumServices
) / sizeof(TCHAR
));
346 _sntprintf(buf
, 300, szNumServices
, NumListedServ
);
347 SendMessage(hStatus
, SB_SETTEXT
, 0, (LPARAM
)buf
);
350 /* turn redraw flag on. It's turned off initially via the LBS_NOREDRAW flag */
351 SendMessage (hListView
, WM_SETREDRAW
, TRUE
, 0) ;
364 DWORD BytesNeeded
= 0;
365 DWORD ResumeHandle
= 0;
366 DWORD NumServices
= 0;
368 ScHandle
= OpenSCManager(NULL
, NULL
, SC_MANAGER_ENUMERATE_SERVICE
);
369 if (ScHandle
!= INVALID_HANDLE_VALUE
)
371 if (EnumServicesStatusEx(ScHandle
,
372 SC_ENUM_PROCESS_INFO
,
375 (LPBYTE
)pServiceStatus
,
381 /* Call function again if required size was returned */
382 if (GetLastError() == ERROR_MORE_DATA
)
384 /* reserve memory for service info array */
385 pServiceStatus
= (ENUM_SERVICE_STATUS_PROCESS
*)
386 HeapAlloc(GetProcessHeap(), 0, BytesNeeded
);
387 if (pServiceStatus
== NULL
)
390 /* fill array with service info */
391 if (EnumServicesStatusEx(ScHandle
,
392 SC_ENUM_PROCESS_INFO
,
395 (LPBYTE
)pServiceStatus
,
402 HeapFree(GetProcessHeap(), 0, pServiceStatus
);
406 else /* exit on failure */
413 CloseServiceHandle(ScHandle
);
431 //SC_HANDLE hService;
432 //DWORD dwHandle, dwLen;
436 //TCHAR szStrFileInfo[80];
437 //TCHAR FileName[MAX_PATH];
440 //LPSERVICE_FAILURE_ACTIONS pServiceFailureActions = NULL;
441 //LPQUERY_SERVICE_CONFIG pServiceConfig = NULL;
444 hService = OpenService(ScHandle,
445 pServiceStatus[Index].lpServiceName,
447 if (hService != INVALID_HANDLE_VALUE)
449 / * check if service is required by the system* /
450 if (!QueryServiceConfig2(hService,
451 SERVICE_CONFIG_FAILURE_ACTIONS,
452 (LPBYTE)pServiceFailureActions,
456 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
458 pServiceFailureActions = (LPSERVICE_FAILURE_ACTIONS)
459 HeapAlloc(GetProcessHeap(), 0, BytesNeeded);
460 if (pServiceFailureActions == NULL)
463 if (!QueryServiceConfig2(hService,
464 SERVICE_CONFIG_FAILURE_ACTIONS,
465 (LPBYTE)pServiceFailureActions,
469 HeapFree(GetProcessHeap(), 0, pServiceFailureActions);
473 else / * exit on failure * /
478 if (pServiceFailureActions->cActions)
480 if (pServiceFailureActions->lpsaActions[0].Type == SC_ACTION_REBOOT)
482 LoadString(hInstance, IDS_SERVICES_YES, szStatus, 128);
483 item.pszText = szStatus;
485 SendMessage(hListView, LVM_SETITEMTEXT, item.iItem, (LPARAM) &item);
489 if (pServiceFailureActions != NULL)
491 HeapFree(GetProcessHeap(), 0, pServiceFailureActions);
492 pServiceFailureActions = NULL;
495 / * get vendor of service binary * /
497 if (!QueryServiceConfig(hService, pServiceConfig, 0, &BytesNeeded))
499 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
501 pServiceConfig = (LPQUERY_SERVICE_CONFIG)
502 HeapAlloc(GetProcessHeap(), 0, BytesNeeded);
503 if (pServiceConfig == NULL)
506 if (!QueryServiceConfig(hService,
511 HeapFree(GetProcessHeap(), 0, pServiceConfig);
515 else / * exit on failure * /
521 memset(&FileName, 0, MAX_PATH);
522 if (_tcscspn(pServiceConfig->lpBinaryPathName, _T("\"")))
524 _tcsncpy(FileName, pServiceConfig->lpBinaryPathName,
525 _tcscspn(pServiceConfig->lpBinaryPathName, _T(" ")) );
529 _tcscpy(FileName, pServiceConfig->lpBinaryPathName);
532 HeapFree(GetProcessHeap(), 0, pServiceConfig);
533 pServiceConfig = NULL;
535 dwLen = GetFileVersionInfoSize(FileName, &dwHandle);
538 lpData = (TCHAR*) HeapAlloc(GetProcessHeap(), 0, dwLen);
542 if (!GetFileVersionInfo (FileName, dwHandle, dwLen, lpData)) {
543 HeapFree(GetProcessHeap(), 0, lpData);
547 if (VerQueryValue(lpData, _T("\\VarFileInfo\\Translation"), &pvData, (PUINT) &BufLen))
549 wCodePage = LOWORD(*(DWORD*) pvData);
550 wLangID = HIWORD(*(DWORD*) pvData);
551 wsprintf(szStrFileInfo, _T("StringFileInfo\\%04X%04X\\CompanyName"), wCodePage, wLangID);
554 if (VerQueryValue (lpData, szStrFileInfo, (LPVOID) &lpBuffer, (PUINT) &BufLen)) {
555 item.pszText = lpBuffer;
557 SendMessage(hListView, LVM_SETITEMTEXT, item.iItem, (LPARAM) &item);
559 HeapFree(GetProcessHeap(), 0, lpData);
563 LoadString(hInstance, IDS_SERVICES_UNKNOWN, szStatus, 128);
564 item.pszText = szStatus;
566 SendMessage(hListView, LVM_SETITEMTEXT, item.iItem, (LPARAM) &item);
568 CloseServiceHandle(hService);
577 HeapFree(GetProcessHeap(), 0, pServiceConfig);
578 pServiceConfig = NULL;
580 dwLen = GetFileVersionInfoSize(FileName, &dwHandle);
583 lpData = (TCHAR*) HeapAlloc(GetProcessHeap(), 0, dwLen);
587 if (!GetFileVersionInfo (FileName, dwHandle, dwLen, lpData)) {
588 HeapFree(GetProcessHeap(), 0, lpData);
592 if (VerQueryValue(lpData, _T("\\VarFileInfo\\Translation"),
593 &pvData, (PUINT) &BufLen))
595 wCodePage = LOWORD(*(DWORD*) pvData);
596 wLangID = HIWORD(*(DWORD*) pvData);
597 wsprintf(szStrFileInfo, _T("StringFileInfo\\%04X%04X\\CompanyName"),
601 if (VerQueryValue (lpData, szStrFileInfo, (LPVOID) &lpBuffer, (PUINT) &BufLen))
603 item.pszText = lpBuffer;
605 SendMessage(hListView, LVM_SETITEMTEXT, item.iItem, (LPARAM) &item);
607 HeapFree(GetProcessHeap(), 0, lpData);
611 LoadString(hInstance, IDS_SERVICES_UNKNOWN, szStatus, 128);
612 item.pszText = szStatus;
614 SendMessage(hListView, LVM_SETITEMTEXT, item.iItem, (LPARAM) &item);