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 WCHAR szDriverPath
[MAX_PATH
];
23 UNICODE_STRING DriverPath
;
25 DWORD dwError
= ERROR_SUCCESS
;
27 /* Build the driver path */
29 L
"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");
31 lpService
->lpServiceName
);
33 RtlInitUnicodeString(&DriverPath
,
36 /* FIXME: Acquire privilege */
38 DPRINT(" Path: %wZ\n", &DriverPath
);
39 Status
= NtLoadDriver(&DriverPath
);
41 /* FIXME: Release privilege */
43 if (!NT_SUCCESS(Status
))
45 dwError
= RtlNtStatusToDosError(Status
);
53 ScmUnloadDriver(PSERVICE lpService
)
55 WCHAR szDriverPath
[MAX_PATH
];
56 UNICODE_STRING DriverPath
;
58 DWORD dwError
= ERROR_SUCCESS
;
60 /* Build the driver path */
62 L
"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");
64 lpService
->lpServiceName
);
66 RtlInitUnicodeString(&DriverPath
,
69 /* FIXME: Acquire privilege */
71 Status
= NtUnloadDriver(&DriverPath
);
73 /* FIXME: Release privilege */
75 if (!NT_SUCCESS(Status
))
77 dwError
= RtlNtStatusToDosError(Status
);
85 ScmGetDriverStatus(PSERVICE lpService
,
86 LPSERVICE_STATUS lpServiceStatus
)
88 OBJECT_ATTRIBUTES ObjectAttributes
;
89 UNICODE_STRING DirName
;
91 NTSTATUS Status
= STATUS_SUCCESS
;
92 POBJECT_DIRECTORY_INFORMATION DirInfo
;
96 DWORD dwError
= ERROR_SUCCESS
;
97 BOOLEAN bFound
= FALSE
;
99 DPRINT1("ScmGetDriverStatus() called\n");
101 memset(lpServiceStatus
, 0, sizeof(SERVICE_STATUS
));
103 if (lpService
->Status
.dwServiceType
== SERVICE_KERNEL_DRIVER
)
105 RtlInitUnicodeString(&DirName
,
110 RtlInitUnicodeString(&DirName
,
114 InitializeObjectAttributes(&ObjectAttributes
,
120 Status
= NtOpenDirectoryObject(&DirHandle
,
121 DIRECTORY_QUERY
| DIRECTORY_TRAVERSE
,
123 if (!NT_SUCCESS(Status
))
125 DPRINT1("NtOpenDirectoryObject() failed!\n");
126 return RtlNtStatusToDosError(Status
);
129 BufferLength
= sizeof(OBJECT_DIRECTORY_INFORMATION
) +
130 2 * MAX_PATH
* sizeof(WCHAR
);
131 DirInfo
= (OBJECT_DIRECTORY_INFORMATION
*) HeapAlloc(GetProcessHeap(),
138 Status
= NtQueryDirectoryObject(DirHandle
,
145 if (Status
== STATUS_NO_MORE_ENTRIES
)
147 DPRINT("No more services\n");
151 if (!NT_SUCCESS(Status
))
154 DPRINT("Comparing: '%S' '%wZ'\n", lpService
->lpServiceName
, &DirInfo
->Name
);
156 if (_wcsicmp(lpService
->lpServiceName
, DirInfo
->Name
.Buffer
) == 0)
158 DPRINT1("Found: '%S' '%wZ'\n",
159 lpService
->lpServiceName
, &DirInfo
->Name
);
166 HeapFree(GetProcessHeap(),
171 if (!NT_SUCCESS(Status
))
173 DPRINT1("Status: %lx\n", Status
);
174 return RtlNtStatusToDosError(Status
);
177 if ((bFound
== TRUE
) &&
178 (lpService
->Status
.dwCurrentState
!= SERVICE_STOP_PENDING
))
180 if (lpService
->Status
.dwCurrentState
== SERVICE_STOPPED
)
182 lpService
->Status
.dwWin32ExitCode
= ERROR_SUCCESS
;
183 lpService
->Status
.dwServiceSpecificExitCode
= ERROR_SUCCESS
;
184 lpService
->Status
.dwCheckPoint
= 0;
185 lpService
->Status
.dwWaitHint
= 0;
186 lpService
->Status
.dwControlsAccepted
= 0;
190 lpService
->Status
.dwCurrentState
= SERVICE_RUNNING
;
191 lpService
->Status
.dwControlsAccepted
= SERVICE_ACCEPT_STOP
;
193 if (lpService
->Status
.dwWin32ExitCode
== ERROR_SERVICE_NEVER_STARTED
)
194 lpService
->Status
.dwWin32ExitCode
= ERROR_SUCCESS
;
199 lpService
->Status
.dwCurrentState
= SERVICE_STOPPED
;
200 lpService
->Status
.dwControlsAccepted
= 0;
201 lpService
->Status
.dwCheckPoint
= 0;
202 lpService
->Status
.dwWaitHint
= 0;
204 if (lpService
->Status
.dwCurrentState
== SERVICE_STOP_PENDING
)
205 lpService
->Status
.dwWin32ExitCode
= ERROR_SUCCESS
;
207 lpService
->Status
.dwWin32ExitCode
= ERROR_GEN_FAILURE
;
210 if (lpServiceStatus
!= NULL
)
212 memcpy(lpServiceStatus
,
214 sizeof(SERVICE_STATUS
));
217 DPRINT1("ScmGetDriverStatus() done (Error: %lu)\n", dwError
);
219 return ERROR_SUCCESS
;
224 ScmControlDriver(PSERVICE lpService
,
226 LPSERVICE_STATUS lpServiceStatus
)
230 DPRINT("ScmControlDriver() called\n");
234 case SERVICE_CONTROL_STOP
:
235 if (lpService
->Status
.dwCurrentState
!= SERVICE_RUNNING
)
237 dwError
= ERROR_INVALID_SERVICE_CONTROL
;
241 dwError
= ScmUnloadDriver(lpService
);
242 if (dwError
== ERROR_SUCCESS
)
244 lpService
->Status
.dwControlsAccepted
= 0;
245 lpService
->Status
.dwCurrentState
= SERVICE_STOPPED
;
249 case SERVICE_CONTROL_INTERROGATE
:
250 dwError
= ScmGetDriverStatus(lpService
,
255 dwError
= ERROR_INVALID_SERVICE_CONTROL
;
259 DPRINT("ScmControlDriver() done (Erorr: %lu)\n", dwError
);