- Prepare to delete marked services upon startup.
authorEric Kohl <eric.kohl@reactos.org>
Sun, 20 Nov 2005 20:18:00 +0000 (20:18 +0000)
committerEric Kohl <eric.kohl@reactos.org>
Sun, 20 Nov 2005 20:18:00 +0000 (20:18 +0000)
- ControlService: Implement unloading of drivers.

svn path=/trunk/; revision=19385

reactos/subsys/system/services/database.c
reactos/subsys/system/services/driver.c [new file with mode: 0644]
reactos/subsys/system/services/rpcserver.c
reactos/subsys/system/services/services.h
reactos/subsys/system/services/services.xml

index 127eacc..8473509 100644 (file)
@@ -404,6 +404,32 @@ ScmReadGroupList(VOID)
 }
 
 
+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 @@ ScmCreateServiceDatabase(VOID)
 
     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 @@ static NTSTATUS
 ScmStartService(PSERVICE Service,
                 PSERVICE_GROUP Group)
 {
-    WCHAR szDriverPath[MAX_PATH];
-    UNICODE_STRING DriverPath;
     NTSTATUS Status;
 
     DPRINT("ScmStartService() called\n");
@@ -845,21 +870,12 @@ ScmStartService(PSERVICE Service,
     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
     {
diff --git a/reactos/subsys/system/services/driver.c b/reactos/subsys/system/services/driver.c
new file mode 100644 (file)
index 0000000..24c634b
--- /dev/null
@@ -0,0 +1,113 @@
+/*\r
+ * driver.c\r
+ */\r
+\r
+/* INCLUDES *****************************************************************/\r
+\r
+#include "services.h"\r
+\r
+#define NDEBUG\r
+#include <debug.h>\r
+\r
+/* FUNCTIONS ****************************************************************/\r
+\r
+NTSTATUS\r
+ScmLoadDriver(PSERVICE lpService)\r
+{\r
+    WCHAR szDriverPath[MAX_PATH];\r
+    UNICODE_STRING DriverPath;\r
+    NTSTATUS Status;\r
+\r
+    /* Build the driver path */\r
+    wcscpy(szDriverPath,\r
+           L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");\r
+    wcscat(szDriverPath,\r
+           lpService->lpServiceName);\r
+\r
+    RtlInitUnicodeString(&DriverPath,\r
+                         szDriverPath);\r
+\r
+    /* FIXME: Acquire privilege */\r
+\r
+    DPRINT("  Path: %wZ\n", &DriverPath);\r
+    Status = NtLoadDriver(&DriverPath);\r
+\r
+    /* FIXME: Release privilege */\r
+\r
+    return Status;\r
+}\r
+\r
+\r
+DWORD\r
+ScmUnloadDriver(PSERVICE lpService)\r
+{\r
+    WCHAR szDriverPath[MAX_PATH];\r
+    UNICODE_STRING DriverPath;\r
+    NTSTATUS Status;\r
+    DWORD dwError = ERROR_SUCCESS;\r
+\r
+    /* Build the driver path */\r
+    wcscpy(szDriverPath,\r
+           L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");\r
+    wcscat(szDriverPath,\r
+           lpService->lpServiceName);\r
+\r
+    RtlInitUnicodeString(&DriverPath,\r
+                         szDriverPath);\r
+\r
+    /* FIXME: Acquire privilege */\r
+\r
+    Status = NtUnloadDriver(&DriverPath);\r
+\r
+    /* FIXME: Release privilege */\r
+\r
+    if (!NT_SUCCESS(Status))\r
+    {\r
+        dwError = RtlNtStatusToDosError(Status);\r
+    }\r
+\r
+    return dwError;\r
+}\r
+\r
+\r
+DWORD\r
+ScmControlDriver(PSERVICE lpService,\r
+                 DWORD dwControl,\r
+                 LPSERVICE_STATUS lpServiceStatus)\r
+{\r
+    DWORD dwError;\r
+\r
+    DPRINT("ScmControlDriver() called\n");\r
+\r
+    switch (dwControl)\r
+    {\r
+        case SERVICE_CONTROL_STOP:\r
+            if (lpService->Status.dwCurrentState != SERVICE_RUNNING)\r
+            {\r
+                dwError = ERROR_INVALID_SERVICE_CONTROL;\r
+                goto done;\r
+            }\r
+\r
+            dwError = ScmUnloadDriver(lpService);\r
+            if (dwError == ERROR_SUCCESS)\r
+            {\r
+                lpService->Status.dwControlsAccepted = 0;\r
+                lpService->Status.dwCurrentState = SERVICE_STOPPED;\r
+            }\r
+            break;\r
+\r
+        case SERVICE_CONTROL_INTERROGATE:\r
+            dwError = ERROR_INVALID_SERVICE_CONTROL;\r
+            break;\r
+\r
+        default:\r
+            dwError = ERROR_INVALID_SERVICE_CONTROL;\r
+    }\r
+\r
+done:;\r
+    DPRINT("ScmControlDriver() done (Erorr: %lu)\n", dwError);\r
+\r
+    return dwError;\r
+}\r
+\r
+/* EOF */\r
index 92039e6..35edd55 100644 (file)
@@ -281,6 +281,7 @@ ScmrControlService(handle_t BindingHandle,
     PSERVICE_HANDLE hSvc;
     PSERVICE lpService;
     ACCESS_MASK DesiredAccess;
+    DWORD dwError = ERROR_SUCCESS;
 
     DPRINT("ScmrControlService() called\n");
 
@@ -335,16 +336,30 @@ ScmrControlService(handle_t BindingHandle,
         return ERROR_INVALID_HANDLE;
     }
 
-
-    /* FIXME: Send control code to the service */
-
+    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;
+    }
 
     /* Return service status information */
     RtlCopyMemory(lpServiceStatus,
                   &lpService->Status,
                   sizeof(SERVICE_STATUS));
 
-    return ERROR_SUCCESS;
+    return dwError;
 }
 
 
index ce316c3..997ec6a 100644 (file)
@@ -76,6 +76,15 @@ DWORD ScmCreateNewServiceRecord(LPWSTR lpServiceName,
 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);
index ac9ae45..d8f3409 100644 (file)
@@ -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>