summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPete Batard <pbatard@gmail.com>2010-10-28 11:43:29 +0100
committerPete Batard <pbatard@gmail.com>2010-10-28 11:43:29 +0100
commitf673769618fc70d2c582e06be8976932818ef39f (patch)
tree73b1e8f78430e1fdf0c5bda0cb033d49024e3bb9
parent1b538f0e2bd84f500e02a9abdf7d0489fc1b5c0e (diff)
downloadlibusb-f673769618fc70d2c582e06be8976932818ef39f.tar.gz
merge -> pbr319, part 2
-rw-r--r--INSTALL_WIN.txt13
-rw-r--r--_README.txt61
-rw-r--r--_bd.cmd (renamed from bd.cmd)7
-rw-r--r--_bm.sh (renamed from bm.sh)88
-rw-r--r--_bump.sh (renamed from bump.sh)72
-rw-r--r--_libusb_2008.sln (renamed from libusb_2008.sln)8
-rw-r--r--_libusb_dll_2008.vcproj (renamed from libusb_dll_2008.vcproj)0
-rw-r--r--_libusb_static_2008.vcproj (renamed from libusb_static_2008.vcproj)0
-rw-r--r--ddk_build.cmd23
-rw-r--r--examples/_lsusb_2008.vcproj (renamed from examples/lsusb_2008.vcproj)0
-rw-r--r--examples/_xusb_2008.vcproj (renamed from examples/xusb_2008.vcproj)0
-rw-r--r--examples/lsusb_sources5
-rw-r--r--examples/xusb_sources5
-rw-r--r--libusb/os/libusb_sources21
-rw-r--r--libusb/os/windows_usb.c79
-rw-r--r--libusb/os/windows_usb.h3
16 files changed, 234 insertions, 151 deletions
diff --git a/INSTALL_WIN.txt b/INSTALL_WIN.txt
index f56b6c2..778f891 100644
--- a/INSTALL_WIN.txt
+++ b/INSTALL_WIN.txt
@@ -5,8 +5,8 @@ If you are compiling for MinGW or cygwin, please refer to the INSTALL file.
If you are using Microsoft Visual Studio:
- Open the relevant solution file libusb.dsw for MSVC6, libusb.sln for Visual
- Studio 2005 or later (you will go through a short conversion process if using
- 2008)
+ Studio 2005 or later (you will go through a conversion process if using 2008
+ or later)
- If you want to debug the library, uncomment the ENABLE_DEBUG_LOGGING define
in config.h
- Select your configuration and compile the project
@@ -22,6 +22,8 @@ If you are using the freely available Windows DDK/WDK (Driver Development Kit)
- Navigate to the root directory of the distribution, where the ddk_build.cmd
file is located, and run 'ddk_build'
- To produce a DLL rather than a static library, use: 'ddk_build DLL'
+- To produce a static library that uses LIBCMT[d] instead of MSVCRT[d] (/MT[d]
+ vs /MD[d] in Visual Studio) use: 'ddk_build /MT'
Note that using the Windows DDK, it is possible to compile both the 32 and 64
bit versions of the library.
@@ -40,15 +42,10 @@ Troubleshooting
If the compilation process complains about missing libraries, you need to ensure
that the default library paths for your project point to a directory that
-contains setupapi.lib and ole32.lib.
+contains the necessary libraries.
If needed, these libraries can be obtained by installing either the latest
Windows SDK or the DDK (Links provided at the end of this file).
-The 64 bit version of the library has been tested at least as much as the 32 bit
-version during development. Same goes for Windows 7 vs Vista/XP.
-Therefore we do not expect specific issues related to using these targets with
-libusb.
-
Links
*****
diff --git a/_README.txt b/_README.txt
new file mode 100644
index 0000000..2420227
--- /dev/null
+++ b/_README.txt
@@ -0,0 +1,61 @@
+ libusb 1.0 Windows binary snapshot - README
+
+ *********************************************************************
+ * The latest version of this snapshot can always be downloaded at: *
+ * http://libusb.org/wiki/windows_backend#LatestBinarySnapshots *
+ *********************************************************************
+
+o Visual Studio:
+ - Open existing or create a new project for your application
+ - Copy the libusb.h and stdint.h files into your project and make sure that
+ the location where these files reside appears in the 'Additional Include
+ Directories' section (Configuration Properties -> C/C++ -> General)
+ - Copy the relevant .lib file from MS32\ or MS64\ and add 'libusb-1.0.lib' to
+ your 'Additional Dependencies' (Configuration Properties -> Linker -> Input)
+ Also make sure that the directory where libusb-1.0.lib resides is added to
+ 'Additional Library Directories' (Configuration Properties -> Linker
+ -> General)
+ - If you use the static version of the libusb-1.0 library, make sure that
+ 'Runtime Library' is set to 'Multi-threaded DLL (/MD)' (Configuration
+ Properties -> C/C++ -> Code Generation).
+ NB: If your application requires /MT (Multi-threaded/libCMT), you need to
+ recompile a static libusb 1.0 library from source.
+ - Compile and run your application. If you use the DLL version of libusb-1.0,
+ remember that you need to have a copy of the DLL either in the runtime
+ directory or in system32
+
+o WDK/DDK:
+ - The following is an example of a sources files that you can use to compile
+ a libusb 1.0 based console application. In this sample ..\libusb\ is the
+ directory where you would have copied libusb.h, stdint.h as well as the
+ relevant libusb-1.0.lib
+
+ TARGETNAME=your_app
+ TARGETTYPE=PROGRAM
+ USE_MSVCRT=1
+ UMTYPE=console
+ INCLUDES=..\libusb;$(DDK_INC_PATH)
+ TARGETLIBS=..\libusb\libusb-1.0.lib
+ SOURCES=your_app.c
+
+ - Note that if you plan to use libCMT instead of MSVCRT (USE_LIBCMT=1 instead
+ of USE_MSVCRT=1), you will need to recompile libusb to use libCMT. This can
+ easily be achieved, in the DDK environment, by running 'ddk_build /MT'
+
+o MinGW/cygwin
+ - Copy libusb.h to your default include directory and the relevant MinGW32\ or
+ MinGW64\ .a file to your default library directory. Or, if you don't want to
+ use the default locations, make sure that you feed the relevant -I and -L
+ options to the compiler.
+ - Add the '-lusb-1.0' linker option when compiling.
+
+o Additional information:
+ - The libusb 1.0 API documentation can be accessed at:
+ http://libusb.sourceforge.net/api-1.0/modules.html
+ - For some libusb samples (including source), please have a look in examples/
+ - For additional information on the libusb 1.0 Windows backend please visit:
+ http://libusb.org/wiki/windows_backend
+ - The MinGW and MS generated DLLs are fully interchangeable, provided that you
+ use the import libs provided or generate one from the .def also provided.
+ - If you find any issue, please visit http://libusb.org/ and follow the
+ instructions from the 'Support' & 'Bug and feature Requests'
diff --git a/bd.cmd b/_bd.cmd
index 134f253..a678917 100644
--- a/bd.cmd
+++ b/_bd.cmd
@@ -7,8 +7,11 @@ for %%A in (MS32 MS64) do mkdir E:\dailies\%DATE%\%%A\static
for %%A in (MS32 MS64) do mkdir E:\dailies\%DATE%\%%A\dll
for %%A in (source bin32 bin64) do mkdir E:\dailies\%DATE%\examples\%%A
copy libusb\libusb.h E:\dailies\%DATE%\
+copy msvc\stdint.h E:\dailies\%DATE%\
copy libusb\libusb-1.0.def E:\dailies\%DATE%\
-copy examples\*.c E:\dailies\%DATE%\examples\source
+copy examples\lsusb.c E:\dailies\%DATE%\examples\source
+copy examples\xusb.c E:\dailies\%DATE%\examples\source
+copy _README.txt E:\dailies\%DATE%\README.txt
set ORG_BUILD_ALT_DIR=%BUILD_ALT_DIR%
set ORG_BUILDARCH=%_BUILDARCH%
@@ -65,4 +68,4 @@ goto done
:usage
echo must be run in a WXP build environment!
-:done \ No newline at end of file
+:done
diff --git a/bm.sh b/_bm.sh
index 164260c..a2bf653 100644
--- a/bm.sh
+++ b/_bm.sh
@@ -1,44 +1,44 @@
-#!/bin/sh
-date=`date +%Y.%m.%d`
-
-#
-# 32 bit binaries
-#
-target=e:/dailies/$date/MinGW32
-git clean -f -d -x
-# Not using debug (-g) in CFLAGS DRAMATICALLY reduces the size of the binaries
-export CFLAGS="-O2 -m32"
-export LDFLAGS="-m32"
-export RCFLAGS="--target=pe-i386"
-export DLLTOOLFLAGS="-m i386 -f --32"
-echo `pwd`
-(glibtoolize --version) < /dev/null > /dev/null 2>&1 && LIBTOOLIZE=glibtoolize || LIBTOOLIZE=libtoolize
-$LIBTOOLIZE --copy --force || exit 1
-aclocal || exit 1
-autoheader || exit 1
-autoconf || exit 1
-automake -a -c || exit 1
-./configure --enable-toggable-debug
-make
-mkdir -p $target/static
-mkdir -p $target/dll
-cp -v libusb/.libs/libusb-1.0.a $target/static
-cp -v libusb/.libs/libusb-1.0.dll $target/dll
-cp -v libusb/.libs/libusb-1.0.dll.a $target/dll
-make clean
-
-#
-# 64 bit binaries
-#
-target=e:/dailies/$date/MinGW64
-export CFLAGS="-O2"
-export LDFLAGS=""
-export RCFLAGS=""
-export DLLTOOLFLAGS=""
-./configure --enable-toggable-debug
-make
-mkdir -p $target/static
-mkdir -p $target/dll
-cp -v libusb/.libs/libusb-1.0.a $target/static
-cp -v libusb/.libs/libusb-1.0.dll $target/dll
-cp -v libusb/.libs/libusb-1.0.dll.a $target/dll \ No newline at end of file
+#!/bin/sh
+date=`date +%Y.%m.%d`
+
+#
+# 32 bit binaries
+#
+target=e:/dailies/$date/MinGW32
+git clean -f -d -x
+# Not using debug (-g) in CFLAGS DRAMATICALLY reduces the size of the binaries
+export CFLAGS="-O2 -m32"
+export LDFLAGS="-m32"
+export RCFLAGS="--target=pe-i386"
+export DLLTOOLFLAGS="-m i386 -f --32"
+echo `pwd`
+(glibtoolize --version) < /dev/null > /dev/null 2>&1 && LIBTOOLIZE=glibtoolize || LIBTOOLIZE=libtoolize
+$LIBTOOLIZE --copy --force || exit 1
+aclocal || exit 1
+autoheader || exit 1
+autoconf || exit 1
+automake -a -c || exit 1
+./configure --enable-toggable-debug
+make
+mkdir -p $target/static
+mkdir -p $target/dll
+cp -v libusb/.libs/libusb-1.0.a $target/static
+cp -v libusb/.libs/libusb-1.0.dll $target/dll
+cp -v libusb/.libs/libusb-1.0.dll.a $target/dll
+make clean
+
+#
+# 64 bit binaries
+#
+target=e:/dailies/$date/MinGW64
+export CFLAGS="-O2"
+export LDFLAGS=""
+export RCFLAGS=""
+export DLLTOOLFLAGS=""
+./configure --enable-toggable-debug
+make
+mkdir -p $target/static
+mkdir -p $target/dll
+cp -v libusb/.libs/libusb-1.0.a $target/static
+cp -v libusb/.libs/libusb-1.0.dll $target/dll
+cp -v libusb/.libs/libusb-1.0.dll.a $target/dll
diff --git a/bump.sh b/_bump.sh
index 913512c..db16390 100644
--- a/bump.sh
+++ b/_bump.sh
@@ -1,36 +1,36 @@
-#!/bin/sh
-# bump the version and update the git tree accordingly
-# !!!THIS SCRIPT IS FOR INTERNAL DEVELOPER USE ONLY!!!
-
-type -P sed &>/dev/null || { echo "sed command not found. Aborting." >&2; exit 1; }
-type -P git &>/dev/null || { echo "git command not found. Aborting." >&2; exit 1; }
-
-if [ ! -n "$1" ]; then
- TAG=$(git describe --tags --abbrev=0 2>/dev/null)
- if [ ! -n "$TAG" ]; then
- echo Unable to read tag - aborting.
- exit 1
- fi
-else
- TAG=$1
-fi
-if [ ! ${TAG:0:3} = 'pbh' ]; then
- echo Tag "$TAG" does not start with 'pbh' - aborting
- exit 1
-fi
-TAGVER=${TAG:3}
-case $TAGVER in *[!0-9]*)
- echo "$TAGVER is not a number"
- exit 1
-esac
-OFFSET=9000
-TAGVER=`expr $TAGVER + 1`
-TAGVER_OFF=`expr $TAGVER + $OFFSET`
-echo "Bumping version to pbh$TAGVER (nano: $TAGVER_OFF)"
-sed -e "s/\(^m4_define(LIBUSB_NANO.*\)/m4_define(LIBUSB_NANO, [$TAGVER_OFF])/" configure.ac >> configure.ac~
-mv configure.ac~ configure.ac
-# we're duplicating libusb_version.h generation here, but that avoids having to run configure
-sed -e "s/\(^#define LIBUSB_VERSION_NANO.*\)/#define LIBUSB_VERSION_NANO $TAGVER_OFF/" libusb/libusb_version.h > libusb/libusb_version.h~
-mv libusb/libusb_version.h~ libusb/libusb_version.h
-git commit -a -m "bumped internal version" -e
-git tag "pbh$TAGVER" \ No newline at end of file
+#!/bin/sh
+# bump the version and update the git tree accordingly
+# !!!THIS SCRIPT IS FOR INTERNAL DEVELOPER USE ONLY!!!
+
+type -P sed &>/dev/null || { echo "sed command not found. Aborting." >&2; exit 1; }
+type -P git &>/dev/null || { echo "git command not found. Aborting." >&2; exit 1; }
+
+if [ ! -n "$1" ]; then
+ TAG=$(git describe --tags --abbrev=0 2>/dev/null)
+ if [ ! -n "$TAG" ]; then
+ echo Unable to read tag - aborting.
+ exit 1
+ fi
+else
+ TAG=$1
+fi
+if [ ! ${TAG:0:3} = 'pbh' ]; then
+ echo Tag "$TAG" does not start with 'pbh' - aborting
+ exit 1
+fi
+TAGVER=${TAG:3}
+case $TAGVER in *[!0-9]*)
+ echo "$TAGVER is not a number"
+ exit 1
+esac
+OFFSET=9000
+TAGVER=`expr $TAGVER + 1`
+TAGVER_OFF=`expr $TAGVER + $OFFSET`
+echo "Bumping version to pbh$TAGVER (nano: $TAGVER_OFF)"
+sed -e "s/\(^m4_define(LIBUSB_NANO.*\)/m4_define(LIBUSB_NANO, [$TAGVER_OFF])/" configure.ac >> configure.ac~
+mv configure.ac~ configure.ac
+# we're duplicating libusb_version.h generation here, but that avoids having to run configure
+sed -e "s/\(^#define LIBUSB_VERSION_NANO.*\)/#define LIBUSB_VERSION_NANO $TAGVER_OFF/" libusb/libusb_version.h > libusb/libusb_version.h~
+mv libusb/libusb_version.h~ libusb/libusb_version.h
+git commit -a -m "bumped internal version" -e
+git tag "pbh$TAGVER"
diff --git a/libusb_2008.sln b/_libusb_2008.sln
index 2057702..c1b44c7 100644
--- a/libusb_2008.sln
+++ b/_libusb_2008.sln
@@ -1,15 +1,15 @@
Microsoft Visual Studio Solution File, Format Version 10.00
# Visual Studio 2008
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libusb-1.0 (static)", "libusb_static_2008.vcproj", "{349EE8F9-7D25-4909-AAF5-FF3FADE72187}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libusb-1.0 (static)", "_libusb_static_2008.vcproj", "{349EE8F9-7D25-4909-AAF5-FF3FADE72187}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libusb-1.0 (dll)", "libusb_dll_2008.vcproj", "{349EE8FA-7D25-4909-AAF5-FF3FADE72187}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libusb-1.0 (dll)", "_libusb_dll_2008.vcproj", "{349EE8FA-7D25-4909-AAF5-FF3FADE72187}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lsusb", "examples\lsusb_2008.vcproj", "{F4938DB0-3DE7-4737-9C5A-EAD1BE819F87}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lsusb", "examples\_lsusb_2008.vcproj", "{F4938DB0-3DE7-4737-9C5A-EAD1BE819F87}"
ProjectSection(ProjectDependencies) = postProject
{349EE8F9-7D25-4909-AAF5-FF3FADE72187} = {349EE8F9-7D25-4909-AAF5-FF3FADE72187}
EndProjectSection
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xusb", "examples\xusb_2008.vcproj", "{3F3138D0-7AB7-4268-9BF3-1A3EA5503A11}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xusb", "examples\_xusb_2008.vcproj", "{3F3138D0-7AB7-4268-9BF3-1A3EA5503A11}"
ProjectSection(ProjectDependencies) = postProject
{349EE8F9-7D25-4909-AAF5-FF3FADE72187} = {349EE8F9-7D25-4909-AAF5-FF3FADE72187}
EndProjectSection
diff --git a/libusb_dll_2008.vcproj b/_libusb_dll_2008.vcproj
index 3512b98..3512b98 100644
--- a/libusb_dll_2008.vcproj
+++ b/_libusb_dll_2008.vcproj
diff --git a/libusb_static_2008.vcproj b/_libusb_static_2008.vcproj
index 8541676..8541676 100644
--- a/libusb_static_2008.vcproj
+++ b/_libusb_static_2008.vcproj
diff --git a/ddk_build.cmd b/ddk_build.cmd
index 88d3c25..0444187 100644
--- a/ddk_build.cmd
+++ b/ddk_build.cmd
@@ -1,20 +1,23 @@
+@rem default builds static library.
+@rem you can pass the following arguments (case insensitive):
+@rem - "DLL" to build a DLL instead of a static library
+@rem - "/MT" to build a static library compatible with MSVC's /MT option (LIBCMT vs MSVCRT)
@echo off
-rem default builds static library. Pass argument 'DLL' to build a DLL
-
if Test%BUILD_ALT_DIR%==Test goto usage
+rem process commandline parameters
+set TARGET=LIBRARY
+set STATIC_LIBC=
set version=1.0
+if "%1" == "" goto no_more_args
+rem /I for case insensitive
+if /I Test%1==TestDLL set TARGET=DYNLINK
+if /I Test%1==Test/MT set STATIC_LIBC=1
+:no_more_args
+
cd libusb\os
-rem DLL or static lib selection (must use concatenation)
-if Test%1==TestDLL goto libusb_dll
-:libusb_static
-set TARGET=LIBRARY
-goto libusb_common
-:libusb_dll
-set TARGET=DYNLINK
-:libusb_common
echo TARGETTYPE=%TARGET% > target
copy target+libusb_sources sources >NUL 2>&1
del target
diff --git a/examples/lsusb_2008.vcproj b/examples/_lsusb_2008.vcproj
index 70de59d..70de59d 100644
--- a/examples/lsusb_2008.vcproj
+++ b/examples/_lsusb_2008.vcproj
diff --git a/examples/xusb_2008.vcproj b/examples/_xusb_2008.vcproj
index 71dcf44..71dcf44 100644
--- a/examples/xusb_2008.vcproj
+++ b/examples/_xusb_2008.vcproj
diff --git a/examples/lsusb_sources b/examples/lsusb_sources
index 8600180..ed7fe74 100644
--- a/examples/lsusb_sources
+++ b/examples/lsusb_sources
@@ -7,7 +7,12 @@ _NT_TARGET_VERSION= $(_NT_TARGET_VERSION_WINXP)
MSC_WARNING_LEVEL=/W3
!ENDIF
+!IFDEF STATIC_LIBC
+USE_LIBCMT=1
+!ELSE
USE_MSVCRT=1
+!ENDIF
+
UMTYPE=console
INCLUDES=..\..\msvc;..\..;$(DDK_INC_PATH)
UMLIBS=..\..\libusb\os\obj$(BUILD_ALT_DIR)\*\libusb-1.0.lib
diff --git a/examples/xusb_sources b/examples/xusb_sources
index f7bd1a0..ea1b8f4 100644
--- a/examples/xusb_sources
+++ b/examples/xusb_sources
@@ -8,7 +8,12 @@ _NT_TARGET_VERSION= $(_NT_TARGET_VERSION_WINXP)
MSC_WARNING_LEVEL=/W3
!ENDIF
+!IFDEF STATIC_LIBC
+USE_LIBCMT=1
+!ELSE
USE_MSVCRT=1
+!ENDIF
+
UMTYPE=console
INCLUDES=..\..\msvc;..\..;$(DDK_INC_PATH)
UMLIBS=..\..\libusb\os\obj$(BUILD_ALT_DIR)\*\libusb-1.0.lib
diff --git a/libusb/os/libusb_sources b/libusb/os/libusb_sources
index 3e5b661..0f38ddb 100644
--- a/libusb/os/libusb_sources
+++ b/libusb/os/libusb_sources
@@ -6,16 +6,25 @@ DLLDEF=..\libusb-1.0.def
MSC_WARNING_LEVEL=/W3
!ENDIF
+!IFDEF STATIC_LIBC
+USE_LIBCMT=1
+!ELSE
USE_MSVCRT=1
+!ENDIF
INCLUDES=..;..\..\msvc;$(DDK_INC_PATH)
-C_DEFINES = $(C_DEFINES) $(LIBUSB_DEFINES) /DDDKBUILD
+C_DEFINES= $(C_DEFINES) $(LIBUSB_DEFINES) /DDDKBUILD
+
+# http://jpassing.com/2009/10/21/ltcg-issues-with-the-win7amd64-environment-of-wdk-7600/
+# prevents the following error when using the 64 bit static lib with Visual Studio 2010:
+# "fatal error C1001: An internal error has occurred in the compiler.
+# (compiler file 'f:\dd\vctools\compiler\utc\src\p2\p2symtab.c', line 1823)"
+# and the following with Visual Studio 2010:
+# "fatal error C1047: The object or library file 'libusb-1.0.lib' was created with
+# an older compiler than other objects; rebuild old objects and libraries"
+USER_C_FLAGS=/GL-
-TARGETLIBS=$(SDK_LIB_PATH)\kernel32.lib \
- $(SDK_LIB_PATH)\user32.lib \
- $(SDK_LIB_PATH)\advapi32.lib \
- $(SDK_LIB_PATH)\setupapi.lib \
- $(SDK_LIB_PATH)\ole32.lib
+TARGETLIBS=$(SDK_LIB_PATH)\kernel32.lib
SOURCES=..\core.c \
..\descriptor.c \
diff --git a/libusb/os/windows_usb.c b/libusb/os/windows_usb.c
index 0093bb8..6f53558 100644
--- a/libusb/os/windows_usb.c
+++ b/libusb/os/windows_usb.c
@@ -276,6 +276,8 @@ static int init_dlls(void)
DLL_LOAD_PREFIXED(SetupAPI.dll, p, SetupDiDestroyDeviceInfoList, TRUE);
DLL_LOAD_PREFIXED(SetupAPI.dll, p, SetupDiOpenDevRegKey, TRUE);
DLL_LOAD_PREFIXED(SetupAPI.dll, p, SetupDiGetDeviceRegistryPropertyA, TRUE);
+ DLL_LOAD_PREFIXED(AdvAPI32.dll, p, RegQueryValueExW, TRUE);
+ DLL_LOAD_PREFIXED(AdvAPI32.dll, p, RegCloseKey, TRUE);
return LIBUSB_SUCCESS;
}
@@ -920,7 +922,7 @@ static int force_hcd_device_descriptor(struct libusb_device *dev)
/*
* fetch and cache all the config descriptors through I/O
*/
-static int cache_config_descriptors(struct libusb_device *dev, HANDLE hub_handle)
+static int cache_config_descriptors(struct libusb_device *dev, HANDLE hub_handle, char* device_id)
{
DWORD size, ret_size;
struct libusb_context *ctx = DEVICE_CTX(dev);
@@ -963,18 +965,18 @@ static int cache_config_descriptors(struct libusb_device *dev, HANDLE hub_handle
// Dummy call to get the required data size
if (!DeviceIoControl(hub_handle, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, &cd_buf_short, size,
&cd_buf_short, size, &ret_size, NULL)) {
- usbi_err(ctx, "could not access configuration descriptor (dummy): %s", windows_error_str(0));
+ usbi_err(ctx, "could not access configuration descriptor (dummy) for '%s': %s", device_id, windows_error_str(0));
LOOP_BREAK(LIBUSB_ERROR_IO);
}
if ((ret_size != size) || (cd_buf_short.data.wTotalLength < sizeof(USB_CONFIGURATION_DESCRIPTOR))) {
- usbi_err(ctx, "unexpected configuration descriptor size (dummy).");
+ usbi_err(ctx, "unexpected configuration descriptor size (dummy) for '%s'.", device_id);
LOOP_BREAK(LIBUSB_ERROR_IO);
}
size = sizeof(USB_DESCRIPTOR_REQUEST) + cd_buf_short.data.wTotalLength;
if ((cd_buf_actual = (PUSB_DESCRIPTOR_REQUEST)malloc(size)) == NULL) {
- usbi_err(ctx, "could not allocate configuration descriptor buffer. aborting.");
+ usbi_err(ctx, "could not allocate configuration descriptor buffer for '%s'.", device_id);
LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
}
memset(cd_buf_actual, 0, size);
@@ -989,19 +991,19 @@ static int cache_config_descriptors(struct libusb_device *dev, HANDLE hub_handle
if (!DeviceIoControl(hub_handle, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, cd_buf_actual, size,
cd_buf_actual, size, &ret_size, NULL)) {
- usbi_err(ctx, "could not access configuration descriptor (actual): %s", windows_error_str(0));
+ usbi_err(ctx, "could not access configuration descriptor (actual) for '%s': %s", device_id, windows_error_str(0));
LOOP_BREAK(LIBUSB_ERROR_IO);
}
cd_data = (PUSB_CONFIGURATION_DESCRIPTOR)((UCHAR*)cd_buf_actual+sizeof(USB_DESCRIPTOR_REQUEST));
if ((size != ret_size) || (cd_data->wTotalLength != cd_buf_short.data.wTotalLength)) {
- usbi_err(ctx, "unexpected configuration descriptor size (actual).");
+ usbi_err(ctx, "unexpected configuration descriptor size (actual) for '%s'.", device_id);
LOOP_BREAK(LIBUSB_ERROR_IO);
}
if (cd_data->bDescriptorType != USB_CONFIGURATION_DESCRIPTOR_TYPE) {
- usbi_err(ctx, "not a configuration descriptor");
+ usbi_err(ctx, "not a configuration descriptor for '%s'", device_id);
LOOP_BREAK(LIBUSB_ERROR_IO);
}
@@ -1062,7 +1064,7 @@ static int init_device(struct libusb_device* dev, struct libusb_device* parent_d
return LIBUSB_ERROR_IO;
}
if (conn_info.ConnectionStatus == NoDeviceConnected) {
- usbi_err(ctx, "program assertion failed - no device connected");
+ usbi_err(ctx, "device '%s' is no longer connected!", device_id);
safe_closehandle(handle);
return LIBUSB_ERROR_NO_DEVICE;
}
@@ -1072,7 +1074,7 @@ static int init_device(struct libusb_device* dev, struct libusb_device* parent_d
priv->active_config = conn_info.CurrentConfigurationValue;
usbi_dbg("found %d configurations (active conf: %d)", dev->num_configurations, priv->active_config);
// If we can't read the config descriptors, just set the number of confs to zero
- if (cache_config_descriptors(dev, handle) != LIBUSB_SUCCESS) {
+ if (cache_config_descriptors(dev, handle, device_id) != LIBUSB_SUCCESS) {
dev->num_configurations = 0;
priv->dev_descriptor.bNumConfigurations = 0;
}
@@ -1314,13 +1316,15 @@ static int windows_get_device_list(struct libusb_context *ctx, struct discovered
// Read the Device ID path. This is what we'll use as UID
// Note that if the device is plugged in a different port or hub, the Device ID changes
if (CM_Get_Device_IDA(dev_info_data.DevInst, path, sizeof(path), 0) != CR_SUCCESS) {
- usbi_warn(ctx, "could not read the device id path for device '%s', skipping",
- dev_interface_details->DevicePath);
+ usbi_warn(ctx, "could not read the device id path for devinst %X, skipping",
+ dev_info_data.DevInst);
continue;
}
dev_id_path = sanitize_path(path);
if (dev_id_path == NULL) {
- usbi_warn(ctx, "could not sanitize device id path for '%s'", dev_interface_details->DevicePath);
+ usbi_warn(ctx, "could not sanitize device id path for devinst %X, skipping",
+ dev_info_data.DevInst);
+ continue;
}
// The SPDRP_ADDRESS for USB devices is the device port number on the hub
@@ -1329,8 +1333,8 @@ static int windows_get_device_list(struct libusb_context *ctx, struct discovered
if ( (!pSetupDiGetDeviceRegistryPropertyA(dev_info, &dev_info_data, SPDRP_ADDRESS,
&reg_type, (BYTE*)&port_nr, 4, &size))
|| (size != 4) ) {
- usbi_warn(ctx, "could not retrieve port number for device %s, skipping: %s",
- dev_interface_details->DevicePath, windows_error_str(0));
+ usbi_warn(ctx, "could not retrieve port number for device '%s', skipping: %s",
+ dev_id_path, windows_error_str(0));
continue;
}
}
@@ -1353,9 +1357,9 @@ static int windows_get_device_list(struct libusb_context *ctx, struct discovered
key = pSetupDiOpenDevRegKey(dev_info, &dev_info_data, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ);
if (key != INVALID_HANDLE_VALUE) {
size = sizeof(guid_string_w);
- s = RegQueryValueExW(key, L"DeviceInterfaceGUIDs", NULL, &reg_type,
+ s = pRegQueryValueExW(key, L"DeviceInterfaceGUIDs", NULL, &reg_type,
(BYTE*)guid_string_w, &size);
- RegCloseKey(key);
+ pRegCloseKey(key);
if (s == ERROR_SUCCESS) {
if (nb_guids >= MAX_ENUM_GUIDS) {
// If this assert is ever reported, grow a GUID table dynamically
@@ -1392,6 +1396,7 @@ static int windows_get_device_list(struct libusb_context *ctx, struct discovered
switch (pass) {
case HCD_PASS:
case DEV_PASS:
+ case HUB_PASS:
break;
default:
session_id = get_parent_session_id(ctx, dev_info_data.DevInst);
@@ -1437,17 +1442,8 @@ static int windows_get_device_list(struct libusb_context *ctx, struct discovered
// These are the passes that create "new" devices
session_id = usbi_htab_hash(ctx, dev_id_path);
dev = usbi_get_device_by_session_id(ctx, session_id);
- if (dev != NULL) {
- // No need to re-process hubs
- if (__device_priv(dev)->apib == &usb_api_backend[USB_API_HUB]) {
- continue;
- }
- usbi_dbg("found existing device for session [%lX]", session_id);
- // TODO (post hotplug): reuse priv data that can be reused - for now, just recreate
- if (pass == GEN_PASS) {
- windows_device_priv_release(dev);
- }
- } else {
+ if (dev == NULL) {
+ usbi_dbg("allocating new device for session [%lX]", session_id);
if (pass == DEV_PASS) {
usbi_err(ctx, "program assertion failed: device '%s' was not listed in generic pass", dev_id_path);
LOOP_BREAK(LIBUSB_ERROR_NOT_FOUND);
@@ -1456,9 +1452,6 @@ static int windows_get_device_list(struct libusb_context *ctx, struct discovered
LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
}
windows_device_priv_init(dev);
-
- usbi_dbg("allocating new device for session [%lX]", session_id);
-
// Keep track of devices that need unref
unref_list[unref_cur++] = dev;
if (unref_cur > unref_size) {
@@ -1469,15 +1462,8 @@ static int windows_get_device_list(struct libusb_context *ctx, struct discovered
LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
}
}
-
- // Append newly created devices to the list of discovered devices
- if (pass != HCD_PASS) {
- discdevs = discovered_devs_append(*_discdevs, dev);
- if (!discdevs) {
- LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
- }
- *_discdevs = discdevs;
- }
+ } else {
+ usbi_dbg("found existing device for session [%lX]", session_id);
}
priv = __device_priv(dev);
}
@@ -1524,9 +1510,22 @@ static int windows_get_device_list(struct libusb_context *ctx, struct discovered
case HUB_PASS:
priv->apib = &usb_api_backend[USB_API_HUB];
priv->path = dev_interface_path; dev_interface_path = NULL;
+ break;
// fall through, as we must initialize hubs before generic devices
case GEN_PASS:
- init_device(dev, parent_dev, (uint8_t)port_nr, dev_id_path);
+ r = init_device(dev, parent_dev, (uint8_t)port_nr, dev_id_path);
+ if (r == LIBUSB_SUCCESS) {
+ // Append device to the list of discovered devices
+ discdevs = discovered_devs_append(*_discdevs, dev);
+ if (!discdevs) {
+ LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
+ }
+ *_discdevs = discdevs;
+ } else if (r == LIBUSB_ERROR_NO_DEVICE) {
+ // This can occur if the device was disconnected but Windows hasn't
+ // refreshed its enumeration yet - in that case, we ignore the device
+ r = LIBUSB_SUCCESS;
+ }
break;
default: // HID_PASS and later
if (parent_priv->apib == &usb_api_backend[USB_API_HID]) {
diff --git a/libusb/os/windows_usb.h b/libusb/os/windows_usb.h
index 8ee7146..00571fd 100644
--- a/libusb/os/windows_usb.h
+++ b/libusb/os/windows_usb.h
@@ -377,7 +377,8 @@ DLL_DECLARE_PREFIXED(WINAPI, BOOL, p, SetupDiDestroyDeviceInfoList, (HDEVINFO));
DLL_DECLARE_PREFIXED(WINAPI, HKEY, p, SetupDiOpenDevRegKey, (HDEVINFO, PSP_DEVINFO_DATA, DWORD, DWORD, DWORD, REGSAM));
DLL_DECLARE_PREFIXED(WINAPI, BOOL, p, SetupDiGetDeviceRegistryPropertyA, (HDEVINFO,
PSP_DEVINFO_DATA, DWORD, PDWORD, PBYTE, DWORD, PDWORD));
-
+DLL_DECLARE_PREFIXED(WINAPI, LONG, p, RegQueryValueExW, (HKEY, LPCWSTR, LPDWORD, LPDWORD, LPBYTE, LPDWORD));
+DLL_DECLARE_PREFIXED(WINAPI, LONG, p, RegCloseKey, (HKEY));
/*
* Windows DDK API definitions. Most of it copied from MinGW's includes