From: Pavel Gurvich <pavel@xxxxxxxxxx> introducing use_usbdk global variable providing functionality of dynamic backend switching Signed-off-by: Pavel Gurvich <pavel@xxxxxxxxxx> Signed-off-by: Dmitry Fleytman <dmitry@xxxxxxxxxx> --- gtk/usb-device-manager.c | 264 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 188 insertions(+), 76 deletions(-) diff --git a/gtk/usb-device-manager.c b/gtk/usb-device-manager.c index 7739337..841e3a4 100644 --- a/gtk/usb-device-manager.c +++ b/gtk/usb-device-manager.c @@ -182,6 +182,7 @@ static SpiceUsbDevice *spice_usb_device_ref(SpiceUsbDevice *device); static void spice_usb_device_unref(SpiceUsbDevice *device); #ifdef USE_WINUSB +gboolean use_usbdk; static guint8 spice_usb_device_get_state(SpiceUsbDevice *device); static void spice_usb_device_set_state(SpiceUsbDevice *device, guint8 s); #endif @@ -222,8 +223,33 @@ static guint signals[LAST_SIGNAL] = { 0, }; G_DEFINE_TYPE_WITH_CODE(SpiceUsbDeviceManager, spice_usb_device_manager, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, spice_usb_device_manager_initable_iface_init)); +#ifdef USE_WINUSB +static gboolean is_usbdk_driver_installed(void) +{ + gboolean usbdk_installed = FALSE; + + SC_HANDLE managerHandle = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT); + if (managerHandle) + { + SC_HANDLE serviceHandle = OpenService(managerHandle, TEXT("UsbDk"), GENERIC_READ); + if (serviceHandle) + { + SPICE_DEBUG("UsbDk driver is installed."); + usbdk_installed = TRUE; + CloseServiceHandle(serviceHandle); + } + CloseServiceHandle(managerHandle); + } + return usbdk_installed; +} +#endif + static void spice_usb_device_manager_init(SpiceUsbDeviceManager *self) { +#ifdef USE_WINUSB + use_usbdk = is_usbdk_driver_installed(); +#endif + SpiceUsbDeviceManagerPrivate *priv; priv = SPICE_USB_DEVICE_MANAGER_GET_PRIVATE(self); @@ -374,8 +400,11 @@ static void spice_usb_device_manager_finalize(GObject *gobject) free(priv->auto_conn_filter_rules); free(priv->redirect_on_connect_rules); #ifdef USE_WINUSB - if (priv->installer) - g_object_unref(priv->installer); + if(! use_usbdk) + { + if (priv->installer) + g_object_unref(priv->installer); + } #endif #endif @@ -672,8 +701,16 @@ static gboolean spice_usb_device_manager_get_udev_bus_n_address( bus_str = g_udev_device_get_property(udev, "BUSNUM"); address_str = g_udev_device_get_property(udev, "DEVNUM"); #else /* WinUSB -- request vid:pid instead */ - bus_str = g_udev_device_get_property(udev, "VID"); - address_str = g_udev_device_get_property(udev, "PID"); + if(! use_usbdk) + { + bus_str = g_udev_device_get_property(udev, "VID"); + address_str = g_udev_device_get_property(udev, "PID"); + } + else + { + bus_str = g_udev_device_get_property(udev, "BUSNUM"); + address_str = g_udev_device_get_property(udev, "DEVNUM"); + } #endif if (bus_str) *bus = atoi(bus_str); @@ -835,20 +872,36 @@ static gboolean spice_usb_device_manager_device_match(SpiceUsbDevice *device, const int vid, const int pid) { - return (spice_usb_device_get_vid(device) == vid && + if(! use_usbdk) + { + return (spice_usb_device_get_vid(device) == vid && spice_usb_device_get_pid(device) == pid); + } + else + { + return (spice_usb_device_get_busnum(device) == vid && + spice_usb_device_get_devaddr(device) == pid); + } } static gboolean spice_usb_device_manager_libdev_match(libusb_device *libdev, const int vid, const int pid) { - int vid2, pid2; + if(! use_usbdk) + { + int vid2, pid2; - if (!spice_usb_device_manager_get_libdev_vid_pid(libdev, &vid2, &pid2)) { - return FALSE; + if (!spice_usb_device_manager_get_libdev_vid_pid(libdev, &vid2, &pid2)) { + return FALSE; + } + return (vid == vid2 && pid == pid2); + } + else + { + return (libusb_get_bus_number(libdev) == vid && + libusb_get_device_address(libdev) == pid); } - return (vid == vid2 && pid == pid2); } #endif /* of Win32 -- match functions */ @@ -926,12 +979,15 @@ static void spice_usb_device_manager_remove_dev(SpiceUsbDeviceManager *self, } #ifdef USE_WINUSB - const guint8 state = spice_usb_device_get_state(device); - if ((state == SPICE_USB_DEVICE_STATE_INSTALLING) || - (state == SPICE_USB_DEVICE_STATE_UNINSTALLING)) { - SPICE_DEBUG("skipping " DEV_ID_FMT ". It is un/installing its driver", - bus, address); - return; + if(! use_usbdk) + { + const guint8 state = spice_usb_device_get_state(device); + if ((state == SPICE_USB_DEVICE_STATE_INSTALLING) || + (state == SPICE_USB_DEVICE_STATE_UNINSTALLING)) { + SPICE_DEBUG("skipping " DEV_ID_FMT ". It is un/installing its driver", + bus, address); + return; + } } #endif @@ -1109,6 +1165,11 @@ static void spice_usb_device_manager_drv_install_cb(GObject *gobject, GAsyncResult *res, gpointer user_data) { + if (use_usbdk) + { + return; + } + SpiceUsbDeviceManager *self; SpiceWinUsbDriver *installer; gint status; @@ -1484,33 +1545,45 @@ done: void spice_usb_device_manager_connect_device_async(SpiceUsbDeviceManager *self, - SpiceUsbDevice *device, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) + SpiceUsbDevice *device, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) { #if defined(USE_USBREDIR) && defined(USE_WINUSB) - SpiceWinUsbDriver *installer; - UsbInstallCbInfo *cbinfo; - spice_usb_device_set_state(device, SPICE_USB_DEVICE_STATE_INSTALLING); - if (! self->priv->installer) { - self->priv->installer = spice_win_usb_driver_new(); + if (! use_usbdk) + { + SpiceWinUsbDriver *installer; + UsbInstallCbInfo *cbinfo; + + spice_usb_device_set_state(device, SPICE_USB_DEVICE_STATE_INSTALLING); + 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); + cbinfo->installer = installer; + cbinfo->cancellable = cancellable; + cbinfo->callback = callback; + cbinfo->user_data = user_data; + cbinfo->is_install = TRUE; + + spice_win_usb_driver_install(installer, device, cancellable, + spice_usb_device_manager_drv_install_cb, + cbinfo); + } + else + { + _spice_usb_device_manager_connect_device_async(self, + device, + cancellable, + callback, + user_data); } - installer = self->priv->installer; - cbinfo = g_new0(UsbInstallCbInfo, 1); - cbinfo->manager = self; - cbinfo->device = spice_usb_device_ref(device); - cbinfo->installer = installer; - cbinfo->cancellable = cancellable; - cbinfo->callback = callback; - cbinfo->user_data = user_data; - cbinfo->is_install = TRUE; - - spice_win_usb_driver_install(installer, device, cancellable, - spice_usb_device_manager_drv_install_cb, - cbinfo); #else _spice_usb_device_manager_connect_device_async(self, device, @@ -1558,36 +1631,39 @@ void spice_usb_device_manager_disconnect_device(SpiceUsbDeviceManager *self, spice_usbredir_channel_disconnect_device(channel); #ifdef USE_WINUSB - SpiceWinUsbDriver *installer; - UsbInstallCbInfo *cbinfo; - guint8 state; - - g_warn_if_fail(device != NULL); - g_warn_if_fail(self->priv->installer != NULL); - - state = spice_usb_device_get_state(device); - if ((state != SPICE_USB_DEVICE_STATE_INSTALLED) && - (state != SPICE_USB_DEVICE_STATE_CONNECTED)) { - return; - } + if (! use_usbdk) + { + SpiceWinUsbDriver *installer; + UsbInstallCbInfo *cbinfo; + guint8 state; + + g_warn_if_fail(device != NULL); + g_warn_if_fail(self->priv->installer != NULL); + + state = spice_usb_device_get_state(device); + if ((state != SPICE_USB_DEVICE_STATE_INSTALLED) && + (state != SPICE_USB_DEVICE_STATE_CONNECTED)) { + return; + } - spice_usb_device_set_state(device, SPICE_USB_DEVICE_STATE_UNINSTALLING); - if (! self->priv->installer) { - self->priv->installer = spice_win_usb_driver_new(); + spice_usb_device_set_state(device, SPICE_USB_DEVICE_STATE_UNINSTALLING); + 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); + cbinfo->installer = installer; + cbinfo->cancellable = NULL; + cbinfo->callback = NULL; + cbinfo->user_data = NULL; + cbinfo->is_install = FALSE; + + spice_win_usb_driver_uninstall(installer, device, NULL, + spice_usb_device_manager_drv_install_cb, + cbinfo); } - installer = self->priv->installer; - cbinfo = g_new0(UsbInstallCbInfo, 1); - cbinfo->manager = self; - cbinfo->device = spice_usb_device_ref(device); - cbinfo->installer = installer; - cbinfo->cancellable = NULL; - cbinfo->callback = NULL; - cbinfo->user_data = NULL; - cbinfo->is_install = FALSE; - - spice_win_usb_driver_uninstall(installer, device, NULL, - spice_usb_device_manager_drv_install_cb, - cbinfo); #endif #endif @@ -1805,6 +1881,11 @@ guint16 spice_usb_device_get_pid(const SpiceUsbDevice *device) #ifdef USE_WINUSB void spice_usb_device_set_state(SpiceUsbDevice *device, guint8 state) { + if (use_usbdk) + { + return; + } + SpiceUsbDeviceInfo *info = (SpiceUsbDeviceInfo *)device; g_return_if_fail(info != NULL); @@ -1814,6 +1895,11 @@ void spice_usb_device_set_state(SpiceUsbDevice *device, guint8 state) guint8 spice_usb_device_get_state(SpiceUsbDevice *device) { + if (use_usbdk) + { + return 0; + } + SpiceUsbDeviceInfo *info = (SpiceUsbDeviceInfo *)device; g_return_val_if_fail(info != NULL, 0); @@ -1866,19 +1952,37 @@ static gboolean spice_usb_device_equal_libdev(SpiceUsbDevice *device, libusb_device *libdev) { - int vid1, vid2, pid1, pid2; + if (! use_usbdk) + { + int vid1, vid2, pid1, pid2; - if ((device == NULL) || (libdev == NULL)) - return FALSE; + if ((device == NULL) || (libdev == NULL)) + return FALSE; - vid1 = spice_usb_device_get_vid(device); - pid1 = spice_usb_device_get_pid(device); + vid1 = spice_usb_device_get_vid(device); + pid1 = spice_usb_device_get_pid(device); - if (!spice_usb_device_manager_get_libdev_vid_pid(libdev, &vid2, &pid2)) { - return FALSE; + if (!spice_usb_device_manager_get_libdev_vid_pid(libdev, &vid2, &pid2)) { + return FALSE; + } + + return ((vid1 == vid2) && (pid1 == pid2)); } + else + { + int busnum1, devaddr1, busnum2, devaddr2; - return ((vid1 == vid2) && (pid1 == pid2)); + if ((device == NULL) || (libdev == NULL)) + return FALSE; + + busnum1 = spice_usb_device_get_busnum(device); + devaddr1 = spice_usb_device_get_devaddr(device); + + busnum2 = libusb_get_bus_number(libdev); + devaddr2 = libusb_get_device_address(libdev); + + return ((busnum1 == busnum2) && (devaddr1 == devaddr2)); + } } #else /* non-WinUSB -- compare bus:port of device and libdev */ static gboolean @@ -1927,9 +2031,17 @@ spice_usb_device_manager_device_to_libdev(SpiceUsbDeviceManager *self, g_return_val_if_fail(self->priv->context != NULL, NULL); #ifdef USE_WINUSB - /* For WinUSB we match by vid / pid, since the address may change */ - bus = spice_usb_device_get_vid(device); - addr = spice_usb_device_get_pid(device); + if (! use_usbdk) + { + /* For WinUSB we match by vid / pid, since the address may change */ + bus = spice_usb_device_get_vid(device); + addr = spice_usb_device_get_pid(device); + } + else + { + bus = spice_usb_device_get_busnum(device); + addr = spice_usb_device_get_devaddr(device); + } #else bus = spice_usb_device_get_busnum(device); addr = spice_usb_device_get_devaddr(device); -- 2.1.0 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/spice-devel