ReactOS 0.4.16-dev-340-g0540c21
query.c
Go to the documentation of this file.
1/*
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>
8 */
9
10#include "sc.h"
11
14{
15 SC_HANDLE hSCManager = NULL;
16 LPSERVICE_STATUS_PROCESS pServiceInfo = NULL;
17 SC_HANDLE hSc = NULL;
18 DWORD BufSiz = 0;
19 DWORD BytesNeeded = 0;
20 DWORD Ret;
21
23 NULL,
25 if (hSCManager == NULL)
26 {
28 return NULL;
29 }
30
34 if (hSc == NULL)
35 goto fail;
36
37 Ret = QueryServiceStatusEx(hSc,
39 NULL,
40 BufSiz,
41 &BytesNeeded);
42 if ((Ret != 0) || (GetLastError() != ERROR_INSUFFICIENT_BUFFER))
43 goto fail;
44
46 0,
47 BytesNeeded);
48 if (pServiceInfo == NULL)
49 goto fail;
50
51 if (!QueryServiceStatusEx(hSc,
53 (LPBYTE)pServiceInfo,
54 BytesNeeded,
55 &BytesNeeded))
56 {
57 goto fail;
58 }
59
62 return pServiceInfo;
63
64fail:
66 if (pServiceInfo) HeapFree(GetProcessHeap(), 0, pServiceInfo);
67 if (hSc) CloseServiceHandle(hSc);
69 return NULL;
70}
71
72
73static
76 DWORD dwServiceType,
77 DWORD dwServiceState,
78 DWORD dwBufferSize,
79 DWORD dwResumeIndex,
80 LPCTSTR pszGroupName)
81{
82 SC_HANDLE hSCManager;
83 DWORD BytesNeeded = 0;
84 DWORD ResumeHandle = dwResumeIndex;
85 DWORD NumServices = 0;
86 BOOL Ret;
87
89 NULL,
91 if (hSCManager == NULL)
92 {
94 return 0;
95 }
96
97 if (dwBufferSize == 0)
98 {
101 dwServiceType,
102 dwServiceState,
103 (LPBYTE)*pServiceStatus,
104 dwBufferSize,
105 &BytesNeeded,
106 &NumServices,
107 &ResumeHandle,
108 pszGroupName);
109 if ((Ret == 0) && (GetLastError() != ERROR_MORE_DATA))
110 {
112 return 0;
113 }
114
115 dwBufferSize = BytesNeeded;
116 }
117
118 *pServiceStatus = (ENUM_SERVICE_STATUS_PROCESS *)
120 0,
121 dwBufferSize);
122 if (*pServiceStatus != NULL)
123 {
126 dwServiceType,
127 dwServiceState,
128 (LPBYTE)*pServiceStatus,
129 dwBufferSize,
130 &BytesNeeded,
131 &NumServices,
132 &ResumeHandle,
133 pszGroupName))
134 {
136 return NumServices;
137 }
138 }
139
141 if (*pServiceStatus)
142 HeapFree(GetProcessHeap(), 0, *pServiceStatus);
143
145
146 return NumServices;
147}
148
149
150static
151BOOL
153 IN LPCTSTR *ServiceArgs,
154 IN INT ArgCount,
155 OUT PDWORD pdwServiceType,
156 OUT PDWORD pdwServiceState,
157 OUT PDWORD pdwBufferSize,
158 OUT PDWORD pdwResumeIndex,
159 OUT LPCTSTR *ppszGroupName,
160 OUT LPCTSTR *ppszServiceName)
161{
162 INT TmpCount, TmpIndex;
163 DWORD dwValue;
164
165 TmpCount = ArgCount;
166 TmpIndex = 0;
167 while (TmpCount > 0)
168 {
169 if (!lstrcmpi(ServiceArgs[TmpIndex], _T("type=")))
170 {
171 TmpIndex++;
172 TmpCount--;
173
174 if (TmpCount > 0)
175 {
176 if (!lstrcmpi(ServiceArgs[TmpIndex], _T("service")))
177 {
178 *pdwServiceType = SERVICE_WIN32;
179 }
180 else if (!lstrcmpi(ServiceArgs[TmpIndex], _T("driver")))
181 {
182 *pdwServiceType = SERVICE_DRIVER;
183 }
184 else if (!lstrcmpi(ServiceArgs[TmpIndex], _T("all")))
185 {
186 *pdwServiceType = SERVICE_TYPE_ALL;
187 }
188 else if (!lstrcmpi(ServiceArgs[TmpIndex], _T("interact")))
189 {
190 *pdwServiceType |= SERVICE_INTERACTIVE_PROCESS;
191 }
192 else
193 {
194 _tprintf(_T("ERROR following \"type=\"!\nMust be one of: all, driver, interact, service.\n"));
195 return FALSE;
196 }
197
198 TmpIndex++;
199 TmpCount--;
200 }
201 }
202 else if (!lstrcmpi(ServiceArgs[TmpIndex], _T("state=")))
203 {
204 TmpIndex++;
205 TmpCount--;
206
207 if (TmpCount > 0)
208 {
209 if (!lstrcmpi(ServiceArgs[TmpIndex], _T("active")))
210 {
211 *pdwServiceState = SERVICE_ACTIVE;
212 }
213 else if (!lstrcmpi(ServiceArgs[TmpIndex], _T("inactive")))
214 {
215 *pdwServiceState = SERVICE_INACTIVE;
216 }
217 else if (!lstrcmpi(ServiceArgs[TmpIndex], _T("all")))
218 {
219 *pdwServiceState = SERVICE_STATE_ALL;
220 }
221 else
222 {
223 _tprintf(_T("ERROR following \"state=\"!\nMust be one of: active, all, inactive.\n"));
224 return FALSE;
225 }
226
227 TmpIndex++;
228 TmpCount--;
229 }
230 }
231 else if (!lstrcmpi(ServiceArgs[TmpIndex], _T("bufsize=")))
232 {
233 TmpIndex++;
234 TmpCount--;
235
236 if (TmpCount > 0)
237 {
238 dwValue = _tcstoul(ServiceArgs[TmpIndex], NULL, 10);
239 if (dwValue > 0)
240 {
241 *pdwBufferSize = dwValue;
242 }
243
244 TmpIndex++;
245 TmpCount--;
246 }
247 }
248 else if (!lstrcmpi(ServiceArgs[TmpIndex], _T("ri=")))
249 {
250 TmpIndex++;
251 TmpCount--;
252
253 if (TmpCount >= 0)
254 {
255 dwValue = _tcstoul(ServiceArgs[TmpIndex], NULL, 10);
256 if (dwValue > 0)
257 {
258 *pdwResumeIndex = dwValue;
259 }
260
261 TmpIndex++;
262 TmpCount--;
263 }
264 }
265 else if (!lstrcmpi(ServiceArgs[TmpIndex], _T("group=")))
266 {
267 TmpIndex++;
268 TmpCount--;
269
270 if (TmpCount > 0)
271 {
272 *ppszGroupName = ServiceArgs[TmpIndex];
273
274 TmpIndex++;
275 TmpCount--;
276 }
277 }
278 else
279 {
280 *ppszServiceName = ServiceArgs[TmpIndex];
281
282 TmpIndex++;
283 TmpCount--;
284 }
285 }
286
287 return TRUE;
288}
289
290
291BOOL
292Query(LPCTSTR *ServiceArgs,
293 DWORD ArgCount,
294 BOOL bExtended)
295{
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;
304 DWORD i;
305
306#ifdef SCDBG
307 LPCTSTR *TmpArgs = ServiceArgs;
308 INT TmpCnt = ArgCount;
309
310 _tprintf(_T("Arguments:\n"));
311 while (TmpCnt)
312 {
313 _tprintf(_T(" %s\n"), *TmpArgs);
314 TmpArgs++;
315 TmpCnt--;
316 }
317 _tprintf(_T("\n"));
318#endif /* SCDBG */
319
320 /* Parse arguments */
321 if (!ParseQueryArguments(ServiceArgs,
322 ArgCount,
323 &dwServiceType,
324 &dwServiceState,
325 &dwBufferSize,
326 &dwResumeIndex,
327 &pszGroupName,
328 &pszServiceName))
329 return FALSE;
330
331#ifdef SCDBG
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);
338#endif
339
340 if (pszServiceName)
341 {
342 /* Print only the requested service */
343
345
346 pStatus = QueryService(pszServiceName);
347 if (pStatus)
348 {
349 PrintService(pszServiceName,
350 NULL,
351 pStatus,
352 bExtended);
353
355 }
356 }
357 else
358 {
359 /* Print all matching services */
360
361 NumServices = EnumServices(&pServiceStatus,
362 dwServiceType,
363 dwServiceState,
364 dwBufferSize,
365 dwResumeIndex,
366 pszGroupName);
367 if (NumServices == 0)
368 return FALSE;
369
370 for (i = 0; i < NumServices; i++)
371 {
372 PrintService(pServiceStatus[i].lpServiceName,
373 pServiceStatus[i].lpDisplayName,
374 &pServiceStatus[i].ServiceStatusProcess,
375 bExtended);
376 }
377
378#ifdef SCDBG
379 _tprintf(_T("number : %lu\n"), NumServices);
380#endif
381
382 if (pServiceStatus)
383 HeapFree(GetProcessHeap(), 0, pServiceStatus);
384 }
385
386 return TRUE;
387}
VOID PrintService(LPCTSTR lpServiceName, LPCTSTR lpDisplayName, LPSERVICE_STATUS_PROCESS pStatus, BOOL bExtended)
Definition: print.c:13
BOOL Query(LPCTSTR *ServiceArgs, DWORD ArgCount, BOOL bExtended)
Definition: query.c:292
LPSERVICE_STATUS_PROCESS QueryService(LPCTSTR ServiceName)
Definition: query.c:13
static BOOL ParseQueryArguments(IN LPCTSTR *ServiceArgs, IN INT ArgCount, OUT PDWORD pdwServiceType, OUT PDWORD pdwServiceState, OUT PDWORD pdwBufferSize, OUT PDWORD pdwResumeIndex, OUT LPCTSTR *ppszGroupName, OUT LPCTSTR *ppszServiceName)
Definition: query.c:152
static DWORD EnumServices(ENUM_SERVICE_STATUS_PROCESS **pServiceStatus, DWORD dwServiceType, DWORD dwServiceState, DWORD dwBufferSize, DWORD dwResumeIndex, LPCTSTR pszGroupName)
Definition: query.c:75
static WCHAR ServiceName[]
Definition: browser.c:19
#define ERROR_MORE_DATA
Definition: dderror.h:13
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define GetProcessHeap()
Definition: compat.h:736
#define HeapAlloc
Definition: compat.h:733
#define HeapFree(x, y, z)
Definition: compat.h:735
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
__in WDFDMATRANSACTION __out NTSTATUS * pStatus
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define _tcstoul
Definition: tchar.h:595
#define _tprintf
Definition: tchar.h:506
DWORD ReportLastError(void)
Definition: loadlib.c:67
DWORD * PDWORD
Definition: pedump.c:68
SC_HANDLE hSCManager
Definition: sc.c:12
BOOL WINAPI QueryServiceStatusEx(SC_HANDLE hService, SC_STATUS_TYPE InfoLevel, LPBYTE lpBuffer, DWORD cbBufSize, LPDWORD pcbBytesNeeded)
Definition: scm.c:2887
BOOL WINAPI CloseServiceHandle(SC_HANDLE hSCObject)
Definition: scm.c:580
unsigned char * LPBYTE
Definition: typedefs.h:53
int32_t INT
Definition: typedefs.h:58
#define IN
Definition: typedefs.h:39
#define OUT
Definition: typedefs.h:40
#define _T(x)
Definition: vfdio.h:22
_In_ LPCSTR _Out_writes_to_opt_ cchDisplayName LPSTR lpDisplayName
Definition: winbase.h:2815
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define lstrcmpi
Definition: winbase.h:3898
#define SERVICE_STATE_ALL
Definition: winsvc.h:52
#define SERVICE_QUERY_STATUS
Definition: winsvc.h:55
#define OpenSCManager
Definition: winsvc.h:575
@ SC_STATUS_PROCESS_INFO
Definition: winsvc.h:119
#define SERVICE_ACTIVE
Definition: winsvc.h:50
#define SC_MANAGER_ENUMERATE_SERVICE
Definition: winsvc.h:16
#define SC_MANAGER_CONNECT
Definition: winsvc.h:14
#define EnumServicesStatusEx
Definition: winsvc.h:572
struct _SERVICE_STATUS_PROCESS * LPSERVICE_STATUS_PROCESS
#define SERVICE_INACTIVE
Definition: winsvc.h:51
@ SC_ENUM_PROCESS_INFO
Definition: winsvc.h:122
#define OpenService
Definition: winsvc.h:576
#define SERVICE_TYPE_ALL
Definition: cmtypes.h:969
#define SERVICE_INTERACTIVE_PROCESS
Definition: cmtypes.h:967
#define SERVICE_DRIVER
Definition: cmtypes.h:958
#define SERVICE_WIN32
Definition: cmtypes.h:964
const CHAR * LPCTSTR
Definition: xmlstorage.h:193