[Spice-devel] [PATCH] win-usb-driver: use usbclerk new message: USB_CLERK_DRIVER_SESSION_INSTALL
Arnon Gilboa
agilboa at redhat.com
Thu Oct 25 05:26:15 PDT 2012
ack. seems ok, although CreateFile can move to init.
Uri Lublin wrote:
> 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
> ---
> 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(-)
>
> 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-devel
mailing list