From 59aa297b53fcb9b214f5cec0b9f598e7033a27aa Mon Sep 17 00:00:00 2001 From: Gregor Brunmar Date: Sun, 28 Oct 2007 14:13:03 +0000 Subject: [PATCH] Made each service have its own pipe name as done in Windows svn path=/trunk/; revision=29929 --- reactos/base/system/services/database.c | 46 ++++++++++++++++++++-- reactos/dll/win32/advapi32/service/sctrl.c | 33 ++++++++++++++-- 2 files changed, 73 insertions(+), 6 deletions(-) diff --git a/reactos/base/system/services/database.c b/reactos/base/system/services/database.c index 9192f3c611d..3a6f005200c 100644 --- a/reactos/base/system/services/database.c +++ b/reactos/base/system/services/database.c @@ -6,6 +6,7 @@ * COPYRIGHT: Copyright 2002-2006 Eric Kohl * Copyright 2006 Hervé Poussineau * Copyright 2007 Ged Murphy + * Gregor Brunmar * */ @@ -692,9 +693,11 @@ ScmStartUserModeService(PSERVICE Service, STARTUPINFOW StartupInfo; UNICODE_STRING ImagePath; ULONG Type; + DWORD ServiceCurrent = 0; BOOL Result; NTSTATUS Status; DWORD dwError = ERROR_SUCCESS; + WCHAR NtControlPipeName[MAX_PATH + 1]; RtlInitUnicodeString(&ImagePath, NULL); @@ -723,8 +726,45 @@ ScmStartUserModeService(PSERVICE Service, DPRINT("ImagePath: '%S'\n", ImagePath.Buffer); DPRINT("Type: %lx\n", Type); - /* Create '\\.\pipe\net\NtControlPipe' instance */ - Service->ControlPipeHandle = CreateNamedPipeW(L"\\\\.\\pipe\\net\\NtControlPipe", + /* Get the service number */ + RtlZeroMemory(&QueryTable, + sizeof(QueryTable)); + + QueryTable[0].Name = L""; + QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED; + QueryTable[0].EntryContext = &ServiceCurrent; + + Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL, + L"ServiceCurrent", + QueryTable, + NULL, + NULL); + + if (Status == STATUS_OBJECT_NAME_NOT_FOUND) + { + /* TODO: Create registry entry with correct write access */ + } + else if (!NT_SUCCESS(Status)) + { + DPRINT1("RtlQueryRegistryValues() failed (Status %lx)\n", Status); + return RtlNtStatusToDosError(Status); + } + else + { + ServiceCurrent++; + } + + Status = RtlWriteRegistryValue(RTL_REGISTRY_CONTROL, L"ServiceCurrent", L"", REG_DWORD, &ServiceCurrent, sizeof(ServiceCurrent)); + + if (!NT_SUCCESS(Status)) + { + DPRINT1("RtlWriteRegistryValue() failed (Status %lx)\n", Status); + return RtlNtStatusToDosError(Status); + } + + /* Create '\\.\pipe\net\NtControlPipeXXX' instance */ + swprintf(NtControlPipeName, L"\\\\.\\pipe\\net\\NtControlPipe%u", ServiceCurrent); + Service->ControlPipeHandle = CreateNamedPipeW(NtControlPipeName, PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, 100, @@ -732,7 +772,7 @@ ScmStartUserModeService(PSERVICE Service, 4, 30000, NULL); - DPRINT("CreateNamedPipeW() done\n"); + DPRINT1("CreateNamedPipeW(%S) done\n", NtControlPipeName); if (Service->ControlPipeHandle == INVALID_HANDLE_VALUE) { DPRINT1("Failed to create control pipe!\n"); diff --git a/reactos/dll/win32/advapi32/service/sctrl.c b/reactos/dll/win32/advapi32/service/sctrl.c index 472f6a3de00..9511d6c687f 100644 --- a/reactos/dll/win32/advapi32/service/sctrl.c +++ b/reactos/dll/win32/advapi32/service/sctrl.c @@ -5,6 +5,7 @@ * PURPOSE: Service control manager functions * COPYRIGHT: Copyright 1999 Emanuele Aliberti * Copyright 2007 Ged Murphy + * Gregor Brunmar * */ @@ -197,14 +198,40 @@ ScConnectControlPipe(HANDLE *hPipe) { DWORD dwBytesWritten; DWORD dwState; + DWORD dwServiceCurrent = 0; + NTSTATUS Status; + WCHAR NtControlPipeName[MAX_PATH + 1]; + RTL_QUERY_REGISTRY_TABLE QueryTable[2]; - if (!WaitNamedPipeW(L"\\\\.\\pipe\\net\\NtControlPipe", 15000)) + /* Get the service number and create the named pipe */ + RtlZeroMemory(&QueryTable, + sizeof(QueryTable)); + + QueryTable[0].Name = L""; + QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED; + QueryTable[0].EntryContext = &dwServiceCurrent; + + Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL, + L"ServiceCurrent", + QueryTable, + NULL, + NULL); + + if (!NT_SUCCESS(Status)) { - DPRINT1("WaitNamedPipe() failed (Error %lu)\n", GetLastError()); + DPRINT1("RtlQueryRegistryValues() failed (Status %lx)\n", Status); + return RtlNtStatusToDosError(Status); + } + + swprintf(NtControlPipeName, L"\\\\.\\pipe\\net\\NtControlPipe%u", dwServiceCurrent); + + if (!WaitNamedPipeW(NtControlPipeName, 15000)) + { + DPRINT1("WaitNamedPipe(%S) failed (Error %lu)\n", NtControlPipeName, GetLastError()); return ERROR_FAILED_SERVICE_CONTROLLER_CONNECT; } - *hPipe = CreateFileW(L"\\\\.\\pipe\\net\\NtControlPipe", + *hPipe = CreateFileW(NtControlPipeName, GENERIC_READ | GENERIC_WRITE, 0, NULL,