mirror of
https://github.com/reactos/reactos.git
synced 2024-11-20 06:15:26 +00:00
Use the service contol pipe to send a start command in order to start a service thread.
svn path=/trunk/; revision=13350
This commit is contained in:
parent
91337fece1
commit
9f44705b10
3 changed files with 353 additions and 148 deletions
24
reactos/include/services/services.h
Normal file
24
reactos/include/services/services.h
Normal file
|
@ -0,0 +1,24 @@
|
|||
/* $Id$
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: include/services/services.h
|
||||
* PURPOSE: Private interface between SERVICES.EXE and ADVAPI32.DLL
|
||||
* PROGRAMMER: Eric Kohl
|
||||
*/
|
||||
|
||||
#ifndef __SERVICES_SERVICES_H__
|
||||
#define __SERVICES_SERVICES_H__
|
||||
|
||||
#define SCM_START_COMMAND 1
|
||||
|
||||
typedef struct _SCM_START_PACKET
|
||||
{
|
||||
ULONG Command;
|
||||
ULONG Size;
|
||||
WCHAR Arguments[1];
|
||||
} SCM_START_PACKET, *PSCM_START_PACKET;
|
||||
|
||||
#endif /* __SERVICES_SERVICES_H__ */
|
||||
|
||||
/* EOF */
|
|
@ -13,6 +13,8 @@
|
|||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include "advapi32.h"
|
||||
#include <services/services.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
|
@ -23,9 +25,15 @@ typedef struct _ACTIVE_SERVICE
|
|||
{
|
||||
DWORD ThreadId;
|
||||
UNICODE_STRING ServiceName;
|
||||
LPSERVICE_MAIN_FUNCTIONW MainFunction;
|
||||
union
|
||||
{
|
||||
LPSERVICE_MAIN_FUNCTIONA lpFuncA;
|
||||
LPSERVICE_MAIN_FUNCTIONW lpFuncW;
|
||||
} Main;
|
||||
LPHANDLER_FUNCTION HandlerFunction;
|
||||
SERVICE_STATUS ServiceStatus;
|
||||
BOOL bUnicode;
|
||||
LPWSTR Arguments;
|
||||
} ACTIVE_SERVICE, *PACTIVE_SERVICE;
|
||||
|
||||
|
||||
|
@ -33,7 +41,6 @@ typedef struct _ACTIVE_SERVICE
|
|||
|
||||
static DWORD dwActiveServiceCount = 0;
|
||||
static PACTIVE_SERVICE lpActiveServices = NULL;
|
||||
/* static PHANDLE ActiveServicesThreadHandles; */ /* uncomment when in use */
|
||||
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
@ -80,15 +87,53 @@ static DWORD WINAPI
|
|||
ScServiceMainStub(LPVOID Context)
|
||||
{
|
||||
PACTIVE_SERVICE lpService;
|
||||
DWORD dwArgCount = 0;
|
||||
DWORD dwLength = 0;
|
||||
|
||||
lpService = (PACTIVE_SERVICE)Context;
|
||||
|
||||
DPRINT("ScServiceMainStub() called\n");
|
||||
|
||||
/* FIXME: Send argc and argv (from command line) as arguments */
|
||||
/* Count arguments */
|
||||
while (lpService->Arguments[dwLength])
|
||||
{
|
||||
dwLength += wcslen(&lpService->Arguments[dwLength]) + 1;
|
||||
dwArgCount++;
|
||||
}
|
||||
|
||||
/* Build the argument vector and call the main service routine */
|
||||
if (lpService->bUnicode)
|
||||
{
|
||||
LPWSTR *lpArgVector;
|
||||
LPWSTR Ptr;
|
||||
|
||||
(lpService->MainFunction)(0, NULL);
|
||||
lpArgVector = HeapAlloc(GetProcessHeap(),
|
||||
HEAP_ZERO_MEMORY,
|
||||
(dwArgCount + 1) * sizeof(LPWSTR));
|
||||
if (lpArgVector == NULL)
|
||||
return ERROR_OUTOFMEMORY;
|
||||
|
||||
dwArgCount = 0;
|
||||
Ptr = lpService->Arguments;
|
||||
while (*Ptr)
|
||||
{
|
||||
lpArgVector[dwArgCount] = Ptr;
|
||||
|
||||
dwArgCount++;
|
||||
Ptr += (wcslen(Ptr) + 1);
|
||||
}
|
||||
lpArgVector[dwArgCount] = NULL;
|
||||
|
||||
(lpService->Main.lpFuncW)(dwArgCount, lpArgVector);
|
||||
|
||||
HeapFree(GetProcessHeap(),
|
||||
0,
|
||||
lpArgVector);
|
||||
}
|
||||
else
|
||||
{
|
||||
(lpService->Main.lpFuncA)(0, NULL);
|
||||
}
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
@ -141,17 +186,29 @@ ScConnectControlPipe(HANDLE *hPipe)
|
|||
}
|
||||
|
||||
|
||||
static BOOL
|
||||
ScServiceDispatcher(HANDLE hPipe,
|
||||
PUCHAR lpBuffer,
|
||||
DWORD dwBufferSize)
|
||||
|
||||
static DWORD
|
||||
ScStartService(PSCM_START_PACKET StartPacket)
|
||||
{
|
||||
PACTIVE_SERVICE lpService;
|
||||
HANDLE ThreadHandle;
|
||||
|
||||
DPRINT("ScDispatcherLoop() called\n");
|
||||
DPRINT("Size: %lu\n", StartPacket->Size);
|
||||
DPRINT("Service: %S\n", &StartPacket->Arguments[0]);
|
||||
|
||||
lpService = &lpActiveServices[0];
|
||||
lpService = ScLookupServiceByServiceName(&StartPacket->Arguments[0]);
|
||||
if (lpService == NULL)
|
||||
return ERROR_SERVICE_DOES_NOT_EXIST;
|
||||
|
||||
lpService->Arguments = HeapAlloc(GetProcessHeap(),
|
||||
HEAP_ZERO_MEMORY,
|
||||
StartPacket->Size);
|
||||
if (lpService->Arguments == NULL)
|
||||
return ERROR_OUTOFMEMORY;
|
||||
|
||||
memcpy(lpService->Arguments,
|
||||
StartPacket->Arguments,
|
||||
StartPacket->Size * sizeof(WCHAR));
|
||||
|
||||
ThreadHandle = CreateThread(NULL,
|
||||
0,
|
||||
|
@ -160,21 +217,63 @@ ScServiceDispatcher(HANDLE hPipe,
|
|||
CREATE_SUSPENDED,
|
||||
&lpService->ThreadId);
|
||||
if (ThreadHandle == NULL)
|
||||
return FALSE;
|
||||
return ERROR_SERVICE_NO_THREAD;
|
||||
|
||||
ResumeThread(ThreadHandle);
|
||||
|
||||
CloseHandle(ThreadHandle);
|
||||
|
||||
#if 0
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static BOOL
|
||||
ScServiceDispatcher(HANDLE hPipe,
|
||||
PUCHAR lpBuffer,
|
||||
DWORD dwBufferSize)
|
||||
{
|
||||
LPDWORD Buffer;
|
||||
DWORD Count;
|
||||
BOOL bResult;
|
||||
|
||||
DPRINT("ScDispatcherLoop() called\n");
|
||||
|
||||
Buffer = HeapAlloc(GetProcessHeap(),
|
||||
HEAP_ZERO_MEMORY,
|
||||
1024);
|
||||
if (Buffer == NULL)
|
||||
return FALSE;
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
/* Read command from the control pipe */
|
||||
bResult = ReadFile(hPipe,
|
||||
Buffer,
|
||||
1024,
|
||||
&Count,
|
||||
NULL);
|
||||
if (bResult == FALSE)
|
||||
{
|
||||
DPRINT1("Pipe read failed\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Execute command */
|
||||
switch (Buffer[0])
|
||||
{
|
||||
case SCM_START_COMMAND:
|
||||
DPRINT("Start command\n");
|
||||
ScStartService((PSCM_START_PACKET)Buffer);
|
||||
break;
|
||||
|
||||
default:
|
||||
DPRINT1("Unknown command %lu", Buffer[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
HeapFree(GetProcessHeap(),
|
||||
0,
|
||||
Buffer);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -324,7 +423,8 @@ StartServiceCtrlDispatcherA(LPSERVICE_TABLE_ENTRYA lpServiceStartTable)
|
|||
{
|
||||
RtlCreateUnicodeStringFromAsciiz(&lpActiveServices[i].ServiceName,
|
||||
lpServiceStartTable[i].lpServiceName);
|
||||
lpActiveServices[i].MainFunction = (LPSERVICE_MAIN_FUNCTIONW)lpServiceStartTable[i].lpServiceProc;
|
||||
lpActiveServices[i].Main.lpFuncA = lpServiceStartTable[i].lpServiceProc;
|
||||
lpActiveServices[i].bUnicode = FALSE;
|
||||
}
|
||||
|
||||
dwError = ScConnectControlPipe(&hPipe);
|
||||
|
@ -400,7 +500,8 @@ StartServiceCtrlDispatcherW(LPSERVICE_TABLE_ENTRYW lpServiceStartTable)
|
|||
{
|
||||
RtlCreateUnicodeString(&lpActiveServices[i].ServiceName,
|
||||
lpServiceStartTable[i].lpServiceName);
|
||||
lpActiveServices[i].MainFunction = lpServiceStartTable[i].lpServiceProc;
|
||||
lpActiveServices[i].Main.lpFuncW = lpServiceStartTable[i].lpServiceProc;
|
||||
lpActiveServices[i].bUnicode = TRUE;
|
||||
}
|
||||
|
||||
dwError = ScConnectControlPipe(&hPipe);
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include <windows.h>
|
||||
#include <tchar.h>
|
||||
|
||||
#include <services/services.h>
|
||||
#include "services.h"
|
||||
|
||||
#define NDEBUG
|
||||
|
@ -521,8 +522,72 @@ ScmGetBootAndSystemDriverState(VOID)
|
|||
|
||||
|
||||
static NTSTATUS
|
||||
ScmStartService(PSERVICE Service,
|
||||
PSERVICE_GROUP Group)
|
||||
ScmSendStartCommand(PSERVICE Service, LPWSTR Arguments)
|
||||
{
|
||||
PSCM_START_PACKET StartPacket;
|
||||
DWORD TotalLength;
|
||||
#if 0
|
||||
DWORD Length;
|
||||
#endif
|
||||
PWSTR Ptr;
|
||||
DWORD Count;
|
||||
|
||||
DPRINT("ScmSendStartCommand() called\n");
|
||||
|
||||
/* Calculate the total length of the start command line */
|
||||
TotalLength = wcslen(Service->ServiceName.Buffer) + 1;
|
||||
#if 0
|
||||
if (Arguments != NULL)
|
||||
{
|
||||
Ptr = Arguments;
|
||||
while (*Ptr)
|
||||
{
|
||||
Length = wcslen(Ptr) + 1;
|
||||
TotalLength += Length;
|
||||
Ptr += Length;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
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;
|
||||
|
||||
StartPacket->Command = SCM_START_COMMAND;
|
||||
StartPacket->Size = TotalLength;
|
||||
Ptr = &StartPacket->Arguments[0];
|
||||
wcscpy(Ptr, Service->ServiceName.Buffer);
|
||||
Ptr += (wcslen(Service->ServiceName.Buffer) + 1);
|
||||
|
||||
/* FIXME: Copy argument list */
|
||||
|
||||
*Ptr = 0;
|
||||
|
||||
/* Send the start command */
|
||||
WriteFile(Service->ControlPipeHandle,
|
||||
StartPacket,
|
||||
sizeof(SCM_START_PACKET) + (TotalLength - 1) * sizeof(WCHAR),
|
||||
&Count,
|
||||
NULL);
|
||||
|
||||
/* FIXME: Read the reply */
|
||||
|
||||
HeapFree(GetProcessHeap(),
|
||||
0,
|
||||
StartPacket);
|
||||
|
||||
DPRINT("ScmSendStartCommand() done\n");
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static NTSTATUS
|
||||
ScmStartUserModeService(PSERVICE Service)
|
||||
{
|
||||
RTL_QUERY_REGISTRY_TABLE QueryTable[3];
|
||||
PROCESS_INFORMATION ProcessInformation;
|
||||
|
@ -532,6 +597,149 @@ ScmStartService(PSERVICE Service,
|
|||
BOOL Result;
|
||||
NTSTATUS Status;
|
||||
|
||||
RtlInitUnicodeString(&ImagePath, NULL);
|
||||
|
||||
/* Get service data */
|
||||
RtlZeroMemory(&QueryTable,
|
||||
sizeof(QueryTable));
|
||||
|
||||
QueryTable[0].Name = L"Type";
|
||||
QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
|
||||
QueryTable[0].EntryContext = &Type;
|
||||
|
||||
QueryTable[1].Name = L"ImagePath";
|
||||
QueryTable[1].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
|
||||
QueryTable[1].EntryContext = &ImagePath;
|
||||
|
||||
Status = RtlQueryRegistryValues(RTL_REGISTRY_SERVICES,
|
||||
Service->ServiceName.Buffer,
|
||||
QueryTable,
|
||||
NULL,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("RtlQueryRegistryValues() failed (Status %lx)\n", Status);
|
||||
return Status;
|
||||
}
|
||||
DPRINT("ImagePath: '%S'\n", ImagePath.Buffer);
|
||||
DPRINT("Type: %lx\n", Type);
|
||||
|
||||
/* Create '\\.\pipe\net\NtControlPipe' instance */
|
||||
Service->ControlPipeHandle = CreateNamedPipeW(L"\\\\.\\pipe\\net\\NtControlPipe",
|
||||
PIPE_ACCESS_DUPLEX,
|
||||
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
|
||||
100,
|
||||
8000,
|
||||
4,
|
||||
30000,
|
||||
NULL);
|
||||
DPRINT("CreateNamedPipeW() done\n");
|
||||
if (Service->ControlPipeHandle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
DPRINT1("Failed to create control pipe!\n");
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
StartupInfo.cb = sizeof(StartupInfo);
|
||||
StartupInfo.lpReserved = NULL;
|
||||
StartupInfo.lpDesktop = NULL;
|
||||
StartupInfo.lpTitle = NULL;
|
||||
StartupInfo.dwFlags = 0;
|
||||
StartupInfo.cbReserved2 = 0;
|
||||
StartupInfo.lpReserved2 = 0;
|
||||
|
||||
Result = CreateProcessW(ImagePath.Buffer,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
FALSE,
|
||||
DETACHED_PROCESS | CREATE_SUSPENDED,
|
||||
NULL,
|
||||
NULL,
|
||||
&StartupInfo,
|
||||
&ProcessInformation);
|
||||
RtlFreeUnicodeString(&ImagePath);
|
||||
|
||||
if (!Result)
|
||||
{
|
||||
/* Close control pipe */
|
||||
CloseHandle(Service->ControlPipeHandle);
|
||||
Service->ControlPipeHandle = INVALID_HANDLE_VALUE;
|
||||
|
||||
DPRINT1("Starting '%S' failed!\n", Service->ServiceName.Buffer);
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
DPRINT("Process Id: %lu Handle %lx\n",
|
||||
ProcessInformation.dwProcessId,
|
||||
ProcessInformation.hProcess);
|
||||
DPRINT("Thread Id: %lu Handle %lx\n",
|
||||
ProcessInformation.dwThreadId,
|
||||
ProcessInformation.hThread);
|
||||
|
||||
/* Get process and thread ids */
|
||||
Service->ProcessId = ProcessInformation.dwProcessId;
|
||||
Service->ThreadId = ProcessInformation.dwThreadId;
|
||||
|
||||
/* Resume Thread */
|
||||
ResumeThread(ProcessInformation.hThread);
|
||||
|
||||
/* Connect control pipe */
|
||||
if (ConnectNamedPipe(Service->ControlPipeHandle, NULL))
|
||||
{
|
||||
DWORD dwProcessId = 0;
|
||||
DWORD dwRead = 0;
|
||||
|
||||
DPRINT("Control pipe connected!\n");
|
||||
|
||||
/* Read thread id from pipe */
|
||||
if (!ReadFile(Service->ControlPipeHandle,
|
||||
(LPVOID)&dwProcessId,
|
||||
sizeof(DWORD),
|
||||
&dwRead,
|
||||
NULL))
|
||||
{
|
||||
DPRINT1("Reading the service control pipe failed (Error %lu)\n",
|
||||
GetLastError());
|
||||
Status = STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT("Received process id %lu\n", dwProcessId);
|
||||
|
||||
/* FIXME: Send start command */
|
||||
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT("Connecting control pipe failed!\n");
|
||||
|
||||
/* Close control pipe */
|
||||
CloseHandle(Service->ControlPipeHandle);
|
||||
Service->ControlPipeHandle = INVALID_HANDLE_VALUE;
|
||||
Service->ProcessId = 0;
|
||||
Service->ThreadId = 0;
|
||||
Status = STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
ScmSendStartCommand(Service, NULL);
|
||||
|
||||
/* Close process and thread handle */
|
||||
CloseHandle(ProcessInformation.hThread);
|
||||
CloseHandle(ProcessInformation.hProcess);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
static NTSTATUS
|
||||
ScmStartService(PSERVICE Service,
|
||||
PSERVICE_GROUP Group)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("ScmStartService() called\n");
|
||||
|
||||
Service->ControlPipeHandle = INVALID_HANDLE_VALUE;
|
||||
|
@ -547,138 +755,10 @@ ScmStartService(PSERVICE Service,
|
|||
}
|
||||
else
|
||||
{
|
||||
RtlInitUnicodeString(&ImagePath, NULL);
|
||||
|
||||
/* Get service data */
|
||||
RtlZeroMemory(&QueryTable,
|
||||
sizeof(QueryTable));
|
||||
|
||||
QueryTable[0].Name = L"Type";
|
||||
QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
|
||||
QueryTable[0].EntryContext = &Type;
|
||||
|
||||
QueryTable[1].Name = L"ImagePath";
|
||||
QueryTable[1].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
|
||||
QueryTable[1].EntryContext = &ImagePath;
|
||||
|
||||
Status = RtlQueryRegistryValues(RTL_REGISTRY_SERVICES,
|
||||
Service->ServiceName.Buffer,
|
||||
QueryTable,
|
||||
NULL,
|
||||
NULL);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("ImagePath: '%S'\n", ImagePath.Buffer);
|
||||
DPRINT("Type: %lx\n", Type);
|
||||
|
||||
/* FIXME: create '\\.\pipe\net\NtControlPipe' instance */
|
||||
Service->ControlPipeHandle = CreateNamedPipeW(L"\\\\.\\pipe\\net\\NtControlPipe",
|
||||
PIPE_ACCESS_DUPLEX,
|
||||
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
|
||||
100,
|
||||
8000,
|
||||
4,
|
||||
30000,
|
||||
NULL);
|
||||
DPRINT("CreateNamedPipeW() done\n");
|
||||
if (Service->ControlPipeHandle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
DPRINT1("Failed to create control pipe!\n");
|
||||
Status = STATUS_UNSUCCESSFUL;
|
||||
goto Done;
|
||||
}
|
||||
|
||||
StartupInfo.cb = sizeof(StartupInfo);
|
||||
StartupInfo.lpReserved = NULL;
|
||||
StartupInfo.lpDesktop = NULL;
|
||||
StartupInfo.lpTitle = NULL;
|
||||
StartupInfo.dwFlags = 0;
|
||||
StartupInfo.cbReserved2 = 0;
|
||||
StartupInfo.lpReserved2 = 0;
|
||||
|
||||
Result = CreateProcessW(ImagePath.Buffer,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
FALSE,
|
||||
DETACHED_PROCESS | CREATE_SUSPENDED,
|
||||
NULL,
|
||||
NULL,
|
||||
&StartupInfo,
|
||||
&ProcessInformation);
|
||||
RtlFreeUnicodeString(&ImagePath);
|
||||
|
||||
if (!Result)
|
||||
{
|
||||
/* Close control pipe */
|
||||
CloseHandle(Service->ControlPipeHandle);
|
||||
Service->ControlPipeHandle = INVALID_HANDLE_VALUE;
|
||||
|
||||
DPRINT1("Starting '%S' failed!\n", Service->ServiceName.Buffer);
|
||||
Status = STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT("Process Id: %lu Handle %lx\n",
|
||||
ProcessInformation.dwProcessId,
|
||||
ProcessInformation.hProcess);
|
||||
DPRINT("Thread Id: %lu Handle %lx\n",
|
||||
ProcessInformation.dwThreadId,
|
||||
ProcessInformation.hThread);
|
||||
|
||||
/* Get process and thread ids */
|
||||
Service->ProcessId = ProcessInformation.dwProcessId;
|
||||
Service->ThreadId = ProcessInformation.dwThreadId;
|
||||
|
||||
/* Resume Thread */
|
||||
ResumeThread(ProcessInformation.hThread);
|
||||
|
||||
/* Connect control pipe */
|
||||
if (ConnectNamedPipe(Service->ControlPipeHandle, NULL))
|
||||
{
|
||||
DWORD dwProcessId = 0;
|
||||
DWORD dwRead = 0;
|
||||
|
||||
DPRINT("Control pipe connected!\n");
|
||||
|
||||
/* FIXME: Read thread id from pipe */
|
||||
if (!ReadFile(Service->ControlPipeHandle,
|
||||
(LPVOID)&dwProcessId,
|
||||
sizeof(DWORD),
|
||||
&dwRead,
|
||||
NULL))
|
||||
{
|
||||
DPRINT1("Reading the service control pipe failed (Error %lu)\n", GetLastError());
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT("Received process id %lu\n", dwProcessId);
|
||||
|
||||
/* FIXME: Send start command */
|
||||
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT("Connecting control pipe failed!\n");
|
||||
|
||||
/* Close control pipe */
|
||||
CloseHandle(Service->ControlPipeHandle);
|
||||
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);
|
||||
}
|
||||
}
|
||||
/* Start user-mode service */
|
||||
Status = ScmStartUserModeService(Service);
|
||||
}
|
||||
|
||||
Done:
|
||||
DPRINT("ScmStartService() done (Status %lx)\n", Status);
|
||||
|
||||
if (NT_SUCCESS(Status))
|
||||
|
|
Loading…
Reference in a new issue