[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