Author: tfaber
Date: Fri Jun 19 18:16:27 2015
New Revision: 68196

URL: http://svn.reactos.org/svn/reactos?rev=68196&view=rev
Log:
[ADVAPI32]
- Use a separate heap allocation for the thread parameters to 
ScServiceMainStub, since the thread can live longer than the ACTIVE_SERVICE 
structure
CORE-9235

Modified:
    trunk/reactos/dll/win32/advapi32/service/sctrl.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=68196&r1=68195&r2=68196&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] Fri Jun 19 
18:16:27 2015
@@ -40,9 +40,9 @@
     UNICODE_STRING ServiceName;
     union
     {
-        SERVICE_THREAD_PARAMSA A;
-        SERVICE_THREAD_PARAMSW W;
-    } ThreadParams;
+        LPSERVICE_MAIN_FUNCTIONA A;
+        LPSERVICE_MAIN_FUNCTIONW W;
+    } ServiceMain;
     LPHANDLER_FUNCTION HandlerFunction;
     LPHANDLER_FUNCTION_EX HandlerFunctionEx;
     LPVOID HandlerContext;
@@ -165,43 +165,41 @@
 
 
 static DWORD WINAPI
-ScServiceMainStub(LPVOID Context)
-{
-    PACTIVE_SERVICE lpService = (PACTIVE_SERVICE)Context;
-
-    TRACE("ScServiceMainStub() called\n");
+ScServiceMainStubA(LPVOID Context)
+{
+    PSERVICE_THREAD_PARAMSA ThreadParams = Context;
+
+    TRACE("ScServiceMainStubA() called\n");
 
     /* Call the main service routine and free the arguments vector */
-    if (lpService->bUnicode)
-    {
-        
(lpService->ThreadParams.W.lpServiceMain)(lpService->ThreadParams.W.dwArgCount,
-                                                  
lpService->ThreadParams.W.lpArgVector);
-
-        if (lpService->ThreadParams.W.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;
-        }
-    }
+    (ThreadParams->lpServiceMain)(ThreadParams->dwArgCount,
+                                  ThreadParams->lpArgVector);
+
+    if (ThreadParams->lpArgVector != NULL)
+    {
+        HeapFree(GetProcessHeap(), 0, ThreadParams->lpArgVector);
+    }
+    HeapFree(GetProcessHeap(), 0, ThreadParams);
+
+    return ERROR_SUCCESS;
+}
+
+static DWORD WINAPI
+ScServiceMainStubW(LPVOID Context)
+{
+    PSERVICE_THREAD_PARAMSW ThreadParams = Context;
+
+    TRACE("ScServiceMainStubW() called\n");
+
+    /* Call the main service routine and free the arguments vector */
+    (ThreadParams->lpServiceMain)(ThreadParams->dwArgCount,
+                                  ThreadParams->lpArgVector);
+
+    if (ThreadParams->lpArgVector != NULL)
+    {
+        HeapFree(GetProcessHeap(), 0, ThreadParams->lpArgVector);
+    }
+    HeapFree(GetProcessHeap(), 0, ThreadParams);
 
     return ERROR_SUCCESS;
 }
@@ -451,6 +449,8 @@
     HANDLE ThreadHandle;
     DWORD ThreadId;
     DWORD dwError;
+    PSERVICE_THREAD_PARAMSA ThreadParamsA;
+    PSERVICE_THREAD_PARAMSW ThreadParamsW;
 
     if (lpService == NULL || ControlPacket == NULL)
         return ERROR_INVALID_PARAMETER;
@@ -465,54 +465,59 @@
     /* Build the arguments vector */
     if (lpService->bUnicode == TRUE)
     {
+        ThreadParamsW = HeapAlloc(GetProcessHeap(), 0, sizeof(*ThreadParamsW));
+        if (ThreadParamsW == NULL)
+            return ERROR_NOT_ENOUGH_MEMORY;
         dwError = ScBuildUnicodeArgsVector(ControlPacket,
-                                           
&lpService->ThreadParams.W.dwArgCount,
-                                           
&lpService->ThreadParams.W.lpArgVector);
-    }
-    else
-    {
-        dwError = ScBuildAnsiArgsVector(ControlPacket,
-                                        &lpService->ThreadParams.A.dwArgCount,
-                                        
&lpService->ThreadParams.A.lpArgVector);
-    }
-
-    if (dwError != ERROR_SUCCESS)
-        return dwError;
-
-    /* Invoke the services entry point and implement the command loop */
-    ThreadHandle = CreateThread(NULL,
-                                0,
-                                ScServiceMainStub,
-                                lpService,
-                                CREATE_SUSPENDED,
-                                &ThreadId);
-    if (ThreadHandle == NULL)
-    {
-        /* Free the arguments vector */
-        if (lpService->bUnicode)
+                                           &ThreadParamsW->dwArgCount,
+                                           &ThreadParamsW->lpArgVector);
+        if (dwError != ERROR_SUCCESS)
+            return dwError;
+        ThreadParamsW->lpServiceMain = lpService->ServiceMain.W;
+        ThreadHandle = CreateThread(NULL,
+                                    0,
+                                    ScServiceMainStubW,
+                                    ThreadParamsW,
+                                    CREATE_SUSPENDED,
+                                    &ThreadId);
+        if (ThreadHandle == NULL)
         {
-            if (lpService->ThreadParams.W.lpArgVector != NULL)
+            if (ThreadParamsW->lpArgVector != NULL)
             {
                 HeapFree(GetProcessHeap(),
                          0,
-                         lpService->ThreadParams.W.lpArgVector);
-                lpService->ThreadParams.W.lpArgVector = NULL;
-                lpService->ThreadParams.W.dwArgCount = 0;
+                         ThreadParamsW->lpArgVector);
             }
+            HeapFree(GetProcessHeap(), 0, ThreadParamsW);
         }
