- Prepare to delete marked services upon startup. - ControlService: Implement unloading of drivers. Modified: trunk/reactos/subsys/system/services/database.c Added: trunk/reactos/subsys/system/services/driver.c Modified: trunk/reactos/subsys/system/services/rpcserver.c Modified: trunk/reactos/subsys/system/services/services.h Modified: trunk/reactos/subsys/system/services/services.xml _____
Modified: trunk/reactos/subsys/system/services/database.c --- trunk/reactos/subsys/system/services/database.c 2005-11-20 19:31:49 UTC (rev 19384) +++ trunk/reactos/subsys/system/services/database.c 2005-11-20 20:18:00 UTC (rev 19385) @@ -404,6 +404,32 @@
}
+VOID +ScmDeleteMarkedServices(VOID) +{ + PLIST_ENTRY ServiceEntry; + PSERVICE CurrentService; + + ServiceEntry = ServiceListHead.Flink; + while (ServiceEntry != &ServiceListHead) + { + CurrentService = CONTAINING_RECORD(ServiceEntry, SERVICE, ServiceListEntry); + + ServiceEntry = ServiceEntry->Flink; + + if (CurrentService->bDeleted == TRUE) + { + DPRINT1("Delete service: %S\n", CurrentService->lpServiceName); + + /* FIXME: Delete the registry keys */ + + /* FIXME: Delete the service record from the list */ + + } + } +} + + DWORD ScmCreateServiceDatabase(VOID) { @@ -474,7 +500,8 @@
RegCloseKey(hServicesKey);
- /* FIXME: Delete services that are marked for delete */ + /* Delete services that are marked for delete */ + ScmDeleteMarkedServices();
DPRINT("ScmCreateServiceDatabase() done\n");
@@ -836,8 +863,6 @@ ScmStartService(PSERVICE Service, PSERVICE_GROUP Group) { - WCHAR szDriverPath[MAX_PATH]; - UNICODE_STRING DriverPath; NTSTATUS Status;
DPRINT("ScmStartService() called\n"); @@ -845,21 +870,12 @@ Service->ControlPipeHandle = INVALID_HANDLE_VALUE; DPRINT("Service->Type: %lu\n", Service->Status.dwServiceType);
- if (Service->Status.dwServiceType == SERVICE_KERNEL_DRIVER || - Service->Status.dwServiceType == SERVICE_FILE_SYSTEM_DRIVER || - Service->Status.dwServiceType == SERVICE_RECOGNIZER_DRIVER) + if (Service->Status.dwServiceType & SERVICE_DRIVER) { /* Load driver */ - wcscpy(szDriverPath, - L"\Registry\Machine\System\CurrentControlSet\Services\"); - wcscat(szDriverPath, - Service->lpServiceName); - - RtlInitUnicodeString(&DriverPath, - szDriverPath); - - DPRINT(" Path: %wZ\n", &DriverPath); - Status = NtLoadDriver(&DriverPath); + Status = ScmLoadDriver(Service); + if (Status == STATUS_SUCCESS) + Service->Status.dwControlsAccepted = SERVICE_ACCEPT_STOP; } else { _____
Added: trunk/reactos/subsys/system/services/driver.c --- trunk/reactos/subsys/system/services/driver.c 2005-11-20 19:31:49 UTC (rev 19384) +++ trunk/reactos/subsys/system/services/driver.c 2005-11-20 20:18:00 UTC (rev 19385) @@ -0,0 +1,113 @@
+/* + * driver.c + */ + +/* INCLUDES *****************************************************************/ + +#include "services.h" + +#define NDEBUG +#include <debug.h> + +/* FUNCTIONS ****************************************************************/ + +NTSTATUS +ScmLoadDriver(PSERVICE lpService) +{ + WCHAR szDriverPath[MAX_PATH]; + UNICODE_STRING DriverPath; + NTSTATUS Status; + + /* Build the driver path */ + wcscpy(szDriverPath, + L"\Registry\Machine\System\CurrentControlSet\Services\"); + wcscat(szDriverPath, + lpService->lpServiceName); + + RtlInitUnicodeString(&DriverPath, + szDriverPath); + + /* FIXME: Acquire privilege */ + + DPRINT(" Path: %wZ\n", &DriverPath); + Status = NtLoadDriver(&DriverPath); + + /* FIXME: Release privilege */ + + return Status; +} + + +DWORD +ScmUnloadDriver(PSERVICE lpService) +{ + WCHAR szDriverPath[MAX_PATH]; + UNICODE_STRING DriverPath; + NTSTATUS Status; + DWORD dwError = ERROR_SUCCESS; + + /* Build the driver path */ + wcscpy(szDriverPath, + L"\Registry\Machine\System\CurrentControlSet\Services\"); + wcscat(szDriverPath, + lpService->lpServiceName); + + RtlInitUnicodeString(&DriverPath, + szDriverPath); + + /* FIXME: Acquire privilege */ + + Status = NtUnloadDriver(&DriverPath); + + /* FIXME: Release privilege */ + + if (!NT_SUCCESS(Status)) + { + dwError = RtlNtStatusToDosError(Status); + } + + return dwError; +} + + +DWORD +ScmControlDriver(PSERVICE lpService, + DWORD dwControl, + LPSERVICE_STATUS lpServiceStatus) +{ + DWORD dwError; + + DPRINT("ScmControlDriver() called\n"); + + switch (dwControl) + { + case SERVICE_CONTROL_STOP: + if (lpService->Status.dwCurrentState != SERVICE_RUNNING) + { + dwError = ERROR_INVALID_SERVICE_CONTROL; + goto done; + } + + dwError = ScmUnloadDriver(lpService); + if (dwError == ERROR_SUCCESS) + { + lpService->Status.dwControlsAccepted = 0; + lpService->Status.dwCurrentState = SERVICE_STOPPED; + } + break; + + case SERVICE_CONTROL_INTERROGATE: + dwError = ERROR_INVALID_SERVICE_CONTROL; + break; + + default: + dwError = ERROR_INVALID_SERVICE_CONTROL; + } + +done:; + DPRINT("ScmControlDriver() done (Erorr: %lu)\n", dwError); + + return dwError; +} + +/* EOF */ _____
Modified: trunk/reactos/subsys/system/services/rpcserver.c --- trunk/reactos/subsys/system/services/rpcserver.c 2005-11-20 19:31:49 UTC (rev 19384) +++ trunk/reactos/subsys/system/services/rpcserver.c 2005-11-20 20:18:00 UTC (rev 19385) @@ -281,6 +281,7 @@
PSERVICE_HANDLE hSvc; PSERVICE lpService; ACCESS_MASK DesiredAccess; + DWORD dwError = ERROR_SUCCESS;
DPRINT("ScmrControlService() called\n");
@@ -335,16 +336,30 @@ return ERROR_INVALID_HANDLE; }
+ if (lpService->Status.dwServiceType & SERVICE_DRIVER) + { + /* Send control code to the driver */ + dwError = ScmControlDriver(lpService, + dwControl, + lpServiceStatus); + } + else + { + /* FIXME: Send control code to the service */ +#if 0 + dwError = ScmControlService(lpService, + dwControl, + lpServiceStatus); +#endif + dwError = ERROR_INVALID_SERVICE_CONTROL; + }
- /* FIXME: Send control code to the service */ - - /* Return service status information */ RtlCopyMemory(lpServiceStatus, &lpService->Status, sizeof(SERVICE_STATUS));
- return ERROR_SUCCESS; + return dwError; }
_____
Modified: trunk/reactos/subsys/system/services/services.h --- trunk/reactos/subsys/system/services/services.h 2005-11-20 19:31:49 UTC (rev 19384) +++ trunk/reactos/subsys/system/services/services.h 2005-11-20 20:18:00 UTC (rev 19385) @@ -76,6 +76,15 @@
DWORD ScmMarkServiceForDelete(PSERVICE pService);
+/* driver.c */ + +NTSTATUS ScmLoadDriver(PSERVICE lpService); +DWORD ScmUnloadDriver(PSERVICE lpService); +DWORD ScmControlDriver(PSERVICE lpService, + DWORD dwControl, + LPSERVICE_STATUS lpServiceStatus); + + /* rpcserver.c */
VOID ScmStartRpcServer(VOID); _____
Modified: trunk/reactos/subsys/system/services/services.xml --- trunk/reactos/subsys/system/services/services.xml 2005-11-20 19:31:49 UTC (rev 19384) +++ trunk/reactos/subsys/system/services/services.xml 2005-11-20 20:18:00 UTC (rev 19385) @@ -12,6 +12,7 @@
<library>rpcrt4</library> <file>config.c</file> <file>database.c</file> + <file>driver.c</file> <file>rpcserver.c</file> <file>services.c</file> <file>services.rc</file>