[SERVICES/ADVAPI32]
authorEric Kohl <eric.kohl@reactos.org>
Sun, 21 Aug 2011 15:35:19 +0000 (15:35 +0000)
committerEric Kohl <eric.kohl@reactos.org>
Sun, 21 Aug 2011 15:35:19 +0000 (15:35 +0000)
Rewrite the command packet transfer code between the service control manager (services.exe) and the service control dispatcher (advapi32.dll). The service name is no longer stored in an array of WCHARs at the end of the command packet. The service name is now stored behind the fixed size command packet header using an offset value in the header to determine the start of the string. The same method will be used to store start arguments to the service dispatcher, but it is not fully implemented yet.

svn path=/trunk/; revision=53358

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

index 1c2cc7e..8b22e36 100644 (file)
@@ -918,33 +918,43 @@ ScmControlService(PSERVICE Service,
 
     DWORD dwWriteCount = 0;
     DWORD dwReadCount = 0;
-    DWORD TotalLength;
+    DWORD PacketSize;
+    PWSTR Ptr;
     DWORD dwError = ERROR_SUCCESS;
 
     DPRINT("ScmControlService() called\n");
 
     EnterCriticalSection(&ControlServiceCriticalSection);
 
-    TotalLength = wcslen(Service->lpServiceName) + 1;
+    /* Calculate the total length of the start command line */
+    PacketSize = sizeof(SCM_CONTROL_PACKET);
+    PacketSize += (wcslen(Service->lpServiceName) + 1) * sizeof(WCHAR);
 
     ControlPacket = (SCM_CONTROL_PACKET*)HeapAlloc(GetProcessHeap(),
                                                    HEAP_ZERO_MEMORY,
-                                                   sizeof(SCM_CONTROL_PACKET) + (TotalLength * sizeof(WCHAR)));
+                                                   PacketSize);
     if (ControlPacket == NULL)
     {
         LeaveCriticalSection(&ControlServiceCriticalSection);
         return ERROR_NOT_ENOUGH_MEMORY;
     }
 
+    ControlPacket->dwSize = PacketSize;
     ControlPacket->dwControl = dwControl;
-    ControlPacket->dwSize = TotalLength;
     ControlPacket->hServiceStatus = (SERVICE_STATUS_HANDLE)Service;
-    wcscpy(&ControlPacket->szArguments[0], Service->lpServiceName);
+
+    ControlPacket->dwServiceNameOffset = sizeof(SCM_CONTROL_PACKET);
+
+    Ptr = (PWSTR)((PBYTE)ControlPacket + ControlPacket->dwServiceNameOffset);
+    wcscpy(Ptr, Service->lpServiceName);
+
+    ControlPacket->dwArgumentsCount = 0;
+    ControlPacket->dwArgumentsOffset = 0;
 
     /* Send the control packet */
     WriteFile(Service->lpImage->hControlPipe,
               ControlPacket,
-              sizeof(SCM_CONTROL_PACKET) + (TotalLength * sizeof(WCHAR)),
+              PacketSize,
               &dwWriteCount,
               NULL);
 
