[PATCH] winedevice: Improve error handling when a driver fails to load
Alistair Leslie-Hughes
leslie_alistair at hotmail.com
Sun Apr 8 21:18:01 CDT 2018
Signed-off-by: Alistair Leslie-Hughes <leslie_alistair at hotmail.com>
---
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 d938ca270d9..49742b742eb 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];
};
@@ -428,7 +431,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;
@@ -438,6 +441,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 );
@@ -453,6 +457,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 )))
@@ -481,14 +486,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;
@@ -499,7 +508,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 );
--
2.16.3
More information about the wine-devel
mailing list