diff options
-rw-r--r-- | configure.ac | 3 | ||||
-rw-r--r-- | libusb/os/threads_windows.c | 96 | ||||
-rw-r--r-- | libusb/os/threads_windows.h | 30 | ||||
-rw-r--r-- | libusb/os/windows_common.c | 16 | ||||
-rw-r--r-- | libusb/os/windows_common.h | 3 | ||||
-rw-r--r-- | libusb/os/windows_usbdk.c | 18 | ||||
-rw-r--r-- | libusb/os/windows_winusb.c | 17 | ||||
-rw-r--r-- | libusb/version_nano.h | 2 | ||||
-rw-r--r-- | msvc/libusb_dll_2013.vcxproj | 2 | ||||
-rw-r--r-- | msvc/libusb_dll_2015.vcxproj | 2 | ||||
-rw-r--r-- | msvc/libusb_dll_2017.vcxproj | 2 | ||||
-rw-r--r-- | msvc/libusb_dll_2019.vcxproj | 2 | ||||
-rw-r--r-- | msvc/libusb_static_2013.vcxproj | 2 | ||||
-rw-r--r-- | msvc/libusb_static_2015.vcxproj | 2 | ||||
-rw-r--r-- | msvc/libusb_static_2017.vcxproj | 2 | ||||
-rw-r--r-- | msvc/libusb_static_2019.vcxproj | 2 |
16 files changed, 50 insertions, 151 deletions
diff --git a/configure.ac b/configure.ac index ddde325..0bd2cd8 100644 --- a/configure.ac +++ b/configure.ac @@ -178,8 +178,7 @@ windows) LIBS="" LTLDFLAGS="${LTLDFLAGS} -avoid-version -Wl,--add-stdcall-alias" AC_DEFINE([POLL_NFDS_TYPE],[unsigned int],[type of second poll() argument]) - AC_DEFINE([WINVER], 0x0501, [Oldest Windows version supported]) - AC_DEFINE([_WIN32_WINNT], 0x0501, [Oldest Windows version supported]) + AC_DEFINE([_WIN32_WINNT], [_WIN32_WINNT_VISTA], [Oldest Windows version supported (Vista)]) ;; haiku) AC_DEFINE(OS_HAIKU, 1, [Haiku backend]) diff --git a/libusb/os/threads_windows.c b/libusb/os/threads_windows.c index 030f89e..27b1fb5 100644 --- a/libusb/os/threads_windows.c +++ b/libusb/os/threads_windows.c @@ -2,6 +2,7 @@ * libusb synchronization on Microsoft Windows * * Copyright © 2010 Michael Plante <michael.plante@gmail.com> + * Copyright © 2020 Chris Dickens <christopher.a.dickens@gmail.com> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -24,97 +25,20 @@ #include "libusbi.h" -struct usbi_cond_perthread { - struct list_head list; - HANDLE event; -}; - -void usbi_cond_init(usbi_cond_t *cond) -{ - list_init(&cond->waiters); - list_init(&cond->not_waiting); -} - -static int usbi_cond_intwait(usbi_cond_t *cond, - usbi_mutex_t *mutex, DWORD timeout_ms) -{ - struct usbi_cond_perthread *pos; - DWORD r; - - // Same assumption as usbi_cond_broadcast() holds - if (list_empty(&cond->not_waiting)) { - pos = malloc(sizeof(*pos)); - if (pos == NULL) - return ENOMEM; // This errno is not POSIX-allowed. - pos->event = CreateEvent(NULL, FALSE, FALSE, NULL); // auto-reset. - if (pos->event == NULL) { - free(pos); - return ENOMEM; - } - } else { - pos = list_first_entry(&cond->not_waiting, struct usbi_cond_perthread, list); - list_del(&pos->list); // remove from not_waiting list. - // Ensure the event is clear before waiting - WaitForSingleObject(pos->event, 0); - } - - list_add(&pos->list, &cond->waiters); - - LeaveCriticalSection(mutex); - r = WaitForSingleObject(pos->event, timeout_ms); - EnterCriticalSection(mutex); - - list_del(&pos->list); - list_add(&pos->list, &cond->not_waiting); - - if (r == WAIT_OBJECT_0) - return 0; - else if (r == WAIT_TIMEOUT) - return ETIMEDOUT; - else - return EINVAL; -} - -// N.B.: usbi_cond_*wait() can also return ENOMEM, even though pthread_cond_*wait cannot! -int usbi_cond_wait(usbi_cond_t *cond, usbi_mutex_t *mutex) -{ - return usbi_cond_intwait(cond, mutex, INFINITE); -} - int usbi_cond_timedwait(usbi_cond_t *cond, usbi_mutex_t *mutex, const struct timeval *tv) { DWORD millis; - millis = (DWORD)(tv->tv_sec * 1000) + (tv->tv_usec / 1000); + millis = (DWORD)(tv->tv_sec * 1000L) + (tv->tv_usec / 1000L); /* round up to next millisecond */ - if (tv->tv_usec % 1000) + if (tv->tv_usec % 1000L) millis++; - return usbi_cond_intwait(cond, mutex, millis); -} - -void usbi_cond_broadcast(usbi_cond_t *cond) -{ - // Assumes mutex is locked; this is not in keeping with POSIX spec, but - // libusb does this anyway, so we simplify by not adding more sync - // primitives to the CV definition! - struct usbi_cond_perthread *pos; - - list_for_each_entry(pos, &cond->waiters, list, struct usbi_cond_perthread) - SetEvent(pos->event); - // The wait function will remove its respective item from the list. -} -void usbi_cond_destroy(usbi_cond_t *cond) -{ - // This assumes no one is using this anymore. The check MAY NOT BE safe. - struct usbi_cond_perthread *pos, *next; - - if (!list_empty(&cond->waiters)) - return; // (!see above!) - list_for_each_entry_safe(pos, next, &cond->not_waiting, list, struct usbi_cond_perthread) { - CloseHandle(pos->event); - list_del(&pos->list); - free(pos); - } -} + if (SleepConditionVariableCS(cond, mutex, millis)) + return 0; + else if (GetLastError() == ERROR_TIMEOUT) + return ETIMEDOUT; + else + return EINVAL; +}
\ No newline at end of file diff --git a/libusb/os/threads_windows.h b/libusb/os/threads_windows.h index e971163..3a98df5 100644 --- a/libusb/os/threads_windows.h +++ b/libusb/os/threads_windows.h @@ -57,7 +57,7 @@ static inline void usbi_mutex_destroy(usbi_mutex_t *mutex) } // We *were* getting timespec from pthread.h: -#if (!defined(HAVE_STRUCT_TIMESPEC) && !defined(_TIMESPEC_DEFINED)) +#if !defined(HAVE_STRUCT_TIMESPEC) && !defined(_TIMESPEC_DEFINED) #define HAVE_STRUCT_TIMESPEC 1 #define _TIMESPEC_DEFINED 1 struct timespec { @@ -71,19 +71,25 @@ struct timespec { #define ETIMEDOUT 10060 /* This is the value in winsock.h. */ #endif -typedef struct usbi_cond { - // Every time a thread touches the CV, it winds up in one of these lists. - // It stays there until the CV is destroyed, even if the thread terminates. - struct list_head waiters; - struct list_head not_waiting; -} usbi_cond_t; - -void usbi_cond_init(usbi_cond_t *cond); -int usbi_cond_wait(usbi_cond_t *cond, usbi_mutex_t *mutex); +typedef CONDITION_VARIABLE usbi_cond_t; +static inline void usbi_cond_init(usbi_cond_t *cond) +{ + InitializeConditionVariable(cond); +} +static inline void usbi_cond_wait(usbi_cond_t *cond, usbi_mutex_t *mutex) +{ + (void)SleepConditionVariableCS(cond, mutex, INFINITE); +} int usbi_cond_timedwait(usbi_cond_t *cond, usbi_mutex_t *mutex, const struct timeval *tv); -void usbi_cond_broadcast(usbi_cond_t *cond); -void usbi_cond_destroy(usbi_cond_t *cond); +static inline void usbi_cond_broadcast(usbi_cond_t *cond) +{ + WakeAllConditionVariable(cond); +} +static inline void usbi_cond_destroy(usbi_cond_t *cond) +{ + UNUSED(cond); +} typedef DWORD usbi_tls_key_t; static inline void usbi_tls_key_create(usbi_tls_key_t *key) diff --git a/libusb/os/windows_common.c b/libusb/os/windows_common.c index 577899a..e69d0b0 100644 --- a/libusb/os/windows_common.c +++ b/libusb/os/windows_common.c @@ -34,7 +34,6 @@ #define EPOCH_TIME UINT64_C(116444736000000000) // 1970.01.01 00:00:000 in MS Filetime // Public -BOOL (WINAPI *pCancelIoEx)(HANDLE, LPOVERLAPPED); enum windows_version windows_version = WINDOWS_UNDEFINED; // Global variables for init/exit @@ -59,11 +58,6 @@ 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)); @@ -287,12 +281,6 @@ void windows_force_sync_completion(OVERLAPPED *overlapped, ULONG size) static BOOL windows_init_dlls(void) { - DLL_GET_HANDLE(Kernel32); - DLL_LOAD_FUNC_PREFIXED(Kernel32, p, IsWow64Process, FALSE); - pCancelIoEx = (BOOL (WINAPI *)(HANDLE, LPOVERLAPPED)) - GetProcAddress(DLL_HANDLE_NAME(Kernel32), "CancelIoEx"); - usbi_dbg("Will use CancelIo%s for I/O cancellation", pCancelIoEx ? "Ex" : ""); - DLL_GET_HANDLE(User32); DLL_LOAD_FUNC_PREFIXED(User32, p, GetMessageA, TRUE); DLL_LOAD_FUNC_PREFIXED(User32, p, PeekMessageA, TRUE); @@ -303,7 +291,6 @@ static BOOL windows_init_dlls(void) static void windows_exit_dlls(void) { - DLL_FREE_HANDLE(Kernel32); DLL_FREE_HANDLE(User32); } @@ -394,8 +381,7 @@ static BOOL is_x64(void) // Detect if we're running a 32 or 64 bit system if (sizeof(uintptr_t) < 8) { - if (pIsWow64Process != NULL) - pIsWow64Process(GetCurrentProcess(), &ret); + IsWow64Process(GetCurrentProcess(), &ret); } else { ret = TRUE; } diff --git a/libusb/os/windows_common.h b/libusb/os/windows_common.h index 7533573..069b147 100644 --- a/libusb/os/windows_common.h +++ b/libusb/os/windows_common.h @@ -134,9 +134,6 @@ enum windows_version { extern enum windows_version windows_version; -/* This call is only available from Vista */ -extern BOOL (WINAPI *pCancelIoEx)(HANDLE, LPOVERLAPPED); - #include <pshpack1.h> typedef struct USB_DEVICE_DESCRIPTOR { diff --git a/libusb/os/windows_usbdk.c b/libusb/os/windows_usbdk.c index aa48ce2..bbec3d8 100644 --- a/libusb/os/windows_usbdk.c +++ b/libusb/os/windows_usbdk.c @@ -728,20 +728,12 @@ static int usbdk_abort_transfers(struct usbi_transfer *itransfer) struct usbdk_transfer_priv *transfer_priv = _usbdk_transfer_priv(itransfer); struct winfd *pollable_fd = &transfer_priv->pollable_fd; - if (pCancelIoEx != NULL) { - // Use CancelIoEx if available to cancel just a single transfer - if (!pCancelIoEx(priv->system_handle, pollable_fd->overlapped)) { - usbi_err(ctx, "CancelIoEx failed: %s", windows_error_str(0)); - return LIBUSB_ERROR_NO_DEVICE; - } - } else { - if (!usbdk_helper.AbortPipe(priv->redirector_handle, transfer->endpoint)) { - usbi_err(ctx, "AbortPipe failed: %s", windows_error_str(0)); - return LIBUSB_ERROR_NO_DEVICE; - } - } + // Use CancelIoEx to cancel just a single transfer + if (CancelIoEx(priv->system_handle, pollable_fd->overlapped)) + return LIBUSB_SUCCESS; - return LIBUSB_SUCCESS; + usbi_warn(ctx, "CancelIoEx failed: %s", windows_error_str(0)); + return LIBUSB_ERROR_NOT_FOUND; } static int usbdk_cancel_transfer(struct usbi_transfer *itransfer) diff --git a/libusb/os/windows_winusb.c b/libusb/os/windows_winusb.c index ddd6e86..9fd188f 100644 --- a/libusb/os/windows_winusb.c +++ b/libusb/os/windows_winusb.c @@ -2100,8 +2100,8 @@ static int winusbx_init(struct libusb_context *ctx) if (WinUSBX[i].Initialize != NULL) { WinUSBX[i].initialized = true; - // Assume driver supports CancelIoEx() if it is available - WinUSBX[i].CancelIoEx_supported = (pCancelIoEx != NULL); + // Assume driver supports CancelIoEx() + WinUSBX[i].CancelIoEx_supported = true; usbi_dbg("initalized sub API %s", winusbx_driver_names[i]); } else { usbi_warn(ctx, "Failed to initalize sub API %s", winusbx_driver_names[i]); @@ -2926,7 +2926,7 @@ static int winusbx_abort_transfers(int sub_api, struct usbi_transfer *itransfer) if (WinUSBX[sub_api].CancelIoEx_supported) { // Try to use CancelIoEx if available to cancel just a single transfer handle = handle_priv->interface_handle[current_interface].dev_handle; - if (pCancelIoEx(handle, transfer_priv->pollable_fd.overlapped)) + if (CancelIoEx(handle, transfer_priv->pollable_fd.overlapped)) return LIBUSB_SUCCESS; else if (GetLastError() == ERROR_NOT_FOUND) return LIBUSB_ERROR_NOT_FOUND; @@ -3978,16 +3978,11 @@ static int hid_abort_transfers(int sub_api, struct usbi_transfer *itransfer) hid_handle = handle_priv->interface_handle[current_interface].api_handle; - if (pCancelIoEx != NULL) { - // Use CancelIoEx if available to cancel just a single transfer - if (pCancelIoEx(hid_handle, transfer_priv->pollable_fd.overlapped)) + // Use CancelIoEx to cancel just a single transfer + if (CancelIoEx(hid_handle, transfer_priv->pollable_fd.overlapped)) return LIBUSB_SUCCESS; - } else { - if (CancelIo(hid_handle)) - return LIBUSB_SUCCESS; - } - usbi_warn(ctx, "cancel failed: %s", windows_error_str(0)); + usbi_warn(ctx, "CancelIoEx failed: %s", windows_error_str(0)); return LIBUSB_ERROR_NOT_FOUND; } diff --git a/libusb/version_nano.h b/libusb/version_nano.h index ff18b42..a8f90d9 100644 --- a/libusb/version_nano.h +++ b/libusb/version_nano.h @@ -1 +1 @@ -#define LIBUSB_NANO 11432 +#define LIBUSB_NANO 11433 diff --git a/msvc/libusb_dll_2013.vcxproj b/msvc/libusb_dll_2013.vcxproj index 2526945..b858f77 100644 --- a/msvc/libusb_dll_2013.vcxproj +++ b/msvc/libusb_dll_2013.vcxproj @@ -46,7 +46,7 @@ <ItemDefinitionGroup> <ClCompile> <AdditionalIncludeDirectories>.;..\libusb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>WINVER=0x0501;_WIN32_WINNT=0x0501;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions>_WIN32_WINNT=_WIN32_WINNT_VISTA;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions> <WarningLevel>Level4</WarningLevel> </ClCompile> <ClCompile Condition="'$(Configuration)'=='Debug'"> diff --git a/msvc/libusb_dll_2015.vcxproj b/msvc/libusb_dll_2015.vcxproj index b89f7d4..4a73ef7 100644 --- a/msvc/libusb_dll_2015.vcxproj +++ b/msvc/libusb_dll_2015.vcxproj @@ -47,7 +47,7 @@ <ClCompile> <AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions> <AdditionalIncludeDirectories>.;..\libusb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>WINVER=0x0501;_WIN32_WINNT=0x0501;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions>_WIN32_WINNT=_WIN32_WINNT_VISTA;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions> <WarningLevel>Level4</WarningLevel> </ClCompile> <ClCompile Condition="'$(Configuration)'=='Debug'"> diff --git a/msvc/libusb_dll_2017.vcxproj b/msvc/libusb_dll_2017.vcxproj index 63767cd..20fa6c4 100644 --- a/msvc/libusb_dll_2017.vcxproj +++ b/msvc/libusb_dll_2017.vcxproj @@ -66,7 +66,7 @@ <ClCompile> <AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions> <AdditionalIncludeDirectories>.;..\libusb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>WINVER=0x0501;_WIN32_WINNT=0x0501;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions>_WIN32_WINNT=_WIN32_WINNT_VISTA;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions> <WarningLevel>Level4</WarningLevel> </ClCompile> <ClCompile Condition="'$(Configuration)'=='Debug'"> diff --git a/msvc/libusb_dll_2019.vcxproj b/msvc/libusb_dll_2019.vcxproj index 5dc8ae8..69e42e1 100644 --- a/msvc/libusb_dll_2019.vcxproj +++ b/msvc/libusb_dll_2019.vcxproj @@ -66,7 +66,7 @@ <ClCompile> <AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions> <AdditionalIncludeDirectories>.;..\libusb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>WINVER=0x0501;_WIN32_WINNT=0x0501;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions>_WIN32_WINNT=_WIN32_WINNT_VISTA;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions> <WarningLevel>Level4</WarningLevel> </ClCompile> <ClCompile Condition="'$(Configuration)'=='Debug'"> diff --git a/msvc/libusb_static_2013.vcxproj b/msvc/libusb_static_2013.vcxproj index d74730a..559acf1 100644 --- a/msvc/libusb_static_2013.vcxproj +++ b/msvc/libusb_static_2013.vcxproj @@ -46,7 +46,7 @@ <ItemDefinitionGroup> <ClCompile> <AdditionalIncludeDirectories>.;..\libusb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>WINVER=0x0501;_WIN32_WINNT=0x0501;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions>_WIN32_WINNT=_WIN32_WINNT_VISTA;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions> <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName> <WarningLevel>Level4</WarningLevel> </ClCompile> diff --git a/msvc/libusb_static_2015.vcxproj b/msvc/libusb_static_2015.vcxproj index 336441b..ba07666 100644 --- a/msvc/libusb_static_2015.vcxproj +++ b/msvc/libusb_static_2015.vcxproj @@ -47,7 +47,7 @@ <ClCompile> <AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions> <AdditionalIncludeDirectories>.;..\libusb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>WINVER=0x0501;_WIN32_WINNT=0x0501;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions>_WIN32_WINNT=_WIN32_WINNT_VISTA;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions> <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName> <WarningLevel>Level4</WarningLevel> </ClCompile> diff --git a/msvc/libusb_static_2017.vcxproj b/msvc/libusb_static_2017.vcxproj index 7d157aa..08816d2 100644 --- a/msvc/libusb_static_2017.vcxproj +++ b/msvc/libusb_static_2017.vcxproj @@ -66,7 +66,7 @@ <ClCompile> <AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions> <AdditionalIncludeDirectories>.;..\libusb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>WINVER=0x0501;_WIN32_WINNT=0x0501;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions>_WIN32_WINNT=_WIN32_WINNT_VISTA;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions> <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName> <WarningLevel>Level4</WarningLevel> </ClCompile> diff --git a/msvc/libusb_static_2019.vcxproj b/msvc/libusb_static_2019.vcxproj index 894bc92..24ab3e3 100644 --- a/msvc/libusb_static_2019.vcxproj +++ b/msvc/libusb_static_2019.vcxproj @@ -66,7 +66,7 @@ <ClCompile> <AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions> <AdditionalIncludeDirectories>.;..\libusb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>WINVER=0x0501;_WIN32_WINNT=0x0501;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions>_WIN32_WINNT=_WIN32_WINNT_VISTA;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions> <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName> <WarningLevel>Level4</WarningLevel> </ClCompile> |