@@ -986,9 +996,7 @@ ScmSendStartCommand(PSERVICE Service,
 {
     PSCM_CONTROL_PACKET ControlPacket;
     SCM_REPLY_PACKET ReplyPacket;
-    DWORD TotalLength;
-    DWORD ArgsLength = 0;
-    DWORD Length;
+    DWORD PacketSize;
     PWSTR Ptr;
     DWORD dwWriteCount = 0;
     DWORD dwReadCount = 0;
@@ -998,52 +1006,59 @@ ScmSendStartCommand(PSERVICE Service,
     DPRINT("ScmSendStartCommand() called\n");
 
     /* Calculate the total length of the start command line */
-    TotalLength = wcslen(Service->lpServiceName) + 1;
-    if (argc > 0)
+    PacketSize = sizeof(SCM_CONTROL_PACKET);
+    PacketSize += (wcslen(Service->lpServiceName) + 1) * sizeof(WCHAR);
+
+    /* Calculate the required packet size for the start arguments */
+    if (argc > 0 && argv != NULL)
     {
+        PacketSize = ALIGN_UP(PacketSize, LPWSTR);
+
+        DPRINT("Argc: %lu\n", argc);
         for (i = 0; i < argc; i++)
         {
-            DPRINT("Arg: %S\n", argv[i]);
-            Length = wcslen(argv[i]) + 1;
-            TotalLength += Length;
-            ArgsLength += Length;
+            DPRINT("Argv[%lu]: %S\n", i, argv[i]);
+            PacketSize += (wcslen(argv[i]) + 1) * sizeof(WCHAR) + sizeof(PWSTR);
         }
     }
-    TotalLength++;
-    DPRINT("ArgsLength: %ld TotalLength: %ld\n", ArgsLength, TotalLength);
 
     /* Allocate a control packet */
     ControlPacket = (SCM_CONTROL_PACKET*)HeapAlloc(GetProcessHeap(),
                                                    HEAP_ZERO_MEMORY,
-                                                   sizeof(SCM_CONTROL_PACKET) + (TotalLength - 1) * sizeof(WCHAR));
+                                                   PacketSize);
     if (ControlPacket == NULL)
         return ERROR_NOT_ENOUGH_MEMORY;
 
+    ControlPacket->dwSize = PacketSize;
     ControlPacket->dwControl = SERVICE_CONTROL_START;
     ControlPacket->hServiceStatus = (SERVICE_STATUS_HANDLE)Service;
-    ControlPacket->dwSize = TotalLength;
-    Ptr = &ControlPacket->szArguments[0];
+    ControlPacket->dwServiceNameOffset = sizeof(SCM_CONTROL_PACKET);
+
+    Ptr = (PWSTR)((PBYTE)ControlPacket + ControlPacket->dwServiceNameOffset);
     wcscpy(Ptr, Service->lpServiceName);
-    Ptr += (wcslen(Service->lpServiceName) + 1);
+
+    ControlPacket->dwArgumentsCount = 0;
+    ControlPacket->dwArgumentsOffset = 0;
 
     /* Copy argument list */
-    if (argc > 0)
+    if (argc > 0 && argv != NULL)
     {
-        UNIMPLEMENTED;
-        DPRINT1("Arguments sent to service ignored!\n");
+//        Ptr += wcslen(Service->lpServiceName) + 1;
+//        Ptr = ALIGN_UP_POINTER(Ptr, LPWSTR);
+
+//        ControlPacket->dwArgumentsOffset = (DWORD)((INT_PTR)Ptr - (INT_PTR)ControlPacket);
+
+
 #if 0
         memcpy(Ptr, Arguments, ArgsLength);
         Ptr += ArgsLength;
 #endif
     }
 
-    /* Terminate the argument list */
-    *Ptr = 0;
-
     /* Send the start command */
     WriteFile(Service->lpImage->hControlPipe,
               ControlPacket,
-              sizeof(SCM_CONTROL_PACKET) + (TotalLength - 1) * sizeof(WCHAR),
+              PacketSize,
               &dwWriteCount,
               NULL);
 
index 6f909a2..6a78959 100644 (file)
@@ -11,7 +11,6 @@
 /* INCLUDES ****************************************************************/
 
 #include "services.h"
-#include "svcctl_s.h"
 
 #define NDEBUG
 #include <debug.h>
@@ -2868,8 +2867,17 @@ DWORD RStartServiceW(
     DWORD dwError = ERROR_SUCCESS;
     PSERVICE_HANDLE hSvc;
     PSERVICE lpService = NULL;
+    DWORD i;
 
-    DPRINT("RStartServiceW() called\n");
+    DPRINT("RStartServiceW(%p %lu %p) called\n", hService, argc, argv);
+    DPRINT("  argc: %lu\n", argc);
+    if (argv != NULL)
+    {
+        for (i = 0; i < argc; i++)
+        {
+            DPRINT("  argv[%lu]: %S\n", i, argv[i]);
+        }
+    }
 
     if (ScmShutdown)
         return ERROR_SHUTDOWN_IN_PROGRESS;
@@ -2901,13 +2909,8 @@ DWORD RStartServiceW(
     if (lpService->bDeleted)
         return ERROR_SERVICE_MARKED_FOR_DELETE;
 
-    if (argv) {
-        UNIMPLEMENTED;
-        argv = NULL;
-    }
-
     /* Start the service */
-    dwError = ScmStartService(lpService, argc, (LPWSTR *)argv);
+    dwError = ScmStartService(lpService, argc, (LPWSTR*)argv);
 
     return dwError;
 }
index 210f8db..c22f95a 100644 (file)
@@ -11,6 +11,7 @@
 #include <ndk/obfuncs.h>
 #include <ndk/rtlfuncs.h>
 #include <services/services.h>
+#include "svcctl_s.h"
 
 
 typedef struct _SERVICE_GROUP
index 1a1b31e..c77f133 100644 (file)
@@ -125,14 +125,20 @@ ScLookupServiceByServiceName(LPCWSTR lpServiceName)
 {
     DWORD i;
 
+    TRACE("ScLookupServiceByServiceName(%S) called\n", lpServiceName);
+
     for (i = 0; i < dwActiveServiceCount; i++)
     {
+        TRACE("Checking %S\n", lpActiveServices[i].ServiceName.Buffer);
         if (_wcsicmp(lpActiveServices[i].ServiceName.Buffer, lpServiceName) == 0)
         {
+            TRACE("Found!\n");
             return &lpActiveServices[i];
         }
     }
 
+    TRACE("No service found!\n");
+
     SetLastError(ERROR_SERVICE_DOES_NOT_EXIST);
 
     return NULL;
@@ -344,23 +350,52 @@ ScStartService(PACTIVE_SERVICE lpService,
 {
     HANDLE ThreadHandle;
     DWORD ThreadId;
+    PWSTR pServiceName;
+    PWSTR Ptr;
+    DWORD dwArgumentsSize;
 
     TRACE("ScStartService() called\n");
     TRACE("Size: %lu\n", ControlPacket->dwSize);
-    TRACE("Service: %S\n", &ControlPacket->szArguments[0]);
+    TRACE("Service: %S\n", (PWSTR)((PBYTE)ControlPacket + ControlPacket->dwServiceNameOffset));
 
     /* Set the service status handle */
     lpService->hServiceStatus = ControlPacket->hServiceStatus;
 
+    pServiceName = (PWSTR)((PBYTE)ControlPacket + ControlPacket->dwServiceNameOffset);
+
+    /* Get the service name size */
+    dwArgumentsSize = (wcslen(pServiceName) + 1) * sizeof(WCHAR);
+
+    /* Get the size of the service start arguments */
+    if (ControlPacket->dwArgumentsCount > 0 &&
+        ControlPacket->dwArgumentsOffset != 0)
+    {
+        /* FIXME */
+#if 0
+        dwArgumentSize += (wcslen(...) + 1) * sizeof(WCHAR);
+#endif
+    }
+
     lpService->Arguments = HeapAlloc(GetProcessHeap(),
                                      HEAP_ZERO_MEMORY,
-                                     (ControlPacket->dwSize + 1) * sizeof(WCHAR));
+                                     dwArgumentsSize + sizeof(WCHAR));
     if (lpService->Arguments == NULL)
         return ERROR_OUTOFMEMORY;
 
-    memcpy(lpService->Arguments,
-           ControlPacket->szArguments,
-           ControlPacket->dwSize * sizeof(WCHAR));
+    Ptr = lpService->Arguments;
+
+    /* Add the service name as first argument */
+    wcscpy(Ptr, pServiceName);
+    Ptr += (wcslen(pServiceName) + 1);
+
+    /* Add service start arguments */
+    if (ControlPacket->dwArgumentsCount > 0 &&
+        ControlPacket->dwArgumentsOffset != 0)
+    {
+        /* FIXME */
+    }
+
+    *Ptr = 0;
 
     /* invoke the services entry point and implement the command loop */
     ThreadHandle = CreateThread(NULL,
@@ -385,7 +420,7 @@ ScControlService(PACTIVE_SERVICE lpService,
 {
     TRACE("ScControlService() called\n");
     TRACE("Size: %lu\n", ControlPacket->dwSize);
-    TRACE("Service: %S\n", &ControlPacket->szArguments[0]);
+    TRACE("Service: %S\n", (PWSTR)((PBYTE)ControlPacket + ControlPacket->dwServiceNameOffset));
 
     if (lpService->HandlerFunction)
     {
@@ -446,7 +481,7 @@ ScServiceDispatcher(HANDLE hPipe,
             return FALSE;
         }
 
-        lpServiceName = &ControlPacket->szArguments[0];
+        lpServiceName = (LPWSTR)((PBYTE)ControlPacket + ControlPacket->dwServiceNameOffset);
         TRACE("Service: %S\n", lpServiceName);
 
         lpService = ScLookupServiceByServiceName(lpServiceName);
index 009c250..9a46a61 100644 (file)
 
 typedef struct _SCM_CONTROL_PACKET
 {
+    DWORD dwSize;
     DWORD dwControl;
     SERVICE_STATUS_HANDLE hServiceStatus;
-    DWORD dwSize;
-    WCHAR szArguments[1];
+    DWORD dwServiceNameOffset;
+    DWORD dwArgumentsCount;
+    DWORD dwArgumentsOffset;
 } SCM_CONTROL_PACKET, *PSCM_CONTROL_PACKET;
 
 typedef struct _SCM_REPLY_PACKET