From ff2da6c81c569d6a422be5569967157b2e070186 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Sat, 3 Sep 2011 19:47:56 +0000 Subject: [PATCH] [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 --- reactos/base/system/services/database.c | 25 +- reactos/dll/win32/advapi32/service/sctrl.c | 298 +++++++++++---------- 2 files changed, 174 insertions(+), 149 deletions(-) diff --git a/reactos/base/system/services/database.c b/reactos/base/system/services/database.c index 8b22e36867e..2191e401e60 100644 --- a/reactos/base/system/services/database.c +++ b/reactos/base/system/services/database.c @@ -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 */ diff --git a/reactos/dll/win32/advapi32/service/sctrl.c b/reactos/dll/win32/advapi32/service/sctrl.c index c77f133ee49..53a9aef1514 100644 --- a/reactos/dll/win32/advapi32/service/sctrl.c +++ b/reactos/dll/win32/advapi32/service/sctrl.c @@ -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; - - 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; + (lpService->ThreadParams.A.lpServiceMain)(lpService->ThreadParams.A.dwArgCount, + lpService->ThreadParams.A.lpArgVector); - 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); - dwArgCount = 0; - Ptr = AnsiString; - while (*Ptr) - { - lpArgVector[dwArgCount] = Ptr; - - dwArgCount++; - Ptr += (strlen(Ptr) + 1); + lpService->ThreadParams.A.lpArgVector = NULL; + lpService->ThreadParams.A.dwArgCount = 0; } - 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); - - /* Get the service name size */ - dwArgumentsSize = (wcslen(pServiceName) + 1) * sizeof(WCHAR); + if (lpService->bUnicode == TRUE) + { + lpService->ThreadParams.W.dwArgCount = ControlPacket->dwArgumentsCount; + lpService->ThreadParams.W.lpArgVector = NULL; - /* Get the size of the service start arguments */ - if (ControlPacket->dwArgumentsCount > 0 && - ControlPacket->dwArgumentsOffset != 0) + 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; + + 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); -#endif - } + 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; /* ? */ - lpService->Arguments = HeapAlloc(GetProcessHeap(), - HEAP_ZERO_MEMORY, - dwArgumentsSize + sizeof(WCHAR)); - if (lpService->Arguments == NULL) - return ERROR_OUTOFMEMORY; + AnsiString = HeapAlloc(GetProcessHeap(), + 0, + AnsiLength + 1); + if (AnsiString == NULL) + return ERROR_OUTOFMEMORY; - Ptr = lpService->Arguments; + WideCharToMultiByte(CP_ACP, + 0, + lpService->Arguments, + dwLength, + AnsiString, + AnsiLength, + NULL, + NULL); - /* Add the service name as first argument */ - wcscpy(Ptr, pServiceName); - Ptr += (wcslen(pServiceName) + 1); + AnsiString[AnsiLength] = ANSI_NULL; - /* Add service start arguments */ - if (ControlPacket->dwArgumentsCount > 0 && - ControlPacket->dwArgumentsOffset != 0) - { - /* FIXME */ - } + 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; - *Ptr = 0; + dwArgCount++; + Ptr += (strlen(Ptr) + 1); + } + lpArgVector[dwArgCount] = NULL; + + (lpService->ThreadParams.A.lpServiceMain)(dwArgCount, lpArgVector); + + HeapFree(GetProcessHeap(), + 0, + lpArgVector); + HeapFree(GetProcessHeap(), + 0, + AnsiString); +#endif + } - /* 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; } -- 2.17.1