[ros-diffs] [ekohl] 45711: [SERVICES] - Generate unique service status handles. Services could set the status information of another service because the status handles were not guaranteed to be unique for all services. - Lock and unlock the service database when getting or setting service status information.

ekohl at svn.reactos.org ekohl at svn.reactos.org
Sat Feb 27 22:47:59 CET 2010


Author: ekohl
Date: Sat Feb 27 22:47:59 2010
New Revision: 45711

URL: http://svn.reactos.org/svn/reactos?rev=45711&view=rev
Log:
[SERVICES]
- Generate unique service status handles. Services could set the status information of another service because the status handles were not guaranteed to be unique for all services.
- Lock and unlock the service database when getting or setting service status information.

Modified:
    trunk/reactos/base/system/services/database.c
    trunk/reactos/base/system/services/rpcserver.c
    trunk/reactos/base/system/services/services.h
    trunk/reactos/dll/win32/advapi32/service/sctrl.c
    trunk/reactos/include/reactos/services/services.h

Modified: trunk/reactos/base/system/services/database.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/services/database.c?rev=45711&r1=45710&r2=45711&view=diff
==============================================================================
--- trunk/reactos/base/system/services/database.c [iso-8859-1] (original)
+++ trunk/reactos/base/system/services/database.c [iso-8859-1] Sat Feb 27 22:47:59 2010
@@ -107,37 +107,6 @@
                                            SERVICE,
                                            ServiceListEntry);
         if (CurrentService->dwResumeCount > dwResumeCount)
-        {
-            DPRINT("Found service: '%S'\n", CurrentService->lpDisplayName);
-            return CurrentService;
-        }
-
-        ServiceEntry = ServiceEntry->Flink;
-    }
-
-    DPRINT("Couldn't find a matching service\n");
-
-    return NULL;
-}
-
-
-PSERVICE
-ScmGetServiceEntryByClientHandle(HANDLE Handle)
-{
-    PLIST_ENTRY ServiceEntry;
-    PSERVICE CurrentService;
-
-    DPRINT("ScmGetServiceEntryByClientHandle() called\n");
-    DPRINT("looking for %p\n", Handle);
-
-    ServiceEntry = ServiceListHead.Flink;
-    while (ServiceEntry != &ServiceListHead)
-    {
-        CurrentService = CONTAINING_RECORD(ServiceEntry,
-                                           SERVICE,
-                                           ServiceListEntry);
-
-        if (CurrentService->hClient == Handle)
         {
             DPRINT("Found service: '%S'\n", CurrentService->lpDisplayName);
             return CurrentService;
@@ -728,8 +697,8 @@
         return ERROR_NOT_ENOUGH_MEMORY;
 
     ControlPacket->dwControl = dwControl;
-    ControlPacket->hClient = Service->hClient;
     ControlPacket->dwSize = TotalLength;
+    ControlPacket->hServiceStatus = (SERVICE_STATUS_HANDLE)Service;
     wcscpy(&ControlPacket->szArguments[0], Service->lpServiceName);
 
     /* Send the control packet */
@@ -793,7 +762,7 @@
         return ERROR_NOT_ENOUGH_MEMORY;
 
     ControlPacket->dwControl = SERVICE_CONTROL_START;
-    ControlPacket->hClient = Service->hClient;
+    ControlPacket->hServiceStatus = (SERVICE_STATUS_HANDLE)Service;
     ControlPacket->dwSize = TotalLength;
     Ptr = &ControlPacket->szArguments[0];
     wcscpy(Ptr, Service->lpServiceName);
@@ -850,6 +819,7 @@
     WCHAR NtControlPipeName[MAX_PATH + 1];
     HKEY hServiceCurrentKey = INVALID_HANDLE_VALUE;
     DWORD KeyDisposition;
+    DWORD dwProcessId;
 
     RtlInitUnicodeString(&ImagePath, NULL);
 
@@ -991,7 +961,7 @@
 
         /* Read SERVICE_STATUS_HANDLE from pipe */
         if (!ReadFile(Service->ControlPipeHandle,
-                      (LPVOID)&Service->hClient,
+                      (LPVOID)&dwProcessId,
                       sizeof(DWORD),
                       &dwRead,
                       NULL))
@@ -1002,7 +972,7 @@
         }
         else
         {
-            DPRINT("Received service status %lu\n", Service->hClient);
+            DPRINT("Received service process ID %lu\n", dwProcessId);
 
             /* Send start command */
             dwError = ScmSendStartCommand(Service, argc, argv);
@@ -1244,4 +1214,25 @@
     DPRINT("ScmGetBootAndSystemDriverState() done\n");
 }
 
+
+BOOL
+ScmLockDatabaseExclusive(VOID)
+{
+    return RtlAcquireResourceExclusive(&DatabaseLock, TRUE);
+}
+
+
+BOOL
+ScmLockDatabaseShared(VOID)
+{
+    return RtlAcquireResourceShared(&DatabaseLock, TRUE);
+}
+
+
+VOID
+ScmUnlockDatabase(VOID)
+{
+    RtlReleaseResource(&DatabaseLock);
+}
+
 /* EOF */

Modified: trunk/reactos/base/system/services/rpcserver.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/services/rpcserver.c?rev=45711&r1=45710&r2=45711&view=diff
==============================================================================
--- trunk/reactos/base/system/services/rpcserver.c [iso-8859-1] (original)
+++ trunk/reactos/base/system/services/rpcserver.c [iso-8859-1] Sat Feb 27 22:47:59 2010
@@ -978,10 +978,14 @@
         return ERROR_INVALID_HANDLE;
     }
 
+    ScmLockDatabaseShared();
+
     /* Return service status information */
     RtlCopyMemory(lpServiceStatus,
                   &lpService->Status,
                   sizeof(SERVICE_STATUS));
+
+    ScmUnlockDatabase();
 
     return ERROR_SUCCESS;
 }
