[Spice-devel] [PATCH 5/5] usb-device-manager: Configure UsbDk hiding rules on auto-redirection

Christophe Fergeau cfergeau at redhat.com
Thu May 28 08:48:56 PDT 2015


On Thu, May 28, 2015 at 01:24:04PM +0300, Kirill Moizik wrote:
> From: Dmitry Fleytman <dmitry at daynix.com>
> 
> When spice run with auto redirection rule, hide rule should be applied to detach device from host stack 
> during device plug-in to avoid "new hardware wizard" pop up (in case there is no driver for redirected device on host)
> 
> Signed-off-by: Kirill Moizik <kirill at daynix.com>
> Signed-off-by: Dmitry Fleytman <dmitry at daynix.com>
> ---
>  gtk/usb-device-manager.c | 102 +++++++++++++++++++++++++++++++++++++++++++++--
>  1 file changed, 98 insertions(+), 4 deletions(-)
> 
> diff --git a/gtk/usb-device-manager.c b/gtk/usb-device-manager.c
> index 841e3a4..9786f16 100644
> --- a/gtk/usb-device-manager.c
> +++ b/gtk/usb-device-manager.c
> @@ -29,6 +29,10 @@
>  #include <errno.h>
>  #include <libusb.h>
>  
> +#ifdef USE_WINUSB
> +#include "usbdk_api.h"
> +#endif
> +
>  #if defined(USE_GUDEV)
>  #include <gudev/gudev.h>
>  #elif defined(G_OS_WIN32)
> @@ -124,6 +128,8 @@ struct _SpiceUsbDeviceManagerPrivate {
>  #endif
>  #ifdef USE_WINUSB
>      SpiceWinUsbDriver     *installer;
> +    usbdk_api_wrapper      usbdk_api;
> +    HANDLE                 usbdk_hider_handle;
>  #endif
>  #endif
>      GPtrArray *devices;
> @@ -246,13 +252,19 @@ static gboolean is_usbdk_driver_installed(void)
>  
>  static void spice_usb_device_manager_init(SpiceUsbDeviceManager *self)
>  {
> +    SpiceUsbDeviceManagerPrivate *priv =
> +        SPICE_USB_DEVICE_MANAGER_GET_PRIVATE(self);
> +
>  #ifdef USE_WINUSB
>      use_usbdk = is_usbdk_driver_installed();

Any reason why line was added before rather than in this commit?

> -#endif
>  
> -    SpiceUsbDeviceManagerPrivate *priv;
> +    if(use_usbdk) {
> +        if (usbdk_api_load(&priv->usbdk_api) == -1) {
> +            SPICE_DEBUG("Failed to load UsbDk API DLL");

missing use_usbdk = FALSE; in error cases.

> +        }
> +    }
> +#endif
>  
> -    priv = SPICE_USB_DEVICE_MANAGER_GET_PRIVATE(self);
>      self->priv = priv;
>  
>      priv->channels = g_ptr_array_new();
> @@ -411,6 +423,12 @@ static void spice_usb_device_manager_finalize(GObject *gobject)
>      g_free(priv->auto_connect_filter);
>      g_free(priv->redirect_on_connect);
>  
> +#ifdef USE_WINUSB
> +    if (use_usbdk) {
> +        usbdk_api_unload(&priv->usbdk_api);
> +    }
> +#endif

You probably need

    if(priv->usbdk_hider_handle != NULL) {
        priv->usbdk_api.ClearRules(priv->usbdk_hider_handle);
        priv->usbdk_api.CloseHiderHandle(priv->usbdk_hider_handle);
    }
?

> +
>      /* 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);
> @@ -428,7 +446,6 @@ static void spice_usb_device_manager_get_property(GObject     *gobject,
>  {
>      SpiceUsbDeviceManager *self = SPICE_USB_DEVICE_MANAGER(gobject);
>      SpiceUsbDeviceManagerPrivate *priv = self->priv;
> -

Unrelated white space change

>      switch (prop_id) {
>      case PROP_SESSION:
>          g_value_set_object(value, priv->session);
> @@ -448,6 +465,13 @@ static void spice_usb_device_manager_get_property(GObject     *gobject,
>      }
>  }
>  
> +#ifdef USE_WINUSB
> +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,
> @@ -462,6 +486,13 @@ static void spice_usb_device_manager_set_property(GObject       *gobject,
>          break;
>      case PROP_AUTO_CONNECT:
>          priv->auto_connect = g_value_get_boolean(value);
> +#ifdef USE_WINUSB
> +        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);
> @@ -1906,6 +1937,69 @@ guint8 spice_usb_device_get_state(SpiceUsbDevice *device)
>  
>      return info->state;
>  }
> +
> +static
> +void spice_usb_device_manager_set_rules(SpiceUsbDeviceManagerPrivate *priv)
> +{
> +    struct usbredirfilter_rule *rules;
> +    int r, count;
> +
> +    r = usbredirfilter_string_to_rules(priv->redirect_on_connect, ",", "|", &rules, &count);
> +    if (r) {
> +        SPICE_DEBUG("auto-conenct rules parsing failed with error %d", r);
> +        return;
> +    }
> +
> +    for (int i = 0; i < count; i++) {
> +        USB_DK_HIDE_RULE rule;
> +        rule.Hide = (uint64_t)rules[i].allow;
> +        rule.Class = (uint64_t)rules[i].device_class;
> +        rule.VID = (uint64_t)rules[i].vendor_id;
> +        rule.PID = (uint64_t)rules[i].product_id;
> +        rule.BCD = (uint64_t)rules[i].device_version_bcd;
> +        if(!priv->usbdk_api.AddRule(priv->usbdk_hider_handle, &rule)) {
> +            SPICE_DEBUG("UsbDk set hide rule API failed");
> +        }
> +    }
> +
> +    free(rules);
> +}
> +

This helper could go to usbdk_api_wrapper maybe:
usbdk_api_wrapper_set_rules(wrapper, handle, priv->redirect_on_connect) ?


> +static
> +void _usbdk_autoredir_enable(SpiceUsbDeviceManager *manager)
> +{
> +    if(!use_usbdk)
> +        return;
> +
> +    SpiceUsbDeviceManagerPrivate *priv = manager->priv;
> +
> +    if(priv->redirect_on_connect == NULL) {
> +        SPICE_DEBUG("No autoredirect rules, no hider setup needed");
> +        return;
> +    }
> +
> +    priv->usbdk_hider_handle = priv->usbdk_api.CreateHandle();
> +    if(priv->usbdk_hider_handle == NULL) {
> +        SPICE_DEBUG("Failed to instanciate UsbDk interface");
> +        return;
> +    }
> +
> +    spice_usb_device_manager_set_rules(priv);
> +}
> +
> +static
> +void _usbdk_autoredir_disable(SpiceUsbDeviceManager *manager)
> +{
> +    if(!use_usbdk)
> +        return;
> +
> +    SpiceUsbDeviceManagerPrivate *priv = manager->priv;
> +    if(priv->usbdk_hider_handle != NULL) {
> +        priv->usbdk_api.ClearRules(priv->usbdk_hider_handle);
> +        priv->usbdk_api.CloseHiderHandle(priv->usbdk_hider_handle);

priv->usbdk_hider_handle = NULL;

> +    }
> +}
> +
>  #endif
>  
>  static SpiceUsbDevice *spice_usb_device_ref(SpiceUsbDevice *device)
> -- 
> 2.1.0
> 
> _______________________________________________
> Spice-devel mailing list
> Spice-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/spice-devel
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.freedesktop.org/archives/spice-devel/attachments/20150528/d5aea397/attachment.sig>


More information about the Spice-devel mailing list