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