From 7bad6444250ba8a0554c8095a2cc077cc3960cc2 Mon Sep 17 00:00:00 2001 From: Pete Batard Date: Wed, 3 Feb 2010 18:29:57 +0000 Subject: r139: improved CancelIoEx vs CancelIo detection(Michael Plante, Orin Eman) --- libusb/os/windows_compat.c | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/libusb/os/windows_compat.c b/libusb/os/windows_compat.c index 06f165a..301872b 100644 --- a/libusb/os/windows_compat.c +++ b/libusb/os/windows_compat.c @@ -67,10 +67,6 @@ #include #include #include -#if defined(_MSC_VER) && (_MSC_VER > 1200) -// For VER_PRODUCTBUILD used in the cancel_io inline -#include -#endif #include "windows_compat.h" @@ -137,22 +133,20 @@ BOOLEAN is_polling_set = FALSE; LONG pipe_number = 0; static volatile LONG compat_spinlock = 0; -// Attempt to use CancelIoEx on platforms and environments supporting it -// NB: this fucntion doesn't care about the validity of the handles +// CancelIoEx, available on Vista and later only, provides the ability to cancel +// a single transfer (OVERLAPPED) when used. As it may not be part of any of the +// platform headers, we hook into the Kernel32 system DLL directly to seek it. +static BOOL (__stdcall *pCancelIoEx)(HANDLE, LPOVERLAPPED) = NULL; __inline BOOL cancel_io(int index) { if ((index < 0) || (index >= MAX_FDS)) { return FALSE; } - if (windows_version < WINDOWS_VISTA_AND_LATER) { + if (pCancelIoEx != NULL) { + return (*pCancelIoEx)(poll_fd[index].handle, poll_fd[index].overlapped); + } else { return CancelIo(poll_fd[index].handle); } - // cygwin and MinGW don't have Ex for now... -#if !defined(_MSC_VER) || !defined(VER_PRODUCTBUILD) || (VER_PRODUCTBUILD<6000) - return CancelIo(poll_fd[index].handle); -#else - return CancelIoEx(poll_fd[index].handle, poll_fd[index].overlapped); -#endif } // Init @@ -164,6 +158,10 @@ void init_polling(void) SleepEx(0, TRUE); } if (!is_polling_set) { + pCancelIoEx = (BOOL (__stdcall *)(HANDLE,LPOVERLAPPED)) + GetProcAddress(GetModuleHandle("KERNEL32"), "CancelIoEx"); + printb("init_polling: Will use CancelIo%s for I/O cancellation\n", + (pCancelIoEx != NULL)?"Ex":""); for (i=0; i