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
22 /* local function decs */
23 VOID
PrintService(BOOL bExtended
);
24 BOOL
EnumServices(DWORD ServiceType
, DWORD ServiceState
);
25 BOOL
QueryService(LPCTSTR ServiceName
, BOOL bExtended
);
27 /* global variables */
28 static ENUM_SERVICE_STATUS_PROCESS
*pServiceStatus
= NULL
;
29 DWORD NumServices
= 0;
33 Query(LPCTSTR ServiceName
, LPCTSTR
*ServiceArgs
, BOOL bExtended
)
35 if (! ServiceName
) /* display all running services and drivers */
37 /* get default values */
38 EnumServices(SERVICE_WIN32
, SERVICE_ACTIVE
);
40 /* print default values */
41 PrintService(bExtended
);
43 else if (_tcsicmp(ServiceName
, _T("type=")) == 0)
45 LPCTSTR Type
= *ServiceArgs
;
47 if (_tcsicmp(Type
, _T("driver")) == 0)
48 EnumServices(SERVICE_DRIVER
, SERVICE_ACTIVE
);
49 else if (_tcsicmp(Type
, _T("service")) == 0)
50 EnumServices(SERVICE_WIN32
, SERVICE_ACTIVE
);
51 else if (_tcsicmp(Type
, _T("all")) == 0)
52 EnumServices(SERVICE_DRIVER
|SERVICE_WIN32
, SERVICE_ACTIVE
);
55 _tprintf(_T("\nERROR following \"type=\"!\n"));
56 _tprintf(_T("Must be \"driver\" or \"service\" or \"all\"\n"));
59 PrintService(bExtended
);
61 else if(_tcsicmp(ServiceName
, _T("state=")) == 0)
63 LPCTSTR State
= *ServiceArgs
;
65 if (_tcsicmp(State
, _T("inactive")) == 0)
66 EnumServices(SERVICE_WIN32
, SERVICE_INACTIVE
);
67 else if (_tcsicmp(State
, _T("all")) == 0)
68 EnumServices(SERVICE_WIN32
, SERVICE_STATE_ALL
);
71 _tprintf(_T("\nERROR following \"state=\"!\n"));
72 _tprintf(_T("Must be \"active\" or \"inactive\" or \"all\"\n"));
75 PrintService(bExtended
);
78 else if(_tcsicmp(ServiceName, _T("bufsize=")))
80 else if(_tcsicmp(ServiceName, _T("ri=")))
82 else if(_tcsicmp(ServiceName, _T("group=")))
84 else /* print only the service requested */
86 QueryService(ServiceName
, bExtended
);
94 QueryService(LPCTSTR ServiceName
, BOOL bExtended
)
96 SERVICE_STATUS_PROCESS
*pServiceInfo
= NULL
;
99 DWORD BytesNeeded
= 0;
102 hSc
= OpenService(hSCManager
, ServiceName
, SERVICE_QUERY_STATUS
);
106 _tprintf(_T("QueryService: openService failed\n"));
111 Ret
= QueryServiceStatusEx(hSc
,
112 SC_STATUS_PROCESS_INFO
,
117 if ((Ret
!= 0) || (GetLastError() != ERROR_INSUFFICIENT_BUFFER
))
119 _tprintf(_T("QueryService: First call to QueryServiceStatusEx failed : "));
123 else /* Call function again if required size was returned */
125 /* reserve memory for service info array */
126 pServiceInfo
= (SERVICE_STATUS_PROCESS
*)
127 HeapAlloc(GetProcessHeap(), 0, BytesNeeded
);
128 if (pServiceInfo
== NULL
)
130 _tprintf(_T("QueryService: Failed to allocate memory : "));
135 /* fill array with service info */
136 if (! QueryServiceStatusEx(hSc
,
137 SC_STATUS_PROCESS_INFO
,
138 (LPBYTE
)pServiceInfo
,
142 _tprintf(_T("QueryService: Second call to QueryServiceStatusEx failed : "));
144 HeapFree(GetProcessHeap(), 0, pServiceInfo
);
150 _tprintf(_T("SERVICE_NAME: %s\n"), ServiceName
);
152 _tprintf(_T("\tTYPE : %x "),
153 (unsigned int)pServiceInfo
->dwServiceType
);
154 switch (pServiceInfo
->dwServiceType
)
156 case 1 : _tprintf(_T("KERNEL_DRIVER\n")); break;
157 case 2 : _tprintf(_T("FILE_SYSTEM_DRIVER\n")); break;
158 case 16 : _tprintf(_T("WIN32_OWN_PROCESS\n")); break;
159 case 32 : _tprintf(_T("WIN32_SHARE_PROCESS\n")); break;
160 default : _tprintf(_T("\n")); break;
163 _tprintf(_T("\tSTATE : %x "),
164 (unsigned int)pServiceInfo
->dwCurrentState
);
166 switch (pServiceInfo
->dwCurrentState
)
168 case 1 : _tprintf(_T("STOPPED\n")); break;
169 case 2 : _tprintf(_T("START_PENDING\n")); break;
170 case 3 : _tprintf(_T("STOP_PENDING\n")); break;
171 case 4 : _tprintf(_T("RUNNING\n")); break;
172 case 5 : _tprintf(_T("CONTINUE_PENDING\n")); break;
173 case 6 : _tprintf(_T("PAUSE_PENDING\n")); break;
174 case 7 : _tprintf(_T("PAUSED\n")); break;
175 default : _tprintf(_T("\n")); break;
178 // _tprintf(_T("\n\taccepted : 0x%x\n\n"),
179 // pServiceStatus[i].ServiceStatusProcess.dwControlsAccepted);
180 // (STOPPABLE,NOT_PAUSABLE,ACCEPTS_SHUTDOWN)
182 _tprintf(_T("\tWIN32_EXIT_CODE : %d (0x%x)\n"),
183 (unsigned int)pServiceInfo
->dwWin32ExitCode
,
184 (unsigned int)pServiceInfo
->dwWin32ExitCode
);
185 _tprintf(_T("\tSERVICE_EXIT_CODE : %d (0x%x)\n"),
186 (unsigned int)pServiceInfo
->dwServiceSpecificExitCode
,
187 (unsigned int)pServiceInfo
->dwServiceSpecificExitCode
);
188 _tprintf(_T("\tCHECKPOINT : 0x%x\n"),
189 (unsigned int)pServiceInfo
->dwCheckPoint
);
190 _tprintf(_T("\tWAIT_HINT : 0x%x\n"),
191 (unsigned int)pServiceInfo
->dwWaitHint
);
194 _tprintf(_T("\tPID : %lu\n"),
195 pServiceInfo
->dwProcessId
);
196 _tprintf(_T("\tFLAGS : %lu\n"),
197 pServiceInfo
->dwServiceFlags
);
200 HeapFree(GetProcessHeap(), 0, pServiceInfo
);
207 EnumServices(DWORD ServiceType
, DWORD ServiceState
)
210 DWORD BytesNeeded
= 0;
211 DWORD ResumeHandle
= 0;
214 /* determine required buffer size */
215 Ret
= EnumServicesStatusEx(hSCManager
,
216 SC_ENUM_PROCESS_INFO
,
219 (LPBYTE
)pServiceStatus
,
226 if ((Ret
!= 0) && (GetLastError() != ERROR_MORE_DATA
))
228 _tprintf(_T("EnumServices: First call to EnumServicesStatusEx failed : "));
232 else /* Call function again if required size was returned */
234 /* reserve memory for service info array */
235 pServiceStatus
= (ENUM_SERVICE_STATUS_PROCESS
*)
236 HeapAlloc(GetProcessHeap(), 0, BytesNeeded
);
237 if (pServiceStatus
== NULL
)
239 _tprintf(_T("EnumServices: Failed to allocate memory : "));
244 /* fill array with service info */
245 if (! EnumServicesStatusEx(hSCManager
,
246 SC_ENUM_PROCESS_INFO
,
249 (LPBYTE
)pServiceStatus
,
256 _tprintf(_T("EnumServices: Second call to EnumServicesStatusEx failed : "));
258 HeapFree(GetProcessHeap(), 0, pServiceStatus
);
268 PrintService(BOOL bExtended
)
272 for (i
=0; i
< NumServices
; i
++)
275 _tprintf(_T("SERVICE_NAME: %s\n"), pServiceStatus
[i
].lpServiceName
);
276 _tprintf(_T("DISPLAY_NAME: %s\n"), pServiceStatus
[i
].lpDisplayName
);
278 _tprintf(_T("\tTYPE : %x "),
279 (unsigned int)pServiceStatus
[i
].ServiceStatusProcess
.dwServiceType
);
280 switch (pServiceStatus
[i
].ServiceStatusProcess
.dwServiceType
)
282 case 1 : _tprintf(_T("KERNEL_DRIVER\n")); break;
283 case 2 : _tprintf(_T("FILE_SYSTEM_DRIVER\n")); break;
284 case 16 : _tprintf(_T("WIN32_OWN_PROCESS\n")); break;
285 case 32 : _tprintf(_T("WIN32_SHARE_PROCESS\n")); break;
286 default : _tprintf(_T("\n")); break;
289 _tprintf(_T("\tSTATE : %x "),
290 (unsigned int)pServiceStatus
[i
].ServiceStatusProcess
.dwCurrentState
);
292 switch (pServiceStatus
[i
].ServiceStatusProcess
.dwCurrentState
)
294 case 1 : _tprintf(_T("STOPPED\n")); break;
295 case 2 : _tprintf(_T("START_PENDING\n")); break;
296 case 3 : _tprintf(_T("STOP_PENDING\n")); break;
297 case 4 : _tprintf(_T("RUNNING\n")); break;
298 case 5 : _tprintf(_T("CONTINUE_PENDING\n")); break;
299 case 6 : _tprintf(_T("PAUSE_PENDING\n")); break;
300 case 7 : _tprintf(_T("PAUSED\n")); break;
301 default : _tprintf(_T("\n")); break;
304 // _tprintf(_T("\n\taccepted : 0x%x\n\n"),
305 // pServiceStatus[i].ServiceStatusProcess.dwControlsAccepted);
306 // (STOPPABLE,NOT_PAUSABLE,ACCEPTS_SHUTDOWN)
308 _tprintf(_T("\tWIN32_EXIT_CODE : %d (0x%x)\n"),
309 (unsigned int)pServiceStatus
[i
].ServiceStatusProcess
.dwWin32ExitCode
,
310 (unsigned int)pServiceStatus
[i
].ServiceStatusProcess
.dwWin32ExitCode
);
311 _tprintf(_T("\tSERVICE_EXIT_CODE : %d (0x%x)\n"),
312 (unsigned int)pServiceStatus
[i
].ServiceStatusProcess
.dwServiceSpecificExitCode
,
313 (unsigned int)pServiceStatus
[i
].ServiceStatusProcess
.dwServiceSpecificExitCode
);
314 _tprintf(_T("\tCHECKPOINT : 0x%x\n"),
315 (unsigned int)pServiceStatus
[i
].ServiceStatusProcess
.dwCheckPoint
);
316 _tprintf(_T("\tWAIT_HINT : 0x%x\n"),
317 (unsigned int)pServiceStatus
[i
].ServiceStatusProcess
.dwWaitHint
);
320 _tprintf(_T("\tPID : %lu\n"),
321 pServiceStatus
[i
].ServiceStatusProcess
.dwProcessId
);
322 _tprintf(_T("\tFLAGS : %lu\n"),
323 pServiceStatus
[i
].ServiceStatusProcess
.dwServiceFlags
);
329 _tprintf(_T("number : %lu\n"), NumServices
);