Author: ekohl
Date: Sun Aug 21 15:35:19 2011
New Revision: 53358
URL:
http://svn.reactos.org/svn/reactos?rev=53358&view=rev
Log:
[SERVICES/ADVAPI32]
Rewrite the command packet transfer code between the service control manager
(services.exe) and the service control dispatcher (advapi32.dll). The service name is no
longer stored in an array of WCHARs at the end of the command packet. The service name is
now stored behind the fixed size command packet header using an offset value in the header
to determine the start of the string. The same method will be used to store start
arguments to the service dispatcher, but it is not fully implemented yet.
Modified:
trunk/reactos/base/system/services/database.c
trunk/reactos/base/system/services/rpcserver.c
trunk/reactos/base/system/services/services.h
trunk/reactos/dll/win32/advapi32/service/sctrl.c
trunk/reactos/include/reactos/services/services.h
Modified: trunk/reactos/base/system/services/database.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/services/datab…
==============================================================================
--- trunk/reactos/base/system/services/database.c [iso-8859-1] (original)
+++ trunk/reactos/base/system/services/database.c [iso-8859-1] Sun Aug 21 15:35:19 2011
@@ -918,33 +918,43 @@
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 @@
{
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 @@
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;
- }
- }
- TotalLength++;
- DPRINT("ArgsLength: %ld TotalLength: %ld\n", ArgsLength, TotalLength);
+ DPRINT("Argv[%lu]: %S\n", i, argv[i]);
+ PacketSize += (wcslen(argv[i]) + 1) * sizeof(WCHAR) + sizeof(PWSTR);
+ }
+ }
/* 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)
- {
- UNIMPLEMENTED;
- DPRINT1("Arguments sent to service ignored!\n");
+ if (argc > 0 && argv != NULL)
+ {
+// 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);
Modified: trunk/reactos/base/system/services/rpcserver.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/services/rpcse…
==============================================================================
--- trunk/reactos/base/system/services/rpcserver.c [iso-8859-1] (original)
+++ trunk/reactos/base/system/services/rpcserver.c [iso-8859-1] Sun Aug 21 15:35:19 2011
@@ -11,7 +11,6 @@
/* INCLUDES ****************************************************************/
#include "services.h"
-#include "svcctl_s.h"
#define NDEBUG
#include <debug.h>
@@ -2868,8 +2867,17 @@
DWORD dwError = ERROR_SUCCESS;
PSERVICE_HANDLE hSvc;
PSERVICE lpService = NULL;
-
- DPRINT("RStartServiceW() called\n");
+ DWORD i;
+
+ 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 @@
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;
}
Modified: trunk/reactos/base/system/services/services.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/services/servi…
==============================================================================
--- trunk/reactos/base/system/services/services.h [iso-8859-1] (original)
+++ trunk/reactos/base/system/services/services.h [iso-8859-1] Sun Aug 21 15:35:19 2011
@@ -11,6 +11,7 @@
#include <ndk/obfuncs.h>
#include <ndk/rtlfuncs.h>
#include <services/services.h>
+#include "svcctl_s.h"
typedef struct _SERVICE_GROUP
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] Sun Aug 21 15:35:19
2011
@@ -125,13 +125,19 @@
{
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);
@@ -344,23 +350,52 @@
{
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 @@
{
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 @@
return FALSE;
}
- lpServiceName = &ControlPacket->szArguments[0];
+ lpServiceName = (LPWSTR)((PBYTE)ControlPacket +
ControlPacket->dwServiceNameOffset);
TRACE("Service: %S\n", lpServiceName);
lpService = ScLookupServiceByServiceName(lpServiceName);
Modified: trunk/reactos/include/reactos/services/services.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/reactos/services/s…
==============================================================================
--- trunk/reactos/include/reactos/services/services.h [iso-8859-1] (original)
+++ trunk/reactos/include/reactos/services/services.h [iso-8859-1] Sun Aug 21 15:35:19
2011
@@ -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