From db6c5b59b67f92dcfd06fefb6c04866b45205ebb Mon Sep 17 00:00:00 2001 From: Aric Stewart Date: Wed, 12 Sep 2018 11:22:09 -0500 Subject: [PATCH] winebus.sys: Improve unloading the winebus driver. Signed-off-by: Aric Stewart Signed-off-by: Alexandre Julliard --- dlls/winebus.sys/bus.h | 3 +++ dlls/winebus.sys/bus_iohid.c | 34 +++++++++++++++++++++++++--------- dlls/winebus.sys/bus_sdl.c | 10 ++++++++++ dlls/winebus.sys/bus_udev.c | 10 ++++++++++ dlls/winebus.sys/main.c | 9 +++++++++ 5 files changed, 57 insertions(+), 9 deletions(-) diff --git a/dlls/winebus.sys/bus.h b/dlls/winebus.sys/bus.h index bf93c04259f..16e9bf7d540 100644 --- a/dlls/winebus.sys/bus.h +++ b/dlls/winebus.sys/bus.h @@ -22,6 +22,9 @@ typedef int(*enum_func)(DEVICE_OBJECT *device, void *context); NTSTATUS WINAPI udev_driver_init(DRIVER_OBJECT *driver, UNICODE_STRING *registry_path) DECLSPEC_HIDDEN; NTSTATUS WINAPI iohid_driver_init(DRIVER_OBJECT *driver, UNICODE_STRING *registry_path) DECLSPEC_HIDDEN; NTSTATUS WINAPI sdl_driver_init(DRIVER_OBJECT *driver, UNICODE_STRING *registry_path) DECLSPEC_HIDDEN; +void udev_driver_unload( void ) DECLSPEC_HIDDEN; +void iohid_driver_unload( void ) DECLSPEC_HIDDEN; +void sdl_driver_unload( void ) DECLSPEC_HIDDEN; /* Native device function table */ typedef struct diff --git a/dlls/winebus.sys/bus_iohid.c b/dlls/winebus.sys/bus_iohid.c index ac706f5265c..95077ac0be2 100644 --- a/dlls/winebus.sys/bus_iohid.c +++ b/dlls/winebus.sys/bus_iohid.c @@ -98,6 +98,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(plugplay); static DRIVER_OBJECT *iohid_driver_obj = NULL; static IOHIDManagerRef hid_manager; +static CFRunLoopRef run_loop; +static HANDLE run_loop_handle; static const WCHAR busidW[] = {'I','O','H','I','D',0}; @@ -372,7 +374,7 @@ static void handle_RemovalCallback(void *context, IOReturn result, void *sender, /* This puts the relevant run loop for event handling into a WINE thread */ static DWORD CALLBACK runloop_thread(void *args) { - CFRunLoopRef run_loop = CFRunLoopGetCurrent(); + run_loop = CFRunLoopGetCurrent(); IOHIDManagerSetDeviceMatching(hid_manager, NULL); IOHIDManagerRegisterDeviceMatchingCallback(hid_manager, handle_DeviceMatchingCallback, NULL); @@ -388,18 +390,12 @@ static DWORD CALLBACK runloop_thread(void *args) CFRunLoopRun(); TRACE("Run Loop exiting\n"); - - IOHIDManagerRegisterDeviceMatchingCallback(hid_manager, NULL, NULL); - IOHIDManagerRegisterDeviceRemovalCallback(hid_manager, NULL, NULL); - IOHIDManagerUnscheduleFromRunLoop(hid_manager, run_loop, kCFRunLoopDefaultMode); - CFRelease(hid_manager); return 1; + } NTSTATUS WINAPI iohid_driver_init(DRIVER_OBJECT *driver, UNICODE_STRING *registry_path) { - HANDLE run_loop_handle; - TRACE("(%p, %s)\n", driver, debugstr_w(registry_path->Buffer)); iohid_driver_obj = driver; @@ -414,10 +410,25 @@ NTSTATUS WINAPI iohid_driver_init(DRIVER_OBJECT *driver, UNICODE_STRING *registr return STATUS_UNSUCCESSFUL; } - CloseHandle(run_loop_handle); return STATUS_SUCCESS; } +void iohid_driver_unload( void ) +{ + TRACE("Unloading Driver\n"); + if (iohid_driver_obj != NULL) + { + IOHIDManagerUnscheduleFromRunLoop(hid_manager, run_loop, kCFRunLoopDefaultMode); + CFRunLoopStop(run_loop); + WaitForSingleObject(run_loop_handle, INFINITE); + CloseHandle(run_loop_handle); + IOHIDManagerRegisterDeviceMatchingCallback(hid_manager, NULL, NULL); + IOHIDManagerRegisterDeviceRemovalCallback(hid_manager, NULL, NULL); + CFRelease(hid_manager); + } + TRACE("Driver Unloaded\n"); +} + #else NTSTATUS WINAPI iohid_driver_init(DRIVER_OBJECT *driver, UNICODE_STRING *registry_path) @@ -426,4 +437,9 @@ NTSTATUS WINAPI iohid_driver_init(DRIVER_OBJECT *driver, UNICODE_STRING *registr return STATUS_NOT_IMPLEMENTED; } +void iohid_driver_unload( void ) +{ + TRACE("Stub: Unload Driver\n"); +} + #endif /* HAVE_IOHIDMANAGERCREATE */ diff --git a/dlls/winebus.sys/bus_sdl.c b/dlls/winebus.sys/bus_sdl.c index 159727f6bce..6b2b28e8c90 100644 --- a/dlls/winebus.sys/bus_sdl.c +++ b/dlls/winebus.sys/bus_sdl.c @@ -927,6 +927,11 @@ static DWORD CALLBACK deviceloop_thread(void *args) return 0; } +void sdl_driver_unload( void ) +{ + TRACE("Unload Driver\n"); +} + NTSTATUS WINAPI sdl_driver_init(DRIVER_OBJECT *driver, UNICODE_STRING *registry_path) { static const WCHAR controller_modeW[] = {'M','a','p',' ','C','o','n','t','r','o','l','l','e','r','s',0}; @@ -1023,4 +1028,9 @@ NTSTATUS WINAPI sdl_driver_init(DRIVER_OBJECT *driver, UNICODE_STRING *registry_ return STATUS_NOT_IMPLEMENTED; } +void sdl_driver_unload( void ) +{ + TRACE("Stub: Unload Driver\n"); +} + #endif /* SONAME_LIBSDL2 */ diff --git a/dlls/winebus.sys/bus_udev.c b/dlls/winebus.sys/bus_udev.c index 788b564851e..dabda6a2705 100644 --- a/dlls/winebus.sys/bus_udev.c +++ b/dlls/winebus.sys/bus_udev.c @@ -1418,6 +1418,11 @@ static DWORD CALLBACK deviceloop_thread(void *args) return 0; } +void udev_driver_unload( void ) +{ + TRACE("Unload Driver\n"); +} + NTSTATUS WINAPI udev_driver_init(DRIVER_OBJECT *driver, UNICODE_STRING *registry_path) { HANDLE events[2]; @@ -1482,4 +1487,9 @@ NTSTATUS WINAPI udev_driver_init(DRIVER_OBJECT *driver, UNICODE_STRING *registry return STATUS_NOT_IMPLEMENTED; } +void udev_driver_unload( void ) +{ + TRACE("Stub: Unload Driver\n"); +} + #endif /* HAVE_UDEV */ diff --git a/dlls/winebus.sys/main.c b/dlls/winebus.sys/main.c index ce68e4af860..fd795f127c8 100644 --- a/dlls/winebus.sys/main.c +++ b/dlls/winebus.sys/main.c @@ -699,6 +699,13 @@ BOOL is_xbox_gamepad(WORD vid, WORD pid) return FALSE; } +static void WINAPI driver_unload(DRIVER_OBJECT *driver) +{ + udev_driver_unload(); + iohid_driver_unload(); + sdl_driver_unload(); +} + NTSTATUS WINAPI DriverEntry( DRIVER_OBJECT *driver, UNICODE_STRING *path ) { static const WCHAR udevW[] = {'\\','D','r','i','v','e','r','\\','U','D','E','V',0}; @@ -720,5 +727,7 @@ NTSTATUS WINAPI DriverEntry( DRIVER_OBJECT *driver, UNICODE_STRING *path ) IoCreateDriver(&udev, udev_driver_init); IoCreateDriver(&iohid, iohid_driver_init); + driver->DriverUnload = driver_unload; + return STATUS_SUCCESS; }