Re: [spice-gtk Win32 v4 06/17] Windows mingw: usb: Dynamically install a libusb driver for USB devices

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

On 07/05/2012 10:43 PM, Uri Lublin wrote:
- Added win-usb-driver-install.[ch]
- Added win-usb-clerk.h

Operation (on Windows, spice-gtk point of view):
- After some sanity checks, just before redir'ing a USB device
   a libusb driver needs to be installed (before libusb can open the device)
- A connection (NamedPipe) is established with usb-clerk, a libusb
   driver installation service, and a request for driver installation
   is sent.
- Installation status is asynchronously read from the pipe, and
   spice_usb_drv_install_finished() is called.
- Upon a successful intallation, usbredir continues.

Linux operation is not changed.
---
  gtk/Makefile.am              |    3 +
  gtk/usb-device-manager.c     |  150 +++++++++++++++-
  gtk/win-usb-clerk.h          |   35 ++++
  gtk/win-usb-driver-install.c |  387 ++++++++++++++++++++++++++++++++++++++++++
  gtk/win-usb-driver-install.h |   98 +++++++++++
  5 files changed, 663 insertions(+), 10 deletions(-)
  create mode 100644 gtk/win-usb-clerk.h
  create mode 100644 gtk/win-usb-driver-install.c
  create mode 100644 gtk/win-usb-driver-install.h


<snip>

@@ -635,7 +649,7 @@ static void spice_usb_device_manager_add_dev(SpiceUsbDeviceManager  *self,
              spice_usb_device_manager_connect_device_async(self,
                                     device, NULL,
                                     spice_usb_device_manager_auto_connect_cb,
-                                   g_object_ref(device));
+                                   device);
          }
      }



This seems wrong as spice_usb_device_manager_auto_connect_cb will still do a spice_usb_device_unref, so
we must ref it here to match, also this seems like something which belongs in a different patch...

@@ -700,6 +714,87 @@ static void spice_usb_device_manager_channel_connect_cb(
      g_object_unref(result);
  }

+#ifdef G_OS_WIN32
+
+typedef struct _UsbInstallCbInfo {
+    SpiceUsbDeviceManager *manager;
+    SpiceUsbDevice        *device;
+    SpiceWinUsbDriver     *installer;
+    GCancellable          *cancellable;
+    GAsyncReadyCallback   callback;
+    gpointer              user_data;
+} UsbInstallCbInfo;
+
+/**
+ * spice_usb_device_manager_drv_install_cb:
+ * @gobject: #SpiceWinUsbDriver in charge of installing the driver
+ * @res: #GAsyncResult of async win usb driver installation
+ * @user_data: #SpiceUsbDeviceManager requested the installation
+ *
+ * Called when an Windows libusb driver installation completed.
+ *
+ * If the driver installation was successful, continue with USB
+ * device redirection
+ */
+static void spice_usb_device_manager_drv_install_cb(GObject *gobject,
+                                                    GAsyncResult *res,
+                                                    gpointer user_data)
+{
+    SpiceUsbDeviceManager *self;
+    SpiceWinUsbDriver *installer;
+    gint status;
+    GError *err = NULL;
+    SpiceUsbDevice *device;
+    UsbInstallCbInfo *cbinfo;
+    GCancellable *cancellable;
+    GAsyncReadyCallback callback;
+
+    SPICE_DEBUG("Win USB driver Installation finished");
+
+    g_return_if_fail(user_data != NULL);
+
+    cbinfo = user_data;
+    self        = cbinfo->manager;
+    device      = cbinfo->device;
+    installer   = cbinfo->installer;
+    cancellable = cbinfo->cancellable;
+    callback    = cbinfo->callback;
+    user_data   = cbinfo->user_data;
+
+    g_free(cbinfo);
+
+    g_return_if_fail(SPICE_IS_USB_DEVICE_MANAGER(self));
+    g_return_if_fail(SPICE_IS_WIN_USB_DRIVER(installer));
+    g_return_if_fail(device!= NULL);
+
+    status = spice_win_usb_driver_install_finish(installer, res, &err);
+
+    g_object_unref(installer);
+
+    if (err) {
+        g_warning("win usb driver installation failed -- %s",
+                  err->message);
+        g_error_free(err);
+        spice_usb_device_unref(device);
+        return;
+    }
+
+    if (!status) {
+        g_warning("failed to install win usb driver (status=0)");
+        spice_usb_device_unref(device);

Can you please raise the appropriate error signal here, so that the user gets
an error dialog ?

+        return;
+    }
+
+    /* device is already ref'ed */
+    _spice_usb_device_manager_connect_device_async(self,
+                                                   device,
+                                                   cancellable,
+                                                   callback,
+                                                   user_data);
+
+}
+#endif
+
  /* ------------------------------------------------------------------ */
  /* private api                                                        */

