On Mon, Jun 15, 2015 at 12:57:15PM +0300, Kirill Moizik wrote: > From: Kirill Moizik <kirillm@xxxxxxxxxx> > > Introduce UsbDk API definitions and binding code. > > Signed-off-by: Kirill Moizik <kirillm@xxxxxxxxxx> > --- > 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@xxxxxxxxxx> > + Kirill Moizik <kirill@xxxxxxxxxx> > +*/ > +#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
Attachment:
pgpK971xpGg5R.pgp
Description: PGP signature
_______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/spice-devel