diff --git a/reactos/base/system/services/database.c b/reactos/base/system/services/database.c index 1c2cc7eeaa6..8b22e36867e 100644 --- a/reactos/base/system/services/database.c +++ b/reactos/base/system/services/database.c @@ -918,33 +918,43 @@ ScmControlService(PSERVICE Service, DWORD dwWriteCount = 0; DWORD dwReadCount = 0; - DWORD TotalLength; + DWORD PacketSize; + PWSTR Ptr; DWORD dwError = ERROR_SUCCESS; DPRINT("ScmControlService() called\n"); EnterCriticalSection(&ControlServiceCriticalSection); - TotalLength = wcslen(Service->lpServiceName) + 1; + /* Calculate the total length of the start command line */ + PacketSize = sizeof(SCM_CONTROL_PACKET); + PacketSize += (wcslen(Service->lpServiceName) + 1) * sizeof(WCHAR); ControlPacket = (SCM_CONTROL_PACKET*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - sizeof(SCM_CONTROL_PACKET) + (TotalLength * sizeof(WCHAR))); + PacketSize); if (ControlPacket == NULL) { LeaveCriticalSection(&ControlServiceCriticalSection); return ERROR_NOT_ENOUGH_MEMORY; } + ControlPacket->dwSize = PacketSize; ControlPacket->dwControl = dwControl; - ControlPacket->dwSize = TotalLength; ControlPacket->hServiceStatus = (SERVICE_STATUS_HANDLE)Service; - wcscpy(&ControlPacket->szArguments[0], Service->lpServiceName); + + ControlPacket->dwServiceNameOffset = sizeof(SCM_CONTROL_PACKET); + + Ptr = (PWSTR)((PBYTE)ControlPacket + ControlPacket->dwServiceNameOffset); + wcscpy(Ptr, Service->lpServiceName); + + ControlPacket->dwArgumentsCount = 0; + ControlPacket->dwArgumentsOffset = 0; /* Send the control packet */ WriteFile(Service->lpImage->hControlPipe, ControlPacket, - sizeof(SCM_CONTROL_PACKET) + (TotalLength * sizeof(WCHAR)), + PacketSize, &dwWriteCount, NULL); @@ -986,9 +996,7 @@ ScmSendStartCommand(PSERVICE Service, { PSCM_CONTROL_PACKET ControlPacket; SCM_REPLY_PACKET ReplyPacket; - DWORD TotalLength; - DWORD ArgsLength = 0; - DWORD Length; + DWORD PacketSize; PWSTR Ptr; DWORD dwWriteCount = 0; DWORD dwReadCount = 0; @@ -998,52 +1006,59 @@ ScmSendStartCommand(PSERVICE Service, DPRINT("ScmSendStartCommand() called\n"); /* Calculate the total length of the start command line */ - TotalLength = wcslen(Service->lpServiceName) + 1; - if (argc > 0) + PacketSize = sizeof(SCM_CONTROL_PACKET); + PacketSize += (wcslen(Service->lpServiceName) + 1) * sizeof(WCHAR); + + /* Calculate the required packet size for the start arguments */ + if (argc > 0 && argv != NULL) { + PacketSize = ALIGN_UP(PacketSize, LPWSTR); + + DPRINT("Argc: %lu\n", argc); for (i = 0; i < argc; i++) { - DPRINT("Arg: %S\n", argv[i]); - Length = wcslen(argv[i]) + 1; - TotalLength += Length; - ArgsLength += Length; + DPRINT("Argv[%lu]: %S\n", i, argv[i]); + PacketSize += (wcslen(argv[i]) + 1) * sizeof(WCHAR) + sizeof(PWSTR); } } - TotalLength++; - DPRINT("ArgsLength: %ld TotalLength: %ld\n", ArgsLength, TotalLength); /* Allocate a control packet */ ControlPacket = (SCM_CONTROL_PACKET*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - sizeof(SCM_CONTROL_PACKET) + (TotalLength - 1) * sizeof(WCHAR)); + PacketSize); if (ControlPacket == NULL) return ERROR_NOT_ENOUGH_MEMORY; + ControlPacket->dwSize = PacketSize; ControlPacket->dwControl = SERVICE_CONTROL_START; ControlPacket->hServiceStatus = (SERVICE_STATUS_HANDLE)Service; - ControlPacket->dwSize = TotalLength; - Ptr = &ControlPacket->szArguments[0]; + ControlPacket->dwServiceNameOffset = sizeof(SCM_CONTROL_PACKET); + + Ptr = (PWSTR)((PBYTE)ControlPacket + ControlPacket->dwServiceNameOffset); wcscpy(Ptr, Service->lpServiceName); - Ptr += (wcslen(Service->lpServiceName) + 1); + + ControlPacket->dwArgumentsCount = 0; + ControlPacket->dwArgumentsOffset = 0; /* Copy argument list */ - if (argc > 0) + if (argc > 0 && argv != NULL) { - UNIMPLEMENTED; - DPRINT1("Arguments sent to service ignored!\n"); +// Ptr += wcslen(Service->lpServiceName) + 1; +// Ptr = ALIGN_UP_POINTER(Ptr, LPWSTR); + +// ControlPacket->dwArgumentsOffset = (DWORD)((INT_PTR)Ptr - (INT_PTR)ControlPacket); + + #if 0 memcpy(Ptr, Arguments, ArgsLength); Ptr += ArgsLength; #endif } - /* Terminate the argument list */ - *Ptr = 0; - /* Send the start command */ WriteFile(Service->lpImage->hControlPipe, ControlPacket, - sizeof(SCM_CONTROL_PACKET) + (TotalLength - 1) * sizeof(WCHAR), + PacketSize, &dwWriteCount, NULL); diff --git a/reactos/base/system/services/rpcserver.c b/reactos/base/system/services/rpcserver.c index 6f909a28622..6a7895992de 100644 --- a/reactos/base/system/services/rpcserver.c +++ b/reactos/base/system/services/rpcserver.c @@ -11,7 +11,6 @@ /* INCLUDES ****************************************************************/ #include "services.h" -#include "svcctl_s.h" #define NDEBUG #include @@ -2868,8 +2867,17 @@ DWORD RStartServiceW( DWORD dwError = ERROR_SUCCESS; PSERVICE_HANDLE hSvc; PSERVICE lpService = NULL; + DWORD i; - DPRINT("RStartServiceW() called\n"); + DPRINT("RStartServiceW(%p %lu %p) called\n", hService, argc, argv); + DPRINT(" argc: %lu\n", argc); + if (argv != NULL) + { + for (i = 0; i < argc; i++) + { + DPRINT(" argv[%lu]: %S\n", i, argv[i]); + } + } if (ScmShutdown) return ERROR_SHUTDOWN_IN_PROGRESS; @@ -2901,13 +2909,8 @@ DWORD RStartServiceW( if (lpService->bDeleted) return ERROR_SERVICE_MARKED_FOR_DELETE; - if (argv) { - UNIMPLEMENTED; - argv = NULL; - } - /* Start the service */ - dwError = ScmStartService(lpService, argc, (LPWSTR *)argv); + dwError = ScmStartService(lpService, argc, (LPWSTR*)argv); return dwError; } diff --git a/reactos/base/system/services/services.h b/reactos/base/system/services/services.h index 210f8db5219..c22f95a1ccc 100644 --- a/reactos/base/system/services/services.h +++ b/reactos/base/system/services/services.h @@ -11,6 +11,7 @@ #include #include #include +#include "svcctl_s.h" typedef struct _SERVICE_GROUP diff --git a/reactos/dll/win32/advapi32/service/sctrl.c b/reactos/dll/win32/advapi32/service/sctrl.c index 1a1b31e6966..c77f133ee49 100644 --- a/reactos/dll/win32/advapi32/service/sctrl.c +++ b/reactos/dll/win32/advapi32/service/sctrl.c @@ -125,14 +125,20 @@ ScLookupServiceByServiceName(LPCWSTR lpServiceName) { DWORD i; + TRACE("ScLookupServiceByServiceName(%S) called\n", lpServiceName); + for (i = 0; i < dwActiveServiceCount; i++) { + TRACE("Checking %S\n", lpActiveServices[i].ServiceName.Buffer); if (_wcsicmp(lpActiveServices[i].ServiceName.Buffer, lpServiceName) == 0) { + TRACE("Found!\n"); return &lpActiveServices[i]; } } + TRACE("No service found!\n"); + SetLastError(ERROR_SERVICE_DOES_NOT_EXIST); return NULL; @@ -344,23 +350,52 @@ ScStartService(PACTIVE_SERVICE lpService, { HANDLE ThreadHandle; DWORD ThreadId; + PWSTR pServiceName; + PWSTR Ptr; + DWORD dwArgumentsSize; TRACE("ScStartService() called\n"); TRACE("Size: %lu\n", ControlPacket->dwSize); - TRACE("Service: %S\n", &ControlPacket->szArguments[0]); + TRACE("Service: %S\n", (PWSTR)((PBYTE)ControlPacket + ControlPacket->dwServiceNameOffset)); /* 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); + + /* Get the size of the service start arguments */ + if (ControlPacket->dwArgumentsCount > 0 && + ControlPacket->dwArgumentsOffset != 0) + { + /* FIXME */ +#if 0 + dwArgumentSize += (wcslen(...) + 1) * sizeof(WCHAR); +#endif + } + lpService->Arguments = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - (ControlPacket->dwSize + 1) * sizeof(WCHAR)); + dwArgumentsSize + sizeof(WCHAR)); if (lpService->Arguments == NULL) return ERROR_OUTOFMEMORY; - memcpy(lpService->Arguments, - ControlPacket->szArguments, - ControlPacket->dwSize * sizeof(WCHAR)); + 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 */ ThreadHandle = CreateThread(NULL, @@ -385,7 +420,7 @@ ScControlService(PACTIVE_SERVICE lpService, { TRACE("ScControlService() called\n"); TRACE("Size: %lu\n", ControlPacket->dwSize); - TRACE("Service: %S\n", &ControlPacket->szArguments[0]); + TRACE("Service: %S\n", (PWSTR)((PBYTE)ControlPacket + ControlPacket->dwServiceNameOffset)); if (lpService->HandlerFunction) { @@ -446,7 +481,7 @@ ScServiceDispatcher(HANDLE hPipe, return FALSE; } - lpServiceName = &ControlPacket->szArguments[0]; + lpServiceName = (LPWSTR)((PBYTE)ControlPacket + ControlPacket->dwServiceNameOffset); TRACE("Service: %S\n", lpServiceName); lpService = ScLookupServiceByServiceName(lpServiceName); diff --git a/reactos/include/reactos/services/services.h b/reactos/include/reactos/services/services.h index 009c2506b7d..9a46a61ae13 100644 --- a/reactos/include/reactos/services/services.h +++ b/reactos/include/reactos/services/services.h @@ -13,10 +13,12 @@ typedef struct _SCM_CONTROL_PACKET { + DWORD dwSize; DWORD dwControl; SERVICE_STATUS_HANDLE hServiceStatus; - DWORD dwSize; - WCHAR szArguments[1]; + DWORD dwServiceNameOffset; + DWORD dwArgumentsCount; + DWORD dwArgumentsOffset; } SCM_CONTROL_PACKET, *PSCM_CONTROL_PACKET; typedef struct _SCM_REPLY_PACKET