2 * PROJECT: ReactOS Services
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: base/applications/sc/query.c
5 * PURPOSE: queries service info
6 * COPYRIGHT: Copyright 2005 - 2006 Ged Murphy <gedmurphy@gmail.com>
7 * Copyright 2018 Eric Kohl <eric.kohl@reactos.org>
12 LPSERVICE_STATUS_PROCESS
13 QueryService(LPCTSTR ServiceName
)
15 SC_HANDLE hSCManager
= NULL
;
16 LPSERVICE_STATUS_PROCESS pServiceInfo
= NULL
;
19 DWORD BytesNeeded
= 0;
22 hSCManager
= OpenSCManager(NULL
,
25 if (hSCManager
== NULL
)
31 hSc
= OpenService(hSCManager
,
33 SERVICE_QUERY_STATUS
);
37 Ret
= QueryServiceStatusEx(hSc
,
38 SC_STATUS_PROCESS_INFO
,
42 if ((Ret
!= 0) || (GetLastError() != ERROR_INSUFFICIENT_BUFFER
))
45 pServiceInfo
= (LPSERVICE_STATUS_PROCESS
)HeapAlloc(GetProcessHeap(),
48 if (pServiceInfo
== NULL
)
51 if (!QueryServiceStatusEx(hSc
,
52 SC_STATUS_PROCESS_INFO
,
60 CloseServiceHandle(hSc
);
61 CloseServiceHandle(hSCManager
);
66 if (pServiceInfo
) HeapFree(GetProcessHeap(), 0, pServiceInfo
);
67 if (hSc
) CloseServiceHandle(hSc
);
68 if (hSCManager
) CloseServiceHandle(hSCManager
);
75 EnumServices(ENUM_SERVICE_STATUS_PROCESS
**pServiceStatus
,
83 DWORD BytesNeeded
= 0;
84 DWORD ResumeHandle
= dwResumeIndex
;
85 DWORD NumServices
= 0;
88 hSCManager
= OpenSCManager(NULL
,
90 SC_MANAGER_ENUMERATE_SERVICE
);
91 if (hSCManager
== NULL
)
97 if (dwBufferSize
== 0)
99 Ret
= EnumServicesStatusEx(hSCManager
,
100 SC_ENUM_PROCESS_INFO
,
103 (LPBYTE
)*pServiceStatus
,
109 if ((Ret
== 0) && (GetLastError() != ERROR_MORE_DATA
))
115 dwBufferSize
= BytesNeeded
;
118 *pServiceStatus
= (ENUM_SERVICE_STATUS_PROCESS
*)
119 HeapAlloc(GetProcessHeap(),
122 if (*pServiceStatus
!= NULL
)
124 if (EnumServicesStatusEx(hSCManager
,
125 SC_ENUM_PROCESS_INFO
,
128 (LPBYTE
)*pServiceStatus
,
135 CloseServiceHandle(hSCManager
);
142 HeapFree(GetProcessHeap(), 0, *pServiceStatus
);
144 CloseServiceHandle(hSCManager
);
153 IN LPCTSTR
*ServiceArgs
,
155 OUT PDWORD pdwServiceType
,
156 OUT PDWORD pdwServiceState
,
157 OUT PDWORD pdwBufferSize
,
158 OUT PDWORD pdwResumeIndex
,
159 OUT LPCTSTR
*ppszGroupName
,
160 OUT LPCTSTR
*ppszServiceName
)
162 INT TmpCount
, TmpIndex
;
169 if (!lstrcmpi(ServiceArgs
[TmpIndex
], _T("type=")))
176 if (!lstrcmpi(ServiceArgs
[TmpIndex
], _T("service")))
178 *pdwServiceType
= SERVICE_WIN32
;
180 else if (!lstrcmpi(ServiceArgs
[TmpIndex
], _T("driver")))
182 *pdwServiceType
= SERVICE_DRIVER
;
184 else if (!lstrcmpi(ServiceArgs
[TmpIndex
], _T("all")))
186 *pdwServiceType
= SERVICE_TYPE_ALL
;
188 else if (!lstrcmpi(ServiceArgs
[TmpIndex
], _T("interact")))
190 *pdwServiceType
|= SERVICE_INTERACTIVE_PROCESS
;
194 _tprintf(_T("ERROR following \"type=\"!\nMust be one of: all, driver, interact, service.\n"));
202 else if (!lstrcmpi(ServiceArgs
[TmpIndex
], _T("state=")))
209 if (!lstrcmpi(ServiceArgs
[TmpIndex
], _T("active")))
211 *pdwServiceState
= SERVICE_ACTIVE
;
213 else if (!lstrcmpi(ServiceArgs
[TmpIndex
], _T("inactive")))
215 *pdwServiceState
= SERVICE_INACTIVE
;
217 else if (!lstrcmpi(ServiceArgs
[TmpIndex
], _T("all")))
219 *pdwServiceState
= SERVICE_STATE_ALL
;
223 _tprintf(_T("ERROR following \"state=\"!\nMust be one of: active, all, inactive.\n"));
231 else if (!lstrcmpi(ServiceArgs
[TmpIndex
], _T("bufsize=")))
238 dwValue
= _tcstoul(ServiceArgs
[TmpIndex
], NULL
, 10);
241 *pdwBufferSize
= dwValue
;
248 else if (!lstrcmpi(ServiceArgs
[TmpIndex
], _T("ri=")))
255 dwValue
= _tcstoul(ServiceArgs
[TmpIndex
], NULL
, 10);
258 *pdwResumeIndex
= dwValue
;
265 else if (!lstrcmpi(ServiceArgs
[TmpIndex
], _T("group=")))
272 *ppszGroupName
= ServiceArgs
[TmpIndex
];
280 *ppszServiceName
= ServiceArgs
[TmpIndex
];
292 Query(LPCTSTR
*ServiceArgs
,
296 LPENUM_SERVICE_STATUS_PROCESS pServiceStatus
= NULL
;
297 DWORD NumServices
= 0;
298 DWORD dwServiceType
= SERVICE_WIN32
;
299 DWORD dwServiceState
= SERVICE_ACTIVE
;
300 DWORD dwBufferSize
= 0;
301 DWORD dwResumeIndex
= 0;
302 LPCTSTR pszGroupName
= NULL
;
303 LPCTSTR pszServiceName
= NULL
;
307 LPCTSTR
*TmpArgs
= ServiceArgs
;
308 INT TmpCnt
= ArgCount
;
310 _tprintf(_T("Arguments:\n"));
313 _tprintf(_T(" %s\n"), *TmpArgs
);
320 /* Parse arguments */
321 if (!ParseQueryArguments(ServiceArgs
,
332 _tprintf(_T("Service type: %lx\n"), dwServiceType
);
333 _tprintf(_T("Service state: %lx\n"), dwServiceState
);
334 _tprintf(_T("Buffer size: %lu\n"), dwBufferSize
);
335 _tprintf(_T("Resume index: %lu\n"), dwResumeIndex
);
336 _tprintf(_T("Group name: %s\n"), pszGroupName
);
337 _tprintf(_T("Service name: %s\n"), pszServiceName
);
342 /* Print only the requested service */
344 LPSERVICE_STATUS_PROCESS pStatus
;
346 pStatus
= QueryService(pszServiceName
);
349 PrintService(pszServiceName
,
354 HeapFree(GetProcessHeap(), 0, pStatus
);
359 /* Print all matching services */
361 NumServices
= EnumServices(&pServiceStatus
,
367 if (NumServices
== 0)
370 for (i
= 0; i
< NumServices
; i
++)
372 PrintService(pServiceStatus
[i
].lpServiceName
,
373 pServiceStatus
[i
].lpDisplayName
,
374 &pServiceStatus
[i
].ServiceStatusProcess
,
379 _tprintf(_T("number : %lu\n"), NumServices
);
383 HeapFree(GetProcessHeap(), 0, pServiceStatus
);