@@ -873,6 +968,7 @@ gboolean spice_usb_device_manager_is_device_connected(SpiceUsbDeviceManager *sel
      return !!spice_usb_device_manager_get_channel_for_dev(self, device);
  }

+#ifdef USE_USBREDIR
  /**
   * spice_usb_device_manager_connect_device_async:
   * @manager: the #SpiceUsbDeviceManager manager
@@ -881,11 +977,12 @@ gboolean spice_usb_device_manager_is_device_connected(SpiceUsbDeviceManager *sel
   * @callback: a #GAsyncReadyCallback to call when the request is satisfied
   * @user_data: data to pass to callback
   */
-void spice_usb_device_manager_connect_device_async(SpiceUsbDeviceManager *self,
-                                             SpiceUsbDevice *device,
-                                             GCancellable *cancellable,
-                                             GAsyncReadyCallback callback,
-                                             gpointer user_data)
+static void
+_spice_usb_device_manager_connect_device_async(SpiceUsbDeviceManager *self,
+                                               SpiceUsbDevice *device,
+                                               GCancellable *cancellable,
+                                               GAsyncReadyCallback callback,
+                                               gpointer user_data)
  {
      GSimpleAsyncResult *result;

@@ -897,7 +994,6 @@ void spice_usb_device_manager_connect_device_async(SpiceUsbDeviceManager *self,
      result = g_simple_async_result_new(G_OBJECT(self), callback, user_data,
                                 spice_usb_device_manager_connect_device_async);

-#ifdef USE_USBREDIR
      SpiceUsbDeviceManagerPrivate *priv = self->priv;
      libusb_device *libdev;
      guint i;
@@ -924,17 +1020,51 @@ void spice_usb_device_manager_connect_device_async(SpiceUsbDeviceManager *self,
          libusb_unref_device(libdev);
          return;
      }
-#endif

      g_simple_async_result_set_error(result,
                              SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED,
                              _("No free USB channel"));
-#ifdef USE_USBREDIR
  done:
-#endif
      g_simple_async_result_complete_in_idle(result);
      g_object_unref(result);
  }
+#endif
+
+
+void spice_usb_device_manager_connect_device_async(SpiceUsbDeviceManager *self,
+                                             SpiceUsbDevice *device,
+                                             GCancellable *cancellable,
+                                             GAsyncReadyCallback callback,
+                                             gpointer user_data)
+{
+
+#ifdef USE_USBREDIR
+    device = spice_usb_device_ref(device);
+
+#ifdef G_OS_WIN32
+    SpiceWinUsbDriver *installer;
+    UsbInstallCbInfo *cbinfo;
+
+    installer = spice_win_usb_driver_new();
+    cbinfo = g_new0(UsbInstallCbInfo, 1);
+    cbinfo->manager     = self;
+    cbinfo->device      = device;
+    cbinfo->installer   = installer;
+    cbinfo->cancellable = cancellable;
+    cbinfo->callback    = callback;
+    cbinfo->user_data   = user_data;
+    spice_win_usb_driver_install(installer, device, NULL,
+                                 spice_usb_device_manager_drv_install_cb,
+                                 cbinfo);
+#else
+    _spice_usb_device_manager_connect_device_async(self,
+                                                   device,
+                                                   cancellable,
+                                                   callback,
+                                                   user_data);
+#endif
+#endif
+}

  gboolean spice_usb_device_manager_connect_device_finish(
      SpiceUsbDeviceManager *self, GAsyncResult *res, GError **err)

<snip>

Regards,

Hans
_______________________________________________
Spice-devel mailing list
Spice-devel@xxxxxxxxxxxxxxxxxxxxx
http://lists.freedesktop.org/mailman/listinfo/spice-devel


[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]     [Monitors]