Something went wrong. Try again.
Reactos
Something went wrong. Try again.
11 kB · 387 lines
C
at master
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388/* * PROJECT: ReactOS Services * LICENSE: GPL - See COPYING in the top level directory * FILE: base/applications/sc/query.c * PURPOSE: queries service info * COPYRIGHT: Copyright 2005 - 2006 Ged Murphy <gedmurphy@gmail.com> * Copyright 2018 Eric Kohl <eric.kohl@reactos.org> */
#include "sc.h"
LPSERVICE_STATUS_PROCESSQueryService(LPCTSTR ServiceName){ SC_HANDLE hSCManager = NULL; LPSERVICE_STATUS_PROCESS pServiceInfo = NULL; SC_HANDLE hSc = NULL; DWORD BufSiz = 0; DWORD BytesNeeded = 0; DWORD Ret;
hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT); if (hSCManager == NULL) { ReportLastError(); return NULL; }
hSc = OpenService(hSCManager, ServiceName, SERVICE_QUERY_STATUS); if (hSc == NULL) goto fail;
Ret = QueryServiceStatusEx(hSc, SC_STATUS_PROCESS_INFO, NULL, BufSiz, &BytesNeeded); if ((Ret != 0) || (GetLastError() != ERROR_INSUFFICIENT_BUFFER)) goto fail;
pServiceInfo = (LPSERVICE_STATUS_PROCESS)HeapAlloc(GetProcessHeap(), 0, BytesNeeded); if (pServiceInfo == NULL) goto fail;
if (!QueryServiceStatusEx(hSc, SC_STATUS_PROCESS_INFO, (LPBYTE)pServiceInfo, BytesNeeded, &BytesNeeded)) { goto fail; }
CloseServiceHandle(hSc); CloseServiceHandle(hSCManager); return pServiceInfo;
fail: ReportLastError(); if (pServiceInfo) HeapFree(GetProcessHeap(), 0, pServiceInfo); if (hSc) CloseServiceHandle(hSc); if (hSCManager) CloseServiceHandle(hSCManager); return NULL;}
staticDWORDEnumServices(ENUM_SERVICE_STATUS_PROCESS **pServiceStatus, DWORD dwServiceType, DWORD dwServiceState, DWORD dwBufferSize, DWORD dwResumeIndex, LPCTSTR pszGroupName){ SC_HANDLE hSCManager; DWORD BytesNeeded = 0; DWORD ResumeHandle = dwResumeIndex; DWORD NumServices = 0; BOOL Ret;
hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE); if (hSCManager == NULL) { ReportLastError(); return 0; }
if (dwBufferSize == 0) { Ret = EnumServicesStatusEx(hSCManager, SC_ENUM_PROCESS_INFO, dwServiceType, dwServiceState, (LPBYTE)*pServiceStatus, dwBufferSize, &BytesNeeded, &NumServices, &ResumeHandle, pszGroupName); if ((Ret == 0) && (GetLastError() != ERROR_MORE_DATA)) { ReportLastError(); return 0; }
dwBufferSize = BytesNeeded; }
*pServiceStatus = (ENUM_SERVICE_STATUS_PROCESS *) HeapAlloc(GetProcessHeap(), 0, dwBufferSize); if (*pServiceStatus != NULL) { if (EnumServicesStatusEx(hSCManager, SC_ENUM_PROCESS_INFO, dwServiceType, dwServiceState, (LPBYTE)*pServiceStatus, dwBufferSize, &BytesNeeded, &NumServices, &ResumeHandle, pszGroupName)) { CloseServiceHandle(hSCManager); return NumServices; } }
ReportLastError(); if (*pServiceStatus) HeapFree(GetProcessHeap(), 0, *pServiceStatus);
CloseServiceHandle(hSCManager);
return NumServices;}
staticBOOLParseQueryArguments( IN LPCTSTR *ServiceArgs, IN INT ArgCount, OUT PDWORD pdwServiceType, OUT PDWORD pdwServiceState, OUT PDWORD pdwBufferSize, OUT PDWORD pdwResumeIndex, OUT LPCTSTR *ppszGroupName, OUT LPCTSTR *ppszServiceName){ INT TmpCount, TmpIndex; DWORD dwValue;
TmpCount = ArgCount; TmpIndex = 0; while (TmpCount > 0) { if (!lstrcmpi(ServiceArgs[TmpIndex], _T("type="))) { TmpIndex++; TmpCount--;
if (TmpCount > 0) { if (!lstrcmpi(ServiceArgs[TmpIndex], _T("service"))) { *pdwServiceType = SERVICE_WIN32; } else if (!lstrcmpi(ServiceArgs[TmpIndex], _T("driver"))) { *pdwServiceType = SERVICE_DRIVER; } else if (!lstrcmpi(ServiceArgs[TmpIndex], _T("all"))) { *pdwServiceType = SERVICE_TYPE_ALL; } else if (!lstrcmpi(ServiceArgs[TmpIndex], _T("interact"))) { *pdwServiceType |= SERVICE_INTERACTIVE_PROCESS; } else { _tprintf(_T("ERROR following \"type=\"!\nMust be one of: all, driver, interact, service.\n")); return FALSE; }
TmpIndex++; TmpCount--; } } else if (!lstrcmpi(ServiceArgs[TmpIndex], _T("state="))) { TmpIndex++; TmpCount--;
if (TmpCount > 0) { if (!lstrcmpi(ServiceArgs[TmpIndex], _T("active"))) { *pdwServiceState = SERVICE_ACTIVE; } else if (!lstrcmpi(ServiceArgs[TmpIndex], _T("inactive"))) { *pdwServiceState = SERVICE_INACTIVE; } else if (!lstrcmpi(ServiceArgs[TmpIndex], _T("all"))) { *pdwServiceState = SERVICE_STATE_ALL; } else { _tprintf(_T("ERROR following \"state=\"!\nMust be one of: active, all, inactive.\n")); return FALSE; }
TmpIndex++; TmpCount--; } } else if (!lstrcmpi(ServiceArgs[TmpIndex], _T("bufsize="))) { TmpIndex++; TmpCount--;
if (TmpCount > 0) { dwValue = _tcstoul(ServiceArgs[TmpIndex], NULL, 10); if (dwValue > 0) { *pdwBufferSize = dwValue; }
TmpIndex++; TmpCount--; } } else if (!lstrcmpi(ServiceArgs[TmpIndex], _T("ri="))) { TmpIndex++; TmpCount--;
if (TmpCount >= 0) { dwValue = _tcstoul(ServiceArgs[TmpIndex], NULL, 10); if (dwValue > 0) { *pdwResumeIndex = dwValue; }
TmpIndex++; TmpCount--; } } else if (!lstrcmpi(ServiceArgs[TmpIndex], _T("group="))) { TmpIndex++; TmpCount--;
if (TmpCount > 0) { *ppszGroupName = ServiceArgs[TmpIndex];
TmpIndex++; TmpCount--; } } else { *ppszServiceName = ServiceArgs[TmpIndex];
TmpIndex++; TmpCount--; } }
return TRUE;}
BOOLQuery(LPCTSTR *ServiceArgs, DWORD ArgCount, BOOL bExtended){ LPENUM_SERVICE_STATUS_PROCESS pServiceStatus = NULL; DWORD NumServices = 0; DWORD dwServiceType = SERVICE_WIN32; DWORD dwServiceState = SERVICE_ACTIVE; DWORD dwBufferSize = 0; DWORD dwResumeIndex = 0; LPCTSTR pszGroupName = NULL; LPCTSTR pszServiceName = NULL; DWORD i;
#ifdef SCDBG LPCTSTR *TmpArgs = ServiceArgs; INT TmpCnt = ArgCount;
_tprintf(_T("Arguments:\n")); while (TmpCnt) { _tprintf(_T(" %s\n"), *TmpArgs); TmpArgs++; TmpCnt--; } _tprintf(_T("\n"));#endif /* SCDBG */
/* Parse arguments */ if (!ParseQueryArguments(ServiceArgs, ArgCount, &dwServiceType, &dwServiceState, &dwBufferSize, &dwResumeIndex, &pszGroupName, &pszServiceName)) return FALSE;
#ifdef SCDBG _tprintf(_T("Service type: %lx\n"), dwServiceType); _tprintf(_T("Service state: %lx\n"), dwServiceState); _tprintf(_T("Buffer size: %lu\n"), dwBufferSize); _tprintf(_T("Resume index: %lu\n"), dwResumeIndex); _tprintf(_T("Group name: %s\n"), pszGroupName); _tprintf(_T("Service name: %s\n"), pszServiceName);#endif
if (pszServiceName) { /* Print only the requested service */
LPSERVICE_STATUS_PROCESS pStatus;
pStatus = QueryService(pszServiceName); if (pStatus) { PrintService(pszServiceName, NULL, pStatus, bExtended);
HeapFree(GetProcessHeap(), 0, pStatus); } } else { /* Print all matching services */
NumServices = EnumServices(&pServiceStatus, dwServiceType, dwServiceState, dwBufferSize, dwResumeIndex, pszGroupName); if (NumServices == 0) return FALSE;
for (i = 0; i < NumServices; i++) { PrintService(pServiceStatus[i].lpServiceName, pServiceStatus[i].lpDisplayName, &pServiceStatus[i].ServiceStatusProcess, bExtended); }
#ifdef SCDBG _tprintf(_T("number : %lu\n"), NumServices);#endif
if (pServiceStatus) HeapFree(GetProcessHeap(), 0, pServiceStatus); }
return TRUE;}