[Spice-devel] [PATCH v3 3/7] UsbDk: Add UsbDk wrapper

Christophe Fergeau cfergeau at redhat.com
Tue Jun 16 06:15:52 PDT 2015


On Mon, Jun 15, 2015 at 12:57:15PM +0300, Kirill Moizik wrote:
> From: Kirill Moizik <kirillm at daynix.com>
> 
> Introduce UsbDk API definitions and binding code.
> 
> Signed-off-by: Kirill Moizik <kirillm at daynix.com>
> ---
>  src/Makefile.am |   2 +
>  src/usbdk_api.c | 163 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  src/usbdk_api.h |  34 ++++++++++++
>  3 files changed, 199 insertions(+)
>  create mode 100644 src/usbdk_api.c
>  create mode 100644 src/usbdk_api.h
> 
> diff --git a/src/Makefile.am b/src/Makefile.am
> index 25e2255..655357a 100644
> --- a/src/Makefile.am
> +++ b/src/Makefile.am
> @@ -367,6 +367,8 @@ WIN_USB_FILES= \
>  	win-usb-clerk.h			\
>  	win-usb-driver-install.h	\
>  	win-usb-driver-install.c	\
> +	usbdk_api.h			\
> +	usbdk_api.c			\
>  	$(NULL)
>  
>  if OS_WIN32
> diff --git a/src/usbdk_api.c b/src/usbdk_api.c
> new file mode 100644
> index 0000000..e189a01
> --- /dev/null
> +++ b/src/usbdk_api.c
> @@ -0,0 +1,163 @@
> +/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
> +/*
> +   Copyright (C) 2014-2015 Red Hat, Inc.
> +
> +   This library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   This library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with this library; if not, see <http://www.gnu.org/licenses/>.
> +
> +  Authors:
> +    Dmitry Fleytman <dmitry at daynix.com>
> +    Kirill Moizik <kirill at daynix.com>
> +*/
> +#include <config.h>
> +
> +#include <windows.h>
> +#include <glib-object.h>
> +#include "usbdk_api.h"
> +#include "channel-usbredir-priv.h"
> +
> +#define USB_DK_HIDE_RULE_MATCH_ALL ((ULONG64)(-1))
> +typedef struct tag_USB_DK_HIDE_RULE
> +{
> +    ULONG64 Hide;
> +    ULONG64 Class;
> +    ULONG64 VID;
> +    ULONG64 PID;
> +    ULONG64 BCD;
> +} USB_DK_HIDE_RULE, *PUSB_DK_HIDE_RULE;
> +
> +typedef HANDLE(__cdecl *USBDK_CREATEHIDERHANDLE)(void);
> +typedef BOOL(__cdecl * USBDK_ADDHIDERULE)(HANDLE hider_handle, PUSB_DK_HIDE_RULE rule);
> +typedef BOOL(__cdecl *USBDK_CLEARHIDERULES)(HANDLE hider_handle);
> +typedef void(__cdecl *USBDK_CLOSEHIDERHANDLE)(HANDLE hider_handle);
> +
> + struct tag_usbdk_api_wrapper {
> +    HMODULE                                 module;
> +    USBDK_CREATEHIDERHANDLE                 CreateHandle;
> +    USBDK_ADDHIDERULE                       AddRule;
> +    USBDK_CLEARHIDERULES                    ClearRules;
> +    USBDK_CLOSEHIDERHANDLE                  CloseHiderHandle;
> +};
> +
> +BOOL usbdk_add_hide_rule(usbdk_api_wrapper *usbdk_api, HANDLE hider_handle, PUSB_DK_HIDE_RULE rule);
> +
> +BOOL usbdk_is_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;
> +}
> +
> +void usbdk_api_unload(usbdk_api_wrapper *usbdk_api) {
> +    SPICE_DEBUG("Unloading UsbDk API DLL");
> +    FreeLibrary(usbdk_api->module);
> +    g_free(usbdk_api);
> +}
> +
> +int usbdk_api_load(usbdk_api_wrapper **usbdk_api) {
> +    SPICE_DEBUG("Loading UsbDk API DLL");
> +
> +    *usbdk_api = g_new0(usbdk_api_wrapper, 1);
> +    (*usbdk_api)->module = LoadLibraryA("UsbDkHelper");
> +    if ((*usbdk_api)->module == NULL) {
> +        DWORD err = GetLastError();
> +        usbdk_api_unload(*usbdk_api);
> +        SPICE_DEBUG("Failed to load UsbDkHelper.dll, error %lu", err);
> +        return -1 ;
> +    }
> +
> +    (*usbdk_api)->CreateHandle = (USBDK_CREATEHIDERHANDLE)
> +        GetProcAddress((*usbdk_api)->module, "UsbDk_CreateHiderHandle");
> +    if ((*usbdk_api)->CreateHandle == NULL) {
> +        g_warning("Failed to find CreateHandle entry point");
> +        goto error_unload;
> +    }
> +
> +    (*usbdk_api)->AddRule = (USBDK_ADDHIDERULE)
> +        GetProcAddress((*usbdk_api)->module, "UsbDk_AddHideRule");
> +    if ((*usbdk_api)->AddRule == NULL) {
> +        g_warning("Failed to find AddRule entry point");
> +        goto error_unload;
> +    }
> +
> +    (*usbdk_api)->ClearRules = (USBDK_CLEARHIDERULES)
> +        GetProcAddress((*usbdk_api)->module, "UsbDk_ClearHideRules");
> +    if ((*usbdk_api)->ClearRules == NULL) {
> +        g_warning("Failed to find ClearRules entry point");
> +        goto error_unload;
> +    }
> +
> +    (*usbdk_api)->CloseHiderHandle = (USBDK_CLOSEHIDERHANDLE)
> +        GetProcAddress((*usbdk_api)->module, "UsbDk_CloseHiderHandle");
> +    if ((*usbdk_api)->CloseHiderHandle == NULL) {
> +        g_warning("Failed to find CloseHiderHandle  entry point");
> +        goto error_unload;
> +    }
> +    return 0;
> +
> +error_unload:
> +    usbdk_api_unload(*usbdk_api);
> +    return -1;
> +}
> +
> +void usbdk_api_set_hide_rules(usbdk_api_wrapper *usbdk_api, HANDLE hider_handle, gchar *redirect_on_connect)
> +{
> +    struct usbredirfilter_rule *rules;
> +    int r, count;
> +
> +    r = usbredirfilter_string_to_rules(redirect_on_connect, ",", "|", &rules, &count);
> +    if (r) {
> +        g_warning("auto-connect rules parsing failed with error %d", r);
> +        return;
> +    }
> +
> +    for (int i = 0; i < count; i++) {
> +        USB_DK_HIDE_RULE rule;
> +        rule.Hide  = (rules[i].allow                == -1) ? USB_DK_HIDE_RULE_MATCH_ALL : (uint64_t)rules[i].allow;
> +        rule.Class = (rules[i].device_class         == -1) ? USB_DK_HIDE_RULE_MATCH_ALL : (uint64_t)rules[i].device_class;
> +        rule.VID   = (rules[i].vendor_id            == -1) ? USB_DK_HIDE_RULE_MATCH_ALL : (uint64_t)rules[i].vendor_id;
> +        rule.PID   = (rules[i].product_id           == -1) ? USB_DK_HIDE_RULE_MATCH_ALL : (uint64_t)rules[i].product_id;
> +        rule.BCD   = (rules[i].device_version_bcd   == -1) ? USB_DK_HIDE_RULE_MATCH_ALL : (uint64_t)rules[i].device_version_bcd;

Using the ? operator gives very long lines, what about a helper like:

uint64_t usbredir_field_to_usbdk(int value)
{
    if (value >= 0)
        return (int)value;
    else if (value == -1)
        return USB_DK_HIDE_RULE_MATCH_ALL;

    /* value is < -1 */
    g_return_val_if_reached(USB_DK_HIDE_RULE_MATCH_ALL);
}

Christophe
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.freedesktop.org/archives/spice-devel/attachments/20150616/39884211/attachment-0001.sig>


More information about the Spice-devel mailing list