2 * PROJECT: ReactOS kernel-mode tests
3 * LICENSE: GPLv2+ - See COPYING in the top level directory
4 * PURPOSE: Kernel-Mode Test Suite Loader service control functions
5 * PROGRAMMER: Thomas Faber <thfabba@gmx.de>
13 #define SERVICE_ACCESS (SERVICE_START | SERVICE_STOP | DELETE)
15 static SC_HANDLE ScmHandle
;
18 * @name KmtServiceInit
20 * Initialize service management routines (by opening the service control manager)
22 * @return Win32 error code
27 DWORD Error
= ERROR_SUCCESS
;
31 ScmHandle
= OpenSCManager(NULL
, NULL
, SC_MANAGER_CREATE_SERVICE
);
39 * @name KmtServiceCleanup
41 * Clean up resources used by service management routines.
44 * If TRUE, the function will never set ErrorLineAndFile, and always return ERROR_SUCCESS
46 * @return Win32 error code
52 DWORD Error
= ERROR_SUCCESS
;
54 if (ScmHandle
&& !CloseServiceHandle(ScmHandle
) && !IgnoreErrors
)
61 * @name KmtCreateService
63 * Create the specified driver service and return a handle to it
66 * Name of the service to create
68 * File name of the driver, relative to the current directory
70 * Service display name
71 * @param ServiceHandle
72 * Pointer to a variable to receive the handle to the service
74 * @return Win32 error code
78 IN PCWSTR ServiceName
,
79 IN PCWSTR ServicePath
,
80 IN PCWSTR DisplayName OPTIONAL
,
81 OUT SC_HANDLE
*ServiceHandle
)
83 DWORD Error
= ERROR_SUCCESS
;
84 WCHAR DriverPath
[MAX_PATH
];
85 HRESULT result
= S_OK
;
87 assert(ServiceHandle
);
88 assert(ServiceName
&& ServicePath
);
90 if (!GetModuleFileName(NULL
, DriverPath
, sizeof DriverPath
/ sizeof DriverPath
[0]))
91 error_goto(Error
, cleanup
);
93 assert(wcsrchr(DriverPath
, L
'\\') != NULL
);
94 wcsrchr(DriverPath
, L
'\\')[1] = L
'\0';
96 result
= StringCbCat(DriverPath
, sizeof DriverPath
, ServicePath
);
98 error_value_goto(Error
, result
, cleanup
);
100 if (GetFileAttributes(DriverPath
) == INVALID_FILE_ATTRIBUTES
)
101 error_goto(Error
, cleanup
);
103 *ServiceHandle
= CreateService(ScmHandle
, ServiceName
, DisplayName
,
104 SERVICE_ACCESS
, SERVICE_KERNEL_DRIVER
, SERVICE_DEMAND_START
,
105 SERVICE_ERROR_NORMAL
, DriverPath
, NULL
, NULL
, NULL
, NULL
, NULL
);
108 error_goto(Error
, cleanup
);
115 * @name KmtStartService
117 * Start the specified driver service by handle or name (and return a handle to it)
120 * If *ServiceHandle is NULL, name of the service to start
121 * @param ServiceHandle
122 * Pointer to a variable containing the service handle,
123 * or NULL (in which case it will be filled with a handle to the service)
125 * @return Win32 error code
129 IN PCWSTR ServiceName OPTIONAL
,
130 IN OUT SC_HANDLE
*ServiceHandle
)
132 DWORD Error
= ERROR_SUCCESS
;
134 assert(ServiceHandle
);
135 assert(ServiceName
|| *ServiceHandle
);
138 *ServiceHandle
= OpenService(ScmHandle
, ServiceName
, SERVICE_ACCESS
);
141 error_goto(Error
, cleanup
);
143 if (!StartService(*ServiceHandle
, 0, NULL
))
144 error_goto(Error
, cleanup
);
151 * @name KmtCreateAndStartService
153 * Create and start the specified driver service and return a handle to it
156 * Name of the service to create
158 * File name of the driver, relative to the current directory
160 * Service display name
161 * @param ServiceHandle
162 * Pointer to a variable to receive the handle to the service
163 * @param RestartIfRunning
164 * TRUE to stop and restart the service if it is already running
166 * @return Win32 error code
169 KmtCreateAndStartService(
170 IN PCWSTR ServiceName
,
171 IN PCWSTR ServicePath
,
172 IN PCWSTR DisplayName OPTIONAL
,
173 OUT SC_HANDLE
*ServiceHandle
,
174 IN BOOLEAN RestartIfRunning
)
176 DWORD Error
= ERROR_SUCCESS
;
178 assert(ServiceHandle
);
180 Error
= KmtCreateService(ServiceName
, ServicePath
, DisplayName
, ServiceHandle
);
182 if (Error
&& Error
!= ERROR_SERVICE_EXISTS
)
185 Error
= KmtStartService(ServiceName
, ServiceHandle
);
187 if (Error
!= ERROR_SERVICE_ALREADY_RUNNING
)
190 Error
= ERROR_SUCCESS
;
192 if (!RestartIfRunning
)
195 Error
= KmtStopService(ServiceName
, ServiceHandle
);
199 Error
= KmtStartService(ServiceName
, ServiceHandle
);
204 assert(Error
|| *ServiceHandle
);
209 * @name KmtStopService
211 * Stop the specified driver service by handle or name (and return a handle to it)
214 * If *ServiceHandle is NULL, name of the service to stop
215 * @param ServiceHandle
216 * Pointer to a variable containing the service handle,
217 * or NULL (in which case it will be filled with a handle to the service)
219 * @return Win32 error code
223 IN PCWSTR ServiceName OPTIONAL
,
224 IN OUT SC_HANDLE
*ServiceHandle
)
226 DWORD Error
= ERROR_SUCCESS
;
227 SERVICE_STATUS ServiceStatus
;
229 assert(ServiceHandle
);
230 assert(ServiceName
|| *ServiceHandle
);
233 *ServiceHandle
= OpenService(ScmHandle
, ServiceName
, SERVICE_ACCESS
);
236 error_goto(Error
, cleanup
);
238 if (!ControlService(*ServiceHandle
, SERVICE_CONTROL_STOP
, &ServiceStatus
))
239 error_goto(Error
, cleanup
);
246 * @name KmtDeleteService
248 * Delete the specified driver service by handle or name (and return a handle to it)
251 * If *ServiceHandle is NULL, name of the service to delete
252 * @param ServiceHandle
253 * Pointer to a variable containing the service handle.
254 * Will be set to NULL on success
256 * @return Win32 error code
260 IN PCWSTR ServiceName OPTIONAL
,
261 IN OUT SC_HANDLE
*ServiceHandle
)
263 DWORD Error
= ERROR_SUCCESS
;
265 assert(ServiceHandle
);
266 assert(ServiceName
|| *ServiceHandle
);
269 *ServiceHandle
= OpenService(ScmHandle
, ServiceName
, SERVICE_ACCESS
);
272 error_goto(Error
, cleanup
);
274 if (!DeleteService(*ServiceHandle
))
275 error_goto(Error
, cleanup
);
278 CloseServiceHandle(*ServiceHandle
);
285 * @name KmtCloseService
287 * Close the specified driver service handle
289 * @param ServiceHandle
290 * Pointer to a variable containing the service handle.
291 * Will be set to NULL on success
293 * @return Win32 error code
295 DWORD
KmtCloseService(
296 IN OUT SC_HANDLE
*ServiceHandle
)
298 DWORD Error
= ERROR_SUCCESS
;
300 assert(ServiceHandle
);
302 if (*ServiceHandle
&& !CloseServiceHandle(*ServiceHandle
))
303 error_goto(Error
, cleanup
);
305 *ServiceHandle
= NULL
;