Author: ekohl
Date: Sat Sep  3 19:47:56 2011
New Revision: 53564

URL: http://svn.reactos.org/svn/reactos?rev=53564&view=rev
Log:
[SERVICES/ADVAPI32]
Pass the service start argument vector to the started service main function. 
ANSI services are not supported yet.

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

Modified: trunk/reactos/base/system/services/database.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/services/database.c?rev=53564&r1=53563&r2=53564&view=diff
==============================================================================
--- trunk/reactos/base/system/services/database.c [iso-8859-1] (original)
+++ trunk/reactos/base/system/services/database.c [iso-8859-1] Sat Sep  3 
19:47:56 2011
@@ -1002,6 +1002,8 @@
     DWORD dwReadCount = 0;
     DWORD dwError = ERROR_SUCCESS;
     DWORD i;
+    PWSTR *pOffPtr;
+    PWSTR pArgPtr;
 
     DPRINT("ScmSendStartCommand() called\n");
 
@@ -1043,16 +1045,25 @@
     /* Copy argument list */
     if (argc > 0 && argv != NULL)
     {
-//        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
+        Ptr += wcslen(Service->lpServiceName) + 1;
+        pOffPtr = (PWSTR*)ALIGN_UP_POINTER(Ptr, PWSTR);
+        pArgPtr = (PWSTR)((ULONG_PTR)pOffPtr + argc * sizeof(PWSTR));
+
+        ControlPacket->dwArgumentsCount = argc;
+        ControlPacket->dwArgumentsOffset = (DWORD)((ULONG_PTR)pOffPtr - 
(ULONG_PTR)ControlPacket);
+
+        DPRINT("dwArgumentsCount: %lu\n", ControlPacket->dwArgumentsCount);
+        DPRINT("dwArgumentsOffset: %lu\n", ControlPacket->dwArgumentsOffset);
+
+        for (i = 0; i < argc; i++)
+        {
+             wcscpy(pArgPtr, argv[i]);
+             *pOffPtr = (PWSTR)((ULONG_PTR)pArgPtr - (ULONG_PTR)pOffPtr);
+             DPRINT("offset: %p\n", *pOffPtr);
+
+             pArgPtr += wcslen(argv[i]) + 1;
+             pOffPtr++;
+        }
     }
 
     /* Send the start command */

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=53564&r1=53563&r2=53564&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 Sep  3 
19:47:56 2011
@@ -18,20 +18,35 @@
 
 /* TYPES *********************************************************************/
 
+typedef struct _SERVICE_THREAD_PARAMSA
+{
+    LPSERVICE_MAIN_FUNCTIONA lpServiceMain;
+    DWORD dwArgCount;
+    LPSTR *lpArgVector;
+} SERVICE_THREAD_PARAMSA, *PSERVICE_THREAD_PARAMSA;
+
+
+typedef struct _SERVICE_THREAD_PARAMSW
+{
+    LPSERVICE_MAIN_FUNCTIONW lpServiceMain;
+    DWORD dwArgCount;
+    LPWSTR *lpArgVector;
+} SERVICE_THREAD_PARAMSW, *PSERVICE_THREAD_PARAMSW;
+
+
 typedef struct _ACTIVE_SERVICE
 {
     SERVICE_STATUS_HANDLE hServiceStatus;
     UNICODE_STRING ServiceName;
     union
     {
-        LPSERVICE_MAIN_FUNCTIONA lpFuncA;
-        LPSERVICE_MAIN_FUNCTIONW lpFuncW;
-    } Main;
+        SERVICE_THREAD_PARAMSA A;
+        SERVICE_THREAD_PARAMSW W;
+    } ThreadParams;
     LPHANDLER_FUNCTION HandlerFunction;
     LPHANDLER_FUNCTION_EX HandlerFunctionEx;
     LPVOID HandlerContext;
     BOOL bUnicode;
-    LPWSTR Arguments;
 } ACTIVE_SERVICE, *PACTIVE_SERVICE;
 
 
