[Spice-devel] [PATCH spice-gtk 10/10] usbredir: Give devices a user friendly description

Hans de Goede hdegoede at redhat.com
Mon Dec 19 03:24:43 PST 2011


Before this patch devices were described like this to the user:
USB device at 2-14
After this patch the description is:
SanDisk Cruzer Blade [0781:5567] at 2-14

Signed-off-by: Hans de Goede <hdegoede at redhat.com>
---
 gtk/usb-device-manager.c |   64 ++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 62 insertions(+), 2 deletions(-)

diff --git a/gtk/usb-device-manager.c b/gtk/usb-device-manager.c
index 69ba108..05d2350 100644
--- a/gtk/usb-device-manager.c
+++ b/gtk/usb-device-manager.c
@@ -26,6 +26,12 @@
 #include "glib-compat.h"
 
 #ifdef USE_USBREDIR
+#ifdef __linux__
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#endif
 #include <libusb.h>
 #include <gudev/gudev.h>
 #include "channel-usbredir-priv.h"
@@ -422,6 +428,38 @@ const char *spice_usb_device_manager_libusb_strerror(enum libusb_error error_cod
     }
     return "Unknown error";
 }
+
+#ifdef __linux__
+/* <Sigh> libusb does not allow getting the manufacturer and product strings
+   without opening the device, so grab them directly from sysfs */
+static void spice_usb_device_manager_get_sysfs_attribute(int bus, int address,
+    const char *attribute, char *buf, int buf_size)
+{
+    struct stat stat_buf;
+    char filename[256];
+    FILE *f;
+
+    buf[0] = '\0';
+
+    snprintf(filename, sizeof(filename), "/dev/bus/usb/%03d/%03d",
+             bus, address);
+    if (stat(filename, &stat_buf) != 0)
+        return;
+
+    snprintf(filename, sizeof(filename), "/sys/dev/char/%d:%d/%s",
+             major(stat_buf.st_rdev), minor(stat_buf.st_rdev), attribute);
+    f = fopen(filename, "r");
+    if (!f)
+        return;
+
+    if (fgets(buf, buf_size, f))
+        buf[strlen(buf) - 1] = '\0';
+    else
+        buf[0] = '\0';
+
+    fclose(f);
+}
+#endif
 #endif
 
 /* ------------------------------------------------------------------ */
@@ -843,14 +881,36 @@ gchar *spice_usb_device_get_description(SpiceUsbDevice *_device)
 {
 #ifdef USE_USBREDIR
     libusb_device *device = (libusb_device *)_device;
-    int bus, address;
+    struct libusb_device_descriptor desc;
+    int rc, bus, address;
+    /* USB descriptor strings are max 128 bytes */
+    char manufacturer[128] = "";
+    char product[128] = "";
 
     g_return_val_if_fail(device != NULL, NULL);
 
     bus     = libusb_get_bus_number(device);
     address = libusb_get_device_address(device);
 
-    return g_strdup_printf("USB device at %d-%d", bus, address);
+#if __linux__
+    spice_usb_device_manager_get_sysfs_attribute(bus, address, "manufacturer",
+                                           manufacturer, sizeof(manufacturer));
+    spice_usb_device_manager_get_sysfs_attribute(bus, address, "product",
+                                                 product, sizeof(product));
+#endif
+    if (!manufacturer[0])
+        strcpy(manufacturer, "USB");
+    if (!product[0])
+        strcpy(product, "Device");
+
+    rc = libusb_get_device_descriptor(device, &desc);
+    if (rc != LIBUSB_SUCCESS) {
+        return g_strdup_printf("%s %s at %d-%d", manufacturer, product,
+                               bus, address);
+    }
+
+    return g_strdup_printf("%s %s [%04x:%04x] at %d-%d", manufacturer, product,
+                           desc.idVendor, desc.idProduct, bus, address);
 #else
     return NULL;
 #endif
-- 
1.7.7.4



More information about the Spice-devel mailing list