@@ -1030,7 +1034,7 @@
         return ERROR_INVALID_HANDLE;
     }
 
-    lpService = ScmGetServiceEntryByClientHandle((HANDLE)hServiceStatus);
+    lpService = (PSERVICE)hServiceStatus;
     if (lpService == NULL)
     {
         DPRINT("lpService == NULL!\n");
@@ -1059,10 +1063,13 @@
         return ERROR_INVALID_DATA;
     }
 
+    ScmLockDatabaseExclusive();
 
     RtlCopyMemory(&lpService->Status,
                   lpServiceStatus,
                   sizeof(SERVICE_STATUS));
+
+    ScmUnlockDatabase();
 
     DPRINT("Set %S to %lu\n", lpService->lpDisplayName, lpService->Status.dwCurrentState);
     DPRINT("RSetServiceStatus() done\n");

Modified: trunk/reactos/base/system/services/services.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/services/services.h?rev=45711&r1=45710&r2=45711&view=diff
==============================================================================
--- trunk/reactos/base/system/services/services.h [iso-8859-1] (original)
+++ trunk/reactos/base/system/services/services.h [iso-8859-1] Sat Feb 27 22:47:59 2010
@@ -42,7 +42,6 @@
     DWORD dwResumeCount;
     DWORD dwRefCount;
 
-    CLIENT_HANDLE hClient;
     SERVICE_STATUS Status;
     DWORD dwStartType;
     DWORD dwErrorControl;
@@ -112,7 +111,6 @@
 PSERVICE ScmGetServiceEntryByName(LPCWSTR lpServiceName);
 PSERVICE ScmGetServiceEntryByDisplayName(LPCWSTR lpDisplayName);
 PSERVICE ScmGetServiceEntryByResumeCount(DWORD dwResumeCount);
-PSERVICE ScmGetServiceEntryByClientHandle(HANDLE Handle);
 DWORD ScmCreateNewServiceRecord(LPCWSTR lpServiceName,
                                 PSERVICE *lpServiceRecord);
 VOID ScmDeleteServiceRecord(PSERVICE lpService);
@@ -121,6 +119,11 @@
 DWORD ScmControlService(PSERVICE Service,
                         DWORD dwControl,
                         LPSERVICE_STATUS lpServiceStatus);
+
+BOOL ScmLockDatabaseExclusive(VOID);
+BOOL ScmLockDatabaseShared(VOID);
+VOID ScmUnlockDatabase(VOID);
+
 
 /* driver.c */
 

