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…
==============================================================================
--- 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;