From: Kirill Moizik <kmoizik@xxxxxxxxxx> Backend is chosen dynamically, if UsbDk is not installed, then WinUsb/usbclerk will be chosen. Signed-off-by: Kirill Moizik <kirillm@xxxxxxxxxx> --- 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.1.0 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/spice-devel