mirror of
https://github.com/reactos/reactos.git
synced 2024-10-02 23:46:50 +00:00
[SERVICES]
- Add optional asynchronous io code for service control pipes. This is disabled by default due to bugs in NPFS. - Read service pipe timeout value from the registry. svn path=/trunk/; revision=53686
This commit is contained in:
parent
1b9f1974ad
commit
0d4f432270
|
@ -23,6 +23,13 @@
|
||||||
*/
|
*/
|
||||||
// #define USE_SERVICE_START_PENDING
|
// #define USE_SERVICE_START_PENDING
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Uncomment the line below to use asynchronous IO operations
|
||||||
|
* on the service control pipes.
|
||||||
|
*/
|
||||||
|
// #define USE_ASYNCHRONOUS_IO
|
||||||
|
|
||||||
|
|
||||||
/* GLOBALS *******************************************************************/
|
/* GLOBALS *******************************************************************/
|
||||||
|
|
||||||
LIST_ENTRY ImageListHead;
|
LIST_ENTRY ImageListHead;
|
||||||
|
@ -32,6 +39,8 @@ static RTL_RESOURCE DatabaseLock;
|
||||||
static DWORD dwResumeCount = 1;
|
static DWORD dwResumeCount = 1;
|
||||||
|
|
||||||
static CRITICAL_SECTION ControlServiceCriticalSection;
|
static CRITICAL_SECTION ControlServiceCriticalSection;
|
||||||
|
static DWORD dwPipeTimeout = 30000; /* 30 Seconds */
|
||||||
|
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
|
@ -92,12 +101,16 @@ ScmCreateNewControlPipe(PSERVICE_IMAGE pServiceImage)
|
||||||
DPRINT("PipeName: %S\n", szControlPipeName);
|
DPRINT("PipeName: %S\n", szControlPipeName);
|
||||||
|
|
||||||
pServiceImage->hControlPipe = CreateNamedPipeW(szControlPipeName,
|
pServiceImage->hControlPipe = CreateNamedPipeW(szControlPipeName,
|
||||||
|
#ifdef USE_ASYNCHRONOUS_IO
|
||||||
|
PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
|
||||||
|
#else
|
||||||
PIPE_ACCESS_DUPLEX,
|
PIPE_ACCESS_DUPLEX,
|
||||||
|
#endif
|
||||||
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
|
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
|
||||||
100,
|
100,
|
||||||
8000,
|
8000,
|
||||||
4,
|
4,
|
||||||
30000,
|
dwPipeTimeout,
|
||||||
NULL);
|
NULL);
|
||||||
DPRINT("CreateNamedPipeW(%S) done\n", szControlPipeName);
|
DPRINT("CreateNamedPipeW(%S) done\n", szControlPipeName);
|
||||||
if (pServiceImage->hControlPipe == INVALID_HANDLE_VALUE)
|
if (pServiceImage->hControlPipe == INVALID_HANDLE_VALUE)
|
||||||
|
@ -921,6 +934,10 @@ ScmControlService(PSERVICE Service,
|
||||||
DWORD PacketSize;
|
DWORD PacketSize;
|
||||||
PWSTR Ptr;
|
PWSTR Ptr;
|
||||||
DWORD dwError = ERROR_SUCCESS;
|
DWORD dwError = ERROR_SUCCESS;
|
||||||
|
BOOL bResult;
|
||||||
|
#ifdef USE_ASYNCHRONOUS_IO
|
||||||
|
OVERLAPPED Overlapped = {0, 0, 0, 0, 0};
|
||||||
|
#endif
|
||||||
|
|
||||||
DPRINT("ScmControlService() called\n");
|
DPRINT("ScmControlService() called\n");
|
||||||
|
|
||||||
|
@ -951,20 +968,140 @@ ScmControlService(PSERVICE Service,
|
||||||
ControlPacket->dwArgumentsCount = 0;
|
ControlPacket->dwArgumentsCount = 0;
|
||||||
ControlPacket->dwArgumentsOffset = 0;
|
ControlPacket->dwArgumentsOffset = 0;
|
||||||
|
|
||||||
/* Send the control packet */
|
#ifdef USE_ASYNCHRONOUS_IO
|
||||||
WriteFile(Service->lpImage->hControlPipe,
|
bResult = WriteFile(Service->lpImage->hControlPipe,
|
||||||
ControlPacket,
|
ControlPacket,
|
||||||
PacketSize,
|
PacketSize,
|
||||||
&dwWriteCount,
|
&dwWriteCount,
|
||||||
NULL);
|
&Overlapped);
|
||||||
|
if (bResult == FALSE)
|
||||||
|
{
|
||||||
|
DPRINT1("WriteFile() returned FALSE\n");
|
||||||
|
|
||||||
|
dwError = GetLastError();
|
||||||
|
if (dwError == ERROR_IO_PENDING)
|
||||||
|
{
|
||||||
|
DPRINT1("dwError: ERROR_IO_PENDING\n");
|
||||||
|
|
||||||
|
dwError = WaitForSingleObject(Service->lpImage->hControlPipe,
|
||||||
|
dwPipeTimeout);
|
||||||
|
DPRINT1("WaitForSingleObject() returned %lu\n", dwError);
|
||||||
|
|
||||||
|
if (dwError == WAIT_TIMEOUT)
|
||||||
|
{
|
||||||
|
bResult = CancelIo(Service->lpImage->hControlPipe);
|
||||||
|
if (bResult == FALSE)
|
||||||
|
{
|
||||||
|
DPRINT1("CancelIo() failed (Error: %lu)\n", GetLastError());
|
||||||
|
}
|
||||||
|
|
||||||
|
dwError = ERROR_SERVICE_REQUEST_TIMEOUT;
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
else if (dwError == ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
bResult = GetOverlappedResult(Service->lpImage->hControlPipe,
|
||||||
|
&Overlapped,
|
||||||
|
&dwWriteCount,
|
||||||
|
TRUE);
|
||||||
|
if (bResult == FALSE)
|
||||||
|
{
|
||||||
|
dwError = GetLastError();
|
||||||
|
DPRINT1("GetOverlappedResult() failed (Error %lu)\n", dwError);
|
||||||
|
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DPRINT1("WriteFile() failed (Error %lu)\n", dwError);
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Read the reply */
|
/* Read the reply */
|
||||||
ReadFile(Service->lpImage->hControlPipe,
|
Overlapped.hEvent = (HANDLE) NULL;
|
||||||
&ReplyPacket,
|
|
||||||
sizeof(SCM_REPLY_PACKET),
|
|
||||||
&dwReadCount,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
|
bResult = ReadFile(Service->lpImage->hControlPipe,
|
||||||
|
&ReplyPacket,
|
||||||
|
sizeof(SCM_REPLY_PACKET),
|
||||||
|
&dwReadCount,
|
||||||
|
&Overlapped);
|
||||||
|
if (bResult == FALSE)
|
||||||
|
{
|
||||||
|
DPRINT1("ReadFile() returned FALSE\n");
|
||||||
|
|
||||||
|
dwError = GetLastError();
|
||||||
|
if (dwError == ERROR_IO_PENDING)
|
||||||
|
{
|
||||||
|
DPRINT1("dwError: ERROR_IO_PENDING\n");
|
||||||
|
|
||||||
|
dwError = WaitForSingleObject(Service->lpImage->hControlPipe,
|
||||||
|
dwPipeTimeout);
|
||||||
|
DPRINT1("WaitForSingleObject() returned %lu\n", dwError);
|
||||||
|
|
||||||
|
if (dwError == WAIT_TIMEOUT)
|
||||||
|
{
|
||||||
|
bResult = CancelIo(Service->lpImage->hControlPipe);
|
||||||
|
if (bResult == FALSE)
|
||||||
|
{
|
||||||
|
DPRINT1("CancelIo() failed (Error: %lu)\n", GetLastError());
|
||||||
|
}
|
||||||
|
|
||||||
|
dwError = ERROR_SERVICE_REQUEST_TIMEOUT;
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
else if (dwError == ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
bResult = GetOverlappedResult(Service->lpImage->hControlPipe,
|
||||||
|
&Overlapped,
|
||||||
|
&dwReadCount,
|
||||||
|
TRUE);
|
||||||
|
if (bResult == FALSE)
|
||||||
|
{
|
||||||
|
dwError = GetLastError();
|
||||||
|
DPRINT1("GetOverlappedResult() failed (Error %lu)\n", dwError);
|
||||||
|
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DPRINT1("ReadFile() failed (Error %lu)\n", dwError);
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
/* Send the control packet */
|
||||||
|
bResult = WriteFile(Service->lpImage->hControlPipe,
|
||||||
|
ControlPacket,
|
||||||
|
PacketSize,
|
||||||
|
&dwWriteCount,
|
||||||
|
NULL);
|
||||||
|
if (bResult == FALSE)
|
||||||
|
{
|
||||||
|
dwError = GetLastError();
|
||||||
|
DPRINT("WriteFile() failed (Error %lu)\n", dwError);
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read the reply */
|
||||||
|
bResult = ReadFile(Service->lpImage->hControlPipe,
|
||||||
|
&ReplyPacket,
|
||||||
|
sizeof(SCM_REPLY_PACKET),
|
||||||
|
&dwReadCount,
|
||||||
|
NULL);
|
||||||
|
if (bResult == FALSE)
|
||||||
|
{
|
||||||
|
dwError = GetLastError();
|
||||||
|
DPRINT("ReadFile() failed (Error %lu)\n", dwError);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Done:
|
||||||
/* Release the contol packet */
|
/* Release the contol packet */
|
||||||
HeapFree(GetProcessHeap(),
|
HeapFree(GetProcessHeap(),
|
||||||
0,
|
0,
|
||||||
|
@ -1004,6 +1141,10 @@ ScmSendStartCommand(PSERVICE Service,
|
||||||
DWORD i;
|
DWORD i;
|
||||||
PWSTR *pOffPtr;
|
PWSTR *pOffPtr;
|
||||||
PWSTR pArgPtr;
|
PWSTR pArgPtr;
|
||||||
|
BOOL bResult;
|
||||||
|
#ifdef USE_ASYNCHRONOUS_IO
|
||||||
|
OVERLAPPED Overlapped = {0, 0, 0, 0, 0};
|
||||||
|
#endif
|
||||||
|
|
||||||
DPRINT("ScmSendStartCommand() called\n");
|
DPRINT("ScmSendStartCommand() called\n");
|
||||||
|
|
||||||
|
@ -1066,20 +1207,140 @@ ScmSendStartCommand(PSERVICE Service,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Send the start command */
|
#ifdef USE_ASYNCHRONOUS_IO
|
||||||
WriteFile(Service->lpImage->hControlPipe,
|
bResult = WriteFile(Service->lpImage->hControlPipe,
|
||||||
ControlPacket,
|
ControlPacket,
|
||||||
PacketSize,
|
PacketSize,
|
||||||
&dwWriteCount,
|
&dwWriteCount,
|
||||||
NULL);
|
&Overlapped);
|
||||||
|
if (bResult == FALSE)
|
||||||
|
{
|
||||||
|
DPRINT1("WriteFile() returned FALSE\n");
|
||||||
|
|
||||||
|
dwError = GetLastError();
|
||||||
|
if (dwError == ERROR_IO_PENDING)
|
||||||
|
{
|
||||||
|
DPRINT1("dwError: ERROR_IO_PENDING\n");
|
||||||
|
|
||||||
|
dwError = WaitForSingleObject(Service->lpImage->hControlPipe,
|
||||||
|
dwPipeTimeout);
|
||||||
|
DPRINT1("WaitForSingleObject() returned %lu\n", dwError);
|
||||||
|
|
||||||
|
if (dwError == WAIT_TIMEOUT)
|
||||||
|
{
|
||||||
|
bResult = CancelIo(Service->lpImage->hControlPipe);
|
||||||
|
if (bResult == FALSE)
|
||||||
|
{
|
||||||
|
DPRINT1("CancelIo() failed (Error: %lu)\n", GetLastError());
|
||||||
|
}
|
||||||
|
|
||||||
|
dwError = ERROR_SERVICE_REQUEST_TIMEOUT;
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
else if (dwError == ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
bResult = GetOverlappedResult(Service->lpImage->hControlPipe,
|
||||||
|
&Overlapped,
|
||||||
|
&dwWriteCount,
|
||||||
|
TRUE);
|
||||||
|
if (bResult == FALSE)
|
||||||
|
{
|
||||||
|
dwError = GetLastError();
|
||||||
|
DPRINT1("GetOverlappedResult() failed (Error %lu)\n", dwError);
|
||||||
|
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DPRINT1("WriteFile() failed (Error %lu)\n", dwError);
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Read the reply */
|
/* Read the reply */
|
||||||
ReadFile(Service->lpImage->hControlPipe,
|
Overlapped.hEvent = (HANDLE) NULL;
|
||||||
&ReplyPacket,
|
|
||||||
sizeof(SCM_REPLY_PACKET),
|
|
||||||
&dwReadCount,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
|
bResult = ReadFile(Service->lpImage->hControlPipe,
|
||||||
|
&ReplyPacket,
|
||||||
|
sizeof(SCM_REPLY_PACKET),
|
||||||
|
&dwReadCount,
|
||||||
|
&Overlapped);
|
||||||
|
if (bResult == FALSE)
|
||||||
|
{
|
||||||
|
DPRINT1("ReadFile() returned FALSE\n");
|
||||||
|
|
||||||
|
dwError = GetLastError();
|
||||||
|
if (dwError == ERROR_IO_PENDING)
|
||||||
|
{
|
||||||
|
DPRINT1("dwError: ERROR_IO_PENDING\n");
|
||||||
|
|
||||||
|
dwError = WaitForSingleObject(Service->lpImage->hControlPipe,
|
||||||
|
dwPipeTimeout);
|
||||||
|
DPRINT1("WaitForSingleObject() returned %lu\n", dwError);
|
||||||
|
|
||||||
|
if (dwError == WAIT_TIMEOUT)
|
||||||
|
{
|
||||||
|
bResult = CancelIo(Service->lpImage->hControlPipe);
|
||||||
|
if (bResult == FALSE)
|
||||||
|
{
|
||||||
|
DPRINT1("CancelIo() failed (Error: %lu)\n", GetLastError());
|
||||||
|
}
|
||||||
|
|
||||||
|
dwError = ERROR_SERVICE_REQUEST_TIMEOUT;
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
else if (dwError == ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
bResult = GetOverlappedResult(Service->lpImage->hControlPipe,
|
||||||
|
&Overlapped,
|
||||||
|
&dwReadCount,
|
||||||
|
TRUE);
|
||||||
|
if (bResult == FALSE)
|
||||||
|
{
|
||||||
|
dwError = GetLastError();
|
||||||
|
DPRINT1("GetOverlappedResult() failed (Error %lu)\n", dwError);
|
||||||
|
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DPRINT1("ReadFile() failed (Error %lu)\n", dwError);
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
/* Send the start command */
|
||||||
|
bResult = WriteFile(Service->lpImage->hControlPipe,
|
||||||
|
ControlPacket,
|
||||||
|
PacketSize,
|
||||||
|
&dwWriteCount,
|
||||||
|
NULL);
|
||||||
|
if (bResult == FALSE)
|
||||||
|
{
|
||||||
|
dwError = GetLastError();
|
||||||
|
DPRINT("WriteFile() failed (Error %lu)\n", dwError);
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read the reply */
|
||||||
|
bResult = ReadFile(Service->lpImage->hControlPipe,
|
||||||
|
&ReplyPacket,
|
||||||
|
sizeof(SCM_REPLY_PACKET),
|
||||||
|
&dwReadCount,
|
||||||
|
NULL);
|
||||||
|
if (bResult == FALSE)
|
||||||
|
{
|
||||||
|
dwError = GetLastError();
|
||||||
|
DPRINT("ReadFile() failed (Error %lu)\n", dwError);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Done:
|
||||||
/* Release the contol packet */
|
/* Release the contol packet */
|
||||||
HeapFree(GetProcessHeap(),
|
HeapFree(GetProcessHeap(),
|
||||||
0,
|
0,
|
||||||
|
@ -1096,6 +1357,166 @@ ScmSendStartCommand(PSERVICE Service,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static DWORD
|
||||||
|
ScmWaitForServiceConnect(PSERVICE Service)
|
||||||
|
{
|
||||||
|
DWORD dwRead = 0;
|
||||||
|
DWORD dwProcessId = 0;
|
||||||
|
DWORD dwError = ERROR_SUCCESS;
|
||||||
|
BOOL bResult;
|
||||||
|
#ifdef USE_ASYNCHRONOUS_IO
|
||||||
|
OVERLAPPED Overlapped = {0, 0, 0, 0, 0};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
DPRINT1("ScmWaitForServiceConnect()\n");
|
||||||
|
|
||||||
|
#ifdef USE_ASYNCHRONOUS_IO
|
||||||
|
Overlapped.hEvent = (HANDLE)NULL;
|
||||||
|
|
||||||
|
bResult = ConnectNamedPipe(Service->lpImage->hControlPipe,
|
||||||
|
&Overlapped);
|
||||||
|
if (bResult == FALSE)
|
||||||
|
{
|
||||||
|
DPRINT1("ConnectNamedPipe() returned FALSE\n");
|
||||||
|
|
||||||
|
dwError = GetLastError();
|
||||||
|
if (dwError == ERROR_IO_PENDING)
|
||||||
|
{
|
||||||
|
DPRINT1("dwError: ERROR_IO_PENDING\n");
|
||||||
|
|
||||||
|
dwError = WaitForSingleObject(Service->lpImage->hControlPipe,
|
||||||
|
dwPipeTimeout);
|
||||||
|
DPRINT1("WaitForSingleObject() returned %lu\n", dwError);
|
||||||
|
|
||||||
|
if (dwError == WAIT_TIMEOUT)
|
||||||
|
{
|
||||||
|
bResult = CancelIo(Service->lpImage->hControlPipe);
|
||||||
|
if (bResult == FALSE)
|
||||||
|
{
|
||||||
|
DPRINT1("CancelIo() failed (Error: %lu)\n", GetLastError());
|
||||||
|
}
|
||||||
|
|
||||||
|
return ERROR_SERVICE_REQUEST_TIMEOUT;
|
||||||
|
}
|
||||||
|
else if (dwError == ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
bResult = GetOverlappedResult(Service->lpImage->hControlPipe,
|
||||||
|
&Overlapped,
|
||||||
|
&dwRead,
|
||||||
|
TRUE);
|
||||||
|
if (bResult == FALSE)
|
||||||
|
{
|
||||||
|
dwError = GetLastError();
|
||||||
|
DPRINT1("GetOverlappedResult failed (Error %lu)\n", dwError);
|
||||||
|
|
||||||
|
return dwError;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (dwError != ERROR_PIPE_CONNECTED)
|
||||||
|
{
|
||||||
|
DPRINT1("ConnectNamedPipe failed (Error %lu)\n", dwError);
|
||||||
|
return dwError;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DPRINT1("Control pipe connected!\n");
|
||||||
|
|
||||||
|
Overlapped.hEvent = (HANDLE) NULL;
|
||||||
|
|
||||||
|
/* Read the process id from pipe */
|
||||||
|
bResult = ReadFile(Service->lpImage->hControlPipe,
|
||||||
|
(LPVOID)&dwProcessId,
|
||||||
|
sizeof(DWORD),
|
||||||
|
&dwRead,
|
||||||
|
&Overlapped);
|
||||||
|
if (bResult == FALSE)
|
||||||
|
{
|
||||||
|
DPRINT1("ReadFile() returned FALSE\n");
|
||||||
|
|
||||||
|
dwError = GetLastError();
|
||||||
|
if (dwError == ERROR_IO_PENDING)
|
||||||
|
{
|
||||||
|
DPRINT1("dwError: ERROR_IO_PENDING\n");
|
||||||
|
|
||||||
|
dwError = WaitForSingleObject(Service->lpImage->hControlPipe,
|
||||||
|
dwPipeTimeout);
|
||||||
|
if (dwError == WAIT_TIMEOUT)
|
||||||
|
{
|
||||||
|
DPRINT1("WaitForSingleObject() returned WAIT_TIMEOUT\n");
|
||||||
|
|
||||||
|
bResult = CancelIo(Service->lpImage->hControlPipe);
|
||||||
|
if (bResult == FALSE)
|
||||||
|
{
|
||||||
|
DPRINT1("CancelIo() failed (Error: %lu)\n", GetLastError());
|
||||||
|
}
|
||||||
|
|
||||||
|
return ERROR_SERVICE_REQUEST_TIMEOUT;
|
||||||
|
}
|
||||||
|
else if (dwError == ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
DPRINT1("WaitForSingleObject() returned ERROR_SUCCESS\n");
|
||||||
|
|
||||||
|
DPRINT1("Process Id: %lu\n", dwProcessId);
|
||||||
|
|
||||||
|
bResult = GetOverlappedResult(Service->lpImage->hControlPipe,
|
||||||
|
&Overlapped,
|
||||||
|
&dwRead,
|
||||||
|
TRUE);
|
||||||
|
if (bResult == FALSE)
|
||||||
|
{
|
||||||
|
dwError = GetLastError();
|
||||||
|
DPRINT1("GetOverlappedResult() failed (Error %lu)\n", dwError);
|
||||||
|
|
||||||
|
return dwError;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DPRINT1("WaitForSingleObject() returned %lu\n", dwError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DPRINT1("ReadFile() failed (Error %lu)\n", dwError);
|
||||||
|
return dwError;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DPRINT1("ScmWaitForServiceConnect() done\n");
|
||||||
|
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
#else
|
||||||
|
|
||||||
|
/* Connect control pipe */
|
||||||
|
if (ConnectNamedPipe(Service->lpImage->hControlPipe, NULL) ?
|
||||||
|
TRUE : (dwError = GetLastError()) == ERROR_PIPE_CONNECTED)
|
||||||
|
{
|
||||||
|
DPRINT("Control pipe connected!\n");
|
||||||
|
|
||||||
|
/* Read SERVICE_STATUS_HANDLE from pipe */
|
||||||
|
bResult = ReadFile(Service->lpImage->hControlPipe,
|
||||||
|
(LPVOID)&dwProcessId,
|
||||||
|
sizeof(DWORD),
|
||||||
|
&dwRead,
|
||||||
|
NULL);
|
||||||
|
if (bResult == FALSE)
|
||||||
|
{
|
||||||
|
dwError = GetLastError();
|
||||||
|
DPRINT1("Reading the service control pipe failed (Error %lu)\n",
|
||||||
|
dwError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DPRINT1("Connecting control pipe failed! (Error %lu)\n", dwError);
|
||||||
|
}
|
||||||
|
|
||||||
|
return dwError;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static DWORD
|
static DWORD
|
||||||
ScmStartUserModeService(PSERVICE Service,
|
ScmStartUserModeService(PSERVICE Service,
|
||||||
DWORD argc,
|
DWORD argc,
|
||||||
|
@ -1105,7 +1526,6 @@ ScmStartUserModeService(PSERVICE Service,
|
||||||
STARTUPINFOW StartupInfo;
|
STARTUPINFOW StartupInfo;
|
||||||
BOOL Result;
|
BOOL Result;
|
||||||
DWORD dwError = ERROR_SUCCESS;
|
DWORD dwError = ERROR_SUCCESS;
|
||||||
DWORD dwProcessId;
|
|
||||||
|
|
||||||
DPRINT("ScmStartUserModeService(%p)\n", Service);
|
DPRINT("ScmStartUserModeService(%p)\n", Service);
|
||||||
|
|
||||||
|
@ -1156,35 +1576,20 @@ ScmStartUserModeService(PSERVICE Service,
|
||||||
ResumeThread(ProcessInformation.hThread);
|
ResumeThread(ProcessInformation.hThread);
|
||||||
|
|
||||||
/* Connect control pipe */
|
/* Connect control pipe */
|
||||||
if (ConnectNamedPipe(Service->lpImage->hControlPipe, NULL) ?
|
dwError = ScmWaitForServiceConnect(Service);
|
||||||
TRUE : (dwError = GetLastError()) == ERROR_PIPE_CONNECTED)
|
if (dwError == ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
DWORD dwRead = 0;
|
/* Send start command */
|
||||||
|
dwError = ScmSendStartCommand(Service,
|
||||||
DPRINT("Control pipe connected!\n");
|
argc,
|
||||||
|
argv);
|
||||||
/* Read SERVICE_STATUS_HANDLE from pipe */
|
|
||||||
if (!ReadFile(Service->lpImage->hControlPipe,
|
|
||||||
(LPVOID)&dwProcessId,
|
|
||||||
sizeof(DWORD),
|
|
||||||
&dwRead,
|
|
||||||
NULL))
|
|
||||||
{
|
|
||||||
dwError = GetLastError();
|
|
||||||
DPRINT1("Reading the service control pipe failed (Error %lu)\n",
|
|
||||||
dwError);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DPRINT("Received service process ID %lu\n", dwProcessId);
|
|
||||||
|
|
||||||
/* Send start command */
|
|
||||||
dwError = ScmSendStartCommand(Service, argc, argv);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DPRINT1("Connecting control pipe failed! (Error %lu)\n", dwError);
|
DPRINT1("Connecting control pipe failed! (Error %lu)\n", dwError);
|
||||||
|
Service->lpImage->dwProcessId = 0;
|
||||||
|
Service->lpImage->hProcess = NULL;
|
||||||
|
CloseHandle(ProcessInformation.hProcess);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Close thread handle */
|
/* Close thread handle */
|
||||||
|
@ -1531,7 +1936,29 @@ ScmUnlockDatabase(VOID)
|
||||||
VOID
|
VOID
|
||||||
ScmInitNamedPipeCriticalSection(VOID)
|
ScmInitNamedPipeCriticalSection(VOID)
|
||||||
{
|
{
|
||||||
|
HKEY hKey;
|
||||||
|
DWORD dwKeySize;
|
||||||
|
DWORD dwError;
|
||||||
|
|
||||||
InitializeCriticalSection(&ControlServiceCriticalSection);
|
InitializeCriticalSection(&ControlServiceCriticalSection);
|
||||||
|
|
||||||
|
dwError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
|
||||||
|
L"SYSTEM\\CurrentControlSet\\Control",
|
||||||
|
0,
|
||||||
|
KEY_READ,
|
||||||
|
&hKey);
|
||||||
|
if (dwError == ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
dwKeySize = sizeof(DWORD);
|
||||||
|
RegQueryValueExW(hKey,
|
||||||
|
L"ServicesPipeTimeout",
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
(LPBYTE)&dwPipeTimeout,
|
||||||
|
&dwKeySize);
|
||||||
|
|
||||||
|
RegCloseKey(hKey);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue