[Spice-devel] [PATCH spice-gtk 7/7] usbredir: Add awareness of host/guest side filtering

Hans de Goede hdegoede at redhat.com
Sat Feb 18 15:50:24 PST 2012


Signed-off-by: Hans de Goede <hdegoede at redhat.com>
---
 gtk/channel-usbredir-priv.h |    6 +++++
 gtk/channel-usbredir.c      |   19 +++++++++++++++--
 gtk/map-file                |    1 +
 gtk/usb-device-manager.c    |   44 +++++++++++++++++++++++++++++++++++++++---
 gtk/usb-device-manager.h    |    3 ++
 gtk/usb-device-widget.c     |    4 ++-
 6 files changed, 69 insertions(+), 8 deletions(-)

diff --git a/gtk/channel-usbredir-priv.h b/gtk/channel-usbredir-priv.h
index 10dd479..97035d5 100644
--- a/gtk/channel-usbredir-priv.h
+++ b/gtk/channel-usbredir-priv.h
@@ -22,6 +22,7 @@
 #define __SPICE_CLIENT_USBREDIR_CHANNEL_PRIV_H__
 
 #include <libusb.h>
+#include <usbredirfilter.h>
 #include "spice-client.h"
 
 G_BEGIN_DECLS
@@ -49,6 +50,11 @@ void spice_usbredir_channel_disconnect_device(SpiceUsbredirChannel *channel);
 
 libusb_device *spice_usbredir_channel_get_device(SpiceUsbredirChannel *channel);
 
+void spice_usbredir_channel_get_guest_filter(
+                               SpiceUsbredirChannel         *channel,
+                               struct usbredirfilter_rule  **rules_ret,
+                               int                          *rules_count_ret);
+
 G_END_DECLS
 
 #endif /* __SPICE_CLIENT_USBREDIR_CHANNEL_PRIV_H__ */
diff --git a/gtk/channel-usbredir.c b/gtk/channel-usbredir.c
index 3b72372..784c4ee 100644
--- a/gtk/channel-usbredir.c
+++ b/gtk/channel-usbredir.c
@@ -437,6 +437,22 @@ libusb_device *spice_usbredir_channel_get_device(SpiceUsbredirChannel *channel)
     return channel->priv->device;
 }
 
+G_GNUC_INTERNAL
+void spice_usbredir_channel_get_guest_filter(
+                               SpiceUsbredirChannel         *channel,
+                               struct usbredirfilter_rule  **rules_ret,
+                               int                          *rules_count_ret)
+{
+    SpiceUsbredirChannelPrivate *priv = channel->priv;
+
+    g_return_if_fail(priv->host != NULL);
+
+    usbredirhost_get_guest_filter(priv->host, rules_ret, rules_count_ret);
+}
+
+/* ------------------------------------------------------------------ */
+/* callbacks (any context)                                            */
+
 /* Note that this function must be re-entrant safe, as it can get called
    from both the main thread as well as from the usb event handling thread */
 static void usbredir_write_flush_callback(void *user_data)
@@ -451,9 +467,6 @@ static void usbredir_write_flush_callback(void *user_data)
     usbredirhost_write_guest_data(priv->host);
 }
 
