Windows: Drop support for Windows XP
authorChris Dickens <christopher.a.dickens@gmail.com>
Wed, 22 Jan 2020 00:13:07 +0000 (16:13 -0800)
committerChris Dickens <christopher.a.dickens@gmail.com>
Wed, 22 Jan 2020 00:13:07 +0000 (16:13 -0800)
XP is nearly 20 years old and there are hoops we jump through to keep
supporting it. Time to say goodbye and simplify some things.

Closes #267

Signed-off-by: Chris Dickens <christopher.a.dickens@gmail.com>
16 files changed:
configure.ac
libusb/os/threads_windows.c
libusb/os/threads_windows.h
libusb/os/windows_common.c
libusb/os/windows_common.h
libusb/os/windows_usbdk.c
libusb/os/windows_winusb.c
libusb/version_nano.h
msvc/libusb_dll_2013.vcxproj
msvc/libusb_dll_2015.vcxproj
msvc/libusb_dll_2017.vcxproj
msvc/libusb_dll_2019.vcxproj
msvc/libusb_static_2013.vcxproj
msvc/libusb_static_2015.vcxproj
msvc/libusb_static_2017.vcxproj
msvc/libusb_static_2019.vcxproj

index ddde325..0bd2cd8 100644 (file)
@@ -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])
index 030f89e..27b1fb5 100644 (file)
@@ -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
 
 #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
index e971163..3a98df5 100644 (file)
@@ -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)
index 577899a..e69d0b0 100644 (file)
@@ -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;
        }
index 7533573..069b147 100644 (file)
@@ -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 {
index aa48ce2..bbec3d8 100644 (file)
@@ -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)
index ddd6e86..9fd188f 100644 (file)
@@ -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;
 }
 
index ff18b42..a8f90d9 100644 (file)
@@ -1 +1 @@
-#define LIBUSB_NANO 11432
+#define LIBUSB_NANO 11433
index 2526945..b858f77 100644 (file)
@@ -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'">
index b89f7d4..4a73ef7 100644 (file)
@@ -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'">
index 63767cd..20fa6c4 100644 (file)
@@ -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'">
index 5dc8ae8..69e42e1 100644 (file)
@@ -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'">
index d74730a..559acf1 100644 (file)
@@ -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>
index 336441b..ba07666 100644 (file)
@@ -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>
index 7d157aa..08816d2 100644 (file)
@@ -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>
index 894bc92..24ab3e3 100644 (file)
@@ -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>