mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-03 01:51:48 +00:00
services: Add a timeout to all pipe communications with the service process.
This commit is contained in:
parent
c9dc9a1063
commit
f51668fdf9
|
@ -893,16 +893,28 @@ static BOOL service_accepts_control(const struct service_entry *service, DWORD d
|
|||
BOOL service_send_command( struct service_entry *service, HANDLE pipe,
|
||||
const void *data, DWORD size, DWORD *result )
|
||||
{
|
||||
OVERLAPPED overlapped;
|
||||
DWORD count;
|
||||
BOOL r;
|
||||
|
||||
r = WriteFile(pipe, data, size, &count, NULL);
|
||||
overlapped.hEvent = service->overlapped_event;
|
||||
r = WriteFile(pipe, data, size, &count, &overlapped);
|
||||
if (!r && GetLastError() == ERROR_IO_PENDING)
|
||||
{
|
||||
WaitForSingleObject( service->overlapped_event, service_pipe_timeout );
|
||||
r = GetOverlappedResult( pipe, &overlapped, &count, FALSE );
|
||||
}
|
||||
if (!r || count != size)
|
||||
{
|
||||
WINE_ERR("service protocol error - failed to write pipe!\n");
|
||||
return FALSE;
|
||||
}
|
||||
r = ReadFile(pipe, result, sizeof *result, &count, NULL);
|
||||
r = ReadFile(pipe, result, sizeof *result, &count, &overlapped);
|
||||
if (!r && GetLastError() == ERROR_IO_PENDING)
|
||||
{
|
||||
WaitForSingleObject( service->overlapped_event, service_pipe_timeout );
|
||||
r = GetOverlappedResult( pipe, &overlapped, &count, FALSE );
|
||||
}
|
||||
if (!r || count != sizeof *result)
|
||||
{
|
||||
WINE_ERR("service protocol error - failed to read pipe "
|
||||
|
|
|
@ -95,6 +95,7 @@ void free_service_entry(struct service_entry *entry)
|
|||
HeapFree(GetProcessHeap(), 0, entry->dependOnGroups);
|
||||
CloseHandle(entry->control_mutex);
|
||||
CloseHandle(entry->control_pipe);
|
||||
CloseHandle(entry->overlapped_event);
|
||||
CloseHandle(entry->status_changed_event);
|
||||
HeapFree(GetProcessHeap(), 0, entry);
|
||||
}
|
||||
|
@ -672,8 +673,10 @@ static DWORD service_wait_for_startup(struct service_entry *service_entry, HANDL
|
|||
/******************************************************************************
|
||||
* service_send_start_message
|
||||
*/
|
||||
static BOOL service_send_start_message(struct service_entry *service, LPCWSTR *argv, DWORD argc)
|
||||
static BOOL service_send_start_message(struct service_entry *service, HANDLE process_handle,
|
||||
LPCWSTR *argv, DWORD argc)
|
||||
{
|
||||
OVERLAPPED overlapped;
|
||||
DWORD i, len, result;
|
||||
service_start_info *ssi;
|
||||
LPWSTR p;
|
||||
|
@ -681,12 +684,27 @@ static BOOL service_send_start_message(struct service_entry *service, LPCWSTR *a
|
|||
|
||||
WINE_TRACE("%s %p %d\n", wine_dbgstr_w(service->name), argv, argc);
|
||||
|
||||
/* FIXME: this can block so should be done in another thread */
|
||||
r = ConnectNamedPipe(service->control_pipe, NULL);
|
||||
if (!r && GetLastError() != ERROR_PIPE_CONNECTED)
|
||||
overlapped.hEvent = service->overlapped_event;
|
||||
if (!ConnectNamedPipe(service->control_pipe, &overlapped))
|
||||
{
|
||||
WINE_ERR("pipe connect failed\n");
|
||||
return FALSE;
|
||||
if (GetLastError() == ERROR_IO_PENDING)
|
||||
{
|
||||
HANDLE handles[2];
|
||||
handles[0] = service->overlapped_event;
|
||||
handles[1] = process_handle;
|
||||
if (WaitForMultipleObjects( 2, handles, FALSE, service_pipe_timeout ) != WAIT_OBJECT_0)
|
||||
CancelIo( service->control_pipe );
|
||||
if (!HasOverlappedCompleted( &overlapped ))
|
||||
{
|
||||
WINE_ERR( "service %s failed to start\n", wine_dbgstr_w( service->name ));
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else if (GetLastError() != ERROR_PIPE_CONNECTED)
|
||||
{
|
||||
WINE_ERR("pipe connect failed\n");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* calculate how much space do we need to send the startup info */
|
||||
|
@ -743,9 +761,11 @@ DWORD service_start(struct service_entry *service, DWORD service_argc, LPCWSTR *
|
|||
|
||||
if (!service->status_changed_event)
|
||||
service->status_changed_event = CreateEventW(NULL, FALSE, FALSE, NULL);
|
||||
if (!service->overlapped_event)
|
||||
service->overlapped_event = CreateEventW(NULL, TRUE, FALSE, NULL);
|
||||
|
||||
name = service_get_pipe_name();
|
||||
service->control_pipe = CreateNamedPipeW(name, PIPE_ACCESS_DUPLEX,
|
||||
service->control_pipe = CreateNamedPipeW(name, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
|
||||
PIPE_TYPE_BYTE|PIPE_WAIT, 1, 256, 256, 10000, NULL );
|
||||
HeapFree(GetProcessHeap(), 0, name);
|
||||
if (service->control_pipe==INVALID_HANDLE_VALUE)
|
||||
|
@ -760,7 +780,7 @@ DWORD service_start(struct service_entry *service, DWORD service_argc, LPCWSTR *
|
|||
|
||||
if (err == ERROR_SUCCESS)
|
||||
{
|
||||
if (!service_send_start_message(service, service_argv, service_argc))
|
||||
if (!service_send_start_message(service, process_handle, service_argv, service_argc))
|
||||
err = ERROR_SERVICE_REQUEST_TIMEOUT;
|
||||
}
|
||||
|
||||
|
|
|
@ -44,6 +44,7 @@ struct service_entry
|
|||
LPWSTR dependOnGroups;
|
||||
HANDLE control_mutex;
|
||||
HANDLE control_pipe;
|
||||
HANDLE overlapped_event;
|
||||
HANDLE status_changed_event;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue