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

View file

@ -11,12 +11,13 @@
/* FUNCTIONS ****************************************************************/
NTSTATUS
DWORD
ScmLoadDriver(PSERVICE lpService)
{
WCHAR szDriverPath[MAX_PATH];
UNICODE_STRING DriverPath;
NTSTATUS Status;
DWORD dwError = ERROR_SUCCESS;
/* Build the driver path */
wcscpy(szDriverPath,
@ -34,7 +35,12 @@ ScmLoadDriver(PSERVICE lpService)
/* 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;
PSERVICE_HANDLE hSvc;
PSERVICE lpService = NULL;
NTSTATUS Status;
DPRINT1("ScmrStartServiceW() called\n");
@ -1790,12 +1789,7 @@ ScmrStartServiceW(handle_t BindingHandle,
return ERROR_SERVICE_MARKED_FOR_DELETE;
/* Start the service */
Status = ScmStartService(lpService);
if (!NT_SUCCESS(Status))
{
DPRINT("ScmStartService failed!\n");
return RtlNtStatusToDosError(Status);
}
dwError = ScmStartService(lpService, (LPWSTR)lpServiceArgBuffer);
return dwError;
}
@ -2099,7 +2093,6 @@ ScmrStartServiceA(handle_t BindingHandle,
DWORD dwError = ERROR_SUCCESS;
PSERVICE_HANDLE hSvc;
PSERVICE lpService = NULL;
NTSTATUS Status;
DPRINT1("ScmrStartServiceA() called\n");
@ -2136,9 +2129,9 @@ ScmrStartServiceA(handle_t BindingHandle,
/* FIXME: Convert argument vector to Unicode */
/* Start the service */
Status = ScmStartService(lpService);
if (!NT_SUCCESS(Status))
return RtlNtStatusToDosError(Status);
dwError = ScmStartService(lpService, NULL);
/* FIXME: Free argument vector */
return dwError;
}

View file

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

View file

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

View file

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