Modified: trunk/reactos/dll/win32/advapi32/service/sctrl.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/advapi32/service/sctrl.c?rev=45711&r1=45710&r2=45711&view=diff
==============================================================================
--- trunk/reactos/dll/win32/advapi32/service/sctrl.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/advapi32/service/sctrl.c [iso-8859-1] Sat Feb 27 22:47:59 2010
@@ -22,7 +22,7 @@
 
 typedef struct _ACTIVE_SERVICE
 {
-    CLIENT_HANDLE hService;
+    SERVICE_STATUS_HANDLE hServiceStatus;
     UNICODE_STRING ServiceName;
     union
     {
@@ -32,7 +32,6 @@
     LPHANDLER_FUNCTION HandlerFunction;
     LPHANDLER_FUNCTION_EX HandlerFunctionEx;
     LPVOID HandlerContext;
-    SERVICE_STATUS ServiceStatus;
     BOOL bUnicode;
     LPWSTR Arguments;
 } ACTIVE_SERVICE, *PACTIVE_SERVICE;
@@ -199,6 +198,7 @@
     NTSTATUS Status;
     WCHAR NtControlPipeName[MAX_PATH + 1];
     RTL_QUERY_REGISTRY_TABLE QueryTable[2];
+    DWORD dwProcessId;
 
     /* Get the service number and create the named pipe */
     RtlZeroMemory(&QueryTable,
@@ -249,37 +249,34 @@
         return ERROR_FAILED_SERVICE_CONTROLLER_CONNECT;
     }
 
-    /* Share the SERVICE_HANDLE handle with the SCM */
+    /* Pass the ProcessId to the SCM */
+    dwProcessId = GetCurrentProcessId();
     WriteFile(*hPipe,
-              (DWORD *)&lpActiveServices->hService,
-              sizeof(CLIENT_HANDLE),
+              &dwProcessId,
+              sizeof(DWORD),
               &dwBytesWritten,
               NULL);
 
-    TRACE("Sent SERVICE_HANDLE %lu\n", lpActiveServices->hService);
+    TRACE("Sent Process ID %lu\n", dwProcessId);
+
 
     return ERROR_SUCCESS;
 }
 
 
 static DWORD
