[SERVICES]

- Use one instead of two critical sections to synchronize service start and control actions.
- Fail, if an already running service is started again.

svn path=/trunk/; revision=50977
This commit is contained in:
Eric Kohl 2011-03-05 18:37:39 +00:00
parent d529634650
commit 7b3c204407

View file

@ -30,8 +30,7 @@ LIST_ENTRY ServiceListHead;
static RTL_RESOURCE DatabaseLock;
static DWORD dwResumeCount = 1;
static CRITICAL_SECTION NamedPipeCriticalSection;
static CRITICAL_SECTION StartServiceCriticalSection;
static CRITICAL_SECTION ControlServiceCriticalSection;
/* FUNCTIONS *****************************************************************/
@ -693,6 +692,8 @@ ScmControlService(PSERVICE Service,
DPRINT("ScmControlService() called\n");
EnterCriticalSection(&ControlServiceCriticalSection);
TotalLength = wcslen(Service->lpServiceName) + 1;
ControlPacket = (SCM_CONTROL_PACKET*)HeapAlloc(GetProcessHeap(),
@ -706,8 +707,6 @@ 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,
@ -722,8 +721,6 @@ ScmControlService(PSERVICE Service,
&dwReadCount,
NULL);
LeaveCriticalSection(&NamedPipeCriticalSection);
/* Release the contol packet */
HeapFree(GetProcessHeap(),
0,
@ -734,6 +731,8 @@ ScmControlService(PSERVICE Service,
dwError = ReplyPacket.dwError;
}
LeaveCriticalSection(&ControlServiceCriticalSection);
DPRINT("ScmControlService() done\n");
return dwError;
@ -801,8 +800,6 @@ ScmSendStartCommand(PSERVICE Service,
/* Terminate the argument list */
*Ptr = 0;
EnterCriticalSection(&NamedPipeCriticalSection);
/* Send the start command */
WriteFile(Service->ControlPipeHandle,
ControlPacket,
@ -817,8 +814,6 @@ ScmSendStartCommand(PSERVICE Service,
&dwReadCount,
NULL);
LeaveCriticalSection(&NamedPipeCriticalSection);
/* Release the contol packet */
HeapFree(GetProcessHeap(),
0,
@ -924,6 +919,9 @@ ScmStartUserModeService(PSERVICE Service,
/* Create '\\.\pipe\net\NtControlPipeXXX' instance */
swprintf(NtControlPipeName, L"\\\\.\\pipe\\net\\NtControlPipe%u", ServiceCurrent);
DPRINT1("Service: %p ImagePath: %wZ PipeName: %S\n", Service, &ImagePath, NtControlPipeName);
Service->ControlPipeHandle = CreateNamedPipeW(NtControlPipeName,
PIPE_ACCESS_DUPLEX,
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
@ -1036,10 +1034,19 @@ ScmStartService(PSERVICE Service, DWORD argc, LPWSTR *argv)
PSERVICE_GROUP Group = Service->lpGroup;
DWORD dwError = ERROR_SUCCESS;
EnterCriticalSection(&StartServiceCriticalSection);
DPRINT("ScmStartService() called\n");
DPRINT1("Start Service %p (%S)\n", Service, Service->lpServiceName);
EnterCriticalSection(&ControlServiceCriticalSection);
if (Service->Status.dwCurrentState != SERVICE_STOPPED)
{
DPRINT1("Service %S is already running!\n", Service->lpServiceName);
LeaveCriticalSection(&ControlServiceCriticalSection);
return ERROR_SERVICE_ALREADY_RUNNING;
}
Service->ControlPipeHandle = INVALID_HANDLE_VALUE;
DPRINT("Service->Type: %lu\n", Service->Status.dwServiceType);
@ -1067,8 +1074,9 @@ ScmStartService(PSERVICE Service, DWORD argc, LPWSTR *argv)
}
}
LeaveCriticalSection(&ControlServiceCriticalSection);
DPRINT("ScmStartService() done (Error %lu)\n", dwError);
LeaveCriticalSection(&StartServiceCriticalSection);
if (dwError == ERROR_SUCCESS)
{
@ -1274,16 +1282,14 @@ ScmUnlockDatabase(VOID)
VOID
ScmInitNamedPipeCriticalSection(VOID)
{
InitializeCriticalSection(&NamedPipeCriticalSection);
InitializeCriticalSection(&StartServiceCriticalSection);
InitializeCriticalSection(&ControlServiceCriticalSection);
}
VOID
ScmDeleteNamedPipeCriticalSection(VOID)
{
DeleteCriticalSection(&StartServiceCriticalSection);
DeleteCriticalSection(&NamedPipeCriticalSection);
DeleteCriticalSection(&ControlServiceCriticalSection);
}
/* EOF */