[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

svn path=/trunk/; revision=68196
This commit is contained in:
Thomas Faber 2015-06-19 18:16:27 +00:00
parent 9f97886e2a
commit 7b8f59932c

View file

@ -40,9 +40,9 @@ typedef struct _ACTIVE_SERVICE
UNICODE_STRING ServiceName; UNICODE_STRING ServiceName;
union union
{ {
SERVICE_THREAD_PARAMSA A; LPSERVICE_MAIN_FUNCTIONA A;
SERVICE_THREAD_PARAMSW W; LPSERVICE_MAIN_FUNCTIONW W;
} ThreadParams; } ServiceMain;
LPHANDLER_FUNCTION HandlerFunction; LPHANDLER_FUNCTION HandlerFunction;
LPHANDLER_FUNCTION_EX HandlerFunctionEx; LPHANDLER_FUNCTION_EX HandlerFunctionEx;
LPVOID HandlerContext; LPVOID HandlerContext;
@ -165,43 +165,41 @@ ScLookupServiceByServiceName(LPCWSTR lpServiceName)
static DWORD WINAPI static DWORD WINAPI
ScServiceMainStub(LPVOID Context) ScServiceMainStubA(LPVOID Context)
{ {
PACTIVE_SERVICE lpService = (PACTIVE_SERVICE)Context; PSERVICE_THREAD_PARAMSA ThreadParams = Context;
TRACE("ScServiceMainStub() called\n"); TRACE("ScServiceMainStubA() called\n");
/* Call the main service routine and free the arguments vector */ /* Call the main service routine and free the arguments vector */
if (lpService->bUnicode) (ThreadParams->lpServiceMain)(ThreadParams->dwArgCount,
ThreadParams->lpArgVector);
if (ThreadParams->lpArgVector != NULL)
{ {
(lpService->ThreadParams.W.lpServiceMain)(lpService->ThreadParams.W.dwArgCount, HeapFree(GetProcessHeap(), 0, ThreadParams->lpArgVector);
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 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)
{ {
(lpService->ThreadParams.A.lpServiceMain)(lpService->ThreadParams.A.dwArgCount, HeapFree(GetProcessHeap(), 0, ThreadParams->lpArgVector);
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;
}
} }
HeapFree(GetProcessHeap(), 0, ThreadParams);
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
@ -451,6 +449,8 @@ ScStartService(PACTIVE_SERVICE lpService,
HANDLE ThreadHandle; HANDLE ThreadHandle;
DWORD ThreadId; DWORD ThreadId;
DWORD dwError; DWORD dwError;
PSERVICE_THREAD_PARAMSA ThreadParamsA;
PSERVICE_THREAD_PARAMSW ThreadParamsW;
if (lpService == NULL || ControlPacket == NULL) if (lpService == NULL || ControlPacket == NULL)
return ERROR_INVALID_PARAMETER; return ERROR_INVALID_PARAMETER;
@ -465,54 +465,59 @@ ScStartService(PACTIVE_SERVICE lpService,
/* Build the arguments vector */ /* Build the arguments vector */
if (lpService->bUnicode == TRUE) if (lpService->bUnicode == TRUE)
{ {
ThreadParamsW = HeapAlloc(GetProcessHeap(), 0, sizeof(*ThreadParamsW));
if (ThreadParamsW == NULL)
return ERROR_NOT_ENOUGH_MEMORY;
dwError = ScBuildUnicodeArgsVector(ControlPacket, dwError = ScBuildUnicodeArgsVector(ControlPacket,
&lpService->ThreadParams.W.dwArgCount, &ThreadParamsW->dwArgCount,
&lpService->ThreadParams.W.lpArgVector); &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 (ThreadParamsW->lpArgVector != NULL)
{
HeapFree(GetProcessHeap(),
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, dwError = ScBuildAnsiArgsVector(ControlPacket,
&lpService->ThreadParams.A.dwArgCount, &ThreadParamsA->dwArgCount,
&lpService->ThreadParams.A.lpArgVector); &ThreadParamsA->lpArgVector);
} if (dwError != ERROR_SUCCESS)
return dwError;
if (dwError != ERROR_SUCCESS) ThreadParamsA->lpServiceMain = lpService->ServiceMain.A;
return dwError; ThreadHandle = CreateThread(NULL,
0,
/* Invoke the services entry point and implement the command loop */ ScServiceMainStubA,
ThreadHandle = CreateThread(NULL, ThreadParamsA,
0, CREATE_SUSPENDED,
ScServiceMainStub, &ThreadId);
lpService, if (ThreadHandle == NULL)
CREATE_SUSPENDED,
&ThreadId);
if (ThreadHandle == NULL)
{
/* Free the arguments vector */
if (lpService->bUnicode)
{ {
if (lpService->ThreadParams.W.lpArgVector != NULL) if (ThreadParamsA->lpArgVector != NULL)
{ {
HeapFree(GetProcessHeap(), HeapFree(GetProcessHeap(),
0, 0,
lpService->ThreadParams.W.lpArgVector); ThreadParamsA->lpArgVector);
lpService->ThreadParams.W.lpArgVector = NULL;
lpService->ThreadParams.W.dwArgCount = 0;
} }
HeapFree(GetProcessHeap(), 0, ThreadParamsA);
} }
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); ResumeThread(ThreadHandle);
@ -922,7 +927,7 @@ StartServiceCtrlDispatcherA(const SERVICE_TABLE_ENTRYA *lpServiceStartTable)
{ {
RtlCreateUnicodeStringFromAsciiz(&lpActiveServices[i].ServiceName, RtlCreateUnicodeStringFromAsciiz(&lpActiveServices[i].ServiceName,
lpServiceStartTable[i].lpServiceName); lpServiceStartTable[i].lpServiceName);
lpActiveServices[i].ThreadParams.A.lpServiceMain = lpServiceStartTable[i].lpServiceProc; lpActiveServices[i].ServiceMain.A = lpServiceStartTable[i].lpServiceProc;
lpActiveServices[i].hServiceStatus = 0; lpActiveServices[i].hServiceStatus = 0;
lpActiveServices[i].bUnicode = FALSE; lpActiveServices[i].bUnicode = FALSE;
lpActiveServices[i].bOwnProcess = FALSE; lpActiveServices[i].bOwnProcess = FALSE;
@ -1009,7 +1014,7 @@ StartServiceCtrlDispatcherW(const SERVICE_TABLE_ENTRYW *lpServiceStartTable)
{ {
RtlCreateUnicodeString(&lpActiveServices[i].ServiceName, RtlCreateUnicodeString(&lpActiveServices[i].ServiceName,
lpServiceStartTable[i].lpServiceName); lpServiceStartTable[i].lpServiceName);
lpActiveServices[i].ThreadParams.W.lpServiceMain = lpServiceStartTable[i].lpServiceProc; lpActiveServices[i].ServiceMain.W = lpServiceStartTable[i].lpServiceProc;
lpActiveServices[i].hServiceStatus = 0; lpActiveServices[i].hServiceStatus = 0;
lpActiveServices[i].bUnicode = TRUE; lpActiveServices[i].bUnicode = TRUE;
lpActiveServices[i].bOwnProcess = FALSE; lpActiveServices[i].bOwnProcess = FALSE;