[Spice-commits] gtk/usb-device-manager.c gtk/win-usb-clerk.h gtk/win-usb-driver-install.c

Uri Lublin uril at kemper.freedesktop.org
Thu Oct 25 05:28:46 PDT 2012


 gtk/usb-device-manager.c     |   19 ++++++++++++--
 gtk/win-usb-clerk.h          |    3 +-
 gtk/win-usb-driver-install.c |   56 +++++++++++++++++++++++++------------------
 3 files changed, 51 insertions(+), 27 deletions(-)

New commits:
commit 759bdc1db02311d2099b22ee1ef298abd3dfc2f3
Author: Uri Lublin <uril at redhat.com>
Date:   Wed Oct 17 19:28:11 2012 +0200

    win-usb-driver: use usbclerk new message: USB_CLERK_DRIVER_SESSION_INSTALL
    
    With this message usbclerk keeps a list of devices for which
    a libusb driver was installed (per connection).
    When a spice-gtk client exits, the connection is closed, and
    usbclerk uninstalls the driver for all devices in the list.
    
    That means we need to keep the connection open, so added
    the win-usb driver installer to usb-device-manager's priv.
    
    This prevents the case were the user exits the client, while a usb
    device is connected to the guest, and can not use the device from
    the client machine.
    
    rhbz#869542

