Rémi Bernon : winebus.sys: Fix duplicate lnxev / hidraw device lookup.

Alexandre Julliard julliard at winehq.org
Fri Aug 13 14:44:14 CDT 2021


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

Author: Rémi Bernon <rbernon at codeweavers.com>
Date:   Fri Aug 13 09:46:16 2021 +0200

winebus.sys: Fix duplicate lnxev / hidraw device lookup.

The comparison result was wrong, and the device syspath always differs
anyway between two different subsystems. We need to compare the parent
device syspath.

The input subsystem devices also needs to be deduplicated between eventX
devices and jsX devices.

Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/winebus.sys/bus_udev.c | 48 +++++++++++++++++++++++++++------------------
 1 file changed, 29 insertions(+), 19 deletions(-)

diff --git a/dlls/winebus.sys/bus_udev.c b/dlls/winebus.sys/bus_udev.c
index b9466b0178b..887996daf49 100644
--- a/dlls/winebus.sys/bus_udev.c
+++ b/dlls/winebus.sys/bus_udev.c
@@ -976,9 +976,23 @@ static const platform_vtbl lnxev_vtbl = {
 };
 #endif
 
-static int check_same_device(DEVICE_OBJECT *device, void* context)
+static const char *get_device_syspath(struct udev_device *dev)
 {
-    return !compare_platform_device(device, context);
+    struct udev_device *parent;
+
+    if ((parent = udev_device_get_parent_with_subsystem_devtype(dev, "hid", NULL)))
+        return udev_device_get_syspath(parent);
+
+    if ((parent = udev_device_get_parent_with_subsystem_devtype(dev, "usb", "usb_device")))
+        return udev_device_get_syspath(parent);
+
+    return "";
+}
+
+static int check_device_syspath(DEVICE_OBJECT *device, void* context)
+{
+    struct platform_private *private = impl_from_DEVICE_OBJECT(device);
+    return strcmp(get_device_syspath(private->udev_device), context);
 }
 
 static int parse_uevent_info(const char *uevent, DWORD *vendor_id,
@@ -1078,28 +1092,24 @@ static void try_add_device(struct udev_device *dev)
         return;
     }
 
+    TRACE("udev %s syspath %s\n", debugstr_a(devnode), udev_device_get_syspath(dev));
+
+#ifdef HAS_PROPER_INPUT_HEADER
+    device = bus_enumerate_hid_devices(&lnxev_vtbl, check_device_syspath, (void *)get_device_syspath(dev));
+    if (!device) device = bus_enumerate_hid_devices(&hidraw_vtbl, check_device_syspath, (void *)get_device_syspath(dev));
+    if (device)
+    {
+        TRACE("duplicate device found, not adding the new one\n");
+        close(fd);
+        return;
+    }
+#endif
+
     subsystem = udev_device_get_subsystem(dev);
     hiddev = udev_device_get_parent_with_subsystem_devtype(dev, "hid", NULL);
     if (hiddev)
     {
         const char *bcdDevice = NULL;
-#ifdef HAS_PROPER_INPUT_HEADER
-        const platform_vtbl *other_vtbl = NULL;
-        DEVICE_OBJECT *dup = NULL;
-        if (strcmp(subsystem, "hidraw") == 0)
-            other_vtbl = &lnxev_vtbl;
-        else if (strcmp(subsystem, "input") == 0)
-            other_vtbl = &hidraw_vtbl;
-
-        if (other_vtbl)
-            dup = bus_enumerate_hid_devices(other_vtbl, check_same_device, dev);
-        if (dup)
-        {
-            TRACE("Duplicate cross bus device (%p) found, not adding the new one\n", dup);
-            close(fd);
-            return;
-        }
-#endif
         parse_uevent_info(udev_device_get_sysattr_value(hiddev, "uevent"),
                           &vid, &pid, &input, &serial);
         if (serial == NULL)




More information about the wine-cvs mailing list