From a328e318a1c0f3a84c8c2eb008e4fe01ca631f1b Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Sun, 27 Feb 2011 19:25:14 +0000 Subject: [PATCH] [SERVICES] Protect the service start and sending of control packages by critical sections. This way, services will be started one by one and control packages will also be sent one by one. Please test if this fixes bug #5924. svn path=/trunk/; revision=50926 --- reactos/base/system/services/database.c | 32 +++++++++++++++++++++++++ reactos/base/system/services/services.c | 4 ++++ reactos/base/system/services/services.h | 3 +++ 3 files changed, 39 insertions(+) diff --git a/reactos/base/system/services/database.c b/reactos/base/system/services/database.c index 7a9819e4c8b..ed0bdcb61d6 100644 --- a/reactos/base/system/services/database.c +++ b/reactos/base/system/services/database.c @@ -30,6 +30,8 @@ LIST_ENTRY ServiceListHead; static RTL_RESOURCE DatabaseLock; static DWORD dwResumeCount = 1; +static CRITICAL_SECTION NamedPipeCriticalSection; +static CRITICAL_SECTION StartServiceCriticalSection; /* FUNCTIONS *****************************************************************/ @@ -704,6 +706,8 @@ ScmControlService(PSERVICE Service, ControlPacket->hServiceStatus = (SERVICE_STATUS_HANDLE)Service; wcscpy(&ControlPacket->szArguments[0], Service->lpServiceName); + EnterCriticalSection(&NamedPipeCriticalSection); + /* Send the control packet */ WriteFile(Service->ControlPipeHandle, ControlPacket, @@ -718,6 +722,8 @@ ScmControlService(PSERVICE Service, &dwReadCount, NULL); + LeaveCriticalSection(&NamedPipeCriticalSection); + /* Release the contol packet */ HeapFree(GetProcessHeap(), 0, @@ -795,6 +801,8 @@ ScmSendStartCommand(PSERVICE Service, /* Terminate the argument list */ *Ptr = 0; + EnterCriticalSection(&NamedPipeCriticalSection); + /* Send the start command */ WriteFile(Service->ControlPipeHandle, ControlPacket, @@ -809,6 +817,8 @@ ScmSendStartCommand(PSERVICE Service, &dwReadCount, NULL); + LeaveCriticalSection(&NamedPipeCriticalSection); + /* Release the contol packet */ HeapFree(GetProcessHeap(), 0, @@ -912,6 +922,8 @@ ScmStartUserModeService(PSERVICE Service, return Status; } + EnterCriticalSection(&StartServiceCriticalSection); + /* Create '\\.\pipe\net\NtControlPipeXXX' instance */ swprintf(NtControlPipeName, L"\\\\.\\pipe\\net\\NtControlPipe%u", ServiceCurrent); Service->ControlPipeHandle = CreateNamedPipeW(NtControlPipeName, @@ -926,6 +938,7 @@ ScmStartUserModeService(PSERVICE Service, if (Service->ControlPipeHandle == INVALID_HANDLE_VALUE) { DPRINT1("Failed to create control pipe!\n"); + LeaveCriticalSection(&StartServiceCriticalSection); return GetLastError(); } @@ -957,6 +970,7 @@ ScmStartUserModeService(PSERVICE Service, Service->ControlPipeHandle = INVALID_HANDLE_VALUE; DPRINT1("Starting '%S' failed!\n", Service->lpServiceName); + LeaveCriticalSection(&StartServiceCriticalSection); return dwError; } @@ -1016,6 +1030,8 @@ ScmStartUserModeService(PSERVICE Service, CloseHandle(ProcessInformation.hThread); CloseHandle(ProcessInformation.hProcess); + LeaveCriticalSection(&StartServiceCriticalSection); + return dwError; } @@ -1257,4 +1273,20 @@ ScmUnlockDatabase(VOID) RtlReleaseResource(&DatabaseLock); } + +VOID +ScmInitNamedPipeCriticalSection(VOID) +{ + InitializeCriticalSection(&NamedPipeCriticalSection); + InitializeCriticalSection(&StartServiceCriticalSection); +} + + +VOID +ScmDeleteNamedPipeCriticalSection(VOID) +{ + DeleteCriticalSection(&StartServiceCriticalSection); + DeleteCriticalSection(&NamedPipeCriticalSection); +} + /* EOF */ diff --git a/reactos/base/system/services/services.c b/reactos/base/system/services/services.c index 96aecd2a77b..e5a00411259 100644 --- a/reactos/base/system/services/services.c +++ b/reactos/base/system/services/services.c @@ -385,6 +385,8 @@ wWinMain(HINSTANCE hInstance, /* Acquire privileges to load drivers */ AcquireLoadDriverPrivilege(); + ScmInitNamedPipeCriticalSection(); + /* Start auto-start services */ ScmAutoStartServices(); @@ -404,6 +406,8 @@ wWinMain(HINSTANCE hInstance, } #endif + ScmDeleteNamedPipeCriticalSection(); + CloseHandle(hScmStartEvent); DPRINT("SERVICES: Finished.\n"); diff --git a/reactos/base/system/services/services.h b/reactos/base/system/services/services.h index 8371ad18b71..673edbf115d 100644 --- a/reactos/base/system/services/services.h +++ b/reactos/base/system/services/services.h @@ -123,6 +123,9 @@ BOOL ScmLockDatabaseExclusive(VOID); BOOL ScmLockDatabaseShared(VOID); VOID ScmUnlockDatabase(VOID); +VOID ScmInitNamedPipeCriticalSection(VOID); +VOID ScmDeleteNamedPipeCriticalSection(VOID); + /* driver.c */