@@ -148,59 +163,169 @@
 static DWORD WINAPI
 ScServiceMainStub(LPVOID Context)
 {
-    PACTIVE_SERVICE lpService;
-    DWORD dwArgCount = 0;
-    DWORD dwLength = 0;
-    DWORD dwLen;
-    LPWSTR lpPtr;
-
-    lpService = (PACTIVE_SERVICE)Context;
+    PACTIVE_SERVICE lpService = (PACTIVE_SERVICE)Context;
 
     TRACE("ScServiceMainStub() called\n");
 
-    /* Count arguments */
-    lpPtr = lpService->Arguments;
-    while (*lpPtr)
-    {
-        TRACE("arg: %S\n", lpPtr);
-        dwLen = wcslen(lpPtr) + 1;
-        dwArgCount++;
-        dwLength += dwLen;
-        lpPtr += dwLen;
-    }
-    TRACE("dwArgCount: %ld\ndwLength: %ld\n", dwArgCount, dwLength);
-
-    /* Build the argument vector and call the main service routine */
+    /* Call the main service routine and free the arguments vector */
     if (lpService->bUnicode)
     {
-        LPWSTR *lpArgVector;
-        LPWSTR Ptr;
-
-        lpArgVector = HeapAlloc(GetProcessHeap(),
-                                HEAP_ZERO_MEMORY,
-                                (dwArgCount + 1) * sizeof(LPWSTR));
-        if (lpArgVector == NULL)
-            return ERROR_OUTOFMEMORY;
-
-        dwArgCount = 0;
-        Ptr = lpService->Arguments;
-        while (*Ptr)
-        {
-            lpArgVector[dwArgCount] = Ptr;
-
-            dwArgCount++;
-            Ptr += (wcslen(Ptr) + 1);
-        }
-        lpArgVector[dwArgCount] = NULL;
-
-        (lpService->Main.lpFuncW)(dwArgCount, lpArgVector);
-
-        HeapFree(GetProcessHeap(),
-                 0,
-                 lpArgVector);
+        
(lpService->ThreadParams.W.lpServiceMain)(lpService->ThreadParams.W.dwArgCount,
+                                                  
lpService->ThreadParams.W.lpArgVector);
+
+        if (lpService->ThreadParams.A.lpArgVector != NULL)
+        {
+            HeapFree(GetProcessHeap(),
+                     0,
+                     lpService->ThreadParams.W.lpArgVector);
+
+            lpService->ThreadParams.W.lpArgVector = NULL;
+            lpService->ThreadParams.W.dwArgCount = 0;
+        }
     }
     else
     {
+        
(lpService->ThreadParams.A.lpServiceMain)(lpService->ThreadParams.A.dwArgCount,
+                                                  
lpService->ThreadParams.A.lpArgVector);
+
+        if (lpService->ThreadParams.A.lpArgVector != NULL)
+        {
+            HeapFree(GetProcessHeap(),
+                     0,
+                     lpService->ThreadParams.A.lpArgVector);
+
+            lpService->ThreadParams.A.lpArgVector = NULL;
+            lpService->ThreadParams.A.dwArgCount = 0;
+        }
+    }
+
+    return ERROR_SUCCESS;
+}
+
+
+static DWORD
+ScConnectControlPipe(HANDLE *hPipe)
+{
+    DWORD dwBytesWritten;
+    DWORD dwState;
+    DWORD dwServiceCurrent = 0;
+    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,
+                  sizeof(QueryTable));
+
+    QueryTable[0].Name = L"";
+    QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | 
RTL_QUERY_REGISTRY_REQUIRED;
+    QueryTable[0].EntryContext = &dwServiceCurrent;
+
+    Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,
+                                    L"ServiceCurrent",
+                                    QueryTable,
+                                    NULL,
+                                    NULL);
+
+    if (!NT_SUCCESS(Status))
+    {
+        ERR("RtlQueryRegistryValues() failed (Status %lx)\n", Status);
+        return RtlNtStatusToDosError(Status);
+    }
+
+    swprintf(NtControlPipeName, L"\\\\.\\pipe\\net\\NtControlPipe%u", 
dwServiceCurrent);
+
+    if (!WaitNamedPipeW(NtControlPipeName, 15000))
+    {
+        ERR("WaitNamedPipe(%S) failed (Error %lu)\n", NtControlPipeName, 
GetLastError());
+        return ERROR_FAILED_SERVICE_CONTROLLER_CONNECT;
+    }
+
+    *hPipe = CreateFileW(NtControlPipeName,
+                         GENERIC_READ | GENERIC_WRITE,
+                         0,
+                         NULL,
+                         OPEN_EXISTING,
+                         FILE_ATTRIBUTE_NORMAL,
+                         NULL);
+    if (*hPipe == INVALID_HANDLE_VALUE)
+    {
+        ERR("CreateFileW() failed for pipe %S (Error %lu)\n", 
NtControlPipeName, GetLastError());
+        return ERROR_FAILED_SERVICE_CONTROLLER_CONNECT;
+    }
+
+    dwState = PIPE_READMODE_MESSAGE;
+    if (!SetNamedPipeHandleState(*hPipe, &dwState, NULL, NULL))
+    {
+        CloseHandle(*hPipe);
+        *hPipe = INVALID_HANDLE_VALUE;
+        return ERROR_FAILED_SERVICE_CONTROLLER_CONNECT;
+    }
+
+    /* Pass the ProcessId to the SCM */
+    dwProcessId = GetCurrentProcessId();
+    WriteFile(*hPipe,
+              &dwProcessId,
+              sizeof(DWORD),
+              &dwBytesWritten,
+              NULL);
+
+    TRACE("Sent Process ID %lu\n", dwProcessId);
+
+    return ERROR_SUCCESS;
+}
+
+
+static DWORD
+ScStartService(PACTIVE_SERVICE lpService,
+               PSCM_CONTROL_PACKET ControlPacket)
+{
+    HANDLE ThreadHandle;
+    DWORD ThreadId;
+    LPWSTR *lpArgW;
+    DWORD i;
+
+    TRACE("ScStartService() called\n");
+    TRACE("Size: %lu\n", ControlPacket->dwSize);
+    TRACE("Service: %S\n", (PWSTR)((PBYTE)ControlPacket + 
ControlPacket->dwServiceNameOffset));
+
+    /* Set the service status handle */
+    lpService->hServiceStatus = ControlPacket->hServiceStatus;
+
+    if (lpService->bUnicode == TRUE)
+    {
+        lpService->ThreadParams.W.dwArgCount = ControlPacket->dwArgumentsCount;
+        lpService->ThreadParams.W.lpArgVector = NULL;
+
+        if (ControlPacket->dwArgumentsOffset > 0)
+        {
+            lpService->ThreadParams.W.lpArgVector =
+                HeapAlloc(GetProcessHeap(),
+                          HEAP_ZERO_MEMORY,
+                          ControlPacket->dwSize - 
ControlPacket->dwArgumentsOffset);
+            if (lpService->ThreadParams.W.lpArgVector == NULL)
+                return ERROR_OUTOFMEMORY;
+
+            memcpy(lpService->ThreadParams.W.lpArgVector,
+                   ((PBYTE)ControlPacket + ControlPacket->dwArgumentsOffset),
+                   ControlPacket->dwSize - ControlPacket->dwArgumentsOffset);
+
+            lpArgW = lpService->ThreadParams.W.lpArgVector;
+            for (i = 0; i < lpService->ThreadParams.W.dwArgCount; i++)
+            {
+                *lpArgW = (LPWSTR)((ULONG_PTR)lpArgW + (ULONG_PTR)*lpArgW);
+                lpArgW++;
+            }
+        }
+    }
+    else
+    {
+        /* FIXME */
+        lpService->ThreadParams.A.dwArgCount = 0;
+        lpService->ThreadParams.A.lpArgVector = NULL;
+
+#if 0
         LPSTR *lpArgVector;
         LPSTR Ptr;
         LPSTR AnsiString;
@@ -256,7 +381,7 @@
         }
         lpArgVector[dwArgCount] = NULL;
 
-        (lpService->Main.lpFuncA)(dwArgCount, lpArgVector);
+        (lpService->ThreadParams.A.lpServiceMain)(dwArgCount, lpArgVector);
 
         HeapFree(GetProcessHeap(),
                  0,
@@ -264,140 +389,10 @@
         HeapFree(GetProcessHeap(),
                  0,
                  AnsiString);
-    }
-
-    return ERROR_SUCCESS;
-}
-
-
-static DWORD
-ScConnectControlPipe(HANDLE *hPipe)
-{
-    DWORD dwBytesWritten;
-    DWORD dwState;
-    DWORD dwServiceCurrent = 0;
-    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,
-                  sizeof(QueryTable));
-
-    QueryTable[0].Name = L"";
-    QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | 
RTL_QUERY_REGISTRY_REQUIRED;
-    QueryTable[0].EntryContext = &dwServiceCurrent;
-
-    Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,
-                                    L"ServiceCurrent",
-                                    QueryTable,
-                                    NULL,
-                                    NULL);
-
-    if (!NT_SUCCESS(Status))
-    {
-        ERR("RtlQueryRegistryValues() failed (Status %lx)\n", Status);
-        return RtlNtStatusToDosError(Status);
-    }
-
-    swprintf(NtControlPipeName, L"\\\\.\\pipe\\net\\NtControlPipe%u", 
dwServiceCurrent);
-
-    if (!WaitNamedPipeW(NtControlPipeName, 15000))
-    {
-        ERR("WaitNamedPipe(%S) failed (Error %lu)\n", NtControlPipeName, 
GetLastError());
-        return ERROR_FAILED_SERVICE_CONTROLLER_CONNECT;
-    }
-
-    *hPipe = CreateFileW(NtControlPipeName,
-                         GENERIC_READ | GENERIC_WRITE,
-                         0,
-                         NULL,
-                         OPEN_EXISTING,
-                         FILE_ATTRIBUTE_NORMAL,
-                         NULL);
-    if (*hPipe == INVALID_HANDLE_VALUE)
-    {
-        ERR("CreateFileW() failed for pipe %S (Error %lu)\n", 
NtControlPipeName, GetLastError());
-        return ERROR_FAILED_SERVICE_CONTROLLER_CONNECT;
-    }
-
-    dwState = PIPE_READMODE_MESSAGE;
-    if (!SetNamedPipeHandleState(*hPipe, &dwState, NULL, NULL))
-    {
-        CloseHandle(*hPipe);
-        *hPipe = INVALID_HANDLE_VALUE;
-        return ERROR_FAILED_SERVICE_CONTROLLER_CONNECT;
-    }
-
-    /* Pass the ProcessId to the SCM */
-    dwProcessId = GetCurrentProcessId();
-    WriteFile(*hPipe,
-              &dwProcessId,
-              sizeof(DWORD),
-              &dwBytesWritten,
-              NULL);
-
-    TRACE("Sent Process ID %lu\n", dwProcessId);
-
-    return ERROR_SUCCESS;
-}
-
-
-static DWORD
-ScStartService(PACTIVE_SERVICE lpService,
-               PSCM_CONTROL_PACKET ControlPacket)
-{
-    HANDLE ThreadHandle;
-    DWORD ThreadId;
-    PWSTR pServiceName;
-    PWSTR Ptr;
-    DWORD dwArgumentsSize;
-
-    TRACE("ScStartService() called\n");
-    TRACE("Size: %lu\n", ControlPacket->dwSize);
-    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,
-                                     dwArgumentsSize + sizeof(WCHAR));
-    if (lpService->Arguments == NULL)
-        return ERROR_OUTOFMEMORY;
-
-    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 */
+    /* Invoke the services entry point and implement the command loop */
     ThreadHandle = CreateThread(NULL,
                                 0,
                                 ScServiceMainStub,
@@ -405,7 +400,33 @@
                                 CREATE_SUSPENDED,
                                 &ThreadId);
     if (ThreadHandle == NULL)
