ReactOS  0.4.13-dev-39-g8b6696f
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 
31  hSc = OpenService(hSCManager,
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 
60  CloseServiceHandle(hSc);
62  return pServiceInfo;
63 
64 fail:
66  if (pServiceInfo) HeapFree(GetProcessHeap(), 0, pServiceInfo);
67  if (hSc) CloseServiceHandle(hSc);
69  return NULL;
70 }
71 
72 
73 static
74 DWORD
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  {
111  ReportLastError();
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 
140  ReportLastError();
141  if (*pServiceStatus)
142  HeapFree(GetProcessHeap(), 0, *pServiceStatus);
143 
145 
146  return NumServices;
147 }
148 
149 
150 static
151 BOOL
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 
291 BOOL
292 Query(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 
344  LPSERVICE_STATUS_PROCESS pStatus;
345 
346  pStatus = QueryService(pszServiceName);
347  if (pStatus)
348  {
349  PrintService(pszServiceName,
350  NULL,
351  pStatus,
352  bExtended);
353 
354  HeapFree(GetProcessHeap(), 0, pStatus);
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 }
#define IN
Definition: typedefs.h:38
#define SC_MANAGER_ENUMERATE_SERVICE
Definition: winsvc.h:16
#define _tprintf
Definition: tchar.h:506
#define TRUE
Definition: types.h:120
const CHAR * LPCTSTR
Definition: xmlstorage.h:193
#define lstrcmpi
Definition: winbase.h:3687
#define SC_MANAGER_CONNECT
Definition: winsvc.h:14
#define SERVICE_INACTIVE
Definition: winsvc.h:51
#define SERVICE_INTERACTIVE_PROCESS
Definition: cmtypes.h:965
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
#define SERVICE_STATE_ALL
Definition: winsvc.h:52
BOOL WINAPI QueryServiceStatusEx(SC_HANDLE hService, SC_STATUS_TYPE InfoLevel, LPBYTE lpBuffer, DWORD cbBufSize, LPDWORD pcbBytesNeeded)
Definition: scm.c:2830
int32_t INT
Definition: typedefs.h:56
#define OpenService
Definition: winsvc.h:576
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
unsigned char * LPBYTE
Definition: typedefs.h:52
unsigned int BOOL
Definition: ntddk_ex.h:94
BOOL WINAPI CloseServiceHandle(SC_HANDLE hSCObject)
Definition: scm.c:577
smooth NULL
Definition: ftsmooth.c:416
#define SERVICE_QUERY_STATUS
Definition: winsvc.h:55
#define SERVICE_TYPE_ALL
Definition: cmtypes.h:967
#define OpenSCManager
Definition: winsvc.h:575
#define _T(x)
Definition: vfdio.h:22
LPTSTR ServiceName
Definition: ServiceMain.c:15
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
#define SERVICE_ACTIVE
Definition: winsvc.h:50
unsigned long DWORD
Definition: ntddk_ex.h:95
BOOL Query(LPCTSTR *ServiceArgs, DWORD ArgCount, BOOL bExtended)
Definition: query.c:292
static DWORD EnumServices(ENUM_SERVICE_STATUS_PROCESS **pServiceStatus, DWORD dwServiceType, DWORD dwServiceState, DWORD dwBufferSize, DWORD dwResumeIndex, LPCTSTR pszGroupName)
Definition: query.c:75
#define _tcstoul
Definition: tchar.h:595
SC_HANDLE hSCManager
Definition: sc.c:12
#define ERROR_MORE_DATA
Definition: dderror.h: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
VOID ReportLastError(VOID)
Definition: sc.c:15
#define SERVICE_WIN32
Definition: cmtypes.h:962
DWORD * PDWORD
Definition: pedump.c:68
#define EnumServicesStatusEx
Definition: winsvc.h:572
struct _SERVICE_STATUS_PROCESS * LPSERVICE_STATUS_PROCESS
#define OUT
Definition: typedefs.h:39
LPSERVICE_STATUS_PROCESS QueryService(LPCTSTR ServiceName)
Definition: query.c:13
#define SERVICE_DRIVER
Definition: cmtypes.h:956
_In_ LPCSTR _Out_writes_to_opt_ cchDisplayName LPSTR lpDisplayName
Definition: winbase.h:2730
#define HeapFree(x, y, z)
Definition: compat.h:394
VOID PrintService(LPCTSTR lpServiceName, LPCTSTR lpDisplayName, LPSERVICE_STATUS_PROCESS pStatus, BOOL bExtended)
Definition: print.c:13
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10