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;