Signed-off-by: Alistair Leslie-Hughes leslie_alistair@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 );