Windows: Enable dynamic selection between WinUSB and UsbDk backends

This commit unifies the two Windows backends into a single project and
enables the user to switch to the UsbDk backend, if available, using the
libusb_set_option() function. All contexts will use the WinUSB backend
by default for backwards compatibility.

With this change, the UsbDk-specific projects are no longer required.

Closes #309

Signed-off-by: Chris Dickens <christopher.a.dickens@gmail.com>
This commit is contained in:
Chris Dickens
2018-01-08 10:17:26 -08:00
parent d0779e9303
commit 54884e84d0
31 changed files with 1193 additions and 923 deletions

View File

@@ -13,10 +13,12 @@ DARWIN_USB_SRC = os/darwin_usb.h os/darwin_usb.c
OPENBSD_USB_SRC = os/openbsd_usb.c
NETBSD_USB_SRC = os/netbsd_usb.c
SUNOS_USB_SRC = os/sunos_usb.c os/sunos_usb.h
WINDOWS_COMMON_SRC = os/windows_nt_common.h os/windows_nt_common.c \
os/windows_common.h libusb-1.0.rc libusb-1.0.def
WINDOWS_USB_SRC = os/windows_winusb.h os/windows_winusb.c
WINDOWS_USBDK_SRC = os/windows_usbdk.h os/windows_usbdk.c
WINDOWS_USB_SRC = libusb-1.0.def libusb-1.0.rc \
os/windows_common.h \
os/windows_nt_common.h os/windows_nt_common.c \
os/windows_nt_shared_types.h \
os/windows_usbdk.h os/windows_usbdk.c \
os/windows_winusb.h os/windows_winusb.c
WINCE_USB_SRC = os/wince_usb.h os/wince_usb.c
HAIKU_USB_SRC = os/haiku_usb.h os/haiku_usb_backend.cpp \
os/haiku_usb_raw.h os/haiku_usb_raw.cpp os/haiku_pollfs.cpp
@@ -25,8 +27,8 @@ EXTRA_DIST = $(POSIX_POLL_SRC) $(POSIX_THREADS_SRC) \
$(WINDOWS_POLL_SRC) $(WINDOWS_THREADS_SRC) \
$(LINUX_USBFS_SRC) $(DARWIN_USB_SRC) \
$(OPENBSD_USB_SRC) $(NETBSD_USB_SRC) \
$(WINDOWS_COMMON_SRC) $(WINDOWS_USB_SRC) $(WINDOWS_USBDK_SRC) \
$(WINCE_USB_SRC) $(HAIKU_USB_SRC) \
$(WINDOWS_USB_SRC) $(WINCE_USB_SRC) \
$(HAIKU_USB_SRC) \
os/linux_udev.c os/linux_netlink.c
if OS_LINUX
@@ -63,12 +65,7 @@ libusb_1_0_la_LIBADD = libusb_haiku.la
endif
if OS_WINDOWS
if USE_USBDK
OS_SRC = $(WINDOWS_USBDK_SRC) $(WINDOWS_COMMON_SRC)
else
OS_SRC = $(WINDOWS_USB_SRC) $(WINDOWS_COMMON_SRC)
endif
OS_SRC = $(WINDOWS_USB_SRC)
.rc.lo:
$(AM_V_GEN)$(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --tag=RC --mode=compile $(RC) $(RCFLAGS) -i $< -o $@

View File

@@ -2065,19 +2065,15 @@ int API_EXPORTED libusb_set_option(libusb_context *ctx,
ctx->debug = (enum libusb_log_level)arg;
#endif
break;
/* Handle all backend-specific options here */
#if 0
/* This code is compiled out until the first backend-specific option is
* added to the library. When this time comes, remove the #if/#endif
* lines and this comment, then replace the case statement with the
* valid option name. */
case LIBUSB_OPTION_<...>:
case LIBUSB_OPTION_USE_USBDK:
if (usbi_backend.set_option)
r = usbi_backend.set_option(ctx, option, ap);
else
r = LIBUSB_ERROR_NOT_SUPPORTED;
break;
#endif
default:
r = LIBUSB_ERROR_INVALID_PARAM;
}

View File

@@ -2016,6 +2016,15 @@ enum libusb_option {
* does nothing: you'll always get messages from all levels.
*/
LIBUSB_OPTION_LOG_LEVEL,
/** Use the UsbDk backend for a specific context, if available.
*
* This option should be set immediately after calling libusb_init(), otherwise
* unspecified behavior may occur.
*
* Only valid on Windows.
*/
LIBUSB_OPTION_USE_USBDK,
};
int LIBUSB_CALL libusb_set_option(libusb_context *ctx, enum libusb_option option, ...);

View File

@@ -41,21 +41,6 @@
#define DUMMY_HANDLE ((HANDLE)(LONG_PTR)-2)
/* Windows versions */
enum windows_version {
WINDOWS_CE = -2,
WINDOWS_UNDEFINED = -1,
WINDOWS_UNSUPPORTED = 0,
WINDOWS_XP = 0x51,
WINDOWS_2003 = 0x52, // Also XP x64
WINDOWS_VISTA = 0x60,
WINDOWS_7 = 0x61,
WINDOWS_8 = 0x62,
WINDOWS_8_1_OR_LATER = 0x63,
WINDOWS_MAX
};
extern int windows_version;
#define MAX_FDS 256
#define POLLIN 0x0001 /* There is data to read */

View File

@@ -32,7 +32,6 @@
// Global variables
int errno = 0;
int windows_version = WINDOWS_CE;
static uint64_t hires_frequency, hires_ticks_to_ps;
static HANDLE driver_handle = INVALID_HANDLE_VALUE;
static int concurrent_usage = -1;
@@ -110,7 +109,7 @@ static int translate_driver_error(DWORD error)
}
}
static int init_dllimports(void)
static BOOL init_dllimports(void)
{
DLL_GET_HANDLE(ceusbkwrapper);
DLL_LOAD_FUNC(ceusbkwrapper, UkwOpenDriver, TRUE);
@@ -136,7 +135,7 @@ static int init_dllimports(void)
DLL_LOAD_FUNC(ceusbkwrapper, UkwIssueBulkTransfer, TRUE);
DLL_LOAD_FUNC(ceusbkwrapper, UkwIsPipeHalted, TRUE);
return LIBUSB_SUCCESS;
return TRUE;
}
static void exit_dllimports(void)
@@ -188,7 +187,7 @@ static int wince_init(struct libusb_context *ctx)
// exit calls. If init is called more than exit, we will not exit properly
if ( ++concurrent_usage == 0 ) { // First init?
// Load DLL imports
if (init_dllimports() != LIBUSB_SUCCESS) {
if (!init_dllimports()) {
usbi_err(ctx, "could not resolve DLL functions");
r = LIBUSB_ERROR_NOT_SUPPORTED;
goto init_exit;

View File

@@ -68,21 +68,23 @@
/*
* Macros for handling DLL themselves
*/
#define DLL_HANDLE_NAME(name) __dll_##name##_handle
#define DLL_DECLARE_HANDLE(name) \
static HMODULE __dll_##name##_handle = NULL
static HMODULE DLL_HANDLE_NAME(name) = NULL
#define DLL_GET_HANDLE(name) \
do { \
__dll_##name##_handle = DLL_LOAD_LIBRARY(name); \
if (!__dll_##name##_handle) \
return LIBUSB_ERROR_NOT_FOUND; \
DLL_HANDLE_NAME(name) = DLL_LOAD_LIBRARY(name); \
if (!DLL_HANDLE_NAME(name)) \
return FALSE; \
} while (0)
#define DLL_FREE_HANDLE(name) \
do { \
if (__dll_##name##_handle) { \
FreeLibrary(__dll_##name##_handle); \
__dll_##name##_handle = NULL; \
if (DLL_HANDLE_NAME(name)) { \
FreeLibrary(DLL_HANDLE_NAME(name)); \
DLL_HANDLE_NAME(name) = NULL; \
} \
} while (0)
@@ -90,9 +92,11 @@
/*
* Macros for handling functions within a DLL
*/
#define DLL_FUNC_NAME(name) __dll_##name##_func_t
#define DLL_DECLARE_FUNC_PREFIXNAME(api, ret, prefixname, name, args) \
typedef ret (api * __dll_##name##_func_t)args; \
static __dll_##name##_func_t prefixname = NULL
typedef ret (api * DLL_FUNC_NAME(name))args; \
static DLL_FUNC_NAME(name) prefixname = NULL
#define DLL_DECLARE_FUNC(api, ret, name, args) \
DLL_DECLARE_FUNC_PREFIXNAME(api, ret, name, name, args)
@@ -101,21 +105,21 @@
#define DLL_LOAD_FUNC_PREFIXNAME(dll, prefixname, name, ret_on_failure) \
do { \
HMODULE h = __dll_##dll##_handle; \
prefixname = (__dll_##name##_func_t)GetProcAddress(h, \
HMODULE h = DLL_HANDLE_NAME(dll); \
prefixname = (DLL_FUNC_NAME(name))GetProcAddress(h, \
DLL_STRINGIFY(name)); \
if (prefixname) \
break; \
prefixname = (__dll_##name##_func_t)GetProcAddress(h, \
prefixname = (DLL_FUNC_NAME(name))GetProcAddress(h, \
DLL_STRINGIFY(name) DLL_STRINGIFY(A)); \
if (prefixname) \
break; \
prefixname = (__dll_##name##_func_t)GetProcAddress(h, \
prefixname = (DLL_FUNC_NAME(name))GetProcAddress(h, \
DLL_STRINGIFY(name) DLL_STRINGIFY(W)); \
if (prefixname) \
break; \
if (ret_on_failure) \
return LIBUSB_ERROR_NOT_FOUND; \
return FALSE; \
} while (0)
#define DLL_LOAD_FUNC(dll, name, ret_on_failure) \

View File

@@ -34,6 +34,11 @@
// Public
BOOL (WINAPI *pCancelIoEx)(HANDLE, LPOVERLAPPED);
enum windows_version windows_version = WINDOWS_UNDEFINED;
// Global variables for init/exit
static unsigned int init_count = 0;
static bool usbdk_available = false;
// Global variables for clock_gettime mechanism
static uint64_t hires_ticks_to_ps;
@@ -53,6 +58,11 @@ struct timer_request {
static HANDLE timer_thread = NULL;
static DWORD timer_thread_id = 0;
/* Kernel32 dependencies */
DLL_DECLARE_HANDLE(Kernel32);
/* This call is only available from XP SP2 */
DLL_DECLARE_FUNC_PREFIXED(WINAPI, BOOL, p, IsWow64Process, (HANDLE, PBOOL));
/* User32 dependencies */
DLL_DECLARE_HANDLE(User32);
DLL_DECLARE_FUNC_PREFIXED(WINAPI, BOOL, p, GetMessageA, (LPMSG, HWND, UINT, UINT));
@@ -114,6 +124,11 @@ const char *windows_error_str(DWORD error_code)
}
#endif
static inline struct windows_context_priv *_context_priv(struct libusb_context *ctx)
{
return (struct windows_context_priv *)ctx->os_priv;
}
/* Hash table functions - modified From glibc 2.3.2:
[Aho,Sethi,Ullman] Compilers: Principles, Techniques and Tools, 1986
[Knuth] The Art of Computer Programming, part 3 (6.4) */
@@ -259,15 +274,22 @@ out_unlock:
return idx;
}
static int windows_init_dlls(void)
/*
* Make a transfer complete synchronously
*/
void windows_force_sync_completion(OVERLAPPED *overlapped, ULONG size)
{
HMODULE hKernel32 = GetModuleHandleA("KERNEL32");
if (hKernel32 == NULL)
return LIBUSB_ERROR_NOT_FOUND;
overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
overlapped->InternalHigh = size;
SetEvent(overlapped->hEvent);
}
static BOOL windows_init_dlls(void)
{
DLL_GET_HANDLE(Kernel32);
DLL_LOAD_FUNC_PREFIXED(Kernel32, p, IsWow64Process, FALSE);
pCancelIoEx = (BOOL (WINAPI *)(HANDLE, LPOVERLAPPED))
GetProcAddress(hKernel32, "CancelIoEx");
GetProcAddress(DLL_HANDLE_NAME(Kernel32), "CancelIoEx");
usbi_dbg("Will use CancelIo%s for I/O cancellation", pCancelIoEx ? "Ex" : "");
DLL_GET_HANDLE(User32);
@@ -275,28 +297,23 @@ static int windows_init_dlls(void)
DLL_LOAD_FUNC_PREFIXED(User32, p, PeekMessageA, TRUE);
DLL_LOAD_FUNC_PREFIXED(User32, p, PostThreadMessageA, TRUE);
return LIBUSB_SUCCESS;
return TRUE;
}
static void windows_exit_dlls(void)
{
DLL_FREE_HANDLE(Kernel32);
DLL_FREE_HANDLE(User32);
}
static bool windows_init_clock(struct libusb_context *ctx)
{
DWORD_PTR affinity, dummy;
HANDLE event = NULL;
HANDLE event;
LARGE_INTEGER li_frequency;
int i;
if (QueryPerformanceFrequency(&li_frequency)) {
// Load DLL imports
if (windows_init_dlls() != LIBUSB_SUCCESS) {
usbi_err(ctx, "could not resolve DLL functions");
return false;
}
// The hires frequency can go as high as 4 GHz, so we'll use a conversion
// to picoseconds to compute the tv_nsecs part in clock_gettime
hires_frequency = li_frequency.QuadPart;
@@ -352,7 +369,7 @@ static bool windows_init_clock(struct libusb_context *ctx)
return true;
}
void windows_destroy_clock(void)
static void windows_destroy_clock(void)
{
if (timer_thread) {
// actually the signal to quit the thread.
@@ -369,6 +386,110 @@ void windows_destroy_clock(void)
}
}
/* Windows version detection */
static BOOL is_x64(void)
{
BOOL ret = FALSE;
// Detect if we're running a 32 or 64 bit system
if (sizeof(uintptr_t) < 8) {
if (pIsWow64Process != NULL)
pIsWow64Process(GetCurrentProcess(), &ret);
} else {
ret = TRUE;
}
return ret;
}
static void get_windows_version(void)
{
OSVERSIONINFOEXA vi, vi2;
const char *arch, *w = NULL;
unsigned major, minor, version;
ULONGLONG major_equal, minor_equal;
BOOL ws;
windows_version = WINDOWS_UNDEFINED;
memset(&vi, 0, sizeof(vi));
vi.dwOSVersionInfoSize = sizeof(vi);
if (!GetVersionExA((OSVERSIONINFOA *)&vi)) {
memset(&vi, 0, sizeof(vi));
vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
if (!GetVersionExA((OSVERSIONINFOA *)&vi))
return;
}
if (vi.dwPlatformId != VER_PLATFORM_WIN32_NT)
return;
if ((vi.dwMajorVersion > 6) || ((vi.dwMajorVersion == 6) && (vi.dwMinorVersion >= 2))) {
// Starting with Windows 8.1 Preview, GetVersionEx() does no longer report the actual OS version
// See: http://msdn.microsoft.com/en-us/library/windows/desktop/dn302074.aspx
major_equal = VerSetConditionMask(0, VER_MAJORVERSION, VER_EQUAL);
for (major = vi.dwMajorVersion; major <= 9; major++) {
memset(&vi2, 0, sizeof(vi2));
vi2.dwOSVersionInfoSize = sizeof(vi2);
vi2.dwMajorVersion = major;
if (!VerifyVersionInfoA(&vi2, VER_MAJORVERSION, major_equal))
continue;
if (vi.dwMajorVersion < major) {
vi.dwMajorVersion = major;
vi.dwMinorVersion = 0;
}
minor_equal = VerSetConditionMask(0, VER_MINORVERSION, VER_EQUAL);
for (minor = vi.dwMinorVersion; minor <= 9; minor++) {
memset(&vi2, 0, sizeof(vi2));
vi2.dwOSVersionInfoSize = sizeof(vi2);
vi2.dwMinorVersion = minor;
if (!VerifyVersionInfoA(&vi2, VER_MINORVERSION, minor_equal))
continue;
vi.dwMinorVersion = minor;
break;
}
break;
}
}
if ((vi.dwMajorVersion > 0xf) || (vi.dwMinorVersion > 0xf))
return;
ws = (vi.wProductType <= VER_NT_WORKSTATION);
version = vi.dwMajorVersion << 4 | vi.dwMinorVersion;
switch (version) {
case 0x50: windows_version = WINDOWS_2000; w = "2000"; break;
case 0x51: windows_version = WINDOWS_XP; w = "XP"; break;
case 0x52: windows_version = WINDOWS_2003; w = "2003"; break;
case 0x60: windows_version = WINDOWS_VISTA; w = (ws ? "Vista" : "2008"); break;
case 0x61: windows_version = WINDOWS_7; w = (ws ? "7" : "2008_R2"); break;
case 0x62: windows_version = WINDOWS_8; w = (ws ? "8" : "2012"); break;
case 0x63: windows_version = WINDOWS_8_1; w = (ws ? "8.1" : "2012_R2"); break;
case 0x64: windows_version = WINDOWS_10; w = (ws ? "10" : "2016"); break;
default:
if (version < 0x50) {
return;
} else {
windows_version = WINDOWS_11_OR_LATER;
w = "11 or later";
}
}
arch = is_x64() ? "64-bit" : "32-bit";
if (vi.wServicePackMinor)
usbi_dbg("Windows %s SP%u.%u %s", w, vi.wServicePackMajor, vi.wServicePackMinor, arch);
else if (vi.wServicePackMajor)
usbi_dbg("Windows %s SP%u %s", w, vi.wServicePackMajor, arch);
else
usbi_dbg("Windows %s %s", w, arch);
}
/*
* Monotonic and real time functions
*/
@@ -413,7 +534,378 @@ static unsigned __stdcall windows_clock_gettime_threaded(void *param)
}
}
int windows_clock_gettime(int clk_id, struct timespec *tp)
static void windows_transfer_callback(const struct windows_backend *backend,
struct usbi_transfer *itransfer, DWORD io_result, DWORD io_size)
{
int status, istatus;
usbi_dbg("handling I/O completion with errcode %u, size %u", (unsigned int)io_result, (unsigned int)io_size);
switch (io_result) {
case NO_ERROR:
status = backend->copy_transfer_data(itransfer, (uint32_t)io_size);
break;
case ERROR_GEN_FAILURE:
usbi_dbg("detected endpoint stall");
status = LIBUSB_TRANSFER_STALL;
break;
case ERROR_SEM_TIMEOUT:
usbi_dbg("detected semaphore timeout");
status = LIBUSB_TRANSFER_TIMED_OUT;
break;
case ERROR_OPERATION_ABORTED:
istatus = backend->copy_transfer_data(itransfer, (uint32_t)io_size);
if (istatus != LIBUSB_TRANSFER_COMPLETED)
usbi_dbg("Failed to copy partial data in aborted operation: %d", istatus);
usbi_dbg("detected operation aborted");
status = LIBUSB_TRANSFER_CANCELLED;
break;
case ERROR_FILE_NOT_FOUND:
usbi_dbg("detected device removed");
status = LIBUSB_TRANSFER_NO_DEVICE;
break;
default:
usbi_err(ITRANSFER_CTX(itransfer), "detected I/O error %u: %s", (unsigned int)io_result, windows_error_str(io_result));
status = LIBUSB_TRANSFER_ERROR;
break;
}
backend->clear_transfer_priv(itransfer); // Cancel polling
if (status == LIBUSB_TRANSFER_CANCELLED)
usbi_handle_transfer_cancellation(itransfer);
else
usbi_handle_transfer_completion(itransfer, (enum libusb_transfer_status)status);
}
static void windows_handle_callback(const struct windows_backend *backend,
struct usbi_transfer *itransfer, DWORD io_result, DWORD io_size)
{
struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
switch (transfer->type) {
case LIBUSB_TRANSFER_TYPE_CONTROL:
case LIBUSB_TRANSFER_TYPE_BULK:
case LIBUSB_TRANSFER_TYPE_INTERRUPT:
case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
windows_transfer_callback(backend, itransfer, io_result, io_size);
break;
case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
usbi_warn(ITRANSFER_CTX(itransfer), "bulk stream transfers are not yet supported on this platform");
break;
default:
usbi_err(ITRANSFER_CTX(itransfer), "unknown endpoint type %d", transfer->type);
}
}
static int windows_init(struct libusb_context *ctx)
{
struct windows_context_priv *priv = _context_priv(ctx);
HANDLE semaphore;
char sem_name[11 + 8 + 1]; // strlen("libusb_init") + (32-bit hex PID) + '\0'
int r = LIBUSB_ERROR_OTHER;
bool winusb_backend_init = false;
sprintf(sem_name, "libusb_init%08X", (unsigned int)(GetCurrentProcessId() & 0xFFFFFFFF));
semaphore = CreateSemaphoreA(NULL, 1, 1, sem_name);
if (semaphore == NULL) {
usbi_err(ctx, "could not create semaphore: %s", windows_error_str(0));
return LIBUSB_ERROR_NO_MEM;
}
// A successful wait brings our semaphore count to 0 (unsignaled)
// => any concurent wait stalls until the semaphore's release
if (WaitForSingleObject(semaphore, INFINITE) != WAIT_OBJECT_0) {
usbi_err(ctx, "failure to access semaphore: %s", windows_error_str(0));
CloseHandle(semaphore);
return LIBUSB_ERROR_NO_MEM;
}
// NB: concurrent usage supposes that init calls are equally balanced with
// exit calls. If init is called more than exit, we will not exit properly
if (++init_count == 1) { // First init?
// Load DLL imports
if (!windows_init_dlls()) {
usbi_err(ctx, "could not resolve DLL functions");
goto init_exit;
}
get_windows_version();
if (windows_version == WINDOWS_UNDEFINED) {
usbi_err(ctx, "failed to detect Windows version");
r = LIBUSB_ERROR_NOT_SUPPORTED;
goto init_exit;
}
if (!windows_init_clock(ctx))
goto init_exit;
if (!htab_create(ctx))
goto init_exit;
r = winusb_backend.init(ctx);
if (r != LIBUSB_SUCCESS)
goto init_exit;
winusb_backend_init = true;
r = usbdk_backend.init(ctx);
if (r == LIBUSB_SUCCESS) {
usbi_dbg("UsbDk backend is available");
usbdk_available = true;
} else {
usbi_info(ctx, "UsbDk backend is not available");
// Do not report this as an error
r = LIBUSB_SUCCESS;
}
}
// By default, new contexts will use the WinUSB backend
priv->backend = &winusb_backend;
r = LIBUSB_SUCCESS;
init_exit: // Holds semaphore here
if ((init_count == 1) && (r != LIBUSB_SUCCESS)) { // First init failed?
if (winusb_backend_init)
winusb_backend.exit(ctx);
htab_destroy();
windows_destroy_clock();
windows_exit_dlls();
--init_count;
}
ReleaseSemaphore(semaphore, 1, NULL); // increase count back to 1
CloseHandle(semaphore);
return r;
}
static void windows_exit(struct libusb_context *ctx)
{
HANDLE semaphore;
char sem_name[11 + 8 + 1]; // strlen("libusb_init") + (32-bit hex PID) + '\0'
UNUSED(ctx);
sprintf(sem_name, "libusb_init%08X", (unsigned int)(GetCurrentProcessId() & 0xFFFFFFFF));
semaphore = CreateSemaphoreA(NULL, 1, 1, sem_name);
if (semaphore == NULL)
return;
// A successful wait brings our semaphore count to 0 (unsignaled)
// => any concurent wait stalls until the semaphore release
if (WaitForSingleObject(semaphore, INFINITE) != WAIT_OBJECT_0) {
CloseHandle(semaphore);
return;
}
// Only works if exits and inits are balanced exactly
if (--init_count == 0) { // Last exit
if (usbdk_available) {
usbdk_backend.exit(ctx);
usbdk_available = false;
}
winusb_backend.exit(ctx);
htab_destroy();
windows_destroy_clock();
windows_exit_dlls();
}
ReleaseSemaphore(semaphore, 1, NULL); // increase count back to 1
CloseHandle(semaphore);
}
static int windows_set_option(struct libusb_context *ctx, enum libusb_option option, va_list ap)
{
struct windows_context_priv *priv = _context_priv(ctx);
UNUSED(ap);
switch (option) {
case LIBUSB_OPTION_USE_USBDK:
if (usbdk_available) {
usbi_dbg("switching context %p to use UsbDk backend", ctx);
priv->backend = &usbdk_backend;
} else {
usbi_err(ctx, "UsbDk backend not available");
return LIBUSB_ERROR_NOT_FOUND;
}
return LIBUSB_SUCCESS;
}
return LIBUSB_ERROR_NOT_SUPPORTED;
}
static int windows_get_device_list(struct libusb_context *ctx, struct discovered_devs **discdevs)
{
struct windows_context_priv *priv = _context_priv(ctx);
return priv->backend->get_device_list(ctx, discdevs);
}
static int windows_open(struct libusb_device_handle *dev_handle)
{
struct windows_context_priv *priv = _context_priv(HANDLE_CTX(dev_handle));
return priv->backend->open(dev_handle);
}
static void windows_close(struct libusb_device_handle *dev_handle)
{
struct windows_context_priv *priv = _context_priv(HANDLE_CTX(dev_handle));
priv->backend->close(dev_handle);
}
static int windows_get_device_descriptor(struct libusb_device *dev,
unsigned char *buffer, int *host_endian)
{
struct windows_context_priv *priv = _context_priv(DEVICE_CTX(dev));
*host_endian = 0;
return priv->backend->get_device_descriptor(dev, buffer);
}
static int windows_get_active_config_descriptor(struct libusb_device *dev,
unsigned char *buffer, size_t len, int *host_endian)
{
struct windows_context_priv *priv = _context_priv(DEVICE_CTX(dev));
*host_endian = 0;
return priv->backend->get_active_config_descriptor(dev, buffer, len);
}
static int windows_get_config_descriptor(struct libusb_device *dev,
uint8_t config_index, unsigned char *buffer, size_t len, int *host_endian)
{
struct windows_context_priv *priv = _context_priv(DEVICE_CTX(dev));
*host_endian = 0;
return priv->backend->get_config_descriptor(dev, config_index, buffer, len);
}
static int windows_get_config_descriptor_by_value(struct libusb_device *dev,
uint8_t bConfigurationValue, unsigned char **buffer, int *host_endian)
{
struct windows_context_priv *priv = _context_priv(DEVICE_CTX(dev));
*host_endian = 0;
return priv->backend->get_config_descriptor_by_value(dev, bConfigurationValue, buffer);
}
static int windows_get_configuration(struct libusb_device_handle *dev_handle, int *config)
{
struct windows_context_priv *priv = _context_priv(HANDLE_CTX(dev_handle));
return priv->backend->get_configuration(dev_handle, config);
}
static int windows_set_configuration(struct libusb_device_handle *dev_handle, int config)
{
struct windows_context_priv *priv = _context_priv(HANDLE_CTX(dev_handle));
return priv->backend->set_configuration(dev_handle, config);
}
static int windows_claim_interface(struct libusb_device_handle *dev_handle, int interface_number)
{
struct windows_context_priv *priv = _context_priv(HANDLE_CTX(dev_handle));
return priv->backend->claim_interface(dev_handle, interface_number);
}
static int windows_release_interface(struct libusb_device_handle *dev_handle, int interface_number)
{
struct windows_context_priv *priv = _context_priv(HANDLE_CTX(dev_handle));
return priv->backend->release_interface(dev_handle, interface_number);
}
static int windows_set_interface_altsetting(struct libusb_device_handle *dev_handle,
int interface_number, int altsetting)
{
struct windows_context_priv *priv = _context_priv(HANDLE_CTX(dev_handle));
return priv->backend->set_interface_altsetting(dev_handle, interface_number, altsetting);
}
static int windows_clear_halt(struct libusb_device_handle *dev_handle, unsigned char endpoint)
{
struct windows_context_priv *priv = _context_priv(HANDLE_CTX(dev_handle));
return priv->backend->clear_halt(dev_handle, endpoint);
}
static int windows_reset_device(struct libusb_device_handle *dev_handle)
{
struct windows_context_priv *priv = _context_priv(HANDLE_CTX(dev_handle));
return priv->backend->reset_device(dev_handle);
}
static void windows_destroy_device(struct libusb_device *dev)
{
struct windows_context_priv *priv = _context_priv(DEVICE_CTX(dev));
priv->backend->destroy_device(dev);
}
static int windows_submit_transfer(struct usbi_transfer *itransfer)
{
struct windows_context_priv *priv = _context_priv(ITRANSFER_CTX(itransfer));
return priv->backend->submit_transfer(itransfer);
}
static int windows_cancel_transfer(struct usbi_transfer *itransfer)
{
struct windows_context_priv *priv = _context_priv(ITRANSFER_CTX(itransfer));
return priv->backend->cancel_transfer(itransfer);
}
static void windows_clear_transfer_priv(struct usbi_transfer *itransfer)
{
struct windows_context_priv *priv = _context_priv(ITRANSFER_CTX(itransfer));
priv->backend->clear_transfer_priv(itransfer);
}
static int windows_handle_events(struct libusb_context *ctx, struct pollfd *fds, POLL_NFDS_TYPE nfds, int num_ready)
{
struct windows_context_priv *priv = _context_priv(ctx);
struct usbi_transfer *itransfer;
DWORD io_size, io_result;
POLL_NFDS_TYPE i;
bool found;
int transfer_fd;
int r = LIBUSB_SUCCESS;
usbi_mutex_lock(&ctx->open_devs_lock);
for (i = 0; i < nfds && num_ready > 0; i++) {
usbi_dbg("checking fd %d with revents = %04x", fds[i].fd, fds[i].revents);
if (!fds[i].revents)
continue;
num_ready--;
// Because a Windows OVERLAPPED is used for poll emulation,
// a pollable fd is created and stored with each transfer
found = false;
transfer_fd = -1;
usbi_mutex_lock(&ctx->flying_transfers_lock);
list_for_each_entry(itransfer, &ctx->flying_transfers, list, struct usbi_transfer) {
transfer_fd = priv->backend->get_transfer_fd(itransfer);
if (transfer_fd == fds[i].fd) {
found = true;
break;
}
}
usbi_mutex_unlock(&ctx->flying_transfers_lock);
if (found) {
priv->backend->get_overlapped_result(itransfer, &io_result, &io_size);
usbi_remove_pollfd(ctx, transfer_fd);
// let handle_callback free the event using the transfer wfd
// If you don't use the transfer wfd, you run a risk of trying to free a
// newly allocated wfd that took the place of the one from the transfer.
windows_handle_callback(priv->backend, itransfer, io_result, io_size);
} else {
usbi_err(ctx, "could not find a matching transfer for fd %d", fds[i].fd);
r = LIBUSB_ERROR_NOT_FOUND;
break;
}
}
usbi_mutex_unlock(&ctx->open_devs_lock);
return r;
}
static int windows_clock_gettime(int clk_id, struct timespec *tp)
{
struct timer_request request;
#if !defined(_MSC_VER) || (_MSC_VER < 1900)
@@ -472,147 +964,44 @@ int windows_clock_gettime(int clk_id, struct timespec *tp)
}
}
static void windows_transfer_callback(struct usbi_transfer *itransfer, DWORD io_result, DWORD io_size)
{
int status, istatus;
usbi_dbg("handling I/O completion with errcode %u, size %u", (unsigned int)io_result, (unsigned int)io_size);
switch (io_result) {
case NO_ERROR:
status = windows_copy_transfer_data(itransfer, (uint32_t)io_size);
break;
case ERROR_GEN_FAILURE:
usbi_dbg("detected endpoint stall");
status = LIBUSB_TRANSFER_STALL;
break;
case ERROR_SEM_TIMEOUT:
usbi_dbg("detected semaphore timeout");
status = LIBUSB_TRANSFER_TIMED_OUT;
break;
case ERROR_OPERATION_ABORTED:
istatus = windows_copy_transfer_data(itransfer, (uint32_t)io_size);
if (istatus != LIBUSB_TRANSFER_COMPLETED)
usbi_dbg("Failed to copy partial data in aborted operation: %d", istatus);
usbi_dbg("detected operation aborted");
status = LIBUSB_TRANSFER_CANCELLED;
break;
case ERROR_FILE_NOT_FOUND:
usbi_dbg("detected device removed");
status = LIBUSB_TRANSFER_NO_DEVICE;
break;
default:
usbi_err(ITRANSFER_CTX(itransfer), "detected I/O error %u: %s", (unsigned int)io_result, windows_error_str(io_result));
status = LIBUSB_TRANSFER_ERROR;
break;
}
windows_clear_transfer_priv(itransfer); // Cancel polling
if (status == LIBUSB_TRANSFER_CANCELLED)
usbi_handle_transfer_cancellation(itransfer);
else
usbi_handle_transfer_completion(itransfer, (enum libusb_transfer_status)status);
}
/*
* Make a transfer complete synchronously
*/
void windows_force_sync_completion(OVERLAPPED *overlapped, ULONG size)
{
overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
overlapped->InternalHigh = size;
SetEvent(overlapped->hEvent);
}
void windows_handle_callback(struct usbi_transfer *itransfer, uint32_t io_result, uint32_t io_size)
{
struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
switch (transfer->type) {
case LIBUSB_TRANSFER_TYPE_CONTROL:
case LIBUSB_TRANSFER_TYPE_BULK:
case LIBUSB_TRANSFER_TYPE_INTERRUPT:
case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
windows_transfer_callback(itransfer, io_result, io_size);
break;
case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
usbi_warn(ITRANSFER_CTX(itransfer), "bulk stream transfers are not yet supported on this platform");
break;
default:
usbi_err(ITRANSFER_CTX(itransfer), "unknown endpoint type %d", transfer->type);
}
}
int windows_handle_events(struct libusb_context *ctx, struct pollfd *fds, POLL_NFDS_TYPE nfds, int num_ready)
{
struct usbi_transfer *itransfer;
DWORD io_size, io_result;
POLL_NFDS_TYPE i;
bool found;
int transfer_fd = -1;
int r = LIBUSB_SUCCESS;
usbi_mutex_lock(&ctx->open_devs_lock);
for (i = 0; i < nfds && num_ready > 0; i++) {
usbi_dbg("checking fd %d with revents = %04x", fds[i].fd, fds[i].revents);
if (!fds[i].revents)
continue;
num_ready--;
// Because a Windows OVERLAPPED is used for poll emulation,
// a pollable fd is created and stored with each transfer
found = false;
usbi_mutex_lock(&ctx->flying_transfers_lock);
list_for_each_entry(itransfer, &ctx->flying_transfers, list, struct usbi_transfer) {
transfer_fd = windows_get_transfer_fd(itransfer);
if (transfer_fd == fds[i].fd) {
found = true;
break;
}
}
usbi_mutex_unlock(&ctx->flying_transfers_lock);
if (found) {
windows_get_overlapped_result(itransfer, &io_result, &io_size);
usbi_remove_pollfd(ctx, transfer_fd);
// let handle_callback free the event using the transfer wfd
// If you don't use the transfer wfd, you run a risk of trying to free a
// newly allocated wfd that took the place of the one from the transfer.
windows_handle_callback(itransfer, io_result, io_size);
} else {
usbi_err(ctx, "could not find a matching transfer for fd %d", fds[i]);
r = LIBUSB_ERROR_NOT_FOUND;
break;
}
}
usbi_mutex_unlock(&ctx->open_devs_lock);
return r;
}
int windows_common_init(struct libusb_context *ctx)
{
if (!windows_init_clock(ctx))
goto error_roll_back;
if (!htab_create(ctx))
goto error_roll_back;
return LIBUSB_SUCCESS;
error_roll_back:
windows_common_exit();
return LIBUSB_ERROR_NO_MEM;
}
void windows_common_exit(void)
{
htab_destroy();
windows_destroy_clock();
windows_exit_dlls();
}
// NB: MSVC6 does not support named initializers.
const struct usbi_os_backend usbi_backend = {
"Windows",
USBI_CAP_HAS_HID_ACCESS,
windows_init,
windows_exit,
windows_set_option,
windows_get_device_list,
NULL, /* hotplug_poll */
windows_open,
windows_close,
windows_get_device_descriptor,
windows_get_active_config_descriptor,
windows_get_config_descriptor,
windows_get_config_descriptor_by_value,
windows_get_configuration,
windows_set_configuration,
windows_claim_interface,
windows_release_interface,
windows_set_interface_altsetting,
windows_clear_halt,
windows_reset_device,
NULL, /* alloc_streams */
NULL, /* free_streams */
NULL, /* dev_mem_alloc */
NULL, /* dev_mem_free */
NULL, /* kernel_driver_active */
NULL, /* detach_kernel_driver */
NULL, /* attach_kernel_driver */
windows_destroy_device,
windows_submit_transfer,
windows_cancel_transfer,
windows_clear_transfer_priv,
windows_handle_events,
NULL, /* handle_transfer_completion */
windows_clock_gettime,
sizeof(struct windows_context_priv),
sizeof(union windows_device_priv),
sizeof(union windows_device_handle_priv),
sizeof(union windows_transfer_priv),
};

View File

@@ -26,45 +26,84 @@
#pragma once
// Missing from MinGW
#if !defined(FACILITY_SETUPAPI)
#define FACILITY_SETUPAPI 15
#endif
#include "windows_nt_shared_types.h"
#include <pshpack1.h>
/* Windows versions */
enum windows_version {
WINDOWS_UNDEFINED,
WINDOWS_2000,
WINDOWS_XP,
WINDOWS_2003, // Also XP x64
WINDOWS_VISTA,
WINDOWS_7,
WINDOWS_8,
WINDOWS_8_1,
WINDOWS_10,
WINDOWS_11_OR_LATER
};
typedef struct USB_CONFIGURATION_DESCRIPTOR {
UCHAR bLength;
UCHAR bDescriptorType;
USHORT wTotalLength;
UCHAR bNumInterfaces;
UCHAR bConfigurationValue;
UCHAR iConfiguration;
UCHAR bmAttributes;
UCHAR MaxPower;
} USB_CONFIGURATION_DESCRIPTOR, *PUSB_CONFIGURATION_DESCRIPTOR;
#include <poppack.h>
typedef struct libusb_device_descriptor USB_DEVICE_DESCRIPTOR, *PUSB_DEVICE_DESCRIPTOR;
extern enum windows_version windows_version;
/* This call is only available from Vista */
extern BOOL (WINAPI *pCancelIoEx)(HANDLE, LPOVERLAPPED);
int windows_common_init(struct libusb_context *ctx);
void windows_common_exit(void);
struct windows_backend {
int (*init)(struct libusb_context *ctx);
void (*exit)(struct libusb_context *ctx);
int (*get_device_list)(struct libusb_context *ctx,
struct discovered_devs **discdevs);
int (*open)(struct libusb_device_handle *dev_handle);
void (*close)(struct libusb_device_handle *dev_handle);
int (*get_device_descriptor)(struct libusb_device *device, unsigned char *buffer);
int (*get_active_config_descriptor)(struct libusb_device *device,
unsigned char *buffer, size_t len);
int (*get_config_descriptor)(struct libusb_device *device,
uint8_t config_index, unsigned char *buffer, size_t len);
int (*get_config_descriptor_by_value)(struct libusb_device *device,
uint8_t bConfigurationValue, unsigned char **buffer);
int (*get_configuration)(struct libusb_device_handle *dev_handle, int *config);
int (*set_configuration)(struct libusb_device_handle *dev_handle, int config);
int (*claim_interface)(struct libusb_device_handle *dev_handle, int interface_number);
int (*release_interface)(struct libusb_device_handle *dev_handle, int interface_number);
int (*set_interface_altsetting)(struct libusb_device_handle *dev_handle,
int interface_number, int altsetting);
int (*clear_halt)(struct libusb_device_handle *dev_handle,
unsigned char endpoint);
int (*reset_device)(struct libusb_device_handle *dev_handle);
void (*destroy_device)(struct libusb_device *dev);
int (*submit_transfer)(struct usbi_transfer *itransfer);
int (*cancel_transfer)(struct usbi_transfer *itransfer);
void (*clear_transfer_priv)(struct usbi_transfer *itransfer);
int (*copy_transfer_data)(struct usbi_transfer *itransfer, uint32_t io_size);
int (*get_transfer_fd)(struct usbi_transfer *itransfer);
void (*get_overlapped_result)(struct usbi_transfer *itransfer,
DWORD *io_result, DWORD *io_size);
};
struct windows_context_priv {
const struct windows_backend *backend;
};
union windows_device_priv {
struct usbdk_device_priv usbdk_priv;
struct winusb_device_priv winusb_priv;
};
union windows_device_handle_priv {
struct usbdk_device_handle_priv usbdk_priv;
struct winusb_device_handle_priv winusb_priv;
};
union windows_transfer_priv {
struct usbdk_transfer_priv usbdk_priv;
struct winusb_transfer_priv winusb_priv;
};
extern const struct windows_backend usbdk_backend;
extern const struct windows_backend winusb_backend;
unsigned long htab_hash(const char *str);
int windows_clock_gettime(int clk_id, struct timespec *tp);
void windows_clear_transfer_priv(struct usbi_transfer *itransfer);
int windows_copy_transfer_data(struct usbi_transfer *itransfer, uint32_t io_size);
int windows_get_transfer_fd(struct usbi_transfer *itransfer);
void windows_get_overlapped_result(struct usbi_transfer *itransfer, DWORD *io_result, DWORD *io_size);
void windows_force_sync_completion(OVERLAPPED *overlapped, ULONG size);
void windows_handle_callback(struct usbi_transfer *itransfer, uint32_t io_result, uint32_t io_size);
int windows_handle_events(struct libusb_context *ctx, struct pollfd *fds, POLL_NFDS_TYPE nfds, int num_ready);
#if defined(ENABLE_LOGGING)
const char *windows_error_str(DWORD error_code);

View File

@@ -0,0 +1,137 @@
#pragma once
#include "windows_common.h"
#include <pshpack1.h>
typedef struct USB_DEVICE_DESCRIPTOR {
UCHAR bLength;
UCHAR bDescriptorType;
USHORT bcdUSB;
UCHAR bDeviceClass;
UCHAR bDeviceSubClass;
UCHAR bDeviceProtocol;
UCHAR bMaxPacketSize0;
USHORT idVendor;
USHORT idProduct;
USHORT bcdDevice;
UCHAR iManufacturer;
UCHAR iProduct;
UCHAR iSerialNumber;
UCHAR bNumConfigurations;
} USB_DEVICE_DESCRIPTOR, *PUSB_DEVICE_DESCRIPTOR;
typedef struct USB_CONFIGURATION_DESCRIPTOR {
UCHAR bLength;
UCHAR bDescriptorType;
USHORT wTotalLength;
UCHAR bNumInterfaces;
UCHAR bConfigurationValue;
UCHAR iConfiguration;
UCHAR bmAttributes;
UCHAR MaxPower;
} USB_CONFIGURATION_DESCRIPTOR, *PUSB_CONFIGURATION_DESCRIPTOR;
#include <poppack.h>
#define MAX_DEVICE_ID_LEN 200
typedef struct USB_DK_DEVICE_ID {
WCHAR DeviceID[MAX_DEVICE_ID_LEN];
WCHAR InstanceID[MAX_DEVICE_ID_LEN];
} USB_DK_DEVICE_ID, *PUSB_DK_DEVICE_ID;
typedef struct USB_DK_DEVICE_INFO {
USB_DK_DEVICE_ID ID;
ULONG64 FilterID;
ULONG64 Port;
ULONG64 Speed;
USB_DEVICE_DESCRIPTOR DeviceDescriptor;
} USB_DK_DEVICE_INFO, *PUSB_DK_DEVICE_INFO;
typedef struct USB_DK_ISO_TRANSFER_RESULT {
ULONG64 ActualLength;
ULONG64 TransferResult;
} USB_DK_ISO_TRANSFER_RESULT, *PUSB_DK_ISO_TRANSFER_RESULT;
typedef struct USB_DK_GEN_TRANSFER_RESULT {
ULONG64 BytesTransferred;
ULONG64 UsbdStatus; // USBD_STATUS code
} USB_DK_GEN_TRANSFER_RESULT, *PUSB_DK_GEN_TRANSFER_RESULT;
typedef struct USB_DK_TRANSFER_RESULT {
USB_DK_GEN_TRANSFER_RESULT GenResult;
PVOID64 IsochronousResultsArray; // array of USB_DK_ISO_TRANSFER_RESULT
} USB_DK_TRANSFER_RESULT, *PUSB_DK_TRANSFER_RESULT;
typedef struct USB_DK_TRANSFER_REQUEST {
ULONG64 EndpointAddress;
PVOID64 Buffer;
ULONG64 BufferLength;
ULONG64 TransferType;
ULONG64 IsochronousPacketsArraySize;
PVOID64 IsochronousPacketsArray;
USB_DK_TRANSFER_RESULT Result;
} USB_DK_TRANSFER_REQUEST, *PUSB_DK_TRANSFER_REQUEST;
struct usbdk_device_priv {
USB_DK_DEVICE_INFO info;
PUSB_CONFIGURATION_DESCRIPTOR *config_descriptors;
HANDLE redirector_handle;
HANDLE system_handle;
uint8_t active_configuration;
};
struct winusb_device_priv {
bool initialized;
bool root_hub;
uint8_t active_config;
uint8_t depth; // distance to HCD
const struct windows_usb_api_backend *apib;
char *dev_id;
char *path; // device interface path
int sub_api; // for WinUSB-like APIs
struct {
char *path; // each interface needs a device interface path,
const struct windows_usb_api_backend *apib; // an API backend (multiple drivers support),
int sub_api;
int8_t nb_endpoints; // and a set of endpoint addresses (USB_MAXENDPOINTS)
uint8_t *endpoint;
bool restricted_functionality; // indicates if the interface functionality is restricted
// by Windows (eg. HID keyboards or mice cannot do R/W)
} usb_interface[USB_MAXINTERFACES];
struct hid_device_priv *hid;
USB_DEVICE_DESCRIPTOR dev_descriptor;
PUSB_CONFIGURATION_DESCRIPTOR *config_descriptor; // list of pointers to the cached config descriptors
};
struct usbdk_device_handle_priv {
// Not currently used
char dummy;
};
struct winusb_device_handle_priv {
int active_interface;
struct {
HANDLE dev_handle; // WinUSB needs an extra handle for the file
HANDLE api_handle; // used by the API to communicate with the device
} interface_handle[USB_MAXINTERFACES];
int autoclaim_count[USB_MAXINTERFACES]; // For auto-release
};
struct usbdk_transfer_priv {
USB_DK_TRANSFER_REQUEST request;
struct winfd pollable_fd;
HANDLE system_handle;
PULONG64 IsochronousPacketsArray;
PUSB_DK_ISO_TRANSFER_RESULT IsochronousResultsArray;
};
struct winusb_transfer_priv {
struct winfd pollable_fd;
HANDLE handle;
uint8_t interface_number;
uint8_t *hid_buffer; // 1 byte extended data buffer, required for HID
uint8_t *hid_dest; // transfer buffer destination, required for HID
size_t hid_expected_size;
};

View File

@@ -23,19 +23,12 @@
#include <config.h>
#if defined(USE_USBDK)
#include <windows.h>
#include <cfgmgr32.h>
#include <stdio.h>
#include "libusbi.h"
#include "windows_common.h"
#include "windows_nt_common.h"
typedef CONST WCHAR *PCWCHAR;
#define wcsncpy_s wcsncpy
#include "windows_usbdk.h"
#if !defined(STATUS_SUCCESS)
@@ -63,24 +56,6 @@ typedef LONG USBD_STATUS;
#define USBD_STATUS_CANCELED ((USBD_STATUS) 0xc0010000)
#endif
static int concurrent_usage = -1;
struct usbdk_device_priv {
USB_DK_DEVICE_INFO info;
PUSB_CONFIGURATION_DESCRIPTOR *config_descriptors;
HANDLE redirector_handle;
HANDLE system_handle;
uint8_t active_configuration;
};
struct usbdk_transfer_priv {
USB_DK_TRANSFER_REQUEST request;
struct winfd pollable_fd;
HANDLE system_handle;
PULONG64 IsochronousPacketsArray;
PUSB_DK_ISO_TRANSFER_RESULT IsochronousResultsArray;
};
static inline struct usbdk_device_priv *_usbdk_device_priv(struct libusb_device *dev)
{
return (struct usbdk_device_priv *)dev->os_priv;
@@ -114,7 +89,7 @@ static FARPROC get_usbdk_proc_addr(struct libusb_context *ctx, LPCSTR api_name)
FARPROC api_ptr = GetProcAddress(usbdk_helper.module, api_name);
if (api_ptr == NULL)
usbi_err(ctx, "UsbDkHelper API %s not found, error %d", api_name, GetLastError());
usbi_err(ctx, "UsbDkHelper API %s not found: %s", api_name, windows_error_str(0));
return api_ptr;
}
@@ -131,7 +106,7 @@ static int load_usbdk_helper_dll(struct libusb_context *ctx)
{
usbdk_helper.module = LoadLibraryA("UsbDkHelper");
if (usbdk_helper.module == NULL) {
usbi_err(ctx, "Failed to load UsbDkHelper.dll, error %d", GetLastError());
usbi_err(ctx, "Failed to load UsbDkHelper.dll: %s", windows_error_str(0));
return LIBUSB_ERROR_NOT_FOUND;
}
@@ -197,30 +172,33 @@ error_unload:
static int usbdk_init(struct libusb_context *ctx)
{
int r;
SC_HANDLE managerHandle;
SC_HANDLE serviceHandle;
if (++concurrent_usage == 0) { // First init?
r = load_usbdk_helper_dll(ctx);
if (r)
goto init_exit;
r = windows_common_init(ctx);
if (r)
goto init_exit;
}
// At this stage, either we went through full init successfully, or didn't need to
r = LIBUSB_SUCCESS;
init_exit:
if (!concurrent_usage && r != LIBUSB_SUCCESS) { // First init failed?
windows_common_exit();
unload_usbdk_helper_dll();
managerHandle = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
if (managerHandle == NULL) {
usbi_warn(ctx, "failed to open service control manager: %s", windows_error_str(0));
return LIBUSB_ERROR_OTHER;
}
if (r != LIBUSB_SUCCESS)
--concurrent_usage; // Not expected to call libusb_exit if we failed.
serviceHandle = OpenServiceA(managerHandle, "UsbDk", GENERIC_READ);
CloseServiceHandle(managerHandle);
return r;
if (serviceHandle == NULL) {
if (GetLastError() != ERROR_SERVICE_DOES_NOT_EXIST)
usbi_warn(ctx, "failed to open UsbDk service: %s", windows_error_str(0));
return LIBUSB_ERROR_NOT_FOUND;
}
CloseServiceHandle(serviceHandle);
return load_usbdk_helper_dll(ctx);
}
static void usbdk_exit(struct libusb_context *ctx)
{
UNUSED(ctx);
unload_usbdk_helper_dll();
}
static int usbdk_get_session_id_for_device(struct libusb_context *ctx,
@@ -296,7 +274,7 @@ static void usbdk_device_init(libusb_device *dev, PUSB_DK_DEVICE_INFO info)
dev->device_address = (uint8_t)(info->Port + 1);
dev->num_configurations = info->DeviceDescriptor.bNumConfigurations;
dev->device_descriptor = info->DeviceDescriptor;
memcpy(&dev->device_descriptor, &info->DeviceDescriptor, LIBUSB_DT_DEVICE_SIZE);
switch (info->Speed) {
case LowSpeed:
@@ -326,7 +304,7 @@ static int usbdk_get_device_list(struct libusb_context *ctx, struct discovered_d
ULONG dev_number;
PUSB_DK_DEVICE_INFO devices;
if(!usbdk_helper.GetDevicesList(&devices, &dev_number))
if (!usbdk_helper.GetDevicesList(&devices, &dev_number))
return LIBUSB_ERROR_OTHER;
for (i = 0; i < dev_number; i++) {
@@ -367,26 +345,16 @@ func_exit:
return r;
}
static void usbdk_exit(struct libusb_context *ctx)
{
UNUSED(ctx);
if (--concurrent_usage < 0) {
windows_common_exit();
unload_usbdk_helper_dll();
}
}
static int usbdk_get_device_descriptor(struct libusb_device *dev, unsigned char *buffer, int *host_endian)
static int usbdk_get_device_descriptor(struct libusb_device *dev, unsigned char *buffer)
{
struct usbdk_device_priv *priv = _usbdk_device_priv(dev);
memcpy(buffer, &priv->info.DeviceDescriptor, DEVICE_DESC_LENGTH);
*host_endian = 0;
return LIBUSB_SUCCESS;
}
static int usbdk_get_config_descriptor(struct libusb_device *dev, uint8_t config_index, unsigned char *buffer, size_t len, int *host_endian)
static int usbdk_get_config_descriptor(struct libusb_device *dev, uint8_t config_index, unsigned char *buffer, size_t len)
{
struct usbdk_device_priv *priv = _usbdk_device_priv(dev);
PUSB_CONFIGURATION_DESCRIPTOR config_header;
@@ -399,15 +367,13 @@ static int usbdk_get_config_descriptor(struct libusb_device *dev, uint8_t config
size = min(config_header->wTotalLength, len);
memcpy(buffer, config_header, size);
*host_endian = 0;
return (int)size;
}
static inline int usbdk_get_active_config_descriptor(struct libusb_device *dev, unsigned char *buffer, size_t len, int *host_endian)
static inline int usbdk_get_active_config_descriptor(struct libusb_device *dev, unsigned char *buffer, size_t len)
{
return usbdk_get_config_descriptor(dev, _usbdk_device_priv(dev)->active_configuration,
buffer, len, host_endian);
buffer, len);
}
static int usbdk_open(struct libusb_device_handle *dev_handle)
@@ -508,7 +474,7 @@ static void usbdk_destroy_device(struct libusb_device *dev)
usbdk_release_config_descriptors(p, p->info.DeviceDescriptor.bNumConfigurations);
}
void windows_clear_transfer_priv(struct usbi_transfer *itransfer)
static void usbdk_clear_transfer_priv(struct usbi_transfer *itransfer)
{
struct usbdk_transfer_priv *transfer_priv = _usbdk_transfer_priv(itransfer);
struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
@@ -678,7 +644,7 @@ static int usbdk_do_submit_transfer(struct usbi_transfer *itransfer,
r = transfer_fn(itransfer);
if (r != LIBUSB_SUCCESS) {
usbi_remove_pollfd(ctx, wfd.fd);
windows_clear_transfer_priv(itransfer);
usbdk_clear_transfer_priv(itransfer);
return r;
}
@@ -758,13 +724,13 @@ static int usbdk_cancel_transfer(struct usbi_transfer *itransfer)
}
}
int windows_copy_transfer_data(struct usbi_transfer *itransfer, uint32_t io_size)
static int usbdk_copy_transfer_data(struct usbi_transfer *itransfer, uint32_t io_size)
{
itransfer->transferred += io_size;
return LIBUSB_TRANSFER_COMPLETED;
}
int windows_get_transfer_fd(struct usbi_transfer *itransfer)
static int usbdk_get_transfer_fd(struct usbi_transfer *itransfer)
{
struct usbdk_transfer_priv *transfer_priv = _usbdk_transfer_priv(itransfer);
return transfer_priv->pollable_fd.fd;
@@ -785,7 +751,7 @@ static DWORD usbdk_translate_usbd_status(USBD_STATUS UsbdStatus)
}
}
void windows_get_overlapped_result(struct usbi_transfer *itransfer, DWORD *io_result, DWORD *io_size)
static void usbdk_get_overlapped_result(struct usbi_transfer *itransfer, DWORD *io_result, DWORD *io_size)
{
struct usbdk_transfer_priv *transfer_priv = _usbdk_transfer_priv(itransfer);
struct winfd *pollable_fd = &transfer_priv->pollable_fd;
@@ -821,57 +787,28 @@ void windows_get_overlapped_result(struct usbi_transfer *itransfer, DWORD *io_re
}
}
const struct usbi_os_backend usbi_backend = {
"Windows",
USBI_CAP_HAS_HID_ACCESS,
const struct windows_backend usbdk_backend = {
usbdk_init,
usbdk_exit,
NULL, // set_option()
usbdk_get_device_list,
NULL,
usbdk_open,
usbdk_close,
usbdk_get_device_descriptor,
usbdk_get_active_config_descriptor,
usbdk_get_config_descriptor,
NULL,
NULL,//usbdk_get_config_descriptor_by_value,
usbdk_get_configuration,
usbdk_set_configuration,
usbdk_claim_interface,
usbdk_release_interface,
usbdk_set_interface_altsetting,
usbdk_clear_halt,
usbdk_reset_device,
NULL,
NULL,
NULL, // dev_mem_alloc()
NULL, // dev_mem_free()
NULL, // kernel_driver_active()
NULL, // detach_kernel_driver()
NULL, // attach_kernel_driver()
usbdk_destroy_device,
usbdk_submit_transfer,
usbdk_cancel_transfer,
windows_clear_transfer_priv,
windows_handle_events,
NULL,
windows_clock_gettime,
0,
sizeof(struct usbdk_device_priv),
0,
sizeof(struct usbdk_transfer_priv),
usbdk_clear_transfer_priv,
usbdk_copy_transfer_data,
usbdk_get_transfer_fd,
usbdk_get_overlapped_result,
};
#endif /* USE_USBDK */

View File

@@ -23,56 +23,19 @@
#pragma once
typedef struct tag_USB_DK_DEVICE_ID {
WCHAR DeviceID[MAX_DEVICE_ID_LEN];
WCHAR InstanceID[MAX_DEVICE_ID_LEN];
} USB_DK_DEVICE_ID, *PUSB_DK_DEVICE_ID;
#include "windows_nt_common.h"
static inline void UsbDkFillIDStruct(USB_DK_DEVICE_ID *ID, PCWCHAR DeviceID, PCWCHAR InstanceID)
static inline void UsbDkFillIDStruct(USB_DK_DEVICE_ID *ID, const WCHAR *DeviceID, const WCHAR *InstanceID)
{
wcsncpy_s(ID->DeviceID, DeviceID, MAX_DEVICE_ID_LEN);
wcsncpy_s(ID->InstanceID, InstanceID, MAX_DEVICE_ID_LEN);
wcsncpy(ID->DeviceID, DeviceID, MAX_DEVICE_ID_LEN);
wcsncpy(ID->InstanceID, InstanceID, MAX_DEVICE_ID_LEN);
}
typedef struct tag_USB_DK_DEVICE_INFO {
USB_DK_DEVICE_ID ID;
ULONG64 FilterID;
ULONG64 Port;
ULONG64 Speed;
USB_DEVICE_DESCRIPTOR DeviceDescriptor;
} USB_DK_DEVICE_INFO, *PUSB_DK_DEVICE_INFO;
typedef struct tag_USB_DK_CONFIG_DESCRIPTOR_REQUEST {
typedef struct USB_DK_CONFIG_DESCRIPTOR_REQUEST {
USB_DK_DEVICE_ID ID;
ULONG64 Index;
} USB_DK_CONFIG_DESCRIPTOR_REQUEST, *PUSB_DK_CONFIG_DESCRIPTOR_REQUEST;
typedef struct tag_USB_DK_ISO_TRANSFER_RESULT {
ULONG64 ActualLength;
ULONG64 TransferResult;
} USB_DK_ISO_TRANSFER_RESULT, *PUSB_DK_ISO_TRANSFER_RESULT;
typedef struct tag_USB_DK_GEN_TRANSFER_RESULT {
ULONG64 BytesTransferred;
ULONG64 UsbdStatus; // USBD_STATUS code
} USB_DK_GEN_TRANSFER_RESULT, *PUSB_DK_GEN_TRANSFER_RESULT;
typedef struct tag_USB_DK_TRANSFER_RESULT {
USB_DK_GEN_TRANSFER_RESULT GenResult;
PVOID64 IsochronousResultsArray; // array of USB_DK_ISO_TRANSFER_RESULT
} USB_DK_TRANSFER_RESULT, *PUSB_DK_TRANSFER_RESULT;
typedef struct tag_USB_DK_TRANSFER_REQUEST {
ULONG64 EndpointAddress;
PVOID64 Buffer;
ULONG64 BufferLength;
ULONG64 TransferType;
ULONG64 IsochronousPacketsArraySize;
PVOID64 IsochronousPacketsArray;
USB_DK_TRANSFER_RESULT Result;
} USB_DK_TRANSFER_REQUEST, *PUSB_DK_TRANSFER_REQUEST;
typedef enum {
TransferFailure = 0,
TransferSuccess,

File diff suppressed because it is too large Load Diff

View File

@@ -195,37 +195,14 @@ struct hid_device_priv {
uint8_t string_index[3]; // man, prod, ser
};
struct windows_device_priv {
bool initialized;
bool root_hub;
uint8_t active_config;
uint8_t depth;
const struct windows_usb_api_backend *apib;
char *dev_id;
char *path; // device interface path
int sub_api; // for WinUSB-like APIs
struct {
char *path; // each interface needs a device interface path,
const struct windows_usb_api_backend *apib; // an API backend (multiple drivers support),
int sub_api;
int8_t nb_endpoints; // and a set of endpoint addresses (USB_MAXENDPOINTS)
uint8_t *endpoint;
bool restricted_functionality; // indicates if the interface functionality is restricted
// by Windows (eg. HID keyboards or mice cannot do R/W)
} usb_interface[USB_MAXINTERFACES];
struct hid_device_priv *hid;
USB_DEVICE_DESCRIPTOR dev_descriptor;
PUSB_CONFIGURATION_DESCRIPTOR *config_descriptor; // list of pointers to the cached config descriptors
};
static inline struct windows_device_priv *_device_priv(struct libusb_device *dev)
static inline struct winusb_device_priv *_device_priv(struct libusb_device *dev)
{
return (struct windows_device_priv *)dev->os_priv;
return (struct winusb_device_priv *)dev->os_priv;
}
static inline struct windows_device_priv *windows_device_priv_init(struct libusb_device *dev)
static inline struct winusb_device_priv *winusb_device_priv_init(struct libusb_device *dev)
{
struct windows_device_priv *p = _device_priv(dev);
struct winusb_device_priv *p = _device_priv(dev);
int i;
p->apib = &usb_api_backend[USB_API_UNSUPPORTED];
@@ -238,9 +215,9 @@ static inline struct windows_device_priv *windows_device_priv_init(struct libusb
return p;
}
static inline void windows_device_priv_release(struct libusb_device *dev)
static inline void winusb_device_priv_release(struct libusb_device *dev)
{
struct windows_device_priv *p = _device_priv(dev);
struct winusb_device_priv *p = _device_priv(dev);
int i;
free(p->dev_id);
@@ -257,33 +234,12 @@ static inline void windows_device_priv_release(struct libusb_device *dev)
}
}
struct interface_handle_t {
HANDLE dev_handle; // WinUSB needs an extra handle for the file
HANDLE api_handle; // used by the API to communicate with the device
};
struct windows_device_handle_priv {
int active_interface;
struct interface_handle_t interface_handle[USB_MAXINTERFACES];
int autoclaim_count[USB_MAXINTERFACES]; // For auto-release
};
static inline struct windows_device_handle_priv *_device_handle_priv(
static inline struct winusb_device_handle_priv *_device_handle_priv(
struct libusb_device_handle *handle)
{
return (struct windows_device_handle_priv *)handle->os_priv;
return (struct winusb_device_handle_priv *)handle->os_priv;
}
// used for async polling functions
struct windows_transfer_priv {
struct winfd pollable_fd;
HANDLE handle;
uint8_t interface_number;
uint8_t *hid_buffer; // 1 byte extended data buffer, required for HID
uint8_t *hid_dest; // transfer buffer destination, required for HID
size_t hid_expected_size;
};
// used to match a device driver (including filter drivers) against a supported API
struct driver_lookup {
char list[MAX_KEY_LENGTH + 1]; // REG_MULTI_SZ list of services (driver) names
@@ -315,11 +271,6 @@ DLL_DECLARE_FUNC_PREFIXED(WINAPI, LONG, p, RegCloseKey, (HKEY));
DLL_DECLARE_HANDLE(OLE32);
DLL_DECLARE_FUNC_PREFIXED(WINAPI, HRESULT, p, IIDFromString, (LPCOLESTR, LPIID));
/* Kernel32 dependencies */
DLL_DECLARE_HANDLE(Kernel32);
/* This call is only available from XP SP2 */
DLL_DECLARE_FUNC_PREFIXED(WINAPI, BOOL, p, IsWow64Process, (HANDLE, PBOOL));
/* SetupAPI dependencies */
DLL_DECLARE_HANDLE(SetupAPI);
DLL_DECLARE_FUNC_PREFIXED(WINAPI, HDEVINFO, p, SetupDiGetClassDevsA, (LPCGUID, PCSTR, HWND, DWORD));

View File

@@ -1 +1 @@
#define LIBUSB_NANO 11274
#define LIBUSB_NANO 11275

View File

@@ -377,6 +377,10 @@
RelativePath="..\libusb\os\windows_nt_common.c"
>
</File>
<File
RelativePath="..\libusb\os\windows_usbdk.c"
>
</File>
<File
RelativePath="..\libusb\os\windows_winusb.c"
>
@@ -427,6 +431,14 @@
RelativePath="..\libusb\os\windows_nt_common.h"
>
</File>
<File
RelativePath="..\libusb\os\windows_nt_shared_types.h"
>
</File>
<File
RelativePath="..\libusb\os\windows_usbdk.h"
>
</File>
<File
RelativePath="..\libusb\os\windows_winusb.h"
>

View File

@@ -147,6 +147,7 @@
<ClCompile Include="..\libusb\sync.c" />
<ClCompile Include="..\libusb\os\threads_windows.c" />
<ClCompile Include="..\libusb\os\windows_nt_common.c" />
<ClCompile Include="..\libusb\os\windows_usbdk.c" />
<ClCompile Include="..\libusb\os\windows_winusb.c" />
</ItemGroup>
<ItemGroup>
@@ -160,6 +161,8 @@
<ClInclude Include="..\libusb\version_nano.h" />
<ClInclude Include="..\libusb\os\windows_common.h" />
<ClInclude Include="..\libusb\os\windows_nt_common.h" />
<ClInclude Include="..\libusb\os\windows_nt_shared_types.h" />
<ClInclude Include="..\libusb\os\windows_usbdk.h" />
<ClInclude Include="..\libusb\os\windows_winusb.h" />
</ItemGroup>
<ItemGroup>

View File

@@ -38,6 +38,12 @@
<ClCompile Include="..\libusb\os\threads_windows.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\libusb\os\windows_nt_common.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\libusb\os\windows_usbdk.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\libusb\os\windows_winusb.c">
<Filter>Source Files</Filter>
</ClCompile>
@@ -61,12 +67,27 @@
<ClInclude Include="..\libusb\os\threads_windows.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\libusb\os\windows_winusb.h">
<ClInclude Include="..\libusb\version.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\libusb\version_nano.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\libusb\os\windows_common.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\libusb\os\windows_nt_common.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\libusb\os\windows_nt_shared_types.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\libusb\os\windows_usbdk.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\libusb\os\windows_winusb.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="..\libusb\libusb-1.0.def">

View File

@@ -151,6 +151,7 @@
<ClCompile Include="..\libusb\sync.c" />
<ClCompile Include="..\libusb\os\threads_windows.c" />
<ClCompile Include="..\libusb\os\windows_nt_common.c" />
<ClCompile Include="..\libusb\os\windows_usbdk.c" />
<ClCompile Include="..\libusb\os\windows_winusb.c" />
</ItemGroup>
<ItemGroup>
@@ -164,6 +165,8 @@
<ClInclude Include="..\libusb\version_nano.h" />
<ClInclude Include="..\libusb\os\windows_common.h" />
<ClInclude Include="..\libusb\os\windows_nt_common.h" />
<ClInclude Include="..\libusb\os\windows_nt_shared_types.h" />
<ClInclude Include="..\libusb\os\windows_usbdk.h" />
<ClInclude Include="..\libusb\os\windows_winusb.h" />
</ItemGroup>
<ItemGroup>

View File

@@ -20,6 +20,9 @@
<ClCompile Include="..\libusb\descriptor.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\libusb\hotplug.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\libusb\io.c">
<Filter>Source Files</Filter>
</ClCompile>
@@ -35,10 +38,13 @@
<ClCompile Include="..\libusb\os\threads_windows.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\libusb\os\windows_winusb.c">
<ClCompile Include="..\libusb\os\windows_nt_common.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\libusb\hotplug.c">
<ClCompile Include="..\libusb\os\windows_usbdk.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\libusb\os\windows_winusb.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
@@ -46,6 +52,9 @@
<ClInclude Include=".\config.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\libusb\hotplug.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\libusb\libusb.h">
<Filter>Header Files</Filter>
</ClInclude>
@@ -58,16 +67,25 @@
<ClInclude Include="..\libusb\os\threads_windows.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\libusb\os\windows_winusb.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\libusb\version.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\libusb\version_nano.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\libusb\hotplug.h">
<ClInclude Include="..\libusb\os\windows_common.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\libusb\os\windows_nt_common.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\libusb\os\windows_nt_shared_types.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\libusb\os\windows_usbdk.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\libusb\os\windows_winusb.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>

View File

@@ -151,6 +151,7 @@
<ClCompile Include="..\libusb\sync.c" />
<ClCompile Include="..\libusb\os\threads_windows.c" />
<ClCompile Include="..\libusb\os\windows_nt_common.c" />
<ClCompile Include="..\libusb\os\windows_usbdk.c" />
<ClCompile Include="..\libusb\os\windows_winusb.c" />
</ItemGroup>
<ItemGroup>
@@ -164,6 +165,8 @@
<ClInclude Include="..\libusb\version_nano.h" />
<ClInclude Include="..\libusb\os\windows_common.h" />
<ClInclude Include="..\libusb\os\windows_nt_common.h" />
<ClInclude Include="..\libusb\os\windows_nt_shared_types.h" />
<ClInclude Include="..\libusb\os\windows_usbdk.h" />
<ClInclude Include="..\libusb\os\windows_winusb.h" />
</ItemGroup>
<ItemGroup>

View File

@@ -151,6 +151,7 @@
<ClCompile Include="..\libusb\sync.c" />
<ClCompile Include="..\libusb\os\threads_windows.c" />
<ClCompile Include="..\libusb\os\windows_nt_common.c" />
<ClCompile Include="..\libusb\os\windows_usbdk.c" />
<ClCompile Include="..\libusb\os\windows_winusb.c" />
</ItemGroup>
<ItemGroup>
@@ -164,6 +165,8 @@
<ClInclude Include="..\libusb\version_nano.h" />
<ClInclude Include="..\libusb\os\windows_common.h" />
<ClInclude Include="..\libusb\os\windows_nt_common.h" />
<ClInclude Include="..\libusb\os\windows_nt_shared_types.h" />
<ClInclude Include="..\libusb\os\windows_usbdk.h" />
<ClInclude Include="..\libusb\os\windows_winusb.h" />
</ItemGroup>
<ItemGroup>

View File

@@ -151,6 +151,7 @@
<ClCompile Include="..\libusb\sync.c" />
<ClCompile Include="..\libusb\os\threads_windows.c" />
<ClCompile Include="..\libusb\os\windows_nt_common.c" />
<ClCompile Include="..\libusb\os\windows_usbdk.c" />
<ClCompile Include="..\libusb\os\windows_winusb.c" />
</ItemGroup>
<ItemGroup>
@@ -164,6 +165,8 @@
<ClInclude Include="..\libusb\version_nano.h" />
<ClInclude Include="..\libusb\os\windows_common.h" />
<ClInclude Include="..\libusb\os\windows_nt_common.h" />
<ClInclude Include="..\libusb\os\windows_nt_shared_types.h" />
<ClInclude Include="..\libusb\os\windows_usbdk.h" />
<ClInclude Include="..\libusb\os\windows_winusb.h" />
</ItemGroup>
<ItemGroup>

View File

@@ -32,13 +32,13 @@ TARGETLIBS=$(SDK_LIB_PATH)\kernel32.lib
SOURCES=..\core.c \
..\descriptor.c \
..\hotplug.c \
..\io.c \
..\strerror.c \
..\sync.c \
..\hotplug.c \
threads_windows.c \
poll_windows.c \
windows_winusb.c \
windows_usbdk.c \
windows_nt_common.c \
windows_usbdk.c \
windows_winusb.c \
..\libusb-1.0.rc

View File

@@ -317,6 +317,10 @@
RelativePath="..\libusb\os\windows_nt_common.c"
>
</File>
<File
RelativePath="..\libusb\os\windows_usbdk.c"
>
</File>
<File
RelativePath="..\libusb\os\windows_winusb.c"
>
@@ -367,6 +371,14 @@
RelativePath="..\libusb\os\windows_nt_common.h"
>
</File>
<File
RelativePath="..\libusb\os\windows_nt_shared_types.h"
>
</File>
<File
RelativePath="..\libusb\os\windows_usbdk.h"
>
</File>
<File
RelativePath="..\libusb\os\windows_winusb.h"
>

View File

@@ -137,6 +137,7 @@
<ClCompile Include="..\libusb\sync.c" />
<ClCompile Include="..\libusb\os\threads_windows.c" />
<ClCompile Include="..\libusb\os\windows_nt_common.c" />
<ClCompile Include="..\libusb\os\windows_usbdk.c" />
<ClCompile Include="..\libusb\os\windows_winusb.c" />
</ItemGroup>
<ItemGroup>
@@ -150,6 +151,8 @@
<ClInclude Include="..\libusb\version_nano.h" />
<ClInclude Include="..\libusb\os\windows_common.h" />
<ClInclude Include="..\libusb\os\windows_nt_common.h" />
<ClInclude Include="..\libusb\os\windows_nt_shared_types.h" />
<ClInclude Include="..\libusb\os\windows_usbdk.h" />
<ClInclude Include="..\libusb\os\windows_winusb.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

View File

@@ -17,6 +17,9 @@
<ClCompile Include="..\libusb\descriptor.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\libusb\hotplug.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\libusb\io.c">
<Filter>Source Files</Filter>
</ClCompile>
@@ -32,10 +35,13 @@
<ClCompile Include="..\libusb\os\threads_windows.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\libusb\os\windows_winusb.c">
<ClCompile Include="..\libusb\os\windows_nt_common.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\libusb\hotplug.c">
<ClCompile Include="..\libusb\os\windows_usbdk.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\libusb\os\windows_winusb.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
@@ -43,6 +49,9 @@
<ClInclude Include=".\config.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\libusb\hotplug.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\libusb\libusb.h">
<Filter>Header Files</Filter>
</ClInclude>
@@ -55,19 +64,25 @@
<ClInclude Include="..\libusb\os\threads_windows.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\libusb\os\windows_winusb.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\libusb\os\windows_common.h">
<ClInclude Include="..\libusb\version.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\libusb\version_nano.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\libusb\version.h">
<ClInclude Include="..\libusb\os\windows_common.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\libusb\hotplug.h">
<ClInclude Include="..\libusb\os\windows_nt_common.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\libusb\os\windows_nt_shared_types.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\libusb\os\windows_usbdk.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\libusb\os\windows_winusb.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>

View File

@@ -141,6 +141,7 @@
<ClCompile Include="..\libusb\sync.c" />
<ClCompile Include="..\libusb\os\threads_windows.c" />
<ClCompile Include="..\libusb\os\windows_nt_common.c" />
<ClCompile Include="..\libusb\os\windows_usbdk.c" />
<ClCompile Include="..\libusb\os\windows_winusb.c" />
</ItemGroup>
<ItemGroup>
@@ -154,6 +155,8 @@
<ClInclude Include="..\libusb\version_nano.h" />
<ClInclude Include="..\libusb\os\windows_common.h" />
<ClInclude Include="..\libusb\os\windows_nt_common.h" />
<ClInclude Include="..\libusb\os\windows_nt_shared_types.h" />
<ClInclude Include="..\libusb\os\windows_usbdk.h" />
<ClInclude Include="..\libusb\os\windows_winusb.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

View File

@@ -17,6 +17,9 @@
<ClCompile Include="..\libusb\descriptor.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\libusb\hotplug.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\libusb\io.c">
<Filter>Source Files</Filter>
</ClCompile>
@@ -32,10 +35,13 @@
<ClCompile Include="..\libusb\os\threads_windows.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\libusb\os\windows_winusb.c">
<ClCompile Include="..\libusb\os\windows_nt_common.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\libusb\hotplug.c">
<ClCompile Include="..\libusb\os\windows_usbdk.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\libusb\os\windows_winusb.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
@@ -43,6 +49,9 @@
<ClInclude Include=".\config.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\libusb\hotplug.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\libusb\libusb.h">
<Filter>Header Files</Filter>
</ClInclude>
@@ -55,19 +64,25 @@
<ClInclude Include="..\libusb\os\threads_windows.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\libusb\os\windows_winusb.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\libusb\os\windows_common.h">
<ClInclude Include="..\libusb\version.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\libusb\version_nano.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\libusb\version.h">
<ClInclude Include="..\libusb\os\windows_common.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\libusb\hotplug.h">
<ClInclude Include="..\libusb\os\windows_nt_common.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\libusb\os\windows_nt_shared_types.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\libusb\os\windows_usbdk.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\libusb\os\windows_winusb.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>

View File

@@ -141,6 +141,7 @@
<ClCompile Include="..\libusb\sync.c" />
<ClCompile Include="..\libusb\os\threads_windows.c" />
<ClCompile Include="..\libusb\os\windows_nt_common.c" />
<ClCompile Include="..\libusb\os\windows_usbdk.c" />
<ClCompile Include="..\libusb\os\windows_winusb.c" />
</ItemGroup>
<ItemGroup>
@@ -154,6 +155,8 @@
<ClInclude Include="..\libusb\version_nano.h" />
<ClInclude Include="..\libusb\os\windows_common.h" />
<ClInclude Include="..\libusb\os\windows_nt_common.h" />
<ClInclude Include="..\libusb\os\windows_nt_shared_types.h" />
<ClInclude Include="..\libusb\os\windows_usbdk.h" />
<ClInclude Include="..\libusb\os\windows_winusb.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

View File

@@ -145,6 +145,7 @@
<ClCompile Include="..\libusb\sync.c" />
<ClCompile Include="..\libusb\os\threads_windows.c" />
<ClCompile Include="..\libusb\os\windows_nt_common.c" />
<ClCompile Include="..\libusb\os\windows_usbdk.c" />
<ClCompile Include="..\libusb\os\windows_winusb.c" />
</ItemGroup>
<ItemGroup>
@@ -158,6 +159,8 @@
<ClInclude Include="..\libusb\version_nano.h" />
<ClInclude Include="..\libusb\os\windows_common.h" />
<ClInclude Include="..\libusb\os\windows_nt_common.h" />
<ClInclude Include="..\libusb\os\windows_nt_shared_types.h" />
<ClInclude Include="..\libusb\os\windows_usbdk.h" />
<ClInclude Include="..\libusb\os\windows_winusb.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

View File

@@ -145,6 +145,7 @@
<ClCompile Include="..\libusb\sync.c" />
<ClCompile Include="..\libusb\os\threads_windows.c" />
<ClCompile Include="..\libusb\os\windows_nt_common.c" />
<ClCompile Include="..\libusb\os\windows_usbdk.c" />
<ClCompile Include="..\libusb\os\windows_winusb.c" />
</ItemGroup>
<ItemGroup>
@@ -158,6 +159,8 @@
<ClInclude Include="..\libusb\version_nano.h" />
<ClInclude Include="..\libusb\os\windows_common.h" />
<ClInclude Include="..\libusb\os\windows_nt_common.h" />
<ClInclude Include="..\libusb\os\windows_nt_shared_types.h" />
<ClInclude Include="..\libusb\os\windows_usbdk.h" />
<ClInclude Include="..\libusb\os\windows_winusb.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />