[Spice-devel] [PATCH 3/5] usbdk: make backend selection dynamic

Kirill Moizik kirill at daynix.com
Thu May 28 03:24:02 PDT 2015


From: Pavel Gurvich <pavel at daynix.com>

introducing use_usbdk global variable providing functionality of dynamic backend switching

Signed-off-by: Pavel Gurvich <pavel at daynix.com>
Signed-off-by: Dmitry Fleytman <dmitry at daynix.com>
---
 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



More information about the Spice-devel mailing list