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
)
23 UNICODE_STRING DriverPath
;
25 DWORD dwError
= ERROR_SUCCESS
;
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 /* FIXME: Acquire privilege */
45 DPRINT(" Path: %wZ\n", &DriverPath
);
46 Status
= NtLoadDriver(&DriverPath
);
48 /* FIXME: Release privilege */
50 if (!NT_SUCCESS(Status
))
52 dwError
= RtlNtStatusToDosError(Status
);
55 HeapFree(GetProcessHeap(), 0, pszDriverPath
);
62 ScmUnloadDriver(PSERVICE lpService
)
65 UNICODE_STRING DriverPath
;
67 DWORD dwError
= ERROR_SUCCESS
;
69 /* Build the driver path */
70 /* 52 = wcslen(L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\") */
71 pszDriverPath
= HeapAlloc(GetProcessHeap(),
73 (52 + wcslen(lpService
->lpServiceName
) + 1) * sizeof(WCHAR
));
74 if (pszDriverPath
== NULL
)
75 return ERROR_NOT_ENOUGH_MEMORY
;
78 L
"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");
80 lpService
->lpServiceName
);
82 RtlInitUnicodeString(&DriverPath
,
85 /* FIXME: Acquire privilege */
87 Status
= NtUnloadDriver(&DriverPath
);
89 /* FIXME: Release privilege */
91 if (!NT_SUCCESS(Status
))
93 dwError
= RtlNtStatusToDosError(Status
);
96 HeapFree(GetProcessHeap(), 0, pszDriverPath
);
103 ScmGetDriverStatus(PSERVICE lpService
,
104 LPSERVICE_STATUS lpServiceStatus
)
106 OBJECT_ATTRIBUTES ObjectAttributes
;
107 UNICODE_STRING DirName
;
109 NTSTATUS Status
= STATUS_SUCCESS
;
110 POBJECT_DIRECTORY_INFORMATION DirInfo
;
114 DWORD dwError
= ERROR_SUCCESS
;
115 BOOLEAN bFound
= FALSE
;
117 DPRINT1("ScmGetDriverStatus() called\n");
119 memset(lpServiceStatus
, 0, sizeof(SERVICE_STATUS
));
121 if (lpService
->Status
.dwServiceType
== SERVICE_KERNEL_DRIVER
)
123 RtlInitUnicodeString(&DirName
,
128 RtlInitUnicodeString(&DirName
,
132 InitializeObjectAttributes(&ObjectAttributes
,
138 Status
= NtOpenDirectoryObject(&DirHandle
,
139 DIRECTORY_QUERY
| DIRECTORY_TRAVERSE
,
141 if (!NT_SUCCESS(Status
))
143 DPRINT1("NtOpenDirectoryObject() failed!\n");
144 return RtlNtStatusToDosError(Status
);
147 BufferLength
= sizeof(OBJECT_DIRECTORY_INFORMATION
) +
148 2 * MAX_PATH
* sizeof(WCHAR
);
149 DirInfo
= (OBJECT_DIRECTORY_INFORMATION
*) HeapAlloc(GetProcessHeap(),
156 Status
= NtQueryDirectoryObject(DirHandle
,
163 if (Status
== STATUS_NO_MORE_ENTRIES
)
165 DPRINT("No more services\n");
169 if (!NT_SUCCESS(Status
))
172 DPRINT("Comparing: '%S' '%wZ'\n", lpService
->lpServiceName
, &DirInfo
->Name
);
174 if (_wcsicmp(lpService
->lpServiceName
, DirInfo
->Name
.Buffer
) == 0)
176 DPRINT1("Found: '%S' '%wZ'\n",
177 lpService
->lpServiceName
, &DirInfo
->Name
);
184 HeapFree(GetProcessHeap(),
189 if (!NT_SUCCESS(Status
))
191 DPRINT1("Status: %lx\n", Status
);
192 return RtlNtStatusToDosError(Status
);
195 if ((bFound
== TRUE
) &&
196 (lpService
->Status
.dwCurrentState
!= SERVICE_STOP_PENDING
))
198 if (lpService
->Status
.dwCurrentState
== SERVICE_STOPPED
)
200 lpService
->Status
.dwWin32ExitCode
= ERROR_SUCCESS
;
201 lpService
->Status
.dwServiceSpecificExitCode
= ERROR_SUCCESS
;
202 lpService
->Status
.dwCheckPoint
= 0;
203 lpService
->Status
.dwWaitHint
= 0;
204 lpService
->Status
.dwControlsAccepted
= 0;
208 lpService
->Status
.dwCurrentState
= SERVICE_RUNNING
;
209 lpService
->Status
.dwControlsAccepted
= SERVICE_ACCEPT_STOP
;
211 if (lpService
->Status
.dwWin32ExitCode
== ERROR_SERVICE_NEVER_STARTED
)
212 lpService
->Status
.dwWin32ExitCode
= ERROR_SUCCESS
;
217 lpService
->Status
.dwCurrentState
= SERVICE_STOPPED
;
218 lpService
->Status
.dwControlsAccepted
= 0;
219 lpService
->Status
.dwCheckPoint
= 0;
220 lpService
->Status
.dwWaitHint
= 0;
222 if (lpService
->Status
.dwCurrentState
== SERVICE_STOP_PENDING
)
223 lpService
->Status
.dwWin32ExitCode
= ERROR_SUCCESS
;
225 lpService
->Status
.dwWin32ExitCode
= ERROR_GEN_FAILURE
;
228 if (lpServiceStatus
!= NULL
)
230 memcpy(lpServiceStatus
,
232 sizeof(SERVICE_STATUS
));
235 DPRINT1("ScmGetDriverStatus() done (Error: %lu)\n", dwError
);
237 return ERROR_SUCCESS
;
242 ScmControlDriver(PSERVICE lpService
,
244 LPSERVICE_STATUS lpServiceStatus
)
248 DPRINT("ScmControlDriver() called\n");
252 case SERVICE_CONTROL_STOP
:
253 if (lpService
->Status
.dwCurrentState
!= SERVICE_RUNNING
)
255 dwError
= ERROR_INVALID_SERVICE_CONTROL
;
259 dwError
= ScmUnloadDriver(lpService
);
260 if (dwError
== ERROR_SUCCESS
)
262 lpService
->Status
.dwControlsAccepted
= 0;
263 lpService
->Status
.dwCurrentState
= SERVICE_STOPPED
;
267 case SERVICE_CONTROL_INTERROGATE
:
268 dwError
= ScmGetDriverStatus(lpService
,
273 dwError
= ERROR_INVALID_SERVICE_CONTROL
;
277 DPRINT("ScmControlDriver() done (Erorr: %lu)\n", dwError
);