winedevice: Improve error handling when a driver fails to load.
Signed-off-by: Alistair Leslie-Hughes <leslie_alistair@hotmail.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
b5c1a8f635
commit
dd2624a24f
@ -50,12 +50,15 @@ static SC_HANDLE manager_handle;
|
|||||||
static BOOL shutdown_in_progress;
|
static BOOL shutdown_in_progress;
|
||||||
static HANDLE stop_event;
|
static HANDLE stop_event;
|
||||||
|
|
||||||
|
#define EVENT_STARTED 0
|
||||||
|
#define EVENT_ERROR 1
|
||||||
|
|
||||||
struct wine_driver
|
struct wine_driver
|
||||||
{
|
{
|
||||||
struct wine_rb_entry entry;
|
struct wine_rb_entry entry;
|
||||||
|
|
||||||
SERVICE_STATUS_HANDLE handle;
|
SERVICE_STATUS_HANDLE handle;
|
||||||
HANDLE started;
|
HANDLE events[2];
|
||||||
DRIVER_OBJECT *driver_obj;
|
DRIVER_OBJECT *driver_obj;
|
||||||
WCHAR name[1];
|
WCHAR name[1];
|
||||||
};
|
};
|
||||||
@ -391,7 +394,7 @@ static void WINAPI async_create_driver( PTP_CALLBACK_INSTANCE instance, void *co
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
SetEvent(driver->started);
|
SetEvent(driver->events[EVENT_STARTED]);
|
||||||
|
|
||||||
EnterCriticalSection( &drivers_cs );
|
EnterCriticalSection( &drivers_cs );
|
||||||
driver->driver_obj = driver_obj;
|
driver->driver_obj = driver_obj;
|
||||||
@ -401,6 +404,7 @@ static void WINAPI async_create_driver( PTP_CALLBACK_INSTANCE instance, void *co
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
SetEvent(driver->events[EVENT_ERROR]);
|
||||||
EnterCriticalSection( &drivers_cs );
|
EnterCriticalSection( &drivers_cs );
|
||||||
wine_rb_remove( &wine_drivers, &driver->entry );
|
wine_rb_remove( &wine_drivers, &driver->entry );
|
||||||
LeaveCriticalSection( &drivers_cs );
|
LeaveCriticalSection( &drivers_cs );
|
||||||
@ -416,6 +420,7 @@ static NTSTATUS create_driver( const WCHAR *driver_name )
|
|||||||
TP_CALLBACK_ENVIRON environment;
|
TP_CALLBACK_ENVIRON environment;
|
||||||
struct wine_driver *driver;
|
struct wine_driver *driver;
|
||||||
DWORD length;
|
DWORD length;
|
||||||
|
DWORD ret;
|
||||||
|
|
||||||
length = FIELD_OFFSET( struct wine_driver, name[strlenW(driver_name) + 1] );
|
length = FIELD_OFFSET( struct wine_driver, name[strlenW(driver_name) + 1] );
|
||||||
if (!(driver = HeapAlloc( GetProcessHeap(), 0, length )))
|
if (!(driver = HeapAlloc( GetProcessHeap(), 0, length )))
|
||||||
@ -444,14 +449,18 @@ static NTSTATUS create_driver( const WCHAR *driver_name )
|
|||||||
environment.Version = 1;
|
environment.Version = 1;
|
||||||
environment.CleanupGroup = cleanup_group;
|
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 */
|
/* don't block the service control handler */
|
||||||
if (!TrySubmitThreadpoolCallback( async_create_driver, driver, &environment ))
|
if (!TrySubmitThreadpoolCallback( async_create_driver, driver, &environment ))
|
||||||
async_create_driver( NULL, driver );
|
async_create_driver( NULL, driver );
|
||||||
|
|
||||||
/* Windows wait 30 Seconds */
|
/* 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 ERROR_SERVICE_REQUEST_TIMEOUT;
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
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)
|
if (unload_driver( entry, TRUE ) != STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
struct wine_driver *driver = WINE_RB_ENTRY_VALUE( entry, struct wine_driver, entry );
|
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 );
|
ObDereferenceObject( driver->driver_obj );
|
||||||
CloseServiceHandle( (void *)driver->handle );
|
CloseServiceHandle( (void *)driver->handle );
|
||||||
HeapFree( GetProcessHeap(), 0, driver );
|
HeapFree( GetProcessHeap(), 0, driver );
|
||||||
|
Loading…
x
Reference in New Issue
Block a user