+    {
+        /* Free the arguments vector */
+        if (lpService->bUnicode)
+        {
+            if (lpService->ThreadParams.W.lpArgVector != NULL)
+            {
+                HeapFree(GetProcessHeap(),
+                         0,
+                         lpService->ThreadParams.W.lpArgVector);
+                lpService->ThreadParams.W.lpArgVector = NULL;
+                lpService->ThreadParams.W.dwArgCount = 0;
+            }
+        }
+        else
+        {
+            if (lpService->ThreadParams.A.lpArgVector != NULL)
+            {
+                HeapFree(GetProcessHeap(),
+                         0,
+                         lpService->ThreadParams.A.lpArgVector);
+                lpService->ThreadParams.A.lpArgVector = NULL;
+                lpService->ThreadParams.A.dwArgCount = 0;
+            }
+        }
+
         return ERROR_SERVICE_NO_THREAD;
+    }
 
     ResumeThread(ThreadHandle);
     CloseHandle(ThreadHandle);
@@ -430,13 +451,6 @@
     {
         /* FIXME: send correct params */
         (lpService->HandlerFunctionEx)(ControlPacket->dwControl, 0, NULL, 
NULL);
-    }
-
-    if (ControlPacket->dwControl == SERVICE_CONTROL_STOP)
-    {
-        HeapFree(GetProcessHeap(),
-                 0,
-                 lpService->Arguments);
     }
 
     TRACE("ScControlService() done\n");
@@ -820,7 +834,7 @@
     {
         RtlCreateUnicodeStringFromAsciiz(&lpActiveServices[i].ServiceName,
                                          lpServiceStartTable[i].lpServiceName);
-        lpActiveServices[i].Main.lpFuncA = 
lpServiceStartTable[i].lpServiceProc;
+        lpActiveServices[i].ThreadParams.A.lpServiceMain = 
lpServiceStartTable[i].lpServiceProc;
         lpActiveServices[i].hServiceStatus = 0;
         lpActiveServices[i].bUnicode = FALSE;
     }
@@ -915,7 +929,7 @@
     {
         RtlCreateUnicodeString(&lpActiveServices[i].ServiceName,
                                lpServiceStartTable[i].lpServiceName);
-        lpActiveServices[i].Main.lpFuncW = 
lpServiceStartTable[i].lpServiceProc;
+        lpActiveServices[i].ThreadParams.W.lpServiceMain = 
lpServiceStartTable[i].lpServiceProc;
         lpActiveServices[i].hServiceStatus = 0;
         lpActiveServices[i].bUnicode = TRUE;
     }


Reply via email to