diff --git a/dlls/winebus.sys/bus.h b/dlls/winebus.sys/bus.h index 803ffaad132..6d9090d8603 100644 --- a/dlls/winebus.sys/bus.h +++ b/dlls/winebus.sys/bus.h @@ -47,7 +47,6 @@ DEVICE_OBJECT *bus_create_hid_device(const WCHAR *busidW, WORD vid, WORD pid, WO DWORD version, DWORD uid, const WCHAR *serialW, BOOL is_gamepad, const platform_vtbl *vtbl, struct unix_device *unix_device) DECLSPEC_HIDDEN; DEVICE_OBJECT *bus_find_hid_device(const WCHAR *bus_id, void *platform_dev) DECLSPEC_HIDDEN; -void bus_unlink_hid_device(DEVICE_OBJECT *device) DECLSPEC_HIDDEN; void process_hid_report(DEVICE_OBJECT *device, BYTE *report, DWORD length) DECLSPEC_HIDDEN; DEVICE_OBJECT *bus_enumerate_hid_devices(const WCHAR *bus_id, enum_func function, void *context) DECLSPEC_HIDDEN; diff --git a/dlls/winebus.sys/bus_iohid.c b/dlls/winebus.sys/bus_iohid.c index 9b842dc81a5..9531607f16d 100644 --- a/dlls/winebus.sys/bus_iohid.c +++ b/dlls/winebus.sys/bus_iohid.c @@ -97,6 +97,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(plugplay); static IOHIDManagerRef hid_manager; static CFRunLoopRef run_loop; +static struct list event_queue = LIST_INIT(event_queue); static const WCHAR busidW[] = {'I','O','H','I','D',0}; static struct iohid_bus_options options; @@ -377,19 +378,13 @@ static void handle_DeviceMatchingCallback(void *context, IOReturn result, void * static void handle_RemovalCallback(void *context, IOReturn result, void *sender, IOHIDDeviceRef IOHIDDevice) { - DEVICE_OBJECT *device; TRACE("OS/X IOHID Device Removed %p\n", IOHIDDevice); IOHIDDeviceRegisterInputReportCallback(IOHIDDevice, NULL, 0, NULL, NULL); /* Note: Yes, we leak the buffer. But according to research there is no safe way to deallocate that buffer. */ IOHIDDeviceUnscheduleFromRunLoop(IOHIDDevice, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); IOHIDDeviceClose(IOHIDDevice, 0); - device = bus_find_hid_device(busidW, IOHIDDevice); - if (device) - { - bus_unlink_hid_device(device); - IoInvalidateDeviceRelations(bus_pdo, BusRelations); - } + bus_event_queue_device_removed(&event_queue, busidW, IOHIDDevice); } NTSTATUS iohid_bus_init(void *args) @@ -415,9 +410,15 @@ NTSTATUS iohid_bus_init(void *args) NTSTATUS iohid_bus_wait(void *args) { - CFRunLoopRun(); + struct bus_event *result = args; + + do + { + if (bus_event_queue_pop(&event_queue, result)) return STATUS_PENDING; + } while (CFRunLoopRunInMode(kCFRunLoopDefaultMode, 10, TRUE) != kCFRunLoopRunStopped); TRACE("IOHID main loop exiting\n"); + bus_event_queue_destroy(&event_queue); IOHIDManagerRegisterDeviceMatchingCallback(hid_manager, NULL, NULL); IOHIDManagerRegisterDeviceRemovalCallback(hid_manager, NULL, NULL); CFRelease(hid_manager); diff --git a/dlls/winebus.sys/main.c b/dlls/winebus.sys/main.c index ec5e7715488..dcaa42919f6 100644 --- a/dlls/winebus.sys/main.c +++ b/dlls/winebus.sys/main.c @@ -374,7 +374,7 @@ DEVICE_OBJECT *bus_enumerate_hid_devices(const WCHAR *bus_id, enum_func function return ret; } -void bus_unlink_hid_device(DEVICE_OBJECT *device) +static void bus_unlink_hid_device(DEVICE_OBJECT *device) { struct device_extension *ext = (struct device_extension *)device->DeviceExtension;