[Spice-devel] [spice-gtk 6/6] UsbDk: Add UsbDk as a default backend

Christophe Fergeau cfergeau at redhat.com
Fri Jun 12 09:21:19 PDT 2015


Backend is chosen dynamically, if UsbDk is not installed, then WinUsb/usbclerk
will be chosen.

Signed-off-by: Kirill Moizik <kirillm at daynix.com>
---
 src/usb-device-manager.c | 86 +++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 78 insertions(+), 8 deletions(-)

diff --git a/src/usb-device-manager.c b/src/usb-device-manager.c
index 0c67acc..987cb20 100644
--- a/src/usb-device-manager.c
+++ b/src/usb-device-manager.c
@@ -29,6 +29,10 @@
 #include <errno.h>
 #include <libusb.h>
 
+#ifdef G_OS_WIN32
+#include "usbdk_api.h"
+#endif
+
 #if defined(USE_GUDEV)
 #include <gudev/gudev.h>
 #elif defined(G_OS_WIN32)
@@ -121,6 +125,8 @@ struct _SpiceUsbDeviceManagerPrivate {
     libusb_hotplug_callback_handle hp_handle;
 #endif
 #ifdef G_OS_WIN32
+    usbdk_api_wrapper     *usbdk_api;
+    HANDLE                 usbdk_hider_handle;
     SpiceWinUsbDriver     *installer;
 #endif
     gboolean               use_usbclerk;
@@ -221,14 +227,21 @@ static void spice_usb_device_manager_init(SpiceUsbDeviceManager *self)
     priv = SPICE_USB_DEVICE_MANAGER_GET_PRIVATE(self);
     self->priv = priv;
 
+#ifdef G_OS_WIN32
+    priv->use_usbclerk = !usbdk_is_driver_installed();
+    if (!priv->use_usbclerk) {
+        if (usbdk_api_load(&priv->usbdk_api) != 0) {
+            priv->use_usbclerk = TRUE;
+            usbdk_api_unload(priv->usbdk_api);
+            SPICE_DEBUG("Failed to load UsbDk API DLL");
+        }
+    }
+#endif
     priv->channels = g_ptr_array_new();
 #ifdef USE_USBREDIR
     priv->devices  = g_ptr_array_new_with_free_func((GDestroyNotify)
                                                     spice_usb_device_unref);
 #endif
-#ifdef G_OS_WIN32
-    priv->use_usbclerk = TRUE;
-#endif
 }
 
 static gboolean spice_usb_device_manager_initable_init(GInitable  *initable,
@@ -366,6 +379,15 @@ static void spice_usb_device_manager_finalize(GObject *gobject)
     g_free(priv->auto_connect_filter);
     g_free(priv->redirect_on_connect);
 
+#ifdef G_OS_WIN32
+    if (!priv->use_usbclerk) {
+        if (priv->usbdk_hider_handle != NULL) {
+            usbdk_clear_hide_rules(priv->usbdk_api, priv->usbdk_hider_handle);
+            usbdk_close_hider_handle(priv->usbdk_api, priv->usbdk_hider_handle);
+        }
+        usbdk_api_unload(priv->usbdk_api);
+    }
+#endif
     /* Chain up to the parent class */
     if (G_OBJECT_CLASS(spice_usb_device_manager_parent_class)->finalize)
         G_OBJECT_CLASS(spice_usb_device_manager_parent_class)->finalize(gobject);
@@ -403,6 +425,13 @@ static void spice_usb_device_manager_get_property(GObject     *gobject,
     }
 }
 
+#ifdef G_OS_WIN32
+static
+void _usbdk_autoredir_enable(SpiceUsbDeviceManager *manager);
+static
+void _usbdk_autoredir_disable(SpiceUsbDeviceManager *manager);
+#endif
+
 static void spice_usb_device_manager_set_property(GObject       *gobject,
                                                   guint          prop_id,
                                                   const GValue  *value,
@@ -417,6 +446,15 @@ static void spice_usb_device_manager_set_property(GObject       *gobject,
         break;
     case PROP_AUTO_CONNECT:
         priv->auto_connect = g_value_get_boolean(value);
+#ifdef G_OS_WIN32
+        if (!priv->use_usbclerk) {
+            if (priv->auto_connect) {
+                _usbdk_autoredir_enable(self);
+            } else {
+                _usbdk_autoredir_disable(self);
+            }
+        }
+#endif
         break;
     case PROP_AUTO_CONNECT_FILTER: {
         const gchar *filter = g_value_get_string(value);
@@ -1806,6 +1844,36 @@ guint8 spice_usb_device_get_state(SpiceUsbDevice *device)
 
     return info->state;
 }
+static
+void _usbdk_autoredir_enable(SpiceUsbDeviceManager *manager)
+{
+    SpiceUsbDeviceManagerPrivate *priv = manager->priv;
+
+    if (priv->redirect_on_connect == NULL) {
+        SPICE_DEBUG("No autoredirect rules, no hider setup needed");
+        return;
+    }
+
+    priv->usbdk_hider_handle = usbdk_create_hider_handle(priv->usbdk_api);
+    if (priv->usbdk_hider_handle == NULL) {
+        SPICE_DEBUG("Failed to instanciate UsbDk interface");
+        return;
+    }
+    usbdk_api_set_hide_rules(priv->usbdk_api, priv->usbdk_hider_handle, priv->redirect_on_connect);
+}
+
+static
+void _usbdk_autoredir_disable(SpiceUsbDeviceManager *manager)
+{
+    SpiceUsbDeviceManagerPrivate *priv = manager->priv;
+    g_return_if_fail(!priv->use_usbclerk);
+
+    if (priv->usbdk_hider_handle != NULL) {
+        usbdk_clear_hide_rules(priv->usbdk_api, priv->usbdk_hider_handle);
+        usbdk_close_hider_handle(priv->usbdk_api, priv->usbdk_hider_handle);
+        priv->usbdk_hider_handle = NULL;
+    }
+}
 #endif
 
 static SpiceUsbDevice *spice_usb_device_ref(SpiceUsbDevice *device)
@@ -1853,19 +1921,21 @@ spice_usb_manager_device_equal_libdev(SpiceUsbDeviceManager *manager,
                                       SpiceUsbDevice *device,
                                       libusb_device  *libdev)
 {
-   int vid, pid;
+   int busnum, devaddr;
 
     if ((device == NULL) || (libdev == NULL))
        return FALSE;
 
     if (manager->priv->use_usbclerk) {
-        vid = spice_usb_device_get_vid(device);
-        pid = spice_usb_device_get_pid(device);
+        busnum = spice_usb_device_get_vid(device);
+        devaddr = spice_usb_device_get_pid(device);
     } else {
-        g_return_val_if_reached(FALSE);
+        busnum = spice_usb_device_get_busnum(device);
+        devaddr = spice_usb_device_get_devaddr(device);
     }
 
-    return spice_usb_device_manager_libdev_match(manager, libdev, vid, pid);
+    return spice_usb_device_manager_libdev_match(manager, libdev,
+                                                 busnum, devaddr);
 }
 #endif
 
-- 
2.4.3



More information about the Spice-devel mailing list