static RTL_RESOURCE DatabaseLock;
static DWORD dwResumeCount = 1;
+static CRITICAL_SECTION NamedPipeCriticalSection;
+static CRITICAL_SECTION StartServiceCriticalSection;
/* FUNCTIONS *****************************************************************/
DWORD
-ScmSendServiceCommand(PSERVICE Service,
- DWORD dwControl,
- DWORD argc,
- LPWSTR *argv)
+ScmControlService(PSERVICE Service,
+ DWORD dwControl)
+{
+ PSCM_CONTROL_PACKET ControlPacket;
+ SCM_REPLY_PACKET ReplyPacket;
+
+ DWORD dwWriteCount = 0;
+ DWORD dwReadCount = 0;
+ DWORD TotalLength;
+ DWORD dwError = ERROR_SUCCESS;
+
+ DPRINT("ScmControlService() called\n");
+
+ TotalLength = wcslen(Service->lpServiceName) + 1;
+
+ ControlPacket = (SCM_CONTROL_PACKET*)HeapAlloc(GetProcessHeap(),
+ HEAP_ZERO_MEMORY,
+ sizeof(SCM_CONTROL_PACKET) + (TotalLength * sizeof(WCHAR)));
+ if (ControlPacket == NULL)
+ return ERROR_NOT_ENOUGH_MEMORY;
+
+ ControlPacket->dwControl = dwControl;
+ ControlPacket->dwSize = TotalLength;
+ ControlPacket->hServiceStatus = (SERVICE_STATUS_HANDLE)Service;
+ wcscpy(&ControlPacket->szArguments[0], Service->lpServiceName);
+
+ EnterCriticalSection(&NamedPipeCriticalSection);
+
+ /* Send the control packet */
+ WriteFile(Service->ControlPipeHandle,
+ ControlPacket,
+ sizeof(SCM_CONTROL_PACKET) + (TotalLength * sizeof(WCHAR)),
+ &dwWriteCount,
+ NULL);
+
+ /* Read the reply */
+ ReadFile(Service->ControlPipeHandle,
+ &ReplyPacket,
+ sizeof(SCM_REPLY_PACKET),
+ &dwReadCount,
+ NULL);
+
+ LeaveCriticalSection(&NamedPipeCriticalSection);
+
+ /* Release the contol packet */
+ HeapFree(GetProcessHeap(),
+ 0,
+ ControlPacket);
+
+ if (dwReadCount == sizeof(SCM_REPLY_PACKET))
+ {
+ dwError = ReplyPacket.dwError;
+ }
+
+ DPRINT("ScmControlService() done\n");
+
+ return dwError;
+}
+
+
+static DWORD
+ScmSendStartCommand(PSERVICE Service,
+ DWORD argc,
+ LPWSTR *argv)
{
PSCM_CONTROL_PACKET ControlPacket;
SCM_REPLY_PACKET ReplyPacket;
DWORD dwError = ERROR_SUCCESS;
DWORD i;
- DPRINT("ScmSendServiceCommand() called\n");
+ DPRINT("ScmSendStartCommand() called\n");
/* Calculate the total length of the start command line */
TotalLength = wcslen(Service->lpServiceName) + 1;
if (ControlPacket == NULL)
return ERROR_NOT_ENOUGH_MEMORY;
- ControlPacket->dwControl = dwControl;
+ ControlPacket->dwControl = SERVICE_CONTROL_START;
ControlPacket->hServiceStatus = (SERVICE_STATUS_HANDLE)Service;
ControlPacket->dwSize = TotalLength;
Ptr = &ControlPacket->szArguments[0];
/* Terminate the argument list */
*Ptr = 0;
+ EnterCriticalSection(&NamedPipeCriticalSection);
+
/* Send the start command */
WriteFile(Service->ControlPipeHandle,
ControlPacket,
&dwReadCount,
NULL);
+ LeaveCriticalSection(&NamedPipeCriticalSection);
+
/* Release the contol packet */
HeapFree(GetProcessHeap(),
0,
dwError = ReplyPacket.dwError;
}
- DPRINT("ScmSendServiceCommand() done\n");
+ DPRINT("ScmSendStartCommand() done\n");
return dwError;
}
return Status;
}
+ EnterCriticalSection(&StartServiceCriticalSection);
+
/* 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");
+ LeaveCriticalSection(&StartServiceCriticalSection);
return GetLastError();
}
Service->ControlPipeHandle = INVALID_HANDLE_VALUE;
DPRINT1("Starting '%S' failed!\n", Service->lpServiceName);
+ LeaveCriticalSection(&StartServiceCriticalSection);
return dwError;
}
DPRINT("Received service process ID %lu\n", dwProcessId);
/* Send start command */
- dwError = ScmSendServiceCommand(Service,
- SERVICE_CONTROL_START,
- argc,
- argv);
+ dwError = ScmSendStartCommand(Service, argc, argv);
}
}
else
CloseHandle(ProcessInformation.hThread);
CloseHandle(ProcessInformation.hProcess);
+ LeaveCriticalSection(&StartServiceCriticalSection);
+
return dwError;
}
CurrentService->Status.dwCurrentState == SERVICE_START_PENDING)
{
/* shutdown service */
- ScmSendServiceCommand(CurrentService,
- SERVICE_CONTROL_STOP,
- 0,
- NULL);
+ ScmControlService(CurrentService, SERVICE_CONTROL_STOP);
}
ServiceEntry = ServiceEntry->Flink;
RtlReleaseResource(&DatabaseLock);
}
+
+VOID
+ScmInitNamedPipeCriticalSection(VOID)
+{
+ InitializeCriticalSection(&NamedPipeCriticalSection);
+ InitializeCriticalSection(&StartServiceCriticalSection);
+}
+
+
+VOID
+ScmDeleteNamedPipeCriticalSection(VOID)
+{
+ DeleteCriticalSection(&StartServiceCriticalSection);
+ DeleteCriticalSection(&NamedPipeCriticalSection);
+}
+
/* EOF */