mirror of
https://github.com/reactos/reactos.git
synced 2024-10-06 01:13:38 +00:00
[SERVICES/ADVAPI32]
Pass the service start argument vector to the started service main function. ANSI services are not supported yet. svn path=/trunk/; revision=53564
This commit is contained in:
parent
1a358ac727
commit
ff2da6c81c
|
@ -1002,6 +1002,8 @@ ScmSendStartCommand(PSERVICE Service,
|
|||
DWORD dwReadCount = 0;
|
||||
DWORD dwError = ERROR_SUCCESS;
|
||||
DWORD i;
|
||||
PWSTR *pOffPtr;
|
||||
PWSTR pArgPtr;
|
||||
|
||||
DPRINT("ScmSendStartCommand() called\n");
|
||||
|
||||
|
@ -1043,16 +1045,25 @@ ScmSendStartCommand(PSERVICE Service,
|
|||
/* Copy argument list */
|
||||
if (argc > 0 && argv != NULL)
|
||||
{
|
||||
// Ptr += wcslen(Service->lpServiceName) + 1;
|
||||
// Ptr = ALIGN_UP_POINTER(Ptr, LPWSTR);
|
||||
Ptr += wcslen(Service->lpServiceName) + 1;
|
||||
pOffPtr = (PWSTR*)ALIGN_UP_POINTER(Ptr, PWSTR);
|
||||
pArgPtr = (PWSTR)((ULONG_PTR)pOffPtr + argc * sizeof(PWSTR));
|
||||
|
||||
// ControlPacket->dwArgumentsOffset = (DWORD)((INT_PTR)Ptr - (INT_PTR)ControlPacket);
|
||||
ControlPacket->dwArgumentsCount = argc;
|
||||
ControlPacket->dwArgumentsOffset = (DWORD)((ULONG_PTR)pOffPtr - (ULONG_PTR)ControlPacket);
|
||||
|
||||
DPRINT("dwArgumentsCount: %lu\n", ControlPacket->dwArgumentsCount);
|
||||
DPRINT("dwArgumentsOffset: %lu\n", ControlPacket->dwArgumentsOffset);
|
||||
|
||||
#if 0
|
||||
memcpy(Ptr, Arguments, ArgsLength);
|
||||
Ptr += ArgsLength;
|
||||
#endif
|
||||
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 */
|
||||
|
|
|
@ -18,20 +18,35 @@ WINE_DEFAULT_DEBUG_CHANNEL(advapi);
|
|||
|
||||
/* 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,122 +163,40 @@ ScLookupServiceByServiceName(LPCWSTR lpServiceName)
|
|||
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;
|
||||
(lpService->ThreadParams.W.lpServiceMain)(lpService->ThreadParams.W.dwArgCount,
|
||||
lpService->ThreadParams.W.lpArgVector);
|
||||
|
||||
lpArgVector = HeapAlloc(GetProcessHeap(),
|
||||
HEAP_ZERO_MEMORY,
|
||||
(dwArgCount + 1) * sizeof(LPWSTR));
|
||||
if (lpArgVector == NULL)
|
||||
return ERROR_OUTOFMEMORY;
|
||||
|
||||
dwArgCount = 0;
|
||||
Ptr = lpService->Arguments;
|
||||
while (*Ptr)
|
||||
if (lpService->ThreadParams.A.lpArgVector != NULL)
|
||||
{
|
||||
lpArgVector[dwArgCount] = Ptr;
|
||||
HeapFree(GetProcessHeap(),
|
||||
0,
|
||||
lpService->ThreadParams.W.lpArgVector);
|
||||
|
||||
dwArgCount++;
|
||||
Ptr += (wcslen(Ptr) + 1);
|
||||
lpService->ThreadParams.W.lpArgVector = NULL;
|
||||
lpService->ThreadParams.W.dwArgCount = 0;
|
||||
}
|
||||
lpArgVector[dwArgCount] = NULL;
|
||||
|
||||
(lpService->Main.lpFuncW)(dwArgCount, lpArgVector);
|
||||
|
||||
HeapFree(GetProcessHeap(),
|
||||
0,
|
||||
lpArgVector);
|
||||
}
|
||||
else
|
||||
{
|
||||
LPSTR *lpArgVector;
|
||||
LPSTR Ptr;
|
||||
LPSTR AnsiString;
|
||||
DWORD AnsiLength;
|
||||
(lpService->ThreadParams.A.lpServiceMain)(lpService->ThreadParams.A.dwArgCount,
|
||||
lpService->ThreadParams.A.lpArgVector);
|
||||
|
||||
AnsiLength = WideCharToMultiByte(CP_ACP,
|
||||
0,
|
||||
lpService->Arguments,
|
||||
dwLength,
|
||||
NULL,
|
||||
0,
|
||||
NULL,
|
||||
NULL);
|
||||
if (AnsiLength == 0)
|
||||
return ERROR_INVALID_PARAMETER; /* ? */
|
||||
|
||||
AnsiString = HeapAlloc(GetProcessHeap(),
|
||||
0,
|
||||
AnsiLength + 1);
|
||||
if (AnsiString == NULL)
|
||||
return ERROR_OUTOFMEMORY;
|
||||
|
||||
WideCharToMultiByte(CP_ACP,
|
||||
0,
|
||||
lpService->Arguments,
|
||||
dwLength,
|
||||
AnsiString,
|
||||
AnsiLength,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
AnsiString[AnsiLength] = ANSI_NULL;
|
||||
|
||||
lpArgVector = HeapAlloc(GetProcessHeap(),
|
||||
0,
|
||||
(dwArgCount + 1) * sizeof(LPSTR));
|
||||
if (lpArgVector == NULL)
|
||||
if (lpService->ThreadParams.A.lpArgVector != NULL)
|
||||
{
|
||||
HeapFree(GetProcessHeap(),
|
||||
0,
|
||||
AnsiString);
|
||||
return ERROR_OUTOFMEMORY;
|
||||
0,
|
||||
lpService->ThreadParams.A.lpArgVector);
|
||||
|
||||
lpService->ThreadParams.A.lpArgVector = NULL;
|
||||
lpService->ThreadParams.A.dwArgCount = 0;
|
||||
}
|
||||
|
||||
dwArgCount = 0;
|
||||
Ptr = AnsiString;
|
||||
while (*Ptr)
|
||||
{
|
||||
lpArgVector[dwArgCount] = Ptr;
|
||||
|
||||
dwArgCount++;
|
||||
Ptr += (strlen(Ptr) + 1);
|
||||
}
|
||||
lpArgVector[dwArgCount] = NULL;
|
||||
|
||||
(lpService->Main.lpFuncA)(dwArgCount, lpArgVector);
|
||||
|
||||
HeapFree(GetProcessHeap(),
|
||||
0,
|
||||
lpArgVector);
|
||||
HeapFree(GetProcessHeap(),
|
||||
0,
|
||||
AnsiString);
|
||||
}
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
|
@ -350,9 +283,8 @@ ScStartService(PACTIVE_SERVICE lpService,
|
|||
{
|
||||
HANDLE ThreadHandle;
|
||||
DWORD ThreadId;
|
||||
PWSTR pServiceName;
|
||||
PWSTR Ptr;
|
||||
DWORD dwArgumentsSize;
|
||||
LPWSTR *lpArgW;
|
||||
DWORD i;
|
||||
|
||||
TRACE("ScStartService() called\n");
|
||||
TRACE("Size: %lu\n", ControlPacket->dwSize);
|
||||
|
@ -361,43 +293,106 @@ ScStartService(PACTIVE_SERVICE lpService,
|
|||
/* Set the service status handle */
|
||||
lpService->hServiceStatus = ControlPacket->hServiceStatus;
|
||||
|
||||
pServiceName = (PWSTR)((PBYTE)ControlPacket + ControlPacket->dwServiceNameOffset);
|
||||
if (lpService->bUnicode == TRUE)
|
||||
{
|
||||
lpService->ThreadParams.W.dwArgCount = ControlPacket->dwArgumentsCount;
|
||||
lpService->ThreadParams.W.lpArgVector = NULL;
|
||||
|
||||
/* Get the service name size */
|
||||
dwArgumentsSize = (wcslen(pServiceName) + 1) * sizeof(WCHAR);
|
||||
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;
|
||||
|
||||
/* Get the size of the service start arguments */
|
||||
if (ControlPacket->dwArgumentsCount > 0 &&
|
||||
ControlPacket->dwArgumentsOffset != 0)
|
||||
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
|
||||
dwArgumentSize += (wcslen(...) + 1) * sizeof(WCHAR);
|
||||
LPSTR *lpArgVector;
|
||||
LPSTR Ptr;
|
||||
LPSTR AnsiString;
|
||||
DWORD AnsiLength;
|
||||
|
||||
AnsiLength = WideCharToMultiByte(CP_ACP,
|
||||
0,
|
||||
lpService->Arguments,
|
||||
dwLength,
|
||||
NULL,
|
||||
0,
|
||||
NULL,
|
||||
NULL);
|
||||
if (AnsiLength == 0)
|
||||
return ERROR_INVALID_PARAMETER; /* ? */
|
||||
|
||||
AnsiString = HeapAlloc(GetProcessHeap(),
|
||||
0,
|
||||
AnsiLength + 1);
|
||||
if (AnsiString == NULL)
|
||||
return ERROR_OUTOFMEMORY;
|
||||
|
||||
WideCharToMultiByte(CP_ACP,
|
||||
0,
|
||||
lpService->Arguments,
|
||||
dwLength,
|
||||
AnsiString,
|
||||
AnsiLength,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
AnsiString[AnsiLength] = ANSI_NULL;
|
||||
|
||||
lpArgVector = HeapAlloc(GetProcessHeap(),
|
||||
0,
|
||||
(dwArgCount + 1) * sizeof(LPSTR));
|
||||
if (lpArgVector == NULL)
|
||||
{
|
||||
HeapFree(GetProcessHeap(),
|
||||
0,
|
||||
AnsiString);
|
||||
return ERROR_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
dwArgCount = 0;
|
||||
Ptr = AnsiString;
|
||||
while (*Ptr)
|
||||
{
|
||||
lpArgVector[dwArgCount] = Ptr;
|
||||
|
||||
dwArgCount++;
|
||||
Ptr += (strlen(Ptr) + 1);
|
||||
}
|
||||
lpArgVector[dwArgCount] = NULL;
|
||||
|
||||
(lpService->ThreadParams.A.lpServiceMain)(dwArgCount, lpArgVector);
|
||||
|
||||
HeapFree(GetProcessHeap(),
|
||||
0,
|
||||
lpArgVector);
|
||||
HeapFree(GetProcessHeap(),
|
||||
0,
|
||||
AnsiString);
|
||||
#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 @@ ScStartService(PACTIVE_SERVICE lpService,
|
|||
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);
|
||||
|
@ -432,13 +453,6 @@ ScControlService(PACTIVE_SERVICE lpService,
|
|||
(lpService->HandlerFunctionEx)(ControlPacket->dwControl, 0, NULL, NULL);
|
||||
}
|
||||
|
||||
if (ControlPacket->dwControl == SERVICE_CONTROL_STOP)
|
||||
{
|
||||
HeapFree(GetProcessHeap(),
|
||||
0,
|
||||
lpService->Arguments);
|
||||
}
|
||||
|
||||
TRACE("ScControlService() done\n");
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
|
@ -820,7 +834,7 @@ StartServiceCtrlDispatcherA(const SERVICE_TABLE_ENTRYA * lpServiceStartTable)
|
|||
{
|
||||
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 @@ StartServiceCtrlDispatcherW(const SERVICE_TABLE_ENTRYW * lpServiceStartTable)
|
|||
{
|
||||
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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue