Piotr Caban : winebus.sys: Stop device report threads to avoid crash on driver unload.

Alexandre Julliard julliard at winehq.org
Tue Sep 17 16:22:49 CDT 2019


Module: wine
Branch: master
Commit: 4b3437907badf9cd3f0938710d68792cc7fe3be2
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=4b3437907badf9cd3f0938710d68792cc7fe3be2

Author: Piotr Caban <piotr at codeweavers.com>
Date:   Tue Sep 17 13:55:08 2019 +0200

winebus.sys: Stop device report threads to avoid crash on driver unload.

Signed-off-by: Piotr Caban <piotr at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/winebus.sys/bus_udev.c |  9 +++++++++
 dlls/winebus.sys/main.c     | 10 +++++++---
 2 files changed, 16 insertions(+), 3 deletions(-)

diff --git a/dlls/winebus.sys/bus_udev.c b/dlls/winebus.sys/bus_udev.c
index 3ed1b029e8..926c755a85 100644
--- a/dlls/winebus.sys/bus_udev.c
+++ b/dlls/winebus.sys/bus_udev.c
@@ -1478,6 +1478,12 @@ static DWORD CALLBACK deviceloop_thread(void *args)
     return 0;
 }
 
+static int device_unload(DEVICE_OBJECT *device, void *context)
+{
+    try_remove_device(impl_from_DEVICE_OBJECT(device)->udev_device);
+    return 1;
+}
+
 void udev_driver_unload( void )
 {
     TRACE("Unload Driver\n");
@@ -1487,6 +1493,9 @@ void udev_driver_unload( void )
     close(deviceloop_control[0]);
     close(deviceloop_control[1]);
     CloseHandle(deviceloop_handle);
+
+    bus_enumerate_hid_devices(&hidraw_vtbl, device_unload, NULL);
+    bus_enumerate_hid_devices(&lnxev_vtbl, device_unload, NULL);
 }
 
 NTSTATUS udev_driver_init(void)
diff --git a/dlls/winebus.sys/main.c b/dlls/winebus.sys/main.c
index 89ea65bba6..fc6b8be7f5 100644
--- a/dlls/winebus.sys/main.c
+++ b/dlls/winebus.sys/main.c
@@ -329,17 +329,21 @@ DEVICE_OBJECT *bus_find_hid_device(const platform_vtbl *vtbl, void *platform_dev
 
 DEVICE_OBJECT* bus_enumerate_hid_devices(const platform_vtbl *vtbl, enum_func function, void* context)
 {
-    struct pnp_device *dev;
+    struct pnp_device *dev, *dev_next;
     DEVICE_OBJECT *ret = NULL;
+    int cont;
 
     TRACE("(%p)\n", vtbl);
 
     EnterCriticalSection(&device_list_cs);
-    LIST_FOR_EACH_ENTRY(dev, &pnp_devset, struct pnp_device, entry)
+    LIST_FOR_EACH_ENTRY_SAFE(dev, dev_next, &pnp_devset, struct pnp_device, entry)
     {
         struct device_extension *ext = (struct device_extension *)dev->device->DeviceExtension;
         if (ext->vtbl != vtbl) continue;
-        if (function(dev->device, context) == 0)
+        LeaveCriticalSection(&device_list_cs);
+        cont = function(dev->device, context);
+        EnterCriticalSection(&device_list_cs);
+        if (!cont)
         {
             ret = dev->device;
             break;




More information about the wine-cvs mailing list