From: Eric Kohl Date: Tue, 16 Sep 2008 19:47:16 +0000 (+0000) Subject: RSetServiceStatus: X-Git-Tag: backups/ros-branch-0_3_7@37061~202 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=7fc5d5420a77a0f470760c7a531a79079d996f05 RSetServiceStatus: - 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 --- diff --git a/reactos/base/system/services/rpcserver.c b/reactos/base/system/services/rpcserver.c index 64353ed51f4..b0030dcf35b 100644 --- a/reactos/base/system/services/rpcserver.c +++ b/reactos/base/system/services/rpcserver.c @@ -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, @@ -991,9 +1011,20 @@ DWORD RSetServiceStatus( 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) @@ -1002,6 +1033,30 @@ DWORD RSetServiceStatus( 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));