[Spice-devel,spice-gtk,8/9] usb-device-manager: Windows: identify devices by vid:pid instead of bus.address

Submitted by Uri Lublin on March 25, 2013, 10:01 a.m.

Details

Message ID 1364205690-12784-9-git-send-email-uril@redhat.com
State New
Headers show

Not browsing as part of any series.

Commit Message

Uri Lublin March 25, 2013, 10:01 a.m.
rhbz#842816

Sometimes bus.address of a USB device changes upon WinUSB driver installation
for that device. This makes bus.address not a good identifier to use when
running on Windows machines.

Instead this patch makes usb-device-manager, when running on a Windows client,
identify devices by their vid:pid.

What changes were made in this patch (in addition to previous patches):
- vid:pid are asked from the udev.
- match functions that compare vid:pid were added
- when comparing devices vid:pid are used.

This also means that a scenario where two USB devices with the same vid:pid
on a Windows client is not supported. However there was a problem with this
scenario before as on Windows drivers for (specific) USB devices are
installed based on their vid:pid.
---
 gtk/usb-device-manager.c | 33 +++++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)

Patch hide | download patch | download mbox

diff --git a/gtk/usb-device-manager.c b/gtk/usb-device-manager.c
index a1399ee..7c59012 100644
--- a/gtk/usb-device-manager.c
+++ b/gtk/usb-device-manager.c
@@ -597,8 +597,13 @@  static gboolean spice_usb_device_manager_get_udev_bus_n_address(

     *bus = *address = 0;

+#ifndef G_OS_WIN32
     bus_str = g_udev_device_get_property(udev, "BUSNUM");
     address_str = g_udev_device_get_property(udev, "DEVNUM");
+#else /* Windows -- request vid:pid instead */
+    bus_str = g_udev_device_get_property(udev, "VID");
+    address_str = g_udev_device_get_property(udev, "PID");
+#endif
     if (bus_str)
         *bus = atoi(bus_str);
     if (address_str)
@@ -699,6 +704,7 @@  static void spice_usb_device_manager_auto_connect_cb(GObject      *gobject,
     spice_usb_device_unref(device);
 }

+#ifndef G_OS_WIN32 /* match functions for Linux -- match by bus.addr */
 static gboolean
 spice_usb_device_manager_device_match(SpiceUsbDevice *device,
                                       const int bus, const int address)
@@ -715,6 +721,28 @@  spice_usb_device_manager_libdev_match(libusb_device *libdev,
             libusb_get_device_address(libdev) == address);
 }

+#else /* Win32 -- match functions for Windows -- match by vid:pid */
+static gboolean
+spice_usb_device_manager_device_match(SpiceUsbDevice *device,
+                                      const int vid, const int pid)
+{
+    return (spice_usb_device_get_vid(device) == vid &&
+            spice_usb_device_get_pid(device) == pid);
+}
+
+static gboolean
+spice_usb_device_manager_libdev_match(libusb_device *libdev,
+                                      const int vid, const int pid)
+{
+    int vid2, pid2;
+
+    if (!spice_usb_device_manager_get_libdev_vid_pid(libdev, &vid2, &pid2)) {
+        return FALSE;
+    }
+    return (vid == vid2 && pid == pid2);
+}
+#endif /* of Win32 -- match functions */
+
 static SpiceUsbDevice*
 spice_usb_device_manager_find_device(SpiceUsbDeviceManager *self,
                                      const int bus, const int address)
@@ -1663,8 +1691,13 @@  spice_usb_device_manager_device_to_libdev(SpiceUsbDeviceManager *self,
     g_return_val_if_fail(self->priv != NULL, NULL);
     g_return_val_if_fail(self->priv->context != NULL, NULL);

+#ifndef G_OS_WIN32
     bus  = spice_usb_device_get_busnum(device);
     addr = spice_usb_device_get_devaddr(device);
+#else
+    bus  = spice_usb_device_get_vid(device);
+    addr = spice_usb_device_get_pid(device);
+#endif

     libusb_get_device_list(self->priv->context, &devlist);
     if (!devlist)