RSetServiceStatus:
authorEric Kohl <eric.kohl@reactos.org>
Tue, 16 Sep 2008 19:47:16 +0000 (19:47 +0000)
committerEric Kohl <eric.kohl@reactos.org>
Tue, 16 Sep 2008 19:47:16 +0000 (19:47 +0000)
- Don't fail if the system is shutting down because services must report successful shutdown to the service manager while the system is shutting down.
- Add some more parameter checks.

svn path=/trunk/; revision=36272

reactos/base/system/services/rpcserver.c

index 64353ed..b0030dc 100644 (file)
@@ -982,6 +982,26 @@ DWORD RQueryServiceStatus(
 }
 
 
 }
 
 
+static BOOL
+ScmIsValidServiceState(DWORD dwCurrentState)
+{
+    switch (dwCurrentState)
+    {
+        case SERVICE_STOPPED:
+        case SERVICE_START_PENDING:
+        case SERVICE_STOP_PENDING:
+        case SERVICE_RUNNING:
+        case SERVICE_CONTINUE_PENDING:
+        case SERVICE_PAUSE_PENDING:
+        case SERVICE_PAUSED:
+            return TRUE;
+
+        default:
+            return FALSE;
+    }
+}
+
+
 /* Function 7 */
 DWORD RSetServiceStatus(
     handle_t BindingHandle,
 /* Function 7 */
 DWORD RSetServiceStatus(
     handle_t BindingHandle,
@@ -991,9 +1011,20 @@ DWORD RSetServiceStatus(
     PSERVICE lpService;
 
     DPRINT("RSetServiceStatus() called\n");
     PSERVICE lpService;
 
     DPRINT("RSetServiceStatus() called\n");
-
-    if (ScmShutdown)
-        return ERROR_SHUTDOWN_IN_PROGRESS;
+    DPRINT("hServiceStatus = %p\n", hServiceStatus);
+    DPRINT("dwServiceType = %lu\n", lpServiceStatus->dwServiceType);
+    DPRINT("dwCurrentState = %lu\n", lpServiceStatus->dwCurrentState);
+    DPRINT("dwControlsAccepted = %lu\n", lpServiceStatus->dwControlsAccepted);
+    DPRINT("dwWin32ExitCode = %lu\n", lpServiceStatus->dwWin32ExitCode);
+    DPRINT("dwServiceSpecificExitCode = %lu\n", lpServiceStatus->dwServiceSpecificExitCode);
+    DPRINT("dwCheckPoint = %lu\n", lpServiceStatus->dwCheckPoint);
+    DPRINT("dwWaitHint = %lu\n", lpServiceStatus->dwWaitHint);
+
+    if (hServiceStatus == 0)
+    {
+        DPRINT1("hServiceStatus == NULL!\n");
+        return ERROR_INVALID_HANDLE;
+    }
 
     lpService = ScmGetServiceEntryByClientHandle((ULONG)hServiceStatus);
     if (lpService == NULL)
 
     lpService = ScmGetServiceEntryByClientHandle((ULONG)hServiceStatus);
     if (lpService == NULL)
@@ -1002,6 +1033,30 @@ DWORD RSetServiceStatus(
         return ERROR_INVALID_HANDLE;
     }
 
         return ERROR_INVALID_HANDLE;
     }
 
+    /* Check current state */
+    if (!ScmIsValidServiceState(lpServiceStatus->dwCurrentState))
+    {
+        DPRINT1("Invalid service state!\n");
+        return ERROR_INVALID_DATA;
+    }
+
+    /* Check service type */
+    if (!(lpServiceStatus->dwServiceType & SERVICE_WIN32) &&
+         (lpServiceStatus->dwServiceType & SERVICE_DRIVER))
+    {
+        DPRINT1("Invalid service type!\n");
+        return ERROR_INVALID_DATA;
+    }
+
+    /* Check accepted controls */
+    if (lpServiceStatus->dwControlsAccepted == 0 ||
+        lpServiceStatus->dwControlsAccepted & ~0xFF)
+    {
+        DPRINT1("Invalid controls accepted!\n");
+        return ERROR_INVALID_DATA;
+    }
+
+
     RtlCopyMemory(&lpService->Status,
                   lpServiceStatus,
                   sizeof(SERVICE_STATUS));
     RtlCopyMemory(&lpService->Status,
                   lpServiceStatus,
                   sizeof(SERVICE_STATUS));