From dd2624a24fba400bf59b9396e496d16c43d399d9 Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Mon, 9 Apr 2018 02:18:01 +0000 Subject: [PATCH] winedevice: Improve error handling when a driver fails to load. Signed-off-by: Alistair Leslie-Hughes Signed-off-by: Alexandre Julliard --- programs/winedevice/device.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/programs/winedevice/device.c b/programs/winedevice/device.c index 9da34ec1458..fa8b268494e 100644 --- a/programs/winedevice/device.c +++ b/programs/winedevice/device.c @@ -50,12 +50,15 @@ static SC_HANDLE manager_handle; static BOOL shutdown_in_progress; static HANDLE stop_event; +#define EVENT_STARTED 0 +#define EVENT_ERROR 1 + struct wine_driver { struct wine_rb_entry entry; SERVICE_STATUS_HANDLE handle; - HANDLE started; + HANDLE events[2]; DRIVER_OBJECT *driver_obj; WCHAR name[1]; }; @@ -391,7 +394,7 @@ static void WINAPI async_create_driver( PTP_CALLBACK_INSTANCE instance, void *co goto error; } - SetEvent(driver->started); + SetEvent(driver->events[EVENT_STARTED]); EnterCriticalSection( &drivers_cs ); driver->driver_obj = driver_obj; @@ -401,6 +404,7 @@ static void WINAPI async_create_driver( PTP_CALLBACK_INSTANCE instance, void *co return; error: + SetEvent(driver->events[EVENT_ERROR]); EnterCriticalSection( &drivers_cs ); wine_rb_remove( &wine_drivers, &driver->entry ); LeaveCriticalSection( &drivers_cs ); @@ -416,6 +420,7 @@ static NTSTATUS create_driver( const WCHAR *driver_name ) TP_CALLBACK_ENVIRON environment; struct wine_driver *driver; DWORD length; + DWORD ret; length = FIELD_OFFSET( struct wine_driver, name[strlenW(driver_name) + 1] ); if (!(driver = HeapAlloc( GetProcessHeap(), 0, length ))) @@ -444,14 +449,18 @@ static NTSTATUS create_driver( const WCHAR *driver_name ) environment.Version = 1; environment.CleanupGroup = cleanup_group; - driver->started = CreateEventW(NULL, TRUE, FALSE, NULL); + driver->events[EVENT_STARTED] = CreateEventW(NULL, TRUE, FALSE, NULL); + driver->events[EVENT_ERROR] = CreateEventW(NULL, TRUE, FALSE, NULL); /* don't block the service control handler */ if (!TrySubmitThreadpoolCallback( async_create_driver, driver, &environment )) async_create_driver( NULL, driver ); /* Windows wait 30 Seconds */ - if(WaitForSingleObject(driver->started, 30000) == WAIT_TIMEOUT) + ret = WaitForMultipleObjects(2, driver->events, FALSE, 30000); + if(ret == WAIT_OBJECT_0 + EVENT_ERROR) + return STATUS_UNSUCCESSFUL; + else if(ret == WAIT_TIMEOUT) return ERROR_SERVICE_REQUEST_TIMEOUT; return STATUS_SUCCESS; @@ -462,7 +471,8 @@ static void wine_drivers_rb_destroy( struct wine_rb_entry *entry, void *context if (unload_driver( entry, TRUE ) != STATUS_SUCCESS) { struct wine_driver *driver = WINE_RB_ENTRY_VALUE( entry, struct wine_driver, entry ); - CloseHandle(driver->started); + CloseHandle(driver->events[EVENT_STARTED]); + CloseHandle(driver->events[EVENT_ERROR]); ObDereferenceObject( driver->driver_obj ); CloseServiceHandle( (void *)driver->handle ); HeapFree( GetProcessHeap(), 0, driver );