Pass additional arguments to a service when it is started by a call to StartService.

svn path=/trunk/; revision=23846
This commit is contained in:
Eric Kohl 2006-08-31 17:16:19 +00:00
parent 5a633f8fc9
commit 8537a75fba
6 changed files with 70 additions and 50 deletions

View file

@ -528,14 +528,14 @@ ScmGetBootAndSystemDriverState(VOID)
} }
static NTSTATUS static DWORD
ScmSendStartCommand(PSERVICE Service, LPWSTR Arguments) ScmSendStartCommand(PSERVICE Service,
LPWSTR Arguments)
{ {
PSCM_START_PACKET StartPacket; PSCM_START_PACKET StartPacket;
DWORD TotalLength; DWORD TotalLength;
#if 0 DWORD ArgsLength = 0;
DWORD Length; DWORD Length;
#endif
PWSTR Ptr; PWSTR Ptr;
DWORD Count; DWORD Count;
@ -543,7 +543,6 @@ ScmSendStartCommand(PSERVICE Service, LPWSTR Arguments)
/* Calculate the total length of the start command line */ /* Calculate the total length of the start command line */
TotalLength = wcslen(Service->lpServiceName) + 1; TotalLength = wcslen(Service->lpServiceName) + 1;
#if 0
if (Arguments != NULL) if (Arguments != NULL)
{ {
Ptr = Arguments; Ptr = Arguments;
@ -551,18 +550,20 @@ ScmSendStartCommand(PSERVICE Service, LPWSTR Arguments)
{ {
Length = wcslen(Ptr) + 1; Length = wcslen(Ptr) + 1;
TotalLength += Length; TotalLength += Length;
ArgsLength += Length;
Ptr += Length; Ptr += Length;
DPRINT("Arg: %S\n", Ptr);
} }
} }
#endif
TotalLength++; TotalLength++;
DPRINT("ArgsLength: %ld\nTotalLength: %ld\n\n", ArgsLength, TotalLength);
/* Allocate start command packet */ /* Allocate start command packet */
StartPacket = HeapAlloc(GetProcessHeap(), StartPacket = HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY, HEAP_ZERO_MEMORY,
sizeof(SCM_START_PACKET) + (TotalLength - 1) * sizeof(WCHAR)); sizeof(SCM_START_PACKET) + (TotalLength - 1) * sizeof(WCHAR));
if (StartPacket == NULL) if (StartPacket == NULL)
return STATUS_INSUFFICIENT_RESOURCES; return ERROR_NOT_ENOUGH_MEMORY;
StartPacket->Command = SCM_START_COMMAND; StartPacket->Command = SCM_START_COMMAND;
StartPacket->Size = TotalLength; StartPacket->Size = TotalLength;
@ -570,8 +571,14 @@ ScmSendStartCommand(PSERVICE Service, LPWSTR Arguments)
wcscpy(Ptr, Service->lpServiceName); wcscpy(Ptr, Service->lpServiceName);
Ptr += (wcslen(Service->lpServiceName) + 1); Ptr += (wcslen(Service->lpServiceName) + 1);
/* FIXME: Copy argument list */ /* Copy argument list */
if (Arguments != NULL)
{
memcpy(Ptr, Arguments, ArgsLength);
Ptr += ArgsLength;
}
/* Terminate the argument list */
*Ptr = 0; *Ptr = 0;
/* Send the start command */ /* Send the start command */
@ -583,18 +590,20 @@ ScmSendStartCommand(PSERVICE Service, LPWSTR Arguments)
/* FIXME: Read the reply */ /* FIXME: Read the reply */
/* Release the start command packet */
HeapFree(GetProcessHeap(), HeapFree(GetProcessHeap(),
0, 0,
StartPacket); StartPacket);
DPRINT("ScmSendStartCommand() done\n"); DPRINT("ScmSendStartCommand() done\n");
return STATUS_SUCCESS; return ERROR_SUCCESS;
} }
static NTSTATUS static DWORD
ScmStartUserModeService(PSERVICE Service) ScmStartUserModeService(PSERVICE Service,
LPWSTR lpArgs)
{ {
RTL_QUERY_REGISTRY_TABLE QueryTable[3]; RTL_QUERY_REGISTRY_TABLE QueryTable[3];
PROCESS_INFORMATION ProcessInformation; PROCESS_INFORMATION ProcessInformation;
@ -603,6 +612,7 @@ ScmStartUserModeService(PSERVICE Service)
ULONG Type; ULONG Type;
BOOL Result; BOOL Result;
NTSTATUS Status; NTSTATUS Status;
DWORD dwError = ERROR_SUCCESS;
RtlInitUnicodeString(&ImagePath, NULL); RtlInitUnicodeString(&ImagePath, NULL);
@ -626,7 +636,7 @@ ScmStartUserModeService(PSERVICE Service)
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT1("RtlQueryRegistryValues() failed (Status %lx)\n", Status); DPRINT1("RtlQueryRegistryValues() failed (Status %lx)\n", Status);
return Status; return RtlNtStatusToDosError(Status);
} }
DPRINT("ImagePath: '%S'\n", ImagePath.Buffer); DPRINT("ImagePath: '%S'\n", ImagePath.Buffer);
DPRINT("Type: %lx\n", Type); DPRINT("Type: %lx\n", Type);
@ -644,7 +654,7 @@ ScmStartUserModeService(PSERVICE Service)
if (Service->ControlPipeHandle == INVALID_HANDLE_VALUE) if (Service->ControlPipeHandle == INVALID_HANDLE_VALUE)
{ {
DPRINT1("Failed to create control pipe!\n"); DPRINT1("Failed to create control pipe!\n");
return STATUS_UNSUCCESSFUL; return GetLastError();
} }
StartupInfo.cb = sizeof(StartupInfo); StartupInfo.cb = sizeof(StartupInfo);
@ -669,12 +679,13 @@ ScmStartUserModeService(PSERVICE Service)
if (!Result) if (!Result)
{ {
dwError = GetLastError();
/* Close control pipe */ /* Close control pipe */
CloseHandle(Service->ControlPipeHandle); CloseHandle(Service->ControlPipeHandle);
Service->ControlPipeHandle = INVALID_HANDLE_VALUE; Service->ControlPipeHandle = INVALID_HANDLE_VALUE;
DPRINT1("Starting '%S' failed!\n", Service->lpServiceName); DPRINT1("Starting '%S' failed!\n", Service->lpServiceName);
return STATUS_UNSUCCESSFUL; return dwError;
} }
DPRINT("Process Id: %lu Handle %lx\n", DPRINT("Process Id: %lu Handle %lx\n",
@ -706,20 +717,21 @@ ScmStartUserModeService(PSERVICE Service)
&dwRead, &dwRead,
NULL)) NULL))
{ {
dwError = GetLastError();
DPRINT1("Reading the service control pipe failed (Error %lu)\n", DPRINT1("Reading the service control pipe failed (Error %lu)\n",
GetLastError()); dwError);
Status = STATUS_UNSUCCESSFUL;
} }
else else
{ {
DPRINT("Received process id %lu\n", dwProcessId); DPRINT("Received process id %lu\n", dwProcessId);
/* Send start command */ /* Send start command */
Status = ScmSendStartCommand(Service, NULL); dwError = ScmSendStartCommand(Service, lpArgs);
} }
} }
else else
{ {
dwError = GetLastError();
DPRINT("Connecting control pipe failed!\n"); DPRINT("Connecting control pipe failed!\n");
/* Close control pipe */ /* Close control pipe */
@ -727,22 +739,21 @@ ScmStartUserModeService(PSERVICE Service)
Service->ControlPipeHandle = INVALID_HANDLE_VALUE; Service->ControlPipeHandle = INVALID_HANDLE_VALUE;
Service->ProcessId = 0; Service->ProcessId = 0;
Service->ThreadId = 0; Service->ThreadId = 0;
Status = STATUS_UNSUCCESSFUL;
} }
/* Close process and thread handle */ /* Close process and thread handle */
CloseHandle(ProcessInformation.hThread); CloseHandle(ProcessInformation.hThread);
CloseHandle(ProcessInformation.hProcess); CloseHandle(ProcessInformation.hProcess);
return Status; return dwError;
} }
NTSTATUS DWORD
ScmStartService(PSERVICE Service) ScmStartService(PSERVICE Service, LPWSTR lpArgs)
{ {
PSERVICE_GROUP Group = Service->lpGroup; PSERVICE_GROUP Group = Service->lpGroup;
NTSTATUS Status; DWORD dwError = ERROR_SUCCESS;
DPRINT("ScmStartService() called\n"); DPRINT("ScmStartService() called\n");
@ -752,19 +763,19 @@ ScmStartService(PSERVICE Service)
if (Service->Status.dwServiceType & SERVICE_DRIVER) if (Service->Status.dwServiceType & SERVICE_DRIVER)
{ {
/* Load driver */ /* Load driver */
Status = ScmLoadDriver(Service); dwError = ScmLoadDriver(Service);
if (Status == STATUS_SUCCESS) if (dwError == ERROR_SUCCESS)
Service->Status.dwControlsAccepted = SERVICE_ACCEPT_STOP; Service->Status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
} }
else else
{ {
/* Start user-mode service */ /* Start user-mode service */
Status = ScmStartUserModeService(Service); dwError = ScmStartUserModeService(Service, lpArgs);
} }
DPRINT("ScmStartService() done (Status %lx)\n", Status); DPRINT("ScmStartService() done (Error %lu)\n", dwError);
if (NT_SUCCESS(Status)) if (dwError == ERROR_SUCCESS)
{ {
if (Group != NULL) if (Group != NULL)
{ {
@ -802,7 +813,7 @@ ScmStartService(PSERVICE Service)
} }
#endif #endif
return Status; return dwError;
} }
@ -846,7 +857,7 @@ ScmAutoStartServices(VOID)
(CurrentService->dwTag == CurrentGroup->TagArray[i])) (CurrentService->dwTag == CurrentGroup->TagArray[i]))
{ {
CurrentService->ServiceVisited = TRUE; CurrentService->ServiceVisited = TRUE;
ScmStartService(CurrentService); ScmStartService(CurrentService, NULL);
} }
ServiceEntry = ServiceEntry->Flink; ServiceEntry = ServiceEntry->Flink;
@ -864,7 +875,7 @@ ScmAutoStartServices(VOID)
(CurrentService->ServiceVisited == FALSE)) (CurrentService->ServiceVisited == FALSE))
{ {
CurrentService->ServiceVisited = TRUE; CurrentService->ServiceVisited = TRUE;
ScmStartService(CurrentService); ScmStartService(CurrentService, NULL);
} }
ServiceEntry = ServiceEntry->Flink; ServiceEntry = ServiceEntry->Flink;
@ -884,7 +895,7 @@ ScmAutoStartServices(VOID)
(CurrentService->ServiceVisited == FALSE)) (CurrentService->ServiceVisited == FALSE))
{ {
CurrentService->ServiceVisited = TRUE; CurrentService->ServiceVisited = TRUE;
ScmStartService(CurrentService); ScmStartService(CurrentService, NULL);
} }
ServiceEntry = ServiceEntry->Flink; ServiceEntry = ServiceEntry->Flink;
@ -901,7 +912,7 @@ ScmAutoStartServices(VOID)
(CurrentService->ServiceVisited == FALSE)) (CurrentService->ServiceVisited == FALSE))
{ {
CurrentService->ServiceVisited = TRUE; CurrentService->ServiceVisited = TRUE;
ScmStartService(CurrentService); ScmStartService(CurrentService, NULL);
} }
ServiceEntry = ServiceEntry->Flink; ServiceEntry = ServiceEntry->Flink;

View file

@ -11,12 +11,13 @@
/* FUNCTIONS ****************************************************************/ /* FUNCTIONS ****************************************************************/
NTSTATUS DWORD
ScmLoadDriver(PSERVICE lpService) ScmLoadDriver(PSERVICE lpService)
{ {
WCHAR szDriverPath[MAX_PATH]; WCHAR szDriverPath[MAX_PATH];
UNICODE_STRING DriverPath; UNICODE_STRING DriverPath;
NTSTATUS Status; NTSTATUS Status;
DWORD dwError = ERROR_SUCCESS;
/* Build the driver path */ /* Build the driver path */
wcscpy(szDriverPath, wcscpy(szDriverPath,
@ -34,7 +35,12 @@ ScmLoadDriver(PSERVICE lpService)
/* FIXME: Release privilege */ /* FIXME: Release privilege */
return Status; if (!NT_SUCCESS(Status))
{
dwError = RtlNtStatusToDosError(Status);
}
return dwError;
} }

View file

@ -1755,7 +1755,6 @@ ScmrStartServiceW(handle_t BindingHandle,
DWORD dwError = ERROR_SUCCESS; DWORD dwError = ERROR_SUCCESS;
PSERVICE_HANDLE hSvc; PSERVICE_HANDLE hSvc;
PSERVICE lpService = NULL; PSERVICE lpService = NULL;
NTSTATUS Status;
DPRINT1("ScmrStartServiceW() called\n"); DPRINT1("ScmrStartServiceW() called\n");
@ -1790,12 +1789,7 @@ ScmrStartServiceW(handle_t BindingHandle,
return ERROR_SERVICE_MARKED_FOR_DELETE; return ERROR_SERVICE_MARKED_FOR_DELETE;
/* Start the service */ /* Start the service */
Status = ScmStartService(lpService); dwError = ScmStartService(lpService, (LPWSTR)lpServiceArgBuffer);
if (!NT_SUCCESS(Status))
{
DPRINT("ScmStartService failed!\n");
return RtlNtStatusToDosError(Status);
}
return dwError; return dwError;
} }
@ -2099,7 +2093,6 @@ ScmrStartServiceA(handle_t BindingHandle,
DWORD dwError = ERROR_SUCCESS; DWORD dwError = ERROR_SUCCESS;
PSERVICE_HANDLE hSvc; PSERVICE_HANDLE hSvc;
PSERVICE lpService = NULL; PSERVICE lpService = NULL;
NTSTATUS Status;
DPRINT1("ScmrStartServiceA() called\n"); DPRINT1("ScmrStartServiceA() called\n");
@ -2136,9 +2129,9 @@ ScmrStartServiceA(handle_t BindingHandle,
/* FIXME: Convert argument vector to Unicode */ /* FIXME: Convert argument vector to Unicode */
/* Start the service */ /* Start the service */
Status = ScmStartService(lpService); dwError = ScmStartService(lpService, NULL);
if (!NT_SUCCESS(Status))
return RtlNtStatusToDosError(Status); /* FIXME: Free argument vector */
return dwError; return dwError;
} }

View file

@ -88,6 +88,8 @@ DWORD ScmReadString(HKEY hServiceKey,
DWORD ScmCreateServiceDatabase(VOID); DWORD ScmCreateServiceDatabase(VOID);
VOID ScmGetBootAndSystemDriverState(VOID); VOID ScmGetBootAndSystemDriverState(VOID);
VOID ScmAutoStartServices(VOID); VOID ScmAutoStartServices(VOID);
DWORD ScmStartService(PSERVICE Service,
LPWSTR lpArgs);
PSERVICE ScmGetServiceEntryByName(LPWSTR lpServiceName); PSERVICE ScmGetServiceEntryByName(LPWSTR lpServiceName);
PSERVICE ScmGetServiceEntryByDisplayName(LPWSTR lpDisplayName); PSERVICE ScmGetServiceEntryByDisplayName(LPWSTR lpDisplayName);
@ -99,7 +101,7 @@ DWORD ScmMarkServiceForDelete(PSERVICE pService);
/* driver.c */ /* driver.c */
NTSTATUS ScmLoadDriver(PSERVICE lpService); DWORD ScmLoadDriver(PSERVICE lpService);
DWORD ScmUnloadDriver(PSERVICE lpService); DWORD ScmUnloadDriver(PSERVICE lpService);
DWORD ScmControlDriver(PSERVICE lpService, DWORD ScmControlDriver(PSERVICE lpService,
DWORD dwControl, DWORD dwControl,
@ -121,8 +123,6 @@ VOID ScmStartRpcServer(VOID);
/* services.c */ /* services.c */
VOID PrintString(LPCSTR fmt, ...); VOID PrintString(LPCSTR fmt, ...);
NTSTATUS ScmStartService(PSERVICE Service);
/* EOF */ /* EOF */

View file

@ -90,17 +90,24 @@ ScServiceMainStub(LPVOID Context)
PACTIVE_SERVICE lpService; PACTIVE_SERVICE lpService;
DWORD dwArgCount = 0; DWORD dwArgCount = 0;
DWORD dwLength = 0; DWORD dwLength = 0;
DWORD dwLen;
LPWSTR lpPtr;
lpService = (PACTIVE_SERVICE)Context; lpService = (PACTIVE_SERVICE)Context;
DPRINT("ScServiceMainStub() called\n"); DPRINT("ScServiceMainStub() called\n");
/* Count arguments */ /* Count arguments */
while (lpService->Arguments[dwLength]) lpPtr = lpService->Arguments;
while (*lpPtr)
{ {
dwLength += wcslen(&lpService->Arguments[dwLength]) + 1; DPRINT("arg: %S\n", *lpPtr);
dwLen = wcslen(lpPtr) + 1;
dwArgCount++; dwArgCount++;
dwLength += dwLen;
lpPtr += dwLen;
} }
DPRINT("dwArgCount: %ld\ndwLength: %ld\n", dwArgCount, dwLength);
/* Build the argument vector and call the main service routine */ /* Build the argument vector and call the main service routine */
if (lpService->bUnicode) if (lpService->bUnicode)
@ -241,6 +248,7 @@ ScStartService(PSCM_START_PACKET StartPacket)
PACTIVE_SERVICE lpService; PACTIVE_SERVICE lpService;
HANDLE ThreadHandle; HANDLE ThreadHandle;
DPRINT("ScStartService() called\n");
DPRINT("Size: %lu\n", StartPacket->Size); DPRINT("Size: %lu\n", StartPacket->Size);
DPRINT("Service: %S\n", &StartPacket->Arguments[0]); DPRINT("Service: %S\n", &StartPacket->Arguments[0]);

View file

@ -38,6 +38,8 @@
#define LANG_RHAETO_ROMANCE 0x17 #define LANG_RHAETO_ROMANCE 0x17
#define LANG_SAAMI 0x3b #define LANG_SAAMI 0x3b
#define LANG_SORBIAN 0x2e #define LANG_SORBIAN 0x2e
#define LANG_LOWER_SORBIAN 0x2e
#define LANG_UPPER_SORBIAN 0x2e
#define LANG_SUTU 0x30 #define LANG_SUTU 0x30
#define LANG_TSONGA 0x31 #define LANG_TSONGA 0x31
#define LANG_TSWANA 0x32 #define LANG_TSWANA 0x32