-/* ------------------------------------------------------------------ */
-/* callbacks (any context)                                            */
-
 static void usbredir_log(void *user_data, int level, const char *msg)
 {
     SpiceUsbredirChannel *channel = user_data;
diff --git a/gtk/map-file b/gtk/map-file
index 320dae3..5fc73fe 100644
--- a/gtk/map-file
+++ b/gtk/map-file
@@ -87,6 +87,7 @@ spice_usb_device_get_description;
 spice_usb_device_get_type;
 spice_usb_device_manager_connect_device_async;
 spice_usb_device_manager_connect_device_finish;
+spice_usb_device_manager_device_ok_with_guest;
 spice_usb_device_manager_disconnect_device;
 spice_usb_device_manager_get;
 spice_usb_device_manager_get_devices;
diff --git a/gtk/usb-device-manager.c b/gtk/usb-device-manager.c
index cc67131..03ec775 100644
--- a/gtk/usb-device-manager.c
+++ b/gtk/usb-device-manager.c
@@ -592,10 +592,17 @@ static void spice_usb_device_manager_add_dev(SpiceUsbDeviceManager  *self,
     g_ptr_array_add(priv->devices, device);
 
     if (priv->auto_connect) {
-        if (usbredirhost_check_device_filter(
-                priv->auto_conn_filter_rules,
-                priv->auto_conn_filter_rules_count,
-                device, 0) == 0)
+        int guest_ok, auto_ok;
+
+        guest_ok = spice_usb_device_manager_device_ok_with_guest(
+                                            self, (SpiceUsbDevice *)device);
+
+        auto_ok = usbredirhost_check_device_filter(
+                            priv->auto_conn_filter_rules,
+                            priv->auto_conn_filter_rules_count,
+                            device, 0) == 0;
+
+        if (guest_ok && auto_ok)
             spice_usb_device_manager_connect_device_async(self,
                                    (SpiceUsbDevice *)device, NULL,
                                    spice_usb_device_manager_auto_connect_cb,
@@ -916,6 +923,34 @@ void spice_usb_device_manager_disconnect_device(SpiceUsbDeviceManager *self,
 #endif
 }
 
+int spice_usb_device_manager_device_ok_with_guest(SpiceUsbDeviceManager *self,
+                                                  SpiceUsbDevice *device)
+{
+#ifdef USE_USBREDIR
+    struct usbredirfilter_rule *guest_filter_rules = NULL;
+    SpiceUsbDeviceManagerPrivate *priv = self->priv;
+    int guest_filter_rules_count;
+
+    if (!priv->channels->len)
+        return 1; /* No way to check, report ok. */
+
+    /* We assume all channels have the same filter, so we just take the
+       filter from the first channel */
+    spice_usbredir_channel_get_guest_filter(
+        g_ptr_array_index(priv->channels, 0),
+        &guest_filter_rules, &guest_filter_rules_count);
+
+    if (!guest_filter_rules)
+        return 1; /* No rules means all devices are ok */
+
+    return usbredirhost_check_device_filter(
+                            guest_filter_rules, guest_filter_rules_count,
+                            (libusb_device *)device, 0) == 0;
+#else
+    return 1;
+#endif
+}
+
 /**
  * spice_usb_device_get_description:
  * @device: #SpiceUsbDevice to get the description of
@@ -974,3 +1009,4 @@ gchar *spice_usb_device_get_description(SpiceUsbDevice *_device, const gchar *fo
     return NULL;
 #endif
 }
+
diff --git a/gtk/usb-device-manager.h b/gtk/usb-device-manager.h
index eabfd00..4a5f435 100644
--- a/gtk/usb-device-manager.h
+++ b/gtk/usb-device-manager.h
@@ -110,6 +110,9 @@ gboolean spice_usb_device_manager_connect_device_finish(
 void spice_usb_device_manager_disconnect_device(SpiceUsbDeviceManager *manager,
                                                 SpiceUsbDevice *device);
 
+int spice_usb_device_manager_device_ok_with_guest(SpiceUsbDeviceManager *self,
+                                                  SpiceUsbDevice *device);
+
 G_END_DECLS
 
 #endif /* __SPICE_USB_DEVICE_MANAGER_H__ */
diff --git a/gtk/usb-device-widget.c b/gtk/usb-device-widget.c
index 4b504ca..7cb13e1 100644
--- a/gtk/usb-device-widget.c
+++ b/gtk/usb-device-widget.c
@@ -366,10 +366,12 @@ static void device_added_cb(SpiceUsbDeviceManager *manager,
                                             priv->device_format_string);
 
     check = gtk_check_button_new_with_label(desc);
-
     if (spice_usb_device_manager_is_device_connected(priv->manager,
                                                      device))
         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), TRUE);
+    if (!spice_usb_device_manager_device_ok_with_guest(priv->manager,
+                                                       device))
+        gtk_widget_set_sensitive(check, FALSE);
 
     g_object_set_data_full(
             G_OBJECT(check), "usb-device",
-- 
1.7.7.5



More information about the Spice-devel mailing list