2 * PROJECT: ReactOS Service Control Manager
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: base/system/services/driver.c
5 * PURPOSE: Driver control interface
6 * COPYRIGHT: Copyright 2005-2006 Eric Kohl
10 /* INCLUDES *****************************************************************/
17 /* FUNCTIONS ****************************************************************/
20 ScmLoadDriver(PSERVICE lpService
)
22 NTSTATUS Status
= STATUS_SUCCESS
;
23 BOOLEAN WasPrivilegeEnabled
= FALSE
;
25 UNICODE_STRING DriverPath
;
27 /* Build the driver path */
28 /* 52 = wcslen(L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\") */
29 pszDriverPath
= HeapAlloc(GetProcessHeap(),
31 (52 + wcslen(lpService
->lpServiceName
) + 1) * sizeof(WCHAR
));
32 if (pszDriverPath
== NULL
)
33 return ERROR_NOT_ENOUGH_MEMORY
;
36 L
"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");
38 lpService
->lpServiceName
);
40 RtlInitUnicodeString(&DriverPath
,
43 DPRINT(" Path: %wZ\n", &DriverPath
);
45 /* Acquire driver-loading privilege */
46 Status
= RtlAdjustPrivilege(SE_LOAD_DRIVER_PRIVILEGE
,
49 &WasPrivilegeEnabled
);
50 if (!NT_SUCCESS(Status
))
52 /* We encountered a failure, exit properly */
53 DPRINT1("SERVICES: Cannot acquire driver-loading privilege, Status = 0x%08lx\n", Status
);
57 Status
= NtLoadDriver(&DriverPath
);
59 /* Release driver-loading privilege */
60 RtlAdjustPrivilege(SE_LOAD_DRIVER_PRIVILEGE
,
63 &WasPrivilegeEnabled
);
66 HeapFree(GetProcessHeap(), 0, pszDriverPath
);
67 return RtlNtStatusToDosError(Status
);
72 ScmUnloadDriver(PSERVICE lpService
)
74 NTSTATUS Status
= STATUS_SUCCESS
;
75 BOOLEAN WasPrivilegeEnabled
= FALSE
;
77 UNICODE_STRING DriverPath
;
79 /* Build the driver path */
80 /* 52 = wcslen(L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\") */
81 pszDriverPath
= HeapAlloc(GetProcessHeap(),
83 (52 + wcslen(lpService
->lpServiceName
) + 1) * sizeof(WCHAR
));
84 if (pszDriverPath
== NULL
)
85 return ERROR_NOT_ENOUGH_MEMORY
;
88 L
"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");
90 lpService
->lpServiceName
);
92 RtlInitUnicodeString(&DriverPath
,
95 DPRINT(" Path: %wZ\n", &DriverPath
);
97 /* Acquire driver-unloading privilege */
98 Status
= RtlAdjustPrivilege(SE_LOAD_DRIVER_PRIVILEGE
,
101 &WasPrivilegeEnabled
);
102 if (!NT_SUCCESS(Status
))
104 /* We encountered a failure, exit properly */
105 DPRINT1("SERVICES: Cannot acquire driver-unloading privilege, Status = 0x%08lx\n", Status
);
109 Status
= NtUnloadDriver(&DriverPath
);
111 /* Release driver-unloading privilege */
112 RtlAdjustPrivilege(SE_LOAD_DRIVER_PRIVILEGE
,
115 &WasPrivilegeEnabled
);
118 HeapFree(GetProcessHeap(), 0, pszDriverPath
);
119 return RtlNtStatusToDosError(Status
);
124 ScmGetDriverStatus(PSERVICE lpService
,
125 LPSERVICE_STATUS lpServiceStatus
)
127 OBJECT_ATTRIBUTES ObjectAttributes
;
128 UNICODE_STRING DirName
;
130 NTSTATUS Status
= STATUS_SUCCESS
;
131 POBJECT_DIRECTORY_INFORMATION DirInfo
;
135 DWORD dwError
= ERROR_SUCCESS
;
136 BOOLEAN bFound
= FALSE
;
138 DPRINT1("ScmGetDriverStatus() called\n");
140 memset(lpServiceStatus
, 0, sizeof(SERVICE_STATUS
));
142 if (lpService
->Status
.dwServiceType
== SERVICE_KERNEL_DRIVER
)
144 RtlInitUnicodeString(&DirName
, L
"\\Driver");
146 else // if (lpService->Status.dwServiceType == SERVICE_FILE_SYSTEM_DRIVER)
148 ASSERT(lpService
->Status
.dwServiceType
== SERVICE_FILE_SYSTEM_DRIVER
);
149 RtlInitUnicodeString(&DirName
, L
"\\FileSystem");
152 InitializeObjectAttributes(&ObjectAttributes
,
158 Status
= NtOpenDirectoryObject(&DirHandle
,
159 DIRECTORY_QUERY
| DIRECTORY_TRAVERSE
,
161 if (!NT_SUCCESS(Status
))
163 DPRINT1("NtOpenDirectoryObject() failed!\n");
164 return RtlNtStatusToDosError(Status
);
167 BufferLength
= sizeof(OBJECT_DIRECTORY_INFORMATION
) +
168 2 * MAX_PATH
* sizeof(WCHAR
);
169 DirInfo
= (OBJECT_DIRECTORY_INFORMATION
*) HeapAlloc(GetProcessHeap(),
176 Status
= NtQueryDirectoryObject(DirHandle
,
183 if (Status
== STATUS_NO_MORE_ENTRIES
)
185 DPRINT("No more services\n");
189 if (!NT_SUCCESS(Status
))
192 DPRINT("Comparing: '%S' '%wZ'\n", lpService
->lpServiceName
, &DirInfo
->Name
);
194 if (_wcsicmp(lpService
->lpServiceName
, DirInfo
->Name
.Buffer
) == 0)
196 DPRINT1("Found: '%S' '%wZ'\n",
197 lpService
->lpServiceName
, &DirInfo
->Name
);
204 HeapFree(GetProcessHeap(),
209 if (!NT_SUCCESS(Status
))
211 DPRINT1("Status: %lx\n", Status
);
212 return RtlNtStatusToDosError(Status
);
215 if ((bFound
== TRUE
) &&
216 (lpService
->Status
.dwCurrentState
!= SERVICE_STOP_PENDING
))
218 if (lpService
->Status
.dwCurrentState
== SERVICE_STOPPED
)
220 lpService
->Status
.dwWin32ExitCode
= ERROR_SUCCESS
;
221 lpService
->Status
.dwServiceSpecificExitCode
= ERROR_SUCCESS
;
222 lpService
->Status
.dwCheckPoint
= 0;
223 lpService
->Status
.dwWaitHint
= 0;
224 lpService
->Status
.dwControlsAccepted
= 0;
228 lpService
->Status
.dwCurrentState
= SERVICE_RUNNING
;
229 lpService
->Status
.dwControlsAccepted
= SERVICE_ACCEPT_STOP
;
231 if (lpService
->Status
.dwWin32ExitCode
== ERROR_SERVICE_NEVER_STARTED
)
232 lpService
->Status
.dwWin32ExitCode
= ERROR_SUCCESS
;
237 lpService
->Status
.dwCurrentState
= SERVICE_STOPPED
;
238 lpService
->Status
.dwControlsAccepted
= 0;
239 lpService
->Status
.dwCheckPoint
= 0;
240 lpService
->Status
.dwWaitHint
= 0;
242 if (lpService
->Status
.dwCurrentState
== SERVICE_STOP_PENDING
)
243 lpService
->Status
.dwWin32ExitCode
= ERROR_SUCCESS
;
245 lpService
->Status
.dwWin32ExitCode
= ERROR_GEN_FAILURE
;
248 if (lpServiceStatus
!= NULL
)
250 memcpy(lpServiceStatus
,
252 sizeof(SERVICE_STATUS
));
255 DPRINT1("ScmGetDriverStatus() done (Error: %lu)\n", dwError
);
257 return ERROR_SUCCESS
;
262 ScmControlDriver(PSERVICE lpService
,
264 LPSERVICE_STATUS lpServiceStatus
)
268 DPRINT("ScmControlDriver() called\n");
272 case SERVICE_CONTROL_STOP
:
273 if (lpService
->Status
.dwCurrentState
!= SERVICE_RUNNING
)
275 dwError
= ERROR_INVALID_SERVICE_CONTROL
;
279 dwError
= ScmUnloadDriver(lpService
);
280 if (dwError
== ERROR_SUCCESS
)
282 lpService
->Status
.dwControlsAccepted
= 0;
283 lpService
->Status
.dwCurrentState
= SERVICE_STOPPED
;
287 case SERVICE_CONTROL_INTERROGATE
:
288 dwError
= ScmGetDriverStatus(lpService
,
293 dwError
= ERROR_INVALID_SERVICE_CONTROL
;
297 DPRINT("ScmControlDriver() done (Erorr: %lu)\n", dwError
);