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
static RTL_RESOURCE DatabaseLock;
static DWORD dwResumeCount = 1;
static RTL_RESOURCE DatabaseLock;
static DWORD dwResumeCount = 1;
+static CRITICAL_SECTION NamedPipeCriticalSection;
+static CRITICAL_SECTION StartServiceCriticalSection;
/* FUNCTIONS *****************************************************************/
/* FUNCTIONS *****************************************************************/
ControlPacket->hServiceStatus = (SERVICE_STATUS_HANDLE)Service;
wcscpy(&ControlPacket->szArguments[0], Service->lpServiceName);
ControlPacket->hServiceStatus = (SERVICE_STATUS_HANDLE)Service;
wcscpy(&ControlPacket->szArguments[0], Service->lpServiceName);
+ EnterCriticalSection(&NamedPipeCriticalSection);
+
/* Send the control packet */
WriteFile(Service->ControlPipeHandle,
ControlPacket,
/* Send the control packet */
WriteFile(Service->ControlPipeHandle,
ControlPacket,
+ LeaveCriticalSection(&NamedPipeCriticalSection);
+
/* Release the contol packet */
HeapFree(GetProcessHeap(),
0,
/* Release the contol packet */
HeapFree(GetProcessHeap(),
0,
/* Terminate the argument list */
*Ptr = 0;
/* Terminate the argument list */
*Ptr = 0;
+ EnterCriticalSection(&NamedPipeCriticalSection);
+
/* Send the start command */
WriteFile(Service->ControlPipeHandle,
ControlPacket,
/* Send the start command */
WriteFile(Service->ControlPipeHandle,
ControlPacket,
+ LeaveCriticalSection(&NamedPipeCriticalSection);
+
/* Release the contol packet */
HeapFree(GetProcessHeap(),
0,
/* Release the contol packet */
HeapFree(GetProcessHeap(),
0,
+ EnterCriticalSection(&StartServiceCriticalSection);
+
/* Create '\\.\pipe\net\NtControlPipeXXX' instance */
swprintf(NtControlPipeName, L"\\\\.\\pipe\\net\\NtControlPipe%u", ServiceCurrent);
Service->ControlPipeHandle = CreateNamedPipeW(NtControlPipeName,
/* Create '\\.\pipe\net\NtControlPipeXXX' instance */
swprintf(NtControlPipeName, L"\\\\.\\pipe\\net\\NtControlPipe%u", ServiceCurrent);
Service->ControlPipeHandle = CreateNamedPipeW(NtControlPipeName,
if (Service->ControlPipeHandle == INVALID_HANDLE_VALUE)
{
DPRINT1("Failed to create control pipe!\n");
if (Service->ControlPipeHandle == INVALID_HANDLE_VALUE)
{
DPRINT1("Failed to create control pipe!\n");
+ LeaveCriticalSection(&StartServiceCriticalSection);
Service->ControlPipeHandle = INVALID_HANDLE_VALUE;
DPRINT1("Starting '%S' failed!\n", Service->lpServiceName);
Service->ControlPipeHandle = INVALID_HANDLE_VALUE;
DPRINT1("Starting '%S' failed!\n", Service->lpServiceName);
+ LeaveCriticalSection(&StartServiceCriticalSection);
CloseHandle(ProcessInformation.hThread);
CloseHandle(ProcessInformation.hProcess);
CloseHandle(ProcessInformation.hThread);
CloseHandle(ProcessInformation.hProcess);
+ LeaveCriticalSection(&StartServiceCriticalSection);
+
RtlReleaseResource(&DatabaseLock);
}
RtlReleaseResource(&DatabaseLock);
}
+
+VOID
+ScmInitNamedPipeCriticalSection(VOID)
+{
+ InitializeCriticalSection(&NamedPipeCriticalSection);
+ InitializeCriticalSection(&StartServiceCriticalSection);
+}
+
+
+VOID
+ScmDeleteNamedPipeCriticalSection(VOID)
+{
+ DeleteCriticalSection(&StartServiceCriticalSection);
+ DeleteCriticalSection(&NamedPipeCriticalSection);
+}
+
/* Acquire privileges to load drivers */
AcquireLoadDriverPrivilege();
/* Acquire privileges to load drivers */
AcquireLoadDriverPrivilege();
+ ScmInitNamedPipeCriticalSection();
+
/* Start auto-start services */
ScmAutoStartServices();
/* Start auto-start services */
ScmAutoStartServices();
+ ScmDeleteNamedPipeCriticalSection();
+
CloseHandle(hScmStartEvent);
DPRINT("SERVICES: Finished.\n");
CloseHandle(hScmStartEvent);
DPRINT("SERVICES: Finished.\n");
BOOL ScmLockDatabaseShared(VOID);
VOID ScmUnlockDatabase(VOID);
BOOL ScmLockDatabaseShared(VOID);
VOID ScmUnlockDatabase(VOID);
+VOID ScmInitNamedPipeCriticalSection(VOID);
+VOID ScmDeleteNamedPipeCriticalSection(VOID);
+