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