diff --git a/gtk/usb-device-manager.c b/gtk/usb-device-manager.c
index 3684485..3f4c272 100644
--- a/gtk/usb-device-manager.c
+++ b/gtk/usb-device-manager.c
@@ -109,6 +109,9 @@ struct _SpiceUsbDeviceManagerPrivate {
     struct usbredirfilter_rule *redirect_on_connect_rules;
     int auto_conn_filter_rules_count;
     int redirect_on_connect_rules_count;
+#ifdef G_OS_WIN32
+    SpiceWinUsbDriver     *installer;
+#endif
 #endif
     GPtrArray *devices;
     GPtrArray *channels;
@@ -302,6 +305,10 @@ static void spice_usb_device_manager_finalize(GObject *gobject)
     if (priv->event_thread)
         g_thread_join(priv->event_thread);
     free(priv->auto_conn_filter_rules);
+#ifdef G_OS_WIN32
+    if (priv->installer)
+        g_object_unref(priv->installer);
+#endif
 #endif
 
     g_free(priv->auto_connect_filter);
@@ -876,7 +883,6 @@ static void spice_usb_device_manager_drv_install_cb(GObject *gobject,
 
     status = spice_win_usb_driver_install_finish(installer, res, &err);
 
-    g_object_unref(installer);
     spice_usb_device_unref(device);
 
     spice_usb_device_set_state(device, SPICE_USB_DEVICE_STATE_NONE);
@@ -1209,7 +1215,10 @@ void spice_usb_device_manager_connect_device_async(SpiceUsbDeviceManager *self,
     UsbInstallCbInfo *cbinfo;
 
     spice_usb_device_set_state(device, SPICE_USB_DEVICE_STATE_INSTALLING);
-    installer = spice_win_usb_driver_new();
+    if (! self->priv->installer) {
+        self->priv->installer = spice_win_usb_driver_new();
+    }
+    installer = self->priv->installer;
     cbinfo = g_new0(UsbInstallCbInfo, 1);
     cbinfo->manager     = self;
     cbinfo->device      = spice_usb_device_ref(device);
@@ -1273,9 +1282,13 @@ void spice_usb_device_manager_disconnect_device(SpiceUsbDeviceManager *self,
     UsbInstallCbInfo *cbinfo;
 
     g_warn_if_fail(device != NULL);
+    g_warn_if_fail(self->priv->installer != NULL);
 
     spice_usb_device_set_state(device, SPICE_USB_DEVICE_STATE_UNINSTALLING);
-    installer = spice_win_usb_driver_new();
+    if (! self->priv->installer) {
+        self->priv->installer = spice_win_usb_driver_new();
+    }
+    installer = self->priv->installer;
     cbinfo = g_new0(UsbInstallCbInfo, 1);
     cbinfo->manager     = self;
     cbinfo->device      = spice_usb_device_ref(device);
diff --git a/gtk/win-usb-clerk.h b/gtk/win-usb-clerk.h
index 5b1e3cf..24da3b4 100644
--- a/gtk/win-usb-clerk.h
+++ b/gtk/win-usb-clerk.h
@@ -5,7 +5,7 @@
 
 #define USB_CLERK_PIPE_NAME     TEXT("\\\\.\\pipe\\usbclerkpipe")
 #define USB_CLERK_MAGIC         0xDADA
-#define USB_CLERK_VERSION       0x0002
+#define USB_CLERK_VERSION       0x0003
 
 typedef struct USBClerkHeader {
     UINT16 magic;
@@ -18,6 +18,7 @@ enum {
     USB_CLERK_DRIVER_INSTALL = 1,
     USB_CLERK_DRIVER_REMOVE,
     USB_CLERK_REPLY,
+    USB_CLERK_DRIVER_SESSION_INSTALL,
     USB_CLERK_END_MESSAGE,
 };
 
diff --git a/gtk/win-usb-driver-install.c b/gtk/win-usb-driver-install.c
index 02d20d6..1d68296 100644
--- a/gtk/win-usb-driver-install.c
+++ b/gtk/win-usb-driver-install.c
@@ -113,7 +113,6 @@ void win_usb_driver_handle_reply_cb(GObject *gobject,
 
     g_warn_if_fail(g_input_stream_close(istream, NULL, NULL));
     g_clear_object(&istream);
-    spice_win_usb_driver_close(self);
 
     if (err) {
         g_warning("failed to read reply from usbclerk (%s)", err->message);
@@ -149,7 +148,10 @@ void win_usb_driver_handle_reply_cb(GObject *gobject,
     if (priv->reply.hdr.version != USB_CLERK_VERSION) {
         g_warning("usbclerk version mismatch: mine=0x%04x  server=0x%04x",
                   USB_CLERK_VERSION, priv->reply.hdr.version);
-        /* For now just warn, do not fail */
+        g_simple_async_result_set_error(priv->result,
+                                        SPICE_WIN_USB_DRIVER_ERROR,
+                                        SPICE_WIN_USB_DRIVER_ERROR_MESSAGE,
+                                        "usbclerk version mismatch");
     }
 
     if (priv->reply.hdr.type != USB_CLERK_REPLY) {
@@ -265,30 +267,39 @@ void spice_win_usb_driver_op(SpiceWinUsbDriver *self,
 
     priv = self->priv;
 
-    g_return_if_fail(priv->result == NULL);
-
     result = g_simple_async_result_new(G_OBJECT(self), callback, user_data,
                                        spice_win_usb_driver_op);
 
+    if (priv->result) { /* allow one install/uninstall request at a time */
+        g_warning("Another request exists -- try later");
+        g_simple_async_result_set_error(result,
+                  SPICE_WIN_USB_DRIVER_ERROR, SPICE_WIN_USB_DRIVER_ERROR_FAILED,
+                  "Another request exists -- try later");
+        goto failed_request;
+    }
+
+
     vid = spice_usb_device_get_vid(device);
     pid = spice_usb_device_get_pid(device);
 
-    SPICE_DEBUG("win-usb-driver-install: connecting to usbclerk named pipe");
-    priv->handle = CreateFile(USB_CLERK_PIPE_NAME,
-                              GENERIC_READ | GENERIC_WRITE,
-                              0, NULL,
-                              OPEN_EXISTING,
-                              FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
-                              NULL);
-    if (priv->handle == INVALID_HANDLE_VALUE) {
-        DWORD errval  = GetLastError();
-        gchar *errstr = g_win32_error_message(errval);
-        g_warning("failed to create a named pipe to usbclerk (%ld) %s",
-                  errval,errstr);
-        g_simple_async_result_set_error(result,
-                  G_IO_ERROR, G_IO_ERROR_FAILED,
-                  "Failed to create named pipe (%ld) %s", errval, errstr);
-        goto failed_request;
+    if (! priv->handle ) {
+        SPICE_DEBUG("win-usb-driver-install: connecting to usbclerk named pipe");
+        priv->handle = CreateFile(USB_CLERK_PIPE_NAME,
+                                  GENERIC_READ | GENERIC_WRITE,
+                                  0, NULL,
+                                  OPEN_EXISTING,
+                                  FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
+                                  NULL);
+        if (priv->handle == INVALID_HANDLE_VALUE) {
+            DWORD errval  = GetLastError();
+            gchar *errstr = g_win32_error_message(errval);
+            g_warning("failed to create a named pipe to usbclerk (%ld) %s",
+                      errval,errstr);
+            g_simple_async_result_set_error(result,
+                      G_IO_ERROR, G_IO_ERROR_FAILED,
+                      "Failed to create named pipe (%ld) %s", errval, errstr);
+            goto failed_request;
+        }
     }
 
     if (!spice_win_usb_driver_send_request(self, op_type,
@@ -308,7 +319,6 @@ void spice_win_usb_driver_op(SpiceWinUsbDriver *self,
     return;
 
  failed_request:
-    spice_win_usb_driver_close(self);
     g_simple_async_result_complete_in_idle(result);
     g_clear_object(&result);
 }
@@ -333,8 +343,8 @@ void spice_win_usb_driver_install(SpiceWinUsbDriver *self,
 {
     SPICE_DEBUG("Win usb driver installation started");
 
-    spice_win_usb_driver_op(self, device, USB_CLERK_DRIVER_INSTALL, cancellable,
-                            callback, user_data);
+    spice_win_usb_driver_op(self, device, USB_CLERK_DRIVER_SESSION_INSTALL,
+                            cancellable, callback, user_data);
 }
 
 G_GNUC_INTERNAL


More information about the Spice-commits mailing list