summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AUTHORS2
-rw-r--r--NEWS4
-rw-r--r--README_MSVC.txt58
-rw-r--r--config_msvc.h43
-rw-r--r--configure.ac10
-rw-r--r--examples/Makefile.am10
-rw-r--r--examples/dpfp.c7
-rw-r--r--examples/dpfp_threaded.c9
-rw-r--r--examples/lsusb.c1
-rw-r--r--examples/lsusb.dsp4
-rw-r--r--examples/lsusb_2005.vcproj8
-rw-r--r--examples/lsusb_2008.vcproj8
-rw-r--r--examples/lsusb_sources15
-rw-r--r--examples/xusb.c27
-rw-r--r--examples/xusb.dsp4
-rw-r--r--examples/xusb_2005.vcproj8
-rw-r--r--examples/xusb_2008.vcproj8
-rw-r--r--examples/xusb_sources15
-rw-r--r--libusb-dll_2005.vcproj31
-rw-r--r--libusb-dll_2008.vcproj30
-rw-r--r--libusb-static_2005.vcproj18
-rw-r--r--libusb-static_2008.vcproj18
-rw-r--r--libusb/Makefile.am12
-rw-r--r--libusb/core.c213
-rw-r--r--libusb/io.c253
-rw-r--r--libusb/libusb.h16
-rw-r--r--libusb/libusbi.h80
-rw-r--r--libusb/os/darwin_usb.c211
-rw-r--r--libusb/os/linux_usbfs.c30
-rw-r--r--libusb/os/sources10
-rw-r--r--libusb/os/threads_posix.h46
-rw-r--r--libusb/os/threads_windows.c206
-rw-r--r--libusb/os/threads_windows.h83
-rw-r--r--libusb/os/unistd_posix.h12
-rw-r--r--libusb/os/windows_compat.c84
-rw-r--r--libusb/os/windows_compat.h21
-rw-r--r--libusb/os/windows_usb.c199
-rw-r--r--libusb/os/windows_usb.h4
-rw-r--r--libusb/sync.c5
-rw-r--r--libusb_dll.dsp22
-rw-r--r--libusb_static.dsp18
-rw-r--r--msvc/config.h22
-rw-r--r--msvc/pthread-win32_x64/pthread-win32.sln25
-rw-r--r--msvc/pthread-win32_x64/pthread-win32.vcproj409
44 files changed, 1129 insertions, 1190 deletions
diff --git a/AUTHORS b/AUTHORS
index b346e53..495a72e 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -1,6 +1,6 @@
Copyright (C) 2007-2009 Daniel Drake <dsd@gentoo.org>
Copyright (c) 2001 Johannes Erdfelt <johannes@erdfelt.com>
-Copyright (C) 2008-2009 Nathan Hjelm <hjelmn@users.sourceforge.net>
+Copyright (C) 2008-2010 Nathan Hjelm <hjelmn@users.sourceforge.net>
Other contributors:
Alex Vatchenko
diff --git a/NEWS b/NEWS
index ed82f1c..4d573d6 100644
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,10 @@
This file lists notable changes in each release. For the full history of all
changes, see ChangeLog.
+2009-11-22: v1.0.6
+* Bug fixes
+* Increase libusb_handle_events() timeout to 60s for powersaving
+
2009-11-15: v1.0.5
* Use timerfd when available for timer management
* Small fixes/updates
diff --git a/README_MSVC.txt b/README_MSVC.txt
index 5e4a76e..df45651 100644
--- a/README_MSVC.txt
+++ b/README_MSVC.txt
@@ -1,53 +1,25 @@
To compile libusb 1.0 using either Microsoft Visual Studio or the Windows DDK
-Note 1: For Visual Studio, 3 sets of solution files are provided depending on
-whether you are running MSVC6, Visual Studio 2008 (MSVC9) or Visual Studio 2005
-(MSVC8). For the DDK, just run ddk_build.cmd from a DDK build environment
-command prompt.
-
-Note 2: In the text below, (Win32) means "when producing 32 bit binaries" and
-(x64) "when producing 64 bit binaries". This is independent of whether your
-platform is actually 32 or 64 bit.
-
-- Download the pthread.h and sched.h headers from
- ftp://sourceware.org/pub/pthreads-win32/prebuilt-dll-2-8-0-release/include/
- into the msvc directory.
-
-- (Win32) download pthreadVC2.lib from:
- ftp://sourceware.org/pub/pthreads-win32/prebuilt-dll-2-8-0-release/lib/
- into the msvc directory.
+- If needed, edit msvc/config.h according to your needs (you might want to
+ comment out ENABLE_DEBUG_LOGGING for instance).
-- To run the 32 bit executables, download pthreadVC2.dll from the same link
- either into your executable destination or copy it into C:\Window\System32
- (for 32 bit systems) or C:\Windows\SysWOW64 (for 64 bit systems - yes, this
- is not a typo: 32 bit DLLs must go to SysWOW64 on 64 bit systems).
+That's it! You should now be able to compile the solution.
-- (x64) Follow the "Direct access to the CVS code repository" details on
- http://sourceware.org/pthreads-win32/ and create both a pthreadVC2_x64.lib
- and pthreadVC2_x64.dll from the latest pthread-win32 source.
-
- To help compiling pthreadVC2_x64.dll on x64 platforms, sample .sln and
- .vcproj files are provided in the msvc\pthread-win32_x64\ directory.
-
-- (x64) Copy pthreadVC2_x64.lib to the msvc directory.
-- To run the 64 bit executables, you need to either have pthreadVC2_x64.dll
- in your executable directory or in C:\Windows\System32 (again, not a typo).
-
-Alternativaly, precompiled pthread-win32 binaries for 64bit and 32 bit
-platforms, as well as the necessary headers can be obtained frome:
-http://libusb.org/raw-attachment/wiki/windows_backend/pthread-win32_libusb.zip
-
-- Edit config_msvc.h according to your needs (you might want to comment out
- ENABLE_DEBUG_LOGGING).
-
-You should now be able to compile the solution.
+Note 1: For Visual Studio, 3 sets of solution files are provided depending on
+whether you are running MSVC6, Visual Studio 2008 (MSVC9) or Visual Studio 2005
+(MSVC8). For the DDK, just run ddk_build.cmd from a DDK build environment
+command prompt.
-Note that if the the compilation process complains about missing libraries,
-you will need to ensure that the default library paths for your project point
-to a directory that contains setupapi.lib and ole32.lib.
-If needed, these libraries can be obtained by downloading either the latest
+Note 2: If the the compilation process complains about missing libraries, you
+will need to ensure that the default library paths for your project point to a
+directory that contains setupapi.lib and ole32.lib.
+If needed, these libraries can be obtained by downloading either the latest
Windows SDK or the DDK.
+Note 3: Provided that you have the required environment, it is possible to
+produce either a 32 or 64 bit version of the library. Both these version are
+supported and have been equally tested during development.
+
For additional information, please refer to:
http://libusb.org/wiki/windows_backend \ No newline at end of file
diff --git a/config_msvc.h b/config_msvc.h
deleted file mode 100644
index be1742c..0000000
--- a/config_msvc.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/* config_msvc.h. Manual config.h for MSVC. */
-
-/* Default visibility */
-#define API_EXPORTED /**/
-
-/* Debug message logging */
-#define ENABLE_DEBUG_LOGGING 1
-
-/* Message logging */
-#define ENABLE_LOGGING 1
-
-/* Windows backend */
-#define OS_WINDOWS /**/
-
-/* Name of package */
-#define PACKAGE "libusb"
-
-/* Define to the address where bug reports for this package should be sent. */
-#define PACKAGE_BUGREPORT ""
-
-/* Define to the full name of this package. */
-#define PACKAGE_NAME "libusb"
-
-/* Define to the full name and version of this package. */
-#define PACKAGE_STRING "libusb 1.0.5"
-
-/* Define to the one symbol short name of this package. */
-#define PACKAGE_TARNAME "libusb"
-
-/* Define to the version of this package. */
-#define PACKAGE_VERSION "1.0.5"
-
-/* Define to 1 if you have the ANSI C header files. */
-#define STDC_HEADERS 1
-
-/* Backend handles timeout */
-/* #undef USBI_OS_HANDLES_TIMEOUT */
-
-/* timerfd headers available */
-/* #undef USBI_TIMERFD_AVAILABLE */
-
-/* Version number of package */
-#define VERSION "1.0.5"
diff --git a/configure.ac b/configure.ac
index e578a58..8d3ba9d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,4 +1,4 @@
-AC_INIT([libusb], [1.0.5])
+AC_INIT([libusb], [1.0.6])
AM_INIT_AUTOMAKE
AC_CONFIG_SRCDIR([libusb/core.c])
AC_CONFIG_MACRO_DIR([m4])
@@ -11,6 +11,7 @@ AC_PROG_LIBTOOL
AC_C_INLINE
AM_PROG_CC_C_O
AC_DEFINE([_GNU_SOURCE], [], [Use GNU extensions])
+AC_DEFINE([POSIX_THREADS], [], [Posix Threads])
AC_MSG_CHECKING([operating system])
case $host in
@@ -19,6 +20,7 @@ case $host in
AC_SUBST(OS_LINUX)
AC_MSG_RESULT([Linux])
backend="linux"
+ threads="posix"
AC_CHECK_LIB(rt, clock_gettime)
AM_CFLAGS="-pthread -Wshadow"
AM_LDFLAGS=""
@@ -29,6 +31,7 @@ case $host in
AC_DEFINE(USBI_OS_HANDLES_TIMEOUT, [], [Backend handles timeout])
AC_MSG_RESULT([Darwin/MacOS X])
backend="darwin"
+ threads="posix"
AM_CFLAGS="-pthread -Wshadow"
AM_LDFLAGS="-Wl,-framework -Wl,IOKit -Wl,-framework -Wl,CoreFoundation -Wl,-prebind -no-undefined"
;;
@@ -37,7 +40,8 @@ case $host in
AC_SUBST(OS_WINDOWS)
AC_MSG_RESULT([Windows])
backend="windows"
- LIBS="-lpthreadGC2 -lsetupapi -lole32"
+ threads="windows"
+ LIBS="-lsetupapi -lole32"
AM_CFLAGS="-Wshadow"
AM_LDFLAGS="-no-undefined"
;;
@@ -46,6 +50,7 @@ case $host in
AC_SUBST(OS_WINDOWS)
AC_MSG_RESULT([Windows])
backend="windows"
+ threads="posix"
LIBS="-lpthread -lsetupapi -lole32"
AM_CFLAGS=""
AM_LDFLAGS="-no-undefined"
@@ -57,6 +62,7 @@ esac
AM_CONDITIONAL([OS_LINUX], [test "x$backend" == "xlinux"])
AM_CONDITIONAL([OS_DARWIN], [test "x$backend" == "xdarwin"])
AM_CONDITIONAL([OS_WINDOWS], [test "x$backend" == "xwindows"])
+AM_CONDITIONAL([POSIX_THREADS], [test "x$threads" == "xposix"])
# Library versioning
lt_major="0"
diff --git a/examples/Makefile.am b/examples/Makefile.am
index fe6cae4..8ffc9c5 100644
--- a/examples/Makefile.am
+++ b/examples/Makefile.am
@@ -1,6 +1,12 @@
INCLUDES = -I$(top_srcdir)
-noinst_PROGRAMS = xusb lsusb
-#dpfp dpfp_threaded
+
+if POSIX_THREADS
+DPFP_SRC = dpfp dpfp_threaded
+else
+DPFP_SRC = dpfp
+endif
+
+noinst_PROGRAMS = xusb lsusb $(DPFP_SRC)
lsusb_SOURCES = lsusb.c
lsusb_LDADD = ../libusb/libusb-1.0.la -lusb-1.0
diff --git a/examples/dpfp.c b/examples/dpfp.c
index bd9702a..e218246 100644
--- a/examples/dpfp.c
+++ b/examples/dpfp.c
@@ -416,7 +416,9 @@ static void sighandler(int signum)
int main(void)
{
+#ifndef __MINGW32__
struct sigaction sigact;
+#endif
int r = 1;
r = libusb_init(NULL);
@@ -456,12 +458,17 @@ int main(void)
if (r < 0)
goto out_deinit;
+#ifndef __MINGW32__
sigact.sa_handler = sighandler;
sigemptyset(&sigact.sa_mask);
sigact.sa_flags = 0;
sigaction(SIGINT, &sigact, NULL);
sigaction(SIGTERM, &sigact, NULL);
sigaction(SIGQUIT, &sigact, NULL);
+#else
+ signal(SIGINT, sighandler);
+ signal(SIGTERM, sighandler);
+#endif
while (!do_exit) {
r = libusb_handle_events(NULL);
diff --git a/examples/dpfp_threaded.c b/examples/dpfp_threaded.c
index 59540e3..6ae59ef 100644
--- a/examples/dpfp_threaded.c
+++ b/examples/dpfp_threaded.c
@@ -92,6 +92,7 @@ static void *poll_thread_main(void *arg)
printf("poll thread shutting down\n");
pthread_exit(NULL);
+ return NULL;
}
static int find_dpfp_device(void)
@@ -443,7 +444,9 @@ static void sighandler(int signum)
int main(void)
{
+#ifndef __MINGW32__
struct sigaction sigact;
+#endif
int r = 1;
r = libusb_init(NULL);
@@ -474,13 +477,17 @@ int main(void)
goto out_deinit;
/* async from here onwards */
-
+#ifndef __MINGW32__
sigact.sa_handler = sighandler;
sigemptyset(&sigact.sa_mask);
sigact.sa_flags = 0;
sigaction(SIGINT, &sigact, NULL);
sigaction(SIGTERM, &sigact, NULL);
sigaction(SIGQUIT, &sigact, NULL);
+#else
+ signal(SIGINT, sighandler);
+ signal(SIGTERM, sighandler);
+#endif
r = pthread_create(&poll_thread, NULL, poll_thread_main, NULL);
if (r)
diff --git a/examples/lsusb.c b/examples/lsusb.c
index f08b7cc..eb3855a 100644
--- a/examples/lsusb.c
+++ b/examples/lsusb.c
@@ -18,7 +18,6 @@
*/
#include <stdio.h>
-#include <sys/types.h>
#include <libusb/libusb.h>
#include <libusb/os/driver_install.h>
diff --git a/examples/lsusb.dsp b/examples/lsusb.dsp
index 96841be..b598ffa 100644
--- a/examples/lsusb.dsp
+++ b/examples/lsusb.dsp
@@ -50,7 +50,7 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 pthreadVC2.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib "D:/Program Files/Microsoft SDK/Lib/setupapi.lib" /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib "D:/Program Files/Microsoft SDK/Lib/setupapi.lib" /nologo /subsystem:console /machine:I386
!ELSEIF "$(CFG)" == "lsusb - Win32 Debug"
@@ -74,7 +74,7 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo /n "../Win32/Debug/dll/core.sbr" "../Win32/Debug/dll/descriptor.sbr" "../Win32/Debug/dll/io.sbr" "../Win32/Debug/dll/sync.sbr" "../Win32/Debug/dll/windows_compat.sbr" "../Win32/Debug/dll/windows_usb.sbr"
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 pthreadVC2d.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib "D:/Program Files/Microsoft SDK/Lib/setupapi.lib" /nologo /subsystem:console /debug /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib "D:/Program Files/Microsoft SDK/Lib/setupapi.lib" /nologo /subsystem:console /debug /machine:I386
# SUBTRACT LINK32 /pdb:none
!ENDIF
diff --git a/examples/lsusb_2005.vcproj b/examples/lsusb_2005.vcproj
index 0b46e40..453b2a2 100644
--- a/examples/lsusb_2005.vcproj
+++ b/examples/lsusb_2005.vcproj
@@ -64,7 +64,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="setupapi.lib pthreadVC2.lib ole32.lib advapi32.lib"
+ AdditionalDependencies="setupapi.lib ole32.lib advapi32.lib"
LinkIncremental="2"
AdditionalLibraryDirectories="..\msvc"
GenerateDebugInformation="true"
@@ -140,7 +140,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="setupapi.lib pthreadVC2.lib ole32.lib advapi32.lib"
+ AdditionalDependencies="setupapi.lib ole32.lib advapi32.lib"
LinkIncremental="1"
AdditionalLibraryDirectories="..\msvc"
GenerateDebugInformation="true"
@@ -221,7 +221,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="setupapi.lib pthreadVC2_x64.lib"
+ AdditionalDependencies="setupapi.lib"
LinkIncremental="2"
AdditionalLibraryDirectories="..\msvc"
GenerateDebugInformation="true"
@@ -298,7 +298,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="setupapi.lib pthreadVC2_x64.lib"
+ AdditionalDependencies="setupapi.lib"
LinkIncremental="1"
AdditionalLibraryDirectories="..\msvc"
GenerateDebugInformation="true"
diff --git a/examples/lsusb_2008.vcproj b/examples/lsusb_2008.vcproj
index fa0991f..168cf3f 100644
--- a/examples/lsusb_2008.vcproj
+++ b/examples/lsusb_2008.vcproj
@@ -65,7 +65,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="setupapi.lib pthreadVC2_x64.lib difxapi.lib driver_resources.res"
+ AdditionalDependencies="setupapi.lib difxapi.lib driver_resources.res"
LinkIncremental="2"
AdditionalLibraryDirectories="..\msvc;$(SolutionDir)$(PlatformName)\$(ConfigurationName)\lib\driver-resources"
GenerateDebugInformation="true"
@@ -142,7 +142,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="setupapi.lib pthreadVC2_x64.lib difxapi.lib driver_resources.res"
+ AdditionalDependencies="setupapi.lib difxapi.lib driver_resources.res"
LinkIncremental="2"
AdditionalLibraryDirectories="..\msvc;$(SolutionDir)$(PlatformName)\$(ConfigurationName)\lib\driver-resources"
GenerateDebugInformation="true"
@@ -219,7 +219,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="setupapi.lib pthreadVC2_x64.lib difxapi.lib driver_resources.res"
+ AdditionalDependencies="setupapi.lib difxapi.lib driver_resources.res"
LinkIncremental="1"
AdditionalLibraryDirectories="..\msvc;$(SolutionDir)$(PlatformName)\$(ConfigurationName)\lib\driver-resources"
GenerateDebugInformation="true"
@@ -299,7 +299,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="setupapi.lib pthreadVC2_x64.lib difxapi.lib driver_resources.res"
+ AdditionalDependencies="setupapi.lib difxapi.lib driver_resources.res"
LinkIncremental="1"
AdditionalLibraryDirectories="..\msvc;$(SolutionDir)$(PlatformName)\$(ConfigurationName)\lib\driver-resources"
GenerateDebugInformation="true"
diff --git a/examples/lsusb_sources b/examples/lsusb_sources
index fcb4c4d..82ea935 100644
--- a/examples/lsusb_sources
+++ b/examples/lsusb_sources
@@ -11,26 +11,13 @@ MSC_WARNING_LEVEL=/W3
-!IF "$(_BUILDARCH)"=="AMD64"
-
-PTHREAD_LIB=pthreadVC2_x64.lib
-
-!ELSE
-
-PTHREAD_LIB=pthreadVC2.lib
-
-!ENDIF
-
-
-
USE_MSVCRT=1
UMTYPE=console
INCLUDES=..\..\msvc;..\..;$(DDK_INC_PATH)
-UMLIBS=..\..\msvc\$(PTHREAD_LIB) \
- ..\..\libusb\os\obj$(BUILD_ALT_DIR)\*\libusb-1.0.lib
+UMLIBS=..\..\libusb\os\obj$(BUILD_ALT_DIR)\*\libusb-1.0.lib
SOURCES=..\lsusb.c
diff --git a/examples/xusb.c b/examples/xusb.c
index 15dc126..5000059 100644
--- a/examples/xusb.c
+++ b/examples/xusb.c
@@ -1,6 +1,8 @@
/*
- * xusb: libusb-winusb specific test program, (c) 2009 Pete Batard
- * based on lsusb, copyright (C) 2007 Daniel Drake <dsd@gentoo.org>
+ * xusb: libusb-winusb specific test program
+ * Copyright (c) 2009-2010 Pete Batard <pbatard@gmail.com>
+ * Based on lsusb, copyright (c) 2007 Daniel Drake <dsd@gentoo.org>
+ * With contributions to Mass Storage test by Alan Stern.
*
* This test program tries to access an USB device through WinUSB.
* To access your device, modify this source and add your VID/PID.
@@ -20,13 +22,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifdef _MSC_VER
-#include <config_msvc.h>
-#else
#include <config.h>
-#endif
#include <stdio.h>
-#include <sys/types.h>
#include <inttypes.h>
#include <stdlib.h>
#include <string.h>
@@ -35,7 +32,6 @@
#include <libusb/libusb.h>
#ifdef OS_WINDOWS
-#include <windows.h>
#define msleep(msecs) Sleep(msecs)
#else
#include <unistd.h>
@@ -497,6 +493,17 @@ int test_hid(libusb_device_handle *handle, uint8_t endpoint_in)
return -1;
}
+ printf("\nReading Feature Report...\n");
+ r = libusb_control_transfer(handle, LIBUSB_ENDPOINT_IN|LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE,
+ HID_GET_REPORT, (HID_REPORT_TYPE_FEATURE<<8)|0, 0, input_report, (uint16_t)size, 5000);
+ if (r >= 0) {
+ display_buffer_hex(input_report, size);
+ } else if (r == LIBUSB_ERROR_NOT_FOUND) {
+ printf(" No Feature Report available for this device\n");
+ } else {
+ printf(" Error: %s\n", libusb_strerror(r));
+ }
+
printf("\nReading Input Report...\n");
r = libusb_control_transfer(handle, LIBUSB_ENDPOINT_IN|LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE,
HID_GET_REPORT, (HID_REPORT_TYPE_INPUT<<8)|0x00, 0, input_report, (uint16_t)size, 5000);
@@ -508,7 +515,7 @@ int test_hid(libusb_device_handle *handle, uint8_t endpoint_in)
printf(" Timeout! Please make sure you act on the device within the 5 seconds allocated...\n");
break;
default:
- printf(" Error: %d\n", r);
+ printf(" Error: %s\n", libusb_strerror(r));
break;
}
}
@@ -614,10 +621,10 @@ int test_device(uint16_t vid, uint16_t pid)
}
#endif
+ printf("\nReading string descriptors:\n");
r = libusb_get_string_descriptor(handle, 0, 0, string, 128);
if (r > 0) {
nb_strings = string[0];
- printf("\nReading string descriptors:\n");
for (i=1; i<nb_strings; i++) {
if (libusb_get_string_descriptor_ascii(handle, (uint8_t)i, string, 128) >= 0) {
printf(" String (%d/%d): \"%s\"\n", i, nb_strings-1, string);
diff --git a/examples/xusb.dsp b/examples/xusb.dsp
index 15081c6..b47b8c0 100644
--- a/examples/xusb.dsp
+++ b/examples/xusb.dsp
@@ -50,7 +50,7 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 pthreadVC2.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib "D:/Program Files/Microsoft SDK/Lib/setupapi.lib" /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib "D:/Program Files/Microsoft SDK/Lib/setupapi.lib" /nologo /subsystem:console /machine:I386
!ELSEIF "$(CFG)" == "xusb - Win32 Debug"
@@ -74,7 +74,7 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo /n "../Win32/Debug/dll/core.sbr" "../Win32/Debug/dll/descriptor.sbr" "../Win32/Debug/dll/io.sbr" "../Win32/Debug/dll/sync.sbr" "../Win32/Debug/dll/windows_compat.sbr" "../Win32/Debug/dll/windows_usb.sbr"
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 pthreadVC2d.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib "D:/Program Files/Microsoft SDK/Lib/setupapi.lib" /nologo /subsystem:console /debug /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib "D:/Program Files/Microsoft SDK/Lib/setupapi.lib" /nologo /subsystem:console /debug /machine:I386
!ENDIF
diff --git a/examples/xusb_2005.vcproj b/examples/xusb_2005.vcproj
index 0554e05..19e771a 100644
--- a/examples/xusb_2005.vcproj
+++ b/examples/xusb_2005.vcproj
@@ -64,7 +64,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="setupapi.lib pthreadVC2.lib ole32.lib advapi32.lib"
+ AdditionalDependencies="setupapi.lib ole32.lib advapi32.lib"
LinkIncremental="2"
AdditionalLibraryDirectories="..\msvc"
GenerateDebugInformation="true"
@@ -140,7 +140,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="setupapi.lib pthreadVC2.lib ole32.lib advapi32.lib"
+ AdditionalDependencies="setupapi.lib ole32.lib advapi32.lib"
LinkIncremental="1"
AdditionalLibraryDirectories="..\msvc"
GenerateDebugInformation="true"
@@ -221,7 +221,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="setupapi.lib pthreadVC2_x64.lib"
+ AdditionalDependencies="setupapi.lib"
LinkIncremental="2"
AdditionalLibraryDirectories="..\msvc"
GenerateDebugInformation="true"
@@ -298,7 +298,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="setupapi.lib pthreadVC2_x64.lib"
+ AdditionalDependencies="setupapi.lib"
LinkIncremental="1"
AdditionalLibraryDirectories="..\msvc"
GenerateDebugInformation="true"
diff --git a/examples/xusb_2008.vcproj b/examples/xusb_2008.vcproj
index 4cd9b13..224249a 100644
--- a/examples/xusb_2008.vcproj
+++ b/examples/xusb_2008.vcproj
@@ -65,7 +65,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="setupapi.lib pthreadVC2.lib"
+ AdditionalDependencies="setupapi.lib"
LinkIncremental="2"
AdditionalLibraryDirectories="..\msvc"
GenerateDebugInformation="true"
@@ -142,7 +142,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="setupapi.lib pthreadVC2_x64.lib"
+ AdditionalDependencies="setupapi.lib"
LinkIncremental="2"
AdditionalLibraryDirectories="..\msvc"
GenerateDebugInformation="true"
@@ -219,7 +219,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="setupapi.lib pthreadVC2.lib"
+ AdditionalDependencies="setupapi.lib"
LinkIncremental="1"
AdditionalLibraryDirectories="..\msvc"
GenerateDebugInformation="true"
@@ -299,7 +299,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="setupapi.lib pthreadVC2_x64.lib"
+ AdditionalDependencies="setupapi.lib"
LinkIncremental="1"
AdditionalLibraryDirectories="..\msvc"
GenerateDebugInformation="true"
diff --git a/examples/xusb_sources b/examples/xusb_sources
index 609f369..f69b9e0 100644
--- a/examples/xusb_sources
+++ b/examples/xusb_sources
@@ -11,26 +11,13 @@ MSC_WARNING_LEVEL=/W3
-!IF "$(_BUILDARCH)"=="AMD64"
-
-PTHREAD_LIB=pthreadVC2_x64.lib
-
-!ELSE
-
-PTHREAD_LIB=pthreadVC2.lib
-
-!ENDIF
-
-
-
USE_MSVCRT=1
UMTYPE=console
INCLUDES=..\..\msvc;..\..;$(DDK_INC_PATH)
-UMLIBS=..\..\msvc\$(PTHREAD_LIB) \
- ..\..\libusb\os\obj$(BUILD_ALT_DIR)\*\libusb-1.0.lib
+UMLIBS=..\..\libusb\os\obj$(BUILD_ALT_DIR)\*\libusb-1.0.lib
SOURCES=..\xusb.c
diff --git a/libusb-dll_2005.vcproj b/libusb-dll_2005.vcproj
index 4518037..da05bd8 100644
--- a/libusb-dll_2005.vcproj
+++ b/libusb-dll_2005.vcproj
@@ -43,7 +43,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories=".\msvc;.\libusb;.\"
+ AdditionalIncludeDirectories=".\msvc;.\libusb"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS"
MinimalRebuild="true"
BasicRuntimeChecks="3"
@@ -64,10 +64,9 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="setupapi.lib pthreadVC2.lib ole32.lib advapi32.lib"
+ AdditionalDependencies="setupapi.lib ole32.lib advapi32.lib"
OutputFile="$(OutDir)\libusb-1.0_debug.dll"
LinkIncremental="2"
- AdditionalLibraryDirectories=".\msvc"
ModuleDefinitionFile="libusb\libusb-1.0.def"
GenerateDebugInformation="true"
SubSystem="2"
@@ -123,7 +122,7 @@
/>
<Tool
Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=".\msvc;.\libusb;.\"
+ AdditionalIncludeDirectories=".\msvc;.\libusb"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS"
RuntimeLibrary="2"
UsePrecompiledHeader="0"
@@ -142,10 +141,9 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="setupapi.lib pthreadVC2.lib ole32.lib advapi32.lib"
+ AdditionalDependencies="setupapi.lib ole32.lib advapi32.lib"
OutputFile="$(OutDir)\libusb-1.0.dll"
LinkIncremental="1"
- AdditionalLibraryDirectories=".\msvc"
ModuleDefinitionFile="libusb\libusb-1.0.def"
GenerateDebugInformation="true"
SubSystem="2"
@@ -204,7 +202,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories=".\msvc;.\libusb;.\"
+ AdditionalIncludeDirectories=".\msvc;.\libusb"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS"
MinimalRebuild="true"
BasicRuntimeChecks="3"
@@ -225,10 +223,9 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="setupapi.lib pthreadVC2_x64.lib"
+ AdditionalDependencies="setupapi.lib"
OutputFile="$(OutDir)\libusb-1.0_debug.dll"
LinkIncremental="2"
- AdditionalLibraryDirectories=".\msvc"
ModuleDefinitionFile="libusb\libusb-1.0.def"
GenerateDebugInformation="true"
SubSystem="2"
@@ -285,7 +282,7 @@
/>
<Tool
Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=".\msvc;.\libusb;.\"
+ AdditionalIncludeDirectories=".\msvc;.\libusb"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS"
RuntimeLibrary="2"
UsePrecompiledHeader="0"
@@ -304,10 +301,9 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="setupapi.lib pthreadVC2_x64.lib"
+ AdditionalDependencies="setupapi.lib"
OutputFile="$(OutDir)\libusb-1.0.dll"
LinkIncremental="1"
- AdditionalLibraryDirectories=".\msvc"
ModuleDefinitionFile="libusb\libusb-1.0.def"
GenerateDebugInformation="true"
SubSystem="2"
@@ -402,6 +398,11 @@
>
</File>
<File
+ RelativePath=".\libusb\os\threads_windows.c"
+ >
+ </File>
+
+ <File
RelativePath=".\libusb\os\windows_compat.c"
>
</File>
@@ -416,7 +417,7 @@
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
- RelativePath=".\config_msvc.h"
+ RelativePath=".\msvc\config.h"
>
</File>
<File
@@ -428,6 +429,10 @@
>
</File>
<File
+ RelativePath=".\libusb\os\threads_windows.h"
+ >
+ </File>
+ <File
RelativePath=".\libusb\os\windows_compat.h"
>
</File>
diff --git a/libusb-dll_2008.vcproj b/libusb-dll_2008.vcproj
index 385efab..b08d795 100644
--- a/libusb-dll_2008.vcproj
+++ b/libusb-dll_2008.vcproj
@@ -43,7 +43,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories=".\msvc;.\libusb;.\"
+ AdditionalIncludeDirectories=".\msvc;.\libusb"
PreprocessorDefinitions="_WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS"
MinimalRebuild="true"
BasicRuntimeChecks="3"
@@ -62,9 +62,8 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="setupapi.lib pthreadVC2.lib"
+ AdditionalDependencies="setupapi.lib"
OutputFile="$(OutDir)\libusb-1.0_debug.dll"
- AdditionalLibraryDirectories=".\msvc"
ModuleDefinitionFile="libusb\libusb-1.0.def"
EmbedManagedResourceFile="libusb-1.0.rc"
GenerateDebugInformation="true"
@@ -117,7 +116,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories=".\msvc;.\libusb;.\"
+ AdditionalIncludeDirectories=".\msvc;.\libusb"
PreprocessorDefinitions="_WIN32;_WIN64;_DEBUG;_CRT_SECURE_NO_WARNINGS"
MinimalRebuild="true"
BasicRuntimeChecks="3"
@@ -136,9 +135,8 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="setupapi.lib pthreadVC2_x64.lib"
+ AdditionalDependencies="setupapi.lib"
OutputFile="$(OutDir)\libusb-1.0_debug.dll"
- AdditionalLibraryDirectories=".\msvc"
ModuleDefinitionFile="libusb\libusb-1.0.def"
EmbedManagedResourceFile="libusb-1.0.rc"
GenerateDebugInformation="true"
@@ -192,7 +190,7 @@
Name="VCCLCompilerTool"
Optimization="2"
EnableIntrinsicFunctions="true"
- AdditionalIncludeDirectories=".\msvc;.\libusb;.\"
+ AdditionalIncludeDirectories=".\msvc;.\libusb"
PreprocessorDefinitions="_WIN32;_LIB;_CRT_SECURE_NO_WARNINGS"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
@@ -210,9 +208,8 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="setupapi.lib pthreadVC2.lib"
+ AdditionalDependencies="setupapi.lib"
OutputFile="$(OutDir)\libusb-1.0.dll"
- AdditionalLibraryDirectories=".\msvc"
ModuleDefinitionFile="libusb\libusb-1.0.def"
EmbedManagedResourceFile="libusb-1.0.rc"
/>
@@ -266,7 +263,7 @@
Name="VCCLCompilerTool"
Optimization="2"
EnableIntrinsicFunctions="true"
- AdditionalIncludeDirectories=".\msvc;.\libusb;.\"
+ AdditionalIncludeDirectories=".\msvc;.\libusb"
PreprocessorDefinitions="_WIN32;_WIN64;_LIB;_CRT_SECURE_NO_WARNINGS"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
@@ -284,9 +281,8 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="setupapi.lib pthreadVC2_x64.lib"
+ AdditionalDependencies="setupapi.lib"
OutputFile="$(OutDir)\libusb-1.0.dll"
- AdditionalLibraryDirectories=".\msvc"
ModuleDefinitionFile="libusb\libusb-1.0.def"
EmbedManagedResourceFile="libusb-1.0.rc"
/>
@@ -338,6 +334,10 @@
>
</File>
<File
+ RelativePath=".\libusb\os\threads_windows.c"
+ >
+ </File>
+ <File
RelativePath=".\libusb\os\windows_compat.c"
>
</File>
@@ -352,7 +352,7 @@
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
- RelativePath=".\config_msvc.h"
+ RelativePath=".\msvc\config.h"
>
</File>
<File
@@ -364,6 +364,10 @@
>
</File>
<File
+ RelativePath=".\libusb\os\threads_windows.h"
+ >
+ </File>
+ <File
RelativePath=".\libusb\os\windows_compat.h"
>
</File>
diff --git a/libusb-static_2005.vcproj b/libusb-static_2005.vcproj
index 5fb006d..afd646e 100644
--- a/libusb-static_2005.vcproj
+++ b/libusb-static_2005.vcproj
@@ -43,7 +43,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories=".\msvc;.\libusb;.\"
+ AdditionalIncludeDirectories=".\msvc;.\libusb"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS"
MinimalRebuild="true"
BasicRuntimeChecks="3"
@@ -107,7 +107,7 @@
/>
<Tool
Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=".\msvc;.\libusb;.\"
+ AdditionalIncludeDirectories=".\msvc;.\libusb"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS"
RuntimeLibrary="2"
UsePrecompiledHeader="0"
@@ -170,7 +170,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories=".\msvc;.\libusb;.\"
+ AdditionalIncludeDirectories=".\msvc;.\libusb"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS"
MinimalRebuild="true"
BasicRuntimeChecks="3"
@@ -235,7 +235,7 @@
/>
<Tool
Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=".\msvc;.\libusb;.\"
+ AdditionalIncludeDirectories=".\msvc;.\libusb"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS"
RuntimeLibrary="2"
UsePrecompiledHeader="0"
@@ -298,6 +298,10 @@
>
</File>
<File
+ RelativePath=".\libusb\os\threads_windows.c"
+ >
+ </File>
+ <File
RelativePath=".\libusb\os\windows_compat.c"
>
</File>
@@ -312,7 +316,7 @@
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
- RelativePath=".\config_msvc.h"
+ RelativePath=".\msvc\config.h"
>
</File>
<File
@@ -324,6 +328,10 @@
>
</File>
<File
+ RelativePath=".\libusb\os\threads_windows.h"
+ >
+ </File>
+ <File
RelativePath=".\libusb\os\windows_compat.h"
>
</File>
diff --git a/libusb-static_2008.vcproj b/libusb-static_2008.vcproj
index e17235c..70ecca8 100644
--- a/libusb-static_2008.vcproj
+++ b/libusb-static_2008.vcproj
@@ -43,7 +43,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories=".\msvc;.\libusb;.\"
+ AdditionalIncludeDirectories=".\msvc;.\libusb"
PreprocessorDefinitions="_WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS"
MinimalRebuild="true"
BasicRuntimeChecks="3"
@@ -106,7 +106,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories=".\msvc;.\libusb;.\"
+ AdditionalIncludeDirectories=".\msvc;.\libusb"
PreprocessorDefinitions="_WIN32;_WIN64;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS"
MinimalRebuild="true"
BasicRuntimeChecks="3"
@@ -170,7 +170,7 @@
Name="VCCLCompilerTool"
Optimization="2"
EnableIntrinsicFunctions="true"
- AdditionalIncludeDirectories=".\msvc;.\libusb;.\"
+ AdditionalIncludeDirectories=".\msvc;.\libusb"
PreprocessorDefinitions="_WIN32;_LIB;_CRT_SECURE_NO_WARNINGS"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
@@ -234,7 +234,7 @@
Name="VCCLCompilerTool"
Optimization="2"
EnableIntrinsicFunctions="true"
- AdditionalIncludeDirectories=".\msvc;.\libusb;.\"
+ AdditionalIncludeDirectories=".\msvc;.\libusb"
PreprocessorDefinitions="_WIN32;_WIN64;_LIB;_CRT_SECURE_NO_WARNINGS"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
@@ -296,6 +296,10 @@
>
</File>
<File
+ RelativePath=".\libusb\os\threads_windows.c"
+ >
+ </File>
+ <File
RelativePath=".\libusb\os\windows_compat.c"
>
</File>
@@ -310,7 +314,7 @@
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
- RelativePath=".\config_msvc.h"
+ RelativePath=".\msvc\config.h"
>
</File>
<File
@@ -322,6 +326,10 @@
>
</File>
<File
+ RelativePath=".\libusb\os\threads_windows.h"
+ >
+ </File>
+ <File
RelativePath=".\libusb\os\windows_compat.h"
>
</File>
diff --git a/libusb/Makefile.am b/libusb/Makefile.am
index fb470d2..e8de9f5 100644
--- a/libusb/Makefile.am
+++ b/libusb/Makefile.am
@@ -1,8 +1,14 @@
lib_LTLIBRARIES = libusb-1.0.la
-LINUX_USBFS_SRC = os/linux_usbfs.h os/linux_usbfs.c
-DARWIN_USB_SRC = os/darwin_usb.h os/darwin_usb.c
-WINDOWS_USB_SRC = os/windows_usb.h os/windows_usb.c os/windows_compat.h os/windows_compat.c
+if POSIX_THREADS
+THREADS_SRC = os/threads_posix.h
+else
+THREADS_SRC = os/threads_windows.h os/threads_windows.c
+endif
+
+LINUX_USBFS_SRC = $(THREADS_SRC) os/unistd_posix.h os/linux_usbfs.h os/linux_usbfs.c
+DARWIN_USB_SRC = $(THREADS_SRC) os/unistd_posix.h os/darwin_usb.h os/darwin_usb.c
+WINDOWS_USB_SRC = $(THREADS_SRC) os/windows_compat.h os/windows_compat.c os/windows_usb.h os/windows_usb.c
EXTRA_DIST = $(LINUX_USBFS_SRC) $(DARWIN_USB_SRC) $(WINDOWS_USB_SRC)
diff --git a/libusb/core.c b/libusb/core.c
index 1e9977b..6da729f 100644
--- a/libusb/core.c
+++ b/libusb/core.c
@@ -18,28 +18,16 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifdef _MSC_VER
-#include <config_msvc.h>
-#else
#include <config.h>
-#endif
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <sys/types.h>
#ifndef OS_WINDOWS
-#include <unistd.h>
-#include <poll.h>
-#define _libusb_write write
-#define _libusb_read read
-#define _libusb_close close
-#define _libusb_pipe pipe
-#define _libusb_poll poll
+#include "os/unistd_posix.h"
#endif
-#include "libusb.h"
#include "libusbi.h"
#if defined(OS_LINUX)
@@ -53,7 +41,7 @@ const struct usbi_os_backend * const usbi_backend = &windows_backend;
#endif
struct libusb_context *usbi_default_context = NULL;
-static pthread_mutex_t default_context_lock = PTHREAD_MUTEX_INITIALIZER;
+usbi_mutex_static_t default_context_lock = USBI_MUTEX_INITIALIZER;
/**
* \mainpage libusb-1.0 API Reference
@@ -518,7 +506,7 @@ struct libusb_device *usbi_alloc_device(struct libusb_context *ctx,
if (!dev)
return NULL;
- r = pthread_mutex_init(&dev->lock, NULL);
+ r = usbi_mutex_init(&dev->lock, NULL);
if (r) {
free(dev);
return NULL;
@@ -529,9 +517,9 @@ struct libusb_device *usbi_alloc_device(struct libusb_context *ctx,
dev->session_data = session_id;
memset(&dev->os_priv, 0, priv_size);
- pthread_mutex_lock(&ctx->usb_devs_lock);
+ usbi_mutex_lock(&ctx->usb_devs_lock);
list_add(&dev->list, &ctx->usb_devs);
- pthread_mutex_unlock(&ctx->usb_devs_lock);
+ usbi_mutex_unlock(&ctx->usb_devs_lock);
return dev;
}
@@ -571,13 +559,13 @@ struct libusb_device *usbi_get_device_by_session_id(struct libusb_context *ctx,
struct libusb_device *dev;
struct libusb_device *ret = NULL;
- pthread_mutex_lock(&ctx->usb_devs_lock);
+ usbi_mutex_lock(&ctx->usb_devs_lock);
list_for_each_entry(dev, &ctx->usb_devs, list, struct libusb_device)
if (dev->session_data == session_id) {
ret = dev;
break;
}
- pthread_mutex_unlock(&ctx->usb_devs_lock);
+ usbi_mutex_unlock(&ctx->usb_devs_lock);
return ret;
}
@@ -812,9 +800,9 @@ API_EXPORTED int libusb_get_max_iso_packet_size(libusb_device *dev,
*/
API_EXPORTED libusb_device *libusb_ref_device(libusb_device *dev)
{
- pthread_mutex_lock(&dev->lock);
+ usbi_mutex_lock(&dev->lock);
dev->refcnt++;
- pthread_mutex_unlock(&dev->lock);
+ usbi_mutex_unlock(&dev->lock);
return dev;
}
@@ -830,9 +818,9 @@ API_EXPORTED void libusb_unref_device(libusb_device *dev)
if (!dev)
return;
- pthread_mutex_lock(&dev->lock);
+ usbi_mutex_lock(&dev->lock);
refcnt = --dev->refcnt;
- pthread_mutex_unlock(&dev->lock);
+ usbi_mutex_unlock(&dev->lock);
if (refcnt == 0) {
usbi_dbg("destroy device %d.%d", dev->bus_number, dev->device_address);
@@ -840,9 +828,9 @@ API_EXPORTED void libusb_unref_device(libusb_device *dev)
if (usbi_backend->destroy_device)
usbi_backend->destroy_device(dev);
- pthread_mutex_lock(&dev->ctx->usb_devs_lock);
+ usbi_mutex_lock(&dev->ctx->usb_devs_lock);
list_del(&dev->list);
- pthread_mutex_unlock(&dev->ctx->usb_devs_lock);
+ usbi_mutex_unlock(&dev->ctx->usb_devs_lock);
free(dev);
}
@@ -880,7 +868,7 @@ API_EXPORTED int libusb_open(libusb_device *dev, libusb_device_handle **handle)
if (!_handle)
return LIBUSB_ERROR_NO_MEM;
- r = pthread_mutex_init(&_handle->lock, NULL);
+ r = usbi_mutex_init(&_handle->lock, NULL);
if (r) {
free(_handle);
return LIBUSB_ERROR_OTHER;
@@ -893,14 +881,14 @@ API_EXPORTED int libusb_open(libusb_device *dev, libusb_device_handle **handle)
r = usbi_backend->open(_handle);
if (r < 0) {
libusb_unref_device(dev);
- pthread_mutex_destroy(&_handle->lock);
+ usbi_mutex_destroy(&_handle->lock);
free(_handle);
return (int)r;
}
- pthread_mutex_lock(&ctx->open_devs_lock);
+ usbi_mutex_lock(&ctx->open_devs_lock);
list_add(&_handle->list, &ctx->open_devs);
- pthread_mutex_unlock(&ctx->open_devs_lock);
+ usbi_mutex_unlock(&ctx->open_devs_lock);
*handle = _handle;
@@ -912,17 +900,17 @@ API_EXPORTED int libusb_open(libusb_device *dev, libusb_device_handle **handle)
* so that it picks up the new fd, and then continues. */
/* record that we are messing with poll fds */
- pthread_mutex_lock(&ctx->pollfd_modify_lock);
+ usbi_mutex_lock(&ctx->pollfd_modify_lock);
ctx->pollfd_modify++;
- pthread_mutex_unlock(&ctx->pollfd_modify_lock);
+ usbi_mutex_unlock(&ctx->pollfd_modify_lock);
/* write some data on control pipe to interrupt event handlers */
- r = _libusb_write(ctx->ctrl_pipe[1], &dummy, sizeof(dummy));
+ r = usbi_write(ctx->ctrl_pipe[1], &dummy, sizeof(dummy));
if (r <= 0) {
usbi_warn(ctx, "internal signalling write failed");
- pthread_mutex_lock(&ctx->pollfd_modify_lock);
+ usbi_mutex_lock(&ctx->pollfd_modify_lock);
ctx->pollfd_modify--;
- pthread_mutex_unlock(&ctx->pollfd_modify_lock);
+ usbi_mutex_unlock(&ctx->pollfd_modify_lock);
return 0;
}
@@ -930,14 +918,14 @@ API_EXPORTED int libusb_open(libusb_device *dev, libusb_device_handle **handle)
libusb_lock_events(ctx);
/* read the dummy data */
- r = _libusb_read(ctx->ctrl_pipe[0], &dummy, sizeof(dummy));
+ r = usbi_read(ctx->ctrl_pipe[0], &dummy, sizeof(dummy));
if (r <= 0)
usbi_warn(ctx, "internal signalling read failed");
/* we're done with modifying poll fds */
- pthread_mutex_lock(&ctx->pollfd_modify_lock);
+ usbi_mutex_lock(&ctx->pollfd_modify_lock);
ctx->pollfd_modify--;
- pthread_mutex_unlock(&ctx->pollfd_modify_lock);
+ usbi_mutex_unlock(&ctx->pollfd_modify_lock);
/* Release event handling lock and wake up event waiters */
libusb_unlock_events(ctx);
@@ -999,13 +987,13 @@ out:
static void do_close(struct libusb_context *ctx,
struct libusb_device_handle *dev_handle)
{
- pthread_mutex_lock(&ctx->open_devs_lock);
+ usbi_mutex_lock(&ctx->open_devs_lock);
list_del(&dev_handle->list);
- pthread_mutex_unlock(&ctx->open_devs_lock);
+ usbi_mutex_unlock(&ctx->open_devs_lock);
usbi_backend->close(dev_handle);
libusb_unref_device(dev_handle->dev);
- pthread_mutex_destroy(&dev_handle->lock);
+ usbi_mutex_destroy(&dev_handle->lock);
free(dev_handle);
}
@@ -1039,18 +1027,18 @@ API_EXPORTED void libusb_close(libusb_device_handle *dev_handle)
* descriptor from the polling loop. */
/* record that we are messing with poll fds */
- pthread_mutex_lock(&ctx->pollfd_modify_lock);
+ usbi_mutex_lock(&ctx->pollfd_modify_lock);
ctx->pollfd_modify++;
- pthread_mutex_unlock(&ctx->pollfd_modify_lock);
+ usbi_mutex_unlock(&ctx->pollfd_modify_lock);
/* write some data on control pipe to interrupt event handlers */
- r = _libusb_write(ctx->ctrl_pipe[1], &dummy, sizeof(dummy));
+ r = usbi_write(ctx->ctrl_pipe[1], &dummy, sizeof(dummy));
if (r <= 0) {
usbi_warn(ctx, "internal signalling write failed, closing anyway");
do_close(ctx, dev_handle);
- pthread_mutex_lock(&ctx->pollfd_modify_lock);
+ usbi_mutex_lock(&ctx->pollfd_modify_lock);
ctx->pollfd_modify--;
- pthread_mutex_unlock(&ctx->pollfd_modify_lock);
+ usbi_mutex_unlock(&ctx->pollfd_modify_lock);
return;
}
@@ -1058,7 +1046,7 @@ API_EXPORTED void libusb_close(libusb_device_handle *dev_handle)
libusb_lock_events(ctx);
/* read the dummy data */
- r = _libusb_read(ctx->ctrl_pipe[0], &dummy, sizeof(dummy));
+ r = usbi_read(ctx->ctrl_pipe[0], &dummy, sizeof(dummy));
if (r <= 0)
usbi_warn(ctx, "internal signalling read failed, closing anyway");
@@ -1066,9 +1054,9 @@ API_EXPORTED void libusb_close(libusb_device_handle *dev_handle)
do_close(ctx, dev_handle);
/* we're done with modifying poll fds */
- pthread_mutex_lock(&ctx->pollfd_modify_lock);
+ usbi_mutex_lock(&ctx->pollfd_modify_lock);
ctx->pollfd_modify--;
- pthread_mutex_unlock(&ctx->pollfd_modify_lock);
+ usbi_mutex_unlock(&ctx->pollfd_modify_lock);
/* Release event handling lock and wake up event waiters */
libusb_unlock_events(ctx);
@@ -1215,7 +1203,7 @@ API_EXPORTED int libusb_claim_interface(libusb_device_handle *dev,
if (interface_number >= sizeof(dev->claimed_interfaces) * 8)
return LIBUSB_ERROR_INVALID_PARAM;
- pthread_mutex_lock(&dev->lock);
+ usbi_mutex_lock(&dev->lock);
if (dev->claimed_interfaces & (1 << interface_number))
goto out;
@@ -1224,7 +1212,7 @@ API_EXPORTED int libusb_claim_interface(libusb_device_handle *dev,
dev->claimed_interfaces |= 1 << interface_number;
out:
- pthread_mutex_unlock(&dev->lock);
+ usbi_mutex_unlock(&dev->lock);
return r;
}
@@ -1252,7 +1240,7 @@ API_EXPORTED int libusb_release_interface(libusb_device_handle *dev,
if (interface_number >= sizeof(dev->claimed_interfaces) * 8)
return LIBUSB_ERROR_INVALID_PARAM;
- pthread_mutex_lock(&dev->lock);
+ usbi_mutex_lock(&dev->lock);
if (!(dev->claimed_interfaces & (1 << interface_number))) {
r = LIBUSB_ERROR_NOT_FOUND;
goto out;
@@ -1263,7 +1251,7 @@ API_EXPORTED int libusb_release_interface(libusb_device_handle *dev,
dev->claimed_interfaces &= ~(1 << interface_number);
out:
- pthread_mutex_unlock(&dev->lock);
+ usbi_mutex_unlock(&dev->lock);
return r;
}
@@ -1296,12 +1284,12 @@ API_EXPORTED int libusb_set_interface_alt_setting(libusb_device_handle *dev,
if (interface_number >= sizeof(dev->claimed_interfaces) * 8)
return LIBUSB_ERROR_INVALID_PARAM;
- pthread_mutex_lock(&dev->lock);
+ usbi_mutex_lock(&dev->lock);
if (!(dev->claimed_interfaces & (1 << interface_number))) {
- pthread_mutex_unlock(&dev->lock);
+ usbi_mutex_unlock(&dev->lock);
return LIBUSB_ERROR_NOT_FOUND;
}
- pthread_mutex_unlock(&dev->lock);
+ usbi_mutex_unlock(&dev->lock);
return usbi_backend->set_interface_altsetting(dev, interface_number,
alternate_setting);
@@ -1472,12 +1460,23 @@ API_EXPORTED void libusb_set_debug(libusb_context *ctx, int level)
API_EXPORTED int libusb_init(libusb_context **context)
{
char *dbg = getenv("LIBUSB_DEBUG");
- struct libusb_context *ctx = malloc(sizeof(*ctx));
+ struct libusb_context *ctx;
int r;
- if (!ctx)
+ usbi_mutex_static_lock(&default_context_lock);
+ if (!context && usbi_default_context) {
+ usbi_mutex_static_unlock(&default_context_lock);
+ return 0; /* using default; nothing to do. */
+ }
+ ctx = malloc(sizeof(*ctx));
+ if (!ctx) {
+ usbi_mutex_static_unlock(&default_context_lock);
return LIBUSB_ERROR_NO_MEM;
+ }
memset(ctx, 0, sizeof(*ctx));
+#ifdef USBI_TIMERFD_AVAILABLE
+ ctx->timerfd = -1;
+#endif
if (dbg) {
ctx->debug = atoi(dbg);
@@ -1487,17 +1486,17 @@ API_EXPORTED int libusb_init(libusb_context **context)
usbi_dbg("");
+ usbi_mutex_init(&ctx->usb_devs_lock, NULL);
+ usbi_mutex_init(&ctx->open_devs_lock, NULL);
+ list_init(&ctx->usb_devs);
+ list_init(&ctx->open_devs);
+
if (usbi_backend->init) {
r = usbi_backend->init(ctx);
if (r)
goto err;
}
- pthread_mutex_init(&ctx->usb_devs_lock, NULL);
- pthread_mutex_init(&ctx->open_devs_lock, NULL);
- list_init(&ctx->usb_devs);
- list_init(&ctx->open_devs);
-
r = usbi_io_init(ctx);
if (r < 0) {
if (usbi_backend->exit)
@@ -1505,24 +1504,20 @@ API_EXPORTED int libusb_init(libusb_context **context)
goto err;
}
- pthread_mutex_lock(&default_context_lock);
if (!usbi_default_context) {
usbi_dbg("created default context");
usbi_default_context = ctx;
- } else if (!context) {
- pthread_mutex_unlock(&default_context_lock);
- libusb_exit(ctx); /* free superfluous context; use default context */
- return 0;
}
- pthread_mutex_unlock(&default_context_lock);
+ usbi_mutex_static_unlock(&default_context_lock);
if (context)
*context = ctx;
return 0;
err:
- pthread_mutex_destroy(&ctx->open_devs_lock);
- pthread_mutex_destroy(&ctx->usb_devs_lock);
+ usbi_mutex_static_unlock(&default_context_lock);
+ usbi_mutex_destroy(&ctx->open_devs_lock);
+ usbi_mutex_destroy(&ctx->usb_devs_lock);
free(ctx);
return r;
}
@@ -1546,15 +1541,15 @@ API_EXPORTED void libusb_exit(struct libusb_context *ctx)
if (usbi_backend->exit)
usbi_backend->exit();
- pthread_mutex_lock(&default_context_lock);
+ usbi_mutex_static_lock(&default_context_lock);
if (ctx == usbi_default_context) {
usbi_dbg("freeing default context");
usbi_default_context = NULL;
}
- pthread_mutex_unlock(&default_context_lock);
+ usbi_mutex_static_unlock(&default_context_lock);
- pthread_mutex_destroy(&ctx->open_devs_lock);
- pthread_mutex_destroy(&ctx->usb_devs_lock);
+ usbi_mutex_destroy(&ctx->open_devs_lock);
+ usbi_mutex_destroy(&ctx->usb_devs_lock);
free(ctx);
}
@@ -1617,45 +1612,43 @@ void usbi_log(struct libusb_context *ctx, enum usbi_log_level level,
* Returns a constant string with an English short description of the given
* error code. The caller should never free() the returned pointer since it
* points to a constant string.
- * The returned string is encoded in ASCII form and always starts with a capital
- * letter and ends without any dot.
+ * The returned string is encoded in ASCII form and always starts with a
+ * capital letter and ends without any dot.
* \param errcode the error code whose description is desired
* \returns a short description of the error code in English
*/
API_EXPORTED const char* libusb_strerror(enum libusb_error errcode)
{
- switch (errcode)
- {
- case LIBUSB_SUCCESS:
- return "Success";
- case LIBUSB_ERROR_IO:
- return "Input/output error";
- case LIBUSB_ERROR_INVALID_PARAM:
- return "Invalid parameter";
- case LIBUSB_ERROR_ACCESS:
- return "Access denied (insufficient permissions)";
- case LIBUSB_ERROR_NO_DEVICE:
- return "No such device (it may have been disconnected)";
- case LIBUSB_ERROR_NOT_FOUND:
- return "Entity not found";
- case LIBUSB_ERROR_BUSY:
- return "Resource busy";
- case LIBUSB_ERROR_TIMEOUT:
- return "Operation timed out";
- case LIBUSB_ERROR_OVERFLOW:
- return "Overflow";
- case LIBUSB_ERROR_PIPE:
- return "Pipe error";
- case LIBUSB_ERROR_INTERRUPTED:
- return "System call interrupted (perhaps due to signal)";
- case LIBUSB_ERROR_NO_MEM:
- return "Insufficient memory";
- case LIBUSB_ERROR_NOT_SUPPORTED:
- return "Operation not supported or unimplemented on this platform";
- case LIBUSB_ERROR_OTHER:
- return "Other error";
-
- default:
- return "Unknown error";
- }
+ switch (errcode)
+ {
+ case LIBUSB_SUCCESS:
+ return "Success";
+ case LIBUSB_ERROR_IO:
+ return "Input/output error";
+ case LIBUSB_ERROR_INVALID_PARAM:
+ return "Invalid parameter";
+ case LIBUSB_ERROR_ACCESS:
+ return "Access denied (insufficient permissions)";
+ case LIBUSB_ERROR_NO_DEVICE:
+ return "No such device (it may have been disconnected)";
+ case LIBUSB_ERROR_NOT_FOUND:
+ return "Entity not found";
+ case LIBUSB_ERROR_BUSY:
+ return "Resource busy";
+ case LIBUSB_ERROR_TIMEOUT:
+ return "Operation timed out";
+ case LIBUSB_ERROR_OVERFLOW:
+ return "Overflow";
+ case LIBUSB_ERROR_PIPE:
+ return "Pipe error";
+ case LIBUSB_ERROR_INTERRUPTED:
+ return "System call interrupted (perhaps due to signal)";
+ case LIBUSB_ERROR_NO_MEM:
+ return "Insufficient memory";
+ case LIBUSB_ERROR_NOT_SUPPORTED:
+ return "Operation not supported or unimplemented on this platform";
+ case LIBUSB_ERROR_OTHER:
+ return "Other error";
+ }
+ return "Unknown error";
}
diff --git a/libusb/io.c b/libusb/io.c
index 0b32beb..48122b5 100644
--- a/libusb/io.c
+++ b/libusb/io.c
@@ -18,31 +18,14 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifdef _MSC_VER
-#include <config_msvc.h>
-#else
#include <config.h>
-#endif
#include <errno.h>
-#include <pthread.h>
#include <signal.h>
-#include <stdint.h>
#include <stdlib.h>
#include <string.h>
-#if defined(_MSC_VER)
-#include <time.h>
-#else
-#include <sys/time.h>
-#endif
-#include <time.h>
+
#ifndef OS_WINDOWS
-#include <unistd.h>
-#include <poll.h>
-#define _libusb_write write
-#define _libusb_read read
-#define _libusb_close close
-#define _libusb_pipe pipe
-#define _libusb_poll poll
+#include "os/unistd_posix.h"
#endif
#ifdef USBI_TIMERFD_AVAILABLE
@@ -1011,27 +994,27 @@ printf("completed!\n");
int usbi_io_init(struct libusb_context *ctx)
{
- int r;
-
- /* We could destroy these mutexes in all the failure cases below,
- * but that would substantially complicate the code. */
- pthread_mutex_init(&ctx->flying_transfers_lock, NULL);
- pthread_mutex_init(&ctx->pollfds_lock, NULL);
- pthread_mutex_init(&ctx->pollfd_modify_lock, NULL);
- pthread_mutex_init(&ctx->events_lock, NULL);
- pthread_mutex_init(&ctx->event_waiters_lock, NULL);
- pthread_cond_init(&ctx->event_waiters_cond, NULL);
+ int p, r;
+
+ usbi_mutex_init(&ctx->flying_transfers_lock, NULL);
+ usbi_mutex_init(&ctx->pollfds_lock, NULL);
+ usbi_mutex_init(&ctx->pollfd_modify_lock, NULL);
+ usbi_mutex_init(&ctx->events_lock, NULL);
+ usbi_mutex_init(&ctx->event_waiters_lock, NULL);
+ usbi_cond_init(&ctx->event_waiters_cond, NULL);
list_init(&ctx->flying_transfers);
list_init(&ctx->pollfds);
/* FIXME should use an eventfd on kernels that support it */
- r = _libusb_pipe(ctx->ctrl_pipe);
- if (r < 0)
- return LIBUSB_ERROR_OTHER;
+ p = usbi_pipe(ctx->ctrl_pipe);
+ if (p < 0) {
+ r = LIBUSB_ERROR_OTHER;
+ goto err;
+ }
r = usbi_add_pollfd(ctx, ctx->ctrl_pipe[0], POLLIN);
if (r < 0)
- return r;
+ goto err;
#ifdef USBI_TIMERFD_AVAILABLE
ctx->timerfd = timerfd_create(usbi_backend->get_timerfd_clockid(),
@@ -1039,10 +1022,8 @@ int usbi_io_init(struct libusb_context *ctx)
if (ctx->timerfd >= 0) {
usbi_dbg("using timerfd for timeouts");
r = usbi_add_pollfd(ctx, ctx->timerfd, POLLIN);
- if (r < 0) {
- close(ctx->timerfd);
- return r;
- }
+ if (r < 0)
+ goto err;
} else {
usbi_dbg("timerfd not available (code %d error %d)", ctx->timerfd, errno);
ctx->timerfd = -1;
@@ -1050,29 +1031,45 @@ int usbi_io_init(struct libusb_context *ctx)
#endif
return 0;
+
+err:
+#ifdef USBI_TIMERFD_AVAILABLE
+ if (ctx->timerfd != -1)
+ usbi_close(ctx->timerfd);
+#endif
+ if (0 == p) {
+ usbi_remove_pollfd(ctx, ctx->ctrl_pipe[0]);
+ usbi_close(ctx->ctrl_pipe[0]);
+ usbi_close(ctx->ctrl_pipe[1]);
+ }
+ usbi_mutex_destroy(&ctx->flying_transfers_lock);
+ usbi_mutex_destroy(&ctx->pollfds_lock);
+ usbi_mutex_destroy(&ctx->pollfd_modify_lock);
+ usbi_mutex_destroy(&ctx->events_lock);
+ usbi_mutex_destroy(&ctx->event_waiters_lock);
+ usbi_cond_destroy(&ctx->event_waiters_cond);
+ return r;
}
void usbi_io_exit(struct libusb_context *ctx)
{
usbi_remove_pollfd(ctx, ctx->ctrl_pipe[0]);
- _libusb_close(ctx->ctrl_pipe[0]);
- _libusb_close(ctx->ctrl_pipe[1]);
+ usbi_close(ctx->ctrl_pipe[0]);
+ usbi_close(ctx->ctrl_pipe[1]);
#ifdef USBI_TIMERFD_AVAILABLE
if (usbi_using_timerfd(ctx)) {
usbi_remove_pollfd(ctx, ctx->timerfd);
- _libusb_close(ctx->timerfd);
+ usbi_close(ctx->timerfd);
}
#endif
- pthread_mutex_destroy(&ctx->flying_transfers_lock);
- pthread_mutex_destroy(&ctx->pollfds_lock);
- pthread_mutex_destroy(&ctx->pollfd_modify_lock);
- pthread_mutex_destroy(&ctx->events_lock);
- pthread_mutex_destroy(&ctx->event_waiters_lock);
- pthread_cond_destroy(&ctx->event_waiters_cond);
+ usbi_mutex_destroy(&ctx->flying_transfers_lock);
+ usbi_mutex_destroy(&ctx->pollfds_lock);
+ usbi_mutex_destroy(&ctx->pollfd_modify_lock);
+ usbi_mutex_destroy(&ctx->events_lock);
+ usbi_mutex_destroy(&ctx->event_waiters_lock);
+ usbi_cond_destroy(&ctx->event_waiters_cond);
}
-/* Converts the relative timeout in the libusb_transfer "rider"
- * to an absolute timeout in usbi_transfer */
static int calculate_timeout(struct usbi_transfer *transfer)
{
int r;
@@ -1113,7 +1110,7 @@ static int add_to_flying_list(struct usbi_transfer *transfer)
int r = 0;
int first = 1;
- pthread_mutex_lock(&ctx->flying_transfers_lock);
+ usbi_mutex_lock(&ctx->flying_transfers_lock);
/* if we have no other flying transfers, start the list with this one */
if (list_empty(&ctx->flying_transfers)) {
@@ -1147,7 +1144,7 @@ static int add_to_flying_list(struct usbi_transfer *transfer)
/* otherwise we need to be inserted at the end */
list_add_tail(&transfer->list, &ctx->flying_transfers);
out:
- pthread_mutex_unlock(&ctx->flying_transfers_lock);
+ usbi_mutex_unlock(&ctx->flying_transfers_lock);
return r;
}
@@ -1188,7 +1185,7 @@ API_EXPORTED struct libusb_transfer *libusb_alloc_transfer(int iso_packets)
memset(itransfer, 0, alloc_size);
itransfer->num_iso_packets = iso_packets;
- pthread_mutex_init(&itransfer->lock, NULL);
+ usbi_mutex_init(&itransfer->lock, NULL);
return __USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
}
@@ -1219,7 +1216,7 @@ API_EXPORTED void libusb_free_transfer(struct libusb_transfer *transfer)
free(transfer->buffer);
itransfer = __LIBUSB_TRANSFER_TO_USBI_TRANSFER(transfer);
- pthread_mutex_destroy(&itransfer->lock);
+ usbi_mutex_destroy(&itransfer->lock);
free(itransfer);
}
@@ -1241,7 +1238,7 @@ API_EXPORTED int libusb_submit_transfer(struct libusb_transfer *transfer)
int r;
int first;
- pthread_mutex_lock(&itransfer->lock);
+ usbi_mutex_lock(&itransfer->lock);
itransfer->transferred = 0;
itransfer->flags = 0;
r = calculate_timeout(itransfer);
@@ -1253,9 +1250,9 @@ API_EXPORTED int libusb_submit_transfer(struct libusb_transfer *transfer)
first = add_to_flying_list(itransfer);
r = usbi_backend->submit_transfer(itransfer);
if (r) {
- pthread_mutex_lock(&ctx->flying_transfers_lock);
+ usbi_mutex_lock(&ctx->flying_transfers_lock);
list_del(&itransfer->list);
- pthread_mutex_unlock(&ctx->flying_transfers_lock);
+ usbi_mutex_unlock(&ctx->flying_transfers_lock);
}
#ifdef USBI_TIMERFD_AVAILABLE
else if (first && usbi_using_timerfd(ctx)) {
@@ -1271,7 +1268,7 @@ API_EXPORTED int libusb_submit_transfer(struct libusb_transfer *transfer)
#endif
out:
- pthread_mutex_unlock(&itransfer->lock);
+ usbi_mutex_unlock(&itransfer->lock);
return r;
}
@@ -1296,12 +1293,12 @@ API_EXPORTED int libusb_cancel_transfer(struct libusb_transfer *transfer)
int r;
usbi_dbg("");
- pthread_mutex_lock(&itransfer->lock);
+ usbi_mutex_lock(&itransfer->lock);
r = usbi_backend->cancel_transfer(itransfer);
if (r < 0)
usbi_err(TRANSFER_CTX(transfer),
"cancel transfer failed error %d", r);
- pthread_mutex_unlock(&itransfer->lock);
+ usbi_mutex_unlock(&itransfer->lock);
return r;
}
@@ -1385,10 +1382,10 @@ int usbi_handle_transfer_completion(struct usbi_transfer *itransfer,
* to rearm the timerfd if the transfer that expired was the one with
* the shortest timeout. */
- pthread_mutex_lock(&ctx->flying_transfers_lock);
+ usbi_mutex_lock(&ctx->flying_transfers_lock);
list_del(&itransfer->list);
r = arm_timerfd_for_next_timeout(ctx);
- pthread_mutex_unlock(&ctx->flying_transfers_lock);
+ usbi_mutex_unlock(&ctx->flying_transfers_lock);
if (r < 0) {
return r;
@@ -1418,9 +1415,9 @@ int usbi_handle_transfer_completion(struct usbi_transfer *itransfer,
* this point. */
if (flags & LIBUSB_TRANSFER_FREE_TRANSFER)
libusb_free_transfer(transfer);
- pthread_mutex_lock(&ctx->event_waiters_lock);
- pthread_cond_broadcast(&ctx->event_waiters_cond);
- pthread_mutex_unlock(&ctx->event_waiters_lock);
+ usbi_mutex_lock(&ctx->event_waiters_lock);
+ usbi_cond_broadcast(&ctx->event_waiters_cond);
+ usbi_mutex_unlock(&ctx->event_waiters_lock);
return 0;
}
@@ -1468,15 +1465,15 @@ API_EXPORTED int libusb_try_lock_events(libusb_context *ctx)
/* is someone else waiting to modify poll fds? if so, don't let this thread
* start event handling */
- pthread_mutex_lock(&ctx->pollfd_modify_lock);
+ usbi_mutex_lock(&ctx->pollfd_modify_lock);
r = ctx->pollfd_modify;
- pthread_mutex_unlock(&ctx->pollfd_modify_lock);
+ usbi_mutex_unlock(&ctx->pollfd_modify_lock);
if (r) {
usbi_dbg("someone else is modifying poll fds");
return 1;
}
- r = pthread_mutex_trylock(&ctx->events_lock);
+ r = usbi_mutex_trylock(&ctx->events_lock);
if (r)
return 1;
@@ -1505,7 +1502,7 @@ API_EXPORTED int libusb_try_lock_events(libusb_context *ctx)
API_EXPORTED void libusb_lock_events(libusb_context *ctx)
{
USBI_GET_CONTEXT(ctx);
- pthread_mutex_lock(&ctx->events_lock);
+ usbi_mutex_lock(&ctx->events_lock);
ctx->event_handler_active = 1;
}
@@ -1521,14 +1518,14 @@ API_EXPORTED void libusb_unlock_events(libusb_context *ctx)
{
USBI_GET_CONTEXT(ctx);
ctx->event_handler_active = 0;
- pthread_mutex_unlock(&ctx->events_lock);
+ usbi_mutex_unlock(&ctx->events_lock);
/* FIXME: perhaps we should be a bit more efficient by not broadcasting
* the availability of the events lock when we are modifying pollfds
* (check ctx->pollfd_modify)? */
- pthread_mutex_lock(&ctx->event_waiters_lock);
- pthread_cond_broadcast(&ctx->event_waiters_cond);
- pthread_mutex_unlock(&ctx->event_waiters_lock);
+ usbi_mutex_lock(&ctx->event_waiters_lock);
+ usbi_cond_broadcast(&ctx->event_waiters_cond);
+ usbi_mutex_unlock(&ctx->event_waiters_lock);
}
/** \ingroup poll
@@ -1559,9 +1556,9 @@ API_EXPORTED int libusb_event_handling_ok(libusb_context *ctx)
/* is someone else waiting to modify poll fds? if so, don't let this thread
* continue event handling */
- pthread_mutex_lock(&ctx->pollfd_modify_lock);
+ usbi_mutex_lock(&ctx->pollfd_modify_lock);
r = ctx->pollfd_modify;
- pthread_mutex_unlock(&ctx->pollfd_modify_lock);
+ usbi_mutex_unlock(&ctx->pollfd_modify_lock);
if (r) {
usbi_dbg("someone else is modifying poll fds");
return 0;
@@ -1587,9 +1584,9 @@ API_EXPORTED int libusb_event_handler_active(libusb_context *ctx)
/* is someone else waiting to modify poll fds? if so, don't let this thread
* start event handling -- indicate that event handling is happening */
- pthread_mutex_lock(&ctx->pollfd_modify_lock);
+ usbi_mutex_lock(&ctx->pollfd_modify_lock);
r = ctx->pollfd_modify;
- pthread_mutex_unlock(&ctx->pollfd_modify_lock);
+ usbi_mutex_unlock(&ctx->pollfd_modify_lock);
if (r) {
usbi_dbg("someone else is modifying poll fds");
return 1;
@@ -1620,7 +1617,7 @@ API_EXPORTED int libusb_event_handler_active(libusb_context *ctx)
API_EXPORTED void libusb_lock_event_waiters(libusb_context *ctx)
{
USBI_GET_CONTEXT(ctx);
- pthread_mutex_lock(&ctx->event_waiters_lock);
+ usbi_mutex_lock(&ctx->event_waiters_lock);
}
/** \ingroup poll
@@ -1631,7 +1628,7 @@ API_EXPORTED void libusb_lock_event_waiters(libusb_context *ctx)
API_EXPORTED void libusb_unlock_event_waiters(libusb_context *ctx)
{
USBI_GET_CONTEXT(ctx);
- pthread_mutex_unlock(&ctx->event_waiters_lock);
+ usbi_mutex_unlock(&ctx->event_waiters_lock);
}
/** \ingroup poll
@@ -1666,7 +1663,7 @@ API_EXPORTED int libusb_wait_for_event(libusb_context *ctx, struct timeval *tv)
USBI_GET_CONTEXT(ctx);
if (tv == NULL) {
- pthread_cond_wait(&ctx->event_waiters_cond, &ctx->event_waiters_lock);
+ usbi_cond_wait(&ctx->event_waiters_cond, &ctx->event_waiters_lock);
return 0;
}
@@ -1683,7 +1680,7 @@ API_EXPORTED int libusb_wait_for_event(libusb_context *ctx, struct timeval *tv)
timeout.tv_sec++;
}
- r = pthread_cond_timedwait(&ctx->event_waiters_cond,
+ r = usbi_cond_timedwait(&ctx->event_waiters_cond,
&ctx->event_waiters_lock, &timeout);
return (r == ETIMEDOUT);
}
@@ -1711,10 +1708,6 @@ static int handle_timeouts(struct libusb_context *ctx)
return 0;
}
#else
-/* Note: there is code duplication between handle_timeouts_locked and
- * handle_timeouts, as tranfer cancellation from the backend requires
- * flying_transfers locks that are not set wholesale */
-#ifndef OS_WINDOWS
static int handle_timeouts_locked(struct libusb_context *ctx)
{
int r;
@@ -1756,63 +1749,15 @@ static int handle_timeouts_locked(struct libusb_context *ctx)
}
return 0;
}
-#endif
static int handle_timeouts(struct libusb_context *ctx)
{
int r;
- struct timespec systime_ts;
- struct timeval systime;
- struct usbi_transfer *transfer, *to_handle;
USBI_GET_CONTEXT(ctx);
-
- if (list_empty(&ctx->flying_transfers))
- return 0;
-
- /* get current time */
- r = usbi_backend->clock_gettime(USBI_CLOCK_MONOTONIC, &systime_ts);
- if (r < 0)
- return r;
-
- TIMESPEC_TO_TIMEVAL(&systime, &systime_ts);
-
- /* iterate through flying transfers list, finding all transfers that
- * have expired timeouts. Same trick as usbi_handle_disconnect() so
- * that usbi_handle_transfer_cancellation() can be called in cancel()
- * on the backend. */
- while (1) {
- to_handle = NULL;
- pthread_mutex_lock(&ctx->flying_transfers_lock);
-
- list_for_each_entry(transfer, &ctx->flying_transfers, list, struct usbi_transfer) {
- struct timeval *cur_tv = &transfer->timeout;
-
- /* if we've reached transfers of infinite timeout, we're all done */
- if (!timerisset(cur_tv))
- break;
-
- /* ignore timeouts we've already handled */
- if (transfer->flags & USBI_TRANSFER_TIMED_OUT)
- continue;
-
- /* if transfer has non-expired timeout, nothing more to do */
- if ((cur_tv->tv_sec > systime.tv_sec) ||
- (cur_tv->tv_sec == systime.tv_sec &&
- cur_tv->tv_usec > systime.tv_usec))
- break;
-
- to_handle = transfer;
- break;
- }
- pthread_mutex_unlock(&ctx->flying_transfers_lock);
-
- if (!to_handle)
- break;
-
- /* otherwise, we've got an expired timeout to handle */
- handle_timeout(to_handle);
- }
- return 0;
+ usbi_mutex_lock(&ctx->flying_transfers_lock);
+ r = handle_timeouts_locked(ctx);
+ usbi_mutex_unlock(&ctx->flying_transfers_lock);
+ return r;
}
#endif
@@ -1825,7 +1770,7 @@ static int handle_timerfd_trigger(struct libusb_context *ctx)
if (r < 0)
return r;
- pthread_mutex_lock(&ctx->flying_transfers_lock);
+ usbi_mutex_lock(&ctx->flying_transfers_lock);
/* process the timeout that just happened */
r = handle_timeouts_locked(ctx);
@@ -1836,7 +1781,7 @@ static int handle_timerfd_trigger(struct libusb_context *ctx)
r = arm_timerfd_for_next_timeout(ctx);
out:
- pthread_mutex_unlock(&ctx->flying_transfers_lock);
+ usbi_mutex_unlock(&ctx->flying_transfers_lock);
return r;
}
#endif
@@ -1852,14 +1797,14 @@ static int handle_events(struct libusb_context *ctx, struct timeval *tv)
int i = -1;
int timeout_ms;
- pthread_mutex_lock(&ctx->pollfds_lock);
+ usbi_mutex_lock(&ctx->pollfds_lock);
list_for_each_entry(ipollfd, &ctx->pollfds, list, struct usbi_pollfd)
nfds++;
/* TODO: malloc when number of fd's changes, not on every poll */
fds = malloc(sizeof(*fds) * nfds);
if (!fds) {
- pthread_mutex_unlock(&ctx->pollfds_lock);
+ usbi_mutex_unlock(&ctx->pollfds_lock);
return LIBUSB_ERROR_NO_MEM;
}
@@ -1871,7 +1816,7 @@ static int handle_events(struct libusb_context *ctx, struct timeval *tv)
fds[i].events = pollfd->events;
fds[i].revents = 0;
}
- pthread_mutex_unlock(&ctx->pollfds_lock);
+ usbi_mutex_unlock(&ctx->pollfds_lock);
timeout_ms = (tv->tv_sec * 1000) + (tv->tv_usec / 1000);
@@ -1880,7 +1825,7 @@ static int handle_events(struct libusb_context *ctx, struct timeval *tv)
timeout_ms++;
usbi_dbg("poll() %d fds with timeout in %dms", nfds, timeout_ms);
- r = _libusb_poll(fds, nfds, timeout_ms);
+ r = usbi_poll(fds, nfds, timeout_ms);
usbi_dbg("poll() returned %d", r);
if (r == 0) {
free(fds);
@@ -2012,7 +1957,7 @@ retry:
return r;
}
- /* another thread is doing event handling. wait for pthread events that
+ /* another thread is doing event handling. wait for thread events that
* notify event completion. */
libusb_lock_event_waiters(ctx);
@@ -2169,9 +2114,9 @@ API_EXPORTED int libusb_get_next_timeout(libusb_context *ctx,
if (usbi_using_timerfd(ctx))
return 0;
- pthread_mutex_lock(&ctx->flying_transfers_lock);
+ usbi_mutex_lock(&ctx->flying_transfers_lock);
if (list_empty(&ctx->flying_transfers)) {
- pthread_mutex_unlock(&ctx->flying_transfers_lock);
+ usbi_mutex_unlock(&ctx->flying_transfers_lock);
usbi_dbg("no URBs, no timeout!");
return 0;
}
@@ -2183,7 +2128,7 @@ API_EXPORTED int libusb_get_next_timeout(libusb_context *ctx,
break;
}
}
- pthread_mutex_unlock(&ctx->flying_transfers_lock);
+ usbi_mutex_unlock(&ctx->flying_transfers_lock);
if (!found) {
usbi_dbg("all URBs have already been processed for timeouts");
@@ -2262,9 +2207,9 @@ int usbi_add_pollfd(struct libusb_context *ctx, int fd, short events)
usbi_dbg("add fd %d events %d", fd, events);
ipollfd->pollfd.fd = fd;
ipollfd->pollfd.events = events;
- pthread_mutex_lock(&ctx->pollfds_lock);
+ usbi_mutex_lock(&ctx->pollfds_lock);
list_add_tail(&ipollfd->list, &ctx->pollfds);
- pthread_mutex_unlock(&ctx->pollfds_lock);
+ usbi_mutex_unlock(&ctx->pollfds_lock);
if (ctx->fd_added_cb)
ctx->fd_added_cb(fd, events, ctx->fd_cb_user_data);
@@ -2278,7 +2223,7 @@ void usbi_remove_pollfd(struct libusb_context *ctx, int fd)
int found = 0;
usbi_dbg("remove fd %d", fd);
- pthread_mutex_lock(&ctx->pollfds_lock);
+ usbi_mutex_lock(&ctx->pollfds_lock);
list_for_each_entry(ipollfd, &ctx->pollfds, list, struct usbi_pollfd)
if (ipollfd->pollfd.fd == fd) {
found = 1;
@@ -2287,12 +2232,12 @@ void usbi_remove_pollfd(struct libusb_context *ctx, int fd)
if (!found) {
usbi_dbg("couldn't find fd %d to remove", fd);
- pthread_mutex_unlock(&ctx->pollfds_lock);
+ usbi_mutex_unlock(&ctx->pollfds_lock);
return;
}
list_del(&ipollfd->list);
- pthread_mutex_unlock(&ctx->pollfds_lock);
+ usbi_mutex_unlock(&ctx->pollfds_lock);
free(ipollfd);
if (ctx->fd_removed_cb)
ctx->fd_removed_cb(fd, ctx->fd_cb_user_data);
@@ -2318,7 +2263,7 @@ API_EXPORTED const struct libusb_pollfd **libusb_get_pollfds(
size_t cnt = 0;
USBI_GET_CONTEXT(ctx);
- pthread_mutex_lock(&ctx->pollfds_lock);
+ usbi_mutex_lock(&ctx->pollfds_lock);
list_for_each_entry(ipollfd, &ctx->pollfds, list, struct usbi_pollfd)
cnt++;
@@ -2331,7 +2276,7 @@ API_EXPORTED const struct libusb_pollfd **libusb_get_pollfds(
ret[cnt] = NULL;
out:
- pthread_mutex_unlock(&ctx->pollfds_lock);
+ usbi_mutex_unlock(&ctx->pollfds_lock);
return (const struct libusb_pollfd **) ret;
}
@@ -2360,14 +2305,14 @@ void usbi_handle_disconnect(struct libusb_device_handle *handle)
*/
while (1) {
- pthread_mutex_lock(&HANDLE_CTX(handle)->flying_transfers_lock);
+ usbi_mutex_lock(&HANDLE_CTX(handle)->flying_transfers_lock);
to_cancel = NULL;
list_for_each_entry(cur, &HANDLE_CTX(handle)->flying_transfers, list, struct usbi_transfer)
if (__USBI_TRANSFER_TO_LIBUSB_TRANSFER(cur)->dev_handle == handle) {
to_cancel = cur;
break;
}
- pthread_mutex_unlock(&HANDLE_CTX(handle)->flying_transfers_lock);
+ usbi_mutex_unlock(&HANDLE_CTX(handle)->flying_transfers_lock);
if (!to_cancel)
break;
diff --git a/libusb/libusb.h b/libusb/libusb.h
index 1c3e9c8..8986013 100644
--- a/libusb/libusb.h
+++ b/libusb/libusb.h
@@ -24,13 +24,12 @@
#include <stdint.h>
#ifdef _MSC_VER
#define inline __inline
-#include <time.h>
#else
#include <sys/time.h>
#endif
#include <sys/types.h>
-#include <time.h>
#include <limits.h>
+#include <time.h>
/* 'interface' might be defined as a macro on Windows, so we need to
* undefine it so as not to break the current libusb API, because
@@ -659,9 +658,9 @@ enum libusb_error {
/** Other error */
LIBUSB_ERROR_OTHER = -99
-
- /* IMPORTANT: when adding new values to this enum, remember to update the
- libusb_strerror() function implementation! */
+
+ /* IMPORTANT: when adding new values to this enum, remember to
+ update the libusb_strerror() function implementation! */
};
/** \ingroup asyncio
@@ -1173,8 +1172,8 @@ static inline int libusb_get_descriptor(libusb_device_handle *dev,
uint8_t desc_type, uint8_t desc_index, unsigned char *data, int length)
{
return libusb_control_transfer(dev, LIBUSB_ENDPOINT_IN,
- LIBUSB_REQUEST_GET_DESCRIPTOR, (desc_type << 8) | desc_index, 0, data,
- (uint16_t) length, 1000);
+ LIBUSB_REQUEST_GET_DESCRIPTOR, (desc_type << 8) | desc_index,
+ 0, data, (uint16_t)length, 1000);
}
/** \ingroup desc
@@ -1195,7 +1194,8 @@ static inline int libusb_get_string_descriptor(libusb_device_handle *dev,
uint8_t desc_index, uint16_t langid, unsigned char *data, int length)
{
return libusb_control_transfer(dev, LIBUSB_ENDPOINT_IN,
- LIBUSB_REQUEST_GET_DESCRIPTOR, (LIBUSB_DT_STRING << 8) | desc_index,
+ LIBUSB_REQUEST_GET_DESCRIPTOR,
+ (uint16_t)((LIBUSB_DT_STRING << 8) | desc_index),
langid, data, (uint16_t)length, 1000);
}
diff --git a/libusb/libusbi.h b/libusb/libusbi.h
index 2355535..33b642c 100644
--- a/libusb/libusbi.h
+++ b/libusb/libusbi.h
@@ -21,18 +21,9 @@
#ifndef __LIBUSBI_H__
#define __LIBUSBI_H__
-#ifdef _MSC_VER
-#include <config_msvc.h>
-#else
#include <config.h>
-#endif
-#include <pthread.h>
#include <stddef.h>
-#include <time.h>
-#ifdef OS_WINDOWS
-#include <windows.h>
-#include "os/windows_compat.h"
-#else
+#if !defined(OS_WINDOWS) || defined(__CYGWIN__)
#include <poll.h>
#endif
@@ -60,16 +51,16 @@ struct list_head {
* pos - A structure pointer has a "member" element
* head - list head
* member - the list_head element in "pos"
- * type - the type of the first parameter
+ * type - the type of the first parameter
*/
-#define list_for_each_entry(pos, head, member, type) \
- for (pos = list_entry((head)->next, type, member); \
+#define list_for_each_entry(pos, head, member, type) \
+ for (pos = list_entry((head)->next, type, member); \
&pos->member != (head); \
pos = list_entry(pos->member.next, type, member))
-#define list_for_each_entry_safe(pos, n, head, member, type) \
- for (pos = list_entry((head)->next, type, member), \
- n = list_entry(pos->member.next, type, member); \
+#define list_for_each_entry_safe(pos, n, head, member, type) \
+ for (pos = list_entry((head)->next, type, member), \
+ n = list_entry(pos->member.next, type, member); \
&pos->member != (head); \
pos = n, n = list_entry(n->member.next, type, member))
@@ -124,10 +115,8 @@ enum usbi_log_level {
void usbi_log(struct libusb_context *ctx, enum usbi_log_level level,
const char *function, const char *format, ...);
-
#if !defined(_MSC_VER) || _MSC_VER > 1200
-
#ifdef ENABLE_LOGGING
#define _usbi_log(ctx, level, ...) usbi_log(ctx, level, __FUNCTION__, __VA_ARGS__)
#else
@@ -144,9 +133,7 @@ void usbi_log(struct libusb_context *ctx, enum usbi_log_level level,
#define usbi_warn(ctx, ...) _usbi_log(ctx, LOG_LEVEL_WARNING, __VA_ARGS__)
#define usbi_err(ctx, ...) _usbi_log(ctx, LOG_LEVEL_ERROR, __VA_ARGS__)
-
-#else
-
+#else /* !defined(_MSC_VER) || _MSC_VER > 1200 */
void usbi_log_v(struct libusb_context *ctx, enum usbi_log_level level,
const char *function, const char *format, va_list args);
@@ -177,10 +164,7 @@ void inline usbi_dbg(const char *format, ...)
{ }
#endif
-
-#endif
-
-
+#endif /* !defined(_MSC_VER) || _MSC_VER > 1200 */
#define USBI_GET_CONTEXT(ctx) if (!(ctx)) (ctx) = usbi_default_context
#define DEVICE_CTX(dev) ((dev)->ctx)
@@ -189,6 +173,17 @@ void inline usbi_dbg(const char *format, ...)
#define ITRANSFER_CTX(transfer) \
(TRANSFER_CTX(__USBI_TRANSFER_TO_LIBUSB_TRANSFER(transfer)))
+/* Internal abstraction for thread synchronization */
+#if defined(OS_LINUX) || defined(OS_DARWIN)
+#include <os/threads_posix.h>
+#elif defined(OS_WINDOWS) && (defined(__CYGWIN__) || defined(USE_PTHREAD))
+#include <os/threads_posix.h>
+#include <os/windows_compat.h>
+#elif defined(OS_WINDOWS)
+#include <os/threads_windows.h>
+#include <os/windows_compat.h>
+#endif
+
extern struct libusb_context *usbi_default_context;
struct libusb_context {
@@ -200,28 +195,28 @@ struct libusb_context {
int ctrl_pipe[2];
struct list_head usb_devs;
- pthread_mutex_t usb_devs_lock;
+ usbi_mutex_t usb_devs_lock;
/* A list of open handles. Backends are free to traverse this if required.
*/
struct list_head open_devs;
- pthread_mutex_t open_devs_lock;
+ usbi_mutex_t open_devs_lock;
/* this is a list of in-flight transfer handles, sorted by timeout
* expiration. URBs to timeout the soonest are placed at the beginning of
* the list, URBs that will time out later are placed after, and urbs with
* infinite timeout are always placed at the very end. */
struct list_head flying_transfers;
- pthread_mutex_t flying_transfers_lock;
+ usbi_mutex_t flying_transfers_lock;
/* list of poll fds */
struct list_head pollfds;
- pthread_mutex_t pollfds_lock;
+ usbi_mutex_t pollfds_lock;
/* a counter that is set when we want to interrupt event handling, in order
* to modify the poll fd set. and a lock to protect it. */
unsigned int pollfd_modify;
- pthread_mutex_t pollfd_modify_lock;
+ usbi_mutex_t pollfd_modify_lock;
/* user callbacks for pollfd changes */
libusb_pollfd_added_cb fd_added_cb;
@@ -229,15 +224,15 @@ struct libusb_context {
void *fd_cb_user_data;
/* ensures that only one thread is handling events at any one time */
- pthread_mutex_t events_lock;
+ usbi_mutex_t events_lock;
/* used to see if there is an active thread doing event handling */
int event_handler_active;
/* used to wait for event completion in threads other than the one that is
* event handling */
- pthread_mutex_t event_waiters_lock;
- pthread_cond_t event_waiters_cond;
+ usbi_mutex_t event_waiters_lock;
+ usbi_cond_t event_waiters_cond;
#ifdef USBI_TIMERFD_AVAILABLE
/* used for timeout handling, if supported by OS.
@@ -255,7 +250,7 @@ struct libusb_context {
struct libusb_device {
/* lock protects refcnt, everything else is finalized at initialization
* time */
- pthread_mutex_t lock;
+ usbi_mutex_t lock;
int refcnt;
struct libusb_context *ctx;
@@ -271,7 +266,7 @@ struct libusb_device {
struct libusb_device_handle {
/* lock protects claimed_interfaces */
- pthread_mutex_t lock;
+ usbi_mutex_t lock;
unsigned long claimed_interfaces;
struct list_head list;
@@ -313,7 +308,7 @@ struct usbi_transfer {
* cancelling the transfer from another thread while you are processing
* its completion (presumably there would be races within your OS backend
* if this were possible). */
- pthread_mutex_t lock;
+ usbi_mutex_t lock;
};
#define __USBI_TRANSFER_TO_LIBUSB_TRANSFER(transfer) \
@@ -628,7 +623,7 @@ struct usbi_os_backend {
* was opened
* - another LIBUSB_ERROR code on other failure
*/
- int (*claim_interface)(struct libusb_device_handle *handle, int iface);
+ int (*claim_interface)(struct libusb_device_handle *handle, int interface_number);
/* Release a previously claimed interface.
*
@@ -645,7 +640,7 @@ struct usbi_os_backend {
* was opened
* - another LIBUSB_ERROR code on other failure
*/
- int (*release_interface)(struct libusb_device_handle *handle, int iface);
+ int (*release_interface)(struct libusb_device_handle *handle, int interface_number);
/* Set the alternate setting for an interface.
*
@@ -662,7 +657,7 @@ struct usbi_os_backend {
* - another LIBUSB_ERROR code on other failure
*/
int (*set_interface_altsetting)(struct libusb_device_handle *handle,
- int iface, int altsetting);
+ int interface_number, int altsetting);
/* Clear a halt/stall condition on an endpoint.
*
@@ -709,7 +704,7 @@ struct usbi_os_backend {
* - another LIBUSB_ERROR code on other failure
*/
int (*kernel_driver_active)(struct libusb_device_handle *handle,
- int iface);
+ int interface_number);
/* Detach a kernel driver from an interface. Optional.
*
@@ -725,7 +720,7 @@ struct usbi_os_backend {
* - another LIBUSB_ERROR code on other failure
*/
int (*detach_kernel_driver)(struct libusb_device_handle *handle,
- int iface);
+ int interface_number);
/* Attach a kernel driver to an interface. Optional.
*
@@ -742,7 +737,7 @@ struct usbi_os_backend {
* - another LIBUSB_ERROR code on other failure
*/
int (*attach_kernel_driver)(struct libusb_device_handle *handle,
- int iface);
+ int interface_number);
/* Destroy a device. Optional.
*
@@ -859,3 +854,4 @@ extern const struct usbi_os_backend darwin_backend;
extern const struct usbi_os_backend windows_backend;
#endif
+
diff --git a/libusb/os/darwin_usb.c b/libusb/os/darwin_usb.c
index de3e9a6..1fc6a0e 100644
--- a/libusb/os/darwin_usb.c
+++ b/libusb/os/darwin_usb.c
@@ -1,6 +1,6 @@
/*
* darwin backend for libusb 1.0
- * Copyright (C) 2008-2009 Nathan Hjelm <hjelmn@users.sourceforge.net>
+ * Copyright (C) 2008-2010 Nathan Hjelm <hjelmn@users.sourceforge.net>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -44,6 +44,7 @@
static mach_port_t libusb_darwin_mp = 0; /* master port */
static CFRunLoopRef libusb_darwin_acfl = NULL; /* async cf loop */
+static int initCount = 0;
/* async event thread */
static pthread_t libusb_darwin_at;
@@ -83,6 +84,8 @@ static const char *darwin_error_str (int result) {
return "device not responding";
case kIOReturnOverrun:
return "data overrun";
+ case kIOReturnCannotWire:
+ return "physical memory can not be wired down";
default:
return "unknown error";
}
@@ -121,7 +124,7 @@ static int ep_to_pipeRef(struct libusb_device_handle *dev_handle, uint8_t ep, ui
int8_t i, iface;
- _usbi_log (HANDLE_CTX(dev_handle), LOG_LEVEL_INFO, "converting ep address 0x%02x to pipeRef and interface", ep);
+ usbi_info (HANDLE_CTX(dev_handle), "converting ep address 0x%02x to pipeRef and interface", ep);
for (iface = 0 ; iface < USB_MAXINTERFACES ; iface++) {
cInterface = &priv->interfaces[iface];
@@ -131,7 +134,7 @@ static int ep_to_pipeRef(struct libusb_device_handle *dev_handle, uint8_t ep, ui
if (cInterface->endpoint_addrs[i] == ep) {
*pipep = i + 1;
*ifcp = iface;
- _usbi_log (HANDLE_CTX(dev_handle), LOG_LEVEL_INFO, "pipe %d on interface %d matches", *pipep, *ifcp);
+ usbi_info (HANDLE_CTX(dev_handle), "pipe %d on interface %d matches", *pipep, *ifcp);
return 0;
}
}
@@ -139,7 +142,7 @@ static int ep_to_pipeRef(struct libusb_device_handle *dev_handle, uint8_t ep, ui
}
/* No pipe found with the correct endpoint address */
- _usbi_log (HANDLE_CTX(dev_handle), LOG_LEVEL_WARNING, "no pipeRef found with endpoint address 0x%02x.", ep);
+ usbi_warn (HANDLE_CTX(dev_handle), "no pipeRef found with endpoint address 0x%02x.", ep);
return -1;
}
@@ -218,7 +221,7 @@ static void darwin_devices_detached (void *ptr, io_iterator_t rem_devices) {
CFTypeRef locationCF;
UInt32 message;
- _usbi_log (ctx, LOG_LEVEL_INFO, "a device has been detached");
+ usbi_info (ctx, "a device has been detached");
while ((device = IOIteratorNext (rem_devices)) != 0) {
/* get the location from the i/o registry */
@@ -228,7 +231,7 @@ static void darwin_devices_detached (void *ptr, io_iterator_t rem_devices) {
CFRelease (locationCF);
IOObjectRelease (device);
- pthread_mutex_lock(&ctx->open_devs_lock);
+ usbi_mutex_lock(&ctx->open_devs_lock);
list_for_each_entry(handle, &ctx->open_devs, list, struct libusb_device_handle) {
dpriv = (struct darwin_device_priv *)handle->dev->os_priv;
@@ -241,7 +244,7 @@ static void darwin_devices_detached (void *ptr, io_iterator_t rem_devices) {
}
}
- pthread_mutex_unlock(&ctx->open_devs_lock);
+ usbi_mutex_unlock(&ctx->open_devs_lock);
}
}
@@ -261,7 +264,7 @@ static void *event_thread_main (void *arg0) {
io_notification_port_t libusb_notification_port;
io_iterator_t libusb_rem_device_iterator;
- _usbi_log (ctx, LOG_LEVEL_INFO, "creating hotplug event source");
+ usbi_info (ctx, "creating hotplug event source");
CFRetain (CFRunLoopGetCurrent ());
@@ -277,7 +280,7 @@ static void *event_thread_main (void *arg0) {
(void *)ctx, &libusb_rem_device_iterator);
if (kresult != kIOReturnSuccess) {
- _usbi_log (ctx, LOG_LEVEL_ERROR, "could not add hotplug event source: %s", darwin_error_str (kresult));
+ usbi_err (ctx, "could not add hotplug event source: %s", darwin_error_str (kresult));
pthread_exit ((void *)kresult);
}
@@ -288,12 +291,12 @@ static void *event_thread_main (void *arg0) {
/* let the main thread know about the async runloop */
libusb_darwin_acfl = CFRunLoopGetCurrent ();
- _usbi_log (ctx, LOG_LEVEL_INFO, "libopenusb/darwin.c event_thread_main: thread ready to receive events");
+ usbi_info (ctx, "libopenusb/darwin.c event_thread_main: thread ready to receive events");
/* run the runloop */
CFRunLoopRun();
- _usbi_log (ctx, LOG_LEVEL_INFO, "libopenusb/darwin.c event_thread_main: thread exiting");
+ usbi_info (ctx, "libopenusb/darwin.c event_thread_main: thread exiting");
/* delete notification port */
CFRunLoopSourceInvalidate (libusb_notification_cfsource);
@@ -309,33 +312,37 @@ static void *event_thread_main (void *arg0) {
static int darwin_init(struct libusb_context *ctx) {
IOReturn kresult;
- /* Create the master port for talking to IOKit */
- if (!libusb_darwin_mp) {
- kresult = IOMasterPort (MACH_PORT_NULL, &libusb_darwin_mp);
+ if (!(initCount++)) {
+ /* Create the master port for talking to IOKit */
+ if (!libusb_darwin_mp) {
+ kresult = IOMasterPort (MACH_PORT_NULL, &libusb_darwin_mp);
- if (kresult != kIOReturnSuccess || !libusb_darwin_mp)
- return darwin_to_libusb (kresult);
- }
+ if (kresult != kIOReturnSuccess || !libusb_darwin_mp)
+ return darwin_to_libusb (kresult);
+ }
- pthread_create (&libusb_darwin_at, NULL, event_thread_main, (void *)ctx);
+ pthread_create (&libusb_darwin_at, NULL, event_thread_main, (void *)ctx);
- while (!libusb_darwin_acfl)
- usleep (10);
+ while (!libusb_darwin_acfl)
+ usleep (10);
+ }
return 0;
}
static void darwin_exit (void) {
- void *ret;
+ if (!(--initCount)) {
+ void *ret;
- /* stop the async runloop */
- CFRunLoopStop (libusb_darwin_acfl);
- pthread_join (libusb_darwin_at, &ret);
+ /* stop the async runloop */
+ CFRunLoopStop (libusb_darwin_acfl);
+ pthread_join (libusb_darwin_at, &ret);
- if (libusb_darwin_mp)
- mach_port_deallocate(mach_task_self(), libusb_darwin_mp);
+ if (libusb_darwin_mp)
+ mach_port_deallocate(mach_task_self(), libusb_darwin_mp);
- libusb_darwin_mp = 0;
+ libusb_darwin_mp = 0;
+ }
}
static int darwin_get_device_descriptor(struct libusb_device *dev, unsigned char *buffer, int *host_endian) {
@@ -400,7 +407,7 @@ static int darwin_get_config_descriptor(struct libusb_device *dev, uint8_t confi
if (!priv->device) {
kresult = darwin_get_device (priv->location, &device);
if (kresult || !device) {
- _usbi_log (DEVICE_CTX (dev), LOG_LEVEL_ERROR, "could not find device: %s", darwin_error_str (kresult));
+ usbi_err (DEVICE_CTX (dev), "could not find device: %s", darwin_error_str (kresult));
return darwin_to_libusb (kresult);
}
@@ -434,12 +441,13 @@ static int process_new_device (struct libusb_context *ctx, usb_device_t **device
UInt16 address, idVendor, idProduct;
UInt8 bDeviceClass, bDeviceSubClass;
IOUSBDevRequest req;
- int ret;
+ int ret, need_unref = 0;
dev = usbi_get_device_by_session_id(ctx, locationID);
if (!dev) {
- _usbi_log (ctx, LOG_LEVEL_INFO, "allocating new device for location 0x%08x", locationID);
+ usbi_info (ctx, "allocating new device for location 0x%08x", locationID);
dev = usbi_alloc_device(ctx, locationID);
+ need_unref = 1;
if (!dev)
return LIBUSB_ERROR_NO_MEM;
@@ -490,8 +498,9 @@ static int process_new_device (struct libusb_context *ctx, usb_device_t **device
(*device)->USBDeviceClose (device);
if (ret != kIOReturnSuccess) {
- _usbi_log (ctx, LOG_LEVEL_WARNING, "could not retrieve device descriptor: %s. skipping device", darwin_error_str (ret));
- libusb_unref_device(dev);
+ usbi_warn (ctx, "could not retrieve device descriptor: %s. skipping device", darwin_error_str (ret));
+ if (need_unref)
+ libusb_unref_device(dev);
return -1;
}
/**** end: retrieve device descriptors ****/
@@ -499,7 +508,7 @@ static int process_new_device (struct libusb_context *ctx, usb_device_t **device
/* catch buggy hubs (which appear to be virtual). Apple's own USB prober has problems with these devices. */
if (libusb_le16_to_cpu (priv->dev_descriptor.idProduct) != idProduct) {
/* not a valid device */
- _usbi_log (ctx, LOG_LEVEL_WARNING, "idProduct from iokit (%04x) does not match idProduct in descriptor (%04x). skipping device",
+ usbi_warn (ctx, "idProduct from iokit (%04x) does not match idProduct in descriptor (%04x). skipping device",
idProduct, libusb_le16_to_cpu (priv->dev_descriptor.idProduct));
libusb_unref_device(dev);
return -1;
@@ -515,13 +524,14 @@ static int process_new_device (struct libusb_context *ctx, usb_device_t **device
ret = usbi_sanitize_device(dev);
if (ret < 0) {
- libusb_unref_device(dev);
+ if (need_unref)
+ libusb_unref_device(dev);
return -1;
}
} else {
priv = (struct darwin_device_priv *)dev->os_priv;
- _usbi_log (ctx, LOG_LEVEL_INFO, "using existing device for location 0x%08x", locationID);
+ usbi_info (ctx, "using existing device for location 0x%08x", locationID);
}
/* append the device to the list of discovered devices */
@@ -531,8 +541,11 @@ static int process_new_device (struct libusb_context *ctx, usb_device_t **device
*_discdevs = discdevs;
- _usbi_log (ctx, LOG_LEVEL_INFO, "found device with address %d at %s", dev->device_address, priv->sys_path);
+ usbi_info (ctx, "found device with address %d at %s", dev->device_address, priv->sys_path);
+ if (need_unref)
+ libusb_unref_device(dev);
+
return 0;
}
@@ -569,7 +582,7 @@ static int darwin_open (struct libusb_device_handle *dev_handle) {
if (0 == dpriv->open_count) {
kresult = darwin_get_device (dpriv->location, &darwin_device);
if (kresult) {
- _usbi_log (HANDLE_CTX (dev_handle), LOG_LEVEL_ERROR, "could not find device: %s", darwin_error_str (kresult));
+ usbi_err (HANDLE_CTX (dev_handle), "could not find device: %s", darwin_error_str (kresult));
return darwin_to_libusb (kresult);
}
@@ -579,7 +592,7 @@ static int darwin_open (struct libusb_device_handle *dev_handle) {
kresult = (*(dpriv->device))->USBDeviceOpenSeize (dpriv->device);
if (kresult != kIOReturnSuccess) {
- _usbi_log (HANDLE_CTX (dev_handle), LOG_LEVEL_ERROR, "USBDeviceOpen: %s", darwin_error_str(kresult));
+ usbi_err (HANDLE_CTX (dev_handle), "USBDeviceOpen: %s", darwin_error_str(kresult));
switch (kresult) {
case kIOReturnExclusiveAccess:
@@ -616,7 +629,7 @@ static int darwin_open (struct libusb_device_handle *dev_handle) {
usbi_add_pollfd(HANDLE_CTX(dev_handle), priv->fds[0], POLLIN);
- _usbi_log (HANDLE_CTX (dev_handle), LOG_LEVEL_INFO, "device open for access");
+ usbi_info (HANDLE_CTX (dev_handle), "device open for access");
return 0;
}
@@ -629,7 +642,7 @@ static void darwin_close (struct libusb_device_handle *dev_handle) {
if (dpriv->open_count == 0) {
/* something is probably very wrong if this is the case */
- _usbi_log (HANDLE_CTX (dev_handle), LOG_LEVEL_ERROR, "Close called on a device that was not open!\n");
+ usbi_err (HANDLE_CTX (dev_handle), "Close called on a device that was not open!\n");
return;
}
@@ -653,7 +666,7 @@ static void darwin_close (struct libusb_device_handle *dev_handle) {
if (kresult) {
/* Log the fact that we had a problem closing the file, however failing a
* close isn't really an error, so return success anyway */
- _usbi_log (HANDLE_CTX (dev_handle), LOG_LEVEL_ERROR, "USBDeviceClose: %s", darwin_error_str(kresult));
+ usbi_err (HANDLE_CTX (dev_handle), "USBDeviceClose: %s", darwin_error_str(kresult));
}
}
@@ -661,7 +674,7 @@ static void darwin_close (struct libusb_device_handle *dev_handle) {
if (kresult) {
/* Log the fact that we had a problem closing the file, however failing a
* close isn't really an error, so return success anyway */
- _usbi_log (HANDLE_CTX (dev_handle), LOG_LEVEL_ERROR, "Release: %s", darwin_error_str(kresult));
+ usbi_err (HANDLE_CTX (dev_handle), "Release: %s", darwin_error_str(kresult));
}
dpriv->device = NULL;
@@ -752,12 +765,12 @@ static int get_endpoints (struct libusb_device_handle *dev_handle, int iface) {
u_int16_t dont_care2;
int i;
- _usbi_log (HANDLE_CTX (dev_handle), LOG_LEVEL_INFO, "building table of endpoints.");
+ usbi_info (HANDLE_CTX (dev_handle), "building table of endpoints.");
/* retrieve the total number of endpoints on this interface */
kresult = (*(cInterface->interface))->GetNumEndpoints(cInterface->interface, &numep);
if (kresult) {
- _usbi_log (HANDLE_CTX (dev_handle), LOG_LEVEL_ERROR, "can't get number of endpoints for interface: %s", darwin_error_str(kresult));
+ usbi_err (HANDLE_CTX (dev_handle), "can't get number of endpoints for interface: %s", darwin_error_str(kresult));
return darwin_to_libusb (kresult);
}
@@ -767,12 +780,12 @@ static int get_endpoints (struct libusb_device_handle *dev_handle, int iface) {
&dont_care2, &dont_care3);
if (kresult != kIOReturnSuccess) {
- _usbi_log (HANDLE_CTX (dev_handle), LOG_LEVEL_ERROR, "error getting pipe information for pipe %d: %s", i, darwin_error_str(kresult));
+ usbi_err (HANDLE_CTX (dev_handle), "error getting pipe information for pipe %d: %s", i, darwin_error_str(kresult));
return darwin_to_libusb (kresult);
}
- _usbi_log (HANDLE_CTX (dev_handle), LOG_LEVEL_INFO, "interface: %i pipe %i: dir: %i number: %i", iface, i, direction, number);
+ usbi_info (HANDLE_CTX (dev_handle), "interface: %i pipe %i: dir: %i number: %i", iface, i, direction, number);
cInterface->endpoint_addrs[i - 1] = ((direction << 7 & LIBUSB_ENDPOINT_DIR_MASK) | (number & LIBUSB_ENDPOINT_ADDRESS_MASK));
}
@@ -806,50 +819,50 @@ static int darwin_claim_interface(struct libusb_device_handle *dev_handle, int i
be configured. Otherwise, we need to do it ourselves, or there
will be no interfaces for the device. */
- _usbi_log (HANDLE_CTX (dev_handle), LOG_LEVEL_INFO, "no interface found; selecting configuration" );
+ usbi_info (HANDLE_CTX (dev_handle), "no interface found; selecting configuration" );
kresult = (*(dpriv->device))->GetNumberOfConfigurations (dpriv->device, &nConfig);
if (kresult != kIOReturnSuccess) {
- _usbi_log (HANDLE_CTX (dev_handle), LOG_LEVEL_ERROR, "GetNumberOfConfigurations: %s", darwin_error_str(kresult));
+ usbi_err (HANDLE_CTX (dev_handle), "GetNumberOfConfigurations: %s", darwin_error_str(kresult));
return darwin_to_libusb(kresult);
}
if (nConfig < 1) {
- _usbi_log (HANDLE_CTX (dev_handle), LOG_LEVEL_ERROR, "GetNumberOfConfigurations: no configurations");
+ usbi_err (HANDLE_CTX (dev_handle), "GetNumberOfConfigurations: no configurations");
return LIBUSB_ERROR_OTHER;
}
- _usbi_log (HANDLE_CTX (dev_handle), LOG_LEVEL_INFO, "device has %d configuration%s. using the first",
+ usbi_info (HANDLE_CTX (dev_handle), "device has %d configuration%s. using the first",
(int)nConfig, (nConfig > 1 ? "s" : "") );
/* Always use the first configuration */
kresult = (*(dpriv->device))->GetConfigurationDescriptorPtr (dpriv->device, 0, &configDesc);
if (kresult != kIOReturnSuccess) {
- _usbi_log (HANDLE_CTX (dev_handle), LOG_LEVEL_ERROR, "GetConfigurationDescriptorPtr: %s",
+ usbi_err (HANDLE_CTX (dev_handle), "GetConfigurationDescriptorPtr: %s",
darwin_error_str(kresult));
new_config = 1;
} else
new_config = configDesc->bConfigurationValue;
- _usbi_log (HANDLE_CTX (dev_handle), LOG_LEVEL_INFO, "new configuration value is %d", new_config);
+ usbi_info (HANDLE_CTX (dev_handle), "new configuration value is %d", new_config);
/* set the configuration */
kresult = darwin_set_configuration (dev_handle, new_config);
if (kresult != LIBUSB_SUCCESS) {
- _usbi_log (HANDLE_CTX (dev_handle), LOG_LEVEL_ERROR, "could not set configuration");
+ usbi_err (HANDLE_CTX (dev_handle), "could not set configuration");
return kresult;
}
kresult = darwin_get_interface (dpriv->device, iface, &usbInterface);
if (kresult) {
- _usbi_log (HANDLE_CTX (dev_handle), LOG_LEVEL_ERROR, "darwin_get_interface: %s", darwin_error_str(kresult));
+ usbi_err (HANDLE_CTX (dev_handle), "darwin_get_interface: %s", darwin_error_str(kresult));
return darwin_to_libusb (kresult);
}
}
if (!usbInterface) {
- _usbi_log (HANDLE_CTX (dev_handle), LOG_LEVEL_ERROR, "interface not found");
+ usbi_err (HANDLE_CTX (dev_handle), "interface not found");
return LIBUSB_ERROR_NOT_FOUND;
}
@@ -857,12 +870,12 @@ static int darwin_claim_interface(struct libusb_device_handle *dev_handle, int i
kresult = IOCreatePlugInInterfaceForService (usbInterface, kIOUSBInterfaceUserClientTypeID,
kIOCFPlugInInterfaceID, &plugInInterface, &score);
if (kresult) {
- _usbi_log (HANDLE_CTX (dev_handle), LOG_LEVEL_ERROR, "IOCreatePlugInInterfaceForService: %s", darwin_error_str(kresult));
+ usbi_err (HANDLE_CTX (dev_handle), "IOCreatePlugInInterfaceForService: %s", darwin_error_str(kresult));
return darwin_to_libusb (kresult);
}
if (!plugInInterface) {
- _usbi_log (HANDLE_CTX (dev_handle), LOG_LEVEL_ERROR, "plugin interface not found");
+ usbi_err (HANDLE_CTX (dev_handle), "plugin interface not found");
return LIBUSB_ERROR_NOT_FOUND;
}
@@ -874,7 +887,7 @@ static int darwin_claim_interface(struct libusb_device_handle *dev_handle, int i
CFUUIDGetUUIDBytes(kIOUSBInterfaceInterfaceID),
(LPVOID)&cInterface->interface);
if (kresult || !cInterface->interface) {
- _usbi_log (HANDLE_CTX (dev_handle), LOG_LEVEL_ERROR, "QueryInterface: %s", darwin_error_str(kresult));
+ usbi_err (HANDLE_CTX (dev_handle), "QueryInterface: %s", darwin_error_str(kresult));
return darwin_to_libusb (kresult);
}
@@ -884,7 +897,7 @@ static int darwin_claim_interface(struct libusb_device_handle *dev_handle, int i
/* claim the interface */
kresult = (*(cInterface->interface))->USBInterfaceOpen(cInterface->interface);
if (kresult) {
- _usbi_log(HANDLE_CTX (dev_handle), LOG_LEVEL_ERROR, "USBInterfaceOpen: %s", darwin_error_str(kresult));
+ usbi_err (HANDLE_CTX (dev_handle), "USBInterfaceOpen: %s", darwin_error_str(kresult));
return darwin_to_libusb (kresult);
}
@@ -893,7 +906,7 @@ static int darwin_claim_interface(struct libusb_device_handle *dev_handle, int i
if (kresult) {
/* this should not happen */
darwin_release_interface (dev_handle, iface);
- _usbi_log (HANDLE_CTX (dev_handle), LOG_LEVEL_ERROR, "could not build endpoint table");
+ usbi_err (HANDLE_CTX (dev_handle), "could not build endpoint table");
return kresult;
}
@@ -902,7 +915,7 @@ static int darwin_claim_interface(struct libusb_device_handle *dev_handle, int i
/* create async event source */
kresult = (*(cInterface->interface))->CreateInterfaceAsyncEventSource (cInterface->interface, &cInterface->cfSource);
if (kresult != kIOReturnSuccess) {
- _usbi_log (HANDLE_CTX (dev_handle), LOG_LEVEL_ERROR, "could not create async event source");
+ usbi_err (HANDLE_CTX (dev_handle), "could not create async event source");
/* can't continue without an async event source */
(void)darwin_release_interface (dev_handle, iface);
@@ -913,7 +926,7 @@ static int darwin_claim_interface(struct libusb_device_handle *dev_handle, int i
/* add the cfSource to the async thread's run loop */
CFRunLoopAddSource(libusb_darwin_acfl, cInterface->cfSource, kCFRunLoopDefaultMode);
- _usbi_log (HANDLE_CTX (dev_handle), LOG_LEVEL_INFO, "interface opened");
+ usbi_info (HANDLE_CTX (dev_handle), "interface opened");
return 0;
}
@@ -940,11 +953,11 @@ static int darwin_release_interface(struct libusb_device_handle *dev_handle, int
kresult = (*(cInterface->interface))->USBInterfaceClose(cInterface->interface);
if (kresult)
- _usbi_log (HANDLE_CTX (dev_handle), LOG_LEVEL_ERROR, "USBInterfaceClose: %s", darwin_error_str(kresult));
+ usbi_err (HANDLE_CTX (dev_handle), "USBInterfaceClose: %s", darwin_error_str(kresult));
kresult = (*(cInterface->interface))->Release(cInterface->interface);
if (kresult != kIOReturnSuccess)
- _usbi_log (HANDLE_CTX (dev_handle), LOG_LEVEL_ERROR, "Release: %s", darwin_error_str(kresult));
+ usbi_err (HANDLE_CTX (dev_handle), "Release: %s", darwin_error_str(kresult));
cInterface->interface = IO_OBJECT_NULL;
@@ -970,7 +983,7 @@ static int darwin_set_interface_altsetting(struct libusb_device_handle *dev_hand
if (kresult) {
/* this should not happen */
darwin_release_interface (dev_handle, iface);
- _usbi_log (HANDLE_CTX (dev_handle), LOG_LEVEL_ERROR, "could not build endpoint table");
+ usbi_err (HANDLE_CTX (dev_handle), "could not build endpoint table");
return kresult;
}
@@ -987,7 +1000,7 @@ static int darwin_clear_halt(struct libusb_device_handle *dev_handle, unsigned c
/* determine the interface/endpoint to use */
if (ep_to_pipeRef (dev_handle, endpoint, &pipeRef, &iface) != 0) {
- _usbi_log (HANDLE_CTX (dev_handle), LOG_LEVEL_ERROR, "endpoint not found on any open interface");
+ usbi_err (HANDLE_CTX (dev_handle), "endpoint not found on any open interface");
return LIBUSB_ERROR_NOT_FOUND;
}
@@ -1001,7 +1014,7 @@ static int darwin_clear_halt(struct libusb_device_handle *dev_handle, unsigned c
kresult = (*(cInterface->interface))->ClearPipeStallBothEnds(cInterface->interface, pipeRef);
#endif
if (kresult)
- _usbi_log (HANDLE_CTX (dev_handle), LOG_LEVEL_ERROR, "ClearPipeStall: %s", darwin_error_str (kresult));
+ usbi_err (HANDLE_CTX (dev_handle), "ClearPipeStall: %s", darwin_error_str (kresult));
return darwin_to_libusb (kresult);
}
@@ -1012,7 +1025,7 @@ static int darwin_reset_device(struct libusb_device_handle *dev_handle) {
kresult = (*(dpriv->device))->ResetDevice (dpriv->device);
if (kresult)
- _usbi_log (HANDLE_CTX (dev_handle), LOG_LEVEL_ERROR, "ResetDevice: %s", darwin_error_str (kresult));
+ usbi_err (HANDLE_CTX (dev_handle), "ResetDevice: %s", darwin_error_str (kresult));
return darwin_to_libusb (kresult);
}
@@ -1025,7 +1038,7 @@ static int darwin_kernel_driver_active(struct libusb_device_handle *dev_handle,
kresult = darwin_get_interface (dpriv->device, interface, &usbInterface);
if (kresult) {
- _usbi_log (HANDLE_CTX (dev_handle), LOG_LEVEL_ERROR, "darwin_get_interface: %s", darwin_error_str(kresult));
+ usbi_err (HANDLE_CTX (dev_handle), "darwin_get_interface: %s", darwin_error_str(kresult));
return darwin_to_libusb (kresult);
}
@@ -1072,7 +1085,7 @@ static int submit_bulk_transfer(struct usbi_transfer *itransfer) {
is_read = transfer->endpoint & LIBUSB_ENDPOINT_IN;
if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, &iface) != 0) {
- _usbi_log (TRANSFER_CTX (transfer), LOG_LEVEL_ERROR, "endpoint not found on any open interface");
+ usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
return LIBUSB_ERROR_NOT_FOUND;
}
@@ -1103,8 +1116,8 @@ static int submit_bulk_transfer(struct usbi_transfer *itransfer) {
}
if (ret)
- _usbi_log (TRANSFER_CTX (transfer), LOG_LEVEL_ERROR, "bulk transfer failed (dir = %s): %s", is_read ? "In" : "Out",
- darwin_error_str(ret));
+ usbi_err (TRANSFER_CTX (transfer), "bulk transfer failed (dir = %s): %s (code = 0x%08x)", is_read ? "In" : "Out",
+ darwin_error_str(ret), ret);
return darwin_to_libusb (ret);
}
@@ -1137,7 +1150,7 @@ static int submit_iso_transfer(struct usbi_transfer *itransfer) {
/* determine the interface/endpoint to use */
if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, &iface) != 0) {
- _usbi_log (TRANSFER_CTX (transfer), LOG_LEVEL_ERROR, "endpoint not found on any open interface");
+ usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
return LIBUSB_ERROR_NOT_FOUND;
}
@@ -1147,7 +1160,7 @@ static int submit_iso_transfer(struct usbi_transfer *itransfer) {
/* Last but not least we need the bus frame number */
kresult = (*(cInterface->interface))->GetBusFrameNumber(cInterface->interface, &frame, &atTime);
if (kresult) {
- _usbi_log (TRANSFER_CTX (transfer), LOG_LEVEL_ERROR, "failed to get bus frame number: %d", kresult);
+ usbi_err (TRANSFER_CTX (transfer), "failed to get bus frame number: %d", kresult);
free(tpriv->isoc_framelist);
tpriv->isoc_framelist = NULL;
@@ -1168,7 +1181,7 @@ static int submit_iso_transfer(struct usbi_transfer *itransfer) {
itransfer);
if (kresult != kIOReturnSuccess) {
- _usbi_log (TRANSFER_CTX (transfer), LOG_LEVEL_ERROR, "isochronous transfer failed (dir: %s): %s", is_read ? "In" : "Out",
+ usbi_err (TRANSFER_CTX (transfer), "isochronous transfer failed (dir: %s): %s", is_read ? "In" : "Out",
darwin_error_str(kresult));
free (tpriv->isoc_framelist);
tpriv->isoc_framelist = NULL;
@@ -1203,7 +1216,7 @@ static int submit_control_transfer(struct usbi_transfer *itransfer) {
kresult = (*(dpriv->device))->DeviceRequestAsyncTO(dpriv->device, &(tpriv->req), darwin_async_io_callback, itransfer);
if (kresult != kIOReturnSuccess)
- _usbi_log (TRANSFER_CTX (transfer), LOG_LEVEL_ERROR, "control request failed: %s", darwin_error_str(kresult));
+ usbi_err (TRANSFER_CTX (transfer), "control request failed: %s", darwin_error_str(kresult));
return darwin_to_libusb (kresult);
}
@@ -1220,7 +1233,7 @@ static int darwin_submit_transfer(struct usbi_transfer *itransfer) {
case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
return submit_iso_transfer(itransfer);
default:
- _usbi_log (TRANSFER_CTX(transfer), LOG_LEVEL_ERROR, "unknown endpoint type %d", transfer->type);
+ usbi_err (TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
return LIBUSB_ERROR_INVALID_PARAM;
}
}
@@ -1230,7 +1243,7 @@ static int cancel_control_transfer(struct usbi_transfer *itransfer) {
struct darwin_device_priv *dpriv = (struct darwin_device_priv *)transfer->dev_handle->dev->os_priv;
IOReturn kresult;
- _usbi_log (ITRANSFER_CTX (itransfer), LOG_LEVEL_INFO, "WARNING: aborting all transactions control pipe");
+ usbi_info (ITRANSFER_CTX (itransfer), "WARNING: aborting all transactions control pipe");
kresult = (*(dpriv->device))->USBDeviceAbortPipeZero (dpriv->device);
@@ -1245,19 +1258,19 @@ static int darwin_abort_transfers (struct usbi_transfer *itransfer) {
IOReturn kresult;
if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, &iface) != 0) {
- _usbi_log (TRANSFER_CTX (transfer), LOG_LEVEL_ERROR, "endpoint not found on any open interface");
+ usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
return LIBUSB_ERROR_NOT_FOUND;
}
cInterface = &priv->interfaces[iface];
- _usbi_log (ITRANSFER_CTX (itransfer), LOG_LEVEL_INFO, "WARNING: aborting all transactions on interface %d pipe %d", iface, pipeRef);
+ usbi_info (ITRANSFER_CTX (itransfer), "WARNING: aborting all transactions on interface %d pipe %d", iface, pipeRef);
/* abort transactions */
(*(cInterface->interface))->AbortPipe (cInterface->interface, pipeRef);
- _usbi_log (ITRANSFER_CTX (itransfer), LOG_LEVEL_INFO, "calling clear pipe stall to clear the data toggle bit");
+ usbi_info (ITRANSFER_CTX (itransfer), "calling clear pipe stall to clear the data toggle bit");
/* clear the data toggle bit */
#if (InterfaceVersion < 190)
@@ -1281,7 +1294,7 @@ static int darwin_cancel_transfer(struct usbi_transfer *itransfer) {
case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
return darwin_abort_transfers (itransfer);
default:
- _usbi_log (TRANSFER_CTX(transfer), LOG_LEVEL_ERROR, "unknown endpoint type %d", transfer->type);
+ usbi_err (TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
return LIBUSB_ERROR_INVALID_PARAM;
}
}
@@ -1302,7 +1315,7 @@ static void darwin_async_io_callback (void *refcon, IOReturn result, void *arg0)
struct darwin_device_handle_priv *priv = (struct darwin_device_handle_priv *)transfer->dev_handle->os_priv;
UInt32 message;
- _usbi_log (ITRANSFER_CTX (itransfer), LOG_LEVEL_INFO, "an async io operation has completed");
+ usbi_info (ITRANSFER_CTX (itransfer), "an async io operation has completed");
/* send a completion message to the device's file descriptor */
message = MESSAGE_ASYNC_IO_COMPLETE;
@@ -1315,7 +1328,7 @@ static void darwin_async_io_callback (void *refcon, IOReturn result, void *arg0)
static void darwin_bulk_callback (struct usbi_transfer *itransfer, kern_return_t result, UInt32 io_size) {
enum libusb_transfer_status status;
- _usbi_log (ITRANSFER_CTX (itransfer), LOG_LEVEL_INFO, "handling bulk completion with status %d", result);
+ usbi_info (ITRANSFER_CTX (itransfer), "handling bulk completion with status %d", result);
switch (result) {
case kIOReturnSuccess:
@@ -1326,17 +1339,17 @@ static void darwin_bulk_callback (struct usbi_transfer *itransfer, kern_return_t
usbi_handle_transfer_cancellation(itransfer);
return;
case kIOUSBPipeStalled:
- _usbi_log (ITRANSFER_CTX (itransfer), LOG_LEVEL_WARNING, "bulk error. pipe is stalled");
+ usbi_warn (ITRANSFER_CTX (itransfer), "bulk error. pipe is stalled");
status = LIBUSB_TRANSFER_STALL;
break;
case kIOReturnOverrun:
- _usbi_log (ITRANSFER_CTX (itransfer), LOG_LEVEL_ERROR, "bulk error. data overrun", darwin_error_str (result));
+ usbi_err (ITRANSFER_CTX (itransfer), "bulk error. data overrun", darwin_error_str (result));
status = LIBUSB_TRANSFER_OVERFLOW;
break;
default:
- _usbi_log (ITRANSFER_CTX (itransfer), LOG_LEVEL_ERROR, "bulk error = %s (value = 0x%08x)", darwin_error_str (result), result);
+ usbi_err (ITRANSFER_CTX (itransfer), "bulk error = %s (value = 0x%08x)", darwin_error_str (result), result);
status = LIBUSB_TRANSFER_ERROR;
}
@@ -1348,7 +1361,7 @@ static void darwin_isoc_callback (struct usbi_transfer *itransfer, kern_return_t
struct darwin_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer);
int i, status;
- _usbi_log (ITRANSFER_CTX (itransfer), LOG_LEVEL_INFO, "handling isoc completion with status %d", result);
+ usbi_info (ITRANSFER_CTX (itransfer), "handling isoc completion with status %d", result);
if (result == kIOReturnSuccess && tpriv->isoc_framelist) {
/* copy isochronous results back */
@@ -1368,17 +1381,17 @@ static void darwin_isoc_callback (struct usbi_transfer *itransfer, kern_return_t
usbi_handle_transfer_cancellation(itransfer);
return;
case kIOUSBPipeStalled:
- _usbi_log (ITRANSFER_CTX (itransfer), LOG_LEVEL_WARNING, "unsupported control request");
+ usbi_warn (ITRANSFER_CTX (itransfer), "unsupported control request");
status = LIBUSB_TRANSFER_STALL;
break;
case kIOReturnOverrun:
- _usbi_log (ITRANSFER_CTX (itransfer), LOG_LEVEL_ERROR, "bulk error. data overrun", darwin_error_str (result));
+ usbi_err (ITRANSFER_CTX (itransfer), "bulk error. data overrun", darwin_error_str (result));
status = LIBUSB_TRANSFER_OVERFLOW;
break;
default:
- _usbi_log (ITRANSFER_CTX (itransfer), LOG_LEVEL_ERROR, "control error = %s", darwin_error_str (result));
+ usbi_err (ITRANSFER_CTX (itransfer), "control error = %s", darwin_error_str (result));
status = LIBUSB_TRANSFER_ERROR;
}
@@ -1388,7 +1401,7 @@ static void darwin_isoc_callback (struct usbi_transfer *itransfer, kern_return_t
static void darwin_control_callback (struct usbi_transfer *itransfer, kern_return_t result, UInt32 io_size) {
int status;
- _usbi_log (ITRANSFER_CTX (itransfer), LOG_LEVEL_INFO, "handling control completion with status %d", result);
+ usbi_info (ITRANSFER_CTX (itransfer), "handling control completion with status %d", result);
switch (result) {
case kIOReturnSuccess:
@@ -1399,12 +1412,12 @@ static void darwin_control_callback (struct usbi_transfer *itransfer, kern_retur
usbi_handle_transfer_cancellation(itransfer);
return;
case kIOUSBPipeStalled:
- _usbi_log (ITRANSFER_CTX (itransfer), LOG_LEVEL_WARNING, "unsupported control request");
+ usbi_warn (ITRANSFER_CTX (itransfer), "unsupported control request");
status = LIBUSB_TRANSFER_STALL;
break;
default:
- _usbi_log (ITRANSFER_CTX (itransfer), LOG_LEVEL_ERROR, "control error = %s", darwin_error_str (result));
+ usbi_err (ITRANSFER_CTX (itransfer), "control error = %s", darwin_error_str (result));
status = LIBUSB_TRANSFER_ERROR;
}
@@ -1426,7 +1439,7 @@ static void darwin_handle_callback (struct usbi_transfer *itransfer, kern_return
darwin_isoc_callback (itransfer, result);
break;
default:
- _usbi_log (TRANSFER_CTX(transfer), LOG_LEVEL_ERROR, "unknown endpoint type %d", transfer->type);
+ usbi_err (TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
}
}
@@ -1437,13 +1450,13 @@ static int op_handle_events(struct libusb_context *ctx, struct pollfd *fds, nfds
int i = 0, ret;
UInt32 message;
- pthread_mutex_lock(&ctx->open_devs_lock);
+ usbi_mutex_lock(&ctx->open_devs_lock);
for (i = 0; i < nfds && num_ready > 0; i++) {
struct pollfd *pollfd = &fds[i];
struct libusb_device_handle *handle;
struct darwin_device_handle_priv *hpriv = NULL;
- _usbi_log (ctx, LOG_LEVEL_INFO, "checking fd %i with revents = %x", fds[i], pollfd->revents);
+ usbi_info (ctx, "checking fd %i with revents = %x", fds[i], pollfd->revents);
if (!pollfd->revents)
continue;
@@ -1486,11 +1499,11 @@ static int op_handle_events(struct libusb_context *ctx, struct pollfd *fds, nfds
darwin_handle_callback (itransfer, kresult, io_size);
break;
default:
- _usbi_log (ctx, LOG_LEVEL_ERROR, "unknown message received from device pipe");
+ usbi_err (ctx, "unknown message received from device pipe");
}
}
- pthread_mutex_unlock(&ctx->open_devs_lock);
+ usbi_mutex_unlock(&ctx->open_devs_lock);
return 0;
}
diff --git a/libusb/os/linux_usbfs.c b/libusb/os/linux_usbfs.c
index 3888aa9..dd38e65 100644
--- a/libusb/os/linux_usbfs.c
+++ b/libusb/os/linux_usbfs.c
@@ -1775,7 +1775,7 @@ static int handle_bulk_completion(struct usbi_transfer *itransfer,
enum libusb_transfer_status status = LIBUSB_TRANSFER_COMPLETED;
int r = 0;
- pthread_mutex_lock(&itransfer->lock);
+ usbi_mutex_lock(&itransfer->lock);
usbi_dbg("handling completion status %d of bulk urb %d/%d", urb->status,
urb_idx + 1, num_urbs);
@@ -1819,7 +1819,7 @@ static int handle_bulk_completion(struct usbi_transfer *itransfer,
if (tpriv->reap_action == CANCELLED) {
free(tpriv->urbs);
tpriv->urbs = NULL;
- pthread_mutex_unlock(&itransfer->lock);
+ usbi_mutex_unlock(&itransfer->lock);
r = usbi_handle_transfer_cancellation(itransfer);
goto out_unlock;
}
@@ -1897,10 +1897,10 @@ static int handle_bulk_completion(struct usbi_transfer *itransfer,
completed:
free(tpriv->urbs);
tpriv->urbs = NULL;
- pthread_mutex_unlock(&itransfer->lock);
+ usbi_mutex_unlock(&itransfer->lock);
return usbi_handle_transfer_completion(itransfer, status);
out_unlock:
- pthread_mutex_unlock(&itransfer->lock);
+ usbi_mutex_unlock(&itransfer->lock);
return r;
}
@@ -1914,7 +1914,7 @@ static int handle_iso_completion(struct usbi_transfer *itransfer,
int urb_idx = 0;
int i;
- pthread_mutex_lock(&itransfer->lock);
+ usbi_mutex_lock(&itransfer->lock);
for (i = 0; i < num_urbs; i++) {
if (urb == tpriv->iso_urbs[i]) {
urb_idx = i + 1;
@@ -1923,7 +1923,7 @@ static int handle_iso_completion(struct usbi_transfer *itransfer,
}
if (urb_idx == 0) {
usbi_err(TRANSFER_CTX(transfer), "could not locate urb!");
- pthread_mutex_unlock(&itransfer->lock);
+ usbi_mutex_unlock(&itransfer->lock);
return LIBUSB_ERROR_NOT_FOUND;
}
@@ -1951,10 +1951,10 @@ static int handle_iso_completion(struct usbi_transfer *itransfer,
usbi_dbg("CANCEL: last URB handled, reporting");
free_iso_urbs(tpriv);
if (tpriv->reap_action == CANCELLED) {
- pthread_mutex_unlock(&itransfer->lock);
+ usbi_mutex_unlock(&itransfer->lock);
return usbi_handle_transfer_cancellation(itransfer);
} else {
- pthread_mutex_unlock(&itransfer->lock);
+ usbi_mutex_unlock(&itransfer->lock);
return usbi_handle_transfer_completion(itransfer,
LIBUSB_TRANSFER_ERROR);
}
@@ -1981,12 +1981,12 @@ static int handle_iso_completion(struct usbi_transfer *itransfer,
if (urb_idx == num_urbs) {
usbi_dbg("last URB in transfer --> complete!");
free_iso_urbs(tpriv);
- pthread_mutex_unlock(&itransfer->lock);
+ usbi_mutex_unlock(&itransfer->lock);
return usbi_handle_transfer_completion(itransfer, LIBUSB_TRANSFER_COMPLETED);
}
out:
- pthread_mutex_unlock(&itransfer->lock);
+ usbi_mutex_unlock(&itransfer->lock);
return 0;
}
@@ -1996,7 +1996,7 @@ static int handle_control_completion(struct usbi_transfer *itransfer,
struct linux_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer);
int status;
- pthread_mutex_lock(&itransfer->lock);
+ usbi_mutex_lock(&itransfer->lock);
usbi_dbg("handling completion status %d", urb->status);
if (urb->status == 0)
@@ -2008,7 +2008,7 @@ static int handle_control_completion(struct usbi_transfer *itransfer,
"cancel: unrecognised urb status %d", urb->status);
free(tpriv->urbs);
tpriv->urbs = NULL;
- pthread_mutex_unlock(&itransfer->lock);
+ usbi_mutex_unlock(&itransfer->lock);
return usbi_handle_transfer_cancellation(itransfer);
}
@@ -2036,7 +2036,7 @@ static int handle_control_completion(struct usbi_transfer *itransfer,
free(tpriv->urbs);
tpriv->urbs = NULL;
- pthread_mutex_unlock(&itransfer->lock);
+ usbi_mutex_unlock(&itransfer->lock);
return usbi_handle_transfer_completion(itransfer, status);
}
@@ -2087,7 +2087,7 @@ static int op_handle_events(struct libusb_context *ctx,
int r;
int i = 0;
- pthread_mutex_lock(&ctx->open_devs_lock);
+ usbi_mutex_lock(&ctx->open_devs_lock);
for (i = 0; i < nfds && num_ready > 0; i++) {
struct pollfd *pollfd = &fds[i];
struct libusb_device_handle *handle;
@@ -2118,7 +2118,7 @@ static int op_handle_events(struct libusb_context *ctx,
r = 0;
out:
- pthread_mutex_unlock(&ctx->open_devs_lock);
+ usbi_mutex_unlock(&ctx->open_devs_lock);
return r;
}
diff --git a/libusb/os/sources b/libusb/os/sources
index c4d0163..669e32a 100644
--- a/libusb/os/sources
+++ b/libusb/os/sources
@@ -7,12 +7,6 @@ DLLDEF=..\libusb-1.0.def
MSC_WARNING_LEVEL=/W3
!ENDIF
-!IF "$(_BUILDARCH)"=="AMD64"
-PTHREAD_LIB=pthreadVC2_x64.lib
-!ELSE
-PTHREAD_LIB=pthreadVC2.lib
-!ENDIF
-
USE_MSVCRT=1
INCLUDES=..;..\..;..\..\msvc;$(DDK_INC_PATH)
@@ -22,13 +16,13 @@ TARGETLIBS=$(SDK_LIB_PATH)\kernel32.lib \
$(SDK_LIB_PATH)\advapi32.lib \
$(SDK_LIB_PATH)\user32.lib \
$(SDK_LIB_PATH)\setupapi.lib \
- $(SDK_LIB_PATH)\ole32.lib \
- ..\..\msvc\$(PTHREAD_LIB)
+ $(SDK_LIB_PATH)\ole32.lib
SOURCES=..\core.c \
..\descriptor.c \
..\io.c \
..\sync.c \
+ threads_windows.c \
windows_compat.c \
windows_usb.c \
libusb-1.0.rc
diff --git a/libusb/os/threads_posix.h b/libusb/os/threads_posix.h
new file mode 100644
index 0000000..7e34dc5
--- /dev/null
+++ b/libusb/os/threads_posix.h
@@ -0,0 +1,46 @@
+/*
+ * libusb synchronization using POSIX Threads
+ *
+ * Copyright (C) 2010 Peter Stuge <peter@stuge.se>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __LIBUSB_THREADS_POSIX_H__
+#define __LIBUSB_THREADS_POSIX_H__
+
+#include <pthread.h>
+
+#define usbi_mutex_static_t static pthread_mutex_t
+#define USBI_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
+#define usbi_mutex_static_lock pthread_mutex_lock
+#define usbi_mutex_static_unlock pthread_mutex_unlock
+
+#define usbi_mutex_t pthread_mutex_t
+#define usbi_mutex_init pthread_mutex_init
+#define usbi_mutex_lock pthread_mutex_lock
+#define usbi_mutex_unlock pthread_mutex_unlock
+#define usbi_mutex_trylock pthread_mutex_trylock
+#define usbi_mutex_destroy pthread_mutex_destroy
+
+#define usbi_cond_t pthread_cond_t
+#define usbi_cond_init pthread_cond_init
+#define usbi_cond_wait pthread_cond_wait
+#define usbi_cond_timedwait pthread_cond_timedwait
+#define usbi_cond_broadcast pthread_cond_broadcast
+#define usbi_cond_destroy pthread_cond_destroy
+#define usbi_cond_signal pthread_cond_signal
+
+#endif /* __LIBUSB_THREADS_POSIX_H__ */
diff --git a/libusb/os/threads_windows.c b/libusb/os/threads_windows.c
new file mode 100644
index 0000000..11b55f9
--- /dev/null
+++ b/libusb/os/threads_windows.c
@@ -0,0 +1,206 @@
+/*
+ * libusb synchronization on Microsoft Windows
+ *
+ * Copyright (C) 2010 Michael Plante <michael.plante@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <config.h>
+#include <objbase.h>
+#include <errno.h>
+#include <stdarg.h>
+
+#include "libusbi.h"
+
+
+int usbi_mutex_init(usbi_mutex_t *mutex,
+ const usbi_mutexattr_t *attr) {
+ if(! mutex) return ((errno=EINVAL));
+ *mutex = CreateMutex(NULL, FALSE, NULL);
+ if(!*mutex) return ((errno=ENOMEM));
+ return 0;
+}
+int usbi_mutex_destroy(usbi_mutex_t *mutex) {
+ // It is not clear if CloseHandle failure is due to failure to unlock.
+ // If so, this should be errno=EBUSY.
+ if(!mutex || !CloseHandle(*mutex)) return ((errno=EINVAL));
+ *mutex = NULL;
+ return 0;
+}
+int usbi_mutex_trylock(usbi_mutex_t *mutex) {
+ DWORD result;
+ if(!mutex) return ((errno=EINVAL));
+ result = WaitForSingleObject(*mutex, 0);
+ if(result == WAIT_OBJECT_0 || result == WAIT_ABANDONED)
+ return 0; // acquired (ToDo: check that abandoned is ok)
+ if(result == WAIT_TIMEOUT)
+ return ((errno=EBUSY));
+ return ((errno=EINVAL)); // don't know how this would happen
+ // so don't know proper errno
+}
+int usbi_mutex_lock(usbi_mutex_t *mutex) {
+ DWORD result;
+ if(!mutex) return ((errno=EINVAL));
+ result = WaitForSingleObject(*mutex, INFINITE);
+ if(result == WAIT_OBJECT_0 || result == WAIT_ABANDONED)
+ return 0; // acquired (ToDo: check that abandoned is ok)
+ return ((errno=EINVAL)); // don't know how this would happen
+ // so don't know proper errno
+}
+int usbi_mutex_unlock(usbi_mutex_t *mutex) {
+ if(!mutex) return ((errno=EINVAL));
+ if(!ReleaseMutex(mutex)) return ((errno=EPERM ));
+ return 0;
+}
+
+int usbi_mutex_static_lock(usbi_mutex_static_t *mutex) {
+ if(!mutex) return ((errno=EINVAL));
+ while (InterlockedExchange((LONG *)mutex, 1) == 1) {
+ SleepEx(0, TRUE);
+ }
+ return 0;
+}
+int usbi_mutex_static_unlock(usbi_mutex_static_t *mutex) {
+ if(!mutex) return ((errno=EINVAL));
+ *mutex = 0;
+ return 0;
+}
+
+
+
+int usbi_cond_init(usbi_cond_t *cond,
+ const usbi_condattr_t *attr) {
+ if(!cond) return ((errno=EINVAL));
+ list_init(&cond->waiters );
+ list_init(&cond->not_waiting);
+ return 0;
+}
+int 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, *prev_pos = NULL;
+ if(!cond) return ((errno=EINVAL));
+ if(!list_empty(&cond->waiters)) return ((errno=EBUSY )); // (!see above!)
+ list_for_each_entry(pos, &cond->not_waiting, list, struct usbi_cond_perthread) {
+ free(prev_pos);
+ list_del(&pos->list);
+ prev_pos = pos;
+ }
+ free(prev_pos);
+ prev_pos = pos = NULL;
+
+ return 0;
+}
+
+int 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!
+ int fail = 0;
+ struct usbi_cond_perthread *pos;
+ if(!cond) return ((errno=EINVAL));
+ list_for_each_entry(pos, &cond->waiters, list, struct usbi_cond_perthread) {
+ if(!SetEvent(pos->event))
+ fail = 1;
+ }
+ // The wait function will remove its respective item from the list.
+ return fail ? ((errno=EINVAL)) : 0;
+}
+int usbi_cond_signal(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;
+ if(!cond) return ((errno=EINVAL));
+ if(list_empty(&cond->waiters)) return 0; // no one to wakeup.
+ pos = list_entry(&cond->waiters.next, struct usbi_cond_perthread, list);
+ // The wait function will remove its respective item from the list.
+ return SetEvent(pos->event) ? 0 : ((errno=EINVAL));
+}
+static int __inline usbi_cond_intwait(usbi_cond_t *cond,
+ usbi_mutex_t *mutex,
+ DWORD timeout_ms) {
+ struct usbi_cond_perthread *pos;
+ int found = 0, r;
+ DWORD r2,tid = GetCurrentThreadId();
+ if(!cond || !mutex) return ((errno=EINVAL));
+ list_for_each_entry(pos, &cond->not_waiting, list, struct usbi_cond_perthread) {
+ if(tid == pos->tid) {
+ found = 1;
+ break;
+ }
+ }
+ if(!found) {
+ pos = malloc(sizeof(struct usbi_cond_perthread));
+ if(!pos) return ((errno=ENOMEM)); // This errno is not POSIX-allowed.
+ pos->tid = tid;
+ pos->event = CreateEvent(NULL, FALSE, FALSE, NULL); // auto-reset.
+ if(!pos->event) {
+ free(pos);
+ return ((errno=ENOMEM));
+ }
+ list_add(&pos->list, &cond->not_waiting);
+ }
+
+ list_del(&pos->list); // remove from not_waiting list.
+ list_add(&pos->list, &cond->waiters);
+
+ r = usbi_mutex_unlock(mutex);
+ if(r) return r;
+ r2 = WaitForSingleObject(pos->event, timeout_ms);
+ r = usbi_mutex_lock(mutex);
+ if(r) return r;
+
+ list_del(&pos->list);
+ list_add(&pos->list, &cond->not_waiting);
+
+ if(r2 == WAIT_TIMEOUT) return ((errno=ETIMEDOUT));
+
+ return 0;
+}
+// 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 timespec *abstime) {
+ FILETIME ftime;
+ ULARGE_INTEGER rtime;
+ struct timeval targ_time, cur_time, delta_time;
+ struct timespec cur_time_ns;
+ DWORD millis;
+ extern const uint64_t epoch_time;
+
+ GetSystemTimeAsFileTime(&ftime);
+ rtime.LowPart = ftime.dwLowDateTime;
+ rtime.HighPart = ftime.dwHighDateTime;
+ rtime.QuadPart -= epoch_time;
+ cur_time_ns.tv_sec = (long)(rtime.QuadPart / 10000000);
+ cur_time_ns.tv_nsec = (long)((rtime.QuadPart % 10000000)*100);
+ TIMESPEC_TO_TIMEVAL(&cur_time, &cur_time_ns);
+
+ TIMESPEC_TO_TIMEVAL(&targ_time, abstime);
+ timersub(&targ_time, &cur_time, &delta_time);
+ if(delta_time.tv_sec <= 0) // abstime already passed?
+ millis = 0;
+ else {
+ millis = delta_time.tv_usec/1000;
+ millis += delta_time.tv_sec *1000;
+ }
+
+ return usbi_cond_intwait(cond, mutex, millis);
+}
+
diff --git a/libusb/os/threads_windows.h b/libusb/os/threads_windows.h
new file mode 100644
index 0000000..52ae9c1
--- /dev/null
+++ b/libusb/os/threads_windows.h
@@ -0,0 +1,83 @@
+/*
+ * libusb synchronization on Microsoft Windows
+ *
+ * Copyright (C) 2010 Michael Plante <michael.plante@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __LIBUSB_THREADS_WINDOWS_H__
+#define __LIBUSB_THREADS_WINDOWS_H__
+
+#define usbi_mutex_static_t volatile LONG
+#define USBI_MUTEX_INITIALIZER 0
+
+#define usbi_mutex_t HANDLE
+
+struct usbi_cond_perthread {
+ struct list_head list;
+ DWORD tid;
+ HANDLE event;
+};
+struct usbi_cond_t_ {
+ // 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;
+};
+typedef struct usbi_cond_t_ usbi_cond_t;
+
+// We *were* getting timespec from pthread.h:
+#ifndef HAVE_STRUCT_TIMESPEC
+#define HAVE_STRUCT_TIMESPEC 1
+struct timespec {
+ long tv_sec;
+ long tv_nsec;
+};
+#endif /* HAVE_STRUCT_TIMESPEC */
+
+// We *were* getting ETIMEDOUT from pthread.h:
+#ifndef ETIMEDOUT
+# define ETIMEDOUT 10060 /* This is the value in winsock.h. */
+#endif
+
+#define usbi_mutexattr_t void
+#define usbi_condattr_t void
+
+
+int usbi_mutex_static_lock(usbi_mutex_static_t *mutex);
+int usbi_mutex_static_unlock(usbi_mutex_static_t *mutex);
+
+
+int usbi_mutex_init(usbi_mutex_t *mutex,
+ const usbi_mutexattr_t *attr);
+int usbi_mutex_lock(usbi_mutex_t *mutex);
+int usbi_mutex_unlock(usbi_mutex_t *mutex);
+int usbi_mutex_trylock(usbi_mutex_t *mutex);
+int usbi_mutex_destroy(usbi_mutex_t *mutex);
+
+int usbi_cond_init(usbi_cond_t *cond,
+ const usbi_condattr_t *attr);
+int usbi_cond_destroy(usbi_cond_t *cond);
+int usbi_cond_wait(usbi_cond_t *cond, usbi_mutex_t *mutex);
+int usbi_cond_timedwait(usbi_cond_t *cond,
+ usbi_mutex_t *mutex,
+ const struct timespec *abstime);
+int usbi_cond_broadcast(usbi_cond_t *cond);
+int usbi_cond_signal(usbi_cond_t *cond);
+
+#endif /* __LIBUSB_THREADS_WINDOWS_H__ */
+
diff --git a/libusb/os/unistd_posix.h b/libusb/os/unistd_posix.h
new file mode 100644
index 0000000..0e9981d
--- /dev/null
+++ b/libusb/os/unistd_posix.h
@@ -0,0 +1,12 @@
+#ifndef __LIBUSB_UNISTD_POSIX_H__
+#define __LIBUSB_UNISTD_POSIX_H__
+
+#include <unistd.h>
+#include <poll.h>
+#define usbi_write write
+#define usbi_read read
+#define usbi_close close
+#define usbi_pipe pipe
+#define usbi_poll poll
+
+#endif /* __LIBUSB_UNISTD_POSIX_H__ */
diff --git a/libusb/os/windows_compat.c b/libusb/os/windows_compat.c
index f4bc7ab..664bf5d 100644
--- a/libusb/os/windows_compat.c
+++ b/libusb/os/windows_compat.c
@@ -1,7 +1,7 @@
/*
* Windows compat: POSIX compatibility wrapper
- * Copyright (C) 2009 Pete Batard <pbatard@gmail.com>
- *
+ * Copyright (C) 2009-2010 Pete Batard <pbatard@gmail.com>
+ * With contributions from Michael Plante, Orin Eman et al.
* Parts of poll implementation from libusb-win32, by Stephan Meyer et al.
*
* This library is free software; you can redistribute it and/or
@@ -29,26 +29,26 @@
* For USB pollable async I/O, you would typically:
* - obtain a Windows HANDLE to a file or device that has been opened in
* OVERLAPPED mode
- * - call _libusb_create_fd with this handle to obtain a custom fd.
+ * - call usbi_create_fd with this handle to obtain a custom fd.
* Note that if you need simultaneous R/W access, you need to call create_fd
* twice, once in _O_RDONLY and once in _O_WRONLY mode to obtain 2 separate
* pollable fds
* - leave the core functions call the poll routine and flag POLLIN/POLLOUT
*
* For pipe pollable synchronous I/O (read end polling only), you would:
- * - create an anonymous pipe with _libusb_pipe to obtain 2 fds (r & w)
- * - use _libusb_write / _libusb_read to write to either end of the pipe
+ * - create an anonymous pipe with usbi_pipe to obtain 2 fds (r & w)
+ * - use usbi_write / usbi_read to write to either end of the pipe
* - use poll to check for data to read
- * Note that the _libusb_read/_libusb_write function actually perform
+ * Note that the usbi_read/usbi_write function actually perform
* asynchronous I/O internally, and could potentially be modified to support
* O_NON_BLOCK
*
- * The way the polling on _libusb_read works is by splitting all read I/O
+ * The way the polling on usbi_read works is by splitting all read I/O
* into a dual 1 byte/n-1 bytes asynchronous read operation.
* The 1 byte data (called the marker), is always armed for asynchronous
* readout, so that as soon as data becomes available, an OVERLAPPED event
* will be flagged, which poll can report.
- * Then during the _libusb_read routine itself, this 1 byte marker is copied
+ * Then during the usbi_read routine itself, this 1 byte marker is copied
* to the buffer, along with the rest of the data.
*
* Note that, since most I/O is buffered, being notified when only the first
@@ -56,19 +56,17 @@
* rest of the data should be available in system buffers by the time read
* is called.
*
- * Also note that if you don't use _libusb_read to read inbound data, but
+ * Also note that if you don't use usbi_read to read inbound data, but
* use the OVERLAPPED directly (which is what we do in the USB async I/O
* functions), the marker is not used at all.
*/
-#include <windows.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
-#include <stdint.h>
#include <io.h>
-#include "windows_compat.h"
+#include <libusbi.h>
// Uncomment to debug the polling layer
//#define DEBUG_WINDOWS_COMPAT
@@ -88,7 +86,7 @@
#pragma warning(disable:28719)
#endif
-#if defined(__CYGWIN__ )
+#if defined(__CYGWIN__)
// cygwin produces a warning unless these prototypes are defined
extern int _close(int fd);
extern int _snprintf(char *buffer, size_t count, const char *format, ...);
@@ -124,7 +122,7 @@ struct winfd poll_fd[MAX_FDS];
// internal fd data
struct {
CRITICAL_SECTION mutex; // lock for fds
- BYTE marker; // 1st byte of a _libusb_read operation gets stored here
+ BYTE marker; // 1st byte of a usbi_read operation gets stored here
} _poll_fd[MAX_FDS];
@@ -295,7 +293,7 @@ __inline void _init_read_marker(int index)
/*
* Create an async I/O anonymous pipe (that can be used for sync as well)
*/
-int _libusb_pipe(int filedes[2])
+int usbi_pipe(int filedes[2])
{
int i, j;
HANDLE handle[2];
@@ -318,7 +316,7 @@ int _libusb_pipe(int filedes[2])
our_pipe_number = InterlockedIncrement(&pipe_number) - 1; // - 1 to mirror postfix operation inside _snprintf
if (our_pipe_number >= 0x10000) {
- fprintf(stderr, "_libusb_pipe: program assertion failed - more than 65536 pipes were used");
+ fprintf(stderr, "usbi_pipe: program assertion failed - more than 65536 pipes were used");
our_pipe_number &= 0xFFFF;
}
_snprintf(pipe_name, sizeof(pipe_name), "\\\\.\\pipe\\libusb%08x%04x", (unsigned)GetCurrentProcessId(), our_pipe_number);
@@ -407,7 +405,7 @@ out1:
* read and one for write. Using a single R/W fd is unsupported and will
* produce unexpected results
*/
-struct winfd _libusb_create_fd(HANDLE handle, int access_mode)
+struct winfd usbi_create_fd(HANDLE handle, int access_mode)
{
int i, fd;
struct winfd wfd = INVALID_WINFD;
@@ -420,7 +418,7 @@ struct winfd _libusb_create_fd(HANDLE handle, int access_mode)
}
if ((access_mode != _O_RDONLY) && (access_mode != _O_WRONLY)) {
- printb("_libusb_create_fd: only one of _O_RDONLY or _O_WRONLY are supported.\n"
+ printb("usbi_create_fd: only one of _O_RDONLY or _O_WRONLY are supported.\n"
"If you want to poll for R/W simultaneously, create multiple fds from the same handle.\n");
return INVALID_WINFD;
}
@@ -482,7 +480,7 @@ void _free_index(int index)
*
* Note that the associated Windows handle is not closed by this call
*/
-void _libusb_free_fd(int fd)
+void usbi_free_fd(int fd)
{
int index;
@@ -582,7 +580,7 @@ struct winfd overlapped_to_winfd(OVERLAPPED* overlapped)
* Currently, this function only accepts one of POLLIN or POLLOUT per fd
* (but you can create multiple fds from the same handle for read and write)
*/
-int _libusb_poll(struct pollfd *fds, unsigned int nfds, int timeout)
+int usbi_poll(struct pollfd *fds, unsigned int nfds, int timeout)
{
unsigned i;
int index, object_index, triggered;
@@ -609,7 +607,7 @@ int _libusb_poll(struct pollfd *fds, unsigned int nfds, int timeout)
if ((fds[i].events & ~POLLIN) && (!(fds[i].events & POLLOUT))) {
fds[i].revents |= POLLERR;
errno = EACCES;
- printb("_libusb_poll: unsupported set of events\n");
+ printb("usbi_poll: unsupported set of events\n");
triggered = -1;
goto poll_exit;
}
@@ -622,7 +620,7 @@ int _libusb_poll(struct pollfd *fds, unsigned int nfds, int timeout)
if (index >= 0) {
LeaveCriticalSection(&_poll_fd[index].mutex);
}
- printb("_libusb_poll: invalid fd\n");
+ printb("usbi_poll: invalid fd\n");
triggered = -1;
goto poll_exit;
}
@@ -631,7 +629,7 @@ int _libusb_poll(struct pollfd *fds, unsigned int nfds, int timeout)
if ((fds[i].events & POLLIN) && (poll_fd[index].rw != RW_READ)) {
fds[i].revents |= POLLNVAL | POLLERR;
errno = EBADF;
- printb("_libusb_poll: attempted POLLIN on fd[%d] without READ access\n", i);
+ printb("usbi_poll: attempted POLLIN on fd[%d] without READ access\n", i);
LeaveCriticalSection(&_poll_fd[index].mutex);
triggered = -1;
goto poll_exit;
@@ -640,13 +638,13 @@ int _libusb_poll(struct pollfd *fds, unsigned int nfds, int timeout)
if ((fds[i].events & POLLOUT) && (poll_fd[index].rw != RW_WRITE)) {
fds[i].revents |= POLLNVAL | POLLERR;
errno = EBADF;
- printb("_libusb_poll: attempted POLLOUT on fd[%d] without WRITE access\n", i);
+ printb("usbi_poll: attempted POLLOUT on fd[%d] without WRITE access\n", i);
LeaveCriticalSection(&_poll_fd[index].mutex);
triggered = -1;
goto poll_exit;
}
- printb("_libusb_poll: fd[%d]=%d (overlapped = %p) got events %04X\n", i, poll_fd[index].fd, poll_fd[index].overlapped, fds[i].events);
+ printb("usbi_poll: fd[%d]=%d (overlapped = %p) got events %04X\n", i, poll_fd[index].fd, poll_fd[index].overlapped, fds[i].events);
// The following macro only works if overlapped I/O was reported pending
if ( (HasOverlappedIoCompleted(poll_fd[index].overlapped))
@@ -665,7 +663,7 @@ int _libusb_poll(struct pollfd *fds, unsigned int nfds, int timeout)
// If nothing was triggered, wait on all fds that require it
if ((triggered == 0) && (nb_handles_to_wait_on != 0)) {
- printb("_libusb_poll: starting %d ms wait for %d handles...\n", timeout, (int)nb_handles_to_wait_on);
+ printb("usbi_poll: starting %d ms wait for %d handles...\n", timeout, (int)nb_handles_to_wait_on);
ret = WaitForMultipleObjects(nb_handles_to_wait_on, handles_to_wait_on,
FALSE, (timeout==-1)?INFINITE:(DWORD)timeout);
@@ -703,7 +701,7 @@ poll_exit:
*
* Note that this function will also close the associated handle
*/
-int _libusb_close(int fd)
+int usbi_close(int fd)
{
int index;
HANDLE handle;
@@ -736,7 +734,7 @@ int _libusb_close(int fd)
* - binary mode only
* - no append mode
*/
-ssize_t _libusb_write(int fd, const void *buf, size_t count)
+ssize_t usbi_write(int fd, const void *buf, size_t count)
{
int index;
DWORD wr_count;
@@ -761,11 +759,11 @@ ssize_t _libusb_write(int fd, const void *buf, size_t count)
// For sync mode, we shouldn't get pending async write I/O
if (!HasOverlappedIoCompleted(poll_fd[index].overlapped)) {
- printb("_libusb_write: previous write I/O was flagged pending!\n");
+ printb("usbi_write: previous write I/O was flagged pending!\n");
cancel_io(index);
}
- printb("_libusb_write: writing %d bytes to fd=%d\n", count, poll_fd[index].fd);
+ printb("usbi_write: writing %d bytes to fd=%d\n", count, poll_fd[index].fd);
reset_overlapped(poll_fd[index].overlapped);
if (!WriteFile(poll_fd[index].handle, buf, (DWORD)count, &wr_count, poll_fd[index].overlapped)) {
@@ -779,7 +777,7 @@ ssize_t _libusb_write(int fd, const void *buf, size_t count)
r = 0;
goto out;
} else {
- printb("_libusb_write: GetOverlappedResult failed with error %d\n", (int)GetLastError());
+ printb("usbi_write: GetOverlappedResult failed with error %d\n", (int)GetLastError());
errno = EIO;
goto out;
}
@@ -789,7 +787,7 @@ ssize_t _libusb_write(int fd, const void *buf, size_t count)
}
} else {
// I/O started and failed
- printb("_libusb_write: WriteFile failed with error %d\n", (int)GetLastError());
+ printb("usbi_write: WriteFile failed with error %d\n", (int)GetLastError());
errno = EIO;
goto out;
}
@@ -813,7 +811,7 @@ out:
* synchronous read for custom poll (works on Windows file handles that
* have been opened with the FILE_FLAG_OVERLAPPED flag)
*/
-ssize_t _libusb_read(int fd, void *buf, size_t count)
+ssize_t usbi_read(int fd, void *buf, size_t count)
{
int index;
DWORD rd_count;
@@ -841,7 +839,7 @@ ssize_t _libusb_read(int fd, void *buf, size_t count)
// still waiting for completion => force completion
if (!HasOverlappedIoCompleted(poll_fd[index].overlapped)) {
if (WaitForSingleObject(poll_fd[index].overlapped->hEvent, INFINITE) != WAIT_OBJECT_0) {
- printb("_libusb_read: waiting for marker failed: %d\n", (int)GetLastError());
+ printb("usbi_read: waiting for marker failed: %d\n", (int)GetLastError());
errno = EIO;
goto out;
}
@@ -850,19 +848,19 @@ ssize_t _libusb_read(int fd, void *buf, size_t count)
// Find out if we've read the first byte
if (!GetOverlappedResult(poll_fd[index].handle, poll_fd[index].overlapped, &rd_count, FALSE)) {
if (GetLastError() != ERROR_MORE_DATA) {
- printb("_libusb_read: readout of marker failed: %d\n", (int)GetLastError());
+ printb("usbi_read: readout of marker failed: %d\n", (int)GetLastError());
errno = EIO;
goto out;
} else {
- printb("_libusb_read: readout of marker reported more data\n");
+ printb("usbi_read: readout of marker reported more data\n");
}
}
- printb("_libusb_read: count = %d, rd_count(marker) = %d\n", count, (int)rd_count);
+ printb("usbi_read: count = %d, rd_count(marker) = %d\n", count, (int)rd_count);
// We should have our marker by now
if (rd_count != 1) {
- printb("_libusb_read: unexpected number of bytes for marker (%d)\n", (int)rd_count);
+ printb("usbi_read: unexpected number of bytes for marker (%d)\n", (int)rd_count);
errno = EIO;
goto out;
}
@@ -876,24 +874,24 @@ ssize_t _libusb_read(int fd, void *buf, size_t count)
if(GetLastError() == ERROR_IO_PENDING) {
if (!GetOverlappedResult(poll_fd[index].handle, poll_fd[index].overlapped, &rd_count, TRUE)) {
if (GetLastError() == ERROR_MORE_DATA) {
- printb("_libusb_read: could not fetch all data\n");
+ printb("usbi_read: could not fetch all data\n");
}
- printb("_libusb_read: readout of supplementary data failed: %d\n", (int)GetLastError());
+ printb("usbi_read: readout of supplementary data failed: %d\n", (int)GetLastError());
errno = EIO;
goto out;
}
} else {
- printb("_libusb_read: could not start blocking read of supplementary: %d\n", (int)GetLastError());
+ printb("usbi_read: could not start blocking read of supplementary: %d\n", (int)GetLastError());
errno = EIO;
goto out;
}
}
// If ReadFile completed synchronously, we're fine too
- printb("_libusb_read: rd_count(supplementary ) = %d\n", (int)rd_count);
+ printb("usbi_read: rd_count(supplementary ) = %d\n", (int)rd_count);
if ((rd_count+1) != count) {
- printb("_libusb_read: wanted %d-1, got %d\n", count, (int)rd_count);
+ printb("usbi_read: wanted %d-1, got %d\n", count, (int)rd_count);
errno = EIO;
goto out;
}
diff --git a/libusb/os/windows_compat.h b/libusb/os/windows_compat.h
index 76f8417..699f167 100644
--- a/libusb/os/windows_compat.h
+++ b/libusb/os/windows_compat.h
@@ -1,7 +1,7 @@
/*
* Windows compat: POSIX compatibility wrapper
- * Copyright (C) 2009 Pete Batard <pbatard@gmail.com>
- *
+ * Copyright (C) 2009-2010 Pete Batard <pbatard@gmail.com>
+ * With contributions from Michael Plante, Orin Eman et al.
* Parts of poll implementation from libusb-win32, by Stephan Meyer et al.
*
* This library is free software; you can redistribute it and/or
@@ -43,6 +43,7 @@ extern enum windows_version windows_version;
#define MAX_FDS 256
+#if !defined(__CYGWIN__)
#define POLLIN 0x0001 /* There is data to read */
#define POLLPRI 0x0002 /* There is urgent data to read */
#define POLLOUT 0x0004 /* Writing now will not block */
@@ -55,6 +56,7 @@ struct pollfd {
short events; /* requested events */
short revents; /* returned events */
};
+#endif
typedef unsigned int nfds_t;
// access modes
@@ -74,16 +76,16 @@ struct winfd {
};
extern const struct winfd INVALID_WINFD;
-int _libusb_pipe(int pipefd[2]);
-int _libusb_poll(struct pollfd *fds, unsigned int nfds, int timeout);
-ssize_t _libusb_write(int fd, const void *buf, size_t count);
-ssize_t _libusb_read(int fd, void *buf, size_t count);
-int _libusb_close(int fd);
+int usbi_pipe(int pipefd[2]);
+int usbi_poll(struct pollfd *fds, unsigned int nfds, int timeout);
+ssize_t usbi_write(int fd, const void *buf, size_t count);
+ssize_t usbi_read(int fd, void *buf, size_t count);
+int usbi_close(int fd);
void init_polling(void);
void exit_polling(void);
-struct winfd _libusb_create_fd(HANDLE handle, int access_mode);
-void _libusb_free_fd(int fd);
+struct winfd usbi_create_fd(HANDLE handle, int access_mode);
+void usbi_free_fd(int fd);
struct winfd fd_to_winfd(int fd);
struct winfd handle_to_winfd(HANDLE handle);
struct winfd overlapped_to_winfd(OVERLAPPED* overlapped);
@@ -129,3 +131,4 @@ do { \
} \
} while (0)
#endif
+
diff --git a/libusb/os/windows_usb.c b/libusb/os/windows_usb.c
index 3723239..610a91d 100644
--- a/libusb/os/windows_usb.c
+++ b/libusb/os/windows_usb.c
@@ -1,7 +1,9 @@
/*
* windows backend for libusb 1.0
- * Copyright (c) 2009 Pete Batard <pbatard@gmail.com>
+ * Copyright (c) 2009-2010 Pete Batard <pbatard@gmail.com>
+ * With contributions from Michael Plante, Orin Eman et al.
* Parts of this code adapted from libusb-win32-v1 by Stephan Meyer
+ * Major code testing contribution by Xiaofan Chen
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -28,12 +30,12 @@
//#define USE_HIDD_FOR_REPORTS
// - Should libusb automatically claim the interfaces it requires?
#define AUTO_CLAIM
+// - Forces instant overlapped completion on timeouts: can prevents extensive
+// wait in poll, after a timeout, but might affect subsequent API calls.
+// ***USE AT YOUR OWN RISKS***
+//#define FORCE_INSTANT_TIMEOUTS
-#if defined(_MSC_VER)
-#include <config_msvc.h>
-#else
#include <config.h>
-#endif
#include <windows.h>
#include <setupapi.h>
#include <ctype.h>
@@ -44,7 +46,7 @@
#include <inttypes.h>
#include <objbase.h> // for string to GUID conv. requires libole32.a
-#include "libusbi.h"
+#include <libusbi.h>
#include "windows_compat.h"
#include "windows_usb.h"
@@ -494,7 +496,7 @@ static int windows_init(struct libusb_context *ctx)
_hcd_cur = &((*_hcd_cur)->next);
}
- // TODO (v2): thread for hotplug (see darwin source)
+ // TODO (2nd official release): thread for hotplug (see darwin source)
}
if (hcd_root == NULL)
@@ -561,7 +563,7 @@ static int initialize_device(struct libusb_device *dev, libusb_bus_t busnum,
usbi_dbg("active config: %d", priv->active_config);
} else {
// USB devices that don't have a config value are usually missing a driver
- // TODO (v1.5): use this for automated driver installation
+ // TODO (after first official release): use this for automated driver installation
// NB: SetupDiGetDeviceRegistryProperty w/ SPDRP_INSTALL_STATE would tell us
// if the driver is properly installed, but driverless devices don't seem to
// be enumerable by SetupDi...
@@ -739,7 +741,7 @@ static int usb_enumerate_hub(struct libusb_context *ctx, struct discovered_devs
char *tmp_str = NULL, *path_str = NULL;
unsigned long session_id;
libusb_devaddr_t devaddr = 0;
- struct windows_device_priv *priv, *parent_priv;
+ struct windows_device_priv *priv, *parent_priv;
// obviously, root (HCD) hubs have no parent
is_hcd = (parent_dev == NULL);
@@ -871,6 +873,10 @@ static int usb_enumerate_hub(struct libusb_context *ctx, struct discovered_devs
if (dev) {
usbi_dbg("using existing device for session %ld", session_id);
priv = __device_priv(dev);
+ // Because we are rebuilding the list, there's no guarantee
+ // the parent device pointer is still the same.
+ // Other device data should still be reusable
+ priv->parent_dev = parent_dev;
} else {
usbi_dbg("allocating new device for session %ld", session_id);
if ((dev = usbi_alloc_device(ctx, session_id)) == NULL) {
@@ -1264,9 +1270,7 @@ static int set_device_paths(struct libusb_context *ctx, struct discovered_devs *
uint8_t api;
bool found;
-// list_driverless(ctx);
-
- // TODO (v1.5): MI_## automated driver installation
+ // TODO (after first official release): MI_## automated driver installation
guid = GUID_DEVINTERFACE_USB_DEVICE;
for (i = 0; ; i++)
{
@@ -1553,6 +1557,12 @@ static int windows_get_active_config_descriptor(struct libusb_device *dev, unsig
static int windows_open(struct libusb_device_handle *dev_handle)
{
struct windows_device_priv *priv = __device_priv(dev_handle->dev);
+ struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
+
+ if (priv->apib == NULL) {
+ usbi_err(ctx, "program assertion failed - device is not initialized");
+ return LIBUSB_ERROR_NO_DEVICE;
+ }
return priv->apib->open(dev_handle);
}
@@ -1581,10 +1591,10 @@ static int windows_get_configuration(struct libusb_device_handle *dev_handle, in
* from http://msdn.microsoft.com/en-us/library/ms793522.aspx: "The port driver
* does not currently expose a service that allows higher-level drivers to set
* the configuration."
- * TODO (>v1): See what users of devices with multiple confs report with this call
*/
static int windows_set_configuration(struct libusb_device_handle *dev_handle, int config)
{
+ struct windows_device_priv *priv = __device_priv(dev_handle->dev);
int r = LIBUSB_SUCCESS;
if (config >= USB_MAXCONFIG)
@@ -1595,6 +1605,9 @@ static int windows_set_configuration(struct libusb_device_handle *dev_handle, in
LIBUSB_REQUEST_SET_CONFIGURATION, (uint16_t)config,
0, NULL, 0, 1000);
+ if (r == LIBUSB_SUCCESS) {
+ priv->active_config = (uint8_t)config;
+ }
return r;
}
@@ -1678,9 +1691,7 @@ static void windows_destroy_device(struct libusb_device *dev)
static void windows_clear_transfer_priv(struct usbi_transfer *itransfer)
{
struct windows_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
-
- usbi_remove_pollfd(ITRANSFER_CTX(itransfer), transfer_priv->pollable_fd.fd);
- _libusb_free_fd(transfer_priv->pollable_fd.fd);
+ usbi_free_fd(transfer_priv->pollable_fd.fd);
safe_free(transfer_priv->hid_buffer);
}
@@ -1778,23 +1789,25 @@ static int windows_abort_transfers(struct usbi_transfer *itransfer)
static int windows_cancel_transfer(struct usbi_transfer *itransfer)
{
struct libusb_transfer *transfer = __USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
+#if defined(FORCE_INSTANT_TIMEOUTS)
+ struct windows_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
- windows_clear_transfer_priv(itransfer); // Cancel polling
-
+ // Forces instant overlapped completion on timeouts - use at your own risks
+ if (itransfer->flags | USBI_TRANSFER_TIMED_OUT) {
+ transfer_priv->pollable_fd.overlapped->Internal &= ~STATUS_PENDING;
+ }
+#endif
switch (transfer->type) {
case LIBUSB_TRANSFER_TYPE_CONTROL:
- windows_abort_control(itransfer);
- break;
+ return windows_abort_control(itransfer);
case LIBUSB_TRANSFER_TYPE_BULK:
case LIBUSB_TRANSFER_TYPE_INTERRUPT:
case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
- windows_abort_transfers(itransfer);
- break;
+ return windows_abort_transfers(itransfer);
default:
usbi_err(ITRANSFER_CTX(itransfer), "unknown endpoint type %d", transfer->type);
- break;
+ return LIBUSB_ERROR_INVALID_PARAM;
}
- return usbi_handle_transfer_cancellation(itransfer);
}
static void windows_transfer_callback(struct usbi_transfer *itransfer, uint32_t io_result, uint32_t io_size)
@@ -1803,7 +1816,7 @@ static void windows_transfer_callback(struct usbi_transfer *itransfer, uint32_t
struct windows_device_priv *priv = __device_priv(transfer->dev_handle->dev);
int status;
- usbi_dbg("handling I/O completion with status %d", io_result);
+ usbi_dbg("handling I/O completion with errcode %d", io_result);
switch(io_result) {
case NO_ERROR:
@@ -1813,12 +1826,25 @@ static void windows_transfer_callback(struct usbi_transfer *itransfer, uint32_t
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:
+ if (itransfer->flags | USBI_TRANSFER_TIMED_OUT) {
+ usbi_dbg("detected timeout");
+ status = LIBUSB_TRANSFER_TIMED_OUT;
+ } else {
+ usbi_dbg("detected operation aborted");
+ status = LIBUSB_TRANSFER_CANCELLED;
+ }
+ break;
default:
- usbi_err(ITRANSFER_CTX(itransfer), "I/O error: %s", windows_error_str(0));
+ usbi_err(ITRANSFER_CTX(itransfer), "detected I/O error: %s", windows_error_str(0));
status = LIBUSB_TRANSFER_ERROR;
break;
}
-
+ windows_clear_transfer_priv(itransfer); // Cancel polling
usbi_handle_transfer_completion(itransfer, status);
}
@@ -1846,7 +1872,7 @@ static int windows_handle_events(struct libusb_context *ctx, struct pollfd *fds,
struct usbi_transfer *transfer;
DWORD io_size, io_result;
- pthread_mutex_lock(&ctx->open_devs_lock);
+ 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);
@@ -1880,7 +1906,7 @@ static int windows_handle_events(struct libusb_context *ctx, struct pollfd *fds,
io_result = GetLastError();
}
usbi_remove_pollfd(ctx, transfer_priv->pollable_fd.fd);
- _libusb_free_fd(transfer_priv->pollable_fd.fd);
+ usbi_free_fd(transfer_priv->pollable_fd.fd);
windows_handle_callback(transfer, io_result, io_size);
} else {
usbi_err(ctx, "could not find a matching transfer for fd %x", fds[i]);
@@ -1888,7 +1914,7 @@ static int windows_handle_events(struct libusb_context *ctx, struct pollfd *fds,
}
}
- pthread_mutex_unlock(&ctx->open_devs_lock);
+ usbi_mutex_unlock(&ctx->open_devs_lock);
return LIBUSB_SUCCESS;
}
@@ -2490,7 +2516,7 @@ static int winusb_submit_control_transfer(struct usbi_transfer *itransfer)
usbi_dbg("will use interface %d", current_interface);
winusb_handle = handle_priv->interface_handle[current_interface].api_handle;
- wfd = _libusb_create_fd(winusb_handle, _O_RDONLY);
+ wfd = usbi_create_fd(winusb_handle, _O_RDONLY);
if (wfd.fd < 0) {
return LIBUSB_ERROR_NO_MEM;
}
@@ -2498,7 +2524,7 @@ static int winusb_submit_control_transfer(struct usbi_transfer *itransfer)
if (!WinUsb_ControlTransfer(wfd.handle, *setup, transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE, size, NULL, wfd.overlapped)) {
if(GetLastError() != ERROR_IO_PENDING) {
usbi_err(ctx, "WinUsb_ControlTransfer failed: %s", windows_error_str(0));
- _libusb_free_fd(wfd.fd);
+ usbi_free_fd(wfd.fd);
return LIBUSB_ERROR_IO;
}
} else {
@@ -2566,7 +2592,7 @@ static int winusb_submit_bulk_transfer(struct usbi_transfer *itransfer)
winusb_handle = handle_priv->interface_handle[current_interface].api_handle;
direction_in = transfer->endpoint & LIBUSB_ENDPOINT_IN;
- wfd = _libusb_create_fd(winusb_handle, direction_in?_O_RDONLY:_O_WRONLY);
+ wfd = usbi_create_fd(winusb_handle, direction_in?_O_RDONLY:_O_WRONLY);
if (wfd.fd < 0) {
return LIBUSB_ERROR_NO_MEM;
}
@@ -2581,7 +2607,7 @@ static int winusb_submit_bulk_transfer(struct usbi_transfer *itransfer)
if (!ret) {
if(GetLastError() != ERROR_IO_PENDING) {
usbi_err(ctx, "WinUsb_Pipe Transfer failed: %s", windows_error_str(0));
- _libusb_free_fd(wfd.fd);
+ usbi_free_fd(wfd.fd);
return LIBUSB_ERROR_IO;
}
} else {
@@ -2670,7 +2696,7 @@ static int winusb_abort_transfers(struct usbi_transfer *itransfer)
* IOCTL_USB_HUB_CYCLE_PORT ioctl was removed from Vista => the best we can do is
* cycle the pipes (and even then, the control pipe can not be reset using WinUSB)
*/
-// TODO (v2): see if we can force eject the device and redetect it (reuse hotplug?)
+// TODO (2nd official release): see if we can force eject the device and redetect it (reuse hotplug?)
static int winusb_reset_device(struct libusb_device_handle *dev_handle)
{
struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
@@ -2689,7 +2715,7 @@ static int winusb_reset_device(struct libusb_device_handle *dev_handle)
{
// Cancel any pollable I/O
usbi_remove_pollfd(ctx, wfd.fd);
- _libusb_free_fd(wfd.fd);
+ usbi_free_fd(wfd.fd);
wfd = handle_to_winfd(winusb_handle);
}
@@ -3121,35 +3147,75 @@ static int _hid_set_report(struct hid_device_priv* dev, HANDLE hid_handle, int i
static int _hid_get_feature(struct hid_device_priv* dev, HANDLE hid_handle, int id, void *data, size_t *size)
{
- uint8_t buf[HID_MAX_REPORT_SIZE + 1];
+ uint8_t *buf;
+ ULONG read_size = (ULONG)(*size + 1);
+ int r = LIBUSB_ERROR_OTHER;
+ uint32_t err;
- if (*size >MAX_HID_REPORT_SIZE)
+ if (*size > MAX_HID_REPORT_SIZE)
return LIBUSB_ERROR_INVALID_PARAM;
+ buf = (uint8_t*)calloc(1, read_size);
+ if (buf == NULL) {
+ return LIBUSB_ERROR_NO_MEM;
+ }
buf[0] = (uint8_t)id;
+ usbi_dbg("report ID: 0x%02X", buf[0]);
- *size += 1;
- if (HidD_GetFeature(hid_handle, buf, (ULONG)*size)) {
- return LIBUSB_COMPLETED;
+ if (HidD_GetFeature(hid_handle, buf, read_size)) {
+ if (buf[0] != id) {
+ usbi_dbg("program assertion failed - mismatched report ID (got %02X instead of %02X)",
+ buf[0], id);
+ }
+ memcpy(data, buf+1, read_size);
+ r = LIBUSB_COMPLETED;
+ } else {
+ err = GetLastError();
+ switch (err) {
+ case ERROR_INVALID_FUNCTION:
+ r = LIBUSB_ERROR_NOT_FOUND;
+ default:
+ usbi_dbg("error %s", windows_error_str(r));
+ r = LIBUSB_ERROR_OTHER;
+ }
}
- return LIBUSB_ERROR_OTHER;
+ safe_free(buf);
+ return r;
}
static int _hid_set_feature(struct hid_device_priv* dev, HANDLE hid_handle, int id, void *data, size_t *size)
{
- uint8_t buf[HID_MAX_REPORT_SIZE + 1];
+ uint8_t *buf;
+ uint32_t err;
+ int r = LIBUSB_ERROR_OTHER;
+ ULONG write_size = (ULONG)(*size + 1);
if (*size >MAX_HID_REPORT_SIZE)
return LIBUSB_ERROR_INVALID_PARAM;
+ buf = (uint8_t*)malloc(write_size);
+ if (buf == NULL) {
+ return LIBUSB_ERROR_NO_MEM;
+ }
buf[0] = (uint8_t)id;
- memcpy(buf + 1, data, *size);
+ usbi_dbg("report ID: 0x%02X", buf[0]);
+
+ memcpy(buf+1, data, *size);
- *size += 1;
- if (HidD_SetFeature(hid_handle, buf, (ULONG)*size)) {
- return LIBUSB_COMPLETED;
+ if (HidD_SetFeature(hid_handle, buf, write_size)) {
+ r = LIBUSB_COMPLETED;
+ } else {
+ err = GetLastError();
+ switch (err) {
+ case ERROR_INVALID_FUNCTION:
+ r = LIBUSB_ERROR_NOT_FOUND;
+ default:
+ usbi_dbg("error %s", windows_error_str(r));
+ r = LIBUSB_ERROR_OTHER;
+ }
}
- return LIBUSB_ERROR_OTHER;
+ safe_free(buf);
+ return r;
}
static int _hid_class_request(struct hid_device_priv* dev, HANDLE hid_handle, int request_type,
@@ -3177,8 +3243,8 @@ static int _hid_class_request(struct hid_device_priv* dev, HANDLE hid_handle, in
&& report_type == HID_REPORT_TYPE_FEATURE)
return _hid_set_feature(dev, hid_handle, report_id, data, size);
- if (LIBUSB_REQ_OUT(request_type)
- && request == HID_REQ_SET_REPORT
+ if (LIBUSB_REQ_IN(request_type)
+ && request == HID_REQ_GET_REPORT
&& report_type == HID_REPORT_TYPE_FEATURE)
return _hid_get_feature(dev, hid_handle, report_id, data, size);
@@ -3308,15 +3374,15 @@ static int hid_open(struct libusb_device_handle *dev_handle)
priv->hid->input_report_id = value_caps[0].ReportID;
for (i=1; i<(int)size; i++) {
if (value_caps[i].ReportID != priv->hid->input_report_id) {
- usbi_warn(ctx, "multiple input report IDs found for HID");
- usbi_warn(ctx, " will only handle report ID 0x%02X for interrupt transfers",
+ usbi_warn(ctx, " multiple input report IDs found for HID:");
+ usbi_warn(ctx, " will only handle report ID 0x%02X for interrupt transfers",
priv->hid->input_report_id);
break;
}
}
- usbi_dbg("will use report ID 0x%02X for interrupt transfers", priv->hid->input_report_id);
+ usbi_dbg(" will use report ID 0x%02X for interrupt transfers", priv->hid->input_report_id);
} else {
- usbi_warn(ctx, "could process input report IDs");
+ usbi_warn(ctx, " could not process input report IDs");
}
safe_free(value_caps);
}
@@ -3332,20 +3398,20 @@ static int hid_open(struct libusb_device_handle *dev_handle)
priv->hid->output_report_id = value_caps[0].ReportID;
for (i=1; i<(int)size; i++) {
if (value_caps[i].ReportID != priv->hid->output_report_id) {
- usbi_warn(ctx, "multiple output report IDs found for HID");
- usbi_warn(ctx, " will only handle report ID 0x%02X for interrupt transfers",
+ usbi_warn(ctx, " multiple output report IDs found for HID:");
+ usbi_warn(ctx, " will only handle report ID 0x%02X for interrupt transfers",
priv->hid->output_report_id);
break;
}
}
- usbi_dbg("will use report ID 0x%02X for interrupt transfers", priv->hid->output_report_id);
+ usbi_dbg(" will use report ID 0x%02X for interrupt transfers", priv->hid->output_report_id);
} else {
usbi_warn(ctx, "could process output report IDs");
}
safe_free(value_caps);
}
- priv->hid->output_report_size = capabilities.OutputReportByteLength;
priv->hid->input_report_size = capabilities.InputReportByteLength;
+ priv->hid->output_report_size = capabilities.OutputReportByteLength;
priv->hid->feature_report_size = capabilities.FeatureReportByteLength;
// Fetch string descriptors
@@ -3488,7 +3554,7 @@ static int hid_submit_control_transfer(struct usbi_transfer *itransfer)
usbi_dbg("will use interface %d", current_interface);
hid_handle = handle_priv->interface_handle[current_interface].api_handle;
- wfd = _libusb_create_fd(hid_handle, _O_RDONLY);
+ wfd = usbi_create_fd(hid_handle, _O_RDONLY);
if (wfd.fd < 0) {
return LIBUSB_ERROR_NO_MEM;
}
@@ -3555,7 +3621,7 @@ static int hid_submit_control_transfer(struct usbi_transfer *itransfer)
transfer_priv->pollable_fd = wfd;
transfer_priv->interface_number = (uint8_t)current_interface;
} else {
- _libusb_free_fd(wfd.fd);
+ usbi_free_fd(wfd.fd);
}
return r;
@@ -3590,7 +3656,7 @@ static int hid_submit_bulk_transfer(struct usbi_transfer *itransfer) {
hid_handle = handle_priv->interface_handle[current_interface].api_handle;
direction_in = transfer->endpoint & LIBUSB_ENDPOINT_IN;
- wfd = _libusb_create_fd(hid_handle, direction_in?_O_RDONLY:_O_WRONLY);
+ wfd = usbi_create_fd(hid_handle, direction_in?_O_RDONLY:_O_WRONLY);
if (wfd.fd < 0) {
return LIBUSB_ERROR_NO_MEM;
}
@@ -3606,6 +3672,7 @@ static int hid_submit_bulk_transfer(struct usbi_transfer *itransfer) {
ret = ReadFile(hid_handle, transfer_priv->hid_buffer, transfer->length+1, &size, wfd.overlapped);
} else {
transfer_priv->hid_buffer[0] = priv->hid->output_report_id;
+ memcpy(transfer_priv->hid_buffer+1, transfer->buffer, transfer->length);
usbi_dbg("writing %d bytes (report ID: 0x%02X)", transfer->length+1, transfer_priv->hid_buffer[0]);
transfer_priv->hid_buffer[0] = 0;
ret = WriteFile(hid_handle, transfer_priv->hid_buffer, transfer->length+1, &size, wfd.overlapped);
@@ -3613,12 +3680,16 @@ static int hid_submit_bulk_transfer(struct usbi_transfer *itransfer) {
if (!ret) {
if (GetLastError() != ERROR_IO_PENDING) {
usbi_err(ctx, "HID transfer failed: %s", windows_error_str(0));
- _libusb_free_fd(wfd.fd);
+ usbi_free_fd(wfd.fd);
safe_free(transfer_priv->hid_buffer);
return LIBUSB_ERROR_IO;
}
} else {
- safe_free(transfer_priv->hid_buffer);
+ // Only write operations that completed synchronously need to free up
+ // hid_buffer. For reads, copy_transfer_data() handles that process.
+ if (transfer->endpoint & LIBUSB_ENDPOINT_OUT) {
+ safe_free(transfer_priv->hid_buffer);
+ }
if (size == 0) {
usbi_err(ctx, "program assertion failed - no data was transferred");
size = 1;
@@ -3628,7 +3699,7 @@ static int hid_submit_bulk_transfer(struct usbi_transfer *itransfer) {
r = LIBUSB_ERROR_OVERFLOW;
}
wfd.completed_synchronously = true;
- wfd.overlapped->InternalHigh = size - 1;
+ wfd.overlapped->InternalHigh = size;
}
transfer_priv->pollable_fd = wfd;
diff --git a/libusb/os/windows_usb.h b/libusb/os/windows_usb.h
index b11b318..e5c5c79 100644
--- a/libusb/os/windows_usb.h
+++ b/libusb/os/windows_usb.h
@@ -1,7 +1,9 @@
/*
* Windows backend for libusb 1.0
- * Copyright (C) 2009 Pete Batard <pbatard@gmail.com>
+ * Copyright (C) 2009-2010 Pete Batard <pbatard@gmail.com>
+ * With contributions from Michael Plante, Orin Eman et al.
* Parts of this code adapted from libusb-win32-v1 by Stephan Meyer
+ * Major code testing contribution by Xiaofan Chen
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
diff --git a/libusb/sync.c b/libusb/sync.c
index 6e65bce..51db50d 100644
--- a/libusb/sync.c
+++ b/libusb/sync.c
@@ -17,13 +17,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifdef _MSC_VER
-#include <config_msvc.h>
-#else
#include <config.h>
-#endif
#include <errno.h>
-#include <stdint.h>
#include <stdlib.h>
#include <string.h>
diff --git a/libusb_dll.dsp b/libusb_dll.dsp
index 83c2de8..31dbeb7 100644
--- a/libusb_dll.dsp
+++ b/libusb_dll.dsp
@@ -43,7 +43,7 @@ RSC=rc.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBUSB_DLL_EXPORTS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "msvc" /I "libusb" /I "." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /FR /FD /EHsc /c
+# ADD CPP /nologo /MD /W3 /GX /O2 /I "msvc" /I "libusb" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /FR /FD /EHsc /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG"
@@ -53,7 +53,7 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
-# ADD LINK32 pthreadVC2.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib "D:/Program Files/Microsoft SDK/Lib/setupapi.lib" /nologo /dll /machine:I386 /out:"Win32/Release/dll/libusb-1.0.dll"
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib "D:/Program Files/Microsoft SDK/Lib/setupapi.lib" /nologo /dll /machine:I386 /out:"Win32/Release/dll/libusb-1.0.dll"
!ELSEIF "$(CFG)" == "libusb_dll - Win32 Debug"
@@ -69,7 +69,7 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBUSB_DLL_EXPORTS" /YX /FD /GZ /c
-# ADD CPP /nologo /Gz /MDd /W3 /Gm /GX /ZI /Od /I "msvc" /I "libusb" /I "." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /FR /FD /EHsc /c
+# ADD CPP /nologo /Gz /MDd /W3 /Gm /GX /ZI /Od /I "msvc" /I "libusb" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /FR /FD /EHsc /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "_DEBUG"
@@ -79,7 +79,7 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo /n
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 pthreadVC2d.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib "D:/Program Files/Microsoft SDK/Lib/setupapi.lib" /nologo /dll /debug /machine:I386 /out:"Win32/Debug/dll/libusb-1.0_debug.dll"
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib "D:/Program Files/Microsoft SDK/Lib/setupapi.lib" /nologo /dll /debug /machine:I386 /out:"Win32/Debug/dll/libusb-1.0_debug.dll"
# SUBTRACT LINK32 /pdb:none /incremental:no
!ENDIF
@@ -127,6 +127,10 @@ SOURCE=.\libusb\sync.c
# End Source File
# Begin Source File
+SOURCE=.\libusb\os\threads_windows.c
+# End Source File
+# Begin Source File
+
SOURCE=.\libusb\os\windows_compat.c
# End Source File
# Begin Source File
@@ -139,7 +143,7 @@ SOURCE=.\libusb\os\windows_usb.c
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
-SOURCE=.\config_msvc.h
+SOURCE=.\msvc\config.h
# End Source File
# Begin Source File
@@ -163,6 +167,14 @@ SOURCE=.\msvc\resource.h
# End Source File
# Begin Source File
+SOURCE=.\libusb\os\threads_posix.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\libusb\os\threads_windows.h
+# End Source File
+# Begin Source File
+
SOURCE=.\libusb\os\windows_compat.h
# End Source File
# Begin Source File
diff --git a/libusb_static.dsp b/libusb_static.dsp
index 9b0c674..eb12cd1 100644
--- a/libusb_static.dsp
+++ b/libusb_static.dsp
@@ -41,7 +41,7 @@ RSC=rc.exe
# PROP Intermediate_Dir "Win32/Release/lib"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "msvc" /I "libusb" /I "." /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /FR /FD /EHsc /c
+# ADD CPP /nologo /MD /W3 /GX /O2 /I "msvc" /I "libusb" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /FR /FD /EHsc /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
@@ -64,7 +64,7 @@ LIB32=link.exe -lib
# PROP Intermediate_Dir "Win32/Debug/lib"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
-# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "msvc" /I "libusb" /I "." /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /FR /FD /GZ /EHsc /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "msvc" /I "libusb" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /FR /FD /GZ /EHsc /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
@@ -111,6 +111,10 @@ SOURCE=.\libusb\sync.c
# End Source File
# Begin Source File
+SOURCE=.\libusb\os\threads_windows.c
+# End Source File
+# Begin Source File
+
SOURCE=.\libusb\os\windows_compat.c
# End Source File
# Begin Source File
@@ -123,7 +127,7 @@ SOURCE=.\libusb\os\windows_usb.c
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
-SOURCE=.\config_msvc.h
+SOURCE=.\msvc\config.h
# End Source File
# Begin Source File
@@ -143,6 +147,14 @@ SOURCE=.\libusb\os\linux_usbfs.h
# End Source File
# Begin Source File
+SOURCE=.\libusb\os\threads_posix.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\libusb\os\threads_windows.h
+# End Source File
+# Begin Source File
+
SOURCE=.\libusb\os\windows_compat.h
# End Source File
# Begin Source File
diff --git a/msvc/config.h b/msvc/config.h
new file mode 100644
index 0000000..27cfe6c
--- /dev/null
+++ b/msvc/config.h
@@ -0,0 +1,22 @@
+/* config.h. Manual config for MSVC. */
+
+/* Default visibility */
+#define API_EXPORTED /**/
+
+/* Debug message logging */
+#define ENABLE_DEBUG_LOGGING 1
+
+/* Message logging */
+#define ENABLE_LOGGING 1
+
+/* Windows backend */
+#define OS_WINDOWS /**/
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Backend handles timeout */
+/* #undef USBI_OS_HANDLES_TIMEOUT */
+
+/* timerfd headers available */
+/* #undef USBI_TIMERFD_AVAILABLE */
diff --git a/msvc/pthread-win32_x64/pthread-win32.sln b/msvc/pthread-win32_x64/pthread-win32.sln
deleted file mode 100644
index 843252f..0000000
--- a/msvc/pthread-win32_x64/pthread-win32.sln
+++ /dev/null
@@ -1,25 +0,0 @@
-Microsoft Visual Studio Solution File, Format Version 9.00
-# Visual Studio 2005
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pthread-win32", "pthread-win32.vcproj", "{E97509CF-6701-4526-8FCC-CC290C52E785}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Win32 = Debug|Win32
- Debug|x64 = Debug|x64
- Release|Win32 = Release|Win32
- Release|x64 = Release|x64
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {E97509CF-6701-4526-8FCC-CC290C52E785}.Debug|Win32.ActiveCfg = Debug|Win32
- {E97509CF-6701-4526-8FCC-CC290C52E785}.Debug|Win32.Build.0 = Debug|Win32
- {E97509CF-6701-4526-8FCC-CC290C52E785}.Debug|x64.ActiveCfg = Debug|x64
- {E97509CF-6701-4526-8FCC-CC290C52E785}.Debug|x64.Build.0 = Debug|x64
- {E97509CF-6701-4526-8FCC-CC290C52E785}.Release|Win32.ActiveCfg = Release|Win32
- {E97509CF-6701-4526-8FCC-CC290C52E785}.Release|Win32.Build.0 = Release|Win32
- {E97509CF-6701-4526-8FCC-CC290C52E785}.Release|x64.ActiveCfg = Release|x64
- {E97509CF-6701-4526-8FCC-CC290C52E785}.Release|x64.Build.0 = Release|x64
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
-EndGlobal
diff --git a/msvc/pthread-win32_x64/pthread-win32.vcproj b/msvc/pthread-win32_x64/pthread-win32.vcproj
deleted file mode 100644
index b0be80d..0000000
--- a/msvc/pthread-win32_x64/pthread-win32.vcproj
+++ /dev/null
@@ -1,409 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="9.00"
- Name="pthreadVC2"
- ProjectGUID="{E97509CF-6701-4526-8FCC-CC290C52E785}"
- RootNamespace="pthreadwin32"
- Keyword="Win32Proj"
- TargetFrameworkVersion="196613"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- <Platform
- Name="x64"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
- IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
- ConfigurationType="2"
- CharacterSet="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="."
- PreprocessorDefinitions="PTW32_BUILD"
- MinimalRebuild="true"
- BasicRuntimeChecks="3"
- RuntimeLibrary="3"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- DebugInformationFormat="4"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_UNICODE;UNICODE;PTW32_RC_MSC"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="ws2_32.lib&#x0A;"
- LinkIncremental="2"
- GenerateDebugInformation="true"
- SubSystem="1"
- TargetMachine="1"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Debug|x64"
- OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
- IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
- ConfigurationType="2"
- CharacterSet="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- TargetEnvironment="3"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="."
- PreprocessorDefinitions="PTW32_BUILD"
- MinimalRebuild="true"
- BasicRuntimeChecks="3"
- RuntimeLibrary="3"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- DebugInformationFormat="3"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_UNICODE;UNICODE;PTW32_RC_MSC"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="ws2_32.lib&#x0A;"
- OutputFile="$(OutDir)\$(ProjectName)_$(PlatformName).dll"
- LinkIncremental="2"
- GenerateDebugInformation="true"
- SubSystem="1"
- TargetMachine="17"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release|Win32"
- OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
- IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
- ConfigurationType="2"
- CharacterSet="1"
- WholeProgramOptimization="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- EnableIntrinsicFunctions="true"
- AdditionalIncludeDirectories="."
- PreprocessorDefinitions="PTW32_BUILD"
- RuntimeLibrary="2"
- EnableFunctionLevelLinking="true"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- DebugInformationFormat="3"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_UNICODE;UNICODE;PTW32_RC_MSC"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="ws2_32.lib&#x0A;"
- LinkIncremental="1"
- GenerateDebugInformation="true"
- SubSystem="1"
- OptimizeReferences="2"
- EnableCOMDATFolding="2"
- TargetMachine="1"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release|x64"
- OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
- IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
- ConfigurationType="2"
- CharacterSet="1"
- WholeProgramOptimization="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- TargetEnvironment="3"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- EnableIntrinsicFunctions="true"
- AdditionalIncludeDirectories="."
- PreprocessorDefinitions="PTW32_BUILD"
- RuntimeLibrary="2"
- EnableFunctionLevelLinking="true"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- DebugInformationFormat="3"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_UNICODE;UNICODE;PTW32_RC_MSC"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="ws2_32.lib&#x0A;"
- OutputFile="$(OutDir)\$(ProjectName)_$(PlatformName).dll"
- LinkIncremental="1"
- GenerateDebugInformation="true"
- SubSystem="1"
- OptimizeReferences="2"
- EnableCOMDATFolding="2"
- TargetMachine="17"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <Filter
- Name="Source Files"
- Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
- UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
- >
- <File
- RelativePath=".\pthread.c"
- >
- </File>
- </Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
- >
- <File
- RelativePath=".\implement.h"
- >
- </File>
- <File
- RelativePath=".\pthread.h"
- >
- </File>
- <File
- RelativePath=".\sched.h"
- >
- </File>
- <File
- RelativePath=".\semaphore.h"
- >
- </File>
- </Filter>
- <Filter
- Name="Resource Files"
- Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
- UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
- >
- <File
- RelativePath=".\version.rc"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_UNICODE;UNICODE;PTW32_RC_MSC"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug|x64"
- >
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_UNICODE;UNICODE;PTW32_RC_MSC"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32"
- >
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_UNICODE;UNICODE;PTW32_RC_MSC"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|x64"
- >
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_UNICODE;UNICODE;PTW32_RC_MSC"
- />
- </FileConfiguration>
- </File>
- </Filter>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>