-        else
+    }
+    else
+    {
+        ThreadParamsA = HeapAlloc(GetProcessHeap(), 0, sizeof(*ThreadParamsA));
+        if (ThreadParamsA == NULL)
+            return ERROR_NOT_ENOUGH_MEMORY;
+        dwError = ScBuildAnsiArgsVector(ControlPacket,
+                                        &ThreadParamsA->dwArgCount,
+                                        &ThreadParamsA->lpArgVector);
+        if (dwError != ERROR_SUCCESS)
+            return dwError;
+        ThreadParamsA->lpServiceMain = lpService->ServiceMain.A;
+        ThreadHandle = CreateThread(NULL,
+                                    0,
+                                    ScServiceMainStubA,
+                                    ThreadParamsA,
+                                    CREATE_SUSPENDED,
+                                    &ThreadId);
+        if (ThreadHandle == NULL)
         {
-            if (lpService->ThreadParams.A.lpArgVector != NULL)
+            if (ThreadParamsA->lpArgVector != NULL)
             {
                 HeapFree(GetProcessHeap(),
                          0,
-                         lpService->ThreadParams.A.lpArgVector);
-                lpService->ThreadParams.A.lpArgVector = NULL;
-                lpService->ThreadParams.A.dwArgCount = 0;
+                         ThreadParamsA->lpArgVector);
             }
+            HeapFree(GetProcessHeap(), 0, ThreadParamsA);
         }
-
-        return ERROR_SERVICE_NO_THREAD;
     }
 
     ResumeThread(ThreadHandle);
@@ -922,7 +927,7 @@
     {
         RtlCreateUnicodeStringFromAsciiz(&lpActiveServices[i].ServiceName,
                                          lpServiceStartTable[i].lpServiceName);
-        lpActiveServices[i].ThreadParams.A.lpServiceMain = 
lpServiceStartTable[i].lpServiceProc;
+        lpActiveServices[i].ServiceMain.A = 
lpServiceStartTable[i].lpServiceProc;
         lpActiveServices[i].hServiceStatus = 0;
         lpActiveServices[i].bUnicode = FALSE;
         lpActiveServices[i].bOwnProcess = FALSE;
@@ -1009,7 +1014,7 @@
     {
         RtlCreateUnicodeString(&lpActiveServices[i].ServiceName,
                                lpServiceStartTable[i].lpServiceName);
-        lpActiveServices[i].ThreadParams.W.lpServiceMain = 
lpServiceStartTable[i].lpServiceProc;
+        lpActiveServices[i].ServiceMain.W = 
lpServiceStartTable[i].lpServiceProc;
         lpActiveServices[i].hServiceStatus = 0;
         lpActiveServices[i].bUnicode = TRUE;
         lpActiveServices[i].bOwnProcess = FALSE;


Reply via email to