2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS SC utility
4 * FILE: subsys/system/sc/query.c
5 * PURPOSE: control ReactOS services
6 * PROGRAMMERS: Ged Murphy (gedmurphy@gmail.com)
8 * Ged Murphy 20/10/05 Created
13 * Allow calling of 2 options e.g.:
14 * type= driver state= inactive
19 /* local function decs */
20 VOID
PrintService(BOOL bExtended
);
21 BOOL
EnumServices(LPCTSTR ServiceName
, DWORD ServiceType
, DWORD ServiceState
);
22 BOOL
QueryService(LPCTSTR ServiceName
, BOOL bExtended
);
24 /* global variables */
25 static ENUM_SERVICE_STATUS_PROCESS
*pServiceStatus
= NULL
;
26 DWORD NumServices
= 0;
30 Query(LPCTSTR ServiceName
, LPCTSTR
*ServiceArgs
, BOOL bExtended
)
33 if (! ServiceName
) /* display all running services and drivers */
35 /* get default values */
36 EnumServices(NULL
, SERVICE_WIN32
, SERVICE_ACTIVE
);
38 /* print default values */
39 PrintService(bExtended
);
41 else if (_tcsicmp(ServiceName
, _T("type=")) == 0)
43 LPCTSTR Type
= *ServiceArgs
;
45 if (_tcsicmp(Type
, _T("driver")) == 0)
46 EnumServices(NULL
, SERVICE_DRIVER
, SERVICE_ACTIVE
);
47 else if (_tcsicmp(Type
, _T("service")) == 0)
48 EnumServices(NULL
, SERVICE_WIN32
, SERVICE_ACTIVE
);
49 else if (_tcsicmp(Type
, _T("all")) == 0)
50 EnumServices(NULL
, SERVICE_DRIVER
|SERVICE_WIN32
, SERVICE_ACTIVE
);
53 _tprintf(_T("\nERROR following \"type=\"!\n"));
54 _tprintf(_T("Must be \"driver\" or \"service\" or \"all\"\n"));
57 PrintService(bExtended
);
59 else if(_tcsicmp(ServiceName
, _T("state=")) == 0)
61 LPCTSTR State
= *ServiceArgs
;
63 if (_tcsicmp(State
, _T("inactive")) == 0)
64 EnumServices(NULL
, SERVICE_WIN32
, SERVICE_INACTIVE
);
65 else if (_tcsicmp(State
, _T("all")) == 0)
66 EnumServices(NULL
, SERVICE_WIN32
, SERVICE_STATE_ALL
);
69 _tprintf(_T("\nERROR following \"state=\"!\n"));
70 _tprintf(_T("Must be \"active\" or \"inactive\" or \"all\"\n"));
73 PrintService(bExtended
);
76 else if(_tcsicmp(ServiceName, _T("bufsize=")))
78 else if(_tcsicmp(ServiceName, _T("ri=")))
80 else if(_tcsicmp(ServiceName, _T("group=")))
82 else /* print only the service requested */
84 QueryService(ServiceName
, bExtended
);
92 QueryService(LPCTSTR ServiceName
, BOOL bExtended
)
94 SERVICE_STATUS_PROCESS
*pServiceInfo
= NULL
;
97 DWORD BytesNeeded
= 0;
100 hSc
= OpenService(hSCManager
, ServiceName
, SERVICE_QUERY_STATUS
);
104 _tprintf(_T("QueryService: openService failed\n"));
109 Ret
= QueryServiceStatusEx(hSc
,
110 SC_STATUS_PROCESS_INFO
,
115 if ((Ret
!= 0) || (GetLastError() != ERROR_INSUFFICIENT_BUFFER
))
117 _tprintf(_T("QueryService: First call to QueryServiceStatusEx failed : "));
121 else /* Call function again if required size was returned */
123 /* reserve memory for service info array */
124 pServiceInfo
= (SERVICE_STATUS_PROCESS
*)
125 HeapAlloc(GetProcessHeap(), 0, BytesNeeded
);
126 if (pServiceInfo
== NULL
)
128 _tprintf(_T("QueryService: Failed to allocate memory : "));
133 /* fill array with service info */
134 if (! QueryServiceStatusEx(hSc
,
135 SC_STATUS_PROCESS_INFO
,
136 (LPBYTE
)pServiceInfo
,
140 _tprintf(_T("QueryService: Second call to QueryServiceStatusEx failed : "));
142 HeapFree(GetProcessHeap(), 0, pServiceInfo
);
148 _tprintf(_T("SERVICE_NAME: %s\n"), ServiceName
);
150 _tprintf(_T("\tTYPE : %x "),
151 (unsigned int)pServiceInfo
->dwServiceType
);
152 switch (pServiceInfo
->dwServiceType
)
154 case 1 : _tprintf(_T("KERNEL_DRIVER\n")); break;
155 case 2 : _tprintf(_T("FILE_SYSTEM_DRIVER\n")); break;
156 case 16 : _tprintf(_T("WIN32_OWN_PROCESS\n")); break;
157 case 32 : _tprintf(_T("WIN32_SHARE_PROCESS\n")); break;
158 default : _tprintf(_T("\n")); break;
161 _tprintf(_T("\tSTATE : %x "),
162 (unsigned int)pServiceInfo
->dwCurrentState
);
164 switch (pServiceInfo
->dwCurrentState
)
166 case 1 : _tprintf(_T("STOPPED\n")); break;
167 case 2 : _tprintf(_T("START_PENDING\n")); break;
168 case 3 : _tprintf(_T("STOP_PENDING\n")); break;
169 case 4 : _tprintf(_T("RUNNING\n")); break;
170 case 5 : _tprintf(_T("CONTINUE_PENDING\n")); break;
171 case 6 : _tprintf(_T("PAUSE_PENDING\n")); break;
172 case 7 : _tprintf(_T("PAUSED\n")); break;
173 default : _tprintf(_T("\n")); break;
176 // _tprintf(_T("\n\taccepted : 0x%x\n\n"),
177 // pServiceStatus[i].ServiceStatusProcess.dwControlsAccepted);
178 // (STOPPABLE,NOT_PAUSABLE,ACCEPTS_SHUTDOWN)
180 _tprintf(_T("\tWIN32_EXIT_CODE : %d (0x%x)\n"),
181 (unsigned int)pServiceInfo
->dwWin32ExitCode
,
182 (unsigned int)pServiceInfo
->dwWin32ExitCode
);
183 _tprintf(_T("\tSERVICE_EXIT_CODE : %d (0x%x)\n"),
184 (unsigned int)pServiceInfo
->dwServiceSpecificExitCode
,
185 (unsigned int)pServiceInfo
->dwServiceSpecificExitCode
);
186 _tprintf(_T("\tCHECKPOINT : 0x%x\n"),
187 (unsigned int)pServiceInfo
->dwCheckPoint
);
188 _tprintf(_T("\tWAIT_HINT : 0x%x\n"),
189 (unsigned int)pServiceInfo
->dwWaitHint
);
192 _tprintf(_T("\tPID : %lu\n"),
193 pServiceInfo
->dwProcessId
);
194 _tprintf(_T("\tFLAGS : %lu\n"),
195 pServiceInfo
->dwServiceFlags
);
198 HeapFree(GetProcessHeap(), 0, pServiceInfo
);
205 EnumServices(LPCTSTR ServiceName
, DWORD ServiceType
, DWORD ServiceState
)
208 DWORD BytesNeeded
= 0;
209 DWORD ResumeHandle
= 0;
212 /* determine required buffer size */
213 Ret
= EnumServicesStatusEx(hSCManager
,
214 SC_ENUM_PROCESS_INFO
,
217 (LPBYTE
)pServiceStatus
,
224 if ((Ret
!= 0) && (GetLastError() != ERROR_MORE_DATA
))
226 _tprintf(_T("EnumServices: First call to EnumServicesStatusEx failed : "));
230 else /* Call function again if required size was returned */
232 /* reserve memory for service info array */
233 pServiceStatus
= (ENUM_SERVICE_STATUS_PROCESS
*)
234 HeapAlloc(GetProcessHeap(), 0, BytesNeeded
);
235 if (pServiceStatus
== NULL
)
237 _tprintf(_T("EnumServices: Failed to allocate memory : "));
242 /* fill array with service info */
243 if (! EnumServicesStatusEx(hSCManager
,
244 SC_ENUM_PROCESS_INFO
,
247 (LPBYTE
)pServiceStatus
,
254 _tprintf(_T("EnumServices: Second call to EnumServicesStatusEx failed : "));
256 HeapFree(GetProcessHeap(), 0, pServiceStatus
);
266 PrintService(BOOL bExtended
)
270 for (i
=0; i
< NumServices
; i
++)
273 _tprintf(_T("SERVICE_NAME: %s\n"), pServiceStatus
[i
].lpServiceName
);
274 _tprintf(_T("DISPLAY_NAME: %s\n"), pServiceStatus
[i
].lpDisplayName
);
276 _tprintf(_T("\tTYPE : %x "),
277 (unsigned int)pServiceStatus
[i
].ServiceStatusProcess
.dwServiceType
);
278 switch (pServiceStatus
[i
].ServiceStatusProcess
.dwServiceType
)
280 case 1 : _tprintf(_T("KERNEL_DRIVER\n")); break;
281 case 2 : _tprintf(_T("FILE_SYSTEM_DRIVER\n")); break;
282 case 16 : _tprintf(_T("WIN32_OWN_PROCESS\n")); break;
283 case 32 : _tprintf(_T("WIN32_SHARE_PROCESS\n")); break;
284 default : _tprintf(_T("\n")); break;
287 _tprintf(_T("\tSTATE : %x "),
288 (unsigned int)pServiceStatus
[i
].ServiceStatusProcess
.dwCurrentState
);
290 switch (pServiceStatus
[i
].ServiceStatusProcess
.dwCurrentState
)
292 case 1 : _tprintf(_T("STOPPED\n")); break;
293 case 2 : _tprintf(_T("START_PENDING\n")); break;
294 case 3 : _tprintf(_T("STOP_PENDING\n")); break;
295 case 4 : _tprintf(_T("RUNNING\n")); break;
296 case 5 : _tprintf(_T("CONTINUE_PENDING\n")); break;
297 case 6 : _tprintf(_T("PAUSE_PENDING\n")); break;
298 case 7 : _tprintf(_T("PAUSED\n")); break;
299 default : _tprintf(_T("\n")); break;
302 // _tprintf(_T("\n\taccepted : 0x%x\n\n"),
303 // pServiceStatus[i].ServiceStatusProcess.dwControlsAccepted);
304 // (STOPPABLE,NOT_PAUSABLE,ACCEPTS_SHUTDOWN)
306 _tprintf(_T("\tWIN32_EXIT_CODE : %d (0x%x)\n"),
307 (unsigned int)pServiceStatus
[i
].ServiceStatusProcess
.dwWin32ExitCode
,
308 (unsigned int)pServiceStatus
[i
].ServiceStatusProcess
.dwWin32ExitCode
);
309 _tprintf(_T("\tSERVICE_EXIT_CODE : %d (0x%x)\n"),
310 (unsigned int)pServiceStatus
[i
].ServiceStatusProcess
.dwServiceSpecificExitCode
,
311 (unsigned int)pServiceStatus
[i
].ServiceStatusProcess
.dwServiceSpecificExitCode
);
312 _tprintf(_T("\tCHECKPOINT : 0x%x\n"),
313 (unsigned int)pServiceStatus
[i
].ServiceStatusProcess
.dwCheckPoint
);
314 _tprintf(_T("\tWAIT_HINT : 0x%x\n"),
315 (unsigned int)pServiceStatus
[i
].ServiceStatusProcess
.dwWaitHint
);
318 _tprintf(_T("\tPID : %lu\n"),
319 pServiceStatus
[i
].ServiceStatusProcess
.dwProcessId
);
320 _tprintf(_T("\tFLAGS : %lu\n"),
321 pServiceStatus
[i
].ServiceStatusProcess
.dwServiceFlags
);
327 _tprintf(_T("number : %lu\n"), NumServices
);