-ScStartService(PSCM_CONTROL_PACKET ControlPacket)
-{
-    PACTIVE_SERVICE lpService;
+ScStartService(PACTIVE_SERVICE lpService,
+               PSCM_CONTROL_PACKET ControlPacket)
+{
     HANDLE ThreadHandle;
     DWORD ThreadId;
 
     TRACE("ScStartService() called\n");
-    TRACE("client handle: %lu\n", ControlPacket->hClient);
     TRACE("Size: %lu\n", ControlPacket->dwSize);
     TRACE("Service: %S\n", &ControlPacket->szArguments[0]);
 
-    lpService = (PACTIVE_SERVICE)ControlPacket->hClient;
-    if (lpService == NULL)
-    {
-        TRACE("Service not found\n");
-        return ERROR_SERVICE_DOES_NOT_EXIST;
-    }
+    /* Set the service status handle */
+    lpService->hServiceStatus = ControlPacket->hServiceStatus;
 
     lpService->Arguments = HeapAlloc(GetProcessHeap(),
                                      HEAP_ZERO_MEMORY,
@@ -309,20 +306,12 @@
 
 
 static DWORD
-ScControlService(PSCM_CONTROL_PACKET ControlPacket)
-{
-    PACTIVE_SERVICE lpService;
-
+ScControlService(PACTIVE_SERVICE lpService,
+                 PSCM_CONTROL_PACKET ControlPacket)
+{
     TRACE("ScControlService() called\n");
     TRACE("Size: %lu\n", ControlPacket->dwSize);
     TRACE("Service: %S\n", &ControlPacket->szArguments[0]);
-
-    lpService = (PACTIVE_SERVICE)ControlPacket->hClient;
-    if (lpService == NULL)
-    {
-        TRACE("Service not found\n");
-        return ERROR_SERVICE_DOES_NOT_EXIST;
-    }
 
     if (lpService->HandlerFunction)
     {
@@ -356,6 +345,8 @@
     DWORD Count;
     BOOL bResult;
     DWORD dwRunningServices = 0;
+    LPWSTR lpServiceName;
+    PACTIVE_SERVICE lpService;
 
     TRACE("ScDispatcherLoop() called\n");
 
@@ -379,25 +370,32 @@
             return FALSE;
         }
 
-        /* Execute command */
-        switch (ControlPacket->dwControl)
-        {
-            case SERVICE_CONTROL_START:
-                TRACE("Start command - recieved SERVICE_CONTROL_START\n");
-                if (ScStartService(ControlPacket) == ERROR_SUCCESS)
-                    dwRunningServices++;
-                break;
-
-            case SERVICE_CONTROL_STOP:
-                TRACE("Stop command - recieved SERVICE_CONTROL_STOP\n");
-                if (ScControlService(ControlPacket) == ERROR_SUCCESS)
-                    dwRunningServices--;
-                break;
-
-            default:
-                TRACE("Command %lu received", ControlPacket->dwControl);
-                ScControlService(ControlPacket);
-                continue;
+        lpServiceName = &ControlPacket->szArguments[0];
+        TRACE("Service: %S\n", lpServiceName);
+
+        lpService = ScLookupServiceByServiceName(lpServiceName);
+        if (lpService != NULL)
+        {
+            /* Execute command */
+            switch (ControlPacket->dwControl)
+            {
+                case SERVICE_CONTROL_START:
+                    TRACE("Start command - recieved SERVICE_CONTROL_START\n");
+                    if (ScStartService(lpService, ControlPacket) == ERROR_SUCCESS)
+                        dwRunningServices++;
+                    break;
+
+                case SERVICE_CONTROL_STOP:
+                    TRACE("Stop command - recieved SERVICE_CONTROL_STOP\n");
+                    if (ScControlService(lpService, ControlPacket) == ERROR_SUCCESS)
+                        dwRunningServices--;
+                    break;
+
+                default:
+                    TRACE("Command %lu received", ControlPacket->dwControl);
+                    ScControlService(lpService, ControlPacket);
+                    continue;
+            }
         }
 
         if (dwRunningServices == 0)
@@ -461,9 +459,9 @@
     Service->HandlerFunction = lpHandlerProc;
     Service->HandlerFunctionEx = NULL;
 
-    TRACE("RegisterServiceCtrlHandler returning %lu\n", Service->hService);
-
-    return (SERVICE_STATUS_HANDLE)Service->hService;
+    TRACE("RegisterServiceCtrlHandler returning %lu\n", Service->hServiceStatus);
+
+    return Service->hServiceStatus;
 }
 
 
@@ -520,9 +518,9 @@
     Service->HandlerFunctionEx = lpHandlerProc;
     Service->HandlerContext = lpContext;
 
-    TRACE("RegisterServiceCtrlHandlerEx returning %lu\n", Service->hService);
-
-    return (SERVICE_STATUS_HANDLE)Service->hService;
+    TRACE("RegisterServiceCtrlHandlerEx returning %lu\n", Service->hServiceStatus);
+
+    return Service->hServiceStatus;
 }
 
 
@@ -683,7 +681,7 @@
         RtlCreateUnicodeStringFromAsciiz(&lpActiveServices[i].ServiceName,
                                          lpServiceStartTable[i].lpServiceName);
         lpActiveServices[i].Main.lpFuncA = lpServiceStartTable[i].lpServiceProc;
-        lpActiveServices[i].hService = (CLIENT_HANDLE)&lpActiveServices[i];
+        lpActiveServices[i].hServiceStatus = 0;
         lpActiveServices[i].bUnicode = FALSE;
     }
 
@@ -773,7 +771,7 @@
         RtlCreateUnicodeString(&lpActiveServices[i].ServiceName,
                                lpServiceStartTable[i].lpServiceName);
         lpActiveServices[i].Main.lpFuncW = lpServiceStartTable[i].lpServiceProc;
-        lpActiveServices[i].hService = (CLIENT_HANDLE)&lpActiveServices[i];
+        lpActiveServices[i].hServiceStatus = 0;
         lpActiveServices[i].bUnicode = TRUE;
     }
 

Modified: trunk/reactos/include/reactos/services/services.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/reactos/services/services.h?rev=45711&r1=45710&r2=45711&view=diff
==============================================================================
--- trunk/reactos/include/reactos/services/services.h [iso-8859-1] (original)
+++ trunk/reactos/include/reactos/services/services.h [iso-8859-1] Sat Feb 27 22:47:59 2010
@@ -11,12 +11,10 @@
 
 #define SERVICE_CONTROL_START 0
 
-DECLARE_HANDLE(CLIENT_HANDLE);
-
 typedef struct _SCM_CONTROL_PACKET
 {
     DWORD dwControl;
-    CLIENT_HANDLE hClient;
+    SERVICE_STATUS_HANDLE hServiceStatus;
     DWORD dwSize;
     WCHAR szArguments[1];
 } SCM_CONTROL_PACKET, *PSCM_CONTROL_PACKET;




More information about the Ros-diffs mailing list