Module: wine Branch: master Commit: c3bfc1b7264277395f2bbe9b2c059d34f4dffae3 URL: https://source.winehq.org/git/wine.git/?a=commit;h=c3bfc1b7264277395f2bbe9b2...
Author: Piotr Caban piotr@codeweavers.com Date: Tue Nov 12 20:03:31 2019 +0100
winebus: Fix DEVICE_RELATIONS content on device removal.
Signed-off-by: Piotr Caban piotr@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/winebus.sys/bus.h | 1 + dlls/winebus.sys/bus_iohid.c | 1 + dlls/winebus.sys/bus_sdl.c | 2 ++ dlls/winebus.sys/bus_udev.c | 2 ++ dlls/winebus.sys/main.c | 14 ++++++++++---- 5 files changed, 16 insertions(+), 4 deletions(-)
diff --git a/dlls/winebus.sys/bus.h b/dlls/winebus.sys/bus.h index 09666dc151..041a37ad04 100644 --- a/dlls/winebus.sys/bus.h +++ b/dlls/winebus.sys/bus.h @@ -45,6 +45,7 @@ DEVICE_OBJECT *bus_create_hid_device(const WCHAR *busidW, WORD vid, WORD pid, WORD input, DWORD version, DWORD uid, const WCHAR *serialW, BOOL is_gamepad, const platform_vtbl *vtbl, DWORD platform_data_size) DECLSPEC_HIDDEN; DEVICE_OBJECT *bus_find_hid_device(const platform_vtbl *vtbl, void *platform_dev) DECLSPEC_HIDDEN; +void bus_unlink_hid_device(DEVICE_OBJECT *device) DECLSPEC_HIDDEN; void bus_remove_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 platform_vtbl *vtbl, enum_func function, void* context) DECLSPEC_HIDDEN; diff --git a/dlls/winebus.sys/bus_iohid.c b/dlls/winebus.sys/bus_iohid.c index ed91b51fc8..df578b4b9d 100644 --- a/dlls/winebus.sys/bus_iohid.c +++ b/dlls/winebus.sys/bus_iohid.c @@ -368,6 +368,7 @@ static void handle_RemovalCallback(void *context, IOReturn result, void *sender, device = bus_find_hid_device(&iohid_vtbl, IOHIDDevice); if (device) { + bus_unlink_hid_device(device); IoInvalidateDeviceRelations(bus_pdo, BusRelations); bus_remove_hid_device(device); } diff --git a/dlls/winebus.sys/bus_sdl.c b/dlls/winebus.sys/bus_sdl.c index 61651c92f6..7a2069fafe 100644 --- a/dlls/winebus.sys/bus_sdl.c +++ b/dlls/winebus.sys/bus_sdl.c @@ -899,6 +899,7 @@ static void try_remove_device(SDL_JoystickID id) sdl_controller = private->sdl_controller; sdl_haptic = private->sdl_haptic;
+ bus_unlink_hid_device(device); IoInvalidateDeviceRelations(bus_pdo, BusRelations);
bus_remove_hid_device(device); @@ -988,6 +989,7 @@ static void try_add_device(unsigned int index) if (!rc) { ERR("Building report descriptor failed, removing device\n"); + bus_unlink_hid_device(device); bus_remove_hid_device(device); HeapFree(GetProcessHeap(), 0, serial); return; diff --git a/dlls/winebus.sys/bus_udev.c b/dlls/winebus.sys/bus_udev.c index 239051723c..24d7961b06 100644 --- a/dlls/winebus.sys/bus_udev.c +++ b/dlls/winebus.sys/bus_udev.c @@ -1259,6 +1259,7 @@ static void try_add_device(struct udev_device *dev) ERR("Building report descriptor failed, removing device\n"); close(fd); udev_device_unref(dev); + bus_unlink_hid_device(device); bus_remove_hid_device(device); HeapFree(GetProcessHeap(), 0, serial); return; @@ -1293,6 +1294,7 @@ static void try_remove_device(struct udev_device *dev) #endif if (!device) return;
+ bus_unlink_hid_device(device); IoInvalidateDeviceRelations(bus_pdo, BusRelations);
private = impl_from_DEVICE_OBJECT(device); diff --git a/dlls/winebus.sys/main.c b/dlls/winebus.sys/main.c index 7b05d4ce84..8bba968202 100644 --- a/dlls/winebus.sys/main.c +++ b/dlls/winebus.sys/main.c @@ -346,6 +346,16 @@ DEVICE_OBJECT* bus_enumerate_hid_devices(const platform_vtbl *vtbl, enum_func fu return ret; }
+void bus_unlink_hid_device(DEVICE_OBJECT *device) +{ + struct device_extension *ext = (struct device_extension *)device->DeviceExtension; + struct pnp_device *pnp_device = ext->pnp_device; + + EnterCriticalSection(&device_list_cs); + list_remove(&pnp_device->entry); + LeaveCriticalSection(&device_list_cs); +} + void bus_remove_hid_device(DEVICE_OBJECT *device) { struct device_extension *ext = (struct device_extension *)device->DeviceExtension; @@ -355,10 +365,6 @@ void bus_remove_hid_device(DEVICE_OBJECT *device)
TRACE("(%p)\n", device);
- EnterCriticalSection(&device_list_cs); - list_remove(&pnp_device->entry); - LeaveCriticalSection(&device_list_cs); - /* Cancel pending IRPs */ EnterCriticalSection(&ext->report_cs); while ((entry = RemoveHeadList(&ext->irp_queue)) != &ext->irp_queue)