Merge pull request #4463 from leoetlino/libusb

Externals: Update libusb to version 1.0.21
This commit is contained in:
Mat M 2016-12-01 21:14:58 -05:00 committed by GitHub
commit 20676a6640
82 changed files with 14319 additions and 1662 deletions

View File

@ -1,7 +1,7 @@
Copyright © 2001 Johannes Erdfelt <johannes@erdfelt.com> Copyright © 2001 Johannes Erdfelt <johannes@erdfelt.com>
Copyright © 2007-2009 Daniel Drake <dsd@gentoo.org> Copyright © 2007-2009 Daniel Drake <dsd@gentoo.org>
Copyright © 2010-2012 Peter Stuge <peter@stuge.se> Copyright © 2010-2012 Peter Stuge <peter@stuge.se>
Copyright © 2008-2013 Nathan Hjelm <hjelmn@users.sourceforge.net> Copyright © 2008-2016 Nathan Hjelm <hjelmn@users.sourceforge.net>
Copyright © 2009-2013 Pete Batard <pete@akeo.ie> Copyright © 2009-2013 Pete Batard <pete@akeo.ie>
Copyright © 2009-2013 Ludovic Rousseau <ludovic.rousseau@gmail.com> Copyright © 2009-2013 Ludovic Rousseau <ludovic.rousseau@gmail.com>
Copyright © 2010-2012 Michael Plante <michael.plante@gmail.com> Copyright © 2010-2012 Michael Plante <michael.plante@gmail.com>

View File

@ -1,6 +1,23 @@
For detailed information about the changes below, please see the git log or For detailed information about the changes below, please see the git log or
visit: http://log.libusb.info visit: http://log.libusb.info
2016-10-01: v1.0.21:
* Core: Refactor code related to transfer flags and timeout handling
* Darwin: Ignore root hub simulation devices
* Darwin: Improved support for OS X El Capitan
* Darwin: Work around devices with buggy endpoint descriptors
* Darwin: Do not use objc_registerThreadWithCollector after its deprecation
* Darwin: Use C11 atomics on 10.12+ as the OS atomics are now deprecated
* Linux: Support preallocating kernel memory for zerocopy USB
* Linux: Deal with receiving POLLERR before all transfers have completed
* Solaris: Add solaris backend
* Windows: Add Visual Studio 2015 support
* Windows: Add usbdk backend
* Prevent attempts to recursively handle events
* Fix race condition in handle_timeout()
* Allow transferred argument to be optional in bulk APIs
* Various other bug fixes and improvements
2015-09-13: v1.0.20 2015-09-13: v1.0.20
* Add Haiku support * Add Haiku support
* Fix multiple memory and resource leaks (#16, #52, #76, #81) * Fix multiple memory and resource leaks (#16, #52, #76, #81)

View File

@ -1,4 +1,4 @@
Dolphin-specific changes (as of 2016-08-25) Dolphin-specific changes (as of 2016-11-20)
------------------------------------------- -------------------------------------------
- removed all toplevel directories save msvc/ & libusb/ - removed all toplevel directories save msvc/ & libusb/

View File

@ -1,19 +1,25 @@
Installation Instructions Installation Instructions
************************* *************************
Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005, Copyright (C) 1994-1996, 1999-2002, 2004-2013 Free Software Foundation,
2006 Free Software Foundation, Inc. Inc.
This file is free documentation; the Free Software Foundation gives Copying and distribution of this file, with or without modification,
unlimited permission to copy, distribute and modify it. are permitted in any medium without royalty provided the copyright
notice and this notice are preserved. This file is offered as-is,
without warranty of any kind.
Basic Installation Basic Installation
================== ==================
Briefly, the shell commands `./configure; make; make install' should Briefly, the shell command `./configure && make && make install'
configure, build, and install this package. The following should configure, build, and install this package. The following
more-detailed instructions are generic; see the `README' file for more-detailed instructions are generic; see the `README' file for
instructions specific to this package. instructions specific to this package. Some packages provide this
`INSTALL' file but do not implement all of the features documented
below. The lack of an optional feature in a given package is not
necessarily a bug. More recommendations for GNU packages can be found
in *note Makefile Conventions: (standards)Makefile Conventions.
The `configure' shell script attempts to guess correct values for The `configure' shell script attempts to guess correct values for
various system-dependent variables used during compilation. It uses various system-dependent variables used during compilation. It uses
@ -53,12 +59,22 @@ The simplest way to compile this package is:
2. Type `make' to compile the package. 2. Type `make' to compile the package.
3. Optionally, type `make check' to run any self-tests that come with 3. Optionally, type `make check' to run any self-tests that come with
the package. the package, generally using the just-built uninstalled binaries.
4. Type `make install' to install the programs and any data files and 4. Type `make install' to install the programs and any data files and
documentation. documentation. When installing into a prefix owned by root, it is
recommended that the package be configured and built as a regular
user, and only the `make install' phase executed with root
privileges.
5. You can remove the program binaries and object files from the 5. Optionally, type `make installcheck' to repeat any self-tests, but
this time using the binaries in their final installed location.
This target does not install anything. Running this target as a
regular user, particularly if the prior `make install' required
root privileges, verifies that the installation completed
correctly.
6. You can remove the program binaries and object files from the
source code directory by typing `make clean'. To also remove the source code directory by typing `make clean'. To also remove the
files that `configure' created (so you can compile the package for files that `configure' created (so you can compile the package for
a different kind of computer), type `make distclean'. There is a different kind of computer), type `make distclean'. There is
@ -67,12 +83,22 @@ The simplest way to compile this package is:
all sorts of other programs in order to regenerate files that came all sorts of other programs in order to regenerate files that came
with the distribution. with the distribution.
7. Often, you can also type `make uninstall' to remove the installed
files again. In practice, not all packages have tested that
uninstallation works correctly, even though it is required by the
GNU Coding Standards.
8. Some packages, particularly those that use Automake, provide `make
distcheck', which can by used by developers to test that all other
targets like `make install' and `make uninstall' work correctly.
This target is generally not run by end users.
Compilers and Options Compilers and Options
===================== =====================
Some systems require unusual options for compilation or linking that the Some systems require unusual options for compilation or linking that
`configure' script does not know about. Run `./configure --help' for the `configure' script does not know about. Run `./configure --help'
details on some of the pertinent environment variables. for details on some of the pertinent environment variables.
You can give `configure' initial values for configuration parameters You can give `configure' initial values for configuration parameters
by setting variables in the command line or in the environment. Here by setting variables in the command line or in the environment. Here
@ -90,20 +116,36 @@ same time, by placing the object files for each architecture in their
own directory. To do this, you can use GNU `make'. `cd' to the own directory. To do this, you can use GNU `make'. `cd' to the
directory where you want the object files and executables to go and run directory where you want the object files and executables to go and run
the `configure' script. `configure' automatically checks for the the `configure' script. `configure' automatically checks for the
source code in the directory that `configure' is in and in `..'. source code in the directory that `configure' is in and in `..'. This
is known as a "VPATH" build.
With a non-GNU `make', it is safer to compile the package for one With a non-GNU `make', it is safer to compile the package for one
architecture at a time in the source code directory. After you have architecture at a time in the source code directory. After you have
installed the package for one architecture, use `make distclean' before installed the package for one architecture, use `make distclean' before
reconfiguring for another architecture. reconfiguring for another architecture.
On MacOS X 10.5 and later systems, you can create libraries and
executables that work on multiple system types--known as "fat" or
"universal" binaries--by specifying multiple `-arch' options to the
compiler but only a single `-arch' option to the preprocessor. Like
this:
./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
CPP="gcc -E" CXXCPP="g++ -E"
This is not guaranteed to produce working output in all cases, you
may have to build one architecture at a time and combine the results
using the `lipo' tool if you have problems.
Installation Names Installation Names
================== ==================
By default, `make install' installs the package's commands under By default, `make install' installs the package's commands under
`/usr/local/bin', include files under `/usr/local/include', etc. You `/usr/local/bin', include files under `/usr/local/include', etc. You
can specify an installation prefix other than `/usr/local' by giving can specify an installation prefix other than `/usr/local' by giving
`configure' the option `--prefix=PREFIX'. `configure' the option `--prefix=PREFIX', where PREFIX must be an
absolute file name.
You can specify separate installation prefixes for You can specify separate installation prefixes for
architecture-specific files and architecture-independent files. If you architecture-specific files and architecture-independent files. If you
@ -114,15 +156,46 @@ Documentation and other data files still use the regular prefix.
In addition, if you use an unusual directory layout you can give In addition, if you use an unusual directory layout you can give
options like `--bindir=DIR' to specify different values for particular options like `--bindir=DIR' to specify different values for particular
kinds of files. Run `configure --help' for a list of the directories kinds of files. Run `configure --help' for a list of the directories
you can set and what kinds of files go in them. you can set and what kinds of files go in them. In general, the
default for these options is expressed in terms of `${prefix}', so that
specifying just `--prefix' will affect all of the other directory
specifications that were not explicitly provided.
The most portable way to affect installation locations is to pass the
correct locations to `configure'; however, many packages provide one or
both of the following shortcuts of passing variable assignments to the
`make install' command line to change installation locations without
having to reconfigure or recompile.
The first method involves providing an override variable for each
affected directory. For example, `make install
prefix=/alternate/directory' will choose an alternate location for all
directory configuration variables that were expressed in terms of
`${prefix}'. Any directories that were specified during `configure',
but not in terms of `${prefix}', must each be overridden at install
time for the entire installation to be relocated. The approach of
makefile variable overrides for each directory variable is required by
the GNU Coding Standards, and ideally causes no recompilation.
However, some platforms have known limitations with the semantics of
shared libraries that end up requiring recompilation when using this
method, particularly noticeable in packages that use GNU Libtool.
The second method involves providing the `DESTDIR' variable. For
example, `make install DESTDIR=/alternate/directory' will prepend
`/alternate/directory' before all installation names. The approach of
`DESTDIR' overrides is not required by the GNU Coding Standards, and
does not work on platforms that have drive letters. On the other hand,
it does better at avoiding recompilation issues, and works well even
when some directory options were not specified in terms of `${prefix}'
at `configure' time.
Optional Features
=================
If the package supports it, you can cause programs to be installed If the package supports it, you can cause programs to be installed
with an extra prefix or suffix on their names by giving `configure' the with an extra prefix or suffix on their names by giving `configure' the
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
Optional Features
=================
Some packages pay attention to `--enable-FEATURE' options to Some packages pay attention to `--enable-FEATURE' options to
`configure', where FEATURE indicates an optional part of the package. `configure', where FEATURE indicates an optional part of the package.
They may also pay attention to `--with-PACKAGE' options, where PACKAGE They may also pay attention to `--with-PACKAGE' options, where PACKAGE
@ -135,14 +208,58 @@ find the X include and library files automatically, but if it doesn't,
you can use the `configure' options `--x-includes=DIR' and you can use the `configure' options `--x-includes=DIR' and
`--x-libraries=DIR' to specify their locations. `--x-libraries=DIR' to specify their locations.
Some packages offer the ability to configure how verbose the
execution of `make' will be. For these packages, running `./configure
--enable-silent-rules' sets the default to minimal output, which can be
overridden with `make V=1'; while running `./configure
--disable-silent-rules' sets the default to verbose, which can be
overridden with `make V=0'.
Particular systems
==================
On HP-UX, the default C compiler is not ANSI C compatible. If GNU
CC is not installed, it is recommended to use the following options in
order to use an ANSI C compiler:
./configure CC="cc -Ae -D_XOPEN_SOURCE=500"
and if that doesn't work, install pre-built binaries of GCC for HP-UX.
HP-UX `make' updates targets which have the same time stamps as
their prerequisites, which makes it generally unusable when shipped
generated files such as `configure' are involved. Use GNU `make'
instead.
On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot
parse its `<wchar.h>' header file. The option `-nodtk' can be used as
a workaround. If GNU CC is not installed, it is therefore recommended
to try
./configure CC="cc"
and if that doesn't work, try
./configure CC="cc -nodtk"
On Solaris, don't put `/usr/ucb' early in your `PATH'. This
directory contains several dysfunctional programs; working variants of
these programs are available in `/usr/bin'. So, if you need `/usr/ucb'
in your `PATH', put it _after_ `/usr/bin'.
On Haiku, software installed for all users goes in `/boot/common',
not `/usr/local'. It is recommended to use the following options:
./configure --prefix=/boot/common
Specifying the System Type Specifying the System Type
========================== ==========================
There may be some features `configure' cannot figure out automatically, There may be some features `configure' cannot figure out
but needs to determine by the type of machine the package will run on. automatically, but needs to determine by the type of machine the package
Usually, assuming the package is built to be run on the _same_ will run on. Usually, assuming the package is built to be run on the
architectures, `configure' can figure that out, but if it prints a _same_ architectures, `configure' can figure that out, but if it prints
message saying it cannot guess the machine type, give it the a message saying it cannot guess the machine type, give it the
`--build=TYPE' option. TYPE can either be a short name for the system `--build=TYPE' option. TYPE can either be a short name for the system
type, such as `sun4', or a canonical name which has the form: type, such as `sun4', or a canonical name which has the form:
@ -150,7 +267,8 @@ type, such as `sun4', or a canonical name which has the form:
where SYSTEM can have one of these forms: where SYSTEM can have one of these forms:
OS KERNEL-OS OS
KERNEL-OS
See the file `config.sub' for the possible values of each field. If See the file `config.sub' for the possible values of each field. If
`config.sub' isn't included in this package, then this package doesn't `config.sub' isn't included in this package, then this package doesn't
@ -168,9 +286,9 @@ eventually be run) with `--host=TYPE'.
Sharing Defaults Sharing Defaults
================ ================
If you want to set default values for `configure' scripts to share, you If you want to set default values for `configure' scripts to share,
can create a site shell script called `config.site' that gives default you can create a site shell script called `config.site' that gives
values for variables like `CC', `cache_file', and `prefix'. default values for variables like `CC', `cache_file', and `prefix'.
`configure' looks for `PREFIX/share/config.site' if it exists, then `configure' looks for `PREFIX/share/config.site' if it exists, then
`PREFIX/etc/config.site' if it exists. Or, you can set the `PREFIX/etc/config.site' if it exists. Or, you can set the
`CONFIG_SITE' environment variable to the location of the site script. `CONFIG_SITE' environment variable to the location of the site script.
@ -191,18 +309,27 @@ causes the specified `gcc' to be used as the C compiler (unless it is
overridden in the site shell script). overridden in the site shell script).
Unfortunately, this technique does not work for `CONFIG_SHELL' due to Unfortunately, this technique does not work for `CONFIG_SHELL' due to
an Autoconf bug. Until the bug is fixed you can use this workaround: an Autoconf limitation. Until the limitation is lifted, you can use
this workaround:
CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash
`configure' Invocation `configure' Invocation
====================== ======================
`configure' recognizes the following options to control how it operates. `configure' recognizes the following options to control how it
operates.
`--help' `--help'
`-h' `-h'
Print a summary of the options to `configure', and exit. Print a summary of all of the options to `configure', and exit.
`--help=short'
`--help=recursive'
Print a summary of the options unique to this package's
`configure', and exit. The `short' variant lists options used
only in the top level, while the `recursive' variant lists options
also present in any nested packages.
`--version' `--version'
`-V' `-V'
@ -229,6 +356,15 @@ an Autoconf bug. Until the bug is fixed you can use this workaround:
Look for the package's source code in directory DIR. Usually Look for the package's source code in directory DIR. Usually
`configure' can determine that directory automatically. `configure' can determine that directory automatically.
`--prefix=DIR'
Use DIR as the installation prefix. *note Installation Names::
for more details, including other options available for fine-tuning
the installation locations.
`--no-create'
`-n'
Run the configure checks, but stop before creating any output
files.
`configure' also accepts some other, not widely useful, options. Run `configure' also accepts some other, not widely useful, options. Run
`configure --help' for more details. `configure --help' for more details.

View File

@ -1,15 +1,18 @@
libusb # libusb
======
[![Build Status](https://travis-ci.org/libusb/libusb.svg?branch=master)](https://travis-ci.org/libusb/libusb)
[![Build status](https://ci.appveyor.com/api/projects/status/xvrfam94jii4a6lw?svg=true)](https://ci.appveyor.com/project/LudovicRousseau/libusb)
[![Coverity Scan Build Status](https://scan.coverity.com/projects/2180/badge.svg)](https://scan.coverity.com/projects/libusb-libusb)
libusb is a library for USB device access from Linux, Mac OS X, libusb is a library for USB device access from Linux, Mac OS X,
Windows, OpenBSD/NetBSD and Haiku userspace. Windows, OpenBSD/NetBSD and Haiku userspace.
It is written in C (Haiku backend in C++) and licensed under the GNU It is written in C (Haiku backend in C++) and licensed under the GNU
Lesser General Public License version 2.1 or, at your option, any later Lesser General Public License version 2.1 or, at your option, any later
version (see COPYING). version (see [COPYING](COPYING)).
libusb is abstracted internally in such a way that it can hopefully libusb is abstracted internally in such a way that it can hopefully
be ported to other operating systems. Please see the PORTING file be ported to other operating systems. Please see the [PORTING](PORTING)
for more information. file for more information.
libusb homepage: libusb homepage:
http://libusb.info/ http://libusb.info/
@ -24,6 +27,7 @@ http://mailing-list.libusb.info
- Hans de Goede <hdegoede@redhat.com> - Hans de Goede <hdegoede@redhat.com>
- Xiaofan Chen <xiaofanc@gmail.com> - Xiaofan Chen <xiaofanc@gmail.com>
- Ludovic Rousseau <ludovic.rousseau@gmail.com> - Ludovic Rousseau <ludovic.rousseau@gmail.com>
- Nathan Hjelm <hjelmn@users.sourceforge.net> - Nathan Hjelm <hjelmn@cs.unm.edu>
- Chris Dickens <christopher.a.dickens@gmail.com> - Chris Dickens <christopher.a.dickens@gmail.com>
(Please use the mailing list rather than mailing developers directly) (Please use the mailing list rather than mailing developers directly)

View File

@ -1,2 +1,2 @@
Please see the libusb roadmap by visiting: Please see the libusb roadmap by visiting:
https://github.com/libusb/libusb/issues/milestones?direction=asc&sort=due_date https://github.com/libusb/libusb/milestones?direction=asc&sort=due_date&state=open

View File

@ -4,58 +4,71 @@ AUTOMAKE_OPTIONS = subdir-objects
lib_LTLIBRARIES = libusb-1.0.la lib_LTLIBRARIES = libusb-1.0.la
POSIX_POLL_SRC = os/poll_posix.c POSIX_POLL_SRC = os/poll_posix.h os/poll_posix.c
LINUX_USBFS_SRC = os/linux_usbfs.c POSIX_THREADS_SRC = os/threads_posix.h os/threads_posix.c
DARWIN_USB_SRC = os/darwin_usb.c WINDOWS_POLL_SRC = os/poll_windows.h os/poll_windows.c
WINDOWS_THREADS_SRC = os/threads_windows.h os/threads_windows.c
LINUX_USBFS_SRC = os/linux_usbfs.h os/linux_usbfs.c
DARWIN_USB_SRC = os/darwin_usb.h os/darwin_usb.c
OPENBSD_USB_SRC = os/openbsd_usb.c OPENBSD_USB_SRC = os/openbsd_usb.c
NETBSD_USB_SRC = os/netbsd_usb.c NETBSD_USB_SRC = os/netbsd_usb.c
WINDOWS_USB_SRC = os/poll_windows.c os/windows_usb.c libusb-1.0.rc libusb-1.0.def SUNOS_USB_SRC = os/sunos_usb.c os/sunos_usb.h
WINCE_USB_SRC = os/wince_usb.c os/wince_usb.h WINDOWS_COMMON_SRC = os/windows_nt_common.h os/windows_nt_common.c \
os/windows_common.h libusb-1.0.rc libusb-1.0.def
WINDOWS_USB_SRC = os/windows_winusb.h os/windows_winusb.c
WINDOWS_USBDK_SRC = os/windows_usbdk.h os/windows_usbdk.c
WINCE_USB_SRC = os/wince_usb.h os/wince_usb.c
HAIKU_USB_SRC = os/haiku_usb.h os/haiku_usb_backend.cpp \
os/haiku_usb_raw.h os/haiku_usb_raw.cpp os/haiku_pollfs.cpp
DIST_SUBDIRS = EXTRA_DIST = $(POSIX_POLL_SRC) $(POSIX_THREADS_SRC) \
$(WINDOWS_POLL_SRC) $(WINDOWS_THREADS_SRC) \
EXTRA_DIST = $(LINUX_USBFS_SRC) $(DARWIN_USB_SRC) $(OPENBSD_USB_SRC) \ $(LINUX_USBFS_SRC) $(DARWIN_USB_SRC) \
$(NETBSD_USB_SRC) $(WINDOWS_USB_SRC) $(WINCE_USB_SRC) \ $(OPENBSD_USB_SRC) $(NETBSD_USB_SRC) \
$(POSIX_POLL_SRC) \ $(WINDOWS_COMMON_SRC) $(WINDOWS_USB_SRC) $(WINDOWS_USBDK_SRC) \
os/threads_posix.c os/threads_windows.c \ $(WINCE_USB_SRC) $(HAIKU_USB_SRC) \
os/linux_udev.c os/linux_netlink.c os/linux_udev.c os/linux_netlink.c
dist-hook:
cp -r os/haiku $(distdir)/os/haiku
rm -rf $(distdir)/os/haiku/autom4te.cache
if OS_LINUX if OS_LINUX
if USE_UDEV if USE_UDEV
OS_SRC = $(LINUX_USBFS_SRC) $(POSIX_POLL_SRC) \ OS_SRC = $(LINUX_USBFS_SRC) os/linux_udev.c
os/linux_udev.c
else else
OS_SRC = $(LINUX_USBFS_SRC) $(POSIX_POLL_SRC) \ OS_SRC = $(LINUX_USBFS_SRC) os/linux_netlink.c
os/linux_netlink.c
endif endif
endif endif
if OS_DARWIN if OS_DARWIN
OS_SRC = $(DARWIN_USB_SRC) $(POSIX_POLL_SRC) OS_SRC = $(DARWIN_USB_SRC)
AM_CFLAGS_EXT = -no-cpp-precomp AM_CFLAGS_EXT = -no-cpp-precomp
endif endif
if OS_OPENBSD if OS_OPENBSD
OS_SRC = $(OPENBSD_USB_SRC) $(POSIX_POLL_SRC) OS_SRC = $(OPENBSD_USB_SRC)
endif endif
if OS_NETBSD if OS_NETBSD
OS_SRC = $(NETBSD_USB_SRC) $(POSIX_POLL_SRC) OS_SRC = $(NETBSD_USB_SRC)
endif
if OS_SUNOS
OS_SRC = $(SUNOS_USB_SRC)
endif endif
if OS_HAIKU if OS_HAIKU
OS_SRC = $(POSIX_POLL_SRC) noinst_LTLIBRARIES = libusb_haiku.la
SUBDIRS = os/haiku libusb_haiku_la_SOURCES = $(HAIKU_USB_SRC)
libusb_1_0_la_LIBADD = libusb_haiku.la
endif endif
if OS_WINDOWS if OS_WINDOWS
OS_SRC = $(WINDOWS_USB_SRC)
if USE_USBDK
OS_SRC = $(WINDOWS_USBDK_SRC) $(WINDOWS_COMMON_SRC)
else
OS_SRC = $(WINDOWS_USB_SRC) $(WINDOWS_COMMON_SRC)
endif
.rc.lo: .rc.lo:
$(AM_V_GEN)$(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --tag=RC --mode=compile $(RC) $(RCFLAGS) -i $< -o $@ $(AM_V_GEN)$(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --tag=RC --mode=compile $(RC) $(RCFLAGS) -i $< -o $@
@ -69,22 +82,23 @@ if CREATE_IMPORT_LIB
$(AM_V_GEN)$(DLLTOOL) $(DLLTOOLFLAGS) --kill-at --input-def $(srcdir)/libusb-1.0.def --dllname $@ --output-lib .libs/$@.a $(AM_V_GEN)$(DLLTOOL) $(DLLTOOLFLAGS) --kill-at --input-def $(srcdir)/libusb-1.0.def --dllname $@ --output-lib .libs/$@.a
endif endif
if THREADS_POSIX if OS_WINDOWS
THREADS_SRC = os/threads_posix.h os/threads_posix.c POLL_SRC = $(WINDOWS_POLL_SRC)
else else
THREADS_SRC = os/threads_windows.h os/threads_windows.c POLL_SRC = $(POSIX_POLL_SRC)
endif
if THREADS_POSIX
THREADS_SRC = $(POSIX_THREADS_SRC)
else
THREADS_SRC = $(WINDOWS_THREADS_SRC)
endif endif
libusb_1_0_la_CFLAGS = $(AM_CFLAGS) libusb_1_0_la_CFLAGS = $(AM_CFLAGS)
libusb_1_0_la_LDFLAGS = $(LTLDFLAGS) libusb_1_0_la_LDFLAGS = $(LTLDFLAGS)
libusb_1_0_la_SOURCES = libusbi.h core.c descriptor.c io.c strerror.c sync.c \ libusb_1_0_la_SOURCES = libusbi.h libusb.h version.h version_nano.h \
os/linux_usbfs.h os/darwin_usb.h os/windows_usb.h os/windows_common.h \ core.c descriptor.c hotplug.h hotplug.c io.c strerror.c sync.c \
hotplug.h hotplug.c $(THREADS_SRC) $(OS_SRC) \ $(POLL_SRC) $(THREADS_SRC) $(OS_SRC)
os/poll_posix.h os/poll_windows.h
if OS_HAIKU
libusb_1_0_la_LIBADD = os/haiku/libhaikuusb.la
endif
hdrdir = $(includedir)/libusb-1.0 hdrdir = $(includedir)/libusb-1.0
hdr_HEADERS = libusb.h hdr_HEADERS = libusb.h

View File

@ -1,7 +1,7 @@
# Makefile.in generated by automake 1.15 from Makefile.am. # Makefile.in generated by automake 1.14.1 from Makefile.am.
# @configure_input@ # @configure_input@
# Copyright (C) 1994-2014 Free Software Foundation, Inc. # Copyright (C) 1994-2013 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation # This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it, # gives unlimited permission to copy and/or distribute it,
@ -16,17 +16,7 @@
VPATH = @srcdir@ VPATH = @srcdir@
am__is_gnu_make = { \ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
if test -z '$(MAKELEVEL)'; then \
false; \
elif test -n '$(MAKE_HOST)'; then \
true; \
elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
true; \
else \
false; \
fi; \
}
am__make_running_with_option = \ am__make_running_with_option = \
case $${target_option-} in \ case $${target_option-} in \
?) ;; \ ?) ;; \
@ -90,6 +80,8 @@ POST_UNINSTALL = :
build_triplet = @build@ build_triplet = @build@
host_triplet = @host@ host_triplet = @host@
subdir = libusb subdir = libusb
DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
$(top_srcdir)/depcomp $(hdr_HEADERS)
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
@ -97,7 +89,6 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
$(top_srcdir)/libusb/version.h $(top_srcdir)/configure.ac $(top_srcdir)/libusb/version.h $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4) $(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(hdr_HEADERS) $(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES = CONFIG_CLEAN_FILES =
@ -130,45 +121,53 @@ am__uninstall_files_from_dir = { \
$(am__cd) "$$dir" && rm -f $$files; }; \ $(am__cd) "$$dir" && rm -f $$files; }; \
} }
am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(hdrdir)" am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(hdrdir)"
LTLIBRARIES = $(lib_LTLIBRARIES) LTLIBRARIES = $(lib_LTLIBRARIES) $(noinst_LTLIBRARIES)
@OS_HAIKU_TRUE@libusb_1_0_la_DEPENDENCIES = os/haiku/libhaikuusb.la @OS_HAIKU_TRUE@libusb_1_0_la_DEPENDENCIES = libusb_haiku.la
am__libusb_1_0_la_SOURCES_DIST = libusbi.h core.c descriptor.c io.c \ am__libusb_1_0_la_SOURCES_DIST = libusbi.h libusb.h version.h \
strerror.c sync.c os/linux_usbfs.h os/darwin_usb.h \ version_nano.h core.c descriptor.c hotplug.h hotplug.c io.c \
os/windows_usb.h os/windows_common.h hotplug.h hotplug.c \ strerror.c sync.c os/poll_posix.h os/poll_posix.c \
os/threads_windows.h os/threads_windows.c os/threads_posix.h \ os/poll_windows.h os/poll_windows.c os/threads_windows.h \
os/threads_posix.c os/darwin_usb.c os/poll_posix.c \ os/threads_windows.c os/threads_posix.h os/threads_posix.c \
os/darwin_usb.h os/darwin_usb.c os/linux_usbfs.h \
os/linux_usbfs.c os/linux_netlink.c os/linux_udev.c \ os/linux_usbfs.c os/linux_netlink.c os/linux_udev.c \
os/netbsd_usb.c os/openbsd_usb.c os/poll_windows.c \ os/netbsd_usb.c os/openbsd_usb.c os/sunos_usb.c os/sunos_usb.h \
os/windows_usb.c libusb-1.0.rc libusb-1.0.def os/poll_posix.h \ os/windows_winusb.h os/windows_winusb.c os/windows_nt_common.h \
os/poll_windows.h os/windows_nt_common.c os/windows_common.h libusb-1.0.rc \
libusb-1.0.def os/windows_usbdk.h os/windows_usbdk.c
am__dirstamp = $(am__leading_dot)dirstamp am__dirstamp = $(am__leading_dot)dirstamp
@THREADS_POSIX_FALSE@am__objects_1 = \ am__objects_1 = os/libusb_1_0_la-poll_posix.lo
@THREADS_POSIX_FALSE@ os/libusb_1_0_la-threads_windows.lo am__objects_2 = os/libusb_1_0_la-poll_windows.lo
@THREADS_POSIX_TRUE@am__objects_1 = os/libusb_1_0_la-threads_posix.lo @OS_WINDOWS_FALSE@am__objects_3 = $(am__objects_1)
am__objects_2 = os/libusb_1_0_la-darwin_usb.lo @OS_WINDOWS_TRUE@am__objects_3 = $(am__objects_2)
am__objects_3 = os/libusb_1_0_la-poll_posix.lo am__objects_4 = os/libusb_1_0_la-threads_windows.lo
am__objects_4 = os/libusb_1_0_la-linux_usbfs.lo am__objects_5 = os/libusb_1_0_la-threads_posix.lo
am__objects_5 = os/libusb_1_0_la-netbsd_usb.lo @THREADS_POSIX_FALSE@am__objects_6 = $(am__objects_4)
am__objects_6 = os/libusb_1_0_la-openbsd_usb.lo @THREADS_POSIX_TRUE@am__objects_6 = $(am__objects_5)
am__objects_7 = os/libusb_1_0_la-poll_windows.lo \ am__objects_7 = os/libusb_1_0_la-darwin_usb.lo
os/libusb_1_0_la-windows_usb.lo libusb-1.0.lo am__objects_8 = os/libusb_1_0_la-linux_usbfs.lo
@OS_DARWIN_FALSE@@OS_HAIKU_FALSE@@OS_LINUX_FALSE@@OS_NETBSD_FALSE@@OS_OPENBSD_FALSE@@OS_WINDOWS_TRUE@am__objects_8 = $(am__objects_7) am__objects_9 = os/libusb_1_0_la-netbsd_usb.lo
@OS_DARWIN_FALSE@@OS_HAIKU_FALSE@@OS_LINUX_FALSE@@OS_NETBSD_FALSE@@OS_OPENBSD_TRUE@am__objects_8 = $(am__objects_6) \ am__objects_10 = os/libusb_1_0_la-openbsd_usb.lo
@OS_DARWIN_FALSE@@OS_HAIKU_FALSE@@OS_LINUX_FALSE@@OS_NETBSD_FALSE@@OS_OPENBSD_TRUE@ $(am__objects_3) am__objects_11 = os/libusb_1_0_la-sunos_usb.lo
@OS_DARWIN_FALSE@@OS_HAIKU_FALSE@@OS_LINUX_FALSE@@OS_NETBSD_TRUE@am__objects_8 = $(am__objects_5) \ am__objects_12 = os/libusb_1_0_la-windows_winusb.lo
@OS_DARWIN_FALSE@@OS_HAIKU_FALSE@@OS_LINUX_FALSE@@OS_NETBSD_TRUE@ $(am__objects_3) am__objects_13 = os/libusb_1_0_la-windows_nt_common.lo libusb-1.0.lo
@OS_DARWIN_FALSE@@OS_HAIKU_FALSE@@OS_LINUX_TRUE@@USE_UDEV_FALSE@am__objects_8 = $(am__objects_4) \ am__objects_14 = os/libusb_1_0_la-windows_usbdk.lo
@OS_DARWIN_FALSE@@OS_HAIKU_FALSE@@OS_LINUX_TRUE@@USE_UDEV_FALSE@ $(am__objects_3) \ @OS_DARWIN_FALSE@@OS_LINUX_FALSE@@OS_NETBSD_FALSE@@OS_OPENBSD_FALSE@@OS_SUNOS_FALSE@@OS_WINDOWS_TRUE@@USE_USBDK_FALSE@am__objects_15 = $(am__objects_12) \
@OS_DARWIN_FALSE@@OS_HAIKU_FALSE@@OS_LINUX_TRUE@@USE_UDEV_FALSE@ os/libusb_1_0_la-linux_netlink.lo @OS_DARWIN_FALSE@@OS_LINUX_FALSE@@OS_NETBSD_FALSE@@OS_OPENBSD_FALSE@@OS_SUNOS_FALSE@@OS_WINDOWS_TRUE@@USE_USBDK_FALSE@ $(am__objects_13)
@OS_DARWIN_FALSE@@OS_HAIKU_FALSE@@OS_LINUX_TRUE@@USE_UDEV_TRUE@am__objects_8 = $(am__objects_4) \ @OS_DARWIN_FALSE@@OS_LINUX_FALSE@@OS_NETBSD_FALSE@@OS_OPENBSD_FALSE@@OS_SUNOS_FALSE@@OS_WINDOWS_TRUE@@USE_USBDK_TRUE@am__objects_15 = $(am__objects_14) \
@OS_DARWIN_FALSE@@OS_HAIKU_FALSE@@OS_LINUX_TRUE@@USE_UDEV_TRUE@ $(am__objects_3) \ @OS_DARWIN_FALSE@@OS_LINUX_FALSE@@OS_NETBSD_FALSE@@OS_OPENBSD_FALSE@@OS_SUNOS_FALSE@@OS_WINDOWS_TRUE@@USE_USBDK_TRUE@ $(am__objects_13)
@OS_DARWIN_FALSE@@OS_HAIKU_FALSE@@OS_LINUX_TRUE@@USE_UDEV_TRUE@ os/libusb_1_0_la-linux_udev.lo @OS_DARWIN_FALSE@@OS_LINUX_FALSE@@OS_NETBSD_FALSE@@OS_OPENBSD_FALSE@@OS_SUNOS_TRUE@am__objects_15 = $(am__objects_11)
@OS_DARWIN_FALSE@@OS_HAIKU_TRUE@am__objects_8 = $(am__objects_3) @OS_DARWIN_FALSE@@OS_LINUX_FALSE@@OS_NETBSD_FALSE@@OS_OPENBSD_TRUE@am__objects_15 = $(am__objects_10)
@OS_DARWIN_TRUE@am__objects_8 = $(am__objects_2) $(am__objects_3) @OS_DARWIN_FALSE@@OS_LINUX_FALSE@@OS_NETBSD_TRUE@am__objects_15 = $(am__objects_9)
@OS_DARWIN_FALSE@@OS_LINUX_TRUE@@USE_UDEV_FALSE@am__objects_15 = $(am__objects_8) \
@OS_DARWIN_FALSE@@OS_LINUX_TRUE@@USE_UDEV_FALSE@ os/libusb_1_0_la-linux_netlink.lo
@OS_DARWIN_FALSE@@OS_LINUX_TRUE@@USE_UDEV_TRUE@am__objects_15 = $(am__objects_8) \
@OS_DARWIN_FALSE@@OS_LINUX_TRUE@@USE_UDEV_TRUE@ os/libusb_1_0_la-linux_udev.lo
@OS_DARWIN_TRUE@am__objects_15 = $(am__objects_7)
am_libusb_1_0_la_OBJECTS = libusb_1_0_la-core.lo \ am_libusb_1_0_la_OBJECTS = libusb_1_0_la-core.lo \
libusb_1_0_la-descriptor.lo libusb_1_0_la-io.lo \ libusb_1_0_la-descriptor.lo libusb_1_0_la-hotplug.lo \
libusb_1_0_la-strerror.lo libusb_1_0_la-sync.lo \ libusb_1_0_la-io.lo libusb_1_0_la-strerror.lo \
libusb_1_0_la-hotplug.lo $(am__objects_1) $(am__objects_8) libusb_1_0_la-sync.lo $(am__objects_3) $(am__objects_6) \
$(am__objects_15)
libusb_1_0_la_OBJECTS = $(am_libusb_1_0_la_OBJECTS) libusb_1_0_la_OBJECTS = $(am_libusb_1_0_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@) AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
@ -177,6 +176,15 @@ am__v_lt_1 =
libusb_1_0_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ libusb_1_0_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(libusb_1_0_la_CFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libusb_1_0_la_CFLAGS) \
$(CFLAGS) $(libusb_1_0_la_LDFLAGS) $(LDFLAGS) -o $@ $(CFLAGS) $(libusb_1_0_la_LDFLAGS) $(LDFLAGS) -o $@
libusb_haiku_la_LIBADD =
am__libusb_haiku_la_SOURCES_DIST = os/haiku_usb.h \
os/haiku_usb_backend.cpp os/haiku_usb_raw.h \
os/haiku_usb_raw.cpp os/haiku_pollfs.cpp
am__objects_16 = os/haiku_usb_backend.lo os/haiku_usb_raw.lo \
os/haiku_pollfs.lo
@OS_HAIKU_TRUE@am_libusb_haiku_la_OBJECTS = $(am__objects_16)
libusb_haiku_la_OBJECTS = $(am_libusb_haiku_la_OBJECTS)
@OS_HAIKU_TRUE@am_libusb_haiku_la_rpath =
AM_V_P = $(am__v_P_@AM_V@) AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false am__v_P_0 = false
@ -211,30 +219,33 @@ AM_V_CCLD = $(am__v_CCLD_@AM_V@)
am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_0 = @echo " CCLD " $@;
am__v_CCLD_1 = am__v_CCLD_1 =
SOURCES = $(libusb_1_0_la_SOURCES) CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
DIST_SOURCES = $(am__libusb_1_0_la_SOURCES_DIST) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
ctags-recursive dvi-recursive html-recursive info-recursive \ $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
install-data-recursive install-dvi-recursive \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
install-exec-recursive install-html-recursive \ $(AM_CXXFLAGS) $(CXXFLAGS)
install-info-recursive install-pdf-recursive \ AM_V_CXX = $(am__v_CXX_@AM_V@)
install-ps-recursive install-recursive installcheck-recursive \ am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@)
installdirs-recursive pdf-recursive ps-recursive \ am__v_CXX_0 = @echo " CXX " $@;
tags-recursive uninstall-recursive am__v_CXX_1 =
CXXLD = $(CXX)
CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
$(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
AM_V_CXXLD = $(am__v_CXXLD_@AM_V@)
am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@)
am__v_CXXLD_0 = @echo " CXXLD " $@;
am__v_CXXLD_1 =
SOURCES = $(libusb_1_0_la_SOURCES) $(libusb_haiku_la_SOURCES)
DIST_SOURCES = $(am__libusb_1_0_la_SOURCES_DIST) \
$(am__libusb_haiku_la_SOURCES_DIST)
am__can_run_installinfo = \ am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \ case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \ n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \ *) (install-info --version) >/dev/null 2>&1;; \
esac esac
HEADERS = $(hdr_HEADERS) HEADERS = $(hdr_HEADERS)
RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
distclean-recursive maintainer-clean-recursive
am__recursive_targets = \
$(RECURSIVE_TARGETS) \
$(RECURSIVE_CLEAN_TARGETS) \
$(am__extra_recursive_targets)
AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
distdir
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
# Read a list of newline-separated strings from the standard input, # Read a list of newline-separated strings from the standard input,
# and print each of them once, without duplicates. Input order is # and print each of them once, without duplicates. Input order is
@ -254,33 +265,7 @@ am__define_uniq_tagged_files = \
done | $(am__uniquify_input)` done | $(am__uniquify_input)`
ETAGS = etags ETAGS = etags
CTAGS = ctags CTAGS = ctags
am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
am__relativize = \
dir0=`pwd`; \
sed_first='s,^\([^/]*\)/.*$$,\1,'; \
sed_rest='s,^[^/]*/*,,'; \
sed_last='s,^.*/\([^/]*\)$$,\1,'; \
sed_butlast='s,/*[^/]*$$,,'; \
while test -n "$$dir1"; do \
first=`echo "$$dir1" | sed -e "$$sed_first"`; \
if test "$$first" != "."; then \
if test "$$first" = ".."; then \
dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
else \
first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
if test "$$first2" = "$$first"; then \
dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
else \
dir2="../$$dir2"; \
fi; \
dir0="$$dir0"/"$$first"; \
fi; \
fi; \
dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
done; \
reldir="$$dir2"
ACLOCAL = @ACLOCAL@ ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@ AMTAR = @AMTAR@
AM_CFLAGS = @AM_CFLAGS@ AM_CFLAGS = @AM_CFLAGS@
@ -295,6 +280,10 @@ CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@ CFLAGS = @CFLAGS@
CPP = @CPP@ CPP = @CPP@
CPPFLAGS = @CPPFLAGS@ CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@ CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@ DEFS = @DEFS@
DEPDIR = @DEPDIR@ DEPDIR = @DEPDIR@
@ -322,7 +311,6 @@ LIPO = @LIPO@
LN_S = @LN_S@ LN_S = @LN_S@
LTLDFLAGS = @LTLDFLAGS@ LTLDFLAGS = @LTLDFLAGS@
LTLIBOBJS = @LTLIBOBJS@ LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@ MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@ MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@ MKDIR_P = @MKDIR_P@
@ -335,6 +323,7 @@ OS_HAIKU = @OS_HAIKU@
OS_LINUX = @OS_LINUX@ OS_LINUX = @OS_LINUX@
OS_NETBSD = @OS_NETBSD@ OS_NETBSD = @OS_NETBSD@
OS_OPENBSD = @OS_OPENBSD@ OS_OPENBSD = @OS_OPENBSD@
OS_SUNOS = @OS_SUNOS@
OS_WINDOWS = @OS_WINDOWS@ OS_WINDOWS = @OS_WINDOWS@
OTOOL = @OTOOL@ OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@ OTOOL64 = @OTOOL64@
@ -353,6 +342,7 @@ SET_MAKE = @SET_MAKE@
SHELL = @SHELL@ SHELL = @SHELL@
STRIP = @STRIP@ STRIP = @STRIP@
USE_UDEV = @USE_UDEV@ USE_UDEV = @USE_UDEV@
USE_USBDK = @USE_USBDK@
VERSION = @VERSION@ VERSION = @VERSION@
abs_builddir = @abs_builddir@ abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@ abs_srcdir = @abs_srcdir@
@ -360,6 +350,7 @@ abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@ abs_top_srcdir = @abs_top_srcdir@
ac_ct_AR = @ac_ct_AR@ ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@ ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@ am__include = @am__include@
am__leading_dot = @am__leading_dot@ am__leading_dot = @am__leading_dot@
@ -401,7 +392,6 @@ psdir = @psdir@
sbindir = @sbindir@ sbindir = @sbindir@
sharedstatedir = @sharedstatedir@ sharedstatedir = @sharedstatedir@
srcdir = @srcdir@ srcdir = @srcdir@
subdirs = @subdirs@
sysconfdir = @sysconfdir@ sysconfdir = @sysconfdir@
target_alias = @target_alias@ target_alias = @target_alias@
top_build_prefix = @top_build_prefix@ top_build_prefix = @top_build_prefix@
@ -409,50 +399,61 @@ top_builddir = @top_builddir@
top_srcdir = @top_srcdir@ top_srcdir = @top_srcdir@
AUTOMAKE_OPTIONS = subdir-objects AUTOMAKE_OPTIONS = subdir-objects
lib_LTLIBRARIES = libusb-1.0.la lib_LTLIBRARIES = libusb-1.0.la
POSIX_POLL_SRC = os/poll_posix.c POSIX_POLL_SRC = os/poll_posix.h os/poll_posix.c
LINUX_USBFS_SRC = os/linux_usbfs.c POSIX_THREADS_SRC = os/threads_posix.h os/threads_posix.c
DARWIN_USB_SRC = os/darwin_usb.c WINDOWS_POLL_SRC = os/poll_windows.h os/poll_windows.c
WINDOWS_THREADS_SRC = os/threads_windows.h os/threads_windows.c
LINUX_USBFS_SRC = os/linux_usbfs.h os/linux_usbfs.c
DARWIN_USB_SRC = os/darwin_usb.h os/darwin_usb.c
OPENBSD_USB_SRC = os/openbsd_usb.c OPENBSD_USB_SRC = os/openbsd_usb.c
NETBSD_USB_SRC = os/netbsd_usb.c NETBSD_USB_SRC = os/netbsd_usb.c
WINDOWS_USB_SRC = os/poll_windows.c os/windows_usb.c libusb-1.0.rc libusb-1.0.def SUNOS_USB_SRC = os/sunos_usb.c os/sunos_usb.h
WINCE_USB_SRC = os/wince_usb.c os/wince_usb.h WINDOWS_COMMON_SRC = os/windows_nt_common.h os/windows_nt_common.c \
DIST_SUBDIRS = os/windows_common.h libusb-1.0.rc libusb-1.0.def
EXTRA_DIST = $(LINUX_USBFS_SRC) $(DARWIN_USB_SRC) $(OPENBSD_USB_SRC) \
$(NETBSD_USB_SRC) $(WINDOWS_USB_SRC) $(WINCE_USB_SRC) \ WINDOWS_USB_SRC = os/windows_winusb.h os/windows_winusb.c
$(POSIX_POLL_SRC) \ WINDOWS_USBDK_SRC = os/windows_usbdk.h os/windows_usbdk.c
os/threads_posix.c os/threads_windows.c \ WINCE_USB_SRC = os/wince_usb.h os/wince_usb.c
HAIKU_USB_SRC = os/haiku_usb.h os/haiku_usb_backend.cpp \
os/haiku_usb_raw.h os/haiku_usb_raw.cpp os/haiku_pollfs.cpp
EXTRA_DIST = $(POSIX_POLL_SRC) $(POSIX_THREADS_SRC) \
$(WINDOWS_POLL_SRC) $(WINDOWS_THREADS_SRC) \
$(LINUX_USBFS_SRC) $(DARWIN_USB_SRC) \
$(OPENBSD_USB_SRC) $(NETBSD_USB_SRC) \
$(WINDOWS_COMMON_SRC) $(WINDOWS_USB_SRC) $(WINDOWS_USBDK_SRC) \
$(WINCE_USB_SRC) $(HAIKU_USB_SRC) \
os/linux_udev.c os/linux_netlink.c os/linux_udev.c os/linux_netlink.c
@OS_DARWIN_TRUE@OS_SRC = $(DARWIN_USB_SRC) $(POSIX_POLL_SRC) @OS_DARWIN_TRUE@OS_SRC = $(DARWIN_USB_SRC)
@OS_HAIKU_TRUE@OS_SRC = $(POSIX_POLL_SRC) @OS_LINUX_TRUE@@USE_UDEV_FALSE@OS_SRC = $(LINUX_USBFS_SRC) os/linux_netlink.c
@OS_LINUX_TRUE@@USE_UDEV_FALSE@OS_SRC = $(LINUX_USBFS_SRC) $(POSIX_POLL_SRC) \ @OS_LINUX_TRUE@@USE_UDEV_TRUE@OS_SRC = $(LINUX_USBFS_SRC) os/linux_udev.c
@OS_LINUX_TRUE@@USE_UDEV_FALSE@ os/linux_netlink.c @OS_NETBSD_TRUE@OS_SRC = $(NETBSD_USB_SRC)
@OS_OPENBSD_TRUE@OS_SRC = $(OPENBSD_USB_SRC)
@OS_LINUX_TRUE@@USE_UDEV_TRUE@OS_SRC = $(LINUX_USBFS_SRC) $(POSIX_POLL_SRC) \ @OS_SUNOS_TRUE@OS_SRC = $(SUNOS_USB_SRC)
@OS_LINUX_TRUE@@USE_UDEV_TRUE@ os/linux_udev.c @OS_WINDOWS_TRUE@@USE_USBDK_FALSE@OS_SRC = $(WINDOWS_USB_SRC) $(WINDOWS_COMMON_SRC)
@OS_WINDOWS_TRUE@@USE_USBDK_TRUE@OS_SRC = $(WINDOWS_USBDK_SRC) $(WINDOWS_COMMON_SRC)
@OS_NETBSD_TRUE@OS_SRC = $(NETBSD_USB_SRC) $(POSIX_POLL_SRC)
@OS_OPENBSD_TRUE@OS_SRC = $(OPENBSD_USB_SRC) $(POSIX_POLL_SRC)
@OS_WINDOWS_TRUE@OS_SRC = $(WINDOWS_USB_SRC)
@OS_DARWIN_TRUE@AM_CFLAGS_EXT = -no-cpp-precomp @OS_DARWIN_TRUE@AM_CFLAGS_EXT = -no-cpp-precomp
@OS_HAIKU_TRUE@SUBDIRS = os/haiku @OS_HAIKU_TRUE@noinst_LTLIBRARIES = libusb_haiku.la
@THREADS_POSIX_FALSE@THREADS_SRC = os/threads_windows.h os/threads_windows.c @OS_HAIKU_TRUE@libusb_haiku_la_SOURCES = $(HAIKU_USB_SRC)
@THREADS_POSIX_TRUE@THREADS_SRC = os/threads_posix.h os/threads_posix.c @OS_HAIKU_TRUE@libusb_1_0_la_LIBADD = libusb_haiku.la
@OS_WINDOWS_FALSE@POLL_SRC = $(POSIX_POLL_SRC)
@OS_WINDOWS_TRUE@POLL_SRC = $(WINDOWS_POLL_SRC)
@THREADS_POSIX_FALSE@THREADS_SRC = $(WINDOWS_THREADS_SRC)
@THREADS_POSIX_TRUE@THREADS_SRC = $(POSIX_THREADS_SRC)
libusb_1_0_la_CFLAGS = $(AM_CFLAGS) libusb_1_0_la_CFLAGS = $(AM_CFLAGS)
libusb_1_0_la_LDFLAGS = $(LTLDFLAGS) libusb_1_0_la_LDFLAGS = $(LTLDFLAGS)
libusb_1_0_la_SOURCES = libusbi.h core.c descriptor.c io.c strerror.c sync.c \ libusb_1_0_la_SOURCES = libusbi.h libusb.h version.h version_nano.h \
os/linux_usbfs.h os/darwin_usb.h os/windows_usb.h os/windows_common.h \ core.c descriptor.c hotplug.h hotplug.c io.c strerror.c sync.c \
hotplug.h hotplug.c $(THREADS_SRC) $(OS_SRC) \ $(POLL_SRC) $(THREADS_SRC) $(OS_SRC)
os/poll_posix.h os/poll_windows.h
@OS_HAIKU_TRUE@libusb_1_0_la_LIBADD = os/haiku/libhaikuusb.la
hdrdir = $(includedir)/libusb-1.0 hdrdir = $(includedir)/libusb-1.0
hdr_HEADERS = libusb.h hdr_HEADERS = libusb.h
all: all-recursive all: all-am
.SUFFIXES: .SUFFIXES:
.SUFFIXES: .c .lo .o .obj .rc .SUFFIXES: .c .cpp .lo .o .obj .rc
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \ @for dep in $?; do \
case '$(am__configure_deps)' in \ case '$(am__configure_deps)' in \
*$$dep*) \ *$$dep*) \
@ -464,6 +465,7 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu libusb/Makefile'; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu libusb/Makefile'; \
$(am__cd) $(top_srcdir) && \ $(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --gnu libusb/Makefile $(AUTOMAKE) --gnu libusb/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \ @case '$?' in \
*config.status*) \ *config.status*) \
@ -476,9 +478,9 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) $(top_srcdir)/configure: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) $(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps): $(am__aclocal_m4_deps):
@ -516,20 +518,33 @@ clean-libLTLIBRARIES:
echo rm -f $${locs}; \ echo rm -f $${locs}; \
rm -f $${locs}; \ rm -f $${locs}; \
} }
clean-noinstLTLIBRARIES:
-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
@list='$(noinst_LTLIBRARIES)'; \
locs=`for p in $$list; do echo $$p; done | \
sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
sort -u`; \
test -z "$$locs" || { \
echo rm -f $${locs}; \
rm -f $${locs}; \
}
os/$(am__dirstamp): os/$(am__dirstamp):
@$(MKDIR_P) os @$(MKDIR_P) os
@: > os/$(am__dirstamp) @: > os/$(am__dirstamp)
os/$(DEPDIR)/$(am__dirstamp): os/$(DEPDIR)/$(am__dirstamp):
@$(MKDIR_P) os/$(DEPDIR) @$(MKDIR_P) os/$(DEPDIR)
@: > os/$(DEPDIR)/$(am__dirstamp) @: > os/$(DEPDIR)/$(am__dirstamp)
os/libusb_1_0_la-poll_posix.lo: os/$(am__dirstamp) \
os/$(DEPDIR)/$(am__dirstamp)
os/libusb_1_0_la-poll_windows.lo: os/$(am__dirstamp) \
os/$(DEPDIR)/$(am__dirstamp)
os/libusb_1_0_la-threads_windows.lo: os/$(am__dirstamp) \ os/libusb_1_0_la-threads_windows.lo: os/$(am__dirstamp) \
os/$(DEPDIR)/$(am__dirstamp) os/$(DEPDIR)/$(am__dirstamp)
os/libusb_1_0_la-threads_posix.lo: os/$(am__dirstamp) \ os/libusb_1_0_la-threads_posix.lo: os/$(am__dirstamp) \
os/$(DEPDIR)/$(am__dirstamp) os/$(DEPDIR)/$(am__dirstamp)
os/libusb_1_0_la-darwin_usb.lo: os/$(am__dirstamp) \ os/libusb_1_0_la-darwin_usb.lo: os/$(am__dirstamp) \
os/$(DEPDIR)/$(am__dirstamp) os/$(DEPDIR)/$(am__dirstamp)
os/libusb_1_0_la-poll_posix.lo: os/$(am__dirstamp) \
os/$(DEPDIR)/$(am__dirstamp)
os/libusb_1_0_la-linux_usbfs.lo: os/$(am__dirstamp) \ os/libusb_1_0_la-linux_usbfs.lo: os/$(am__dirstamp) \
os/$(DEPDIR)/$(am__dirstamp) os/$(DEPDIR)/$(am__dirstamp)
os/libusb_1_0_la-linux_netlink.lo: os/$(am__dirstamp) \ os/libusb_1_0_la-linux_netlink.lo: os/$(am__dirstamp) \
@ -540,13 +555,24 @@ os/libusb_1_0_la-netbsd_usb.lo: os/$(am__dirstamp) \
os/$(DEPDIR)/$(am__dirstamp) os/$(DEPDIR)/$(am__dirstamp)
os/libusb_1_0_la-openbsd_usb.lo: os/$(am__dirstamp) \ os/libusb_1_0_la-openbsd_usb.lo: os/$(am__dirstamp) \
os/$(DEPDIR)/$(am__dirstamp) os/$(DEPDIR)/$(am__dirstamp)
os/libusb_1_0_la-poll_windows.lo: os/$(am__dirstamp) \ os/libusb_1_0_la-sunos_usb.lo: os/$(am__dirstamp) \
os/$(DEPDIR)/$(am__dirstamp) os/$(DEPDIR)/$(am__dirstamp)
os/libusb_1_0_la-windows_usb.lo: os/$(am__dirstamp) \ os/libusb_1_0_la-windows_winusb.lo: os/$(am__dirstamp) \
os/$(DEPDIR)/$(am__dirstamp)
os/libusb_1_0_la-windows_nt_common.lo: os/$(am__dirstamp) \
os/$(DEPDIR)/$(am__dirstamp)
os/libusb_1_0_la-windows_usbdk.lo: os/$(am__dirstamp) \
os/$(DEPDIR)/$(am__dirstamp) os/$(DEPDIR)/$(am__dirstamp)
libusb-1.0.la: $(libusb_1_0_la_OBJECTS) $(libusb_1_0_la_DEPENDENCIES) $(EXTRA_libusb_1_0_la_DEPENDENCIES) libusb-1.0.la: $(libusb_1_0_la_OBJECTS) $(libusb_1_0_la_DEPENDENCIES) $(EXTRA_libusb_1_0_la_DEPENDENCIES)
$(AM_V_CCLD)$(libusb_1_0_la_LINK) -rpath $(libdir) $(libusb_1_0_la_OBJECTS) $(libusb_1_0_la_LIBADD) $(LIBS) $(AM_V_CCLD)$(libusb_1_0_la_LINK) -rpath $(libdir) $(libusb_1_0_la_OBJECTS) $(libusb_1_0_la_LIBADD) $(LIBS)
os/haiku_usb_backend.lo: os/$(am__dirstamp) \
os/$(DEPDIR)/$(am__dirstamp)
os/haiku_usb_raw.lo: os/$(am__dirstamp) os/$(DEPDIR)/$(am__dirstamp)
os/haiku_pollfs.lo: os/$(am__dirstamp) os/$(DEPDIR)/$(am__dirstamp)
libusb_haiku.la: $(libusb_haiku_la_OBJECTS) $(libusb_haiku_la_DEPENDENCIES) $(EXTRA_libusb_haiku_la_DEPENDENCIES)
$(AM_V_CXXLD)$(CXXLINK) $(am_libusb_haiku_la_rpath) $(libusb_haiku_la_OBJECTS) $(libusb_haiku_la_LIBADD) $(LIBS)
mostlyclean-compile: mostlyclean-compile:
-rm -f *.$(OBJEXT) -rm -f *.$(OBJEXT)
@ -562,6 +588,9 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libusb_1_0_la-io.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libusb_1_0_la-io.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libusb_1_0_la-strerror.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libusb_1_0_la-strerror.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libusb_1_0_la-sync.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libusb_1_0_la-sync.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@os/$(DEPDIR)/haiku_pollfs.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@os/$(DEPDIR)/haiku_usb_backend.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@os/$(DEPDIR)/haiku_usb_raw.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@os/$(DEPDIR)/libusb_1_0_la-darwin_usb.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@os/$(DEPDIR)/libusb_1_0_la-darwin_usb.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@os/$(DEPDIR)/libusb_1_0_la-linux_netlink.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@os/$(DEPDIR)/libusb_1_0_la-linux_netlink.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@os/$(DEPDIR)/libusb_1_0_la-linux_udev.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@os/$(DEPDIR)/libusb_1_0_la-linux_udev.Plo@am__quote@
@ -570,9 +599,12 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@os/$(DEPDIR)/libusb_1_0_la-openbsd_usb.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@os/$(DEPDIR)/libusb_1_0_la-openbsd_usb.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@os/$(DEPDIR)/libusb_1_0_la-poll_posix.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@os/$(DEPDIR)/libusb_1_0_la-poll_posix.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@os/$(DEPDIR)/libusb_1_0_la-poll_windows.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@os/$(DEPDIR)/libusb_1_0_la-poll_windows.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@os/$(DEPDIR)/libusb_1_0_la-sunos_usb.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@os/$(DEPDIR)/libusb_1_0_la-threads_posix.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@os/$(DEPDIR)/libusb_1_0_la-threads_posix.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@os/$(DEPDIR)/libusb_1_0_la-threads_windows.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@os/$(DEPDIR)/libusb_1_0_la-threads_windows.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@os/$(DEPDIR)/libusb_1_0_la-windows_usb.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@os/$(DEPDIR)/libusb_1_0_la-windows_nt_common.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@os/$(DEPDIR)/libusb_1_0_la-windows_usbdk.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@os/$(DEPDIR)/libusb_1_0_la-windows_winusb.Plo@am__quote@
.c.o: .c.o:
@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
@ -612,6 +644,13 @@ libusb_1_0_la-descriptor.lo: descriptor.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o libusb_1_0_la-descriptor.lo `test -f 'descriptor.c' || echo '$(srcdir)/'`descriptor.c @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o libusb_1_0_la-descriptor.lo `test -f 'descriptor.c' || echo '$(srcdir)/'`descriptor.c
libusb_1_0_la-hotplug.lo: hotplug.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT libusb_1_0_la-hotplug.lo -MD -MP -MF $(DEPDIR)/libusb_1_0_la-hotplug.Tpo -c -o libusb_1_0_la-hotplug.lo `test -f 'hotplug.c' || echo '$(srcdir)/'`hotplug.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libusb_1_0_la-hotplug.Tpo $(DEPDIR)/libusb_1_0_la-hotplug.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hotplug.c' object='libusb_1_0_la-hotplug.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o libusb_1_0_la-hotplug.lo `test -f 'hotplug.c' || echo '$(srcdir)/'`hotplug.c
libusb_1_0_la-io.lo: io.c libusb_1_0_la-io.lo: io.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT libusb_1_0_la-io.lo -MD -MP -MF $(DEPDIR)/libusb_1_0_la-io.Tpo -c -o libusb_1_0_la-io.lo `test -f 'io.c' || echo '$(srcdir)/'`io.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT libusb_1_0_la-io.lo -MD -MP -MF $(DEPDIR)/libusb_1_0_la-io.Tpo -c -o libusb_1_0_la-io.lo `test -f 'io.c' || echo '$(srcdir)/'`io.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libusb_1_0_la-io.Tpo $(DEPDIR)/libusb_1_0_la-io.Plo @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libusb_1_0_la-io.Tpo $(DEPDIR)/libusb_1_0_la-io.Plo
@ -633,12 +672,19 @@ libusb_1_0_la-sync.lo: sync.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o libusb_1_0_la-sync.lo `test -f 'sync.c' || echo '$(srcdir)/'`sync.c @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o libusb_1_0_la-sync.lo `test -f 'sync.c' || echo '$(srcdir)/'`sync.c
libusb_1_0_la-hotplug.lo: hotplug.c os/libusb_1_0_la-poll_posix.lo: os/poll_posix.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT libusb_1_0_la-hotplug.lo -MD -MP -MF $(DEPDIR)/libusb_1_0_la-hotplug.Tpo -c -o libusb_1_0_la-hotplug.lo `test -f 'hotplug.c' || echo '$(srcdir)/'`hotplug.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT os/libusb_1_0_la-poll_posix.lo -MD -MP -MF os/$(DEPDIR)/libusb_1_0_la-poll_posix.Tpo -c -o os/libusb_1_0_la-poll_posix.lo `test -f 'os/poll_posix.c' || echo '$(srcdir)/'`os/poll_posix.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libusb_1_0_la-hotplug.Tpo $(DEPDIR)/libusb_1_0_la-hotplug.Plo @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) os/$(DEPDIR)/libusb_1_0_la-poll_posix.Tpo os/$(DEPDIR)/libusb_1_0_la-poll_posix.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hotplug.c' object='libusb_1_0_la-hotplug.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='os/poll_posix.c' object='os/libusb_1_0_la-poll_posix.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o libusb_1_0_la-hotplug.lo `test -f 'hotplug.c' || echo '$(srcdir)/'`hotplug.c @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o os/libusb_1_0_la-poll_posix.lo `test -f 'os/poll_posix.c' || echo '$(srcdir)/'`os/poll_posix.c
os/libusb_1_0_la-poll_windows.lo: os/poll_windows.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT os/libusb_1_0_la-poll_windows.lo -MD -MP -MF os/$(DEPDIR)/libusb_1_0_la-poll_windows.Tpo -c -o os/libusb_1_0_la-poll_windows.lo `test -f 'os/poll_windows.c' || echo '$(srcdir)/'`os/poll_windows.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) os/$(DEPDIR)/libusb_1_0_la-poll_windows.Tpo os/$(DEPDIR)/libusb_1_0_la-poll_windows.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='os/poll_windows.c' object='os/libusb_1_0_la-poll_windows.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o os/libusb_1_0_la-poll_windows.lo `test -f 'os/poll_windows.c' || echo '$(srcdir)/'`os/poll_windows.c
os/libusb_1_0_la-threads_windows.lo: os/threads_windows.c os/libusb_1_0_la-threads_windows.lo: os/threads_windows.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT os/libusb_1_0_la-threads_windows.lo -MD -MP -MF os/$(DEPDIR)/libusb_1_0_la-threads_windows.Tpo -c -o os/libusb_1_0_la-threads_windows.lo `test -f 'os/threads_windows.c' || echo '$(srcdir)/'`os/threads_windows.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT os/libusb_1_0_la-threads_windows.lo -MD -MP -MF os/$(DEPDIR)/libusb_1_0_la-threads_windows.Tpo -c -o os/libusb_1_0_la-threads_windows.lo `test -f 'os/threads_windows.c' || echo '$(srcdir)/'`os/threads_windows.c
@ -661,13 +707,6 @@ os/libusb_1_0_la-darwin_usb.lo: os/darwin_usb.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o os/libusb_1_0_la-darwin_usb.lo `test -f 'os/darwin_usb.c' || echo '$(srcdir)/'`os/darwin_usb.c @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o os/libusb_1_0_la-darwin_usb.lo `test -f 'os/darwin_usb.c' || echo '$(srcdir)/'`os/darwin_usb.c
os/libusb_1_0_la-poll_posix.lo: os/poll_posix.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT os/libusb_1_0_la-poll_posix.lo -MD -MP -MF os/$(DEPDIR)/libusb_1_0_la-poll_posix.Tpo -c -o os/libusb_1_0_la-poll_posix.lo `test -f 'os/poll_posix.c' || echo '$(srcdir)/'`os/poll_posix.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) os/$(DEPDIR)/libusb_1_0_la-poll_posix.Tpo os/$(DEPDIR)/libusb_1_0_la-poll_posix.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='os/poll_posix.c' object='os/libusb_1_0_la-poll_posix.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o os/libusb_1_0_la-poll_posix.lo `test -f 'os/poll_posix.c' || echo '$(srcdir)/'`os/poll_posix.c
os/libusb_1_0_la-linux_usbfs.lo: os/linux_usbfs.c os/libusb_1_0_la-linux_usbfs.lo: os/linux_usbfs.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT os/libusb_1_0_la-linux_usbfs.lo -MD -MP -MF os/$(DEPDIR)/libusb_1_0_la-linux_usbfs.Tpo -c -o os/libusb_1_0_la-linux_usbfs.lo `test -f 'os/linux_usbfs.c' || echo '$(srcdir)/'`os/linux_usbfs.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT os/libusb_1_0_la-linux_usbfs.lo -MD -MP -MF os/$(DEPDIR)/libusb_1_0_la-linux_usbfs.Tpo -c -o os/libusb_1_0_la-linux_usbfs.lo `test -f 'os/linux_usbfs.c' || echo '$(srcdir)/'`os/linux_usbfs.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) os/$(DEPDIR)/libusb_1_0_la-linux_usbfs.Tpo os/$(DEPDIR)/libusb_1_0_la-linux_usbfs.Plo @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) os/$(DEPDIR)/libusb_1_0_la-linux_usbfs.Tpo os/$(DEPDIR)/libusb_1_0_la-linux_usbfs.Plo
@ -703,19 +742,57 @@ os/libusb_1_0_la-openbsd_usb.lo: os/openbsd_usb.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o os/libusb_1_0_la-openbsd_usb.lo `test -f 'os/openbsd_usb.c' || echo '$(srcdir)/'`os/openbsd_usb.c @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o os/libusb_1_0_la-openbsd_usb.lo `test -f 'os/openbsd_usb.c' || echo '$(srcdir)/'`os/openbsd_usb.c
os/libusb_1_0_la-poll_windows.lo: os/poll_windows.c os/libusb_1_0_la-sunos_usb.lo: os/sunos_usb.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT os/libusb_1_0_la-poll_windows.lo -MD -MP -MF os/$(DEPDIR)/libusb_1_0_la-poll_windows.Tpo -c -o os/libusb_1_0_la-poll_windows.lo `test -f 'os/poll_windows.c' || echo '$(srcdir)/'`os/poll_windows.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT os/libusb_1_0_la-sunos_usb.lo -MD -MP -MF os/$(DEPDIR)/libusb_1_0_la-sunos_usb.Tpo -c -o os/libusb_1_0_la-sunos_usb.lo `test -f 'os/sunos_usb.c' || echo '$(srcdir)/'`os/sunos_usb.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) os/$(DEPDIR)/libusb_1_0_la-poll_windows.Tpo os/$(DEPDIR)/libusb_1_0_la-poll_windows.Plo @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) os/$(DEPDIR)/libusb_1_0_la-sunos_usb.Tpo os/$(DEPDIR)/libusb_1_0_la-sunos_usb.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='os/poll_windows.c' object='os/libusb_1_0_la-poll_windows.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='os/sunos_usb.c' object='os/libusb_1_0_la-sunos_usb.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o os/libusb_1_0_la-poll_windows.lo `test -f 'os/poll_windows.c' || echo '$(srcdir)/'`os/poll_windows.c @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o os/libusb_1_0_la-sunos_usb.lo `test -f 'os/sunos_usb.c' || echo '$(srcdir)/'`os/sunos_usb.c
os/libusb_1_0_la-windows_usb.lo: os/windows_usb.c os/libusb_1_0_la-windows_winusb.lo: os/windows_winusb.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT os/libusb_1_0_la-windows_usb.lo -MD -MP -MF os/$(DEPDIR)/libusb_1_0_la-windows_usb.Tpo -c -o os/libusb_1_0_la-windows_usb.lo `test -f 'os/windows_usb.c' || echo '$(srcdir)/'`os/windows_usb.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT os/libusb_1_0_la-windows_winusb.lo -MD -MP -MF os/$(DEPDIR)/libusb_1_0_la-windows_winusb.Tpo -c -o os/libusb_1_0_la-windows_winusb.lo `test -f 'os/windows_winusb.c' || echo '$(srcdir)/'`os/windows_winusb.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) os/$(DEPDIR)/libusb_1_0_la-windows_usb.Tpo os/$(DEPDIR)/libusb_1_0_la-windows_usb.Plo @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) os/$(DEPDIR)/libusb_1_0_la-windows_winusb.Tpo os/$(DEPDIR)/libusb_1_0_la-windows_winusb.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='os/windows_usb.c' object='os/libusb_1_0_la-windows_usb.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='os/windows_winusb.c' object='os/libusb_1_0_la-windows_winusb.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o os/libusb_1_0_la-windows_usb.lo `test -f 'os/windows_usb.c' || echo '$(srcdir)/'`os/windows_usb.c @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o os/libusb_1_0_la-windows_winusb.lo `test -f 'os/windows_winusb.c' || echo '$(srcdir)/'`os/windows_winusb.c
os/libusb_1_0_la-windows_nt_common.lo: os/windows_nt_common.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT os/libusb_1_0_la-windows_nt_common.lo -MD -MP -MF os/$(DEPDIR)/libusb_1_0_la-windows_nt_common.Tpo -c -o os/libusb_1_0_la-windows_nt_common.lo `test -f 'os/windows_nt_common.c' || echo '$(srcdir)/'`os/windows_nt_common.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) os/$(DEPDIR)/libusb_1_0_la-windows_nt_common.Tpo os/$(DEPDIR)/libusb_1_0_la-windows_nt_common.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='os/windows_nt_common.c' object='os/libusb_1_0_la-windows_nt_common.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o os/libusb_1_0_la-windows_nt_common.lo `test -f 'os/windows_nt_common.c' || echo '$(srcdir)/'`os/windows_nt_common.c
os/libusb_1_0_la-windows_usbdk.lo: os/windows_usbdk.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT os/libusb_1_0_la-windows_usbdk.lo -MD -MP -MF os/$(DEPDIR)/libusb_1_0_la-windows_usbdk.Tpo -c -o os/libusb_1_0_la-windows_usbdk.lo `test -f 'os/windows_usbdk.c' || echo '$(srcdir)/'`os/windows_usbdk.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) os/$(DEPDIR)/libusb_1_0_la-windows_usbdk.Tpo os/$(DEPDIR)/libusb_1_0_la-windows_usbdk.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='os/windows_usbdk.c' object='os/libusb_1_0_la-windows_usbdk.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o os/libusb_1_0_la-windows_usbdk.lo `test -f 'os/windows_usbdk.c' || echo '$(srcdir)/'`os/windows_usbdk.c
.cpp.o:
@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $<
.cpp.obj:
@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
.cpp.lo:
@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
mostlyclean-libtool: mostlyclean-libtool:
-rm -f *.lo -rm -f *.lo
@ -745,61 +822,14 @@ uninstall-hdrHEADERS:
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
dir='$(DESTDIR)$(hdrdir)'; $(am__uninstall_files_from_dir) dir='$(DESTDIR)$(hdrdir)'; $(am__uninstall_files_from_dir)
# This directory's subdirectories are mostly independent; you can cd
# into them and run 'make' without going through this Makefile.
# To change the values of 'make' variables: instead of editing Makefiles,
# (1) if the variable is set in 'config.status', edit 'config.status'
# (which will cause the Makefiles to be regenerated when you run 'make');
# (2) otherwise, pass the desired values on the 'make' command line.
$(am__recursive_targets):
@fail=; \
if $(am__make_keepgoing); then \
failcom='fail=yes'; \
else \
failcom='exit 1'; \
fi; \
dot_seen=no; \
target=`echo $@ | sed s/-recursive//`; \
case "$@" in \
distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
*) list='$(SUBDIRS)' ;; \
esac; \
for subdir in $$list; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
dot_seen=yes; \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| eval $$failcom; \
done; \
if test "$$dot_seen" = "no"; then \
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
fi; test -z "$$fail"
ID: $(am__tagged_files) ID: $(am__tagged_files)
$(am__define_uniq_tagged_files); mkid -fID $$unique $(am__define_uniq_tagged_files); mkid -fID $$unique
tags: tags-recursive tags: tags-am
TAGS: tags TAGS: tags
tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
set x; \ set x; \
here=`pwd`; \ here=`pwd`; \
if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
include_option=--etags-include; \
empty_fix=.; \
else \
include_option=--include; \
empty_fix=; \
fi; \
list='$(SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test ! -f $$subdir/TAGS || \
set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
fi; \
done; \
$(am__define_uniq_tagged_files); \ $(am__define_uniq_tagged_files); \
shift; \ shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
@ -812,7 +842,7 @@ tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
$$unique; \ $$unique; \
fi; \ fi; \
fi fi
ctags: ctags-recursive ctags: ctags-am
CTAGS: ctags CTAGS: ctags
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
@ -825,7 +855,7 @@ GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \ here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \ && $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here" && gtags -i $(GTAGS_ARGS) "$$here"
cscopelist: cscopelist-recursive cscopelist: cscopelist-am
cscopelist-am: $(am__tagged_files) cscopelist-am: $(am__tagged_files)
list='$(am__tagged_files)'; \ list='$(am__tagged_files)'; \
@ -874,51 +904,22 @@ distdir: $(DISTFILES)
|| exit 1; \ || exit 1; \
fi; \ fi; \
done done
@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
$(am__make_dryrun) \
|| test -d "$(distdir)/$$subdir" \
|| $(MKDIR_P) "$(distdir)/$$subdir" \
|| exit 1; \
dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
$(am__relativize); \
new_distdir=$$reldir; \
dir1=$$subdir; dir2="$(top_distdir)"; \
$(am__relativize); \
new_top_distdir=$$reldir; \
echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
($(am__cd) $$subdir && \
$(MAKE) $(AM_MAKEFLAGS) \
top_distdir="$$new_top_distdir" \
distdir="$$new_distdir" \
am__remove_distdir=: \
am__skip_length_check=: \
am__skip_mode_fix=: \
distdir) \
|| exit 1; \
fi; \
done
$(MAKE) $(AM_MAKEFLAGS) \
top_distdir="$(top_distdir)" distdir="$(distdir)" \
dist-hook
check-am: all-am check-am: all-am
check: check-recursive check: check-am
all-am: Makefile $(LTLIBRARIES) $(HEADERS) all-am: Makefile $(LTLIBRARIES) $(HEADERS)
installdirs: installdirs-recursive installdirs:
installdirs-am:
for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(hdrdir)"; do \ for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(hdrdir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done done
install: install-recursive install: install-am
install-exec: install-exec-recursive install-exec: install-exec-am
install-data: install-data-recursive install-data: install-data-am
uninstall: uninstall-recursive uninstall: uninstall-am
install-am: all-am install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-recursive installcheck: installcheck-am
install-strip: install-strip:
if test -z '$(STRIP)'; then \ if test -z '$(STRIP)'; then \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
@ -942,103 +943,97 @@ distclean-generic:
maintainer-clean-generic: maintainer-clean-generic:
@echo "This command is intended for maintainers to use" @echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild." @echo "it deletes files that may require special tools to rebuild."
clean: clean-recursive clean: clean-am
clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
mostlyclean-am clean-noinstLTLIBRARIES mostlyclean-am
distclean: distclean-recursive distclean: distclean-am
-rm -rf ./$(DEPDIR) os/$(DEPDIR) -rm -rf ./$(DEPDIR) os/$(DEPDIR)
-rm -f Makefile -rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \ distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags distclean-tags
dvi: dvi-recursive dvi: dvi-am
dvi-am: dvi-am:
html: html-recursive html: html-am
html-am: html-am:
info: info-recursive info: info-am
info-am: info-am:
install-data-am: install-hdrHEADERS install-data-am: install-hdrHEADERS
install-dvi: install-dvi-recursive install-dvi: install-dvi-am
install-dvi-am: install-dvi-am:
install-exec-am: install-libLTLIBRARIES install-exec-am: install-libLTLIBRARIES
install-html: install-html-recursive install-html: install-html-am
install-html-am: install-html-am:
install-info: install-info-recursive install-info: install-info-am
install-info-am: install-info-am:
install-man: install-man:
install-pdf: install-pdf-recursive install-pdf: install-pdf-am
install-pdf-am: install-pdf-am:
install-ps: install-ps-recursive install-ps: install-ps-am
install-ps-am: install-ps-am:
installcheck-am: installcheck-am:
maintainer-clean: maintainer-clean-recursive maintainer-clean: maintainer-clean-am
-rm -rf ./$(DEPDIR) os/$(DEPDIR) -rm -rf ./$(DEPDIR) os/$(DEPDIR)
-rm -f Makefile -rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-recursive mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-am: mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool mostlyclean-libtool
pdf: pdf-recursive pdf: pdf-am
pdf-am: pdf-am:
ps: ps-recursive ps: ps-am
ps-am: ps-am:
uninstall-am: uninstall-hdrHEADERS uninstall-libLTLIBRARIES uninstall-am: uninstall-hdrHEADERS uninstall-libLTLIBRARIES
.MAKE: $(am__recursive_targets) install-am install-strip .MAKE: install-am install-strip
.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
check-am clean clean-generic clean-libLTLIBRARIES \ clean-libLTLIBRARIES clean-libtool clean-noinstLTLIBRARIES \
clean-libtool cscopelist-am ctags ctags-am dist-hook distclean \ cscopelist-am ctags ctags-am distclean distclean-compile \
distclean-compile distclean-generic distclean-libtool \ distclean-generic distclean-libtool distclean-tags distdir dvi \
distclean-tags distdir dvi dvi-am html html-am info info-am \ dvi-am html html-am info info-am install install-am \
install install-am install-data install-data-am install-dvi \ install-data install-data-am install-dvi install-dvi-am \
install-dvi-am install-exec install-exec-am install-hdrHEADERS \ install-exec install-exec-am install-hdrHEADERS install-html \
install-html install-html-am install-info install-info-am \ install-html-am install-info install-info-am \
install-libLTLIBRARIES install-man install-pdf install-pdf-am \ install-libLTLIBRARIES install-man install-pdf install-pdf-am \
install-ps install-ps-am install-strip installcheck \ install-ps install-ps-am install-strip installcheck \
installcheck-am installdirs installdirs-am maintainer-clean \ installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \ maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
tags tags-am uninstall uninstall-am uninstall-hdrHEADERS \ tags tags-am uninstall uninstall-am uninstall-hdrHEADERS \
uninstall-libLTLIBRARIES uninstall-libLTLIBRARIES
.PRECIOUS: Makefile
all: libusb-1.0.la libusb-1.0.dll all: libusb-1.0.la libusb-1.0.dll
dist-hook:
cp -r os/haiku $(distdir)/os/haiku
rm -rf $(distdir)/os/haiku/autom4te.cache
@OS_WINDOWS_TRUE@.rc.lo: @OS_WINDOWS_TRUE@.rc.lo:
@OS_WINDOWS_TRUE@ $(AM_V_GEN)$(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --tag=RC --mode=compile $(RC) $(RCFLAGS) -i $< -o $@ @OS_WINDOWS_TRUE@ $(AM_V_GEN)$(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --tag=RC --mode=compile $(RC) $(RCFLAGS) -i $< -o $@

File diff suppressed because it is too large Load Diff

View File

@ -35,7 +35,7 @@
#define ENDPOINT_DESC_LENGTH 7 #define ENDPOINT_DESC_LENGTH 7
#define ENDPOINT_AUDIO_DESC_LENGTH 9 #define ENDPOINT_AUDIO_DESC_LENGTH 9
/** @defgroup desc USB descriptors /** @defgroup libusb_desc USB descriptors
* This page details how to examine the various standard USB descriptors * This page details how to examine the various standard USB descriptors
* for detected devices * for detected devices
*/ */
@ -94,8 +94,7 @@ int usbi_parse_descriptor(const unsigned char *source, const char *descriptor,
static void clear_endpoint(struct libusb_endpoint_descriptor *endpoint) static void clear_endpoint(struct libusb_endpoint_descriptor *endpoint)
{ {
if (endpoint->extra) free((void *) endpoint->extra);
free((unsigned char *) endpoint->extra);
} }
static int parse_endpoint(struct libusb_context *ctx, static int parse_endpoint(struct libusb_context *ctx,
@ -198,12 +197,12 @@ static void clear_interface(struct libusb_interface *usb_interface)
struct libusb_interface_descriptor *ifp = struct libusb_interface_descriptor *ifp =
(struct libusb_interface_descriptor *) (struct libusb_interface_descriptor *)
usb_interface->altsetting + i; usb_interface->altsetting + i;
if (ifp->extra)
free((void *) ifp->extra); free((void *) ifp->extra);
if (ifp->endpoint) { if (ifp->endpoint) {
for (j = 0; j < ifp->bNumEndpoints; j++) for (j = 0; j < ifp->bNumEndpoints; j++)
clear_endpoint((struct libusb_endpoint_descriptor *) clear_endpoint((struct libusb_endpoint_descriptor *)
ifp->endpoint + j); ifp->endpoint + j);
}
free((void *) ifp->endpoint); free((void *) ifp->endpoint);
} }
} }
@ -211,8 +210,6 @@ static void clear_interface(struct libusb_interface *usb_interface)
usb_interface->altsetting = NULL; usb_interface->altsetting = NULL;
} }
}
static int parse_interface(libusb_context *ctx, static int parse_interface(libusb_context *ctx,
struct libusb_interface *usb_interface, unsigned char *buffer, int size, struct libusb_interface *usb_interface, unsigned char *buffer, int size,
int host_endian) int host_endian)
@ -222,7 +219,6 @@ static int parse_interface(libusb_context *ctx,
int r; int r;
int parsed = 0; int parsed = 0;
int interface_number = -1; int interface_number = -1;
size_t tmp;
struct usb_descriptor_header header; struct usb_descriptor_header header;
struct libusb_interface_descriptor *ifp; struct libusb_interface_descriptor *ifp;
unsigned char *begin; unsigned char *begin;
@ -323,15 +319,13 @@ static int parse_interface(libusb_context *ctx,
if (ifp->bNumEndpoints > 0) { if (ifp->bNumEndpoints > 0) {
struct libusb_endpoint_descriptor *endpoint; struct libusb_endpoint_descriptor *endpoint;
tmp = ifp->bNumEndpoints * sizeof(struct libusb_endpoint_descriptor); endpoint = calloc(ifp->bNumEndpoints, sizeof(struct libusb_endpoint_descriptor));
endpoint = malloc(tmp);
ifp->endpoint = endpoint; ifp->endpoint = endpoint;
if (!endpoint) { if (!endpoint) {
r = LIBUSB_ERROR_NO_MEM; r = LIBUSB_ERROR_NO_MEM;
goto err; goto err;
} }
memset(endpoint, 0, tmp);
for (i = 0; i < ifp->bNumEndpoints; i++) { for (i = 0; i < ifp->bNumEndpoints; i++) {
r = parse_endpoint(ctx, endpoint + i, buffer, size, r = parse_endpoint(ctx, endpoint + i, buffer, size,
host_endian); host_endian);
@ -364,14 +358,13 @@ err:
static void clear_configuration(struct libusb_config_descriptor *config) static void clear_configuration(struct libusb_config_descriptor *config)
{ {
if (config->interface) {
int i; int i;
if (config->interface) {
for (i = 0; i < config->bNumInterfaces; i++) for (i = 0; i < config->bNumInterfaces; i++)
clear_interface((struct libusb_interface *) clear_interface((struct libusb_interface *)
config->interface + i); config->interface + i);
free((void *) config->interface);
} }
if (config->extra) free((void *) config->interface);
free((void *) config->extra); free((void *) config->extra);
} }
@ -381,7 +374,6 @@ static int parse_configuration(struct libusb_context *ctx,
{ {
int i; int i;
int r; int r;
size_t tmp;
struct usb_descriptor_header header; struct usb_descriptor_header header;
struct libusb_interface *usb_interface; struct libusb_interface *usb_interface;
@ -411,13 +403,11 @@ static int parse_configuration(struct libusb_context *ctx,
return LIBUSB_ERROR_IO; return LIBUSB_ERROR_IO;
} }
tmp = config->bNumInterfaces * sizeof(struct libusb_interface); usb_interface = calloc(config->bNumInterfaces, sizeof(struct libusb_interface));
usb_interface = malloc(tmp);
config->interface = usb_interface; config->interface = usb_interface;
if (!config->interface) if (!usb_interface)
return LIBUSB_ERROR_NO_MEM; return LIBUSB_ERROR_NO_MEM;
memset(usb_interface, 0, tmp);
buffer += config->bLength; buffer += config->bLength;
size -= config->bLength; size -= config->bLength;
@ -538,7 +528,7 @@ int usbi_device_cache_descriptor(libusb_device *dev)
return LIBUSB_SUCCESS; return LIBUSB_SUCCESS;
} }
/** \ingroup desc /** \ingroup libusb_desc
* Get the USB device descriptor for a given device. * Get the USB device descriptor for a given device.
* *
* This is a non-blocking function; the device descriptor is cached in memory. * This is a non-blocking function; the device descriptor is cached in memory.
@ -559,7 +549,7 @@ int API_EXPORTED libusb_get_device_descriptor(libusb_device *dev,
return 0; return 0;
} }
/** \ingroup desc /** \ingroup libusb_desc
* Get the USB configuration descriptor for the currently active configuration. * Get the USB configuration descriptor for the currently active configuration.
* This is a non-blocking function which does not involve any requests being * This is a non-blocking function which does not involve any requests being
* sent to the device. * sent to the device.
@ -606,7 +596,7 @@ int API_EXPORTED libusb_get_active_config_descriptor(libusb_device *dev,
return r; return r;
} }
/** \ingroup desc /** \ingroup libusb_desc
* Get a USB configuration descriptor based on its index. * Get a USB configuration descriptor based on its index.
* This is a non-blocking function which does not involve any requests being * This is a non-blocking function which does not involve any requests being
* sent to the device. * sent to the device.
@ -689,7 +679,7 @@ int usbi_get_config_index_by_value(struct libusb_device *dev,
return 0; return 0;
} }
/** \ingroup desc /** \ingroup libusb_desc
* Get a USB configuration descriptor with a specific bConfigurationValue. * Get a USB configuration descriptor with a specific bConfigurationValue.
* This is a non-blocking function which does not involve any requests being * This is a non-blocking function which does not involve any requests being
* sent to the device. * sent to the device.
@ -729,7 +719,7 @@ int API_EXPORTED libusb_get_config_descriptor_by_value(libusb_device *dev,
return libusb_get_config_descriptor(dev, (uint8_t) idx, config); return libusb_get_config_descriptor(dev, (uint8_t) idx, config);
} }
/** \ingroup desc /** \ingroup libusb_desc
* Free a configuration descriptor obtained from * Free a configuration descriptor obtained from
* libusb_get_active_config_descriptor() or libusb_get_config_descriptor(). * libusb_get_active_config_descriptor() or libusb_get_config_descriptor().
* It is safe to call this function with a NULL config parameter, in which * It is safe to call this function with a NULL config parameter, in which
@ -747,7 +737,7 @@ void API_EXPORTED libusb_free_config_descriptor(
free(config); free(config);
} }
/** \ingroup desc /** \ingroup libusb_desc
* Get an endpoints superspeed endpoint companion descriptor (if any) * Get an endpoints superspeed endpoint companion descriptor (if any)
* *
* \param ctx the context to operate on, or NULL for the default context * \param ctx the context to operate on, or NULL for the default context
@ -797,7 +787,7 @@ int API_EXPORTED libusb_get_ss_endpoint_companion_descriptor(
return LIBUSB_ERROR_NOT_FOUND; return LIBUSB_ERROR_NOT_FOUND;
} }
/** \ingroup desc /** \ingroup libusb_desc
* Free a superspeed endpoint companion descriptor obtained from * Free a superspeed endpoint companion descriptor obtained from
* libusb_get_ss_endpoint_companion_descriptor(). * libusb_get_ss_endpoint_companion_descriptor().
* It is safe to call this function with a NULL ep_comp parameter, in which * It is safe to call this function with a NULL ep_comp parameter, in which
@ -890,18 +880,18 @@ static int parse_bos(struct libusb_context *ctx,
return LIBUSB_SUCCESS; return LIBUSB_SUCCESS;
} }
/** \ingroup desc /** \ingroup libusb_desc
* Get a Binary Object Store (BOS) descriptor * Get a Binary Object Store (BOS) descriptor
* This is a BLOCKING function, which will send requests to the device. * This is a BLOCKING function, which will send requests to the device.
* *
* \param handle the handle of an open libusb device * \param dev_handle the handle of an open libusb device
* \param bos output location for the BOS descriptor. Only valid if 0 was returned. * \param bos output location for the BOS descriptor. Only valid if 0 was returned.
* Must be freed with \ref libusb_free_bos_descriptor() after use. * Must be freed with \ref libusb_free_bos_descriptor() after use.
* \returns 0 on success * \returns 0 on success
* \returns LIBUSB_ERROR_NOT_FOUND if the device doesn't have a BOS descriptor * \returns LIBUSB_ERROR_NOT_FOUND if the device doesn't have a BOS descriptor
* \returns another LIBUSB_ERROR code on error * \returns another LIBUSB_ERROR code on error
*/ */
int API_EXPORTED libusb_get_bos_descriptor(libusb_device_handle *handle, int API_EXPORTED libusb_get_bos_descriptor(libusb_device_handle *dev_handle,
struct libusb_bos_descriptor **bos) struct libusb_bos_descriptor **bos)
{ {
struct libusb_bos_descriptor _bos; struct libusb_bos_descriptor _bos;
@ -912,15 +902,15 @@ int API_EXPORTED libusb_get_bos_descriptor(libusb_device_handle *handle,
/* Read the BOS. This generates 2 requests on the bus, /* Read the BOS. This generates 2 requests on the bus,
* one for the header, and one for the full BOS */ * one for the header, and one for the full BOS */
r = libusb_get_descriptor(handle, LIBUSB_DT_BOS, 0, bos_header, r = libusb_get_descriptor(dev_handle, LIBUSB_DT_BOS, 0, bos_header,
LIBUSB_DT_BOS_SIZE); LIBUSB_DT_BOS_SIZE);
if (r < 0) { if (r < 0) {
if (r != LIBUSB_ERROR_PIPE) if (r != LIBUSB_ERROR_PIPE)
usbi_err(handle->dev->ctx, "failed to read BOS (%d)", r); usbi_err(HANDLE_CTX(dev_handle), "failed to read BOS (%d)", r);
return r; return r;
} }
if (r < LIBUSB_DT_BOS_SIZE) { if (r < LIBUSB_DT_BOS_SIZE) {
usbi_err(handle->dev->ctx, "short BOS read %d/%d", usbi_err(HANDLE_CTX(dev_handle), "short BOS read %d/%d",
r, LIBUSB_DT_BOS_SIZE); r, LIBUSB_DT_BOS_SIZE);
return LIBUSB_ERROR_IO; return LIBUSB_ERROR_IO;
} }
@ -932,18 +922,18 @@ int API_EXPORTED libusb_get_bos_descriptor(libusb_device_handle *handle,
if (bos_data == NULL) if (bos_data == NULL)
return LIBUSB_ERROR_NO_MEM; return LIBUSB_ERROR_NO_MEM;
r = libusb_get_descriptor(handle, LIBUSB_DT_BOS, 0, bos_data, r = libusb_get_descriptor(dev_handle, LIBUSB_DT_BOS, 0, bos_data,
_bos.wTotalLength); _bos.wTotalLength);
if (r >= 0) if (r >= 0)
r = parse_bos(handle->dev->ctx, bos, bos_data, r, host_endian); r = parse_bos(HANDLE_CTX(dev_handle), bos, bos_data, r, host_endian);
else else
usbi_err(handle->dev->ctx, "failed to read BOS (%d)", r); usbi_err(HANDLE_CTX(dev_handle), "failed to read BOS (%d)", r);
free(bos_data); free(bos_data);
return r; return r;
} }
/** \ingroup desc /** \ingroup libusb_desc
* Free a BOS descriptor obtained from libusb_get_bos_descriptor(). * Free a BOS descriptor obtained from libusb_get_bos_descriptor().
* It is safe to call this function with a NULL bos parameter, in which * It is safe to call this function with a NULL bos parameter, in which
* case the function simply returns. * case the function simply returns.
@ -962,7 +952,7 @@ void API_EXPORTED libusb_free_bos_descriptor(struct libusb_bos_descriptor *bos)
free(bos); free(bos);
} }
/** \ingroup desc /** \ingroup libusb_desc
* Get an USB 2.0 Extension descriptor * Get an USB 2.0 Extension descriptor
* *
* \param ctx the context to operate on, or NULL for the default context * \param ctx the context to operate on, or NULL for the default context
@ -1006,7 +996,7 @@ int API_EXPORTED libusb_get_usb_2_0_extension_descriptor(
return LIBUSB_SUCCESS; return LIBUSB_SUCCESS;
} }
/** \ingroup desc /** \ingroup libusb_desc
* Free a USB 2.0 Extension descriptor obtained from * Free a USB 2.0 Extension descriptor obtained from
* libusb_get_usb_2_0_extension_descriptor(). * libusb_get_usb_2_0_extension_descriptor().
* It is safe to call this function with a NULL usb_2_0_extension parameter, * It is safe to call this function with a NULL usb_2_0_extension parameter,
@ -1020,7 +1010,7 @@ void API_EXPORTED libusb_free_usb_2_0_extension_descriptor(
free(usb_2_0_extension); free(usb_2_0_extension);
} }
/** \ingroup desc /** \ingroup libusb_desc
* Get a SuperSpeed USB Device Capability descriptor * Get a SuperSpeed USB Device Capability descriptor
* *
* \param ctx the context to operate on, or NULL for the default context * \param ctx the context to operate on, or NULL for the default context
@ -1064,7 +1054,7 @@ int API_EXPORTED libusb_get_ss_usb_device_capability_descriptor(
return LIBUSB_SUCCESS; return LIBUSB_SUCCESS;
} }
/** \ingroup desc /** \ingroup libusb_desc
* Free a SuperSpeed USB Device Capability descriptor obtained from * Free a SuperSpeed USB Device Capability descriptor obtained from
* libusb_get_ss_usb_device_capability_descriptor(). * libusb_get_ss_usb_device_capability_descriptor().
* It is safe to call this function with a NULL ss_usb_device_cap * It is safe to call this function with a NULL ss_usb_device_cap
@ -1078,7 +1068,7 @@ void API_EXPORTED libusb_free_ss_usb_device_capability_descriptor(
free(ss_usb_device_cap); free(ss_usb_device_cap);
} }
/** \ingroup desc /** \ingroup libusb_desc
* Get a Container ID descriptor * Get a Container ID descriptor
* *
* \param ctx the context to operate on, or NULL for the default context * \param ctx the context to operate on, or NULL for the default context
@ -1121,7 +1111,7 @@ int API_EXPORTED libusb_get_container_id_descriptor(struct libusb_context *ctx,
return LIBUSB_SUCCESS; return LIBUSB_SUCCESS;
} }
/** \ingroup desc /** \ingroup libusb_desc
* Free a Container ID descriptor obtained from * Free a Container ID descriptor obtained from
* libusb_get_container_id_descriptor(). * libusb_get_container_id_descriptor().
* It is safe to call this function with a NULL container_id parameter, * It is safe to call this function with a NULL container_id parameter,
@ -1135,19 +1125,19 @@ void API_EXPORTED libusb_free_container_id_descriptor(
free(container_id); free(container_id);
} }
/** \ingroup desc /** \ingroup libusb_desc
* Retrieve a string descriptor in C style ASCII. * Retrieve a string descriptor in C style ASCII.
* *
* Wrapper around libusb_get_string_descriptor(). Uses the first language * Wrapper around libusb_get_string_descriptor(). Uses the first language
* supported by the device. * supported by the device.
* *
* \param dev a device handle * \param dev_handle a device handle
* \param desc_index the index of the descriptor to retrieve * \param desc_index the index of the descriptor to retrieve
* \param data output buffer for ASCII string descriptor * \param data output buffer for ASCII string descriptor
* \param length size of data buffer * \param length size of data buffer
* \returns number of bytes returned in data, or LIBUSB_ERROR code on failure * \returns number of bytes returned in data, or LIBUSB_ERROR code on failure
*/ */
int API_EXPORTED libusb_get_string_descriptor_ascii(libusb_device_handle *dev, int API_EXPORTED libusb_get_string_descriptor_ascii(libusb_device_handle *dev_handle,
uint8_t desc_index, unsigned char *data, int length) uint8_t desc_index, unsigned char *data, int length)
{ {
unsigned char tbuf[255]; /* Some devices choke on size > 255 */ unsigned char tbuf[255]; /* Some devices choke on size > 255 */
@ -1166,7 +1156,7 @@ int API_EXPORTED libusb_get_string_descriptor_ascii(libusb_device_handle *dev,
if (desc_index == 0) if (desc_index == 0)
return LIBUSB_ERROR_INVALID_PARAM; return LIBUSB_ERROR_INVALID_PARAM;
r = libusb_get_string_descriptor(dev, 0, 0, tbuf, sizeof(tbuf)); r = libusb_get_string_descriptor(dev_handle, 0, 0, tbuf, sizeof(tbuf));
if (r < 0) if (r < 0)
return r; return r;
@ -1175,7 +1165,7 @@ int API_EXPORTED libusb_get_string_descriptor_ascii(libusb_device_handle *dev,
langid = tbuf[2] | (tbuf[3] << 8); langid = tbuf[2] | (tbuf[3] << 8);
r = libusb_get_string_descriptor(dev, desc_index, langid, tbuf, r = libusb_get_string_descriptor(dev_handle, desc_index, langid, tbuf,
sizeof(tbuf)); sizeof(tbuf));
if (r < 0) if (r < 0)
return r; return r;

View File

@ -34,14 +34,14 @@
#include "hotplug.h" #include "hotplug.h"
/** /**
* @defgroup hotplug Device hotplug event notification * @defgroup libusb_hotplug Device hotplug event notification
* This page details how to use the libusb hotplug interface, where available. * This page details how to use the libusb hotplug interface, where available.
* *
* Be mindful that not all platforms currently implement hotplug notification and * Be mindful that not all platforms currently implement hotplug notification and
* that you should first call on \ref libusb_has_capability() with parameter * that you should first call on \ref libusb_has_capability() with parameter
* \ref LIBUSB_CAP_HAS_HOTPLUG to confirm that hotplug support is available. * \ref LIBUSB_CAP_HAS_HOTPLUG to confirm that hotplug support is available.
* *
* \page hotplug Device hotplug event notification * \page libusb_hotplug Device hotplug event notification
* *
* \section hotplug_intro Introduction * \section hotplug_intro Introduction
* *
@ -55,7 +55,7 @@
* *
* To receive hotplug notification you register a callback by calling * To receive hotplug notification you register a callback by calling
* \ref libusb_hotplug_register_callback(). This function will optionally return * \ref libusb_hotplug_register_callback(). This function will optionally return
* a handle that can be passed to \ref libusb_hotplug_deregister_callback(). * a callback handle that can be passed to \ref libusb_hotplug_deregister_callback().
* *
* A callback function must return an int (0 or 1) indicating whether the callback is * A callback function must return an int (0 or 1) indicating whether the callback is
* expecting additional events. Returning 0 will rearm the callback and 1 will cause * expecting additional events. Returning 0 will rearm the callback and 1 will cause
@ -75,40 +75,47 @@
* *
* Note: If you receive notification that a device has left and you have any * Note: If you receive notification that a device has left and you have any
* a libusb_device_handles for the device it is up to you to call libusb_close() * a libusb_device_handles for the device it is up to you to call libusb_close()
* on each handle to free up any remaining resources associated with the device. * on each device handle to free up any remaining resources associated with the device.
* Once a device has left any libusb_device_handle associated with the device * Once a device has left any libusb_device_handle associated with the device
* are invalid and will remain so even if the device comes back. * are invalid and will remain so even if the device comes back.
* *
* When handling a LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED event it is considered * When handling a LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED event it is considered
* safe to call any libusb function that takes a libusb_device. On the other hand, * safe to call any libusb function that takes a libusb_device. It also safe to
* when handling a LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT event the only safe function * open a device and submit asynchronous transfers. However, most other functions
* that take a libusb_device_handle are <b>not</b> safe to call. Examples of such
* functions are any of the \ref libusb_syncio "synchronous API" functions or the blocking
* functions that retrieve various \ref libusb_desc "USB descriptors". These functions must
* be used outside of the context of the hotplug callback.
*
* When handling a LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT event the only safe function
* is libusb_get_device_descriptor(). * is libusb_get_device_descriptor().
* *
* The following code provides an example of the usage of the hotplug interface: * The following code provides an example of the usage of the hotplug interface:
\code \code
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <time.h>
#include <libusb.h> #include <libusb.h>
static int count = 0; static int count = 0;
int hotplug_callback(struct libusb_context *ctx, struct libusb_device *dev, int hotplug_callback(struct libusb_context *ctx, struct libusb_device *dev,
libusb_hotplug_event event, void *user_data) { libusb_hotplug_event event, void *user_data) {
static libusb_device_handle *handle = NULL; static libusb_device_handle *dev_handle = NULL;
struct libusb_device_descriptor desc; struct libusb_device_descriptor desc;
int rc; int rc;
(void)libusb_get_device_descriptor(dev, &desc); (void)libusb_get_device_descriptor(dev, &desc);
if (LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED == event) { if (LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED == event) {
rc = libusb_open(dev, &handle); rc = libusb_open(dev, &dev_handle);
if (LIBUSB_SUCCESS != rc) { if (LIBUSB_SUCCESS != rc) {
printf("Could not open USB device\n"); printf("Could not open USB device\n");
} }
} else if (LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT == event) { } else if (LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT == event) {
if (handle) { if (dev_handle) {
libusb_close(handle); libusb_close(dev_handle);
handle = NULL; dev_handle = NULL;
} }
} else { } else {
printf("Unhandled event %d\n", event); printf("Unhandled event %d\n", event);
@ -119,7 +126,7 @@ int hotplug_callback(struct libusb_context *ctx, struct libusb_device *dev,
} }
int main (void) { int main (void) {
libusb_hotplug_callback_handle handle; libusb_hotplug_callback_handle callback_handle;
int rc; int rc;
libusb_init(NULL); libusb_init(NULL);
@ -127,7 +134,7 @@ int main (void) {
rc = libusb_hotplug_register_callback(NULL, LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED | rc = libusb_hotplug_register_callback(NULL, LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED |
LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT, 0, 0x045a, 0x5005, LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT, 0, 0x045a, 0x5005,
LIBUSB_HOTPLUG_MATCH_ANY, hotplug_callback, NULL, LIBUSB_HOTPLUG_MATCH_ANY, hotplug_callback, NULL,
&handle); &callback_handle);
if (LIBUSB_SUCCESS != rc) { if (LIBUSB_SUCCESS != rc) {
printf("Error creating a hotplug callback\n"); printf("Error creating a hotplug callback\n");
libusb_exit(NULL); libusb_exit(NULL);
@ -136,10 +143,10 @@ int main (void) {
while (count < 2) { while (count < 2) {
libusb_handle_events_completed(NULL, NULL); libusb_handle_events_completed(NULL, NULL);
usleep(10000); nanosleep(&(struct timespec){0, 10000000UL}, NULL);
} }
libusb_hotplug_deregister_callback(NULL, handle); libusb_hotplug_deregister_callback(NULL, callback_handle);
libusb_exit(NULL); libusb_exit(NULL);
return 0; return 0;
@ -231,7 +238,7 @@ int API_EXPORTED libusb_hotplug_register_callback(libusb_context *ctx,
libusb_hotplug_event events, libusb_hotplug_flag flags, libusb_hotplug_event events, libusb_hotplug_flag flags,
int vendor_id, int product_id, int dev_class, int vendor_id, int product_id, int dev_class,
libusb_hotplug_callback_fn cb_fn, void *user_data, libusb_hotplug_callback_fn cb_fn, void *user_data,
libusb_hotplug_callback_handle *handle) libusb_hotplug_callback_handle *callback_handle)
{ {
libusb_hotplug_callback *new_callback; libusb_hotplug_callback *new_callback;
static int handle_id = 1; static int handle_id = 1;
@ -298,15 +305,14 @@ int API_EXPORTED libusb_hotplug_register_callback(libusb_context *ctx,
} }
if (handle) { if (callback_handle)
*handle = new_callback->handle; *callback_handle = new_callback->handle;
}
return LIBUSB_SUCCESS; return LIBUSB_SUCCESS;
} }
void API_EXPORTED libusb_hotplug_deregister_callback (struct libusb_context *ctx, void API_EXPORTED libusb_hotplug_deregister_callback (struct libusb_context *ctx,
libusb_hotplug_callback_handle handle) libusb_hotplug_callback_handle callback_handle)
{ {
struct libusb_hotplug_callback *hotplug_cb; struct libusb_hotplug_callback *hotplug_cb;
@ -320,7 +326,7 @@ void API_EXPORTED libusb_hotplug_deregister_callback (struct libusb_context *ctx
usbi_mutex_lock(&ctx->hotplug_cbs_lock); usbi_mutex_lock(&ctx->hotplug_cbs_lock);
list_for_each_entry(hotplug_cb, &ctx->hotplug_cbs, list, list_for_each_entry(hotplug_cb, &ctx->hotplug_cbs, list,
struct libusb_hotplug_callback) { struct libusb_hotplug_callback) {
if (handle == hotplug_cb->handle) { if (callback_handle == hotplug_cb->handle) {
/* Mark this callback for deregistration */ /* Mark this callback for deregistration */
hotplug_cb->needs_free = 1; hotplug_cb->needs_free = 1;
} }

View File

@ -41,7 +41,7 @@
#include "hotplug.h" #include "hotplug.h"
/** /**
* \page io Synchronous and asynchronous device I/O * \page libusb_io Synchronous and asynchronous device I/O
* *
* \section io_intro Introduction * \section io_intro Introduction
* *
@ -55,8 +55,8 @@
* *
* Once you have read through the following discussion, you should consult the * Once you have read through the following discussion, you should consult the
* detailed API documentation pages for the details: * detailed API documentation pages for the details:
* - \ref syncio * - \ref libusb_syncio
* - \ref asyncio * - \ref libusb_asyncio
* *
* \section theory Transfers at a logical level * \section theory Transfers at a logical level
* *
@ -97,7 +97,7 @@
\code \code
unsigned char data[4]; unsigned char data[4];
int actual_length; int actual_length;
int r = libusb_bulk_transfer(handle, LIBUSB_ENDPOINT_IN, data, sizeof(data), &actual_length, 0); int r = libusb_bulk_transfer(dev_handle, LIBUSB_ENDPOINT_IN, data, sizeof(data), &actual_length, 0);
if (r == 0 && actual_length == sizeof(data)) { if (r == 0 && actual_length == sizeof(data)) {
// results of the transaction can now be found in the data buffer // results of the transaction can now be found in the data buffer
// parse them here and report button press // parse them here and report button press
@ -124,7 +124,7 @@ if (r == 0 && actual_length == sizeof(data)) {
* request has been submitted. * request has been submitted.
* *
* For details on how to use the synchronous API, see the * For details on how to use the synchronous API, see the
* \ref syncio "synchronous I/O API documentation" pages. * \ref libusb_syncio "synchronous I/O API documentation" pages.
* *
* \section async The asynchronous interface * \section async The asynchronous interface
* *
@ -165,12 +165,12 @@ if (r == 0 && actual_length == sizeof(data)) {
* calls to the asynchronous interface. * calls to the asynchronous interface.
* *
* For details on how to use the asynchronous API, see the * For details on how to use the asynchronous API, see the
* \ref asyncio "asynchronous I/O API" documentation pages. * \ref libusb_asyncio "asynchronous I/O API" documentation pages.
*/ */
/** /**
* \page packetoverflow Packets and overflows * \page libusb_packetoverflow Packets and overflows
* *
* \section packets Packet abstraction * \section packets Packet abstraction
* *
@ -212,13 +212,13 @@ if (r == 0 && actual_length == sizeof(data)) {
*/ */
/** /**
* @defgroup asyncio Asynchronous device I/O * @defgroup libusb_asyncio Asynchronous device I/O
* *
* This page details libusb's asynchronous (non-blocking) API for USB device * This page details libusb's asynchronous (non-blocking) API for USB device
* I/O. This interface is very powerful but is also quite complex - you will * I/O. This interface is very powerful but is also quite complex - you will
* need to read this page carefully to understand the necessary considerations * need to read this page carefully to understand the necessary considerations
* and issues surrounding use of this interface. Simplistic applications * and issues surrounding use of this interface. Simplistic applications
* may wish to consider the \ref syncio "synchronous I/O API" instead. * may wish to consider the \ref libusb_syncio "synchronous I/O API" instead.
* *
* The asynchronous interface is built around the idea of separating transfer * The asynchronous interface is built around the idea of separating transfer
* submission and handling of transfer completion (the synchronous model * submission and handling of transfer completion (the synchronous model
@ -293,6 +293,12 @@ if (r == 0 && actual_length == sizeof(data)) {
* success or failure reason, number of bytes of data transferred, etc. See * success or failure reason, number of bytes of data transferred, etc. See
* the libusb_transfer structure documentation for more information. * the libusb_transfer structure documentation for more information.
* *
* <b>Important Note</b>: The user-specified callback is called from an event
* handling context. It is therefore important that no calls are made into
* libusb that will attempt to perform any event handling. Examples of such
* functions are any listed in the \ref libusb_syncio "synchronous API" and any of
* the blocking functions that retrieve \ref libusb_desc "USB descriptors".
*
* \subsection Deallocation * \subsection Deallocation
* *
* When a transfer has completed (i.e. the callback function has been invoked), * When a transfer has completed (i.e. the callback function has been invoked),
@ -337,7 +343,7 @@ if (r == 0 && actual_length == sizeof(data)) {
* your application may submit a request for data on an IN endpoint which is * your application may submit a request for data on an IN endpoint which is
* smaller than the data that the device wishes to send. In some circumstances * smaller than the data that the device wishes to send. In some circumstances
* this will cause an overflow, which is a nasty condition to deal with. See * this will cause an overflow, which is a nasty condition to deal with. See
* the \ref packetoverflow page for discussion. * the \ref libusb_packetoverflow page for discussion.
* *
* \section asyncctrl Considerations for control transfers * \section asyncctrl Considerations for control transfers
* *
@ -528,7 +534,7 @@ if (r == 0 && actual_length == sizeof(data)) {
* below for details. * below for details.
* *
* If you prefer a single threaded approach with a single central event loop, * If you prefer a single threaded approach with a single central event loop,
* see the \ref poll "polling and timing" section for how to integrate libusb * see the \ref libusb_poll "polling and timing" section for how to integrate libusb
* into your application's main event loop. * into your application's main event loop.
* *
* \section eventthread Using an event handling thread * \section eventthread Using an event handling thread
@ -555,18 +561,18 @@ void *event_thread_func(void *ctx)
* libusb_handle_events() will not return. * libusb_handle_events() will not return.
* *
* There are 2 different ways of dealing with this, depending on if your * There are 2 different ways of dealing with this, depending on if your
* application uses libusb' \ref hotplug "hotplug" support or not. * application uses libusb' \ref libusb_hotplug "hotplug" support or not.
* *
* Applications which do not use hotplug support, should not start the event * Applications which do not use hotplug support, should not start the event
* thread until after their first call to libusb_open(), and should stop the * thread until after their first call to libusb_open(), and should stop the
* thread when closing the last open device as follows: * thread when closing the last open device as follows:
\code \code
void my_close_handle(libusb_device_handle *handle) void my_close_handle(libusb_device_handle *dev_handle)
{ {
if (open_devs == 1) if (open_devs == 1)
event_thread_run = 0; event_thread_run = 0;
libusb_close(handle); // This wakes up libusb_handle_events() libusb_close(dev_handle); // This wakes up libusb_handle_events()
if (open_devs == 1) if (open_devs == 1)
pthread_join(event_thread); pthread_join(event_thread);
@ -590,12 +596,12 @@ void my_libusb_exit(void)
*/ */
/** /**
* @defgroup poll Polling and timing * @defgroup libusb_poll Polling and timing
* *
* This page documents libusb's functions for polling events and timing. * This page documents libusb's functions for polling events and timing.
* These functions are only necessary for users of the * These functions are only necessary for users of the
* \ref asyncio "asynchronous API". If you are only using the simpler * \ref libusb_asyncio "asynchronous API". If you are only using the simpler
* \ref syncio "synchronous API" then you do not need to ever call these * \ref libusb_syncio "synchronous API" then you do not need to ever call these
* functions. * functions.
* *
* The justification for the functionality described here has already been * The justification for the functionality described here has already been
@ -647,7 +653,7 @@ while (user_has_not_requested_exit)
* sets of file descriptors or handling timeouts. libusb_handle_events() will * sets of file descriptors or handling timeouts. libusb_handle_events() will
* handle those details internally. * handle those details internally.
* *
* \section pollmain The more advanced option * \section libusb_pollmain The more advanced option
* *
* \note This functionality is currently only available on Unix-like platforms. * \note This functionality is currently only available on Unix-like platforms.
* On Windows, libusb_get_pollfds() simply returns NULL. Applications which * On Windows, libusb_get_pollfds() simply returns NULL. Applications which
@ -762,10 +768,10 @@ while (user has not requested application exit) {
* entities are added to solve these problems. You do not need to be concerned * entities are added to solve these problems. You do not need to be concerned
* with these entities otherwise. * with these entities otherwise.
* *
* See the extra documentation: \ref mtasync * See the extra documentation: \ref libusb_mtasync
*/ */
/** \page mtasync Multi-threaded applications and asynchronous I/O /** \page libusb_mtasync Multi-threaded applications and asynchronous I/O
* *
* libusb is a thread-safe library, but extra considerations must be applied * libusb is a thread-safe library, but extra considerations must be applied
* to applications which interact with libusb from multiple threads. * to applications which interact with libusb from multiple threads.
@ -773,8 +779,8 @@ while (user has not requested application exit) {
* The underlying issue that must be addressed is that all libusb I/O * The underlying issue that must be addressed is that all libusb I/O
* revolves around monitoring file descriptors through the poll()/select() * revolves around monitoring file descriptors through the poll()/select()
* system calls. This is directly exposed at the * system calls. This is directly exposed at the
* \ref asyncio "asynchronous interface" but it is important to note that the * \ref libusb_asyncio "asynchronous interface" but it is important to note that the
* \ref syncio "synchronous interface" is implemented on top of the * \ref libusb_syncio "synchronous interface" is implemented on top of the
* asynchonrous interface, therefore the same considerations apply. * asynchonrous interface, therefore the same considerations apply.
* *
* The issue is that if two or more threads are concurrently calling poll() * The issue is that if two or more threads are concurrently calling poll()
@ -1101,7 +1107,7 @@ printf("completed!\n");
* (without implementing the rules and locking semantics documented above) * (without implementing the rules and locking semantics documented above)
* and another trying to send a synchronous USB transfer, you will end up with * and another trying to send a synchronous USB transfer, you will end up with
* two threads monitoring the same descriptors, and the above-described * two threads monitoring the same descriptors, and the above-described
* undesirable behaviour occuring. The solution is for your polling thread to * undesirable behaviour occurring. The solution is for your polling thread to
* play by the rules; the synchronous I/O functions do so, and this will result * play by the rules; the synchronous I/O functions do so, and this will result
* in them getting along in perfect harmony. * in them getting along in perfect harmony.
* *
@ -1118,11 +1124,12 @@ int usbi_io_init(struct libusb_context *ctx)
{ {
int r; int r;
usbi_mutex_init(&ctx->flying_transfers_lock, NULL); usbi_mutex_init(&ctx->flying_transfers_lock);
usbi_mutex_init_recursive(&ctx->events_lock, NULL); usbi_mutex_init(&ctx->events_lock);
usbi_mutex_init(&ctx->event_waiters_lock, NULL); usbi_mutex_init(&ctx->event_waiters_lock);
usbi_cond_init(&ctx->event_waiters_cond, NULL); usbi_cond_init(&ctx->event_waiters_cond);
usbi_mutex_init(&ctx->event_data_lock, NULL); usbi_mutex_init(&ctx->event_data_lock);
usbi_tls_key_create(&ctx->event_handling_key);
list_init(&ctx->flying_transfers); list_init(&ctx->flying_transfers);
list_init(&ctx->ipollfds); list_init(&ctx->ipollfds);
list_init(&ctx->hotplug_msgs); list_init(&ctx->hotplug_msgs);
@ -1169,6 +1176,7 @@ err:
usbi_mutex_destroy(&ctx->event_waiters_lock); usbi_mutex_destroy(&ctx->event_waiters_lock);
usbi_cond_destroy(&ctx->event_waiters_cond); usbi_cond_destroy(&ctx->event_waiters_cond);
usbi_mutex_destroy(&ctx->event_data_lock); usbi_mutex_destroy(&ctx->event_data_lock);
usbi_tls_key_delete(ctx->event_handling_key);
return r; return r;
} }
@ -1188,6 +1196,7 @@ void usbi_io_exit(struct libusb_context *ctx)
usbi_mutex_destroy(&ctx->event_waiters_lock); usbi_mutex_destroy(&ctx->event_waiters_lock);
usbi_cond_destroy(&ctx->event_waiters_cond); usbi_cond_destroy(&ctx->event_waiters_cond);
usbi_mutex_destroy(&ctx->event_data_lock); usbi_mutex_destroy(&ctx->event_data_lock);
usbi_tls_key_delete(ctx->event_handling_key);
if (ctx->pollfds) if (ctx->pollfds)
free(ctx->pollfds); free(ctx->pollfds);
} }
@ -1221,7 +1230,7 @@ static int calculate_timeout(struct usbi_transfer *transfer)
return 0; return 0;
} }
/** \ingroup asyncio /** \ingroup libusb_asyncio
* Allocate a libusb transfer with a specified number of isochronous packet * Allocate a libusb transfer with a specified number of isochronous packet
* descriptors. The returned transfer is pre-initialized for you. When the new * descriptors. The returned transfer is pre-initialized for you. When the new
* transfer is no longer needed, it should be freed with * transfer is no longer needed, it should be freed with
@ -1259,14 +1268,13 @@ struct libusb_transfer * LIBUSB_CALL libusb_alloc_transfer(
return NULL; return NULL;
itransfer->num_iso_packets = iso_packets; itransfer->num_iso_packets = iso_packets;
usbi_mutex_init(&itransfer->lock, NULL); usbi_mutex_init(&itransfer->lock);
usbi_mutex_init(&itransfer->flags_lock, NULL);
transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
usbi_dbg("transfer %p", transfer); usbi_dbg("transfer %p", transfer);
return transfer; return transfer;
} }
/** \ingroup asyncio /** \ingroup libusb_asyncio
* Free a transfer structure. This should be called for all transfers * Free a transfer structure. This should be called for all transfers
* allocated with libusb_alloc_transfer(). * allocated with libusb_alloc_transfer().
* *
@ -1295,7 +1303,6 @@ void API_EXPORTED libusb_free_transfer(struct libusb_transfer *transfer)
itransfer = LIBUSB_TRANSFER_TO_USBI_TRANSFER(transfer); itransfer = LIBUSB_TRANSFER_TO_USBI_TRANSFER(transfer);
usbi_mutex_destroy(&itransfer->lock); usbi_mutex_destroy(&itransfer->lock);
usbi_mutex_destroy(&itransfer->flags_lock);
free(itransfer); free(itransfer);
} }
@ -1330,8 +1337,8 @@ static int arm_timerfd_for_next_timeout(struct libusb_context *ctx)
if (!timerisset(cur_tv)) if (!timerisset(cur_tv))
goto disarm; goto disarm;
/* act on first transfer that is not already cancelled */ /* act on first transfer that has not already been handled */
if (!(transfer->flags & USBI_TRANSFER_TIMEOUT_HANDLED)) { if (!(transfer->timeout_flags & (USBI_TRANSFER_TIMEOUT_HANDLED | USBI_TRANSFER_OS_HANDLES_TIMEOUT))) {
int r; int r;
const struct itimerspec it = { {0, 0}, const struct itimerspec it = { {0, 0},
{ cur_tv->tv_sec, cur_tv->tv_usec * 1000 } }; { cur_tv->tv_sec, cur_tv->tv_usec * 1000 } };
@ -1349,7 +1356,7 @@ disarm:
#else #else
static int arm_timerfd_for_next_timeout(struct libusb_context *ctx) static int arm_timerfd_for_next_timeout(struct libusb_context *ctx)
{ {
(void)ctx; UNUSED(ctx);
return 0; return 0;
} }
#endif #endif
@ -1362,10 +1369,12 @@ static int add_to_flying_list(struct usbi_transfer *transfer)
struct usbi_transfer *cur; struct usbi_transfer *cur;
struct timeval *timeout = &transfer->timeout; struct timeval *timeout = &transfer->timeout;
struct libusb_context *ctx = ITRANSFER_CTX(transfer); struct libusb_context *ctx = ITRANSFER_CTX(transfer);
int r = 0; int r;
int first = 1; int first = 1;
usbi_mutex_lock(&ctx->flying_transfers_lock); r = calculate_timeout(transfer);
if (r)
return r;
/* if we have no other flying transfers, start the list with this one */ /* if we have no other flying transfers, start the list with this one */
if (list_empty(&ctx->flying_transfers)) { if (list_empty(&ctx->flying_transfers)) {
@ -1419,7 +1428,6 @@ out:
if (r) if (r)
list_del(&transfer->list); list_del(&transfer->list);
usbi_mutex_unlock(&ctx->flying_transfers_lock);
return r; return r;
} }
@ -1444,7 +1452,7 @@ static int remove_from_flying_list(struct usbi_transfer *transfer)
return r; return r;
} }
/** \ingroup asyncio /** \ingroup libusb_asyncio
* Submit a transfer. This function will fire off the USB transfer and then * Submit a transfer. This function will fire off the USB transfer and then
* return immediately. * return immediately.
* *
@ -1454,72 +1462,88 @@ static int remove_from_flying_list(struct usbi_transfer *transfer)
* \returns LIBUSB_ERROR_BUSY if the transfer has already been submitted. * \returns LIBUSB_ERROR_BUSY if the transfer has already been submitted.
* \returns LIBUSB_ERROR_NOT_SUPPORTED if the transfer flags are not supported * \returns LIBUSB_ERROR_NOT_SUPPORTED if the transfer flags are not supported
* by the operating system. * by the operating system.
* \returns LIBUSB_ERROR_INVALID_PARAM if the transfer size is larger than
* the operating system and/or hardware can support
* \returns another LIBUSB_ERROR code on other failure * \returns another LIBUSB_ERROR code on other failure
*/ */
int API_EXPORTED libusb_submit_transfer(struct libusb_transfer *transfer) int API_EXPORTED libusb_submit_transfer(struct libusb_transfer *transfer)
{ {
struct usbi_transfer *itransfer = struct usbi_transfer *itransfer =
LIBUSB_TRANSFER_TO_USBI_TRANSFER(transfer); LIBUSB_TRANSFER_TO_USBI_TRANSFER(transfer);
int remove = 0; struct libusb_context *ctx = TRANSFER_CTX(transfer);
int r; int r;
usbi_dbg("transfer %p", transfer); usbi_dbg("transfer %p", transfer);
/*
* Important note on locking, this function takes / releases locks
* in the following order:
* take flying_transfers_lock
* take itransfer->lock
* clear transfer
* add to flying_transfers list
* release flying_transfers_lock
* submit transfer
* release itransfer->lock
* if submit failed:
* take flying_transfers_lock
* remove from flying_transfers list
* release flying_transfers_lock
*
* Note that it takes locks in the order a-b and then releases them
* in the same order a-b. This is somewhat unusual but not wrong,
* release order is not important as long as *all* locks are released
* before re-acquiring any locks.
*
* This means that the ordering of first releasing itransfer->lock
* and then re-acquiring the flying_transfers_list on error is
* important and must not be changed!
*
* This is done this way because when we take both locks we must always
* take flying_transfers_lock first to avoid ab-ba style deadlocks with
* the timeout handling and usbi_handle_disconnect paths.
*
* And we cannot release itransfer->lock before the submission is
* complete otherwise timeout handling for transfers with short
* timeouts may run before submission.
*/
usbi_mutex_lock(&ctx->flying_transfers_lock);
usbi_mutex_lock(&itransfer->lock); usbi_mutex_lock(&itransfer->lock);
usbi_mutex_lock(&itransfer->flags_lock); if (itransfer->state_flags & USBI_TRANSFER_IN_FLIGHT) {
if (itransfer->flags & USBI_TRANSFER_IN_FLIGHT) { usbi_mutex_unlock(&ctx->flying_transfers_lock);
r = LIBUSB_ERROR_BUSY; usbi_mutex_unlock(&itransfer->lock);
goto out; return LIBUSB_ERROR_BUSY;
} }
itransfer->transferred = 0; itransfer->transferred = 0;
itransfer->flags = 0; itransfer->state_flags = 0;
r = calculate_timeout(itransfer); itransfer->timeout_flags = 0;
if (r < 0) {
r = LIBUSB_ERROR_OTHER;
goto out;
}
itransfer->flags |= USBI_TRANSFER_SUBMITTING;
usbi_mutex_unlock(&itransfer->flags_lock);
r = add_to_flying_list(itransfer); r = add_to_flying_list(itransfer);
if (r) { if (r) {
usbi_mutex_lock(&itransfer->flags_lock); usbi_mutex_unlock(&ctx->flying_transfers_lock);
itransfer->flags = 0;
goto out;
}
/* keep a reference to this device */
libusb_ref_device(transfer->dev_handle->dev);
r = usbi_backend->submit_transfer(itransfer);
usbi_mutex_lock(&itransfer->flags_lock);
itransfer->flags &= ~USBI_TRANSFER_SUBMITTING;
if (r == LIBUSB_SUCCESS) {
/* check for two possible special conditions:
* 1) device disconnect occurred immediately after submission
* 2) transfer completed before we got here to update the flags
*/
if (itransfer->flags & USBI_TRANSFER_DEVICE_DISAPPEARED) {
usbi_backend->clear_transfer_priv(itransfer);
remove = 1;
r = LIBUSB_ERROR_NO_DEVICE;
}
else if (!(itransfer->flags & USBI_TRANSFER_COMPLETED)) {
itransfer->flags |= USBI_TRANSFER_IN_FLIGHT;
}
} else {
remove = 1;
}
out:
usbi_mutex_unlock(&itransfer->flags_lock);
if (remove) {
libusb_unref_device(transfer->dev_handle->dev);
remove_from_flying_list(itransfer);
}
usbi_mutex_unlock(&itransfer->lock); usbi_mutex_unlock(&itransfer->lock);
return r; return r;
} }
/*
* We must release the flying transfers lock here, because with
* some backends the submit_transfer method is synchroneous.
*/
usbi_mutex_unlock(&ctx->flying_transfers_lock);
/** \ingroup asyncio r = usbi_backend->submit_transfer(itransfer);
if (r == LIBUSB_SUCCESS) {
itransfer->state_flags |= USBI_TRANSFER_IN_FLIGHT;
/* keep a reference to this device */
libusb_ref_device(transfer->dev_handle->dev);
}
usbi_mutex_unlock(&itransfer->lock);
if (r != LIBUSB_SUCCESS)
remove_from_flying_list(itransfer);
return r;
}
/** \ingroup libusb_asyncio
* Asynchronously cancel a previously submitted transfer. * Asynchronously cancel a previously submitted transfer.
* This function returns immediately, but this does not indicate cancellation * This function returns immediately, but this does not indicate cancellation
* is complete. Your callback function will be invoked at some later time * is complete. Your callback function will be invoked at some later time
@ -1541,9 +1565,8 @@ int API_EXPORTED libusb_cancel_transfer(struct libusb_transfer *transfer)
usbi_dbg("transfer %p", transfer ); usbi_dbg("transfer %p", transfer );
usbi_mutex_lock(&itransfer->lock); usbi_mutex_lock(&itransfer->lock);
usbi_mutex_lock(&itransfer->flags_lock); if (!(itransfer->state_flags & USBI_TRANSFER_IN_FLIGHT)
if (!(itransfer->flags & USBI_TRANSFER_IN_FLIGHT) || (itransfer->state_flags & USBI_TRANSFER_CANCELLING)) {
|| (itransfer->flags & USBI_TRANSFER_CANCELLING)) {
r = LIBUSB_ERROR_NOT_FOUND; r = LIBUSB_ERROR_NOT_FOUND;
goto out; goto out;
} }
@ -1557,18 +1580,17 @@ int API_EXPORTED libusb_cancel_transfer(struct libusb_transfer *transfer)
usbi_dbg("cancel transfer failed error %d", r); usbi_dbg("cancel transfer failed error %d", r);
if (r == LIBUSB_ERROR_NO_DEVICE) if (r == LIBUSB_ERROR_NO_DEVICE)
itransfer->flags |= USBI_TRANSFER_DEVICE_DISAPPEARED; itransfer->state_flags |= USBI_TRANSFER_DEVICE_DISAPPEARED;
} }
itransfer->flags |= USBI_TRANSFER_CANCELLING; itransfer->state_flags |= USBI_TRANSFER_CANCELLING;
out: out:
usbi_mutex_unlock(&itransfer->flags_lock);
usbi_mutex_unlock(&itransfer->lock); usbi_mutex_unlock(&itransfer->lock);
return r; return r;
} }
/** \ingroup asyncio /** \ingroup libusb_asyncio
* Set a transfers bulk stream id. Note users are advised to use * Set a transfers bulk stream id. Note users are advised to use
* libusb_fill_bulk_stream_transfer() instead of calling this function * libusb_fill_bulk_stream_transfer() instead of calling this function
* directly. * directly.
@ -1588,7 +1610,7 @@ void API_EXPORTED libusb_transfer_set_stream_id(
itransfer->stream_id = stream_id; itransfer->stream_id = stream_id;
} }
/** \ingroup asyncio /** \ingroup libusb_asyncio
* Get a transfers bulk stream id. * Get a transfers bulk stream id.
* *
* Since version 1.0.19, \ref LIBUSB_API_VERSION >= 0x01000103 * Since version 1.0.19, \ref LIBUSB_API_VERSION >= 0x01000103
@ -1618,7 +1640,7 @@ int usbi_handle_transfer_completion(struct usbi_transfer *itransfer,
{ {
struct libusb_transfer *transfer = struct libusb_transfer *transfer =
USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
struct libusb_device_handle *handle = transfer->dev_handle; struct libusb_device_handle *dev_handle = transfer->dev_handle;
uint8_t flags; uint8_t flags;
int r; int r;
@ -1626,10 +1648,9 @@ int usbi_handle_transfer_completion(struct usbi_transfer *itransfer,
if (r < 0) if (r < 0)
usbi_err(ITRANSFER_CTX(itransfer), "failed to set timer for next timeout, errno=%d", errno); usbi_err(ITRANSFER_CTX(itransfer), "failed to set timer for next timeout, errno=%d", errno);
usbi_mutex_lock(&itransfer->flags_lock); usbi_mutex_lock(&itransfer->lock);
itransfer->flags &= ~USBI_TRANSFER_IN_FLIGHT; itransfer->state_flags &= ~USBI_TRANSFER_IN_FLIGHT;
itransfer->flags |= USBI_TRANSFER_COMPLETED; usbi_mutex_unlock(&itransfer->lock);
usbi_mutex_unlock(&itransfer->flags_lock);
if (status == LIBUSB_TRANSFER_COMPLETED if (status == LIBUSB_TRANSFER_COMPLETED
&& transfer->flags & LIBUSB_TRANSFER_SHORT_NOT_OK) { && transfer->flags & LIBUSB_TRANSFER_SHORT_NOT_OK) {
@ -1652,7 +1673,7 @@ int usbi_handle_transfer_completion(struct usbi_transfer *itransfer,
* this point. */ * this point. */
if (flags & LIBUSB_TRANSFER_FREE_TRANSFER) if (flags & LIBUSB_TRANSFER_FREE_TRANSFER)
libusb_free_transfer(transfer); libusb_free_transfer(transfer);
libusb_unref_device(handle->dev); libusb_unref_device(dev_handle->dev);
return r; return r;
} }
@ -1664,8 +1685,15 @@ int usbi_handle_transfer_completion(struct usbi_transfer *itransfer,
* will attempt to take the lock. */ * will attempt to take the lock. */
int usbi_handle_transfer_cancellation(struct usbi_transfer *transfer) int usbi_handle_transfer_cancellation(struct usbi_transfer *transfer)
{ {
struct libusb_context *ctx = ITRANSFER_CTX(transfer);
uint8_t timed_out;
usbi_mutex_lock(&ctx->flying_transfers_lock);
timed_out = transfer->timeout_flags & USBI_TRANSFER_TIMED_OUT;
usbi_mutex_unlock(&ctx->flying_transfers_lock);
/* if the URB was cancelled due to timeout, report timeout to the user */ /* if the URB was cancelled due to timeout, report timeout to the user */
if (transfer->flags & USBI_TRANSFER_TIMED_OUT) { if (timed_out) {
usbi_dbg("detected timeout cancellation"); usbi_dbg("detected timeout cancellation");
return usbi_handle_transfer_completion(transfer, LIBUSB_TRANSFER_TIMED_OUT); return usbi_handle_transfer_completion(transfer, LIBUSB_TRANSFER_TIMED_OUT);
} }
@ -1690,7 +1718,7 @@ void usbi_signal_transfer_completion(struct usbi_transfer *transfer)
usbi_mutex_unlock(&ctx->event_data_lock); usbi_mutex_unlock(&ctx->event_data_lock);
} }
/** \ingroup poll /** \ingroup libusb_poll
* Attempt to acquire the event handling lock. This lock is used to ensure that * Attempt to acquire the event handling lock. This lock is used to ensure that
* only one thread is monitoring libusb event sources at any one time. * only one thread is monitoring libusb event sources at any one time.
* *
@ -1707,7 +1735,7 @@ void usbi_signal_transfer_completion(struct usbi_transfer *transfer)
* \param ctx the context to operate on, or NULL for the default context * \param ctx the context to operate on, or NULL for the default context
* \returns 0 if the lock was obtained successfully * \returns 0 if the lock was obtained successfully
* \returns 1 if the lock was not obtained (i.e. another thread holds the lock) * \returns 1 if the lock was not obtained (i.e. another thread holds the lock)
* \ref mtasync * \ref libusb_mtasync
*/ */
int API_EXPORTED libusb_try_lock_events(libusb_context *ctx) int API_EXPORTED libusb_try_lock_events(libusb_context *ctx)
{ {
@ -1733,7 +1761,7 @@ int API_EXPORTED libusb_try_lock_events(libusb_context *ctx)
return 0; return 0;
} }
/** \ingroup poll /** \ingroup libusb_poll
* Acquire the event handling lock, blocking until successful acquisition if * Acquire the event handling lock, blocking until successful acquisition if
* it is contended. This lock is used to ensure that only one thread is * it is contended. This lock is used to ensure that only one thread is
* monitoring libusb event sources at any one time. * monitoring libusb event sources at any one time.
@ -1749,7 +1777,7 @@ int API_EXPORTED libusb_try_lock_events(libusb_context *ctx)
* as soon as possible. * as soon as possible.
* *
* \param ctx the context to operate on, or NULL for the default context * \param ctx the context to operate on, or NULL for the default context
* \ref mtasync * \ref libusb_mtasync
*/ */
void API_EXPORTED libusb_lock_events(libusb_context *ctx) void API_EXPORTED libusb_lock_events(libusb_context *ctx)
{ {
@ -1758,13 +1786,13 @@ void API_EXPORTED libusb_lock_events(libusb_context *ctx)
ctx->event_handler_active = 1; ctx->event_handler_active = 1;
} }
/** \ingroup poll /** \ingroup libusb_poll
* Release the lock previously acquired with libusb_try_lock_events() or * Release the lock previously acquired with libusb_try_lock_events() or
* libusb_lock_events(). Releasing this lock will wake up any threads blocked * libusb_lock_events(). Releasing this lock will wake up any threads blocked
* on libusb_wait_for_event(). * on libusb_wait_for_event().
* *
* \param ctx the context to operate on, or NULL for the default context * \param ctx the context to operate on, or NULL for the default context
* \ref mtasync * \ref libusb_mtasync
*/ */
void API_EXPORTED libusb_unlock_events(libusb_context *ctx) void API_EXPORTED libusb_unlock_events(libusb_context *ctx)
{ {
@ -1780,7 +1808,7 @@ void API_EXPORTED libusb_unlock_events(libusb_context *ctx)
usbi_mutex_unlock(&ctx->event_waiters_lock); usbi_mutex_unlock(&ctx->event_waiters_lock);
} }
/** \ingroup poll /** \ingroup libusb_poll
* Determine if it is still OK for this thread to be doing event handling. * Determine if it is still OK for this thread to be doing event handling.
* *
* Sometimes, libusb needs to temporarily pause all event handlers, and this * Sometimes, libusb needs to temporarily pause all event handlers, and this
@ -1788,7 +1816,7 @@ void API_EXPORTED libusb_unlock_events(libusb_context *ctx)
* this is the case. * this is the case.
* *
* If this function instructs your thread to give up the events lock, you * If this function instructs your thread to give up the events lock, you
* should just continue the usual logic that is documented in \ref mtasync. * should just continue the usual logic that is documented in \ref libusb_mtasync.
* On the next iteration, your thread will fail to obtain the events lock, * On the next iteration, your thread will fail to obtain the events lock,
* and will hence become an event waiter. * and will hence become an event waiter.
* *
@ -1820,14 +1848,14 @@ int API_EXPORTED libusb_event_handling_ok(libusb_context *ctx)
} }
/** \ingroup poll /** \ingroup libusb_poll
* Determine if an active thread is handling events (i.e. if anyone is holding * Determine if an active thread is handling events (i.e. if anyone is holding
* the event handling lock). * the event handling lock).
* *
* \param ctx the context to operate on, or NULL for the default context * \param ctx the context to operate on, or NULL for the default context
* \returns 1 if a thread is handling events * \returns 1 if a thread is handling events
* \returns 0 if there are no threads currently handling events * \returns 0 if there are no threads currently handling events
* \ref mtasync * \ref libusb_mtasync
*/ */
int API_EXPORTED libusb_event_handler_active(libusb_context *ctx) int API_EXPORTED libusb_event_handler_active(libusb_context *ctx)
{ {
@ -1847,7 +1875,30 @@ int API_EXPORTED libusb_event_handler_active(libusb_context *ctx)
return ctx->event_handler_active; return ctx->event_handler_active;
} }
/** \ingroup poll /** \ingroup libusb_poll
* Interrupt any active thread that is handling events. This is mainly useful
* for interrupting a dedicated event handling thread when an application
* wishes to call libusb_exit().
*
* Since version 1.0.21, \ref LIBUSB_API_VERSION >= 0x01000105
*
* \param ctx the context to operate on, or NULL for the default context
* \ref libusb_mtasync
*/
void API_EXPORTED libusb_interrupt_event_handler(libusb_context *ctx)
{
USBI_GET_CONTEXT(ctx);
usbi_dbg("");
usbi_mutex_lock(&ctx->event_data_lock);
if (!usbi_pending_events(ctx)) {
ctx->event_flags |= USBI_EVENT_USER_INTERRUPT;
usbi_signal_event(ctx);
}
usbi_mutex_unlock(&ctx->event_data_lock);
}
/** \ingroup libusb_poll
* Acquire the event waiters lock. This lock is designed to be obtained under * Acquire the event waiters lock. This lock is designed to be obtained under
* the situation where you want to be aware when events are completed, but * the situation where you want to be aware when events are completed, but
* some other thread is event handling so calling libusb_handle_events() is not * some other thread is event handling so calling libusb_handle_events() is not
@ -1864,7 +1915,7 @@ int API_EXPORTED libusb_event_handler_active(libusb_context *ctx)
* locking. * locking.
* *
* \param ctx the context to operate on, or NULL for the default context * \param ctx the context to operate on, or NULL for the default context
* \ref mtasync * \ref libusb_mtasync
*/ */
void API_EXPORTED libusb_lock_event_waiters(libusb_context *ctx) void API_EXPORTED libusb_lock_event_waiters(libusb_context *ctx)
{ {
@ -1872,10 +1923,10 @@ void API_EXPORTED libusb_lock_event_waiters(libusb_context *ctx)
usbi_mutex_lock(&ctx->event_waiters_lock); usbi_mutex_lock(&ctx->event_waiters_lock);
} }
/** \ingroup poll /** \ingroup libusb_poll
* Release the event waiters lock. * Release the event waiters lock.
* \param ctx the context to operate on, or NULL for the default context * \param ctx the context to operate on, or NULL for the default context
* \ref mtasync * \ref libusb_mtasync
*/ */
void API_EXPORTED libusb_unlock_event_waiters(libusb_context *ctx) void API_EXPORTED libusb_unlock_event_waiters(libusb_context *ctx)
{ {
@ -1883,7 +1934,7 @@ void API_EXPORTED libusb_unlock_event_waiters(libusb_context *ctx)
usbi_mutex_unlock(&ctx->event_waiters_lock); usbi_mutex_unlock(&ctx->event_waiters_lock);
} }
/** \ingroup poll /** \ingroup libusb_poll
* Wait for another thread to signal completion of an event. Must be called * Wait for another thread to signal completion of an event. Must be called
* with the event waiters lock held, see libusb_lock_event_waiters(). * with the event waiters lock held, see libusb_lock_event_waiters().
* *
@ -1906,11 +1957,10 @@ void API_EXPORTED libusb_unlock_event_waiters(libusb_context *ctx)
* indicates unlimited timeout. * indicates unlimited timeout.
* \returns 0 after a transfer completes or another thread stops event handling * \returns 0 after a transfer completes or another thread stops event handling
* \returns 1 if the timeout expired * \returns 1 if the timeout expired
* \ref mtasync * \ref libusb_mtasync
*/ */
int API_EXPORTED libusb_wait_for_event(libusb_context *ctx, struct timeval *tv) int API_EXPORTED libusb_wait_for_event(libusb_context *ctx, struct timeval *tv)
{ {
struct timespec timeout;
int r; int r;
USBI_GET_CONTEXT(ctx); USBI_GET_CONTEXT(ctx);
@ -1919,21 +1969,12 @@ int API_EXPORTED libusb_wait_for_event(libusb_context *ctx, struct timeval *tv)
return 0; return 0;
} }
r = usbi_backend->clock_gettime(USBI_CLOCK_REALTIME, &timeout);
if (r < 0) {
usbi_err(ctx, "failed to read realtime clock, error %d", errno);
return LIBUSB_ERROR_OTHER;
}
timeout.tv_sec += tv->tv_sec;
timeout.tv_nsec += tv->tv_usec * 1000;
while (timeout.tv_nsec >= 1000000000) {
timeout.tv_nsec -= 1000000000;
timeout.tv_sec++;
}
r = usbi_cond_timedwait(&ctx->event_waiters_cond, r = usbi_cond_timedwait(&ctx->event_waiters_cond,
&ctx->event_waiters_lock, &timeout); &ctx->event_waiters_lock, tv);
if (r < 0)
return r;
else
return (r == ETIMEDOUT); return (r == ETIMEDOUT);
} }
@ -1943,10 +1984,10 @@ static void handle_timeout(struct usbi_transfer *itransfer)
USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
int r; int r;
itransfer->flags |= USBI_TRANSFER_TIMEOUT_HANDLED; itransfer->timeout_flags |= USBI_TRANSFER_TIMEOUT_HANDLED;
r = libusb_cancel_transfer(transfer); r = libusb_cancel_transfer(transfer);
if (r == 0) if (r == LIBUSB_SUCCESS)
itransfer->flags |= USBI_TRANSFER_TIMED_OUT; itransfer->timeout_flags |= USBI_TRANSFER_TIMED_OUT;
else else
usbi_warn(TRANSFER_CTX(transfer), usbi_warn(TRANSFER_CTX(transfer),
"async cancel failed %d errno=%d", r, errno); "async cancel failed %d errno=%d", r, errno);
@ -1979,7 +2020,7 @@ static int handle_timeouts_locked(struct libusb_context *ctx)
return 0; return 0;
/* ignore timeouts we've already handled */ /* ignore timeouts we've already handled */
if (transfer->flags & (USBI_TRANSFER_TIMEOUT_HANDLED | USBI_TRANSFER_OS_HANDLES_TIMEOUT)) if (transfer->timeout_flags & (USBI_TRANSFER_TIMEOUT_HANDLED | USBI_TRANSFER_OS_HANDLES_TIMEOUT))
continue; continue;
/* if transfer has non-expired timeout, nothing more to do */ /* if transfer has non-expired timeout, nothing more to do */
@ -2038,6 +2079,12 @@ static int handle_events(struct libusb_context *ctx, struct timeval *tv)
int timeout_ms; int timeout_ms;
int special_event; int special_event;
/* prevent attempts to recursively handle events (e.g. calling into
* libusb_handle_events() from within a hotplug or transfer callback) */
if (usbi_handling_events(ctx))
return LIBUSB_ERROR_BUSY;
usbi_start_event_handling(ctx);
/* there are certain fds that libusb uses internally, currently: /* there are certain fds that libusb uses internally, currently:
* *
* 1) event pipe * 1) event pipe
@ -2055,7 +2102,7 @@ static int handle_events(struct libusb_context *ctx, struct timeval *tv)
/* only reallocate the poll fds when the list of poll fds has been modified /* only reallocate the poll fds when the list of poll fds has been modified
* since the last poll, otherwise reuse them to save the additional overhead */ * since the last poll, otherwise reuse them to save the additional overhead */
usbi_mutex_lock(&ctx->event_data_lock); usbi_mutex_lock(&ctx->event_data_lock);
if (ctx->pollfds_modified) { if (ctx->event_flags & USBI_EVENT_POLLFDS_MODIFIED) {
usbi_dbg("poll fds modified, reallocating"); usbi_dbg("poll fds modified, reallocating");
if (ctx->pollfds) { if (ctx->pollfds) {
@ -2070,7 +2117,8 @@ static int handle_events(struct libusb_context *ctx, struct timeval *tv)
ctx->pollfds = calloc(ctx->pollfds_cnt, sizeof(*ctx->pollfds)); ctx->pollfds = calloc(ctx->pollfds_cnt, sizeof(*ctx->pollfds));
if (!ctx->pollfds) { if (!ctx->pollfds) {
usbi_mutex_unlock(&ctx->event_data_lock); usbi_mutex_unlock(&ctx->event_data_lock);
return LIBUSB_ERROR_NO_MEM; r = LIBUSB_ERROR_NO_MEM;
goto done;
} }
list_for_each_entry(ipollfd, &ctx->ipollfds, list, struct usbi_pollfd) { list_for_each_entry(ipollfd, &ctx->ipollfds, list, struct usbi_pollfd) {
@ -2081,7 +2129,7 @@ static int handle_events(struct libusb_context *ctx, struct timeval *tv)
} }
/* reset the flag now that we have the updated list */ /* reset the flag now that we have the updated list */
ctx->pollfds_modified = 0; ctx->event_flags &= ~USBI_EVENT_POLLFDS_MODIFIED;
/* if no further pending events, clear the event pipe so that we do /* if no further pending events, clear the event pipe so that we do
* not immediately return from poll */ * not immediately return from poll */
@ -2102,13 +2150,18 @@ redo_poll:
usbi_dbg("poll() %d fds with timeout in %dms", nfds, timeout_ms); usbi_dbg("poll() %d fds with timeout in %dms", nfds, timeout_ms);
r = usbi_poll(fds, nfds, timeout_ms); r = usbi_poll(fds, nfds, timeout_ms);
usbi_dbg("poll() returned %d", r); usbi_dbg("poll() returned %d", r);
if (r == 0) if (r == 0) {
return handle_timeouts(ctx); r = handle_timeouts(ctx);
else if (r == -1 && errno == EINTR) goto done;
return LIBUSB_ERROR_INTERRUPTED; }
else if (r == -1 && errno == EINTR) {
r = LIBUSB_ERROR_INTERRUPTED;
goto done;
}
else if (r < 0) { else if (r < 0) {
usbi_err(ctx, "poll failed %d err=%d", r, errno); usbi_err(ctx, "poll failed %d err=%d", r, errno);
return LIBUSB_ERROR_IO; r = LIBUSB_ERROR_IO;
goto done;
} }
special_event = 0; special_event = 0;
@ -2125,9 +2178,14 @@ redo_poll:
usbi_mutex_lock(&ctx->event_data_lock); usbi_mutex_lock(&ctx->event_data_lock);
/* check if someone added a new poll fd */ /* check if someone added a new poll fd */
if (ctx->pollfds_modified) if (ctx->event_flags & USBI_EVENT_POLLFDS_MODIFIED)
usbi_dbg("someone updated the poll fds"); usbi_dbg("someone updated the poll fds");
if (ctx->event_flags & USBI_EVENT_USER_INTERRUPT) {
usbi_dbg("someone purposely interrupted");
ctx->event_flags &= ~USBI_EVENT_USER_INTERRUPT;
}
/* check if someone is closing a device */ /* check if someone is closing a device */
if (ctx->device_close) if (ctx->device_close)
usbi_dbg("someone is closing a device"); usbi_dbg("someone is closing a device");
@ -2171,7 +2229,7 @@ redo_poll:
if (ret) { if (ret) {
/* return error code */ /* return error code */
r = ret; r = ret;
goto handled; goto done;
} }
if (0 == --r) if (0 == --r)
@ -2190,7 +2248,7 @@ redo_poll:
if (ret < 0) { if (ret < 0) {
/* return error code */ /* return error code */
r = ret; r = ret;
goto handled; goto done;
} }
if (0 == --r) if (0 == --r)
@ -2208,6 +2266,8 @@ handled:
goto redo_poll; goto redo_poll;
} }
done:
usbi_end_event_handling(ctx);
return r; return r;
} }
@ -2238,7 +2298,7 @@ static int get_next_timeout(libusb_context *ctx, struct timeval *tv,
return 0; return 0;
} }
/** \ingroup poll /** \ingroup libusb_poll
* Handle any pending events. * Handle any pending events.
* *
* libusb determines "pending events" by checking if any timeouts have expired * libusb determines "pending events" by checking if any timeouts have expired
@ -2262,7 +2322,7 @@ static int get_next_timeout(libusb_context *ctx, struct timeval *tv,
* timeval struct for non-blocking mode * timeval struct for non-blocking mode
* \param completed pointer to completion integer to check, or NULL * \param completed pointer to completion integer to check, or NULL
* \returns 0 on success, or a LIBUSB_ERROR code on failure * \returns 0 on success, or a LIBUSB_ERROR code on failure
* \ref mtasync * \ref libusb_mtasync
*/ */
int API_EXPORTED libusb_handle_events_timeout_completed(libusb_context *ctx, int API_EXPORTED libusb_handle_events_timeout_completed(libusb_context *ctx,
struct timeval *tv, int *completed) struct timeval *tv, int *completed)
@ -2317,7 +2377,7 @@ already_done:
return 0; return 0;
} }
/** \ingroup poll /** \ingroup libusb_poll
* Handle any pending events * Handle any pending events
* *
* Like libusb_handle_events_timeout_completed(), but without the completed * Like libusb_handle_events_timeout_completed(), but without the completed
@ -2339,7 +2399,7 @@ int API_EXPORTED libusb_handle_events_timeout(libusb_context *ctx,
return libusb_handle_events_timeout_completed(ctx, tv, NULL); return libusb_handle_events_timeout_completed(ctx, tv, NULL);
} }
/** \ingroup poll /** \ingroup libusb_poll
* Handle any pending events in blocking mode. There is currently a timeout * Handle any pending events in blocking mode. There is currently a timeout
* hardcoded at 60 seconds but we plan to make it unlimited in future. For * hardcoded at 60 seconds but we plan to make it unlimited in future. For
* finer control over whether this function is blocking or non-blocking, or * finer control over whether this function is blocking or non-blocking, or
@ -2361,7 +2421,7 @@ int API_EXPORTED libusb_handle_events(libusb_context *ctx)
return libusb_handle_events_timeout_completed(ctx, &tv, NULL); return libusb_handle_events_timeout_completed(ctx, &tv, NULL);
} }
/** \ingroup poll /** \ingroup libusb_poll
* Handle any pending events in blocking mode. * Handle any pending events in blocking mode.
* *
* Like libusb_handle_events(), with the addition of a completed parameter * Like libusb_handle_events(), with the addition of a completed parameter
@ -2373,7 +2433,7 @@ int API_EXPORTED libusb_handle_events(libusb_context *ctx)
* \param ctx the context to operate on, or NULL for the default context * \param ctx the context to operate on, or NULL for the default context
* \param completed pointer to completion integer to check, or NULL * \param completed pointer to completion integer to check, or NULL
* \returns 0 on success, or a LIBUSB_ERROR code on failure * \returns 0 on success, or a LIBUSB_ERROR code on failure
* \ref mtasync * \ref libusb_mtasync
*/ */
int API_EXPORTED libusb_handle_events_completed(libusb_context *ctx, int API_EXPORTED libusb_handle_events_completed(libusb_context *ctx,
int *completed) int *completed)
@ -2384,7 +2444,7 @@ int API_EXPORTED libusb_handle_events_completed(libusb_context *ctx,
return libusb_handle_events_timeout_completed(ctx, &tv, completed); return libusb_handle_events_timeout_completed(ctx, &tv, completed);
} }
/** \ingroup poll /** \ingroup libusb_poll
* Handle any pending events by polling file descriptors, without checking if * Handle any pending events by polling file descriptors, without checking if
* any other threads are already doing so. Must be called with the event lock * any other threads are already doing so. Must be called with the event lock
* held, see libusb_lock_events(). * held, see libusb_lock_events().
@ -2399,7 +2459,7 @@ int API_EXPORTED libusb_handle_events_completed(libusb_context *ctx,
* \param tv the maximum time to block waiting for events, or zero for * \param tv the maximum time to block waiting for events, or zero for
* non-blocking mode * non-blocking mode
* \returns 0 on success, or a LIBUSB_ERROR code on failure * \returns 0 on success, or a LIBUSB_ERROR code on failure
* \ref mtasync * \ref libusb_mtasync
*/ */
int API_EXPORTED libusb_handle_events_locked(libusb_context *ctx, int API_EXPORTED libusb_handle_events_locked(libusb_context *ctx,
struct timeval *tv) struct timeval *tv)
@ -2417,12 +2477,12 @@ int API_EXPORTED libusb_handle_events_locked(libusb_context *ctx,
return handle_events(ctx, &poll_timeout); return handle_events(ctx, &poll_timeout);
} }
/** \ingroup poll /** \ingroup libusb_poll
* Determines whether your application must apply special timing considerations * Determines whether your application must apply special timing considerations
* when monitoring libusb's file descriptors. * when monitoring libusb's file descriptors.
* *
* This function is only useful for applications which retrieve and poll * This function is only useful for applications which retrieve and poll
* libusb's file descriptors in their own main loop (\ref pollmain). * libusb's file descriptors in their own main loop (\ref libusb_pollmain).
* *
* Ordinarily, libusb's event handler needs to be called into at specific * Ordinarily, libusb's event handler needs to be called into at specific
* moments in time (in addition to times when there is activity on the file * moments in time (in addition to times when there is activity on the file
@ -2443,7 +2503,7 @@ int API_EXPORTED libusb_handle_events_locked(libusb_context *ctx,
* \returns 0 if you must call into libusb at times determined by * \returns 0 if you must call into libusb at times determined by
* libusb_get_next_timeout(), or 1 if all timeout events are handled internally * libusb_get_next_timeout(), or 1 if all timeout events are handled internally
* or through regular activity on the file descriptors. * or through regular activity on the file descriptors.
* \ref pollmain "Polling libusb file descriptors for event handling" * \ref libusb_pollmain "Polling libusb file descriptors for event handling"
*/ */
int API_EXPORTED libusb_pollfds_handle_timeouts(libusb_context *ctx) int API_EXPORTED libusb_pollfds_handle_timeouts(libusb_context *ctx)
{ {
@ -2451,12 +2511,12 @@ int API_EXPORTED libusb_pollfds_handle_timeouts(libusb_context *ctx)
USBI_GET_CONTEXT(ctx); USBI_GET_CONTEXT(ctx);
return usbi_using_timerfd(ctx); return usbi_using_timerfd(ctx);
#else #else
(void)ctx; UNUSED(ctx);
return 0; return 0;
#endif #endif
} }
/** \ingroup poll /** \ingroup libusb_poll
* Determine the next internal timeout that libusb needs to handle. You only * Determine the next internal timeout that libusb needs to handle. You only
* need to use this function if you are calling poll() or select() or similar * need to use this function if you are calling poll() or select() or similar
* on libusb's file descriptors yourself - you do not need to use it if you * on libusb's file descriptors yourself - you do not need to use it if you
@ -2506,7 +2566,7 @@ int API_EXPORTED libusb_get_next_timeout(libusb_context *ctx,
/* find next transfer which hasn't already been processed as timed out */ /* find next transfer which hasn't already been processed as timed out */
list_for_each_entry(transfer, &ctx->flying_transfers, list, struct usbi_transfer) { list_for_each_entry(transfer, &ctx->flying_transfers, list, struct usbi_transfer) {
if (transfer->flags & (USBI_TRANSFER_TIMEOUT_HANDLED | USBI_TRANSFER_OS_HANDLES_TIMEOUT)) if (transfer->timeout_flags & (USBI_TRANSFER_TIMEOUT_HANDLED | USBI_TRANSFER_OS_HANDLES_TIMEOUT))
continue; continue;
/* if we've reached transfers of infinte timeout, we're done looking */ /* if we've reached transfers of infinte timeout, we're done looking */
@ -2541,7 +2601,7 @@ int API_EXPORTED libusb_get_next_timeout(libusb_context *ctx,
return 1; return 1;
} }
/** \ingroup poll /** \ingroup libusb_poll
* Register notification functions for file descriptor additions/removals. * Register notification functions for file descriptor additions/removals.
* These functions will be invoked for every new or removed file descriptor * These functions will be invoked for every new or removed file descriptor
* that libusb uses as an event source. * that libusb uses as an event source.
@ -2583,7 +2643,7 @@ static void usbi_fd_notification(struct libusb_context *ctx)
/* Record that there is a new poll fd. /* Record that there is a new poll fd.
* Only signal an event if there are no prior pending events. */ * Only signal an event if there are no prior pending events. */
pending_events = usbi_pending_events(ctx); pending_events = usbi_pending_events(ctx);
ctx->pollfds_modified = 1; ctx->event_flags |= USBI_EVENT_POLLFDS_MODIFIED;
if (!pending_events) if (!pending_events)
usbi_signal_event(ctx); usbi_signal_event(ctx);
} }
@ -2640,7 +2700,7 @@ void usbi_remove_pollfd(struct libusb_context *ctx, int fd)
ctx->fd_removed_cb(fd, ctx->fd_cb_user_data); ctx->fd_removed_cb(fd, ctx->fd_cb_user_data);
} }
/** \ingroup poll /** \ingroup libusb_poll
* Retrieve a list of file descriptors that should be polled by your main loop * Retrieve a list of file descriptors that should be polled by your main loop
* as libusb event sources. * as libusb event sources.
* *
@ -2685,7 +2745,7 @@ out:
#endif #endif
} }
/** \ingroup poll /** \ingroup libusb_poll
* Free a list of libusb_pollfd structures. This should be called for all * Free a list of libusb_pollfd structures. This should be called for all
* pollfd lists allocated with libusb_get_pollfds(). * pollfd lists allocated with libusb_get_pollfds().
* *
@ -2708,13 +2768,13 @@ void API_EXPORTED libusb_free_pollfds(const struct libusb_pollfd **pollfds)
* device. This function ensures transfers get cancelled appropriately. * device. This function ensures transfers get cancelled appropriately.
* Callers of this function must hold the events_lock. * Callers of this function must hold the events_lock.
*/ */
void usbi_handle_disconnect(struct libusb_device_handle *handle) void usbi_handle_disconnect(struct libusb_device_handle *dev_handle)
{ {
struct usbi_transfer *cur; struct usbi_transfer *cur;
struct usbi_transfer *to_cancel; struct usbi_transfer *to_cancel;
usbi_dbg("device %d.%d", usbi_dbg("device %d.%d",
handle->dev->bus_number, handle->dev->device_address); dev_handle->dev->bus_number, dev_handle->dev->device_address);
/* terminate all pending transfers with the LIBUSB_TRANSFER_NO_DEVICE /* terminate all pending transfers with the LIBUSB_TRANSFER_NO_DEVICE
* status code. * status code.
@ -2723,27 +2783,26 @@ void usbi_handle_disconnect(struct libusb_device_handle *handle)
* possible scenarios: * possible scenarios:
* 1. the transfer is currently in-flight, in which case we terminate the * 1. the transfer is currently in-flight, in which case we terminate the
* transfer here * transfer here
* 2. the transfer is not in-flight (or is but hasn't been marked as such), * 2. the transfer has been added to the flying transfer list by
* in which case we record that the device disappeared and this will be * libusb_submit_transfer, has failed to submit and
* handled by libusb_submit_transfer() * libusb_submit_transfer is waiting for us to release the
* flying_transfers_lock to remove it, so we ignore it
*/ */
while (1) { while (1) {
to_cancel = NULL; to_cancel = NULL;
usbi_mutex_lock(&HANDLE_CTX(handle)->flying_transfers_lock); usbi_mutex_lock(&HANDLE_CTX(dev_handle)->flying_transfers_lock);
list_for_each_entry(cur, &HANDLE_CTX(handle)->flying_transfers, list, struct usbi_transfer) list_for_each_entry(cur, &HANDLE_CTX(dev_handle)->flying_transfers, list, struct usbi_transfer)
if (USBI_TRANSFER_TO_LIBUSB_TRANSFER(cur)->dev_handle == handle) { if (USBI_TRANSFER_TO_LIBUSB_TRANSFER(cur)->dev_handle == dev_handle) {
usbi_mutex_lock(&cur->flags_lock); usbi_mutex_lock(&cur->lock);
if (cur->flags & USBI_TRANSFER_IN_FLIGHT) if (cur->state_flags & USBI_TRANSFER_IN_FLIGHT)
to_cancel = cur; to_cancel = cur;
else usbi_mutex_unlock(&cur->lock);
cur->flags |= USBI_TRANSFER_DEVICE_DISAPPEARED;
usbi_mutex_unlock(&cur->flags_lock);
if (to_cancel) if (to_cancel)
break; break;
} }
usbi_mutex_unlock(&HANDLE_CTX(handle)->flying_transfers_lock); usbi_mutex_unlock(&HANDLE_CTX(dev_handle)->flying_transfers_lock);
if (!to_cancel) if (!to_cancel)
break; break;

View File

@ -20,6 +20,10 @@ EXPORTS
libusb_control_transfer@32 = libusb_control_transfer libusb_control_transfer@32 = libusb_control_transfer
libusb_detach_kernel_driver libusb_detach_kernel_driver
libusb_detach_kernel_driver@8 = libusb_detach_kernel_driver libusb_detach_kernel_driver@8 = libusb_detach_kernel_driver
libusb_dev_mem_alloc
libusb_dev_mem_alloc@8 = libusb_dev_mem_alloc
libusb_dev_mem_free
libusb_dev_mem_free@12 = libusb_dev_mem_free
libusb_error_name libusb_error_name
libusb_error_name@4 = libusb_error_name libusb_error_name@4 = libusb_error_name
libusb_event_handler_active libusb_event_handler_active
@ -36,6 +40,8 @@ EXPORTS
libusb_free_container_id_descriptor@4 = libusb_free_container_id_descriptor libusb_free_container_id_descriptor@4 = libusb_free_container_id_descriptor
libusb_free_device_list libusb_free_device_list
libusb_free_device_list@8 = libusb_free_device_list libusb_free_device_list@8 = libusb_free_device_list
libusb_free_pollfds
libusb_free_pollfds@4 = libusb_free_pollfds
libusb_free_ss_endpoint_companion_descriptor libusb_free_ss_endpoint_companion_descriptor
libusb_free_ss_endpoint_companion_descriptor@4 = libusb_free_ss_endpoint_companion_descriptor libusb_free_ss_endpoint_companion_descriptor@4 = libusb_free_ss_endpoint_companion_descriptor
libusb_free_ss_usb_device_capability_descriptor libusb_free_ss_usb_device_capability_descriptor
@ -80,8 +86,6 @@ EXPORTS
libusb_get_parent@4 = libusb_get_parent libusb_get_parent@4 = libusb_get_parent
libusb_get_pollfds libusb_get_pollfds
libusb_get_pollfds@4 = libusb_get_pollfds libusb_get_pollfds@4 = libusb_get_pollfds
libusb_free_pollfds
libusb_free_pollfds@4 = libusb_free_pollfds
libusb_get_port_number libusb_get_port_number
libusb_get_port_number@4 = libusb_get_port_number libusb_get_port_number@4 = libusb_get_port_number
libusb_get_port_numbers libusb_get_port_numbers
@ -116,14 +120,16 @@ EXPORTS
libusb_hotplug_register_callback@36 = libusb_hotplug_register_callback libusb_hotplug_register_callback@36 = libusb_hotplug_register_callback
libusb_init libusb_init
libusb_init@4 = libusb_init libusb_init@4 = libusb_init
libusb_interrupt_event_handler
libusb_interrupt_event_handler@4 = libusb_interrupt_event_handler
libusb_interrupt_transfer libusb_interrupt_transfer
libusb_interrupt_transfer@24 = libusb_interrupt_transfer libusb_interrupt_transfer@24 = libusb_interrupt_transfer
libusb_kernel_driver_active libusb_kernel_driver_active
libusb_kernel_driver_active@8 = libusb_kernel_driver_active libusb_kernel_driver_active@8 = libusb_kernel_driver_active
libusb_lock_event_waiters
libusb_lock_event_waiters@4 = libusb_lock_event_waiters
libusb_lock_events libusb_lock_events
libusb_lock_events@4 = libusb_lock_events libusb_lock_events@4 = libusb_lock_events
libusb_lock_event_waiters
libusb_lock_event_waiters@4 = libusb_lock_event_waiters
libusb_open libusb_open
libusb_open@8 = libusb_open libusb_open@8 = libusb_open
libusb_open_device_with_vid_pid libusb_open_device_with_vid_pid
@ -144,10 +150,10 @@ EXPORTS
libusb_set_debug@8 = libusb_set_debug libusb_set_debug@8 = libusb_set_debug
libusb_set_interface_alt_setting libusb_set_interface_alt_setting
libusb_set_interface_alt_setting@12 = libusb_set_interface_alt_setting libusb_set_interface_alt_setting@12 = libusb_set_interface_alt_setting
libusb_set_pollfd_notifiers
libusb_set_pollfd_notifiers@16 = libusb_set_pollfd_notifiers
libusb_setlocale libusb_setlocale
libusb_setlocale@4 = libusb_setlocale libusb_setlocale@4 = libusb_setlocale
libusb_set_pollfd_notifiers
libusb_set_pollfd_notifiers@16 = libusb_set_pollfd_notifiers
libusb_strerror libusb_strerror
libusb_strerror@4 = libusb_strerror libusb_strerror@4 = libusb_strerror
libusb_submit_transfer libusb_submit_transfer
@ -158,10 +164,10 @@ EXPORTS
libusb_transfer_set_stream_id@8 = libusb_transfer_set_stream_id libusb_transfer_set_stream_id@8 = libusb_transfer_set_stream_id
libusb_try_lock_events libusb_try_lock_events
libusb_try_lock_events@4 = libusb_try_lock_events libusb_try_lock_events@4 = libusb_try_lock_events
libusb_unlock_event_waiters
libusb_unlock_event_waiters@4 = libusb_unlock_event_waiters
libusb_unlock_events libusb_unlock_events
libusb_unlock_events@4 = libusb_unlock_events libusb_unlock_events@4 = libusb_unlock_events
libusb_unlock_event_waiters
libusb_unlock_event_waiters@4 = libusb_unlock_event_waiters
libusb_unref_device libusb_unref_device
libusb_unref_device@4 = libusb_unref_device libusb_unref_device@4 = libusb_unref_device
libusb_wait_for_event libusb_wait_for_event

View File

@ -84,7 +84,7 @@ typedef unsigned __int32 uint32_t;
#endif /* __GNUC__ */ #endif /* __GNUC__ */
/** \def LIBUSB_CALL /** \def LIBUSB_CALL
* \ingroup misc * \ingroup libusb_misc
* libusb's Windows calling convention. * libusb's Windows calling convention.
* *
* Under Windows, the selection of available compilers and configurations * Under Windows, the selection of available compilers and configurations
@ -122,7 +122,7 @@ typedef unsigned __int32 uint32_t;
#endif #endif
/** \def LIBUSB_API_VERSION /** \def LIBUSB_API_VERSION
* \ingroup misc * \ingroup libusb_misc
* libusb's API version. * libusb's API version.
* *
* Since version 1.0.13, to help with feature detection, libusb defines * Since version 1.0.13, to help with feature detection, libusb defines
@ -141,7 +141,7 @@ typedef unsigned __int32 uint32_t;
* Internally, LIBUSB_API_VERSION is defined as follows: * Internally, LIBUSB_API_VERSION is defined as follows:
* (libusb major << 24) | (libusb minor << 16) | (16 bit incremental) * (libusb major << 24) | (libusb minor << 16) | (16 bit incremental)
*/ */
#define LIBUSB_API_VERSION 0x01000104 #define LIBUSB_API_VERSION 0x01000105
/* The following is kept for compatibility, but will be deprecated in the future */ /* The following is kept for compatibility, but will be deprecated in the future */
#define LIBUSBX_API_VERSION LIBUSB_API_VERSION #define LIBUSBX_API_VERSION LIBUSB_API_VERSION
@ -151,7 +151,7 @@ extern "C" {
#endif #endif
/** /**
* \ingroup misc * \ingroup libusb_misc
* Convert a 16-bit value from host-endian to little-endian format. On * Convert a 16-bit value from host-endian to little-endian format. On
* little endian systems, this function does nothing. On big endian systems, * little endian systems, this function does nothing. On big endian systems,
* the bytes are swapped. * the bytes are swapped.
@ -170,7 +170,7 @@ static inline uint16_t libusb_cpu_to_le16(const uint16_t x)
} }
/** \def libusb_le16_to_cpu /** \def libusb_le16_to_cpu
* \ingroup misc * \ingroup libusb_misc
* Convert a 16-bit value from little-endian to host-endian format. On * Convert a 16-bit value from little-endian to host-endian format. On
* little endian systems, this function does nothing. On big endian systems, * little endian systems, this function does nothing. On big endian systems,
* the bytes are swapped. * the bytes are swapped.
@ -181,7 +181,7 @@ static inline uint16_t libusb_cpu_to_le16(const uint16_t x)
/* standard USB stuff */ /* standard USB stuff */
/** \ingroup desc /** \ingroup libusb_desc
* Device and/or Interface Class codes */ * Device and/or Interface Class codes */
enum libusb_class_code { enum libusb_class_code {
/** In the context of a \ref libusb_device_descriptor "device descriptor", /** In the context of a \ref libusb_device_descriptor "device descriptor",
@ -243,7 +243,7 @@ enum libusb_class_code {
LIBUSB_CLASS_VENDOR_SPEC = 0xff LIBUSB_CLASS_VENDOR_SPEC = 0xff
}; };
/** \ingroup desc /** \ingroup libusb_desc
* Descriptor types as defined by the USB specification. */ * Descriptor types as defined by the USB specification. */
enum libusb_descriptor_type { enum libusb_descriptor_type {
/** Device descriptor. See libusb_device_descriptor. */ /** Device descriptor. See libusb_device_descriptor. */
@ -311,7 +311,7 @@ enum libusb_descriptor_type {
#define LIBUSB_ENDPOINT_ADDRESS_MASK 0x0f /* in bEndpointAddress */ #define LIBUSB_ENDPOINT_ADDRESS_MASK 0x0f /* in bEndpointAddress */
#define LIBUSB_ENDPOINT_DIR_MASK 0x80 #define LIBUSB_ENDPOINT_DIR_MASK 0x80
/** \ingroup desc /** \ingroup libusb_desc
* Endpoint direction. Values for bit 7 of the * Endpoint direction. Values for bit 7 of the
* \ref libusb_endpoint_descriptor::bEndpointAddress "endpoint address" scheme. * \ref libusb_endpoint_descriptor::bEndpointAddress "endpoint address" scheme.
*/ */
@ -325,7 +325,7 @@ enum libusb_endpoint_direction {
#define LIBUSB_TRANSFER_TYPE_MASK 0x03 /* in bmAttributes */ #define LIBUSB_TRANSFER_TYPE_MASK 0x03 /* in bmAttributes */
/** \ingroup desc /** \ingroup libusb_desc
* Endpoint transfer type. Values for bits 0:1 of the * Endpoint transfer type. Values for bits 0:1 of the
* \ref libusb_endpoint_descriptor::bmAttributes "endpoint attributes" field. * \ref libusb_endpoint_descriptor::bmAttributes "endpoint attributes" field.
*/ */
@ -346,7 +346,7 @@ enum libusb_transfer_type {
LIBUSB_TRANSFER_TYPE_BULK_STREAM = 4, LIBUSB_TRANSFER_TYPE_BULK_STREAM = 4,
}; };
/** \ingroup misc /** \ingroup libusb_misc
* Standard requests, as defined in table 9-5 of the USB 3.0 specifications */ * Standard requests, as defined in table 9-5 of the USB 3.0 specifications */
enum libusb_standard_request { enum libusb_standard_request {
/** Request status of the specific recipient */ /** Request status of the specific recipient */
@ -394,7 +394,7 @@ enum libusb_standard_request {
LIBUSB_SET_ISOCH_DELAY = 0x31, LIBUSB_SET_ISOCH_DELAY = 0x31,
}; };
/** \ingroup misc /** \ingroup libusb_misc
* Request type bits of the * Request type bits of the
* \ref libusb_control_setup::bmRequestType "bmRequestType" field in control * \ref libusb_control_setup::bmRequestType "bmRequestType" field in control
* transfers. */ * transfers. */
@ -412,7 +412,7 @@ enum libusb_request_type {
LIBUSB_REQUEST_TYPE_RESERVED = (0x03 << 5) LIBUSB_REQUEST_TYPE_RESERVED = (0x03 << 5)
}; };
/** \ingroup misc /** \ingroup libusb_misc
* Recipient bits of the * Recipient bits of the
* \ref libusb_control_setup::bmRequestType "bmRequestType" field in control * \ref libusb_control_setup::bmRequestType "bmRequestType" field in control
* transfers. Values 4 through 31 are reserved. */ * transfers. Values 4 through 31 are reserved. */
@ -432,7 +432,7 @@ enum libusb_request_recipient {
#define LIBUSB_ISO_SYNC_TYPE_MASK 0x0C #define LIBUSB_ISO_SYNC_TYPE_MASK 0x0C
/** \ingroup desc /** \ingroup libusb_desc
* Synchronization type for isochronous endpoints. Values for bits 2:3 of the * Synchronization type for isochronous endpoints. Values for bits 2:3 of the
* \ref libusb_endpoint_descriptor::bmAttributes "bmAttributes" field in * \ref libusb_endpoint_descriptor::bmAttributes "bmAttributes" field in
* libusb_endpoint_descriptor. * libusb_endpoint_descriptor.
@ -453,7 +453,7 @@ enum libusb_iso_sync_type {
#define LIBUSB_ISO_USAGE_TYPE_MASK 0x30 #define LIBUSB_ISO_USAGE_TYPE_MASK 0x30
/** \ingroup desc /** \ingroup libusb_desc
* Usage type for isochronous endpoints. Values for bits 4:5 of the * Usage type for isochronous endpoints. Values for bits 4:5 of the
* \ref libusb_endpoint_descriptor::bmAttributes "bmAttributes" field in * \ref libusb_endpoint_descriptor::bmAttributes "bmAttributes" field in
* libusb_endpoint_descriptor. * libusb_endpoint_descriptor.
@ -469,7 +469,7 @@ enum libusb_iso_usage_type {
LIBUSB_ISO_USAGE_TYPE_IMPLICIT = 2, LIBUSB_ISO_USAGE_TYPE_IMPLICIT = 2,
}; };
/** \ingroup desc /** \ingroup libusb_desc
* A structure representing the standard USB device descriptor. This * A structure representing the standard USB device descriptor. This
* descriptor is documented in section 9.6.1 of the USB 3.0 specification. * descriptor is documented in section 9.6.1 of the USB 3.0 specification.
* All multiple-byte fields are represented in host-endian format. * All multiple-byte fields are represented in host-endian format.
@ -523,7 +523,7 @@ struct libusb_device_descriptor {
uint8_t bNumConfigurations; uint8_t bNumConfigurations;
}; };
/** \ingroup desc /** \ingroup libusb_desc
* A structure representing the standard USB endpoint descriptor. This * A structure representing the standard USB endpoint descriptor. This
* descriptor is documented in section 9.6.6 of the USB 3.0 specification. * descriptor is documented in section 9.6.6 of the USB 3.0 specification.
* All multiple-byte fields are represented in host-endian format. * All multiple-byte fields are represented in host-endian format.
@ -573,7 +573,7 @@ struct libusb_endpoint_descriptor {
int extra_length; int extra_length;
}; };
/** \ingroup desc /** \ingroup libusb_desc
* A structure representing the standard USB interface descriptor. This * A structure representing the standard USB interface descriptor. This
* descriptor is documented in section 9.6.5 of the USB 3.0 specification. * descriptor is documented in section 9.6.5 of the USB 3.0 specification.
* All multiple-byte fields are represented in host-endian format. * All multiple-byte fields are represented in host-endian format.
@ -623,7 +623,7 @@ struct libusb_interface_descriptor {
int extra_length; int extra_length;
}; };
/** \ingroup desc /** \ingroup libusb_desc
* A collection of alternate settings for a particular USB interface. * A collection of alternate settings for a particular USB interface.
*/ */
struct libusb_interface { struct libusb_interface {
@ -635,7 +635,7 @@ struct libusb_interface {
int num_altsetting; int num_altsetting;
}; };
/** \ingroup desc /** \ingroup libusb_desc
* A structure representing the standard USB configuration descriptor. This * A structure representing the standard USB configuration descriptor. This
* descriptor is documented in section 9.6.3 of the USB 3.0 specification. * descriptor is documented in section 9.6.3 of the USB 3.0 specification.
* All multiple-byte fields are represented in host-endian format. * All multiple-byte fields are represented in host-endian format.
@ -682,7 +682,7 @@ struct libusb_config_descriptor {
int extra_length; int extra_length;
}; };
/** \ingroup desc /** \ingroup libusb_desc
* A structure representing the superspeed endpoint companion * A structure representing the superspeed endpoint companion
* descriptor. This descriptor is documented in section 9.6.7 of * descriptor. This descriptor is documented in section 9.6.7 of
* the USB 3.0 specification. All multiple-byte fields are represented in * the USB 3.0 specification. All multiple-byte fields are represented in
@ -700,7 +700,7 @@ struct libusb_ss_endpoint_companion_descriptor {
/** The maximum number of packets the endpoint can send or /** The maximum number of packets the endpoint can send or
* recieve as part of a burst. */ * receive as part of a burst. */
uint8_t bMaxBurst; uint8_t bMaxBurst;
/** In bulk EP: bits 4:0 represents the maximum number of /** In bulk EP: bits 4:0 represents the maximum number of
@ -714,7 +714,7 @@ struct libusb_ss_endpoint_companion_descriptor {
uint16_t wBytesPerInterval; uint16_t wBytesPerInterval;
}; };
/** \ingroup desc /** \ingroup libusb_desc
* A generic representation of a BOS Device Capability descriptor. It is * A generic representation of a BOS Device Capability descriptor. It is
* advised to check bDevCapabilityType and call the matching * advised to check bDevCapabilityType and call the matching
* libusb_get_*_descriptor function to get a structure fully matching the type. * libusb_get_*_descriptor function to get a structure fully matching the type.
@ -738,7 +738,7 @@ struct libusb_bos_dev_capability_descriptor {
; ;
}; };
/** \ingroup desc /** \ingroup libusb_desc
* A structure representing the Binary Device Object Store (BOS) descriptor. * A structure representing the Binary Device Object Store (BOS) descriptor.
* This descriptor is documented in section 9.6.2 of the USB 3.0 specification. * This descriptor is documented in section 9.6.2 of the USB 3.0 specification.
* All multiple-byte fields are represented in host-endian format. * All multiple-byte fields are represented in host-endian format.
@ -769,7 +769,7 @@ struct libusb_bos_descriptor {
; ;
}; };
/** \ingroup desc /** \ingroup libusb_desc
* A structure representing the USB 2.0 Extension descriptor * A structure representing the USB 2.0 Extension descriptor
* This descriptor is documented in section 9.6.2.1 of the USB 3.0 specification. * This descriptor is documented in section 9.6.2.1 of the USB 3.0 specification.
* All multiple-byte fields are represented in host-endian format. * All multiple-byte fields are represented in host-endian format.
@ -795,7 +795,7 @@ struct libusb_usb_2_0_extension_descriptor {
uint32_t bmAttributes; uint32_t bmAttributes;
}; };
/** \ingroup desc /** \ingroup libusb_desc
* A structure representing the SuperSpeed USB Device Capability descriptor * A structure representing the SuperSpeed USB Device Capability descriptor
* This descriptor is documented in section 9.6.2.2 of the USB 3.0 specification. * This descriptor is documented in section 9.6.2.2 of the USB 3.0 specification.
* All multiple-byte fields are represented in host-endian format. * All multiple-byte fields are represented in host-endian format.
@ -837,7 +837,7 @@ struct libusb_ss_usb_device_capability_descriptor {
uint16_t bU2DevExitLat; uint16_t bU2DevExitLat;
}; };
/** \ingroup desc /** \ingroup libusb_desc
* A structure representing the Container ID descriptor. * A structure representing the Container ID descriptor.
* This descriptor is documented in section 9.6.2.3 of the USB 3.0 specification. * This descriptor is documented in section 9.6.2.3 of the USB 3.0 specification.
* All multiple-byte fields, except UUIDs, are represented in host-endian format. * All multiple-byte fields, except UUIDs, are represented in host-endian format.
@ -863,7 +863,7 @@ struct libusb_container_id_descriptor {
uint8_t ContainerID[16]; uint8_t ContainerID[16];
}; };
/** \ingroup asyncio /** \ingroup libusb_asyncio
* Setup packet for control transfers. */ * Setup packet for control transfers. */
struct libusb_control_setup { struct libusb_control_setup {
/** Request type. Bits 0:4 determine recipient, see /** Request type. Bits 0:4 determine recipient, see
@ -899,7 +899,7 @@ struct libusb_context;
struct libusb_device; struct libusb_device;
struct libusb_device_handle; struct libusb_device_handle;
/** \ingroup lib /** \ingroup libusb_lib
* Structure providing the version of the libusb runtime * Structure providing the version of the libusb runtime
*/ */
struct libusb_version { struct libusb_version {
@ -922,7 +922,7 @@ struct libusb_version {
const char* describe; const char* describe;
}; };
/** \ingroup lib /** \ingroup libusb_lib
* Structure representing a libusb session. The concept of individual libusb * Structure representing a libusb session. The concept of individual libusb
* sessions allows for your program to use two libraries (or dynamically * sessions allows for your program to use two libraries (or dynamically
* load two modules) which both independently use libusb. This will prevent * load two modules) which both independently use libusb. This will prevent
@ -937,11 +937,11 @@ struct libusb_version {
* every function call where a context is required. The default context * every function call where a context is required. The default context
* will be used. * will be used.
* *
* For more information, see \ref contexts. * For more information, see \ref libusb_contexts.
*/ */
typedef struct libusb_context libusb_context; typedef struct libusb_context libusb_context;
/** \ingroup dev /** \ingroup libusb_dev
* Structure representing a USB device detected on the system. This is an * Structure representing a USB device detected on the system. This is an
* opaque type for which you are only ever provided with a pointer, usually * opaque type for which you are only ever provided with a pointer, usually
* originating from libusb_get_device_list(). * originating from libusb_get_device_list().
@ -959,7 +959,7 @@ typedef struct libusb_context libusb_context;
typedef struct libusb_device libusb_device; typedef struct libusb_device libusb_device;
/** \ingroup dev /** \ingroup libusb_dev
* Structure representing a handle on a USB device. This is an opaque type for * Structure representing a handle on a USB device. This is an opaque type for
* which you are only ever provided with a pointer, usually originating from * which you are only ever provided with a pointer, usually originating from
* libusb_open(). * libusb_open().
@ -969,7 +969,7 @@ typedef struct libusb_device libusb_device;
*/ */
typedef struct libusb_device_handle libusb_device_handle; typedef struct libusb_device_handle libusb_device_handle;
/** \ingroup dev /** \ingroup libusb_dev
* Speed codes. Indicates the speed at which the device is operating. * Speed codes. Indicates the speed at which the device is operating.
*/ */
enum libusb_speed { enum libusb_speed {
@ -989,7 +989,7 @@ enum libusb_speed {
LIBUSB_SPEED_SUPER = 4, LIBUSB_SPEED_SUPER = 4,
}; };
/** \ingroup dev /** \ingroup libusb_dev
* Supported speeds (wSpeedSupported) bitfield. Indicates what * Supported speeds (wSpeedSupported) bitfield. Indicates what
* speeds the device supports. * speeds the device supports.
*/ */
@ -1007,7 +1007,7 @@ enum libusb_supported_speed {
LIBUSB_SUPER_SPEED_OPERATION = 8, LIBUSB_SUPER_SPEED_OPERATION = 8,
}; };
/** \ingroup dev /** \ingroup libusb_dev
* Masks for the bits of the * Masks for the bits of the
* \ref libusb_usb_2_0_extension_descriptor::bmAttributes "bmAttributes" field * \ref libusb_usb_2_0_extension_descriptor::bmAttributes "bmAttributes" field
* of the USB 2.0 Extension descriptor. * of the USB 2.0 Extension descriptor.
@ -1017,7 +1017,7 @@ enum libusb_usb_2_0_extension_attributes {
LIBUSB_BM_LPM_SUPPORT = 2, LIBUSB_BM_LPM_SUPPORT = 2,
}; };
/** \ingroup dev /** \ingroup libusb_dev
* Masks for the bits of the * Masks for the bits of the
* \ref libusb_ss_usb_device_capability_descriptor::bmAttributes "bmAttributes" field * \ref libusb_ss_usb_device_capability_descriptor::bmAttributes "bmAttributes" field
* field of the SuperSpeed USB Device Capability descriptor. * field of the SuperSpeed USB Device Capability descriptor.
@ -1027,7 +1027,7 @@ enum libusb_ss_usb_device_capability_attributes {
LIBUSB_BM_LTM_SUPPORT = 2, LIBUSB_BM_LTM_SUPPORT = 2,
}; };
/** \ingroup dev /** \ingroup libusb_dev
* USB capability types * USB capability types
*/ */
enum libusb_bos_type { enum libusb_bos_type {
@ -1044,7 +1044,7 @@ enum libusb_bos_type {
LIBUSB_BT_CONTAINER_ID = 4, LIBUSB_BT_CONTAINER_ID = 4,
}; };
/** \ingroup misc /** \ingroup libusb_misc
* Error codes. Most libusb functions return 0 on success or one of these * Error codes. Most libusb functions return 0 on success or one of these
* codes on failure. * codes on failure.
* You can call libusb_error_name() to retrieve a string representation of an * You can call libusb_error_name() to retrieve a string representation of an
@ -1101,7 +1101,7 @@ enum libusb_error {
/* Total number of error codes in enum libusb_error */ /* Total number of error codes in enum libusb_error */
#define LIBUSB_ERROR_COUNT 14 #define LIBUSB_ERROR_COUNT 14
/** \ingroup asyncio /** \ingroup libusb_asyncio
* Transfer status codes */ * Transfer status codes */
enum libusb_transfer_status { enum libusb_transfer_status {
/** Transfer completed without error. Note that this does not indicate /** Transfer completed without error. Note that this does not indicate
@ -1131,13 +1131,16 @@ enum libusb_transfer_status {
when adding new status codes here. */ when adding new status codes here. */
}; };
/** \ingroup asyncio /** \ingroup libusb_asyncio
* libusb_transfer.flags values */ * libusb_transfer.flags values */
enum libusb_transfer_flags { enum libusb_transfer_flags {
/** Report short frames as errors */ /** Report short frames as errors */
LIBUSB_TRANSFER_SHORT_NOT_OK = 1<<0, LIBUSB_TRANSFER_SHORT_NOT_OK = 1<<0,
/** Automatically free() transfer buffer during libusb_free_transfer() */ /** Automatically free() transfer buffer during libusb_free_transfer().
* Note that buffers allocated with libusb_dev_mem_alloc() should not
* be attempted freed in this way, since free() is not an appropriate
* way to release such memory. */
LIBUSB_TRANSFER_FREE_BUFFER = 1<<1, LIBUSB_TRANSFER_FREE_BUFFER = 1<<1,
/** Automatically call libusb_free_transfer() after callback returns. /** Automatically call libusb_free_transfer() after callback returns.
@ -1172,7 +1175,7 @@ enum libusb_transfer_flags {
LIBUSB_TRANSFER_ADD_ZERO_PACKET = 1 << 3, LIBUSB_TRANSFER_ADD_ZERO_PACKET = 1 << 3,
}; };
/** \ingroup asyncio /** \ingroup libusb_asyncio
* Isochronous packet descriptor. */ * Isochronous packet descriptor. */
struct libusb_iso_packet_descriptor { struct libusb_iso_packet_descriptor {
/** Length of data to request in this packet */ /** Length of data to request in this packet */
@ -1187,18 +1190,18 @@ struct libusb_iso_packet_descriptor {
struct libusb_transfer; struct libusb_transfer;
/** \ingroup asyncio /** \ingroup libusb_asyncio
* Asynchronous transfer callback function type. When submitting asynchronous * Asynchronous transfer callback function type. When submitting asynchronous
* transfers, you pass a pointer to a callback function of this type via the * transfers, you pass a pointer to a callback function of this type via the
* \ref libusb_transfer::callback "callback" member of the libusb_transfer * \ref libusb_transfer::callback "callback" member of the libusb_transfer
* structure. libusb will call this function later, when the transfer has * structure. libusb will call this function later, when the transfer has
* completed or failed. See \ref asyncio for more information. * completed or failed. See \ref libusb_asyncio for more information.
* \param transfer The libusb_transfer struct the callback function is being * \param transfer The libusb_transfer struct the callback function is being
* notified about. * notified about.
*/ */
typedef void (LIBUSB_CALL *libusb_transfer_cb_fn)(struct libusb_transfer *transfer); typedef void (LIBUSB_CALL *libusb_transfer_cb_fn)(struct libusb_transfer *transfer);
/** \ingroup asyncio /** \ingroup libusb_asyncio
* The generic USB transfer structure. The user populates this structure and * The generic USB transfer structure. The user populates this structure and
* then submits it in order to request a transfer. After the transfer has * then submits it in order to request a transfer. After the transfer has
* completed, the library populates the transfer with the results and passes * completed, the library populates the transfer with the results and passes
@ -1262,7 +1265,7 @@ struct libusb_transfer {
; ;
}; };
/** \ingroup misc /** \ingroup libusb_misc
* Capabilities supported by an instance of libusb on the current running * Capabilities supported by an instance of libusb on the current running
* platform. Test if the loaded library supports a given capability by calling * platform. Test if the loaded library supports a given capability by calling
* \ref libusb_has_capability(). * \ref libusb_has_capability().
@ -1282,7 +1285,7 @@ enum libusb_capability {
LIBUSB_CAP_SUPPORTS_DETACH_KERNEL_DRIVER = 0x0101 LIBUSB_CAP_SUPPORTS_DETACH_KERNEL_DRIVER = 0x0101
}; };
/** \ingroup lib /** \ingroup libusb_lib
* Log message levels. * Log message levels.
* - LIBUSB_LOG_LEVEL_NONE (0) : no messages ever printed by the library (default) * - LIBUSB_LOG_LEVEL_NONE (0) : no messages ever printed by the library (default)
* - LIBUSB_LOG_LEVEL_ERROR (1) : error messages are printed to stderr * - LIBUSB_LOG_LEVEL_ERROR (1) : error messages are printed to stderr
@ -1334,7 +1337,7 @@ int LIBUSB_CALL libusb_get_ss_endpoint_companion_descriptor(
struct libusb_ss_endpoint_companion_descriptor **ep_comp); struct libusb_ss_endpoint_companion_descriptor **ep_comp);
void LIBUSB_CALL libusb_free_ss_endpoint_companion_descriptor( void LIBUSB_CALL libusb_free_ss_endpoint_companion_descriptor(
struct libusb_ss_endpoint_companion_descriptor *ep_comp); struct libusb_ss_endpoint_companion_descriptor *ep_comp);
int LIBUSB_CALL libusb_get_bos_descriptor(libusb_device_handle *handle, int LIBUSB_CALL libusb_get_bos_descriptor(libusb_device_handle *dev_handle,
struct libusb_bos_descriptor **bos); struct libusb_bos_descriptor **bos);
void LIBUSB_CALL libusb_free_bos_descriptor(struct libusb_bos_descriptor *bos); void LIBUSB_CALL libusb_free_bos_descriptor(struct libusb_bos_descriptor *bos);
int LIBUSB_CALL libusb_get_usb_2_0_extension_descriptor( int LIBUSB_CALL libusb_get_usb_2_0_extension_descriptor(
@ -1367,43 +1370,48 @@ int LIBUSB_CALL libusb_get_max_packet_size(libusb_device *dev,
int LIBUSB_CALL libusb_get_max_iso_packet_size(libusb_device *dev, int LIBUSB_CALL libusb_get_max_iso_packet_size(libusb_device *dev,
unsigned char endpoint); unsigned char endpoint);
int LIBUSB_CALL libusb_open(libusb_device *dev, libusb_device_handle **handle); int LIBUSB_CALL libusb_open(libusb_device *dev, libusb_device_handle **dev_handle);
void LIBUSB_CALL libusb_close(libusb_device_handle *dev_handle); void LIBUSB_CALL libusb_close(libusb_device_handle *dev_handle);
libusb_device * LIBUSB_CALL libusb_get_device(libusb_device_handle *dev_handle); libusb_device * LIBUSB_CALL libusb_get_device(libusb_device_handle *dev_handle);
int LIBUSB_CALL libusb_set_configuration(libusb_device_handle *dev, int LIBUSB_CALL libusb_set_configuration(libusb_device_handle *dev_handle,
int configuration); int configuration);
int LIBUSB_CALL libusb_claim_interface(libusb_device_handle *dev, int LIBUSB_CALL libusb_claim_interface(libusb_device_handle *dev_handle,
int interface_number); int interface_number);
int LIBUSB_CALL libusb_release_interface(libusb_device_handle *dev, int LIBUSB_CALL libusb_release_interface(libusb_device_handle *dev_handle,
int interface_number); int interface_number);
libusb_device_handle * LIBUSB_CALL libusb_open_device_with_vid_pid( libusb_device_handle * LIBUSB_CALL libusb_open_device_with_vid_pid(
libusb_context *ctx, uint16_t vendor_id, uint16_t product_id); libusb_context *ctx, uint16_t vendor_id, uint16_t product_id);
int LIBUSB_CALL libusb_set_interface_alt_setting(libusb_device_handle *dev, int LIBUSB_CALL libusb_set_interface_alt_setting(libusb_device_handle *dev_handle,
int interface_number, int alternate_setting); int interface_number, int alternate_setting);
int LIBUSB_CALL libusb_clear_halt(libusb_device_handle *dev, int LIBUSB_CALL libusb_clear_halt(libusb_device_handle *dev_handle,
unsigned char endpoint); unsigned char endpoint);
int LIBUSB_CALL libusb_reset_device(libusb_device_handle *dev); int LIBUSB_CALL libusb_reset_device(libusb_device_handle *dev_handle);
int LIBUSB_CALL libusb_alloc_streams(libusb_device_handle *dev, int LIBUSB_CALL libusb_alloc_streams(libusb_device_handle *dev_handle,
uint32_t num_streams, unsigned char *endpoints, int num_endpoints); uint32_t num_streams, unsigned char *endpoints, int num_endpoints);
int LIBUSB_CALL libusb_free_streams(libusb_device_handle *dev, int LIBUSB_CALL libusb_free_streams(libusb_device_handle *dev_handle,
unsigned char *endpoints, int num_endpoints); unsigned char *endpoints, int num_endpoints);
int LIBUSB_CALL libusb_kernel_driver_active(libusb_device_handle *dev, unsigned char * LIBUSB_CALL libusb_dev_mem_alloc(libusb_device_handle *dev_handle,
size_t length);
int LIBUSB_CALL libusb_dev_mem_free(libusb_device_handle *dev_handle,
unsigned char *buffer, size_t length);
int LIBUSB_CALL libusb_kernel_driver_active(libusb_device_handle *dev_handle,
int interface_number); int interface_number);
int LIBUSB_CALL libusb_detach_kernel_driver(libusb_device_handle *dev, int LIBUSB_CALL libusb_detach_kernel_driver(libusb_device_handle *dev_handle,
int interface_number); int interface_number);
int LIBUSB_CALL libusb_attach_kernel_driver(libusb_device_handle *dev, int LIBUSB_CALL libusb_attach_kernel_driver(libusb_device_handle *dev_handle,
int interface_number); int interface_number);
int LIBUSB_CALL libusb_set_auto_detach_kernel_driver( int LIBUSB_CALL libusb_set_auto_detach_kernel_driver(
libusb_device_handle *dev, int enable); libusb_device_handle *dev_handle, int enable);
/* async I/O */ /* async I/O */
/** \ingroup asyncio /** \ingroup libusb_asyncio
* Get the data section of a control transfer. This convenience function is here * Get the data section of a control transfer. This convenience function is here
* to remind you that the data does not start until 8 bytes into the actual * to remind you that the data does not start until 8 bytes into the actual
* buffer, as the setup packet comes first. * buffer, as the setup packet comes first.
@ -1421,7 +1429,7 @@ static inline unsigned char *libusb_control_transfer_get_data(
return transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE; return transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE;
} }
/** \ingroup asyncio /** \ingroup libusb_asyncio
* Get the control setup packet of a control transfer. This convenience * Get the control setup packet of a control transfer. This convenience
* function is here to remind you that the control setup occupies the first * function is here to remind you that the control setup occupies the first
* 8 bytes of the transfer data buffer. * 8 bytes of the transfer data buffer.
@ -1439,7 +1447,7 @@ static inline struct libusb_control_setup *libusb_control_transfer_get_setup(
return (struct libusb_control_setup *)(void *) transfer->buffer; return (struct libusb_control_setup *)(void *) transfer->buffer;
} }
/** \ingroup asyncio /** \ingroup libusb_asyncio
* Helper function to populate the setup packet (first 8 bytes of the data * Helper function to populate the setup packet (first 8 bytes of the data
* buffer) for a control transfer. The wIndex, wValue and wLength values should * buffer) for a control transfer. The wIndex, wValue and wLength values should
* be given in host-endian byte order. * be given in host-endian byte order.
@ -1483,7 +1491,7 @@ void LIBUSB_CALL libusb_transfer_set_stream_id(
uint32_t LIBUSB_CALL libusb_transfer_get_stream_id( uint32_t LIBUSB_CALL libusb_transfer_get_stream_id(
struct libusb_transfer *transfer); struct libusb_transfer *transfer);
/** \ingroup asyncio /** \ingroup libusb_asyncio
* Helper function to populate the required \ref libusb_transfer fields * Helper function to populate the required \ref libusb_transfer fields
* for a control transfer. * for a control transfer.
* *
@ -1529,7 +1537,7 @@ static inline void libusb_fill_control_transfer(
transfer->callback = callback; transfer->callback = callback;
} }
/** \ingroup asyncio /** \ingroup libusb_asyncio
* Helper function to populate the required \ref libusb_transfer fields * Helper function to populate the required \ref libusb_transfer fields
* for a bulk transfer. * for a bulk transfer.
* *
@ -1557,7 +1565,7 @@ static inline void libusb_fill_bulk_transfer(struct libusb_transfer *transfer,
transfer->callback = callback; transfer->callback = callback;
} }
/** \ingroup asyncio /** \ingroup libusb_asyncio
* Helper function to populate the required \ref libusb_transfer fields * Helper function to populate the required \ref libusb_transfer fields
* for a bulk transfer using bulk streams. * for a bulk transfer using bulk streams.
* *
@ -1585,7 +1593,7 @@ static inline void libusb_fill_bulk_stream_transfer(
libusb_transfer_set_stream_id(transfer, stream_id); libusb_transfer_set_stream_id(transfer, stream_id);
} }
/** \ingroup asyncio /** \ingroup libusb_asyncio
* Helper function to populate the required \ref libusb_transfer fields * Helper function to populate the required \ref libusb_transfer fields
* for an interrupt transfer. * for an interrupt transfer.
* *
@ -1613,7 +1621,7 @@ static inline void libusb_fill_interrupt_transfer(
transfer->callback = callback; transfer->callback = callback;
} }
/** \ingroup asyncio /** \ingroup libusb_asyncio
* Helper function to populate the required \ref libusb_transfer fields * Helper function to populate the required \ref libusb_transfer fields
* for an isochronous transfer. * for an isochronous transfer.
* *
@ -1643,7 +1651,7 @@ static inline void libusb_fill_iso_transfer(struct libusb_transfer *transfer,
transfer->callback = callback; transfer->callback = callback;
} }
/** \ingroup asyncio /** \ingroup libusb_asyncio
* Convenience function to set the length of all packets in an isochronous * Convenience function to set the length of all packets in an isochronous
* transfer, based on the num_iso_packets field in the transfer structure. * transfer, based on the num_iso_packets field in the transfer structure.
* *
@ -1659,7 +1667,7 @@ static inline void libusb_set_iso_packet_lengths(
transfer->iso_packet_desc[i].length = length; transfer->iso_packet_desc[i].length = length;
} }
/** \ingroup asyncio /** \ingroup libusb_asyncio
* Convenience function to locate the position of an isochronous packet * Convenience function to locate the position of an isochronous packet
* within the buffer of an isochronous transfer. * within the buffer of an isochronous transfer.
* *
@ -1698,7 +1706,7 @@ static inline unsigned char *libusb_get_iso_packet_buffer(
return transfer->buffer + offset; return transfer->buffer + offset;
} }
/** \ingroup asyncio /** \ingroup libusb_asyncio
* Convenience function to locate the position of an isochronous packet * Convenience function to locate the position of an isochronous packet
* within the buffer of an isochronous transfer, for transfers where each * within the buffer of an isochronous transfer, for transfers where each
* packet is of identical size. * packet is of identical size.
@ -1749,33 +1757,33 @@ int LIBUSB_CALL libusb_interrupt_transfer(libusb_device_handle *dev_handle,
unsigned char endpoint, unsigned char *data, int length, unsigned char endpoint, unsigned char *data, int length,
int *actual_length, unsigned int timeout); int *actual_length, unsigned int timeout);
/** \ingroup desc /** \ingroup libusb_desc
* Retrieve a descriptor from the default control pipe. * Retrieve a descriptor from the default control pipe.
* This is a convenience function which formulates the appropriate control * This is a convenience function which formulates the appropriate control
* message to retrieve the descriptor. * message to retrieve the descriptor.
* *
* \param dev a device handle * \param dev_handle a device handle
* \param desc_type the descriptor type, see \ref libusb_descriptor_type * \param desc_type the descriptor type, see \ref libusb_descriptor_type
* \param desc_index the index of the descriptor to retrieve * \param desc_index the index of the descriptor to retrieve
* \param data output buffer for descriptor * \param data output buffer for descriptor
* \param length size of data buffer * \param length size of data buffer
* \returns number of bytes returned in data, or LIBUSB_ERROR code on failure * \returns number of bytes returned in data, or LIBUSB_ERROR code on failure
*/ */
static inline int libusb_get_descriptor(libusb_device_handle *dev, static inline int libusb_get_descriptor(libusb_device_handle *dev_handle,
uint8_t desc_type, uint8_t desc_index, unsigned char *data, int length) uint8_t desc_type, uint8_t desc_index, unsigned char *data, int length)
{ {
return libusb_control_transfer(dev, LIBUSB_ENDPOINT_IN, return libusb_control_transfer(dev_handle, LIBUSB_ENDPOINT_IN,
LIBUSB_REQUEST_GET_DESCRIPTOR, (uint16_t) ((desc_type << 8) | desc_index), LIBUSB_REQUEST_GET_DESCRIPTOR, (uint16_t) ((desc_type << 8) | desc_index),
0, data, (uint16_t) length, 1000); 0, data, (uint16_t) length, 1000);
} }
/** \ingroup desc /** \ingroup libusb_desc
* Retrieve a descriptor from a device. * Retrieve a descriptor from a device.
* This is a convenience function which formulates the appropriate control * This is a convenience function which formulates the appropriate control
* message to retrieve the descriptor. The string returned is Unicode, as * message to retrieve the descriptor. The string returned is Unicode, as
* detailed in the USB specifications. * detailed in the USB specifications.
* *
* \param dev a device handle * \param dev_handle a device handle
* \param desc_index the index of the descriptor to retrieve * \param desc_index the index of the descriptor to retrieve
* \param langid the language ID for the string descriptor * \param langid the language ID for the string descriptor
* \param data output buffer for descriptor * \param data output buffer for descriptor
@ -1783,15 +1791,15 @@ static inline int libusb_get_descriptor(libusb_device_handle *dev,
* \returns number of bytes returned in data, or LIBUSB_ERROR code on failure * \returns number of bytes returned in data, or LIBUSB_ERROR code on failure
* \see libusb_get_string_descriptor_ascii() * \see libusb_get_string_descriptor_ascii()
*/ */
static inline int libusb_get_string_descriptor(libusb_device_handle *dev, static inline int libusb_get_string_descriptor(libusb_device_handle *dev_handle,
uint8_t desc_index, uint16_t langid, unsigned char *data, int length) uint8_t desc_index, uint16_t langid, unsigned char *data, int length)
{ {
return libusb_control_transfer(dev, LIBUSB_ENDPOINT_IN, return libusb_control_transfer(dev_handle, LIBUSB_ENDPOINT_IN,
LIBUSB_REQUEST_GET_DESCRIPTOR, (uint16_t)((LIBUSB_DT_STRING << 8) | desc_index), LIBUSB_REQUEST_GET_DESCRIPTOR, (uint16_t)((LIBUSB_DT_STRING << 8) | desc_index),
langid, data, (uint16_t) length, 1000); langid, data, (uint16_t) length, 1000);
} }
int LIBUSB_CALL libusb_get_string_descriptor_ascii(libusb_device_handle *dev, int LIBUSB_CALL libusb_get_string_descriptor_ascii(libusb_device_handle *dev_handle,
uint8_t desc_index, unsigned char *data, int length); uint8_t desc_index, unsigned char *data, int length);
/* polling and timeouts */ /* polling and timeouts */
@ -1801,6 +1809,7 @@ void LIBUSB_CALL libusb_lock_events(libusb_context *ctx);
void LIBUSB_CALL libusb_unlock_events(libusb_context *ctx); void LIBUSB_CALL libusb_unlock_events(libusb_context *ctx);
int LIBUSB_CALL libusb_event_handling_ok(libusb_context *ctx); int LIBUSB_CALL libusb_event_handling_ok(libusb_context *ctx);
int LIBUSB_CALL libusb_event_handler_active(libusb_context *ctx); int LIBUSB_CALL libusb_event_handler_active(libusb_context *ctx);
void LIBUSB_CALL libusb_interrupt_event_handler(libusb_context *ctx);
void LIBUSB_CALL libusb_lock_event_waiters(libusb_context *ctx); void LIBUSB_CALL libusb_lock_event_waiters(libusb_context *ctx);
void LIBUSB_CALL libusb_unlock_event_waiters(libusb_context *ctx); void LIBUSB_CALL libusb_unlock_event_waiters(libusb_context *ctx);
int LIBUSB_CALL libusb_wait_for_event(libusb_context *ctx, struct timeval *tv); int LIBUSB_CALL libusb_wait_for_event(libusb_context *ctx, struct timeval *tv);
@ -1817,7 +1826,7 @@ int LIBUSB_CALL libusb_pollfds_handle_timeouts(libusb_context *ctx);
int LIBUSB_CALL libusb_get_next_timeout(libusb_context *ctx, int LIBUSB_CALL libusb_get_next_timeout(libusb_context *ctx,
struct timeval *tv); struct timeval *tv);
/** \ingroup poll /** \ingroup libusb_poll
* File descriptor for polling * File descriptor for polling
*/ */
struct libusb_pollfd { struct libusb_pollfd {
@ -1831,7 +1840,7 @@ struct libusb_pollfd {
short events; short events;
}; };
/** \ingroup poll /** \ingroup libusb_poll
* Callback function, invoked when a new file descriptor should be added * Callback function, invoked when a new file descriptor should be added
* to the set of file descriptors monitored for events. * to the set of file descriptors monitored for events.
* \param fd the new file descriptor * \param fd the new file descriptor
@ -1844,7 +1853,7 @@ struct libusb_pollfd {
typedef void (LIBUSB_CALL *libusb_pollfd_added_cb)(int fd, short events, typedef void (LIBUSB_CALL *libusb_pollfd_added_cb)(int fd, short events,
void *user_data); void *user_data);
/** \ingroup poll /** \ingroup libusb_poll
* Callback function, invoked when a file descriptor should be removed from * Callback function, invoked when a file descriptor should be removed from
* the set of file descriptors being monitored for events. After returning * the set of file descriptors being monitored for events. After returning
* from this callback, do not use that file descriptor again. * from this callback, do not use that file descriptor again.
@ -1862,7 +1871,7 @@ void LIBUSB_CALL libusb_set_pollfd_notifiers(libusb_context *ctx,
libusb_pollfd_added_cb added_cb, libusb_pollfd_removed_cb removed_cb, libusb_pollfd_added_cb added_cb, libusb_pollfd_removed_cb removed_cb,
void *user_data); void *user_data);
/** \ingroup hotplug /** \ingroup libusb_hotplug
* Callback handle. * Callback handle.
* *
* Callbacks handles are generated by libusb_hotplug_register_callback() * Callbacks handles are generated by libusb_hotplug_register_callback()
@ -1872,11 +1881,11 @@ void LIBUSB_CALL libusb_set_pollfd_notifiers(libusb_context *ctx,
* *
* Since version 1.0.16, \ref LIBUSB_API_VERSION >= 0x01000102 * Since version 1.0.16, \ref LIBUSB_API_VERSION >= 0x01000102
* *
* For more information, see \ref hotplug. * For more information, see \ref libusb_hotplug.
*/ */
typedef int libusb_hotplug_callback_handle; typedef int libusb_hotplug_callback_handle;
/** \ingroup hotplug /** \ingroup libusb_hotplug
* *
* Since version 1.0.16, \ref LIBUSB_API_VERSION >= 0x01000102 * Since version 1.0.16, \ref LIBUSB_API_VERSION >= 0x01000102
* *
@ -1889,7 +1898,7 @@ typedef enum {
LIBUSB_HOTPLUG_ENUMERATE = 1<<0, LIBUSB_HOTPLUG_ENUMERATE = 1<<0,
} libusb_hotplug_flag; } libusb_hotplug_flag;
/** \ingroup hotplug /** \ingroup libusb_hotplug
* *
* Since version 1.0.16, \ref LIBUSB_API_VERSION >= 0x01000102 * Since version 1.0.16, \ref LIBUSB_API_VERSION >= 0x01000102
* *
@ -1904,11 +1913,11 @@ typedef enum {
LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT = 0x02, LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT = 0x02,
} libusb_hotplug_event; } libusb_hotplug_event;
/** \ingroup hotplug /** \ingroup libusb_hotplug
* Wildcard matching for hotplug events */ * Wildcard matching for hotplug events */
#define LIBUSB_HOTPLUG_MATCH_ANY -1 #define LIBUSB_HOTPLUG_MATCH_ANY -1
/** \ingroup hotplug /** \ingroup libusb_hotplug
* Hotplug callback function type. When requesting hotplug event notifications, * Hotplug callback function type. When requesting hotplug event notifications,
* you pass a pointer to a callback function of this type. * you pass a pointer to a callback function of this type.
* *
@ -1916,7 +1925,7 @@ typedef enum {
* recommended the callback do minimal processing before returning. * recommended the callback do minimal processing before returning.
* *
* libusb will call this function later, when a matching event had happened on * libusb will call this function later, when a matching event had happened on
* a matching device. See \ref hotplug for more information. * a matching device. See \ref libusb_hotplug for more information.
* *
* It is safe to call either libusb_hotplug_register_callback() or * It is safe to call either libusb_hotplug_register_callback() or
* libusb_hotplug_deregister_callback() from within a callback function. * libusb_hotplug_deregister_callback() from within a callback function.
@ -1935,7 +1944,7 @@ typedef int (LIBUSB_CALL *libusb_hotplug_callback_fn)(libusb_context *ctx,
libusb_hotplug_event event, libusb_hotplug_event event,
void *user_data); void *user_data);
/** \ingroup hotplug /** \ingroup libusb_hotplug
* Register a hotplug callback function * Register a hotplug callback function
* *
* Register a callback with the libusb_context. The callback will fire * Register a callback with the libusb_context. The callback will fire
@ -1966,7 +1975,7 @@ typedef int (LIBUSB_CALL *libusb_hotplug_callback_fn)(libusb_context *ctx,
* \param[in] dev_class the device class to match or \ref LIBUSB_HOTPLUG_MATCH_ANY * \param[in] dev_class the device class to match or \ref LIBUSB_HOTPLUG_MATCH_ANY
* \param[in] cb_fn the function to be invoked on a matching event/device * \param[in] cb_fn the function to be invoked on a matching event/device
* \param[in] user_data user data to pass to the callback function * \param[in] user_data user data to pass to the callback function
* \param[out] handle pointer to store the handle of the allocated callback (can be NULL) * \param[out] callback_handle pointer to store the handle of the allocated callback (can be NULL)
* \returns LIBUSB_SUCCESS on success LIBUSB_ERROR code on failure * \returns LIBUSB_SUCCESS on success LIBUSB_ERROR code on failure
*/ */
int LIBUSB_CALL libusb_hotplug_register_callback(libusb_context *ctx, int LIBUSB_CALL libusb_hotplug_register_callback(libusb_context *ctx,
@ -1976,9 +1985,9 @@ int LIBUSB_CALL libusb_hotplug_register_callback(libusb_context *ctx,
int dev_class, int dev_class,
libusb_hotplug_callback_fn cb_fn, libusb_hotplug_callback_fn cb_fn,
void *user_data, void *user_data,
libusb_hotplug_callback_handle *handle); libusb_hotplug_callback_handle *callback_handle);
/** \ingroup hotplug /** \ingroup libusb_hotplug
* Deregisters a hotplug callback. * Deregisters a hotplug callback.
* *
* Deregister a callback from a libusb_context. This function is safe to call from within * Deregister a callback from a libusb_context. This function is safe to call from within
@ -1987,10 +1996,10 @@ int LIBUSB_CALL libusb_hotplug_register_callback(libusb_context *ctx,
* Since version 1.0.16, \ref LIBUSB_API_VERSION >= 0x01000102 * Since version 1.0.16, \ref LIBUSB_API_VERSION >= 0x01000102
* *
* \param[in] ctx context this callback is registered with * \param[in] ctx context this callback is registered with
* \param[in] handle the handle of the callback to deregister * \param[in] callback_handle the handle of the callback to deregister
*/ */
void LIBUSB_CALL libusb_hotplug_deregister_callback(libusb_context *ctx, void LIBUSB_CALL libusb_hotplug_deregister_callback(libusb_context *ctx,
libusb_hotplug_callback_handle handle); libusb_hotplug_callback_handle callback_handle);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -160,11 +160,17 @@ static inline void *usbi_reallocf(void *ptr, size_t size)
#define TIMESPEC_IS_SET(ts) ((ts)->tv_sec != 0 || (ts)->tv_nsec != 0) #define TIMESPEC_IS_SET(ts) ((ts)->tv_sec != 0 || (ts)->tv_nsec != 0)
#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
#define TIMEVAL_TV_SEC_TYPE long
#else
#define TIMEVAL_TV_SEC_TYPE time_t
#endif
/* Some platforms don't have this define */ /* Some platforms don't have this define */
#ifndef TIMESPEC_TO_TIMEVAL #ifndef TIMESPEC_TO_TIMEVAL
#define TIMESPEC_TO_TIMEVAL(tv, ts) \ #define TIMESPEC_TO_TIMEVAL(tv, ts) \
do { \ do { \
(tv)->tv_sec = (ts)->tv_sec; \ (tv)->tv_sec = (TIMEVAL_TV_SEC_TYPE) (ts)->tv_sec; \
(tv)->tv_usec = (ts)->tv_nsec / 1000; \ (tv)->tv_usec = (ts)->tv_nsec / 1000; \
} while (0) } while (0)
#endif #endif
@ -200,17 +206,17 @@ void usbi_log_v(struct libusb_context *ctx, enum libusb_log_level level,
va_end(args); \ va_end(args); \
} }
#else #else
#define LOG_BODY(ctxt, level) do { (void)(ctxt); } while(0) #define LOG_BODY(ctxt, level) \
{ \
(void)(ctxt); \
}
#endif #endif
static inline void usbi_info(struct libusb_context *ctx, const char *format, static inline void usbi_info(struct libusb_context *ctx, const char *format, ...)
...)
LOG_BODY(ctx, LIBUSB_LOG_LEVEL_INFO) LOG_BODY(ctx, LIBUSB_LOG_LEVEL_INFO)
static inline void usbi_warn(struct libusb_context *ctx, const char *format, static inline void usbi_warn(struct libusb_context *ctx, const char *format, ...)
...)
LOG_BODY(ctx, LIBUSB_LOG_LEVEL_WARNING) LOG_BODY(ctx, LIBUSB_LOG_LEVEL_WARNING)
static inline void usbi_err( struct libusb_context *ctx, const char *format, static inline void usbi_err(struct libusb_context *ctx, const char *format, ...)
...)
LOG_BODY(ctx, LIBUSB_LOG_LEVEL_ERROR) LOG_BODY(ctx, LIBUSB_LOG_LEVEL_ERROR)
static inline void usbi_dbg(const char *format, ...) static inline void usbi_dbg(const char *format, ...)
@ -218,7 +224,12 @@ static inline void usbi_dbg(const char *format, ...)
#endif /* !defined(_MSC_VER) || _MSC_VER >= 1400 */ #endif /* !defined(_MSC_VER) || _MSC_VER >= 1400 */
#define USBI_GET_CONTEXT(ctx) if (!(ctx)) (ctx) = usbi_default_context #define USBI_GET_CONTEXT(ctx) \
do { \
if (!(ctx)) \
(ctx) = usbi_default_context; \
} while(0)
#define DEVICE_CTX(dev) ((dev)->ctx) #define DEVICE_CTX(dev) ((dev)->ctx)
#define HANDLE_CTX(handle) (DEVICE_CTX((handle)->dev)) #define HANDLE_CTX(handle) (DEVICE_CTX((handle)->dev))
#define TRANSFER_CTX(transfer) (HANDLE_CTX((transfer)->dev_handle)) #define TRANSFER_CTX(transfer) (HANDLE_CTX((transfer)->dev_handle))
@ -234,7 +245,7 @@ static inline void usbi_dbg(const char *format, ...)
#if defined(THREADS_POSIX) #if defined(THREADS_POSIX)
#include "os/threads_posix.h" #include "os/threads_posix.h"
#elif defined(OS_WINDOWS) || defined(OS_WINCE) #elif defined(OS_WINDOWS) || defined(OS_WINCE)
#include <os/threads_windows.h> #include "os/threads_windows.h"
#endif #endif
extern struct libusb_context *usbi_default_context; extern struct libusb_context *usbi_default_context;
@ -266,6 +277,8 @@ struct libusb_context {
* the list, URBs that will time out later are placed after, and urbs with * the list, URBs that will time out later are placed after, and urbs with
* infinite timeout are always placed at the very end. */ * infinite timeout are always placed at the very end. */
struct list_head flying_transfers; struct list_head flying_transfers;
/* Note paths taking both this and usbi_transfer->lock must always
* take this lock first */
usbi_mutex_t flying_transfers_lock; usbi_mutex_t flying_transfers_lock;
/* user callbacks for pollfd changes */ /* user callbacks for pollfd changes */
@ -279,6 +292,10 @@ struct libusb_context {
/* used to see if there is an active thread doing event handling */ /* used to see if there is an active thread doing event handling */
int event_handler_active; int event_handler_active;
/* A thread-local storage key to track which thread is performing event
* handling */
usbi_tls_key_t event_handling_key;
/* used to wait for event completion in threads other than the one that is /* used to wait for event completion in threads other than the one that is
* event handling */ * event handling */
usbi_mutex_t event_waiters_lock; usbi_mutex_t event_waiters_lock;
@ -287,18 +304,19 @@ struct libusb_context {
/* A lock to protect internal context event data. */ /* A lock to protect internal context event data. */
usbi_mutex_t event_data_lock; usbi_mutex_t event_data_lock;
/* A bitmask of flags that are set to indicate specific events that need to
* be handled. Protected by event_data_lock. */
unsigned int event_flags;
/* A counter that is set when we want to interrupt and prevent event handling, /* A counter that is set when we want to interrupt and prevent event handling,
* in order to safely close a device. Protected by event_data_lock. */ * in order to safely close a device. Protected by event_data_lock. */
unsigned int device_close; unsigned int device_close;
/* list and count of poll fds and an array of poll fd structures that is /* list and count of poll fds and an array of poll fd structures that is
* (re)allocated as necessary prior to polling, and a flag to indicate * (re)allocated as necessary prior to polling. Protected by event_data_lock. */
* when the list of poll fds has changed since the last poll.
* Protected by event_data_lock. */
struct list_head ipollfds; struct list_head ipollfds;
struct pollfd *pollfds; struct pollfd *pollfds;
POLL_NFDS_TYPE pollfds_cnt; POLL_NFDS_TYPE pollfds_cnt;
unsigned int pollfds_modified;
/* A list of pending hotplug messages. Protected by event_data_lock. */ /* A list of pending hotplug messages. Protected by event_data_lock. */
struct list_head hotplug_msgs; struct list_head hotplug_msgs;
@ -315,9 +333,27 @@ struct libusb_context {
struct list_head list; struct list_head list;
}; };
enum usbi_event_flags {
/* The list of pollfds has been modified */
USBI_EVENT_POLLFDS_MODIFIED = 1 << 0,
/* The user has interrupted the event handler */
USBI_EVENT_USER_INTERRUPT = 1 << 1,
};
/* Macros for managing event handling state */
#define usbi_handling_events(ctx) \
(usbi_tls_key_get((ctx)->event_handling_key) != NULL)
#define usbi_start_event_handling(ctx) \
usbi_tls_key_set((ctx)->event_handling_key, ctx)
#define usbi_end_event_handling(ctx) \
usbi_tls_key_set((ctx)->event_handling_key, NULL)
/* Update the following macro if new event sources are added */ /* Update the following macro if new event sources are added */
#define usbi_pending_events(ctx) \ #define usbi_pending_events(ctx) \
((ctx)->device_close || (ctx)->pollfds_modified \ ((ctx)->event_flags || (ctx)->device_close \
|| !list_empty(&(ctx)->hotplug_msgs) || !list_empty(&(ctx)->completed_transfers)) || !list_empty(&(ctx)->hotplug_msgs) || !list_empty(&(ctx)->completed_transfers))
#ifdef USBI_TIMERFD_AVAILABLE #ifdef USBI_TIMERFD_AVAILABLE
@ -353,7 +389,11 @@ struct libusb_device {
#else #else
[0] /* non-standard, but usually working code */ [0] /* non-standard, but usually working code */
#endif #endif
#if defined(OS_SUNOS)
__attribute__ ((aligned (8)));
#else
; ;
#endif
}; };
struct libusb_device_handle { struct libusb_device_handle {
@ -370,7 +410,11 @@ struct libusb_device_handle {
#else #else
[0] /* non-standard, but usually working code */ [0] /* non-standard, but usually working code */
#endif #endif
#if defined(OS_SUNOS)
__attribute__ ((aligned (8)));
#else
; ;
#endif
}; };
enum { enum {
@ -398,7 +442,8 @@ struct usbi_transfer {
struct timeval timeout; struct timeval timeout;
int transferred; int transferred;
uint32_t stream_id; uint32_t stream_id;
uint8_t flags; uint8_t state_flags; /* Protected by usbi_transfer->lock */
uint8_t timeout_flags; /* Protected by the flying_stransfers_lock */
/* this lock is held during libusb_submit_transfer() and /* this lock is held during libusb_submit_transfer() and
* libusb_cancel_transfer() (allowing the OS backend to prevent duplicate * libusb_cancel_transfer() (allowing the OS backend to prevent duplicate
@ -406,38 +451,32 @@ struct usbi_transfer {
* should also take this lock in the handle_events path, to prevent the user * should also take this lock in the handle_events path, to prevent the user
* cancelling the transfer from another thread while you are processing * cancelling the transfer from another thread while you are processing
* its completion (presumably there would be races within your OS backend * its completion (presumably there would be races within your OS backend
* if this were possible). */ * if this were possible).
* Note paths taking both this and the flying_transfers_lock must
* always take the flying_transfers_lock first */
usbi_mutex_t lock; usbi_mutex_t lock;
/* this lock should be held whenever viewing or modifying flags
* relating to the transfer state */
usbi_mutex_t flags_lock;
}; };
enum usbi_transfer_flags { enum usbi_transfer_state_flags {
/* The transfer has timed out */ /* Transfer successfully submitted by backend */
USBI_TRANSFER_TIMED_OUT = 1 << 0, USBI_TRANSFER_IN_FLIGHT = 1 << 0,
/* Set by backend submit_transfer() if the OS handles timeout */
USBI_TRANSFER_OS_HANDLES_TIMEOUT = 1 << 1,
/* Cancellation was requested via libusb_cancel_transfer() */ /* Cancellation was requested via libusb_cancel_transfer() */
USBI_TRANSFER_CANCELLING = 1 << 2, USBI_TRANSFER_CANCELLING = 1 << 1,
/* Operation on the transfer failed because the device disappeared */ /* Operation on the transfer failed because the device disappeared */
USBI_TRANSFER_DEVICE_DISAPPEARED = 1 << 3, USBI_TRANSFER_DEVICE_DISAPPEARED = 1 << 2,
};
/* Transfer is currently being submitted */ enum usbi_transfer_timeout_flags {
USBI_TRANSFER_SUBMITTING = 1 << 4, /* Set by backend submit_transfer() if the OS handles timeout */
USBI_TRANSFER_OS_HANDLES_TIMEOUT = 1 << 0,
/* Transfer successfully submitted by backend */
USBI_TRANSFER_IN_FLIGHT = 1 << 5,
/* Completion handler has run */
USBI_TRANSFER_COMPLETED = 1 << 6,
/* The transfer timeout has been handled */ /* The transfer timeout has been handled */
USBI_TRANSFER_TIMEOUT_HANDLED = 1 << 7, USBI_TRANSFER_TIMEOUT_HANDLED = 1 << 1,
/* The transfer timeout was successfully processed */
USBI_TRANSFER_TIMED_OUT = 1 << 2,
}; };
#define USBI_TRANSFER_TO_LIBUSB_TRANSFER(transfer) \ #define USBI_TRANSFER_TO_LIBUSB_TRANSFER(transfer) \
@ -473,7 +512,7 @@ struct libusb_device *usbi_alloc_device(struct libusb_context *ctx,
struct libusb_device *usbi_get_device_by_session_id(struct libusb_context *ctx, struct libusb_device *usbi_get_device_by_session_id(struct libusb_context *ctx,
unsigned long session_id); unsigned long session_id);
int usbi_sanitize_device(struct libusb_device *dev); int usbi_sanitize_device(struct libusb_device *dev);
void usbi_handle_disconnect(struct libusb_device_handle *handle); void usbi_handle_disconnect(struct libusb_device_handle *dev_handle);
int usbi_handle_transfer_completion(struct usbi_transfer *itransfer, int usbi_handle_transfer_completion(struct usbi_transfer *itransfer,
enum libusb_transfer_status status); enum libusb_transfer_status status);
@ -493,7 +532,8 @@ int usbi_signal_event(struct libusb_context *ctx);
int usbi_clear_event(struct libusb_context *ctx); int usbi_clear_event(struct libusb_context *ctx);
/* Internal abstraction for poll (needs struct usbi_transfer on Windows) */ /* Internal abstraction for poll (needs struct usbi_transfer on Windows) */
#if defined(OS_LINUX) || defined(OS_DARWIN) || defined(OS_OPENBSD) || defined(OS_NETBSD) || defined(OS_HAIKU) #if defined(OS_LINUX) || defined(OS_DARWIN) || defined(OS_OPENBSD) || defined(OS_NETBSD) ||\
defined(OS_HAIKU) || defined(OS_SUNOS)
#include <unistd.h> #include <unistd.h>
#include "os/poll_posix.h" #include "os/poll_posix.h"
#elif defined(OS_WINDOWS) || defined(OS_WINCE) #elif defined(OS_WINDOWS) || defined(OS_WINCE)
@ -670,7 +710,7 @@ struct usbi_os_backend {
* Do not worry about freeing the handle on failed open, the upper layers * Do not worry about freeing the handle on failed open, the upper layers
* do this for you. * do this for you.
*/ */
int (*open)(struct libusb_device_handle *handle); int (*open)(struct libusb_device_handle *dev_handle);
/* Close a device such that the handle cannot be used again. Your backend /* Close a device such that the handle cannot be used again. Your backend
* should destroy any resources that were allocated in the open path. * should destroy any resources that were allocated in the open path.
@ -680,7 +720,7 @@ struct usbi_os_backend {
* *
* This function is called when the user closes a device handle. * This function is called when the user closes a device handle.
*/ */
void (*close)(struct libusb_device_handle *handle); void (*close)(struct libusb_device_handle *dev_handle);
/* Retrieve the device descriptor from a device. /* Retrieve the device descriptor from a device.
* *
@ -787,7 +827,7 @@ struct usbi_os_backend {
* blocking * blocking
* - another LIBUSB_ERROR code on other failure. * - another LIBUSB_ERROR code on other failure.
*/ */
int (*get_configuration)(struct libusb_device_handle *handle, int *config); int (*get_configuration)(struct libusb_device_handle *dev_handle, int *config);
/* Set the active configuration for a device. /* Set the active configuration for a device.
* *
@ -804,7 +844,7 @@ struct usbi_os_backend {
* was opened * was opened
* - another LIBUSB_ERROR code on other failure. * - another LIBUSB_ERROR code on other failure.
*/ */
int (*set_configuration)(struct libusb_device_handle *handle, int config); int (*set_configuration)(struct libusb_device_handle *dev_handle, int config);
/* Claim an interface. When claimed, the application can then perform /* Claim an interface. When claimed, the application can then perform
* I/O to an interface's endpoints. * I/O to an interface's endpoints.
@ -823,7 +863,7 @@ struct usbi_os_backend {
* was opened * was opened
* - another LIBUSB_ERROR code on other failure * - another LIBUSB_ERROR code on other failure
*/ */
int (*claim_interface)(struct libusb_device_handle *handle, int interface_number); int (*claim_interface)(struct libusb_device_handle *dev_handle, int interface_number);
/* Release a previously claimed interface. /* Release a previously claimed interface.
* *
@ -840,7 +880,7 @@ struct usbi_os_backend {
* was opened * was opened
* - another LIBUSB_ERROR code on other failure * - another LIBUSB_ERROR code on other failure
*/ */
int (*release_interface)(struct libusb_device_handle *handle, int interface_number); int (*release_interface)(struct libusb_device_handle *dev_handle, int interface_number);
/* Set the alternate setting for an interface. /* Set the alternate setting for an interface.
* *
@ -856,7 +896,7 @@ struct usbi_os_backend {
* was opened * was opened
* - another LIBUSB_ERROR code on other failure * - another LIBUSB_ERROR code on other failure
*/ */
int (*set_interface_altsetting)(struct libusb_device_handle *handle, int (*set_interface_altsetting)(struct libusb_device_handle *dev_handle,
int interface_number, int altsetting); int interface_number, int altsetting);
/* Clear a halt/stall condition on an endpoint. /* Clear a halt/stall condition on an endpoint.
@ -870,12 +910,12 @@ struct usbi_os_backend {
* was opened * was opened
* - another LIBUSB_ERROR code on other failure * - another LIBUSB_ERROR code on other failure
*/ */
int (*clear_halt)(struct libusb_device_handle *handle, int (*clear_halt)(struct libusb_device_handle *dev_handle,
unsigned char endpoint); unsigned char endpoint);
/* Perform a USB port reset to reinitialize a device. /* Perform a USB port reset to reinitialize a device.
* *
* If possible, the handle should still be usable after the reset * If possible, the device handle should still be usable after the reset
* completes, assuming that the device descriptors did not change during * completes, assuming that the device descriptors did not change during
* reset and all previous interface state can be restored. * reset and all previous interface state can be restored.
* *
@ -889,16 +929,26 @@ struct usbi_os_backend {
* has been disconnected since it was opened * has been disconnected since it was opened
* - another LIBUSB_ERROR code on other failure * - another LIBUSB_ERROR code on other failure
*/ */
int (*reset_device)(struct libusb_device_handle *handle); int (*reset_device)(struct libusb_device_handle *dev_handle);
/* Alloc num_streams usb3 bulk streams on the passed in endpoints */ /* Alloc num_streams usb3 bulk streams on the passed in endpoints */
int (*alloc_streams)(struct libusb_device_handle *handle, int (*alloc_streams)(struct libusb_device_handle *dev_handle,
uint32_t num_streams, unsigned char *endpoints, int num_endpoints); uint32_t num_streams, unsigned char *endpoints, int num_endpoints);
/* Free usb3 bulk streams allocated with alloc_streams */ /* Free usb3 bulk streams allocated with alloc_streams */
int (*free_streams)(struct libusb_device_handle *handle, int (*free_streams)(struct libusb_device_handle *dev_handle,
unsigned char *endpoints, int num_endpoints); unsigned char *endpoints, int num_endpoints);
/* Allocate persistent DMA memory for the given device, suitable for
* zerocopy. May return NULL on failure. Optional to implement.
*/
unsigned char *(*dev_mem_alloc)(struct libusb_device_handle *handle,
size_t len);
/* Free memory allocated by dev_mem_alloc. */
int (*dev_mem_free)(struct libusb_device_handle *handle,
unsigned char *buffer, size_t len);
/* Determine if a kernel driver is active on an interface. Optional. /* Determine if a kernel driver is active on an interface. Optional.
* *
* The presence of a kernel driver on an interface indicates that any * The presence of a kernel driver on an interface indicates that any
@ -911,7 +961,7 @@ struct usbi_os_backend {
* was opened * was opened
* - another LIBUSB_ERROR code on other failure * - another LIBUSB_ERROR code on other failure
*/ */
int (*kernel_driver_active)(struct libusb_device_handle *handle, int (*kernel_driver_active)(struct libusb_device_handle *dev_handle,
int interface_number); int interface_number);
/* Detach a kernel driver from an interface. Optional. /* Detach a kernel driver from an interface. Optional.
@ -927,7 +977,7 @@ struct usbi_os_backend {
* was opened * was opened
* - another LIBUSB_ERROR code on other failure * - another LIBUSB_ERROR code on other failure
*/ */
int (*detach_kernel_driver)(struct libusb_device_handle *handle, int (*detach_kernel_driver)(struct libusb_device_handle *dev_handle,
int interface_number); int interface_number);
/* Attach a kernel driver to an interface. Optional. /* Attach a kernel driver to an interface. Optional.
@ -944,7 +994,7 @@ struct usbi_os_backend {
* preventing reattachment * preventing reattachment
* - another LIBUSB_ERROR code on other failure * - another LIBUSB_ERROR code on other failure
*/ */
int (*attach_kernel_driver)(struct libusb_device_handle *handle, int (*attach_kernel_driver)(struct libusb_device_handle *dev_handle,
int interface_number); int interface_number);
/* Destroy a device. Optional. /* Destroy a device. Optional.
@ -1089,8 +1139,10 @@ extern const struct usbi_os_backend darwin_backend;
extern const struct usbi_os_backend openbsd_backend; extern const struct usbi_os_backend openbsd_backend;
extern const struct usbi_os_backend netbsd_backend; extern const struct usbi_os_backend netbsd_backend;
extern const struct usbi_os_backend windows_backend; extern const struct usbi_os_backend windows_backend;
extern const struct usbi_os_backend usbdk_backend;
extern const struct usbi_os_backend wince_backend; extern const struct usbi_os_backend wince_backend;
extern const struct usbi_os_backend haiku_usb_raw_backend; extern const struct usbi_os_backend haiku_usb_raw_backend;
extern const struct usbi_os_backend sunos_backend;
extern struct list_head active_contexts_list; extern struct list_head active_contexts_list;
extern usbi_mutex_static_t active_contexts_lock; extern usbi_mutex_static_t active_contexts_lock;

View File

@ -1,7 +1,7 @@
/* -*- Mode: C; indent-tabs-mode:nil -*- */ /* -*- Mode: C; indent-tabs-mode:nil -*- */
/* /*
* darwin backend for libusb 1.0 * darwin backend for libusb 1.0
* Copyright © 2008-2014 Nathan Hjelm <hjelmn@users.sourceforge.net> * Copyright © 2008-2016 Nathan Hjelm <hjelmn@users.sourceforge.net>
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -19,6 +19,7 @@
*/ */
#include "config.h" #include "config.h"
#include <time.h>
#include <ctype.h> #include <ctype.h>
#include <errno.h> #include <errno.h>
#include <pthread.h> #include <pthread.h>
@ -28,7 +29,7 @@
#include <sys/types.h> #include <sys/types.h>
#include <unistd.h> #include <unistd.h>
#include <fcntl.h> #include <fcntl.h>
#include <libkern/OSAtomic.h> #include <sys/sysctl.h>
#include <mach/clock.h> #include <mach/clock.h>
#include <mach/clock_types.h> #include <mach/clock_types.h>
@ -36,24 +37,43 @@
#include <mach/mach_port.h> #include <mach/mach_port.h>
#include <AvailabilityMacros.h> #include <AvailabilityMacros.h>
#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 && MAC_OS_X_VERSION_MIN_REQUIRED < 101200
#include <objc/objc-auto.h> #include <objc/objc-auto.h>
#endif #endif
#if MAC_OS_X_VERSION_MIN_REQUIRED >= 101200
/* Apple deprecated the darwin atomics in 10.12 in favor of C11 atomics */
#include <stdatomic.h>
#define libusb_darwin_atomic_fetch_add(x, y) atomic_fetch_add(x, y)
_Atomic int32_t initCount = ATOMIC_VAR_INIT(0);
#else
/* use darwin atomics if the target is older than 10.12 */
#include <libkern/OSAtomic.h>
/* OSAtomicAdd32Barrier returns the new value */
#define libusb_darwin_atomic_fetch_add(x, y) (OSAtomicAdd32Barrier(y, x) - y)
static volatile int32_t initCount = 0;
#endif
#include "darwin_usb.h" #include "darwin_usb.h"
/* async event thread */ /* async event thread */
static pthread_mutex_t libusb_darwin_at_mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t libusb_darwin_at_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t libusb_darwin_at_cond = PTHREAD_COND_INITIALIZER; static pthread_cond_t libusb_darwin_at_cond = PTHREAD_COND_INITIALIZER;
static pthread_once_t darwin_init_once = PTHREAD_ONCE_INIT;
static clock_serv_t clock_realtime; static clock_serv_t clock_realtime;
static clock_serv_t clock_monotonic; static clock_serv_t clock_monotonic;
static CFRunLoopRef libusb_darwin_acfl = NULL; /* event cf loop */ static CFRunLoopRef libusb_darwin_acfl = NULL; /* event cf loop */
static volatile int32_t initCount = 0; static CFRunLoopSourceRef libusb_darwin_acfls = NULL; /* shutdown signal for event cf loop */
static usbi_mutex_t darwin_cached_devices_lock = PTHREAD_MUTEX_INITIALIZER; static usbi_mutex_t darwin_cached_devices_lock = PTHREAD_MUTEX_INITIALIZER;
static struct list_head darwin_cached_devices = {&darwin_cached_devices, &darwin_cached_devices}; static struct list_head darwin_cached_devices = {&darwin_cached_devices, &darwin_cached_devices};
static char *darwin_device_class = kIOUSBDeviceClassName;
#define DARWIN_CACHED_DEVICE(a) ((struct darwin_cached_device *) (((struct darwin_device_priv *)((a)->os_priv))->dev)) #define DARWIN_CACHED_DEVICE(a) ((struct darwin_cached_device *) (((struct darwin_device_priv *)((a)->os_priv))->dev))
@ -189,7 +209,7 @@ static int ep_to_pipeRef(struct libusb_device_handle *dev_handle, uint8_t ep, ui
} }
static int usb_setup_device_iterator (io_iterator_t *deviceIterator, UInt32 location) { static int usb_setup_device_iterator (io_iterator_t *deviceIterator, UInt32 location) {
CFMutableDictionaryRef matchingDict = IOServiceMatching(kIOUSBDeviceClassName); CFMutableDictionaryRef matchingDict = IOServiceMatching(darwin_device_class);
if (!matchingDict) if (!matchingDict)
return kIOReturnError; return kIOReturnError;
@ -234,6 +254,27 @@ static int get_ioregistry_value_number (io_service_t service, CFStringRef proper
return ret; return ret;
} }
static int get_ioregistry_value_data (io_service_t service, CFStringRef property, ssize_t size, void *p) {
CFTypeRef cfData = IORegistryEntryCreateCFProperty (service, property, kCFAllocatorDefault, 0);
int ret = 0;
if (cfData) {
if (CFGetTypeID (cfData) == CFDataGetTypeID ()) {
CFIndex length = CFDataGetLength (cfData);
if (length < size) {
size = length;
}
CFDataGetBytes (cfData, CFRangeMake(0, size), p);
ret = 1;
}
CFRelease (cfData);
}
return ret;
}
static usb_device_t **darwin_device_from_service (io_service_t service) static usb_device_t **darwin_device_from_service (io_service_t service)
{ {
io_cf_plugin_ref_t *plugInInterface = NULL; io_cf_plugin_ref_t *plugInInterface = NULL;
@ -344,19 +385,24 @@ static void *darwin_event_thread_main (void *arg0) {
struct libusb_context *ctx = (struct libusb_context *)arg0; struct libusb_context *ctx = (struct libusb_context *)arg0;
CFRunLoopRef runloop; CFRunLoopRef runloop;
#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
/* Set this thread's name, so it can be seen in the debugger /* Set this thread's name, so it can be seen in the debugger
and crash reports. */ and crash reports. */
#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
pthread_setname_np ("org.libusb.device-hotplug"); pthread_setname_np ("org.libusb.device-hotplug");
#endif
#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 && MAC_OS_X_VERSION_MIN_REQUIRED < 101200
/* Tell the Objective-C garbage collector about this thread. /* Tell the Objective-C garbage collector about this thread.
This is required because, unlike NSThreads, pthreads are This is required because, unlike NSThreads, pthreads are
not automatically registered. Although we don't use not automatically registered. Although we don't use
Objective-C, we use CoreFoundation, which does. */ Objective-C, we use CoreFoundation, which does.
Garbage collection support was entirely removed in 10.12,
so don't bother there. */
objc_registerThreadWithCollector(); objc_registerThreadWithCollector();
#endif #endif
/* hotplug (device arrival/removal) sources */ /* hotplug (device arrival/removal) sources */
CFRunLoopSourceContext libusb_shutdown_cfsourcectx;
CFRunLoopSourceRef libusb_notification_cfsource; CFRunLoopSourceRef libusb_notification_cfsource;
io_notification_port_t libusb_notification_port; io_notification_port_t libusb_notification_port;
io_iterator_t libusb_rem_device_iterator; io_iterator_t libusb_rem_device_iterator;
@ -367,6 +413,13 @@ static void *darwin_event_thread_main (void *arg0) {
runloop = CFRunLoopGetCurrent (); runloop = CFRunLoopGetCurrent ();
CFRetain (runloop); CFRetain (runloop);
/* add the shutdown cfsource to the run loop */
memset(&libusb_shutdown_cfsourcectx, 0, sizeof(libusb_shutdown_cfsourcectx));
libusb_shutdown_cfsourcectx.info = runloop;
libusb_shutdown_cfsourcectx.perform = (void (*)(void *))CFRunLoopStop;
libusb_darwin_acfls = CFRunLoopSourceCreate(NULL, 0, &libusb_shutdown_cfsourcectx);
CFRunLoopAddSource(runloop, libusb_darwin_acfls, kCFRunLoopDefaultMode);
/* add the notification port to the run loop */ /* add the notification port to the run loop */
libusb_notification_port = IONotificationPortCreate (kIOMasterPortDefault); libusb_notification_port = IONotificationPortCreate (kIOMasterPortDefault);
libusb_notification_cfsource = IONotificationPortGetRunLoopSource (libusb_notification_port); libusb_notification_cfsource = IONotificationPortGetRunLoopSource (libusb_notification_port);
@ -374,7 +427,7 @@ static void *darwin_event_thread_main (void *arg0) {
/* create notifications for removed devices */ /* create notifications for removed devices */
kresult = IOServiceAddMatchingNotification (libusb_notification_port, kIOTerminatedNotification, kresult = IOServiceAddMatchingNotification (libusb_notification_port, kIOTerminatedNotification,
IOServiceMatching(kIOUSBDeviceClassName), IOServiceMatching(darwin_device_class),
darwin_devices_detached, darwin_devices_detached,
ctx, &libusb_rem_device_iterator); ctx, &libusb_rem_device_iterator);
@ -386,7 +439,7 @@ static void *darwin_event_thread_main (void *arg0) {
/* create notifications for attached devices */ /* create notifications for attached devices */
kresult = IOServiceAddMatchingNotification(libusb_notification_port, kIOFirstMatchNotification, kresult = IOServiceAddMatchingNotification(libusb_notification_port, kIOFirstMatchNotification,
IOServiceMatching(kIOUSBDeviceClassName), IOServiceMatching(darwin_device_class),
darwin_devices_attached, darwin_devices_attached,
ctx, &libusb_add_device_iterator); ctx, &libusb_add_device_iterator);
@ -416,6 +469,9 @@ static void *darwin_event_thread_main (void *arg0) {
/* remove the notification cfsource */ /* remove the notification cfsource */
CFRunLoopRemoveSource(runloop, libusb_notification_cfsource, kCFRunLoopDefaultMode); CFRunLoopRemoveSource(runloop, libusb_notification_cfsource, kCFRunLoopDefaultMode);
/* remove the shutdown cfsource */
CFRunLoopRemoveSource(runloop, libusb_darwin_acfls, kCFRunLoopDefaultMode);
/* delete notification port */ /* delete notification port */
IONotificationPortDestroy (libusb_notification_port); IONotificationPortDestroy (libusb_notification_port);
@ -423,8 +479,10 @@ static void *darwin_event_thread_main (void *arg0) {
IOObjectRelease (libusb_rem_device_iterator); IOObjectRelease (libusb_rem_device_iterator);
IOObjectRelease (libusb_add_device_iterator); IOObjectRelease (libusb_add_device_iterator);
CFRelease (libusb_darwin_acfls);
CFRelease (runloop); CFRelease (runloop);
libusb_darwin_acfls = NULL;
libusb_darwin_acfl = NULL; libusb_darwin_acfl = NULL;
pthread_exit (NULL); pthread_exit (NULL);
@ -441,16 +499,37 @@ static void __attribute__((destructor)) _darwin_finalize(void) {
usbi_mutex_unlock(&darwin_cached_devices_lock); usbi_mutex_unlock(&darwin_cached_devices_lock);
} }
static void darwin_check_version (void) {
/* adjust for changes in the USB stack in xnu 15 */
int sysctl_args[] = {CTL_KERN, KERN_OSRELEASE};
long version;
char version_string[256] = {'\0',};
size_t length = 256;
sysctl(sysctl_args, 2, version_string, &length, NULL, 0);
errno = 0;
version = strtol (version_string, NULL, 10);
if (0 == errno && version >= 15) {
darwin_device_class = "IOUSBHostDevice";
}
}
static int darwin_init(struct libusb_context *ctx) { static int darwin_init(struct libusb_context *ctx) {
host_name_port_t host_self; host_name_port_t host_self;
int rc; int rc;
rc = pthread_once (&darwin_init_once, darwin_check_version);
if (rc) {
return LIBUSB_ERROR_OTHER;
}
rc = darwin_scan_devices (ctx); rc = darwin_scan_devices (ctx);
if (LIBUSB_SUCCESS != rc) { if (LIBUSB_SUCCESS != rc) {
return rc; return rc;
} }
if (OSAtomicIncrement32Barrier(&initCount) == 1) { if (libusb_darwin_atomic_fetch_add (&initCount, 1) == 0) {
/* create the clocks that will be used */ /* create the clocks that will be used */
host_self = mach_host_self(); host_self = mach_host_self();
@ -470,12 +549,13 @@ static int darwin_init(struct libusb_context *ctx) {
} }
static void darwin_exit (void) { static void darwin_exit (void) {
if (OSAtomicDecrement32Barrier(&initCount) == 0) { if (libusb_darwin_atomic_fetch_add (&initCount, -1) == 1) {
mach_port_deallocate(mach_task_self(), clock_realtime); mach_port_deallocate(mach_task_self(), clock_realtime);
mach_port_deallocate(mach_task_self(), clock_monotonic); mach_port_deallocate(mach_task_self(), clock_monotonic);
/* stop the event runloop and wait for the thread to terminate. */ /* stop the event runloop and wait for the thread to terminate. */
CFRunLoopStop (libusb_darwin_acfl); CFRunLoopSourceSignal(libusb_darwin_acfls);
CFRunLoopWakeUp (libusb_darwin_acfl);
pthread_join (libusb_darwin_at, NULL); pthread_join (libusb_darwin_at, NULL);
} }
} }
@ -570,6 +650,14 @@ static int darwin_check_configuration (struct libusb_context *ctx, struct darwin
return LIBUSB_ERROR_OTHER; /* no configurations at this speed so we can't use it */ return LIBUSB_ERROR_OTHER; /* no configurations at this speed so we can't use it */
} }
/* checking the configuration of a root hub simulation takes ~1 s in 10.11. the device is
not usable anyway */
if (0x05ac == dev->dev_descriptor.idVendor && 0x8005 == dev->dev_descriptor.idProduct) {
usbi_dbg ("ignoring configuration on root hub simulation");
dev->active_config = 0;
return 0;
}
/* find the first configuration */ /* find the first configuration */
kresult = (*darwin_device)->GetConfigurationDescriptorPtr (darwin_device, 0, &configDesc); kresult = (*darwin_device)->GetConfigurationDescriptorPtr (darwin_device, 0, &configDesc);
dev->first_config = (kIOReturnSuccess == kresult) ? configDesc->bConfigurationValue : 1; dev->first_config = (kIOReturnSuccess == kresult) ? configDesc->bConfigurationValue : 1;
@ -710,7 +798,7 @@ static int darwin_cache_device_descriptor (struct libusb_context *ctx, struct da
if (kIOReturnSuccess != ret) { if (kIOReturnSuccess != ret) {
usbi_dbg("kernel responded with code: 0x%08x. sleeping for %d ms before trying again", ret, delay/1000); usbi_dbg("kernel responded with code: 0x%08x. sleeping for %d ms before trying again", ret, delay/1000);
/* sleep for a little while before trying again */ /* sleep for a little while before trying again */
usleep (delay); nanosleep(&(struct timespec){delay / 1000000, (delay * 1000) % 1000000000UL}, NULL);
} }
} while (kIOReturnSuccess != ret && retries--); } while (kIOReturnSuccess != ret && retries--);
@ -760,6 +848,24 @@ static int darwin_cache_device_descriptor (struct libusb_context *ctx, struct da
return LIBUSB_SUCCESS; return LIBUSB_SUCCESS;
} }
static int get_device_port (io_service_t service, UInt8 *port) {
kern_return_t result;
io_service_t parent;
int ret = 0;
if (get_ioregistry_value_number (service, CFSTR("PortNum"), kCFNumberSInt8Type, port)) {
return 1;
}
result = IORegistryEntryGetParentEntry (service, kIOServicePlane, &parent);
if (kIOReturnSuccess == result) {
ret = get_ioregistry_value_data (parent, CFSTR("port"), 1, port);
IOObjectRelease (parent);
}
return ret;
}
static int darwin_get_cached_device(struct libusb_context *ctx, io_service_t service, static int darwin_get_cached_device(struct libusb_context *ctx, io_service_t service,
struct darwin_cached_device **cached_out) { struct darwin_cached_device **cached_out) {
struct darwin_cached_device *new_device; struct darwin_cached_device *new_device;
@ -772,7 +878,9 @@ static int darwin_get_cached_device(struct libusb_context *ctx, io_service_t ser
/* get some info from the io registry */ /* get some info from the io registry */
(void) get_ioregistry_value_number (service, CFSTR("sessionID"), kCFNumberSInt64Type, &sessionID); (void) get_ioregistry_value_number (service, CFSTR("sessionID"), kCFNumberSInt64Type, &sessionID);
(void) get_ioregistry_value_number (service, CFSTR("PortNum"), kCFNumberSInt8Type, &port); if (!get_device_port (service, &port)) {
usbi_dbg("could not get connected port number");
}
usbi_dbg("finding cached device for sessionID 0x%" PRIx64, sessionID); usbi_dbg("finding cached device for sessionID 0x%" PRIx64, sessionID);
@ -1111,7 +1219,7 @@ static int get_endpoints (struct libusb_device_handle *dev_handle, int iface) {
u_int8_t numep, direction, number; u_int8_t numep, direction, number;
u_int8_t dont_care1, dont_care3; u_int8_t dont_care1, dont_care3;
u_int16_t dont_care2; u_int16_t dont_care2;
int i; int rc;
usbi_dbg ("building table of endpoints."); usbi_dbg ("building table of endpoints.");
@ -1123,21 +1231,38 @@ static int get_endpoints (struct libusb_device_handle *dev_handle, int iface) {
} }
/* iterate through pipe references */ /* iterate through pipe references */
for (i = 1 ; i <= numep ; i++) { for (int i = 1 ; i <= numep ; i++) {
kresult = (*(cInterface->interface))->GetPipeProperties(cInterface->interface, i, &direction, &number, &dont_care1, kresult = (*(cInterface->interface))->GetPipeProperties(cInterface->interface, i, &direction, &number, &dont_care1,
&dont_care2, &dont_care3); &dont_care2, &dont_care3);
if (kresult != kIOReturnSuccess) { if (kresult != kIOReturnSuccess) {
usbi_err (HANDLE_CTX (dev_handle), "error getting pipe information for pipe %d: %s", i, darwin_error_str(kresult)); /* probably a buggy device. try to get the endpoint address from the descriptors */
struct libusb_config_descriptor *config;
const struct libusb_endpoint_descriptor *endpoint_desc;
UInt8 alt_setting;
kresult = (*(cInterface->interface))->GetAlternateSetting (cInterface->interface, &alt_setting);
if (kresult) {
usbi_err (HANDLE_CTX (dev_handle), "can't get alternate setting for interface");
return darwin_to_libusb (kresult); return darwin_to_libusb (kresult);
} }
usbi_dbg ("interface: %i pipe %i: dir: %i number: %i", iface, i, direction, number); rc = libusb_get_active_config_descriptor (dev_handle->dev, &config);
if (LIBUSB_SUCCESS != rc) {
return rc;
}
endpoint_desc = config->interface[iface].altsetting[alt_setting].endpoint + i - 1;
cInterface->endpoint_addrs[i - 1] = endpoint_desc->bEndpointAddress;
} else {
cInterface->endpoint_addrs[i - 1] = (((kUSBIn == direction) << kUSBRqDirnShift) | (number & LIBUSB_ENDPOINT_ADDRESS_MASK)); cInterface->endpoint_addrs[i - 1] = (((kUSBIn == direction) << kUSBRqDirnShift) | (number & LIBUSB_ENDPOINT_ADDRESS_MASK));
} }
usbi_dbg ("interface: %i pipe %i: dir: %i number: %i", iface, i, cInterface->endpoint_addrs[i - 1] >> kUSBRqDirnShift,
cInterface->endpoint_addrs[i - 1] & LIBUSB_ENDPOINT_ADDRESS_MASK);
}
cInterface->num_endpoints = numep; cInterface->num_endpoints = numep;
return 0; return 0;
@ -1275,7 +1400,7 @@ static int darwin_release_interface(struct libusb_device_handle *dev_handle, int
if (kresult != kIOReturnSuccess) if (kresult != kIOReturnSuccess)
usbi_warn (HANDLE_CTX (dev_handle), "Release: %s", darwin_error_str(kresult)); usbi_warn (HANDLE_CTX (dev_handle), "Release: %s", darwin_error_str(kresult));
cInterface->interface = IO_OBJECT_NULL; cInterface->interface = (usb_interface_t **) IO_OBJECT_NULL;
return darwin_to_libusb (kresult); return darwin_to_libusb (kresult);
} }
@ -1407,14 +1532,14 @@ static int darwin_kernel_driver_active(struct libusb_device_handle *dev_handle,
/* attaching/detaching kernel drivers is not currently supported (maybe in the future?) */ /* attaching/detaching kernel drivers is not currently supported (maybe in the future?) */
static int darwin_attach_kernel_driver (struct libusb_device_handle *dev_handle, int interface) { static int darwin_attach_kernel_driver (struct libusb_device_handle *dev_handle, int interface) {
(void)dev_handle; UNUSED(dev_handle);
(void)interface; UNUSED(interface);
return LIBUSB_ERROR_NOT_SUPPORTED; return LIBUSB_ERROR_NOT_SUPPORTED;
} }
static int darwin_detach_kernel_driver (struct libusb_device_handle *dev_handle, int interface) { static int darwin_detach_kernel_driver (struct libusb_device_handle *dev_handle, int interface) {
(void)dev_handle; UNUSED(dev_handle);
(void)interface; UNUSED(interface);
return LIBUSB_ERROR_NOT_SUPPORTED; return LIBUSB_ERROR_NOT_SUPPORTED;
} }
@ -1471,7 +1596,7 @@ static int submit_bulk_transfer(struct usbi_transfer *itransfer) {
ret = (*(cInterface->interface))->WritePipeAsync(cInterface->interface, pipeRef, transfer->buffer, ret = (*(cInterface->interface))->WritePipeAsync(cInterface->interface, pipeRef, transfer->buffer,
transfer->length, darwin_async_io_callback, itransfer); transfer->length, darwin_async_io_callback, itransfer);
} else { } else {
itransfer->flags |= USBI_TRANSFER_OS_HANDLES_TIMEOUT; itransfer->timeout_flags |= USBI_TRANSFER_OS_HANDLES_TIMEOUT;
if (IS_XFERIN(transfer)) if (IS_XFERIN(transfer))
ret = (*(cInterface->interface))->ReadPipeAsyncTO(cInterface->interface, pipeRef, transfer->buffer, ret = (*(cInterface->interface))->ReadPipeAsyncTO(cInterface->interface, pipeRef, transfer->buffer,
@ -1503,7 +1628,7 @@ static int submit_stream_transfer(struct usbi_transfer *itransfer) {
return LIBUSB_ERROR_NOT_FOUND; return LIBUSB_ERROR_NOT_FOUND;
} }
itransfer->flags |= USBI_TRANSFER_OS_HANDLES_TIMEOUT; itransfer->timeout_flags |= USBI_TRANSFER_OS_HANDLES_TIMEOUT;
if (IS_XFERIN(transfer)) if (IS_XFERIN(transfer))
ret = (*(cInterface->interface))->ReadStreamsPipeAsyncTO(cInterface->interface, pipeRef, itransfer->stream_id, ret = (*(cInterface->interface))->ReadStreamsPipeAsyncTO(cInterface->interface, pipeRef, itransfer->stream_id,
@ -1619,7 +1744,7 @@ static int submit_control_transfer(struct usbi_transfer *itransfer) {
bzero(&tpriv->req, sizeof(tpriv->req)); bzero(&tpriv->req, sizeof(tpriv->req));
/* IOUSBDeviceInterface expects the request in cpu endianess */ /* IOUSBDeviceInterface expects the request in cpu endianness */
tpriv->req.bmRequestType = setup->bmRequestType; tpriv->req.bmRequestType = setup->bmRequestType;
tpriv->req.bRequest = setup->bRequest; tpriv->req.bRequest = setup->bRequest;
/* these values should be in bus order from libusb_fill_control_setup */ /* these values should be in bus order from libusb_fill_control_setup */
@ -1631,7 +1756,7 @@ static int submit_control_transfer(struct usbi_transfer *itransfer) {
tpriv->req.completionTimeout = transfer->timeout; tpriv->req.completionTimeout = transfer->timeout;
tpriv->req.noDataTimeout = transfer->timeout; tpriv->req.noDataTimeout = transfer->timeout;
itransfer->flags |= USBI_TRANSFER_OS_HANDLES_TIMEOUT; itransfer->timeout_flags |= USBI_TRANSFER_OS_HANDLES_TIMEOUT;
/* all transfers in libusb-1.0 are async */ /* all transfers in libusb-1.0 are async */
@ -1780,7 +1905,7 @@ static void darwin_async_io_callback (void *refcon, IOReturn result, void *arg0)
} }
static int darwin_transfer_status (struct usbi_transfer *itransfer, kern_return_t result) { static int darwin_transfer_status (struct usbi_transfer *itransfer, kern_return_t result) {
if (itransfer->flags & USBI_TRANSFER_TIMED_OUT) if (itransfer->timeout_flags & USBI_TRANSFER_TIMED_OUT)
result = kIOUSBTransactionTimeout; result = kIOUSBTransactionTimeout;
switch (result) { switch (result) {
@ -1797,7 +1922,7 @@ static int darwin_transfer_status (struct usbi_transfer *itransfer, kern_return_
return LIBUSB_TRANSFER_OVERFLOW; return LIBUSB_TRANSFER_OVERFLOW;
case kIOUSBTransactionTimeout: case kIOUSBTransactionTimeout:
usbi_warn (ITRANSFER_CTX (itransfer), "transfer error: timed out"); usbi_warn (ITRANSFER_CTX (itransfer), "transfer error: timed out");
itransfer->flags |= USBI_TRANSFER_TIMED_OUT; itransfer->timeout_flags |= USBI_TRANSFER_TIMED_OUT;
return LIBUSB_TRANSFER_TIMED_OUT; return LIBUSB_TRANSFER_TIMED_OUT;
default: default:
usbi_warn (ITRANSFER_CTX (itransfer), "transfer error: %s (value = 0x%08x)", darwin_error_str (result), result); usbi_warn (ITRANSFER_CTX (itransfer), "transfer error: %s (value = 0x%08x)", darwin_error_str (result), result);

View File

@ -1,6 +1,6 @@
/* /*
* darwin backend for libusb 1.0 * darwin backend for libusb 1.0
* Copyright © 2008-2013 Nathan Hjelm <hjelmn@users.sourceforge.net> * Copyright © 2008-2015 Nathan Hjelm <hjelmn@users.sourceforge.net>
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -28,7 +28,13 @@
#include <IOKit/IOCFPlugIn.h> #include <IOKit/IOCFPlugIn.h>
/* IOUSBInterfaceInferface */ /* IOUSBInterfaceInferface */
#if defined (kIOUSBInterfaceInterfaceID550) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_9 #if defined (kIOUSBInterfaceInterfaceID700) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_9
#define usb_interface_t IOUSBInterfaceInterface700
#define InterfaceInterfaceID kIOUSBInterfaceInterfaceID700
#define InterfaceVersion 700
#elif defined (kIOUSBInterfaceInterfaceID550) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_9
#define usb_interface_t IOUSBInterfaceInterface550 #define usb_interface_t IOUSBInterfaceInterface550
#define InterfaceInterfaceID kIOUSBInterfaceInterfaceID550 #define InterfaceInterfaceID kIOUSBInterfaceInterfaceID550

View File

@ -0,0 +1,367 @@
/*
* Copyright 2007-2008, Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Michael Lotz <mmlr@mlotz.ch>
*/
#include "haiku_usb.h"
#include <cstdio>
#include <Directory.h>
#include <Entry.h>
#include <Looper.h>
#include <Messenger.h>
#include <Node.h>
#include <NodeMonitor.h>
#include <Path.h>
#include <cstring>
class WatchedEntry {
public:
WatchedEntry(BMessenger *, entry_ref *);
~WatchedEntry();
bool EntryCreated(entry_ref *ref);
bool EntryRemoved(ino_t node);
bool InitCheck();
private:
BMessenger* fMessenger;
node_ref fNode;
bool fIsDirectory;
USBDevice* fDevice;
WatchedEntry* fEntries;
WatchedEntry* fLink;
bool fInitCheck;
};
class RosterLooper : public BLooper {
public:
RosterLooper(USBRoster *);
void Stop();
virtual void MessageReceived(BMessage *);
bool InitCheck();
private:
USBRoster* fRoster;
WatchedEntry* fRoot;
BMessenger* fMessenger;
bool fInitCheck;
};
WatchedEntry::WatchedEntry(BMessenger *messenger, entry_ref *ref)
: fMessenger(messenger),
fIsDirectory(false),
fDevice(NULL),
fEntries(NULL),
fLink(NULL),
fInitCheck(false)
{
BEntry entry(ref);
entry.GetNodeRef(&fNode);
BDirectory directory;
if (entry.IsDirectory() && directory.SetTo(ref) >= B_OK) {
fIsDirectory = true;
while (directory.GetNextEntry(&entry) >= B_OK) {
if (entry.GetRef(ref) < B_OK)
continue;
WatchedEntry *child = new(std::nothrow) WatchedEntry(fMessenger, ref);
if (child == NULL)
continue;
if (child->InitCheck() == false) {
delete child;
continue;
}
child->fLink = fEntries;
fEntries = child;
}
watch_node(&fNode, B_WATCH_DIRECTORY, *fMessenger);
}
else {
if (strncmp(ref->name, "raw", 3) == 0)
return;
BPath path, parent_path;
entry.GetPath(&path);
fDevice = new(std::nothrow) USBDevice(path.Path());
if (fDevice != NULL && fDevice->InitCheck() == true) {
// Add this new device to each active context's device list
struct libusb_context *ctx;
unsigned long session_id = (unsigned long)&fDevice;
usbi_mutex_lock(&active_contexts_lock);
list_for_each_entry(ctx, &active_contexts_list, list, struct libusb_context) {
struct libusb_device *dev = usbi_get_device_by_session_id(ctx, session_id);
if (dev) {
usbi_dbg("using previously allocated device with location %lu", session_id);
libusb_unref_device(dev);
continue;
}
usbi_dbg("allocating new device with location %lu", session_id);
dev = usbi_alloc_device(ctx, session_id);
if (!dev) {
usbi_dbg("device allocation failed");
continue;
}
*((USBDevice **)dev->os_priv) = fDevice;
// Calculate pseudo-device-address
int addr, tmp;
if (strcmp(path.Leaf(), "hub") == 0)
tmp = 100; //Random Number
else
sscanf(path.Leaf(), "%d", &tmp);
addr = tmp + 1;
path.GetParent(&parent_path);
while (strcmp(parent_path.Leaf(), "usb") != 0) {
sscanf(parent_path.Leaf(), "%d", &tmp);
addr += tmp + 1;
parent_path.GetParent(&parent_path);
}
sscanf(path.Path(), "/dev/bus/usb/%d", &dev->bus_number);
dev->device_address = addr - (dev->bus_number + 1);
if (usbi_sanitize_device(dev) < 0) {
usbi_dbg("device sanitization failed");
libusb_unref_device(dev);
continue;
}
usbi_connect_device(dev);
}
usbi_mutex_unlock(&active_contexts_lock);
}
else if (fDevice) {
delete fDevice;
fDevice = NULL;
return;
}
}
fInitCheck = true;
}
WatchedEntry::~WatchedEntry()
{
if (fIsDirectory) {
watch_node(&fNode, B_STOP_WATCHING, *fMessenger);
WatchedEntry *child = fEntries;
while (child) {
WatchedEntry *next = child->fLink;
delete child;
child = next;
}
}
if (fDevice) {
// Remove this device from each active context's device list
struct libusb_context *ctx;
struct libusb_device *dev;
unsigned long session_id = (unsigned long)&fDevice;
usbi_mutex_lock(&active_contexts_lock);
list_for_each_entry(ctx, &active_contexts_list, list, struct libusb_context) {
dev = usbi_get_device_by_session_id(ctx, session_id);
if (dev != NULL) {
usbi_disconnect_device(dev);
libusb_unref_device(dev);
} else {
usbi_dbg("device with location %lu not found", session_id);
}
}
usbi_mutex_static_unlock(&active_contexts_lock);
delete fDevice;
}
}
bool
WatchedEntry::EntryCreated(entry_ref *ref)
{
if (!fIsDirectory)
return false;
if (ref->directory != fNode.node) {
WatchedEntry *child = fEntries;
while (child) {
if (child->EntryCreated(ref))
return true;
child = child->fLink;
}
return false;
}
WatchedEntry *child = new(std::nothrow) WatchedEntry(fMessenger, ref);
if (child == NULL)
return false;
child->fLink = fEntries;
fEntries = child;
return true;
}
bool
WatchedEntry::EntryRemoved(ino_t node)
{
if (!fIsDirectory)
return false;
WatchedEntry *child = fEntries;
WatchedEntry *lastChild = NULL;
while (child) {
if (child->fNode.node == node) {
if (lastChild)
lastChild->fLink = child->fLink;
else
fEntries = child->fLink;
delete child;
return true;
}
if (child->EntryRemoved(node))
return true;
lastChild = child;
child = child->fLink;
}
return false;
}
bool
WatchedEntry::InitCheck()
{
return fInitCheck;
}
RosterLooper::RosterLooper(USBRoster *roster)
: BLooper("LibusbRoster Looper"),
fRoster(roster),
fRoot(NULL),
fMessenger(NULL),
fInitCheck(false)
{
BEntry entry("/dev/bus/usb");
if (!entry.Exists()) {
usbi_err(NULL, "usb_raw not published");
return;
}
Run();
fMessenger = new(std::nothrow) BMessenger(this);
if (fMessenger == NULL) {
usbi_err(NULL, "error creating BMessenger object");
return;
}
if (Lock()) {
entry_ref ref;
entry.GetRef(&ref);
fRoot = new(std::nothrow) WatchedEntry(fMessenger, &ref);
Unlock();
if (fRoot == NULL)
return;
if (fRoot->InitCheck() == false) {
delete fRoot;
fRoot = NULL;
return;
}
}
fInitCheck = true;
}
void
RosterLooper::Stop()
{
Lock();
delete fRoot;
delete fMessenger;
Quit();
}
void
RosterLooper::MessageReceived(BMessage *message)
{
int32 opcode;
if (message->FindInt32("opcode", &opcode) < B_OK)
return;
switch (opcode) {
case B_ENTRY_CREATED:
{
dev_t device;
ino_t directory;
const char *name;
if (message->FindInt32("device", &device) < B_OK ||
message->FindInt64("directory", &directory) < B_OK ||
message->FindString("name", &name) < B_OK)
break;
entry_ref ref(device, directory, name);
fRoot->EntryCreated(&ref);
break;
}
case B_ENTRY_REMOVED:
{
ino_t node;
if (message->FindInt64("node", &node) < B_OK)
break;
fRoot->EntryRemoved(node);
break;
}
}
}
bool
RosterLooper::InitCheck()
{
return fInitCheck;
}
USBRoster::USBRoster()
: fLooper(NULL)
{
}
USBRoster::~USBRoster()
{
Stop();
}
int
USBRoster::Start()
{
if (fLooper == NULL) {
fLooper = new(std::nothrow) RosterLooper(this);
if (fLooper == NULL || ((RosterLooper *)fLooper)->InitCheck() == false) {
if (fLooper)
fLooper = NULL;
return LIBUSB_ERROR_OTHER;
}
}
return LIBUSB_SUCCESS;
}
void
USBRoster::Stop()
{
if (fLooper) {
((RosterLooper *)fLooper)->Stop();
fLooper = NULL;
}
}

112
Externals/libusb/libusb/os/haiku_usb.h vendored Normal file
View File

@ -0,0 +1,112 @@
/*
* Haiku Backend for libusb
* Copyright © 2014 Akshay Jaggi <akshay1994.leo@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 <List.h>
#include <Locker.h>
#include <Autolock.h>
#include <USBKit.h>
#include <map>
#include "libusbi.h"
#include "haiku_usb_raw.h"
using namespace std;
class USBDevice;
class USBDeviceHandle;
class USBTransfer;
class USBDevice {
public:
USBDevice(const char *);
virtual ~USBDevice();
const char* Location() const;
uint8 CountConfigurations() const;
const usb_device_descriptor* Descriptor() const;
const usb_configuration_descriptor* ConfigurationDescriptor(uint32) const;
const usb_configuration_descriptor* ActiveConfiguration() const;
uint8 EndpointToIndex(uint8) const;
uint8 EndpointToInterface(uint8) const;
int ClaimInterface(int);
int ReleaseInterface(int);
int CheckInterfacesFree(int);
int SetActiveConfiguration(int);
int ActiveConfigurationIndex() const;
bool InitCheck();
private:
int Initialise();
unsigned int fClaimedInterfaces; // Max Interfaces can be 32. Using a bitmask
usb_device_descriptor fDeviceDescriptor;
unsigned char** fConfigurationDescriptors;
int fActiveConfiguration;
char* fPath;
map<uint8,uint8> fConfigToIndex;
map<uint8,uint8>* fEndpointToIndex;
map<uint8,uint8>* fEndpointToInterface;
bool fInitCheck;
};
class USBDeviceHandle {
public:
USBDeviceHandle(USBDevice *dev);
virtual ~USBDeviceHandle();
int ClaimInterface(int);
int ReleaseInterface(int);
int SetConfiguration(int);
int SetAltSetting(int, int);
status_t SubmitTransfer(struct usbi_transfer *);
status_t CancelTransfer(USBTransfer *);
bool InitCheck();
private:
int fRawFD;
static status_t TransfersThread(void *);
void TransfersWorker();
USBDevice* fUSBDevice;
unsigned int fClaimedInterfaces;
BList fTransfers;
BLocker fTransfersLock;
sem_id fTransfersSem;
thread_id fTransfersThread;
bool fInitCheck;
};
class USBTransfer {
public:
USBTransfer(struct usbi_transfer *, USBDevice *);
virtual ~USBTransfer();
void Do(int);
struct usbi_transfer* UsbiTransfer();
void SetCancelled();
bool IsCancelled();
private:
struct usbi_transfer* fUsbiTransfer;
struct libusb_transfer* fLibusbTransfer;
USBDevice* fUSBDevice;
BLocker fStatusLock;
bool fCancelled;
};
class USBRoster {
public:
USBRoster();
virtual ~USBRoster();
int Start();
void Stop();
private:
void* fLooper;
};

View File

@ -0,0 +1,517 @@
/*
* Haiku Backend for libusb
* Copyright © 2014 Akshay Jaggi <akshay1994.leo@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 <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <new>
#include <vector>
#include "haiku_usb.h"
int _errno_to_libusb(int status)
{
return status;
}
USBTransfer::USBTransfer(struct usbi_transfer *itransfer, USBDevice *device)
{
fUsbiTransfer = itransfer;
fLibusbTransfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
fUSBDevice = device;
fCancelled = false;
}
USBTransfer::~USBTransfer()
{
}
struct usbi_transfer *
USBTransfer::UsbiTransfer()
{
return fUsbiTransfer;
}
void
USBTransfer::SetCancelled()
{
fCancelled = true;
}
bool
USBTransfer::IsCancelled()
{
return fCancelled;
}
void
USBTransfer::Do(int fRawFD)
{
switch (fLibusbTransfer->type) {
case LIBUSB_TRANSFER_TYPE_CONTROL:
{
struct libusb_control_setup *setup = (struct libusb_control_setup *)fLibusbTransfer->buffer;
usb_raw_command command;
command.control.request_type = setup->bmRequestType;
command.control.request = setup->bRequest;
command.control.value = setup->wValue;
command.control.index = setup->wIndex;
command.control.length = setup->wLength;
command.control.data = fLibusbTransfer->buffer + LIBUSB_CONTROL_SETUP_SIZE;
if (fCancelled)
break;
if (ioctl(fRawFD, B_USB_RAW_COMMAND_CONTROL_TRANSFER, &command, sizeof(command)) ||
command.control.status != B_USB_RAW_STATUS_SUCCESS) {
fUsbiTransfer->transferred = -1;
usbi_err(TRANSFER_CTX(fLibusbTransfer), "failed control transfer");
break;
}
fUsbiTransfer->transferred = command.control.length;
}
break;
case LIBUSB_TRANSFER_TYPE_BULK:
case LIBUSB_TRANSFER_TYPE_INTERRUPT:
{
usb_raw_command command;
command.transfer.interface = fUSBDevice->EndpointToInterface(fLibusbTransfer->endpoint);
command.transfer.endpoint = fUSBDevice->EndpointToIndex(fLibusbTransfer->endpoint);
command.transfer.data = fLibusbTransfer->buffer;
command.transfer.length = fLibusbTransfer->length;
if (fCancelled)
break;
if (fLibusbTransfer->type == LIBUSB_TRANSFER_TYPE_BULK) {
if (ioctl(fRawFD, B_USB_RAW_COMMAND_BULK_TRANSFER, &command, sizeof(command)) ||
command.transfer.status != B_USB_RAW_STATUS_SUCCESS) {
fUsbiTransfer->transferred = -1;
usbi_err(TRANSFER_CTX(fLibusbTransfer), "failed bulk transfer");
break;
}
}
else {
if (ioctl(fRawFD, B_USB_RAW_COMMAND_INTERRUPT_TRANSFER, &command, sizeof(command)) ||
command.transfer.status != B_USB_RAW_STATUS_SUCCESS) {
fUsbiTransfer->transferred = -1;
usbi_err(TRANSFER_CTX(fLibusbTransfer), "failed interrupt transfer");
break;
}
}
fUsbiTransfer->transferred = command.transfer.length;
}
break;
// IsochronousTransfers not tested
case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
{
usb_raw_command command;
command.isochronous.interface = fUSBDevice->EndpointToInterface(fLibusbTransfer->endpoint);
command.isochronous.endpoint = fUSBDevice->EndpointToIndex(fLibusbTransfer->endpoint);
command.isochronous.data = fLibusbTransfer->buffer;
command.isochronous.length = fLibusbTransfer->length;
command.isochronous.packet_count = fLibusbTransfer->num_iso_packets;
int i;
usb_iso_packet_descriptor *packetDescriptors = new usb_iso_packet_descriptor[fLibusbTransfer->num_iso_packets];
for (i = 0; i < fLibusbTransfer->num_iso_packets; i++) {
if ((int16)(fLibusbTransfer->iso_packet_desc[i]).length != (fLibusbTransfer->iso_packet_desc[i]).length) {
fUsbiTransfer->transferred = -1;
usbi_err(TRANSFER_CTX(fLibusbTransfer), "failed isochronous transfer");
break;
}
packetDescriptors[i].request_length = (int16)(fLibusbTransfer->iso_packet_desc[i]).length;
}
if (i < fLibusbTransfer->num_iso_packets)
break; // TODO Handle this error
command.isochronous.packet_descriptors = packetDescriptors;
if (fCancelled)
break;
if (ioctl(fRawFD, B_USB_RAW_COMMAND_ISOCHRONOUS_TRANSFER, &command, sizeof(command)) ||
command.isochronous.status != B_USB_RAW_STATUS_SUCCESS) {
fUsbiTransfer->transferred = -1;
usbi_err(TRANSFER_CTX(fLibusbTransfer), "failed isochronous transfer");
break;
}
for (i = 0; i < fLibusbTransfer->num_iso_packets; i++) {
(fLibusbTransfer->iso_packet_desc[i]).actual_length = packetDescriptors[i].actual_length;
switch (packetDescriptors[i].status) {
case B_OK:
(fLibusbTransfer->iso_packet_desc[i]).status = LIBUSB_TRANSFER_COMPLETED;
break;
default:
(fLibusbTransfer->iso_packet_desc[i]).status = LIBUSB_TRANSFER_ERROR;
break;
}
}
delete[] packetDescriptors;
// Do we put the length of transfer here, for isochronous transfers?
fUsbiTransfer->transferred = command.transfer.length;
}
break;
default:
usbi_err(TRANSFER_CTX(fLibusbTransfer), "Unknown type of transfer");
}
}
bool
USBDeviceHandle::InitCheck()
{
return fInitCheck;
}
status_t
USBDeviceHandle::TransfersThread(void *self)
{
USBDeviceHandle *handle = (USBDeviceHandle *)self;
handle->TransfersWorker();
return B_OK;
}
void
USBDeviceHandle::TransfersWorker()
{
while (true) {
status_t status = acquire_sem(fTransfersSem);
if (status == B_BAD_SEM_ID)
break;
if (status == B_INTERRUPTED)
continue;
fTransfersLock.Lock();
USBTransfer *fPendingTransfer = (USBTransfer *) fTransfers.RemoveItem((int32)0);
fTransfersLock.Unlock();
fPendingTransfer->Do(fRawFD);
usbi_signal_transfer_completion(fPendingTransfer->UsbiTransfer());
}
}
status_t
USBDeviceHandle::SubmitTransfer(struct usbi_transfer *itransfer)
{
USBTransfer *transfer = new USBTransfer(itransfer, fUSBDevice);
*((USBTransfer **)usbi_transfer_get_os_priv(itransfer)) = transfer;
BAutolock locker(fTransfersLock);
fTransfers.AddItem(transfer);
release_sem(fTransfersSem);
return LIBUSB_SUCCESS;
}
status_t
USBDeviceHandle::CancelTransfer(USBTransfer *transfer)
{
transfer->SetCancelled();
fTransfersLock.Lock();
bool removed = fTransfers.RemoveItem(transfer);
fTransfersLock.Unlock();
if(removed)
usbi_signal_transfer_completion(transfer->UsbiTransfer());
return LIBUSB_SUCCESS;
}
USBDeviceHandle::USBDeviceHandle(USBDevice *dev)
:
fTransfersThread(-1),
fUSBDevice(dev),
fClaimedInterfaces(0),
fInitCheck(false)
{
fRawFD = open(dev->Location(), O_RDWR | O_CLOEXEC);
if (fRawFD < 0) {
usbi_err(NULL,"failed to open device");
return;
}
fTransfersSem = create_sem(0, "Transfers Queue Sem");
fTransfersThread = spawn_thread(TransfersThread, "Transfer Worker", B_NORMAL_PRIORITY, this);
resume_thread(fTransfersThread);
fInitCheck = true;
}
USBDeviceHandle::~USBDeviceHandle()
{
if (fRawFD > 0)
close(fRawFD);
for(int i = 0; i < 32; i++) {
if (fClaimedInterfaces & (1 << i))
ReleaseInterface(i);
}
delete_sem(fTransfersSem);
if (fTransfersThread > 0)
wait_for_thread(fTransfersThread, NULL);
}
int
USBDeviceHandle::ClaimInterface(int inumber)
{
int status = fUSBDevice->ClaimInterface(inumber);
if (status == LIBUSB_SUCCESS)
fClaimedInterfaces |= (1 << inumber);
return status;
}
int
USBDeviceHandle::ReleaseInterface(int inumber)
{
fUSBDevice->ReleaseInterface(inumber);
fClaimedInterfaces &= ~(1 << inumber);
return LIBUSB_SUCCESS;
}
int
USBDeviceHandle::SetConfiguration(int config)
{
int config_index = fUSBDevice->CheckInterfacesFree(config);
if(config_index == LIBUSB_ERROR_BUSY || config_index == LIBUSB_ERROR_NOT_FOUND)
return config_index;
usb_raw_command command;
command.config.config_index = config_index;
if (ioctl(fRawFD, B_USB_RAW_COMMAND_SET_CONFIGURATION, &command, sizeof(command)) ||
command.config.status != B_USB_RAW_STATUS_SUCCESS) {
return _errno_to_libusb(command.config.status);
}
fUSBDevice->SetActiveConfiguration(config_index);
return LIBUSB_SUCCESS;
}
int
USBDeviceHandle::SetAltSetting(int inumber, int alt)
{
usb_raw_command command;
command.alternate.config_index = fUSBDevice->ActiveConfigurationIndex();
command.alternate.interface_index = inumber;
if (ioctl(fRawFD, B_USB_RAW_COMMAND_GET_ACTIVE_ALT_INTERFACE_INDEX, &command, sizeof(command)) ||
command.alternate.status != B_USB_RAW_STATUS_SUCCESS) {
usbi_err(NULL, "Error retrieving active alternate interface");
return _errno_to_libusb(command.alternate.status);
}
if (command.alternate.alternate_info == alt) {
usbi_dbg("Setting alternate interface successful");
return LIBUSB_SUCCESS;
}
command.alternate.alternate_info = alt;
if (ioctl(fRawFD, B_USB_RAW_COMMAND_SET_ALT_INTERFACE, &command, sizeof(command)) ||
command.alternate.status != B_USB_RAW_STATUS_SUCCESS) { //IF IOCTL FAILS DEVICE DISONNECTED PROBABLY
usbi_err(NULL, "Error setting alternate interface");
return _errno_to_libusb(command.alternate.status);
}
usbi_dbg("Setting alternate interface successful");
return LIBUSB_SUCCESS;
}
USBDevice::USBDevice(const char *path)
:
fPath(NULL),
fActiveConfiguration(0), //0?
fConfigurationDescriptors(NULL),
fClaimedInterfaces(0),
fEndpointToIndex(NULL),
fEndpointToInterface(NULL),
fInitCheck(false)
{
fPath=strdup(path);
Initialise();
}
USBDevice::~USBDevice()
{
free(fPath);
if (fConfigurationDescriptors) {
for(int i = 0; i < fDeviceDescriptor.num_configurations; i++) {
if (fConfigurationDescriptors[i])
delete fConfigurationDescriptors[i];
}
delete[] fConfigurationDescriptors;
}
if (fEndpointToIndex)
delete[] fEndpointToIndex;
if (fEndpointToInterface)
delete[] fEndpointToInterface;
}
bool
USBDevice::InitCheck()
{
return fInitCheck;
}
const char *
USBDevice::Location() const
{
return fPath;
}
uint8
USBDevice::CountConfigurations() const
{
return fDeviceDescriptor.num_configurations;
}
const usb_device_descriptor *
USBDevice::Descriptor() const
{
return &fDeviceDescriptor;
}
const usb_configuration_descriptor *
USBDevice::ConfigurationDescriptor(uint32 index) const
{
if (index > CountConfigurations())
return NULL;
return (usb_configuration_descriptor *) fConfigurationDescriptors[index];
}
const usb_configuration_descriptor *
USBDevice::ActiveConfiguration() const
{
return (usb_configuration_descriptor *) fConfigurationDescriptors[fActiveConfiguration];
}
int
USBDevice::ActiveConfigurationIndex() const
{
return fActiveConfiguration;
}
int USBDevice::ClaimInterface(int interface)
{
if (interface > ActiveConfiguration()->number_interfaces)
return LIBUSB_ERROR_NOT_FOUND;
if (fClaimedInterfaces & (1 << interface))
return LIBUSB_ERROR_BUSY;
fClaimedInterfaces |= (1 << interface);
return LIBUSB_SUCCESS;
}
int USBDevice::ReleaseInterface(int interface)
{
fClaimedInterfaces &= ~(1 << interface);
return LIBUSB_SUCCESS;
}
int
USBDevice::CheckInterfacesFree(int config)
{
if (fConfigToIndex.count(config) == 0)
return LIBUSB_ERROR_NOT_FOUND;
if (fClaimedInterfaces == 0)
return fConfigToIndex[(uint8)config];
return LIBUSB_ERROR_BUSY;
}
int
USBDevice::SetActiveConfiguration(int config_index)
{
fActiveConfiguration = config_index;
return LIBUSB_SUCCESS;
}
uint8
USBDevice::EndpointToIndex(uint8 address) const
{
return fEndpointToIndex[fActiveConfiguration][address];
}
uint8
USBDevice::EndpointToInterface(uint8 address) const
{
return fEndpointToInterface[fActiveConfiguration][address];
}
int
USBDevice::Initialise() //Do we need more error checking, etc? How to report?
{
int fRawFD = open(fPath, O_RDWR | O_CLOEXEC);
if (fRawFD < 0)
return B_ERROR;
usb_raw_command command;
command.device.descriptor = &fDeviceDescriptor;
if (ioctl(fRawFD, B_USB_RAW_COMMAND_GET_DEVICE_DESCRIPTOR, &command, sizeof(command)) ||
command.device.status != B_USB_RAW_STATUS_SUCCESS) {
close(fRawFD);
return B_ERROR;
}
fConfigurationDescriptors = new(std::nothrow) unsigned char *[fDeviceDescriptor.num_configurations];
fEndpointToIndex = new(std::nothrow) map<uint8,uint8> [fDeviceDescriptor.num_configurations];
fEndpointToInterface = new(std::nothrow) map<uint8,uint8> [fDeviceDescriptor.num_configurations];
for (int i = 0; i < fDeviceDescriptor.num_configurations; i++) {
usb_configuration_descriptor tmp_config;
command.config.descriptor = &tmp_config;
command.config.config_index = i;
if (ioctl(fRawFD, B_USB_RAW_COMMAND_GET_CONFIGURATION_DESCRIPTOR, &command, sizeof(command)) ||
command.config.status != B_USB_RAW_STATUS_SUCCESS) {
usbi_err(NULL, "failed retrieving configuration descriptor");
close(fRawFD);
return B_ERROR;
}
fConfigToIndex[tmp_config.configuration_value] = i;
fConfigurationDescriptors[i] = new(std::nothrow) unsigned char[tmp_config.total_length];
command.control.request_type = 128;
command.control.request = 6;
command.control.value = (2 << 8) | i;
command.control.index = 0;
command.control.length = tmp_config.total_length;
command.control.data = fConfigurationDescriptors[i];
if (ioctl(fRawFD, B_USB_RAW_COMMAND_CONTROL_TRANSFER, &command, sizeof(command)) ||
command.control.status!=B_USB_RAW_STATUS_SUCCESS) {
usbi_err(NULL, "failed retrieving full configuration descriptor");
close(fRawFD);
return B_ERROR;
}
for (int j = 0; j < tmp_config.number_interfaces; j++) {
command.alternate.config_index = i;
command.alternate.interface_index = j;
if (ioctl(fRawFD, B_USB_RAW_COMMAND_GET_ALT_INTERFACE_COUNT, &command, sizeof(command)) ||
command.config.status != B_USB_RAW_STATUS_SUCCESS) {
usbi_err(NULL, "failed retrieving number of alternate interfaces");
close(fRawFD);
return B_ERROR;
}
int num_alternate = command.alternate.alternate_info;
for (int k = 0; k < num_alternate; k++) {
usb_interface_descriptor tmp_interface;
command.interface_etc.config_index = i;
command.interface_etc.interface_index = j;
command.interface_etc.alternate_index = k;
command.interface_etc.descriptor = &tmp_interface;
if (ioctl(fRawFD, B_USB_RAW_COMMAND_GET_INTERFACE_DESCRIPTOR_ETC, &command, sizeof(command)) ||
command.config.status != B_USB_RAW_STATUS_SUCCESS) {
usbi_err(NULL, "failed retrieving interface descriptor");
close(fRawFD);
return B_ERROR;
}
for (int l = 0; l < tmp_interface.num_endpoints; l++) {
usb_endpoint_descriptor tmp_endpoint;
command.endpoint_etc.config_index = i;
command.endpoint_etc.interface_index = j;
command.endpoint_etc.alternate_index = k;
command.endpoint_etc.endpoint_index = l;
command.endpoint_etc.descriptor = &tmp_endpoint;
if (ioctl(fRawFD, B_USB_RAW_COMMAND_GET_ENDPOINT_DESCRIPTOR_ETC, &command, sizeof(command)) ||
command.config.status != B_USB_RAW_STATUS_SUCCESS) {
usbi_err(NULL, "failed retrieving endpoint descriptor");
close(fRawFD);
return B_ERROR;
}
fEndpointToIndex[i][tmp_endpoint.endpoint_address] = l;
fEndpointToInterface[i][tmp_endpoint.endpoint_address] = j;
}
}
}
}
close(fRawFD);
fInitCheck = true;
return B_OK;
}

View File

@ -0,0 +1,250 @@
/*
* Haiku Backend for libusb
* Copyright © 2014 Akshay Jaggi <akshay1994.leo@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 <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <new>
#include <vector>
#include "haiku_usb.h"
USBRoster gUsbRoster;
int32 gInitCount = 0;
static int
haiku_init(struct libusb_context *ctx)
{
if (atomic_add(&gInitCount, 1) == 0)
return gUsbRoster.Start();
return LIBUSB_SUCCESS;
}
static void
haiku_exit(void)
{
if (atomic_add(&gInitCount, -1) == 1)
gUsbRoster.Stop();
}
static int
haiku_open(struct libusb_device_handle *dev_handle)
{
USBDevice *dev = *((USBDevice **)dev_handle->dev->os_priv);
USBDeviceHandle *handle = new(std::nothrow) USBDeviceHandle(dev);
if (handle == NULL)
return LIBUSB_ERROR_NO_MEM;
if (handle->InitCheck() == false) {
delete handle;
return LIBUSB_ERROR_NO_DEVICE;
}
*((USBDeviceHandle **)dev_handle->os_priv) = handle;
return LIBUSB_SUCCESS;
}
static void
haiku_close(struct libusb_device_handle *dev_handle)
{
USBDeviceHandle *handle = *((USBDeviceHandle **)dev_handle->os_priv);
if (handle == NULL)
return;
delete handle;
*((USBDeviceHandle **)dev_handle->os_priv) = NULL;
}
static int
haiku_get_device_descriptor(struct libusb_device *device, unsigned char *buffer, int *host_endian)
{
USBDevice *dev = *((USBDevice **)device->os_priv);
memcpy(buffer, dev->Descriptor(), DEVICE_DESC_LENGTH);
*host_endian = 0;
return LIBUSB_SUCCESS;
}
static int
haiku_get_active_config_descriptor(struct libusb_device *device, unsigned char *buffer, size_t len, int *host_endian)
{
USBDevice *dev = *((USBDevice **)device->os_priv);
const usb_configuration_descriptor *act_config = dev->ActiveConfiguration();
if (len > act_config->total_length)
return LIBUSB_ERROR_OVERFLOW;
memcpy(buffer, act_config, len);
*host_endian = 0;
return LIBUSB_SUCCESS;
}
static int
haiku_get_config_descriptor(struct libusb_device *device, uint8_t config_index, unsigned char *buffer, size_t len, int *host_endian)
{
USBDevice *dev = *((USBDevice **)device->os_priv);
const usb_configuration_descriptor *config = dev->ConfigurationDescriptor(config_index);
if (config == NULL) {
usbi_err(DEVICE_CTX(device), "failed getting configuration descriptor");
return LIBUSB_ERROR_INVALID_PARAM;
}
if (len > config->total_length)
len = config->total_length;
memcpy(buffer, config, len);
*host_endian = 0;
return len;
}
static int
haiku_set_configuration(struct libusb_device_handle *dev_handle, int config)
{
USBDeviceHandle *handle= *((USBDeviceHandle **)dev_handle->os_priv);
return handle->SetConfiguration(config);
}
static int
haiku_claim_interface(struct libusb_device_handle *dev_handle, int interface_number)
{
USBDeviceHandle *handle = *((USBDeviceHandle **)dev_handle->os_priv);
return handle->ClaimInterface(interface_number);
}
static int
haiku_set_altsetting(struct libusb_device_handle *dev_handle, int interface_number, int altsetting)
{
USBDeviceHandle *handle = *((USBDeviceHandle **)dev_handle->os_priv);
return handle->SetAltSetting(interface_number, altsetting);
}
static int
haiku_release_interface(struct libusb_device_handle *dev_handle, int interface_number)
{
USBDeviceHandle *handle = *((USBDeviceHandle **)dev_handle->os_priv);
haiku_set_altsetting(dev_handle,interface_number, 0);
return handle->ReleaseInterface(interface_number);
}
static int
haiku_submit_transfer(struct usbi_transfer *itransfer)
{
struct libusb_transfer *fLibusbTransfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
USBDeviceHandle *fDeviceHandle = *((USBDeviceHandle **)fLibusbTransfer->dev_handle->os_priv);
return fDeviceHandle->SubmitTransfer(itransfer);
}
static int
haiku_cancel_transfer(struct usbi_transfer *itransfer)
{
struct libusb_transfer *fLibusbTransfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
USBDeviceHandle *fDeviceHandle = *((USBDeviceHandle **)fLibusbTransfer->dev_handle->os_priv);
return fDeviceHandle->CancelTransfer(*((USBTransfer **)usbi_transfer_get_os_priv(itransfer)));
}
static void
haiku_clear_transfer_priv(struct usbi_transfer *itransfer)
{
USBTransfer *transfer = *((USBTransfer **)usbi_transfer_get_os_priv(itransfer));
delete transfer;
*((USBTransfer **)usbi_transfer_get_os_priv(itransfer)) = NULL;
}
static int
haiku_handle_transfer_completion(struct usbi_transfer *itransfer)
{
USBTransfer *transfer = *((USBTransfer **)usbi_transfer_get_os_priv(itransfer));
usbi_mutex_lock(&itransfer->lock);
if (transfer->IsCancelled()) {
delete transfer;
*((USBTransfer **)usbi_transfer_get_os_priv(itransfer)) = NULL;
usbi_mutex_unlock(&itransfer->lock);
if (itransfer->transferred < 0)
itransfer->transferred = 0;
return usbi_handle_transfer_cancellation(itransfer);
}
libusb_transfer_status status = LIBUSB_TRANSFER_COMPLETED;
if (itransfer->transferred < 0) {
usbi_err(ITRANSFER_CTX(itransfer), "error in transfer");
status = LIBUSB_TRANSFER_ERROR;
itransfer->transferred = 0;
}
delete transfer;
*((USBTransfer **)usbi_transfer_get_os_priv(itransfer)) = NULL;
usbi_mutex_unlock(&itransfer->lock);
return usbi_handle_transfer_completion(itransfer, status);
}
static int
haiku_clock_gettime(int clkid, struct timespec *tp)
{
if (clkid == USBI_CLOCK_REALTIME)
return clock_gettime(CLOCK_REALTIME, tp);
if (clkid == USBI_CLOCK_MONOTONIC)
return clock_gettime(CLOCK_MONOTONIC, tp);
return LIBUSB_ERROR_INVALID_PARAM;
}
const struct usbi_os_backend haiku_usb_raw_backend = {
/*.name =*/ "Haiku usbfs",
/*.caps =*/ 0,
/*.init =*/ haiku_init,
/*.exit =*/ haiku_exit,
/*.get_device_list =*/ NULL,
/*.hotplug_poll =*/ NULL,
/*.open =*/ haiku_open,
/*.close =*/ haiku_close,
/*.get_device_descriptor =*/ haiku_get_device_descriptor,
/*.get_active_config_descriptor =*/ haiku_get_active_config_descriptor,
/*.get_config_descriptor =*/ haiku_get_config_descriptor,
/*.get_config_descriptor_by_value =*/ NULL,
/*.get_configuration =*/ NULL,
/*.set_configuration =*/ haiku_set_configuration,
/*.claim_interface =*/ haiku_claim_interface,
/*.release_interface =*/ haiku_release_interface,
/*.set_interface_altsetting =*/ haiku_set_altsetting,
/*.clear_halt =*/ NULL,
/*.reset_device =*/ NULL,
/*.alloc_streams =*/ NULL,
/*.free_streams =*/ NULL,
/*.dev_mem_alloc =*/ NULL,
/*.dev_mem_free =*/ NULL,
/*.kernel_driver_active =*/ NULL,
/*.detach_kernel_driver =*/ NULL,
/*.attach_kernel_driver =*/ NULL,
/*.destroy_device =*/ NULL,
/*.submit_transfer =*/ haiku_submit_transfer,
/*.cancel_transfer =*/ haiku_cancel_transfer,
/*.clear_transfer_priv =*/ haiku_clear_transfer_priv,
/*.handle_events =*/ NULL,
/*.handle_transfer_completion =*/ haiku_handle_transfer_completion,
/*.clock_gettime =*/ haiku_clock_gettime,
#ifdef USBI_TIMERFD_AVAILABLE
/*.get_timerfd_clockid =*/ NULL,
#endif
/*.device_priv_size =*/ sizeof(USBDevice *),
/*.device_handle_priv_size =*/ sizeof(USBDeviceHandle *),
/*.transfer_priv_size =*/ sizeof(USBTransfer *),
};

View File

@ -0,0 +1,180 @@
/*
* Copyright 2006-2008, Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef _USB_RAW_H_
#define _USB_RAW_H_
#include <USB3.h>
#define B_USB_RAW_PROTOCOL_VERSION 0x0015
#define B_USB_RAW_ACTIVE_ALTERNATE 0xffffffff
typedef enum {
B_USB_RAW_COMMAND_GET_VERSION = 0x1000,
B_USB_RAW_COMMAND_GET_DEVICE_DESCRIPTOR = 0x2000,
B_USB_RAW_COMMAND_GET_CONFIGURATION_DESCRIPTOR,
B_USB_RAW_COMMAND_GET_INTERFACE_DESCRIPTOR,
B_USB_RAW_COMMAND_GET_ENDPOINT_DESCRIPTOR,
B_USB_RAW_COMMAND_GET_STRING_DESCRIPTOR,
B_USB_RAW_COMMAND_GET_GENERIC_DESCRIPTOR,
B_USB_RAW_COMMAND_GET_ALT_INTERFACE_COUNT,
B_USB_RAW_COMMAND_GET_ACTIVE_ALT_INTERFACE_INDEX,
B_USB_RAW_COMMAND_GET_INTERFACE_DESCRIPTOR_ETC,
B_USB_RAW_COMMAND_GET_ENDPOINT_DESCRIPTOR_ETC,
B_USB_RAW_COMMAND_GET_GENERIC_DESCRIPTOR_ETC,
B_USB_RAW_COMMAND_SET_CONFIGURATION = 0x3000,
B_USB_RAW_COMMAND_SET_FEATURE,
B_USB_RAW_COMMAND_CLEAR_FEATURE,
B_USB_RAW_COMMAND_GET_STATUS,
B_USB_RAW_COMMAND_GET_DESCRIPTOR,
B_USB_RAW_COMMAND_SET_ALT_INTERFACE,
B_USB_RAW_COMMAND_CONTROL_TRANSFER = 0x4000,
B_USB_RAW_COMMAND_INTERRUPT_TRANSFER,
B_USB_RAW_COMMAND_BULK_TRANSFER,
B_USB_RAW_COMMAND_ISOCHRONOUS_TRANSFER
} usb_raw_command_id;
typedef enum {
B_USB_RAW_STATUS_SUCCESS = 0,
B_USB_RAW_STATUS_FAILED,
B_USB_RAW_STATUS_ABORTED,
B_USB_RAW_STATUS_STALLED,
B_USB_RAW_STATUS_CRC_ERROR,
B_USB_RAW_STATUS_TIMEOUT,
B_USB_RAW_STATUS_INVALID_CONFIGURATION,
B_USB_RAW_STATUS_INVALID_INTERFACE,
B_USB_RAW_STATUS_INVALID_ENDPOINT,
B_USB_RAW_STATUS_INVALID_STRING,
B_USB_RAW_STATUS_NO_MEMORY
} usb_raw_command_status;
typedef union {
struct {
status_t status;
} version;
struct {
status_t status;
usb_device_descriptor *descriptor;
} device;
struct {
status_t status;
usb_configuration_descriptor *descriptor;
uint32 config_index;
} config;
struct {
status_t status;
uint32 alternate_info;
uint32 config_index;
uint32 interface_index;
} alternate;
struct {
status_t status;
usb_interface_descriptor *descriptor;
uint32 config_index;
uint32 interface_index;
} interface;
struct {
status_t status;
usb_interface_descriptor *descriptor;
uint32 config_index;
uint32 interface_index;
uint32 alternate_index;
} interface_etc;
struct {
status_t status;
usb_endpoint_descriptor *descriptor;
uint32 config_index;
uint32 interface_index;
uint32 endpoint_index;
} endpoint;
struct {
status_t status;
usb_endpoint_descriptor *descriptor;
uint32 config_index;
uint32 interface_index;
uint32 alternate_index;
uint32 endpoint_index;
} endpoint_etc;
struct {
status_t status;
usb_descriptor *descriptor;
uint32 config_index;
uint32 interface_index;
uint32 generic_index;
size_t length;
} generic;
struct {
status_t status;
usb_descriptor *descriptor;
uint32 config_index;
uint32 interface_index;
uint32 alternate_index;
uint32 generic_index;
size_t length;
} generic_etc;
struct {
status_t status;
usb_string_descriptor *descriptor;
uint32 string_index;
size_t length;
} string;
struct {
status_t status;
uint8 type;
uint8 index;
uint16 language_id;
void *data;
size_t length;
} descriptor;
struct {
status_t status;
uint8 request_type;
uint8 request;
uint16 value;
uint16 index;
uint16 length;
void *data;
} control;
struct {
status_t status;
uint32 interface;
uint32 endpoint;
void *data;
size_t length;
} transfer;
struct {
status_t status;
uint32 interface;
uint32 endpoint;
void *data;
size_t length;
usb_iso_packet_descriptor *packet_descriptors;
uint32 packet_count;
} isochronous;
} usb_raw_command;
#endif // _USB_RAW_H_

View File

@ -4,6 +4,7 @@
* Copyright (C) 2007-2009 Daniel Drake <dsd@gentoo.org> * Copyright (C) 2007-2009 Daniel Drake <dsd@gentoo.org>
* Copyright (c) 2001 Johannes Erdfelt <johannes@erdfelt.com> * Copyright (c) 2001 Johannes Erdfelt <johannes@erdfelt.com>
* Copyright (c) 2013 Nathan Hjelm <hjelmn@mac.com> * Copyright (c) 2013 Nathan Hjelm <hjelmn@mac.com>
* Copyright (c) 2016 Chris Dickens <christopher.a.dickens@gmail.com>
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -22,38 +23,27 @@
#include <config.h> #include <config.h>
#include <ctype.h> #include <assert.h>
#include <dirent.h>
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <poll.h> #include <poll.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <unistd.h>
#include <sys/types.h> #include <sys/types.h>
#ifdef HAVE_ASM_TYPES_H #ifdef HAVE_ASM_TYPES_H
#include <asm/types.h> #include <asm/types.h>
#endif #endif
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h> #include <sys/socket.h>
#endif
#include <arpa/inet.h>
#ifdef HAVE_LINUX_NETLINK_H
#include <linux/netlink.h> #include <linux/netlink.h>
#endif
#ifdef HAVE_LINUX_FILTER_H
#include <linux/filter.h>
#endif
#include "libusbi.h" #include "libusbi.h"
#include "linux_usbfs.h" #include "linux_usbfs.h"
#define KERNEL 1 #define NL_GROUP_KERNEL 1
static int linux_netlink_socket = -1; static int linux_netlink_socket = -1;
static int netlink_control_pipe[2] = { -1, -1 }; static int netlink_control_pipe[2] = { -1, -1 };
@ -61,30 +51,36 @@ static pthread_t libusb_linux_event_thread;
static void *linux_netlink_event_thread_main(void *arg); static void *linux_netlink_event_thread_main(void *arg);
struct sockaddr_nl snl = { .nl_family=AF_NETLINK, .nl_groups=KERNEL };
static int set_fd_cloexec_nb(int fd) static int set_fd_cloexec_nb(int fd)
{ {
int flags; int flags;
#if defined(FD_CLOEXEC) #if defined(FD_CLOEXEC)
flags = fcntl (linux_netlink_socket, F_GETFD); flags = fcntl(fd, F_GETFD);
if (0 > flags) { if (flags == -1) {
usbi_err(NULL, "failed to get netlink fd flags (%d)", errno);
return -1; return -1;
} }
if (!(flags & FD_CLOEXEC)) { if (!(flags & FD_CLOEXEC)) {
fcntl (linux_netlink_socket, F_SETFD, flags | FD_CLOEXEC); if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1) {
usbi_err(NULL, "failed to set netlink fd flags (%d)", errno);
return -1;
}
} }
#endif #endif
flags = fcntl (linux_netlink_socket, F_GETFL); flags = fcntl(fd, F_GETFL);
if (0 > flags) { if (flags == -1) {
usbi_err(NULL, "failed to get netlink fd status flags (%d)", errno);
return -1; return -1;
} }
if (!(flags & O_NONBLOCK)) { if (!(flags & O_NONBLOCK)) {
fcntl (linux_netlink_socket, F_SETFL, flags | O_NONBLOCK); if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) {
usbi_err(NULL, "failed to set netlink fd status flags (%d)", errno);
return -1;
}
} }
return 0; return 0;
@ -92,11 +88,11 @@ static int set_fd_cloexec_nb (int fd)
int linux_netlink_start_event_monitor(void) int linux_netlink_start_event_monitor(void)
{ {
struct sockaddr_nl sa_nl = { .nl_family = AF_NETLINK, .nl_groups = NL_GROUP_KERNEL };
int socktype = SOCK_RAW; int socktype = SOCK_RAW;
int opt = 1;
int ret; int ret;
snl.nl_groups = KERNEL;
#if defined(SOCK_CLOEXEC) #if defined(SOCK_CLOEXEC)
socktype |= SOCK_CLOEXEC; socktype |= SOCK_CLOEXEC;
#endif #endif
@ -105,64 +101,71 @@ int linux_netlink_start_event_monitor(void)
#endif #endif
linux_netlink_socket = socket(PF_NETLINK, socktype, NETLINK_KOBJECT_UEVENT); linux_netlink_socket = socket(PF_NETLINK, socktype, NETLINK_KOBJECT_UEVENT);
if (-1 == linux_netlink_socket && EINVAL == errno) { if (linux_netlink_socket == -1 && errno == EINVAL) {
usbi_dbg("failed to create netlink socket of type %d, attempting SOCK_RAW", socktype);
linux_netlink_socket = socket(PF_NETLINK, SOCK_RAW, NETLINK_KOBJECT_UEVENT); linux_netlink_socket = socket(PF_NETLINK, SOCK_RAW, NETLINK_KOBJECT_UEVENT);
} }
if (-1 == linux_netlink_socket) { if (linux_netlink_socket == -1) {
return LIBUSB_ERROR_OTHER; usbi_err(NULL, "failed to create netlink socket (%d)", errno);
goto err;
} }
ret = set_fd_cloexec_nb(linux_netlink_socket); ret = set_fd_cloexec_nb(linux_netlink_socket);
if (0 != ret) { if (ret == -1)
close (linux_netlink_socket); goto err_close_socket;
linux_netlink_socket = -1;
return LIBUSB_ERROR_OTHER; ret = bind(linux_netlink_socket, (struct sockaddr *)&sa_nl, sizeof(sa_nl));
if (ret == -1) {
usbi_err(NULL, "failed to bind netlink socket (%d)", errno);
goto err_close_socket;
} }
ret = bind(linux_netlink_socket, (struct sockaddr *) &snl, sizeof(snl)); ret = setsockopt(linux_netlink_socket, SOL_SOCKET, SO_PASSCRED, &opt, sizeof(opt));
if (0 != ret) { if (ret == -1) {
close(linux_netlink_socket); usbi_err(NULL, "failed to set netlink socket SO_PASSCRED option (%d)", errno);
return LIBUSB_ERROR_OTHER; goto err_close_socket;
} }
/* TODO -- add authentication */
/* setsockopt(linux_netlink_socket, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one)); */
ret = usbi_pipe(netlink_control_pipe); ret = usbi_pipe(netlink_control_pipe);
if (ret) { if (ret) {
usbi_err(NULL, "could not create netlink control pipe"); usbi_err(NULL, "failed to create netlink control pipe");
close(linux_netlink_socket); goto err_close_socket;
return LIBUSB_ERROR_OTHER;
} }
ret = pthread_create(&libusb_linux_event_thread, NULL, linux_netlink_event_thread_main, NULL); ret = pthread_create(&libusb_linux_event_thread, NULL, linux_netlink_event_thread_main, NULL);
if (0 != ret) { if (ret != 0) {
close(netlink_control_pipe[0]); usbi_err(NULL, "failed to create netlink event thread (%d)", ret);
close(netlink_control_pipe[1]); goto err_close_pipe;
close(linux_netlink_socket);
return LIBUSB_ERROR_OTHER;
} }
return LIBUSB_SUCCESS; return LIBUSB_SUCCESS;
err_close_pipe:
close(netlink_control_pipe[0]);
close(netlink_control_pipe[1]);
netlink_control_pipe[0] = -1;
netlink_control_pipe[1] = -1;
err_close_socket:
close(linux_netlink_socket);
linux_netlink_socket = -1;
err:
return LIBUSB_ERROR_OTHER;
} }
int linux_netlink_stop_event_monitor(void) int linux_netlink_stop_event_monitor(void)
{ {
int r;
char dummy = 1; char dummy = 1;
ssize_t r;
if (-1 == linux_netlink_socket) { assert(linux_netlink_socket != -1);
/* already closed. nothing to do */
return LIBUSB_SUCCESS;
}
/* Write some dummy data to the control pipe and /* Write some dummy data to the control pipe and
* wait for the thread to exit */ * wait for the thread to exit */
r = usbi_write(netlink_control_pipe[1], &dummy, sizeof(dummy)); r = usbi_write(netlink_control_pipe[1], &dummy, sizeof(dummy));
if (r <= 0) { if (r <= 0)
usbi_warn(NULL, "netlink control pipe signal failed"); usbi_warn(NULL, "netlink control pipe signal failed");
}
pthread_join(libusb_linux_event_thread, NULL); pthread_join(libusb_linux_event_thread, NULL);
close(linux_netlink_socket); close(linux_netlink_socket);
@ -179,24 +182,23 @@ int linux_netlink_stop_event_monitor(void)
static const char *netlink_message_parse(const char *buffer, size_t len, const char *key) static const char *netlink_message_parse(const char *buffer, size_t len, const char *key)
{ {
const char *end = buffer + len;
size_t keylen = strlen(key); size_t keylen = strlen(key);
size_t offset;
for (offset = 0 ; offset < len && '\0' != buffer[offset] ; offset += strlen(buffer + offset) + 1) { while (buffer < end && *buffer) {
if (0 == strncmp(buffer + offset, key, keylen) && if (strncmp(buffer, key, keylen) == 0 && buffer[keylen] == '=')
'=' == buffer[offset + keylen]) { return buffer + keylen + 1;
return buffer + offset + keylen + 1; buffer += strlen(buffer) + 1;
}
} }
return NULL; return NULL;
} }
/* parse parts of netlink message common to both libudev and the kernel */ /* parse parts of netlink message common to both libudev and the kernel */
static int linux_netlink_parse(char *buffer, size_t len, int *detached, const char **sys_name, static int linux_netlink_parse(const char *buffer, size_t len, int *detached,
uint8_t *busnum, uint8_t *devaddr) { const char **sys_name, uint8_t *busnum, uint8_t *devaddr)
const char *tmp; {
int i; const char *tmp, *slash;
errno = 0; errno = 0;
@ -205,53 +207,32 @@ static int linux_netlink_parse(char *buffer, size_t len, int *detached, const ch
*busnum = 0; *busnum = 0;
*devaddr = 0; *devaddr = 0;
tmp = netlink_message_parse((const char *) buffer, len, "ACTION"); tmp = netlink_message_parse(buffer, len, "ACTION");
if (tmp == NULL) if (!tmp) {
return -1; return -1;
if (0 == strcmp(tmp, "remove")) { } else if (strcmp(tmp, "remove") == 0) {
*detached = 1; *detached = 1;
} else if (0 != strcmp(tmp, "add")) { } else if (strcmp(tmp, "add") != 0) {
usbi_dbg("unknown device action %s", tmp); usbi_dbg("unknown device action %s", tmp);
return -1; return -1;
} }
/* check that this is a usb message */ /* check that this is a usb message */
tmp = netlink_message_parse(buffer, len, "SUBSYSTEM"); tmp = netlink_message_parse(buffer, len, "SUBSYSTEM");
if (NULL == tmp || 0 != strcmp(tmp, "usb")) { if (!tmp || strcmp(tmp, "usb") != 0) {
/* not usb. ignore */
return -1;
}
/* check that this is an actual usb device */
tmp = netlink_message_parse(buffer, len, "DEVTYPE");
if (!tmp || strcmp(tmp, "usb_device") != 0) {
/* not usb. ignore */ /* not usb. ignore */
return -1; return -1;
} }
tmp = netlink_message_parse(buffer, len, "BUSNUM"); tmp = netlink_message_parse(buffer, len, "BUSNUM");
if (NULL == tmp) { if (tmp) {
/* no bus number. try "DEVICE" */
tmp = netlink_message_parse(buffer, len, "DEVICE");
if (NULL == tmp) {
/* not usb. ignore */
return -1;
}
/* Parse a device path such as /dev/bus/usb/003/004 */
char *pLastSlash = (char*)strrchr(tmp,'/');
if(NULL == pLastSlash) {
return -1;
}
*devaddr = strtoul(pLastSlash + 1, NULL, 10);
if (errno) {
errno = 0;
return -1;
}
*busnum = strtoul(pLastSlash - 3, NULL, 10);
if (errno) {
errno = 0;
return -1;
}
return 0;
}
*busnum = (uint8_t)(strtoul(tmp, NULL, 10) & 0xff); *busnum = (uint8_t)(strtoul(tmp, NULL, 10) & 0xff);
if (errno) { if (errno) {
errno = 0; errno = 0;
@ -259,56 +240,104 @@ static int linux_netlink_parse(char *buffer, size_t len, int *detached, const ch
} }
tmp = netlink_message_parse(buffer, len, "DEVNUM"); tmp = netlink_message_parse(buffer, len, "DEVNUM");
if (NULL == tmp) { if (NULL == tmp)
return -1; return -1;
}
*devaddr = (uint8_t)(strtoul(tmp, NULL, 10) & 0xff); *devaddr = (uint8_t)(strtoul(tmp, NULL, 10) & 0xff);
if (errno) { if (errno) {
errno = 0; errno = 0;
return -1; return -1;
} }
} else {
tmp = netlink_message_parse(buffer, len, "DEVPATH"); /* no bus number. try "DEVICE" */
if (NULL == tmp) { tmp = netlink_message_parse(buffer, len, "DEVICE");
if (!tmp) {
/* not usb. ignore */
return -1; return -1;
} }
for (i = strlen(tmp) - 1 ; i ; --i) { /* Parse a device path such as /dev/bus/usb/003/004 */
if ('/' ==tmp[i]) { slash = strrchr(tmp, '/');
*sys_name = tmp + i + 1; if (!slash)
break; return -1;
*busnum = (uint8_t)(strtoul(slash - 3, NULL, 10) & 0xff);
if (errno) {
errno = 0;
return -1;
} }
*devaddr = (uint8_t)(strtoul(slash + 1, NULL, 10) & 0xff);
if (errno) {
errno = 0;
return -1;
} }
return 0;
}
tmp = netlink_message_parse(buffer, len, "DEVPATH");
if (!tmp)
return -1;
slash = strrchr(tmp, '/');
if (slash)
*sys_name = slash + 1;
/* found a usb device */ /* found a usb device */
return 0; return 0;
} }
static int linux_netlink_read_message(void) static int linux_netlink_read_message(void)
{ {
unsigned char buffer[1024]; char cred_buffer[CMSG_SPACE(sizeof(struct ucred))];
struct iovec iov = {.iov_base = buffer, .iov_len = sizeof(buffer)}; char msg_buffer[2048];
struct msghdr meh = { .msg_iov=&iov, .msg_iovlen=1,
.msg_name=&snl, .msg_namelen=sizeof(snl) };
const char *sys_name = NULL; const char *sys_name = NULL;
uint8_t busnum, devaddr; uint8_t busnum, devaddr;
int detached, r; int detached, r;
size_t len; ssize_t len;
struct cmsghdr *cmsg;
struct ucred *cred;
struct sockaddr_nl sa_nl;
struct iovec iov = { .iov_base = msg_buffer, .iov_len = sizeof(msg_buffer) };
struct msghdr msg = {
.msg_iov = &iov, .msg_iovlen = 1,
.msg_control = cred_buffer, .msg_controllen = sizeof(cred_buffer),
.msg_name = &sa_nl, .msg_namelen = sizeof(sa_nl)
};
/* read netlink message */ /* read netlink message */
memset(buffer, 0, sizeof(buffer)); len = recvmsg(linux_netlink_socket, &msg, 0);
len = recvmsg(linux_netlink_socket, &meh, 0); if (len == -1) {
if (len < 32) { if (errno != EAGAIN && errno != EINTR)
if (errno != EAGAIN) usbi_err(NULL, "error receiving message from netlink (%d)", errno);
usbi_dbg("error recieving message from netlink");
return -1; return -1;
} }
/* TODO -- authenticate this message is from the kernel or udevd */ if (len < 32 || (msg.msg_flags & MSG_TRUNC)) {
usbi_err(NULL, "invalid netlink message length");
return -1;
}
r = linux_netlink_parse(buffer, len, &detached, &sys_name, if (sa_nl.nl_groups != NL_GROUP_KERNEL || sa_nl.nl_pid != 0) {
&busnum, &devaddr); usbi_dbg("ignoring netlink message from unknown group/PID (%u/%u)",
(unsigned int)sa_nl.nl_groups, (unsigned int)sa_nl.nl_pid);
return -1;
}
cmsg = CMSG_FIRSTHDR(&msg);
if (!cmsg || cmsg->cmsg_type != SCM_CREDENTIALS) {
usbi_dbg("ignoring netlink message with no sender credentials");
return -1;
}
cred = (struct ucred *)CMSG_DATA(cmsg);
if (cred->uid != 0) {
usbi_dbg("ignoring netlink message with non-zero sender UID %u", (unsigned int)cred->uid);
return -1;
}
r = linux_netlink_parse(msg_buffer, (size_t)len, &detached, &sys_name, &busnum, &devaddr);
if (r) if (r)
return r; return r;
@ -317,7 +346,7 @@ static int linux_netlink_read_message(void)
/* signal device is available (or not) to all contexts */ /* signal device is available (or not) to all contexts */
if (detached) if (detached)
linux_device_disconnected(busnum, devaddr, sys_name); linux_device_disconnected(busnum, devaddr);
else else
linux_hotplug_enumerate(busnum, devaddr, sys_name); linux_hotplug_enumerate(busnum, devaddr, sys_name);
@ -327,7 +356,7 @@ static int linux_netlink_read_message(void)
static void *linux_netlink_event_thread_main(void *arg) static void *linux_netlink_event_thread_main(void *arg)
{ {
char dummy; char dummy;
int r; ssize_t r;
struct pollfd fds[] = { struct pollfd fds[] = {
{ .fd = netlink_control_pipe[0], { .fd = netlink_control_pipe[0],
.events = POLLIN }, .events = POLLIN },
@ -335,16 +364,16 @@ static void *linux_netlink_event_thread_main(void *arg)
.events = POLLIN }, .events = POLLIN },
}; };
/* silence compiler warning */ UNUSED(arg);
(void) arg;
usbi_dbg("netlink event thread entering");
while (poll(fds, 2, -1) >= 0) { while (poll(fds, 2, -1) >= 0) {
if (fds[0].revents & POLLIN) { if (fds[0].revents & POLLIN) {
/* activity on control pipe, read the byte and exit */ /* activity on control pipe, read the byte and exit */
r = usbi_read(netlink_control_pipe[0], &dummy, sizeof(dummy)); r = usbi_read(netlink_control_pipe[0], &dummy, sizeof(dummy));
if (r <= 0) { if (r <= 0)
usbi_warn(NULL, "netlink control pipe read failed"); usbi_warn(NULL, "netlink control pipe read failed");
}
break; break;
} }
if (fds[1].revents & POLLIN) { if (fds[1].revents & POLLIN) {
@ -354,6 +383,8 @@ static void *linux_netlink_event_thread_main(void *arg)
} }
} }
usbi_dbg("netlink event thread exiting");
return NULL; return NULL;
} }

View File

@ -69,7 +69,7 @@ int linux_udev_start_event_monitor(void)
goto err_free_ctx; goto err_free_ctx;
} }
r = udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, "usb", 0); r = udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, "usb", "usb_device");
if (r) { if (r) {
usbi_err(NULL, "could not initialize udev monitor filter for \"usb\" subsystem"); usbi_err(NULL, "could not initialize udev monitor filter for \"usb\" subsystem");
goto err_free_monitor; goto err_free_monitor;
@ -240,7 +240,7 @@ static void udev_hotplug_event(struct udev_device* udev_dev)
if (strncmp(udev_action, "add", 3) == 0) { if (strncmp(udev_action, "add", 3) == 0) {
linux_hotplug_enumerate(busnum, devaddr, sys_name); linux_hotplug_enumerate(busnum, devaddr, sys_name);
} else if (detached) { } else if (detached) {
linux_device_disconnected(busnum, devaddr, sys_name); linux_device_disconnected(busnum, devaddr);
} else { } else {
usbi_err(NULL, "ignoring udev action %s", udev_action); usbi_err(NULL, "ignoring udev action %s", udev_action);
} }
@ -266,6 +266,7 @@ int linux_udev_scan_devices(struct libusb_context *ctx)
} }
udev_enumerate_add_match_subsystem(enumerator, "usb"); udev_enumerate_add_match_subsystem(enumerator, "usb");
udev_enumerate_add_match_property(enumerator, "DEVTYPE", "usb_device");
udev_enumerate_scan_devices(enumerator); udev_enumerate_scan_devices(enumerator);
devices = udev_enumerate_get_list_entry(enumerator); devices = udev_enumerate_get_list_entry(enumerator);

View File

@ -33,10 +33,11 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/utsname.h> #include <sys/utsname.h>
#include <unistd.h> #include <time.h>
#include "libusbi.h" #include "libusbi.h"
#include "linux_usbfs.h" #include "linux_usbfs.h"
@ -121,7 +122,7 @@ static int sysfs_has_descriptors = -1;
static int init_count = 0; static int init_count = 0;
/* Serialize hotplug start/stop */ /* Serialize hotplug start/stop */
usbi_mutex_static_t linux_hotplug_startstop_lock = USBI_MUTEX_INITIALIZER; static usbi_mutex_static_t linux_hotplug_startstop_lock = USBI_MUTEX_INITIALIZER;
/* Serialize scan-devices, event-thread, and poll */ /* Serialize scan-devices, event-thread, and poll */
usbi_mutex_static_t linux_hotplug_lock = USBI_MUTEX_INITIALIZER; usbi_mutex_static_t linux_hotplug_lock = USBI_MUTEX_INITIALIZER;
@ -144,6 +145,7 @@ struct linux_device_priv {
struct linux_device_handle_priv { struct linux_device_handle_priv {
int fd; int fd;
int fd_removed;
uint32_t caps; uint32_t caps;
}; };
@ -201,7 +203,7 @@ static int _get_usbfs_fd(struct libusb_device *dev, mode_t mode, int silent)
usbi_err(ctx, "File doesn't exist, wait %d ms and try again", delay/1000); usbi_err(ctx, "File doesn't exist, wait %d ms and try again", delay/1000);
/* Wait 10ms for USB device path creation.*/ /* Wait 10ms for USB device path creation.*/
usleep(delay); nanosleep(&(struct timespec){delay / 1000000, (delay * 1000) % 1000000000UL}, NULL);
fd = open(path, mode); fd = open(path, mode);
if (fd != -1) if (fd != -1)
@ -842,6 +844,7 @@ static int op_get_config_descriptor(struct libusb_device *dev,
/* send a control message to retrieve active configuration */ /* send a control message to retrieve active configuration */
static int usbfs_get_active_config(struct libusb_device *dev, int fd) static int usbfs_get_active_config(struct libusb_device *dev, int fd)
{ {
struct linux_device_priv *priv = _device_priv(dev);
unsigned char active_config = 0; unsigned char active_config = 0;
int r; int r;
@ -863,10 +866,23 @@ static int usbfs_get_active_config(struct libusb_device *dev, int fd)
/* we hit this error path frequently with buggy devices :( */ /* we hit this error path frequently with buggy devices :( */
usbi_warn(DEVICE_CTX(dev), usbi_warn(DEVICE_CTX(dev),
"get_configuration failed ret=%d errno=%d", r, errno); "get_configuration failed ret=%d errno=%d", r, errno);
return LIBUSB_ERROR_IO; priv->active_config = -1;
} else {
if (active_config > 0) {
priv->active_config = active_config;
} else {
/* some buggy devices have a configuration 0, but we're
* reaching into the corner of a corner case here, so let's
* not support buggy devices in these circumstances.
* stick to the specs: a configuration value of 0 means
* unconfigured. */
usbi_warn(DEVICE_CTX(dev),
"active cfg 0? assuming unconfigured device");
priv->active_config = -1;
}
} }
return active_config; return LIBUSB_SUCCESS;
} }
static int initialize_device(struct libusb_device *dev, uint8_t busnum, static int initialize_device(struct libusb_device *dev, uint8_t busnum,
@ -882,10 +898,9 @@ static int initialize_device(struct libusb_device *dev, uint8_t busnum,
dev->device_address = devaddr; dev->device_address = devaddr;
if (sysfs_dir) { if (sysfs_dir) {
priv->sysfs_dir = malloc(strlen(sysfs_dir) + 1); priv->sysfs_dir = strdup(sysfs_dir);
if (!priv->sysfs_dir) if (!priv->sysfs_dir)
return LIBUSB_ERROR_NO_MEM; return LIBUSB_ERROR_NO_MEM;
strcpy(priv->sysfs_dir, sysfs_dir);
/* Note speed can contain 1.5, in this case __read_sysfs_attr /* Note speed can contain 1.5, in this case __read_sysfs_attr
will stop parsing at the '.' and return 1 */ will stop parsing at the '.' and return 1 */
@ -966,28 +981,8 @@ static int initialize_device(struct libusb_device *dev, uint8_t busnum,
} }
r = usbfs_get_active_config(dev, fd); r = usbfs_get_active_config(dev, fd);
if (r > 0) {
priv->active_config = r;
r = LIBUSB_SUCCESS;
} else if (r == 0) {
/* some buggy devices have a configuration 0, but we're
* reaching into the corner of a corner case here, so let's
* not support buggy devices in these circumstances.
* stick to the specs: a configuration value of 0 means
* unconfigured. */
usbi_dbg("active cfg 0? assuming unconfigured device");
priv->active_config = -1;
r = LIBUSB_SUCCESS;
} else if (r == LIBUSB_ERROR_IO) {
/* buggy devices sometimes fail to report their active config.
* assume unconfigured and continue the probing */
usbi_warn(ctx, "couldn't query active configuration, assuming"
" unconfigured");
priv->active_config = -1;
r = LIBUSB_SUCCESS;
} /* else r < 0, just return the error code */
close(fd); close(fd);
return r; return r;
} }
@ -1115,7 +1110,7 @@ void linux_hotplug_enumerate(uint8_t busnum, uint8_t devaddr, const char *sys_na
usbi_mutex_static_unlock(&active_contexts_lock); usbi_mutex_static_unlock(&active_contexts_lock);
} }
void linux_device_disconnected(uint8_t busnum, uint8_t devaddr, const char *sys_name) void linux_device_disconnected(uint8_t busnum, uint8_t devaddr)
{ {
struct libusb_context *ctx; struct libusb_context *ctx;
struct libusb_device *dev; struct libusb_device *dev;
@ -1299,7 +1294,7 @@ static int op_open(struct libusb_device_handle *handle)
if (handle->dev->attached) { if (handle->dev->attached) {
usbi_dbg("open failed with no device, but device still attached"); usbi_dbg("open failed with no device, but device still attached");
linux_device_disconnected(handle->dev->bus_number, linux_device_disconnected(handle->dev->bus_number,
handle->dev->device_address, NULL); handle->dev->device_address);
} }
usbi_mutex_static_unlock(&linux_hotplug_lock); usbi_mutex_static_unlock(&linux_hotplug_lock);
} }
@ -1319,14 +1314,20 @@ static int op_open(struct libusb_device_handle *handle)
hpriv->caps |= USBFS_CAP_BULK_CONTINUATION; hpriv->caps |= USBFS_CAP_BULK_CONTINUATION;
} }
return usbi_add_pollfd(HANDLE_CTX(handle), hpriv->fd, POLLOUT); r = usbi_add_pollfd(HANDLE_CTX(handle), hpriv->fd, POLLOUT);
if (r < 0)
close(hpriv->fd);
return r;
} }
static void op_close(struct libusb_device_handle *dev_handle) static void op_close(struct libusb_device_handle *dev_handle)
{ {
int fd = _device_handle_priv(dev_handle)->fd; struct linux_device_handle_priv *hpriv = _device_handle_priv(dev_handle);
usbi_remove_pollfd(HANDLE_CTX(dev_handle), fd); /* fd may have already been removed by POLLERR condition in op_handle_events() */
close(fd); if (!hpriv->fd_removed)
usbi_remove_pollfd(HANDLE_CTX(dev_handle), hpriv->fd);
close(hpriv->fd);
} }
static int op_get_configuration(struct libusb_device_handle *handle, static int op_get_configuration(struct libusb_device_handle *handle,
@ -1339,6 +1340,8 @@ static int op_get_configuration(struct libusb_device_handle *handle,
} else { } else {
r = usbfs_get_active_config(handle->dev, r = usbfs_get_active_config(handle->dev,
_device_handle_priv(handle)->fd); _device_handle_priv(handle)->fd);
if (r == LIBUSB_SUCCESS)
*config = _device_priv(handle->dev)->active_config;
} }
if (r < 0) if (r < 0)
return r; return r;
@ -1555,6 +1558,32 @@ static int op_free_streams(struct libusb_device_handle *handle,
endpoints, num_endpoints); endpoints, num_endpoints);
} }
static unsigned char *op_dev_mem_alloc(struct libusb_device_handle *handle,
size_t len)
{
struct linux_device_handle_priv *hpriv = _device_handle_priv(handle);
unsigned char *buffer = (unsigned char *)mmap(NULL, len,
PROT_READ | PROT_WRITE, MAP_SHARED, hpriv->fd, 0);
if (buffer == MAP_FAILED) {
usbi_err(HANDLE_CTX(handle), "alloc dev mem failed errno %d",
errno);
return NULL;
}
return buffer;
}
static int op_dev_mem_free(struct libusb_device_handle *handle,
unsigned char *buffer, size_t len)
{
if (munmap(buffer, len) != 0) {
usbi_err(HANDLE_CTX(handle), "free dev mem failed errno %d",
errno);
return LIBUSB_ERROR_OTHER;
} else {
return LIBUSB_SUCCESS;
}
}
static int op_kernel_driver_active(struct libusb_device_handle *handle, static int op_kernel_driver_active(struct libusb_device_handle *handle,
int interface) int interface)
{ {
@ -2595,15 +2624,27 @@ static int op_handle_events(struct libusb_context *ctx,
} }
if (pollfd->revents & POLLERR) { if (pollfd->revents & POLLERR) {
/* remove the fd from the pollfd set so that it doesn't continuously
* trigger an event, and flag that it has been removed so op_close()
* doesn't try to remove it a second time */
usbi_remove_pollfd(HANDLE_CTX(handle), hpriv->fd); usbi_remove_pollfd(HANDLE_CTX(handle), hpriv->fd);
usbi_handle_disconnect(handle); hpriv->fd_removed = 1;
/* device will still be marked as attached if hotplug monitor thread /* device will still be marked as attached if hotplug monitor thread
* hasn't processed remove event yet */ * hasn't processed remove event yet */
usbi_mutex_static_lock(&linux_hotplug_lock); usbi_mutex_static_lock(&linux_hotplug_lock);
if (handle->dev->attached) if (handle->dev->attached)
linux_device_disconnected(handle->dev->bus_number, linux_device_disconnected(handle->dev->bus_number,
handle->dev->device_address, NULL); handle->dev->device_address);
usbi_mutex_static_unlock(&linux_hotplug_lock); usbi_mutex_static_unlock(&linux_hotplug_lock);
if (hpriv->caps & USBFS_CAP_REAP_AFTER_DISCONNECT) {
do {
r = reap_for_handle(handle);
} while (r == 0);
}
usbi_handle_disconnect(handle);
continue; continue;
} }
@ -2668,6 +2709,9 @@ const struct usbi_os_backend linux_usbfs_backend = {
.alloc_streams = op_alloc_streams, .alloc_streams = op_alloc_streams,
.free_streams = op_free_streams, .free_streams = op_free_streams,
.dev_mem_alloc = op_dev_mem_alloc,
.dev_mem_free = op_dev_mem_free,
.kernel_driver_active = op_kernel_driver_active, .kernel_driver_active = op_kernel_driver_active,
.detach_kernel_driver = op_detach_kernel_driver, .detach_kernel_driver = op_detach_kernel_driver,
.attach_kernel_driver = op_attach_kernel_driver, .attach_kernel_driver = op_attach_kernel_driver,

View File

@ -125,6 +125,7 @@ struct usbfs_hub_portinfo {
#define USBFS_CAP_BULK_CONTINUATION 0x02 #define USBFS_CAP_BULK_CONTINUATION 0x02
#define USBFS_CAP_NO_PACKET_SIZE_LIM 0x04 #define USBFS_CAP_NO_PACKET_SIZE_LIM 0x04
#define USBFS_CAP_BULK_SCATTER_GATHER 0x08 #define USBFS_CAP_BULK_SCATTER_GATHER 0x08
#define USBFS_CAP_REAP_AFTER_DISCONNECT 0x10
#define USBFS_DISCONNECT_CLAIM_IF_DRIVER 0x01 #define USBFS_DISCONNECT_CLAIM_IF_DRIVER 0x01
#define USBFS_DISCONNECT_CLAIM_EXCEPT_DRIVER 0x02 #define USBFS_DISCONNECT_CLAIM_EXCEPT_DRIVER 0x02
@ -181,7 +182,7 @@ void linux_netlink_hotplug_poll(void);
#endif #endif
void linux_hotplug_enumerate(uint8_t busnum, uint8_t devaddr, const char *sys_name); void linux_hotplug_enumerate(uint8_t busnum, uint8_t devaddr, const char *sys_name);
void linux_device_disconnected(uint8_t busnum, uint8_t devaddr, const char *sys_name); void linux_device_disconnected(uint8_t busnum, uint8_t devaddr);
int linux_get_device_address (struct libusb_context *ctx, int detached, int linux_get_device_address (struct libusb_context *ctx, int detached,
uint8_t *busnum, uint8_t *devaddr, const char *dev_node, uint8_t *busnum, uint8_t *devaddr, const char *dev_node,

View File

@ -114,6 +114,9 @@ const struct usbi_os_backend netbsd_backend = {
NULL, /* alloc_streams */ NULL, /* alloc_streams */
NULL, /* free_streams */ NULL, /* free_streams */
NULL, /* dev_mem_alloc() */
NULL, /* dev_mem_free() */
NULL, /* kernel_driver_active() */ NULL, /* kernel_driver_active() */
NULL, /* detach_kernel_driver() */ NULL, /* detach_kernel_driver() */
NULL, /* attach_kernel_driver() */ NULL, /* attach_kernel_driver() */

View File

@ -117,6 +117,9 @@ const struct usbi_os_backend openbsd_backend = {
NULL, /* alloc_streams */ NULL, /* alloc_streams */
NULL, /* free_streams */ NULL, /* free_streams */
NULL, /* dev_mem_alloc() */
NULL, /* dev_mem_free() */
NULL, /* kernel_driver_active() */ NULL, /* kernel_driver_active() */
NULL, /* detach_kernel_driver() */ NULL, /* detach_kernel_driver() */
NULL, /* attach_kernel_driver() */ NULL, /* attach_kernel_driver() */

View File

@ -54,7 +54,7 @@
#define poll_dbg usbi_dbg #define poll_dbg usbi_dbg
#else #else
// MSVC++ < 2005 cannot use a variadic argument and non MSVC // MSVC++ < 2005 cannot use a variadic argument and non MSVC
// compilers produce warnings if parenthesis are ommitted. // compilers produce warnings if parenthesis are omitted.
#if defined(_MSC_VER) && (_MSC_VER < 1400) #if defined(_MSC_VER) && (_MSC_VER < 1400)
#define poll_dbg #define poll_dbg
#else #else
@ -590,9 +590,9 @@ int usbi_poll(struct pollfd *fds, unsigned int nfds, int timeout)
// If nothing was triggered, wait on all fds that require it // If nothing was triggered, wait on all fds that require it
if ((timeout != 0) && (triggered == 0) && (nb_handles_to_wait_on != 0)) { if ((timeout != 0) && (triggered == 0) && (nb_handles_to_wait_on != 0)) {
if (timeout < 0) { if (timeout < 0) {
poll_dbg("starting infinite wait for %d handles...", (int)nb_handles_to_wait_on); poll_dbg("starting infinite wait for %u handles...", (unsigned int)nb_handles_to_wait_on);
} else { } else {
poll_dbg("starting %d ms wait for %d handles...", timeout, (int)nb_handles_to_wait_on); poll_dbg("starting %d ms wait for %u handles...", timeout, (unsigned int)nb_handles_to_wait_on);
} }
ret = WaitForMultipleObjects(nb_handles_to_wait_on, handles_to_wait_on, ret = WaitForMultipleObjects(nb_handles_to_wait_on, handles_to_wait_on,
FALSE, (timeout<0)?INFINITE:(DWORD)timeout); FALSE, (timeout<0)?INFINITE:(DWORD)timeout);
@ -672,7 +672,7 @@ ssize_t usbi_write(int fd, const void *buf, size_t count)
return -1; return -1;
} }
poll_dbg("set pipe event (fd = %d, thread = %08X)", _index, GetCurrentThreadId()); poll_dbg("set pipe event (fd = %d, thread = %08X)", _index, (unsigned int)GetCurrentThreadId());
SetEvent(poll_fd[_index].overlapped->hEvent); SetEvent(poll_fd[_index].overlapped->hEvent);
poll_fd[_index].overlapped->Internal = STATUS_WAIT_0; poll_fd[_index].overlapped->Internal = STATUS_WAIT_0;
// If two threads write on the pipe at the same time, we need to // If two threads write on the pipe at the same time, we need to
@ -707,12 +707,12 @@ ssize_t usbi_read(int fd, void *buf, size_t count)
} }
if (WaitForSingleObject(poll_fd[_index].overlapped->hEvent, INFINITE) != WAIT_OBJECT_0) { if (WaitForSingleObject(poll_fd[_index].overlapped->hEvent, INFINITE) != WAIT_OBJECT_0) {
usbi_warn(NULL, "waiting for event failed: %d", (int)GetLastError()); usbi_warn(NULL, "waiting for event failed: %u", (unsigned int)GetLastError());
errno = EIO; errno = EIO;
goto out; goto out;
} }
poll_dbg("clr pipe event (fd = %d, thread = %08X)", _index, GetCurrentThreadId()); poll_dbg("clr pipe event (fd = %d, thread = %08X)", _index, (unsigned int)GetCurrentThreadId());
poll_fd[_index].overlapped->InternalHigh--; poll_fd[_index].overlapped->InternalHigh--;
// Don't reset unless we don't have any more events to process // Don't reset unless we don't have any more events to process
if (poll_fd[_index].overlapped->InternalHigh <= 0) { if (poll_fd[_index].overlapped->InternalHigh <= 0) {

1292
Externals/libusb/libusb/os/sunos_usb.c vendored Normal file

File diff suppressed because it is too large Load Diff

74
Externals/libusb/libusb/os/sunos_usb.h vendored Normal file
View File

@ -0,0 +1,74 @@
/*
*
* Copyright (c) 2016, Oracle and/or its affiliates.
*
* 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_SUNOS_H
#define LIBUSB_SUNOS_H
#include <libdevinfo.h>
#include <pthread.h>
#include "libusbi.h"
#define READ 0
#define WRITE 1
typedef struct sunos_device_priv {
uint8_t cfgvalue; /* active config value */
uint8_t *raw_cfgdescr; /* active config descriptor */
struct libusb_device_descriptor dev_descr; /* usb device descriptor */
char *ugenpath; /* name of the ugen(4) node */
char *phypath; /* physical path */
} sunos_dev_priv_t;
typedef struct endpoint {
int datafd; /* data file */
int statfd; /* state file */
} sunos_ep_priv_t;
typedef struct sunos_device_handle_priv {
uint8_t altsetting[USB_MAXINTERFACES]; /* a interface's alt */
uint8_t config_index;
sunos_ep_priv_t eps[USB_MAXENDPOINTS];
sunos_dev_priv_t *dpriv; /* device private */
} sunos_dev_handle_priv_t;
typedef struct sunos_transfer_priv {
struct aiocb aiocb;
struct libusb_transfer *transfer;
} sunos_xfer_priv_t;
struct node_args {
struct libusb_context *ctx;
struct discovered_devs **discdevs;
const char *last_ugenpath;
di_devlink_handle_t dlink_hdl;
};
struct devlink_cbarg {
struct node_args *nargs; /* di node walk arguments */
di_node_t myself; /* the di node */
di_minor_t minor;
};
/* AIO callback args */
struct aio_callback_args{
struct libusb_transfer *transfer;
struct aiocb aiocb;
};
#endif /* LIBUSB_SUNOS_H */

View File

@ -21,6 +21,7 @@
#include <config.h> #include <config.h>
#include <time.h>
#if defined(__linux__) || defined(__OpenBSD__) #if defined(__linux__) || defined(__OpenBSD__)
# if defined(__OpenBSD__) # if defined(__OpenBSD__)
# define _BSD_SOURCE # define _BSD_SOURCE
@ -34,30 +35,26 @@
#endif #endif
#include "threads_posix.h" #include "threads_posix.h"
#include "libusbi.h"
int usbi_mutex_init_recursive(pthread_mutex_t *mutex, pthread_mutexattr_t *attr) int usbi_cond_timedwait(pthread_cond_t *cond,
pthread_mutex_t *mutex, const struct timeval *tv)
{ {
int err; struct timespec timeout;
pthread_mutexattr_t stack_attr; int r;
if (!attr) {
attr = &stack_attr; r = usbi_backend->clock_gettime(USBI_CLOCK_REALTIME, &timeout);
err = pthread_mutexattr_init(&stack_attr); if (r < 0)
if (err != 0) return r;
return err;
timeout.tv_sec += tv->tv_sec;
timeout.tv_nsec += tv->tv_usec * 1000;
while (timeout.tv_nsec >= 1000000000L) {
timeout.tv_nsec -= 1000000000L;
timeout.tv_sec++;
} }
/* mutexattr_settype requires _GNU_SOURCE or _XOPEN_SOURCE >= 500 on Linux */ return pthread_cond_timedwait(cond, mutex, &timeout);
err = pthread_mutexattr_settype(attr, PTHREAD_MUTEX_RECURSIVE);
if (err != 0)
goto finish;
err = pthread_mutex_init(mutex, attr);
finish:
if (attr == &stack_attr)
pthread_mutexattr_destroy(&stack_attr);
return err;
} }
int usbi_get_tid(void) int usbi_get_tid(void)

View File

@ -22,6 +22,9 @@
#define LIBUSB_THREADS_POSIX_H #define LIBUSB_THREADS_POSIX_H
#include <pthread.h> #include <pthread.h>
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#define usbi_mutex_static_t pthread_mutex_t #define usbi_mutex_static_t pthread_mutex_t
#define USBI_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER #define USBI_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
@ -29,21 +32,26 @@
#define usbi_mutex_static_unlock pthread_mutex_unlock #define usbi_mutex_static_unlock pthread_mutex_unlock
#define usbi_mutex_t pthread_mutex_t #define usbi_mutex_t pthread_mutex_t
#define usbi_mutex_init pthread_mutex_init #define usbi_mutex_init(mutex) pthread_mutex_init((mutex), NULL)
#define usbi_mutex_lock pthread_mutex_lock #define usbi_mutex_lock pthread_mutex_lock
#define usbi_mutex_unlock pthread_mutex_unlock #define usbi_mutex_unlock pthread_mutex_unlock
#define usbi_mutex_trylock pthread_mutex_trylock #define usbi_mutex_trylock pthread_mutex_trylock
#define usbi_mutex_destroy pthread_mutex_destroy #define usbi_mutex_destroy pthread_mutex_destroy
#define usbi_cond_t pthread_cond_t #define usbi_cond_t pthread_cond_t
#define usbi_cond_init pthread_cond_init #define usbi_cond_init(cond) pthread_cond_init((cond), NULL)
#define usbi_cond_wait pthread_cond_wait #define usbi_cond_wait pthread_cond_wait
#define usbi_cond_timedwait pthread_cond_timedwait
#define usbi_cond_broadcast pthread_cond_broadcast #define usbi_cond_broadcast pthread_cond_broadcast
#define usbi_cond_destroy pthread_cond_destroy #define usbi_cond_destroy pthread_cond_destroy
#define usbi_cond_signal pthread_cond_signal
extern int usbi_mutex_init_recursive(pthread_mutex_t *mutex, pthread_mutexattr_t *attr); #define usbi_tls_key_t pthread_key_t
#define usbi_tls_key_create(key) pthread_key_create((key), NULL)
#define usbi_tls_key_get pthread_getspecific
#define usbi_tls_key_set pthread_setspecific
#define usbi_tls_key_delete pthread_key_delete
int usbi_cond_timedwait(pthread_cond_t *cond,
pthread_mutex_t *mutex, const struct timeval *tv);
int usbi_get_tid(void); int usbi_get_tid(void);

View File

@ -22,134 +22,161 @@
#include <objbase.h> #include <objbase.h>
#include <errno.h> #include <errno.h>
#include <stdarg.h>
#include "libusbi.h" #include "libusbi.h"
extern const uint64_t epoch_time; struct usbi_cond_perthread {
struct list_head list;
DWORD tid;
HANDLE event;
};
int usbi_mutex_init(usbi_mutex_t *mutex, int usbi_mutex_static_lock(usbi_mutex_static_t *mutex)
const usbi_mutexattr_t *attr) { {
UNUSED(attr); if (!mutex)
if(! mutex) return ((errno=EINVAL)); return EINVAL;
while (InterlockedExchange(mutex, 1) == 1)
SleepEx(0, TRUE);
return 0;
}
int usbi_mutex_static_unlock(usbi_mutex_static_t *mutex)
{
if (!mutex)
return EINVAL;
InterlockedExchange(mutex, 0);
return 0;
}
int usbi_mutex_init(usbi_mutex_t *mutex)
{
if (!mutex)
return EINVAL;
*mutex = CreateMutex(NULL, FALSE, NULL); *mutex = CreateMutex(NULL, FALSE, NULL);
if(!*mutex) return ((errno=ENOMEM)); if (!*mutex)
return ENOMEM;
return 0; return 0;
} }
int usbi_mutex_destroy(usbi_mutex_t *mutex) {
// It is not clear if CloseHandle failure is due to failure to unlock. int usbi_mutex_lock(usbi_mutex_t *mutex)
// 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; DWORD result;
if(!mutex) return ((errno=EINVAL));
result = WaitForSingleObject(*mutex, 0); if (!mutex)
if(result == WAIT_OBJECT_0 || result == WAIT_ABANDONED) return EINVAL;
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); result = WaitForSingleObject(*mutex, INFINITE);
if (result == WAIT_OBJECT_0 || result == WAIT_ABANDONED) if (result == WAIT_OBJECT_0 || result == WAIT_ABANDONED)
return 0; // acquired (ToDo: check that abandoned is ok) return 0; // acquired (ToDo: check that abandoned is ok)
return ((errno=EINVAL)); // don't know how this would happen else
return EINVAL; // don't know how this would happen
// so don't know proper errno // so don't know proper errno
} }
int usbi_mutex_unlock(usbi_mutex_t *mutex) {
if(!mutex) return ((errno=EINVAL)); int usbi_mutex_unlock(usbi_mutex_t *mutex)
if(!ReleaseMutex(*mutex)) return ((errno=EPERM )); {
if (!mutex)
return EINVAL;
if (ReleaseMutex(*mutex))
return 0;
else
return EPERM;
}
int usbi_mutex_trylock(usbi_mutex_t *mutex)
{
DWORD result;
if (!mutex)
return EINVAL;
result = WaitForSingleObject(*mutex, 0);
if (result == WAIT_OBJECT_0 || result == WAIT_ABANDONED)
return 0; // acquired (ToDo: check that abandoned is ok)
else if (result == WAIT_TIMEOUT)
return EBUSY;
else
return EINVAL; // don't know how this would happen
// so don't know proper error
}
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 EINVAL;
*mutex = NULL;
return 0; return 0;
} }
int usbi_mutex_static_lock(usbi_mutex_static_t *mutex) { int usbi_cond_init(usbi_cond_t *cond)
if(!mutex) return ((errno=EINVAL)); {
while (InterlockedExchange((LONG *)mutex, 1) == 1) { if (!cond)
SleepEx(0, TRUE); return EINVAL;
}
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) {
UNUSED(attr);
if(!cond) return ((errno=EINVAL));
list_init(&cond->waiters); list_init(&cond->waiters);
list_init(&cond->not_waiting); list_init(&cond->not_waiting);
return 0; return 0;
} }
int usbi_cond_destroy(usbi_cond_t *cond) {
int usbi_cond_destroy(usbi_cond_t *cond)
{
// This assumes no one is using this anymore. The check MAY NOT BE safe. // This assumes no one is using this anymore. The check MAY NOT BE safe.
struct usbi_cond_perthread *pos, *next_pos = NULL; struct usbi_cond_perthread *pos, *next_pos;
if(!cond) return ((errno=EINVAL));
if(!list_empty(&cond->waiters)) return ((errno=EBUSY )); // (!see above!) if(!cond)
return EINVAL;
if (!list_empty(&cond->waiters))
return EBUSY; // (!see above!)
list_for_each_entry_safe(pos, next_pos, &cond->not_waiting, list, struct usbi_cond_perthread) { list_for_each_entry_safe(pos, next_pos, &cond->not_waiting, list, struct usbi_cond_perthread) {
CloseHandle(pos->event); CloseHandle(pos->event);
list_del(&pos->list); list_del(&pos->list);
free(pos); free(pos);
} }
return 0; return 0;
} }
int usbi_cond_broadcast(usbi_cond_t *cond) { int usbi_cond_broadcast(usbi_cond_t *cond)
{
// Assumes mutex is locked; this is not in keeping with POSIX spec, but // 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 // libusb does this anyway, so we simplify by not adding more sync
// primitives to the CV definition! // primitives to the CV definition!
int fail = 0; int fail = 0;
struct usbi_cond_perthread *pos; struct usbi_cond_perthread *pos;
if(!cond) return ((errno=EINVAL));
if (!cond)
return EINVAL;
list_for_each_entry(pos, &cond->waiters, list, struct usbi_cond_perthread) { list_for_each_entry(pos, &cond->waiters, list, struct usbi_cond_perthread) {
if (!SetEvent(pos->event)) if (!SetEvent(pos->event))
fail = 1; fail = 1;
} }
// The wait function will remove its respective item from the list. // The wait function will remove its respective item from the list.
return fail ? ((errno=EINVAL)) : 0; return fail ? 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));
} }
__inline static int usbi_cond_intwait(usbi_cond_t *cond, __inline static int usbi_cond_intwait(usbi_cond_t *cond,
usbi_mutex_t *mutex, usbi_mutex_t *mutex, DWORD timeout_ms)
DWORD timeout_ms) { {
struct usbi_cond_perthread *pos; struct usbi_cond_perthread *pos;
int found = 0, r; int r, found = 0;
DWORD r2, tid = GetCurrentThreadId(); DWORD r2, tid = GetCurrentThreadId();
if(!cond || !mutex) return ((errno=EINVAL));
if (!cond || !mutex)
return EINVAL;
list_for_each_entry(pos, &cond->not_waiting, list, struct usbi_cond_perthread) { list_for_each_entry(pos, &cond->not_waiting, list, struct usbi_cond_perthread) {
if(tid == pos->tid) { if(tid == pos->tid) {
found = 1; found = 1;
break; break;
} }
} }
if (!found) { if (!found) {
pos = (struct usbi_cond_perthread*) calloc(1, sizeof(struct usbi_cond_perthread)); pos = calloc(1, sizeof(struct usbi_cond_perthread));
if(!pos) return ((errno=ENOMEM)); // This errno is not POSIX-allowed. if (!pos)
return ENOMEM; // This errno is not POSIX-allowed.
pos->tid = tid; pos->tid = tid;
pos->event = CreateEvent(NULL, FALSE, FALSE, NULL); // auto-reset. pos->event = CreateEvent(NULL, FALSE, FALSE, NULL); // auto-reset.
if (!pos->event) { if (!pos->event) {
free(pos); free(pos);
return ((errno=ENOMEM)); return ENOMEM;
} }
list_add(&pos->list, &cond->not_waiting); list_add(&pos->list, &cond->not_waiting);
} }
@ -158,57 +185,75 @@ __inline static int usbi_cond_intwait(usbi_cond_t *cond,
list_add(&pos->list, &cond->waiters); list_add(&pos->list, &cond->waiters);
r = usbi_mutex_unlock(mutex); r = usbi_mutex_unlock(mutex);
if(r) return r; if (r)
return r;
r2 = WaitForSingleObject(pos->event, timeout_ms); r2 = WaitForSingleObject(pos->event, timeout_ms);
r = usbi_mutex_lock(mutex); r = usbi_mutex_lock(mutex);
if(r) return r; if (r)
return r;
list_del(&pos->list); list_del(&pos->list);
list_add(&pos->list, &cond->not_waiting); list_add(&pos->list, &cond->not_waiting);
if(r2 == WAIT_TIMEOUT) return ((errno=ETIMEDOUT)); if (r2 == WAIT_OBJECT_0)
return 0; return 0;
else if (r2 == WAIT_TIMEOUT)
return ETIMEDOUT;
else
return EINVAL;
} }
// N.B.: usbi_cond_*wait() can also return ENOMEM, even though pthread_cond_*wait cannot! // 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) { int usbi_cond_wait(usbi_cond_t *cond, usbi_mutex_t *mutex)
{
return usbi_cond_intwait(cond, mutex, INFINITE); return usbi_cond_intwait(cond, mutex, INFINITE);
} }
int usbi_cond_timedwait(usbi_cond_t *cond, int usbi_cond_timedwait(usbi_cond_t *cond,
usbi_mutex_t *mutex, usbi_mutex_t *mutex, const struct timeval *tv)
const struct timespec *abstime) { {
FILETIME filetime;
ULARGE_INTEGER rtime;
struct timeval targ_time, cur_time, delta_time;
struct timespec cur_time_ns;
DWORD millis; DWORD millis;
// GetSystemTimeAsFileTime() is not available on CE millis = (DWORD)(tv->tv_sec * 1000) + (tv->tv_usec / 1000);
SYSTEMTIME st; /* round up to next millisecond */
GetSystemTime(&st); if (tv->tv_usec % 1000)
if (!SystemTimeToFileTime(&st, &filetime))
return 0;
rtime.LowPart = filetime.dwLowDateTime;
rtime.HighPart = filetime.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;
if (delta_time.tv_usec % 1000) // round up to next millisecond
millis++; millis++;
}
return usbi_cond_intwait(cond, mutex, millis); return usbi_cond_intwait(cond, mutex, millis);
} }
int usbi_get_tid(void) { int usbi_tls_key_create(usbi_tls_key_t *key)
return GetCurrentThreadId(); {
if (!key)
return EINVAL;
*key = TlsAlloc();
if (*key == TLS_OUT_OF_INDEXES)
return ENOMEM;
else
return 0;
}
void *usbi_tls_key_get(usbi_tls_key_t key)
{
return TlsGetValue(key);
}
int usbi_tls_key_set(usbi_tls_key_t key, void *value)
{
if (TlsSetValue(key, value))
return 0;
else
return EINVAL;
}
int usbi_tls_key_delete(usbi_tls_key_t key)
{
if (TlsFree(key))
return 0;
else
return EINVAL;
}
int usbi_get_tid(void)
{
return (int)GetCurrentThreadId();
} }

View File

@ -26,33 +26,21 @@
#define usbi_mutex_t HANDLE #define usbi_mutex_t HANDLE
struct usbi_cond_perthread { typedef struct usbi_cond {
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. // 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 // It stays there until the CV is destroyed, even if the thread terminates.
// terminates.
struct list_head waiters; struct list_head waiters;
struct list_head not_waiting; struct list_head not_waiting;
}; } usbi_cond_t;
typedef struct usbi_cond_t_ usbi_cond_t;
// We *were* getting timespec from pthread.h: // We *were* getting timespec from pthread.h:
#if (!defined(HAVE_STRUCT_TIMESPEC) && !defined(_TIMESPEC_DEFINED)) #if (!defined(HAVE_STRUCT_TIMESPEC) && !defined(_TIMESPEC_DEFINED))
#define HAVE_STRUCT_TIMESPEC 1 #define HAVE_STRUCT_TIMESPEC 1
// (shuffle2) see https://github.com/libusb/libusb/pull/60
#if defined(_MSC_VER) && (_MSC_VER >= 1900)
#include <time.h>
#else
#define _TIMESPEC_DEFINED 1 #define _TIMESPEC_DEFINED 1
struct timespec { struct timespec {
long tv_sec; long tv_sec;
long tv_nsec; long tv_nsec;
}; };
#endif
#endif /* HAVE_STRUCT_TIMESPEC | _TIMESPEC_DEFINED */ #endif /* HAVE_STRUCT_TIMESPEC | _TIMESPEC_DEFINED */
// We *were* getting ETIMEDOUT from pthread.h: // We *were* getting ETIMEDOUT from pthread.h:
@ -60,32 +48,28 @@ struct timespec {
# define ETIMEDOUT 10060 /* This is the value in winsock.h. */ # define ETIMEDOUT 10060 /* This is the value in winsock.h. */
#endif #endif
#define usbi_mutexattr_t void #define usbi_tls_key_t DWORD
#define usbi_condattr_t void
// all Windows mutexes are recursive
#define usbi_mutex_init_recursive(mutex, attr) usbi_mutex_init((mutex), (attr))
int usbi_mutex_static_lock(usbi_mutex_static_t *mutex); int usbi_mutex_static_lock(usbi_mutex_static_t *mutex);
int usbi_mutex_static_unlock(usbi_mutex_static_t *mutex); int usbi_mutex_static_unlock(usbi_mutex_static_t *mutex);
int usbi_mutex_init(usbi_mutex_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_lock(usbi_mutex_t *mutex);
int usbi_mutex_unlock(usbi_mutex_t *mutex); int usbi_mutex_unlock(usbi_mutex_t *mutex);
int usbi_mutex_trylock(usbi_mutex_t *mutex); int usbi_mutex_trylock(usbi_mutex_t *mutex);
int usbi_mutex_destroy(usbi_mutex_t *mutex); int usbi_mutex_destroy(usbi_mutex_t *mutex);
int usbi_cond_init(usbi_cond_t *cond, 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_wait(usbi_cond_t *cond, usbi_mutex_t *mutex);
int usbi_cond_timedwait(usbi_cond_t *cond, int usbi_cond_timedwait(usbi_cond_t *cond,
usbi_mutex_t *mutex, usbi_mutex_t *mutex, const struct timeval *tv);
const struct timespec *abstime);
int usbi_cond_broadcast(usbi_cond_t *cond); int usbi_cond_broadcast(usbi_cond_t *cond);
int usbi_cond_signal(usbi_cond_t *cond); int usbi_cond_destroy(usbi_cond_t *cond);
int usbi_tls_key_create(usbi_tls_key_t *key);
void *usbi_tls_key_get(usbi_tls_key_t key);
int usbi_tls_key_set(usbi_tls_key_t key, void *value);
int usbi_tls_key_delete(usbi_tls_key_t key);
int usbi_get_tid(void); int usbi_get_tid(void);

View File

@ -31,29 +31,29 @@
#include "wince_usb.h" #include "wince_usb.h"
// Global variables // Global variables
uint64_t hires_frequency, hires_ticks_to_ps;
const uint64_t epoch_time = UINT64_C(116444736000000000); // 1970.01.01 00:00:000 in MS Filetime const uint64_t epoch_time = UINT64_C(116444736000000000); // 1970.01.01 00:00:000 in MS Filetime
int windows_version = WINDOWS_CE; int windows_version = WINDOWS_CE;
static uint64_t hires_frequency, hires_ticks_to_ps;
static HANDLE driver_handle = INVALID_HANDLE_VALUE;
static int concurrent_usage = -1; static int concurrent_usage = -1;
HANDLE driver_handle = INVALID_HANDLE_VALUE;
/* /*
* Converts a windows error to human readable string * Converts a windows error to human readable string
* uses retval as errorcode, or, if 0, use GetLastError() * uses retval as errorcode, or, if 0, use GetLastError()
*/ */
#if defined(ENABLE_LOGGING) #if defined(ENABLE_LOGGING)
static char* windows_error_str(uint32_t retval) static const char *windows_error_str(DWORD retval)
{ {
static TCHAR wErr_string[ERR_BUFFER_SIZE]; static TCHAR wErr_string[ERR_BUFFER_SIZE];
static char err_string[ERR_BUFFER_SIZE]; static char err_string[ERR_BUFFER_SIZE];
DWORD error_code, format_error;
DWORD size; DWORD size;
size_t i; size_t i;
uint32_t error_code, format_error;
error_code = retval ? retval : GetLastError(); error_code = retval ? retval : GetLastError();
safe_stprintf(wErr_string, ERR_BUFFER_SIZE, _T("[%d] "), error_code); safe_stprintf(wErr_string, ERR_BUFFER_SIZE, _T("[%u] "), (unsigned int)error_code);
size = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error_code, size = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error_code,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), &wErr_string[safe_tcslen(wErr_string)], MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), &wErr_string[safe_tcslen(wErr_string)],
@ -62,19 +62,19 @@ static char* windows_error_str(uint32_t retval)
format_error = GetLastError(); format_error = GetLastError();
if (format_error) if (format_error)
safe_stprintf(wErr_string, ERR_BUFFER_SIZE, safe_stprintf(wErr_string, ERR_BUFFER_SIZE,
_T("Windows error code %u (FormatMessage error code %u)"), error_code, format_error); _T("Windows error code %u (FormatMessage error code %u)"),
(unsigned int)error_code, (unsigned int)format_error);
else else
safe_stprintf(wErr_string, ERR_BUFFER_SIZE, _T("Unknown error code %u"), error_code); safe_stprintf(wErr_string, ERR_BUFFER_SIZE, _T("Unknown error code %u"), (unsigned int)error_code);
} else { } else {
// Remove CR/LF terminators // Remove CR/LF terminators
for (i=safe_tcslen(wErr_string)-1; ((wErr_string[i]==0x0A) || (wErr_string[i]==0x0D)); i--) { for (i = safe_tcslen(wErr_string) - 1; ((wErr_string[i] == 0x0A) || (wErr_string[i] == 0x0D)); i--)
wErr_string[i] = 0; wErr_string[i] = 0;
} }
}
if (WideCharToMultiByte(CP_ACP, 0, wErr_string, -1, err_string, ERR_BUFFER_SIZE, NULL, NULL) < 0) if (WideCharToMultiByte(CP_ACP, 0, wErr_string, -1, err_string, ERR_BUFFER_SIZE, NULL, NULL) < 0)
{
strcpy(err_string, "Unable to convert error string"); strcpy(err_string, "Unable to convert error string");
}
return err_string; return err_string;
} }
#endif #endif
@ -85,7 +85,7 @@ static struct wince_device_priv *_device_priv(struct libusb_device *dev)
} }
// ceusbkwrapper to libusb error code mapping // ceusbkwrapper to libusb error code mapping
static int translate_driver_error(int error) static int translate_driver_error(DWORD error)
{ {
switch (error) { switch (error) {
case ERROR_INVALID_PARAMETER: case ERROR_INVALID_PARAMETER:
@ -101,7 +101,7 @@ static int translate_driver_error(int error)
return LIBUSB_ERROR_BUSY; return LIBUSB_ERROR_BUSY;
// Error codes that are either unexpected, or have // Error codes that are either unexpected, or have
// no suitable LIBUSB_ERROR equivilant. // no suitable LIBUSB_ERROR equivalent.
case ERROR_CANCELLED: case ERROR_CANCELLED:
case ERROR_INTERNAL_ERROR: case ERROR_INTERNAL_ERROR:
default: default:
@ -109,33 +109,40 @@ static int translate_driver_error(int error)
} }
} }
static int init_dllimports() static int init_dllimports(void)
{ {
DLL_LOAD(ceusbkwrapper.dll, UkwOpenDriver, TRUE); DLL_GET_HANDLE(ceusbkwrapper);
DLL_LOAD(ceusbkwrapper.dll, UkwGetDeviceList, TRUE); DLL_LOAD_FUNC(ceusbkwrapper, UkwOpenDriver, TRUE);
DLL_LOAD(ceusbkwrapper.dll, UkwReleaseDeviceList, TRUE); DLL_LOAD_FUNC(ceusbkwrapper, UkwGetDeviceList, TRUE);
DLL_LOAD(ceusbkwrapper.dll, UkwGetDeviceAddress, TRUE); DLL_LOAD_FUNC(ceusbkwrapper, UkwReleaseDeviceList, TRUE);
DLL_LOAD(ceusbkwrapper.dll, UkwGetDeviceDescriptor, TRUE); DLL_LOAD_FUNC(ceusbkwrapper, UkwGetDeviceAddress, TRUE);
DLL_LOAD(ceusbkwrapper.dll, UkwGetConfigDescriptor, TRUE); DLL_LOAD_FUNC(ceusbkwrapper, UkwGetDeviceDescriptor, TRUE);
DLL_LOAD(ceusbkwrapper.dll, UkwCloseDriver, TRUE); DLL_LOAD_FUNC(ceusbkwrapper, UkwGetConfigDescriptor, TRUE);
DLL_LOAD(ceusbkwrapper.dll, UkwCancelTransfer, TRUE); DLL_LOAD_FUNC(ceusbkwrapper, UkwCloseDriver, TRUE);
DLL_LOAD(ceusbkwrapper.dll, UkwIssueControlTransfer, TRUE); DLL_LOAD_FUNC(ceusbkwrapper, UkwCancelTransfer, TRUE);
DLL_LOAD(ceusbkwrapper.dll, UkwClaimInterface, TRUE); DLL_LOAD_FUNC(ceusbkwrapper, UkwIssueControlTransfer, TRUE);
DLL_LOAD(ceusbkwrapper.dll, UkwReleaseInterface, TRUE); DLL_LOAD_FUNC(ceusbkwrapper, UkwClaimInterface, TRUE);
DLL_LOAD(ceusbkwrapper.dll, UkwSetInterfaceAlternateSetting, TRUE); DLL_LOAD_FUNC(ceusbkwrapper, UkwReleaseInterface, TRUE);
DLL_LOAD(ceusbkwrapper.dll, UkwClearHaltHost, TRUE); DLL_LOAD_FUNC(ceusbkwrapper, UkwSetInterfaceAlternateSetting, TRUE);
DLL_LOAD(ceusbkwrapper.dll, UkwClearHaltDevice, TRUE); DLL_LOAD_FUNC(ceusbkwrapper, UkwClearHaltHost, TRUE);
DLL_LOAD(ceusbkwrapper.dll, UkwGetConfig, TRUE); DLL_LOAD_FUNC(ceusbkwrapper, UkwClearHaltDevice, TRUE);
DLL_LOAD(ceusbkwrapper.dll, UkwSetConfig, TRUE); DLL_LOAD_FUNC(ceusbkwrapper, UkwGetConfig, TRUE);
DLL_LOAD(ceusbkwrapper.dll, UkwResetDevice, TRUE); DLL_LOAD_FUNC(ceusbkwrapper, UkwSetConfig, TRUE);
DLL_LOAD(ceusbkwrapper.dll, UkwKernelDriverActive, TRUE); DLL_LOAD_FUNC(ceusbkwrapper, UkwResetDevice, TRUE);
DLL_LOAD(ceusbkwrapper.dll, UkwAttachKernelDriver, TRUE); DLL_LOAD_FUNC(ceusbkwrapper, UkwKernelDriverActive, TRUE);
DLL_LOAD(ceusbkwrapper.dll, UkwDetachKernelDriver, TRUE); DLL_LOAD_FUNC(ceusbkwrapper, UkwAttachKernelDriver, TRUE);
DLL_LOAD(ceusbkwrapper.dll, UkwIssueBulkTransfer, TRUE); DLL_LOAD_FUNC(ceusbkwrapper, UkwDetachKernelDriver, TRUE);
DLL_LOAD(ceusbkwrapper.dll, UkwIsPipeHalted, TRUE); DLL_LOAD_FUNC(ceusbkwrapper, UkwIssueBulkTransfer, TRUE);
DLL_LOAD_FUNC(ceusbkwrapper, UkwIsPipeHalted, TRUE);
return LIBUSB_SUCCESS; return LIBUSB_SUCCESS;
} }
static void exit_dllimports(void)
{
DLL_FREE_HANDLE(ceusbkwrapper);
}
static int init_device( static int init_device(
struct libusb_device *dev, UKW_DEVICE drv_dev, struct libusb_device *dev, UKW_DEVICE drv_dev,
unsigned char bus_addr, unsigned char dev_addr) unsigned char bus_addr, unsigned char dev_addr)
@ -147,9 +154,9 @@ static int init_device(
dev->device_address = dev_addr; dev->device_address = dev_addr;
priv->dev = drv_dev; priv->dev = drv_dev;
if (!UkwGetDeviceDescriptor(priv->dev, &(priv->desc))) { if (!UkwGetDeviceDescriptor(priv->dev, &(priv->desc)))
r = translate_driver_error(GetLastError()); r = translate_driver_error(GetLastError());
}
return r; return r;
} }
@ -159,9 +166,9 @@ static int wince_init(struct libusb_context *ctx)
int r = LIBUSB_ERROR_OTHER; int r = LIBUSB_ERROR_OTHER;
HANDLE semaphore; HANDLE semaphore;
LARGE_INTEGER li_frequency; LARGE_INTEGER li_frequency;
TCHAR sem_name[11+1+8]; // strlen(libusb_init)+'\0'+(32-bit hex PID) TCHAR sem_name[11 + 8 + 1]; // strlen("libusb_init") + (32-bit hex PID) + '\0'
_stprintf(sem_name, _T("libusb_init%08X"), (unsigned int)GetCurrentProcessId()&0xFFFFFFFF); _stprintf(sem_name, _T("libusb_init%08X"), (unsigned int)(GetCurrentProcessId() & 0xFFFFFFFF));
semaphore = CreateSemaphore(NULL, 1, 1, sem_name); semaphore = CreateSemaphore(NULL, 1, 1, sem_name);
if (semaphore == NULL) { if (semaphore == NULL) {
usbi_err(ctx, "could not create semaphore: %s", windows_error_str(0)); usbi_err(ctx, "could not create semaphore: %s", windows_error_str(0));
@ -215,6 +222,9 @@ static int wince_init(struct libusb_context *ctx)
init_exit: // Holds semaphore here. init_exit: // Holds semaphore here.
if (!concurrent_usage && r != LIBUSB_SUCCESS) { // First init failed? if (!concurrent_usage && r != LIBUSB_SUCCESS) { // First init failed?
exit_dllimports();
exit_polling();
if (driver_handle != INVALID_HANDLE_VALUE) { if (driver_handle != INVALID_HANDLE_VALUE) {
UkwCloseDriver(driver_handle); UkwCloseDriver(driver_handle);
driver_handle = INVALID_HANDLE_VALUE; driver_handle = INVALID_HANDLE_VALUE;
@ -232,13 +242,12 @@ init_exit: // Holds semaphore here.
static void wince_exit(void) static void wince_exit(void)
{ {
HANDLE semaphore; HANDLE semaphore;
TCHAR sem_name[11+1+8]; // strlen(libusb_init)+'\0'+(32-bit hex PID) TCHAR sem_name[11 + 8 + 1]; // strlen("libusb_init") + (32-bit hex PID) + '\0'
_stprintf(sem_name, _T("libusb_init%08X"), (unsigned int)GetCurrentProcessId()&0xFFFFFFFF); _stprintf(sem_name, _T("libusb_init%08X"), (unsigned int)(GetCurrentProcessId() & 0xFFFFFFFF));
semaphore = CreateSemaphore(NULL, 1, 1, sem_name); semaphore = CreateSemaphore(NULL, 1, 1, sem_name);
if (semaphore == NULL) { if (semaphore == NULL)
return; return;
}
// A successful wait brings our semaphore count to 0 (unsignaled) // A successful wait brings our semaphore count to 0 (unsignaled)
// => any concurent wait stalls until the semaphore release // => any concurent wait stalls until the semaphore release
@ -249,6 +258,7 @@ static void wince_exit(void)
// Only works if exits and inits are balanced exactly // Only works if exits and inits are balanced exactly
if (--concurrent_usage < 0) { // Last exit if (--concurrent_usage < 0) { // Last exit
exit_dllimports();
exit_polling(); exit_polling();
if (driver_handle != INVALID_HANDLE_VALUE) { if (driver_handle != INVALID_HANDLE_VALUE) {
@ -281,44 +291,51 @@ static int wince_get_device_list(
usbi_err(ctx, "could not get devices: %s", windows_error_str(0)); usbi_err(ctx, "could not get devices: %s", windows_error_str(0));
return libusbErr; return libusbErr;
} }
for (i = 0; i < count; ++i) { for (i = 0; i < count; ++i) {
release_list_offset = i; release_list_offset = i;
success = UkwGetDeviceAddress(devices[i], &bus_addr, &dev_addr, &session_id); success = UkwGetDeviceAddress(devices[i], &bus_addr, &dev_addr, &session_id);
if (!success) { if (!success) {
r = translate_driver_error(GetLastError()); r = translate_driver_error(GetLastError());
usbi_err(ctx, "could not get device address for %d: %s", i, windows_error_str(0)); usbi_err(ctx, "could not get device address for %u: %s", (unsigned int)i, windows_error_str(0));
goto err_out; goto err_out;
} }
dev = usbi_get_device_by_session_id(ctx, session_id); dev = usbi_get_device_by_session_id(ctx, session_id);
if (dev) { if (dev) {
usbi_dbg("using existing device for %d/%d (session %ld)", usbi_dbg("using existing device for %u/%u (session %lu)",
bus_addr, dev_addr, session_id); bus_addr, dev_addr, session_id);
// Release just this element in the device list (as we already hold a // Release just this element in the device list (as we already hold a
// reference to it). // reference to it).
UkwReleaseDeviceList(driver_handle, &devices[i], 1); UkwReleaseDeviceList(driver_handle, &devices[i], 1);
release_list_offset++; release_list_offset++;
} else { } else {
usbi_dbg("allocating new device for %d/%d (session %ld)", usbi_dbg("allocating new device for %u/%u (session %lu)",
bus_addr, dev_addr, session_id); bus_addr, dev_addr, session_id);
dev = usbi_alloc_device(ctx, session_id); dev = usbi_alloc_device(ctx, session_id);
if (!dev) { if (!dev) {
r = LIBUSB_ERROR_NO_MEM; r = LIBUSB_ERROR_NO_MEM;
goto err_out; goto err_out;
} }
r = init_device(dev, devices[i], bus_addr, dev_addr); r = init_device(dev, devices[i], bus_addr, dev_addr);
if (r < 0) if (r < 0)
goto err_out; goto err_out;
r = usbi_sanitize_device(dev); r = usbi_sanitize_device(dev);
if (r < 0) if (r < 0)
goto err_out; goto err_out;
} }
new_devices = discovered_devs_append(new_devices, dev); new_devices = discovered_devs_append(new_devices, dev);
if (!discdevs) { if (!discdevs) {
r = LIBUSB_ERROR_NO_MEM; r = LIBUSB_ERROR_NO_MEM;
goto err_out; goto err_out;
} }
safe_unref_device(dev); safe_unref_device(dev);
} }
*discdevs = new_devices; *discdevs = new_devices;
return r; return r;
err_out: err_out:
@ -360,10 +377,11 @@ static int wince_get_active_config_descriptor(
{ {
struct wince_device_priv *priv = _device_priv(device); struct wince_device_priv *priv = _device_priv(device);
DWORD actualSize = len; DWORD actualSize = len;
*host_endian = 0; *host_endian = 0;
if (!UkwGetConfigDescriptor(priv->dev, UKW_ACTIVE_CONFIGURATION, buffer, len, &actualSize)) { if (!UkwGetConfigDescriptor(priv->dev, UKW_ACTIVE_CONFIGURATION, buffer, len, &actualSize))
return translate_driver_error(GetLastError()); return translate_driver_error(GetLastError());
}
return actualSize; return actualSize;
} }
@ -374,10 +392,11 @@ static int wince_get_config_descriptor(
{ {
struct wince_device_priv *priv = _device_priv(device); struct wince_device_priv *priv = _device_priv(device);
DWORD actualSize = len; DWORD actualSize = len;
*host_endian = 0; *host_endian = 0;
if (!UkwGetConfigDescriptor(priv->dev, config_index, buffer, len, &actualSize)) { if (!UkwGetConfigDescriptor(priv->dev, config_index, buffer, len, &actualSize))
return translate_driver_error(GetLastError()); return translate_driver_error(GetLastError());
}
return actualSize; return actualSize;
} }
@ -387,9 +406,10 @@ static int wince_get_configuration(
{ {
struct wince_device_priv *priv = _device_priv(handle->dev); struct wince_device_priv *priv = _device_priv(handle->dev);
UCHAR cv = 0; UCHAR cv = 0;
if (!UkwGetConfig(priv->dev, &cv)) {
if (!UkwGetConfig(priv->dev, &cv))
return translate_driver_error(GetLastError()); return translate_driver_error(GetLastError());
}
(*config) = cv; (*config) = cv;
return LIBUSB_SUCCESS; return LIBUSB_SUCCESS;
} }
@ -403,9 +423,9 @@ static int wince_set_configuration(
// This should correspond to the "unconfigured state" required by // This should correspond to the "unconfigured state" required by
// libusb when the specified configuration is -1. // libusb when the specified configuration is -1.
UCHAR cv = (config < 0) ? 0 : config; UCHAR cv = (config < 0) ? 0 : config;
if (!UkwSetConfig(priv->dev, cv)) { if (!UkwSetConfig(priv->dev, cv))
return translate_driver_error(GetLastError()); return translate_driver_error(GetLastError());
}
return LIBUSB_SUCCESS; return LIBUSB_SUCCESS;
} }
@ -414,9 +434,10 @@ static int wince_claim_interface(
int interface_number) int interface_number)
{ {
struct wince_device_priv *priv = _device_priv(handle->dev); struct wince_device_priv *priv = _device_priv(handle->dev);
if (!UkwClaimInterface(priv->dev, interface_number)) {
if (!UkwClaimInterface(priv->dev, interface_number))
return translate_driver_error(GetLastError()); return translate_driver_error(GetLastError());
}
return LIBUSB_SUCCESS; return LIBUSB_SUCCESS;
} }
@ -425,12 +446,13 @@ static int wince_release_interface(
int interface_number) int interface_number)
{ {
struct wince_device_priv *priv = _device_priv(handle->dev); struct wince_device_priv *priv = _device_priv(handle->dev);
if (!UkwSetInterfaceAlternateSetting(priv->dev, interface_number, 0)) {
if (!UkwSetInterfaceAlternateSetting(priv->dev, interface_number, 0))
return translate_driver_error(GetLastError()); return translate_driver_error(GetLastError());
}
if (!UkwReleaseInterface(priv->dev, interface_number)) { if (!UkwReleaseInterface(priv->dev, interface_number))
return translate_driver_error(GetLastError()); return translate_driver_error(GetLastError());
}
return LIBUSB_SUCCESS; return LIBUSB_SUCCESS;
} }
@ -439,9 +461,10 @@ static int wince_set_interface_altsetting(
int interface_number, int altsetting) int interface_number, int altsetting)
{ {
struct wince_device_priv *priv = _device_priv(handle->dev); struct wince_device_priv *priv = _device_priv(handle->dev);
if (!UkwSetInterfaceAlternateSetting(priv->dev, interface_number, altsetting)) {
if (!UkwSetInterfaceAlternateSetting(priv->dev, interface_number, altsetting))
return translate_driver_error(GetLastError()); return translate_driver_error(GetLastError());
}
return LIBUSB_SUCCESS; return LIBUSB_SUCCESS;
} }
@ -450,12 +473,13 @@ static int wince_clear_halt(
unsigned char endpoint) unsigned char endpoint)
{ {
struct wince_device_priv *priv = _device_priv(handle->dev); struct wince_device_priv *priv = _device_priv(handle->dev);
if (!UkwClearHaltHost(priv->dev, endpoint)) {
if (!UkwClearHaltHost(priv->dev, endpoint))
return translate_driver_error(GetLastError()); return translate_driver_error(GetLastError());
}
if (!UkwClearHaltDevice(priv->dev, endpoint)) { if (!UkwClearHaltDevice(priv->dev, endpoint))
return translate_driver_error(GetLastError()); return translate_driver_error(GetLastError());
}
return LIBUSB_SUCCESS; return LIBUSB_SUCCESS;
} }
@ -463,9 +487,10 @@ static int wince_reset_device(
struct libusb_device_handle *handle) struct libusb_device_handle *handle)
{ {
struct wince_device_priv *priv = _device_priv(handle->dev); struct wince_device_priv *priv = _device_priv(handle->dev);
if (!UkwResetDevice(priv->dev)) {
if (!UkwResetDevice(priv->dev))
return translate_driver_error(GetLastError()); return translate_driver_error(GetLastError());
}
return LIBUSB_SUCCESS; return LIBUSB_SUCCESS;
} }
@ -475,9 +500,10 @@ static int wince_kernel_driver_active(
{ {
struct wince_device_priv *priv = _device_priv(handle->dev); struct wince_device_priv *priv = _device_priv(handle->dev);
BOOL result = FALSE; BOOL result = FALSE;
if (!UkwKernelDriverActive(priv->dev, interface_number, &result)) {
if (!UkwKernelDriverActive(priv->dev, interface_number, &result))
return translate_driver_error(GetLastError()); return translate_driver_error(GetLastError());
}
return result ? 1 : 0; return result ? 1 : 0;
} }
@ -486,9 +512,10 @@ static int wince_detach_kernel_driver(
int interface_number) int interface_number)
{ {
struct wince_device_priv *priv = _device_priv(handle->dev); struct wince_device_priv *priv = _device_priv(handle->dev);
if (!UkwDetachKernelDriver(priv->dev, interface_number)) {
if (!UkwDetachKernelDriver(priv->dev, interface_number))
return translate_driver_error(GetLastError()); return translate_driver_error(GetLastError());
}
return LIBUSB_SUCCESS; return LIBUSB_SUCCESS;
} }
@ -497,22 +524,25 @@ static int wince_attach_kernel_driver(
int interface_number) int interface_number)
{ {
struct wince_device_priv *priv = _device_priv(handle->dev); struct wince_device_priv *priv = _device_priv(handle->dev);
if (!UkwAttachKernelDriver(priv->dev, interface_number)) {
if (!UkwAttachKernelDriver(priv->dev, interface_number))
return translate_driver_error(GetLastError()); return translate_driver_error(GetLastError());
}
return LIBUSB_SUCCESS; return LIBUSB_SUCCESS;
} }
static void wince_destroy_device(struct libusb_device *dev) static void wince_destroy_device(struct libusb_device *dev)
{ {
struct wince_device_priv *priv = _device_priv(dev); struct wince_device_priv *priv = _device_priv(dev);
UkwReleaseDeviceList(driver_handle, &priv->dev, 1); UkwReleaseDeviceList(driver_handle, &priv->dev, 1);
} }
static void wince_clear_transfer_priv(struct usbi_transfer *itransfer) static void wince_clear_transfer_priv(struct usbi_transfer *itransfer)
{ {
struct wince_transfer_priv *transfer_priv = (struct wince_transfer_priv*)usbi_transfer_get_os_priv(itransfer); struct wince_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
struct winfd wfd = fd_to_winfd(transfer_priv->pollable_fd.fd); struct winfd wfd = fd_to_winfd(transfer_priv->pollable_fd.fd);
// No need to cancel transfer as it is either complete or abandoned // No need to cancel transfer as it is either complete or abandoned
wfd.itransfer = NULL; wfd.itransfer = NULL;
CloseHandle(wfd.handle); CloseHandle(wfd.handle);
@ -523,11 +553,11 @@ static int wince_cancel_transfer(struct usbi_transfer *itransfer)
{ {
struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
struct wince_device_priv *priv = _device_priv(transfer->dev_handle->dev); struct wince_device_priv *priv = _device_priv(transfer->dev_handle->dev);
struct wince_transfer_priv *transfer_priv = (struct wince_transfer_priv*)usbi_transfer_get_os_priv(itransfer); struct wince_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
if (!UkwCancelTransfer(priv->dev, transfer_priv->pollable_fd.overlapped, UKW_TF_NO_WAIT)) { if (!UkwCancelTransfer(priv->dev, transfer_priv->pollable_fd.overlapped, UKW_TF_NO_WAIT))
return translate_driver_error(GetLastError()); return translate_driver_error(GetLastError());
}
return LIBUSB_SUCCESS; return LIBUSB_SUCCESS;
} }
@ -535,7 +565,7 @@ static int wince_submit_control_or_bulk_transfer(struct usbi_transfer *itransfer
{ {
struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev); struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
struct wince_transfer_priv *transfer_priv = (struct wince_transfer_priv*)usbi_transfer_get_os_priv(itransfer); struct wince_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
struct wince_device_priv *priv = _device_priv(transfer->dev_handle->dev); struct wince_device_priv *priv = _device_priv(transfer->dev_handle->dev);
BOOL direction_in, ret; BOOL direction_in, ret;
struct winfd wfd; struct winfd wfd;
@ -577,10 +607,11 @@ static int wince_submit_control_or_bulk_transfer(struct usbi_transfer *itransfer
ret = UkwIssueBulkTransfer(priv->dev, flags, transfer->endpoint, transfer->buffer, ret = UkwIssueBulkTransfer(priv->dev, flags, transfer->endpoint, transfer->buffer,
transfer->length, &transfer->actual_length, wfd.overlapped); transfer->length, &transfer->actual_length, wfd.overlapped);
} }
if (!ret) { if (!ret) {
int libusbErr = translate_driver_error(GetLastError()); int libusbErr = translate_driver_error(GetLastError());
usbi_err(ctx, "UkwIssue%sTransfer failed: error %d", usbi_err(ctx, "UkwIssue%sTransfer failed: error %u",
control_transfer ? "Control" : "Bulk", GetLastError()); control_transfer ? "Control" : "Bulk", (unsigned int)GetLastError());
wince_clear_transfer_priv(itransfer); wince_clear_transfer_priv(itransfer);
return libusbErr; return libusbErr;
} }
@ -622,7 +653,7 @@ static void wince_transfer_callback(
struct wince_device_priv *priv = _device_priv(transfer->dev_handle->dev); struct wince_device_priv *priv = _device_priv(transfer->dev_handle->dev);
int status; int status;
usbi_dbg("handling I/O completion with errcode %d", io_result); usbi_dbg("handling I/O completion with errcode %u", io_result);
if (io_result == ERROR_NOT_SUPPORTED && if (io_result == ERROR_NOT_SUPPORTED &&
transfer->type != LIBUSB_TRANSFER_TYPE_CONTROL) { transfer->type != LIBUSB_TRANSFER_TYPE_CONTROL) {
@ -689,26 +720,21 @@ static void wince_transfer_callback(
status = LIBUSB_TRANSFER_TIMED_OUT; status = LIBUSB_TRANSFER_TIMED_OUT;
break; break;
case ERROR_OPERATION_ABORTED: 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"); usbi_dbg("detected operation aborted");
status = LIBUSB_TRANSFER_CANCELLED; status = LIBUSB_TRANSFER_CANCELLED;
}
break; break;
default: default:
usbi_err(ITRANSFER_CTX(itransfer), "detected I/O error: %s", windows_error_str(io_result)); usbi_err(ITRANSFER_CTX(itransfer), "detected I/O error: %s", windows_error_str(io_result));
status = LIBUSB_TRANSFER_ERROR; status = LIBUSB_TRANSFER_ERROR;
break; break;
} }
wince_clear_transfer_priv(itransfer); wince_clear_transfer_priv(itransfer);
if (status == LIBUSB_TRANSFER_CANCELLED) { if (status == LIBUSB_TRANSFER_CANCELLED)
usbi_handle_transfer_cancellation(itransfer); usbi_handle_transfer_cancellation(itransfer);
} else { else
usbi_handle_transfer_completion(itransfer, (enum libusb_transfer_status)status); usbi_handle_transfer_completion(itransfer, (enum libusb_transfer_status)status);
} }
}
static void wince_handle_callback( static void wince_handle_callback(
struct usbi_transfer *itransfer, struct usbi_transfer *itransfer,
@ -739,15 +765,15 @@ static int wince_handle_events(
BOOL found = FALSE; BOOL found = FALSE;
struct usbi_transfer *transfer; struct usbi_transfer *transfer;
DWORD io_size, io_result; DWORD io_size, io_result;
int r = LIBUSB_SUCCESS;
usbi_mutex_lock(&ctx->open_devs_lock); usbi_mutex_lock(&ctx->open_devs_lock);
for (i = 0; i < nfds && num_ready > 0; i++) { for (i = 0; i < nfds && num_ready > 0; i++) {
usbi_dbg("checking fd %d with revents = %04x", fds[i].fd, fds[i].revents); usbi_dbg("checking fd %d with revents = %04x", fds[i].fd, fds[i].revents);
if (!fds[i].revents) { if (!fds[i].revents)
continue; continue;
}
num_ready--; num_ready--;
@ -772,18 +798,18 @@ static int wince_handle_events(
// newly allocated wfd that took the place of the one from the transfer. // newly allocated wfd that took the place of the one from the transfer.
wince_handle_callback(transfer, io_result, io_size); wince_handle_callback(transfer, io_result, io_size);
} else if (found) { } else if (found) {
usbi_err(ctx, "matching transfer for fd %x has not completed", fds[i]); usbi_err(ctx, "matching transfer for fd %d has not completed", fds[i]);
usbi_mutex_unlock(&ctx->open_devs_lock); r = LIBUSB_ERROR_OTHER;
return LIBUSB_ERROR_OTHER; break;
} else { } else {
usbi_err(ctx, "could not find a matching transfer for fd %x", fds[i]); usbi_err(ctx, "could not find a matching transfer for fd %d", fds[i]);
r = LIBUSB_ERROR_NOT_FOUND;
break;
}
}
usbi_mutex_unlock(&ctx->open_devs_lock); usbi_mutex_unlock(&ctx->open_devs_lock);
return LIBUSB_ERROR_NOT_FOUND;
}
}
usbi_mutex_unlock(&ctx->open_devs_lock); return r;
return LIBUSB_SUCCESS;
} }
/* /*
@ -795,6 +821,7 @@ static int wince_clock_gettime(int clk_id, struct timespec *tp)
ULARGE_INTEGER rtime; ULARGE_INTEGER rtime;
FILETIME filetime; FILETIME filetime;
SYSTEMTIME st; SYSTEMTIME st;
switch(clk_id) { switch(clk_id) {
case USBI_CLOCK_MONOTONIC: case USBI_CLOCK_MONOTONIC:
if (hires_frequency != 0 && QueryPerformanceCounter(&hires_counter)) { if (hires_frequency != 0 && QueryPerformanceCounter(&hires_counter)) {
@ -849,6 +876,9 @@ const struct usbi_os_backend wince_backend = {
NULL, /* alloc_streams */ NULL, /* alloc_streams */
NULL, /* free_streams */ NULL, /* free_streams */
NULL, /* dev_mem_alloc() */
NULL, /* dev_mem_free() */
wince_kernel_driver_active, wince_kernel_driver_active,
wince_detach_kernel_driver, wince_detach_kernel_driver,
wince_attach_kernel_driver, wince_attach_kernel_driver,
@ -864,6 +894,6 @@ const struct usbi_os_backend wince_backend = {
wince_clock_gettime, wince_clock_gettime,
sizeof(struct wince_device_priv), sizeof(struct wince_device_priv),
sizeof(struct wince_device_handle_priv), 0,
sizeof(struct wince_transfer_priv), sizeof(struct wince_transfer_priv),
}; };

View File

@ -87,28 +87,29 @@ typedef struct {
* to specify the currently active configuration for the device. */ * to specify the currently active configuration for the device. */
#define UKW_ACTIVE_CONFIGURATION -1 #define UKW_ACTIVE_CONFIGURATION -1
DLL_DECLARE(WINAPI, HANDLE, UkwOpenDriver, ()); DLL_DECLARE_HANDLE(ceusbkwrapper);
DLL_DECLARE(WINAPI, BOOL, UkwGetDeviceList, (HANDLE, LPUKW_DEVICE, DWORD, LPDWORD)); DLL_DECLARE_FUNC(WINAPI, HANDLE, UkwOpenDriver, ());
DLL_DECLARE(WINAPI, void, UkwReleaseDeviceList, (HANDLE, LPUKW_DEVICE, DWORD)); DLL_DECLARE_FUNC(WINAPI, BOOL, UkwGetDeviceList, (HANDLE, LPUKW_DEVICE, DWORD, LPDWORD));
DLL_DECLARE(WINAPI, BOOL, UkwGetDeviceAddress, (UKW_DEVICE, unsigned char*, unsigned char*, unsigned long*)); DLL_DECLARE_FUNC(WINAPI, void, UkwReleaseDeviceList, (HANDLE, LPUKW_DEVICE, DWORD));
DLL_DECLARE(WINAPI, BOOL, UkwGetDeviceDescriptor, (UKW_DEVICE, LPUKW_DEVICE_DESCRIPTOR)); DLL_DECLARE_FUNC(WINAPI, BOOL, UkwGetDeviceAddress, (UKW_DEVICE, unsigned char*, unsigned char*, unsigned long*));
DLL_DECLARE(WINAPI, BOOL, UkwGetConfigDescriptor, (UKW_DEVICE, DWORD, LPVOID, DWORD, LPDWORD)); DLL_DECLARE_FUNC(WINAPI, BOOL, UkwGetDeviceDescriptor, (UKW_DEVICE, LPUKW_DEVICE_DESCRIPTOR));
DLL_DECLARE(WINAPI, void, UkwCloseDriver, (HANDLE)); DLL_DECLARE_FUNC(WINAPI, BOOL, UkwGetConfigDescriptor, (UKW_DEVICE, DWORD, LPVOID, DWORD, LPDWORD));
DLL_DECLARE(WINAPI, BOOL, UkwCancelTransfer, (UKW_DEVICE, LPOVERLAPPED, DWORD)); DLL_DECLARE_FUNC(WINAPI, void, UkwCloseDriver, (HANDLE));
DLL_DECLARE(WINAPI, BOOL, UkwIssueControlTransfer, (UKW_DEVICE, DWORD, LPUKW_CONTROL_HEADER, LPVOID, DWORD, LPDWORD, LPOVERLAPPED)); DLL_DECLARE_FUNC(WINAPI, BOOL, UkwCancelTransfer, (UKW_DEVICE, LPOVERLAPPED, DWORD));
DLL_DECLARE(WINAPI, BOOL, UkwClaimInterface, (UKW_DEVICE, DWORD)); DLL_DECLARE_FUNC(WINAPI, BOOL, UkwIssueControlTransfer, (UKW_DEVICE, DWORD, LPUKW_CONTROL_HEADER, LPVOID, DWORD, LPDWORD, LPOVERLAPPED));
DLL_DECLARE(WINAPI, BOOL, UkwReleaseInterface, (UKW_DEVICE, DWORD)); DLL_DECLARE_FUNC(WINAPI, BOOL, UkwClaimInterface, (UKW_DEVICE, DWORD));
DLL_DECLARE(WINAPI, BOOL, UkwSetInterfaceAlternateSetting, (UKW_DEVICE, DWORD, DWORD)); DLL_DECLARE_FUNC(WINAPI, BOOL, UkwReleaseInterface, (UKW_DEVICE, DWORD));
DLL_DECLARE(WINAPI, BOOL, UkwClearHaltHost, (UKW_DEVICE, UCHAR)); DLL_DECLARE_FUNC(WINAPI, BOOL, UkwSetInterfaceAlternateSetting, (UKW_DEVICE, DWORD, DWORD));
DLL_DECLARE(WINAPI, BOOL, UkwClearHaltDevice, (UKW_DEVICE, UCHAR)); DLL_DECLARE_FUNC(WINAPI, BOOL, UkwClearHaltHost, (UKW_DEVICE, UCHAR));
DLL_DECLARE(WINAPI, BOOL, UkwGetConfig, (UKW_DEVICE, PUCHAR)); DLL_DECLARE_FUNC(WINAPI, BOOL, UkwClearHaltDevice, (UKW_DEVICE, UCHAR));
DLL_DECLARE(WINAPI, BOOL, UkwSetConfig, (UKW_DEVICE, UCHAR)); DLL_DECLARE_FUNC(WINAPI, BOOL, UkwGetConfig, (UKW_DEVICE, PUCHAR));
DLL_DECLARE(WINAPI, BOOL, UkwResetDevice, (UKW_DEVICE)); DLL_DECLARE_FUNC(WINAPI, BOOL, UkwSetConfig, (UKW_DEVICE, UCHAR));
DLL_DECLARE(WINAPI, BOOL, UkwKernelDriverActive, (UKW_DEVICE, DWORD, PBOOL)); DLL_DECLARE_FUNC(WINAPI, BOOL, UkwResetDevice, (UKW_DEVICE));
DLL_DECLARE(WINAPI, BOOL, UkwAttachKernelDriver, (UKW_DEVICE, DWORD)); DLL_DECLARE_FUNC(WINAPI, BOOL, UkwKernelDriverActive, (UKW_DEVICE, DWORD, PBOOL));
DLL_DECLARE(WINAPI, BOOL, UkwDetachKernelDriver, (UKW_DEVICE, DWORD)); DLL_DECLARE_FUNC(WINAPI, BOOL, UkwAttachKernelDriver, (UKW_DEVICE, DWORD));
DLL_DECLARE(WINAPI, BOOL, UkwIssueBulkTransfer, (UKW_DEVICE, DWORD, UCHAR, LPVOID, DWORD, LPDWORD, LPOVERLAPPED)); DLL_DECLARE_FUNC(WINAPI, BOOL, UkwDetachKernelDriver, (UKW_DEVICE, DWORD));
DLL_DECLARE(WINAPI, BOOL, UkwIsPipeHalted, (UKW_DEVICE, UCHAR, LPBOOL)); DLL_DECLARE_FUNC(WINAPI, BOOL, UkwIssueBulkTransfer, (UKW_DEVICE, DWORD, UCHAR, LPVOID, DWORD, LPDWORD, LPOVERLAPPED));
DLL_DECLARE_FUNC(WINAPI, BOOL, UkwIsPipeHalted, (UKW_DEVICE, UCHAR, LPBOOL));
// Used to determine if an endpoint status really is halted on a failed transfer. // Used to determine if an endpoint status really is halted on a failed transfer.
#define STATUS_HALT_FLAG 0x1 #define STATUS_HALT_FLAG 0x1
@ -118,12 +119,6 @@ struct wince_device_priv {
UKW_DEVICE_DESCRIPTOR desc; UKW_DEVICE_DESCRIPTOR desc;
}; };
struct wince_device_handle_priv {
// This member isn't used, but only exists to avoid an empty structure
// for private data for the device handle.
int reserved;
};
struct wince_transfer_priv { struct wince_transfer_priv {
struct winfd pollable_fd; struct winfd pollable_fd;
uint8_t interface_number; uint8_t interface_number;

View File

@ -37,6 +37,14 @@
#define false FALSE #define false FALSE
#endif #endif
#if defined(__CYGWIN__ )
#define _stricmp strcasecmp
#define _snprintf snprintf
#define _strdup strdup
// _beginthreadex is MSVCRT => unavailable for cygwin. Fallback to using CreateThread
#define _beginthreadex(a, b, c, d, e, f) CreateThread(a, b, (LPTHREAD_START_ROUTINE)c, d, e, (LPDWORD)f)
#endif
#define safe_free(p) do {if (p != NULL) {free((void*)p); p = NULL;}} while(0) #define safe_free(p) do {if (p != NULL) {free((void*)p); p = NULL;}} while(0)
#define safe_closehandle(h) do {if (h != INVALID_HANDLE_VALUE) {CloseHandle(h); h = INVALID_HANDLE_VALUE;}} while(0) #define safe_closehandle(h) do {if (h != INVALID_HANDLE_VALUE) {CloseHandle(h); h = INVALID_HANDLE_VALUE;}} while(0)
#define safe_min(a, b) MIN((size_t)(a), (size_t)(b)) #define safe_min(a, b) MIN((size_t)(a), (size_t)(b))
@ -59,50 +67,73 @@
#endif #endif
#define ERR_BUFFER_SIZE 256 #define ERR_BUFFER_SIZE 256
#define TIMER_REQUEST_RETRY_MS 100
#define MAX_TIMER_SEMAPHORES 128
/* /*
* API macros - from libusb-win32 1.x * API macros - leveraged from libusb-win32 1.x
*/ */
#define DLL_DECLARE_PREFIXNAME(api, ret, prefixname, name, args) \
typedef ret (api * __dll_##name##_t)args; \
static __dll_##name##_t prefixname = NULL
#ifndef _WIN32_WCE #ifndef _WIN32_WCE
#define DLL_STRINGIFY(dll) #dll #define DLL_STRINGIFY(s) #s
#define DLL_GET_MODULE_HANDLE(dll) GetModuleHandleA(DLL_STRINGIFY(dll)) #define DLL_LOAD_LIBRARY(name) LoadLibraryA(DLL_STRINGIFY(name))
#define DLL_LOAD_LIBRARY(dll) LoadLibraryA(DLL_STRINGIFY(dll))
#else #else
#define DLL_STRINGIFY(dll) L#dll #define DLL_STRINGIFY(s) L#s
#define DLL_GET_MODULE_HANDLE(dll) GetModuleHandle(DLL_STRINGIFY(dll)) #define DLL_LOAD_LIBRARY(name) LoadLibrary(DLL_STRINGIFY(name))
#define DLL_LOAD_LIBRARY(dll) LoadLibrary(DLL_STRINGIFY(dll))
#endif #endif
#define DLL_LOAD_PREFIXNAME(dll, prefixname, name, ret_on_failure) \ /*
* Macros for handling DLL themselves
*/
#define DLL_DECLARE_HANDLE(name) \
static HMODULE __dll_##name##_handle = NULL
#define DLL_GET_HANDLE(name) \
do { \ do { \
HMODULE h = DLL_GET_MODULE_HANDLE(dll); \ __dll_##name##_handle = DLL_LOAD_LIBRARY(name); \
if (!h) \ if (!__dll_##name##_handle) \
h = DLL_LOAD_LIBRARY(dll); \ return LIBUSB_ERROR_OTHER; \
if (!h) { \ } while (0)
if (ret_on_failure) { return LIBUSB_ERROR_NOT_FOUND; } \
else { break; } \ #define DLL_FREE_HANDLE(name) \
do { \
if (__dll_##name##_handle) { \
FreeLibrary(__dll_##name##_handle); \
__dll_##name##_handle = NULL; \
} \ } \
prefixname = (__dll_##name##_t)GetProcAddress(h, \ } while(0)
/*
* Macros for handling functions within a DLL
*/
#define DLL_DECLARE_FUNC_PREFIXNAME(api, ret, prefixname, name, args) \
typedef ret (api * __dll_##name##_func_t)args; \
static __dll_##name##_func_t prefixname = NULL
#define DLL_DECLARE_FUNC(api, ret, name, args) \
DLL_DECLARE_FUNC_PREFIXNAME(api, ret, name, name, args)
#define DLL_DECLARE_FUNC_PREFIXED(api, ret, prefix, name, args) \
DLL_DECLARE_FUNC_PREFIXNAME(api, ret, prefix##name, name, args)
#define DLL_LOAD_FUNC_PREFIXNAME(dll, prefixname, name, ret_on_failure) \
do { \
HMODULE h = __dll_##dll##_handle; \
prefixname = (__dll_##name##_func_t)GetProcAddress(h, \
DLL_STRINGIFY(name)); \ DLL_STRINGIFY(name)); \
if (prefixname) break; \ if (prefixname) \
prefixname = (__dll_##name##_t)GetProcAddress(h, \ break; \
prefixname = (__dll_##name##_func_t)GetProcAddress(h, \
DLL_STRINGIFY(name) DLL_STRINGIFY(A)); \ DLL_STRINGIFY(name) DLL_STRINGIFY(A)); \
if (prefixname) break; \ if (prefixname) \
prefixname = (__dll_##name##_t)GetProcAddress(h, \ break; \
prefixname = (__dll_##name##_func_t)GetProcAddress(h, \
DLL_STRINGIFY(name) DLL_STRINGIFY(W)); \ DLL_STRINGIFY(name) DLL_STRINGIFY(W)); \
if (prefixname) break; \ if (prefixname) \
break; \
if (ret_on_failure) \ if (ret_on_failure) \
return LIBUSB_ERROR_NOT_FOUND; \ return LIBUSB_ERROR_NOT_FOUND; \
} while(0) } while(0)
#define DLL_DECLARE(api, ret, name, args) DLL_DECLARE_PREFIXNAME(api, ret, name, name, args) #define DLL_LOAD_FUNC(dll, name, ret_on_failure) \
#define DLL_LOAD(dll, name, ret_on_failure) DLL_LOAD_PREFIXNAME(dll, name, name, ret_on_failure) DLL_LOAD_FUNC_PREFIXNAME(dll, name, name, ret_on_failure)
#define DLL_DECLARE_PREFIXED(api, ret, prefix, name, args) DLL_DECLARE_PREFIXNAME(api, ret, prefix##name, name, args) #define DLL_LOAD_FUNC_PREFIXED(dll, prefix, name, ret_on_failure) \
#define DLL_LOAD_PREFIXED(dll, prefix, name, ret_on_failure) DLL_LOAD_PREFIXNAME(dll, prefix##name, name, ret_on_failure) DLL_LOAD_FUNC_PREFIXNAME(dll, prefix##name, name, ret_on_failure)

View File

@ -0,0 +1,610 @@
/*
* windows backend for libusb 1.0
* Copyright © 2009-2012 Pete Batard <pete@akeo.ie>
* With contributions from Michael Plante, Orin Eman et al.
* Parts of this code adapted from libusb-win32-v1 by Stephan Meyer
* HID Reports IOCTLs inspired from HIDAPI by Alan Ott, Signal 11 Software
* Hash table functions adapted from glibc, by Ulrich Drepper et al.
* 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
* 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 <inttypes.h>
#include <process.h>
#include <stdio.h>
#include "libusbi.h"
#include "windows_common.h"
#include "windows_nt_common.h"
// Global variables
const uint64_t epoch_time = UINT64_C(116444736000000000); // 1970.01.01 00:00:000 in MS Filetime
// Global variables for clock_gettime mechanism
static uint64_t hires_ticks_to_ps;
static uint64_t hires_frequency;
#define TIMER_REQUEST_RETRY_MS 100
#define WM_TIMER_REQUEST (WM_USER + 1)
#define WM_TIMER_EXIT (WM_USER + 2)
// used for monotonic clock_gettime()
struct timer_request {
struct timespec *tp;
HANDLE event;
};
// Timer thread
static HANDLE timer_thread = NULL;
static DWORD timer_thread_id = 0;
/* User32 dependencies */
DLL_DECLARE_HANDLE(User32);
DLL_DECLARE_FUNC_PREFIXED(WINAPI, BOOL, p, GetMessageA, (LPMSG, HWND, UINT, UINT));
DLL_DECLARE_FUNC_PREFIXED(WINAPI, BOOL, p, PeekMessageA, (LPMSG, HWND, UINT, UINT, UINT));
DLL_DECLARE_FUNC_PREFIXED(WINAPI, BOOL, p, PostThreadMessageA, (DWORD, UINT, WPARAM, LPARAM));
static unsigned __stdcall windows_clock_gettime_threaded(void *param);
/*
* Converts a windows error to human readable string
* uses retval as errorcode, or, if 0, use GetLastError()
*/
#if defined(ENABLE_LOGGING)
const char *windows_error_str(DWORD retval)
{
static char err_string[ERR_BUFFER_SIZE];
DWORD error_code, format_error;
DWORD size;
ssize_t i;
error_code = retval ? retval : GetLastError();
safe_sprintf(err_string, ERR_BUFFER_SIZE, "[%u] ", (unsigned int)error_code);
// Translate codes returned by SetupAPI. The ones we are dealing with are either
// in 0x0000xxxx or 0xE000xxxx and can be distinguished from standard error codes.
// See http://msdn.microsoft.com/en-us/library/windows/hardware/ff545011.aspx
switch (error_code & 0xE0000000) {
case 0:
error_code = HRESULT_FROM_WIN32(error_code); // Still leaves ERROR_SUCCESS unmodified
break;
case 0xE0000000:
error_code = 0x80000000 | (FACILITY_SETUPAPI << 16) | (error_code & 0x0000FFFF);
break;
default:
break;
}
size = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error_code,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), &err_string[safe_strlen(err_string)],
ERR_BUFFER_SIZE - (DWORD)safe_strlen(err_string), NULL);
if (size == 0) {
format_error = GetLastError();
if (format_error)
safe_sprintf(err_string, ERR_BUFFER_SIZE,
"Windows error code %u (FormatMessage error code %u)",
(unsigned int)error_code, (unsigned int)format_error);
else
safe_sprintf(err_string, ERR_BUFFER_SIZE, "Unknown error code %u", (unsigned int)error_code);
}
else {
// Remove CR/LF terminators
for (i = safe_strlen(err_string) - 1; (i >= 0) && ((err_string[i] == 0x0A) || (err_string[i] == 0x0D)); i--)
err_string[i] = 0;
}
return err_string;
}
#endif
/* Hash table functions - modified From glibc 2.3.2:
[Aho,Sethi,Ullman] Compilers: Principles, Techniques and Tools, 1986
[Knuth] The Art of Computer Programming, part 3 (6.4) */
#define HTAB_SIZE 1021
typedef struct htab_entry {
unsigned long used;
char *str;
} htab_entry;
static htab_entry *htab_table = NULL;
static usbi_mutex_t htab_write_mutex = NULL;
static unsigned long htab_size, htab_filled;
/* For the used double hash method the table size has to be a prime. To
correct the user given table size we need a prime test. This trivial
algorithm is adequate because the code is called only during init and
the number is likely to be small */
static int isprime(unsigned long number)
{
// no even number will be passed
unsigned int divider = 3;
while((divider * divider < number) && (number % divider != 0))
divider += 2;
return (number % divider != 0);
}
/* Before using the hash table we must allocate memory for it.
We allocate one element more as the found prime number says.
This is done for more effective indexing as explained in the
comment for the hash function. */
static bool htab_create(struct libusb_context *ctx, unsigned long nel)
{
if (htab_table != NULL) {
usbi_err(ctx, "hash table already allocated");
return true;
}
// Create a mutex
usbi_mutex_init(&htab_write_mutex);
// Change nel to the first prime number not smaller as nel.
nel |= 1;
while (!isprime(nel))
nel += 2;
htab_size = nel;
usbi_dbg("using %lu entries hash table", nel);
htab_filled = 0;
// allocate memory and zero out.
htab_table = calloc(htab_size + 1, sizeof(htab_entry));
if (htab_table == NULL) {
usbi_err(ctx, "could not allocate space for hash table");
return false;
}
return true;
}
/* After using the hash table it has to be destroyed. */
static void htab_destroy(void)
{
unsigned long i;
if (htab_table == NULL)
return;
for (i = 0; i < htab_size; i++) {
if (htab_table[i].used)
safe_free(htab_table[i].str);
}
usbi_mutex_destroy(&htab_write_mutex);
safe_free(htab_table);
}
/* This is the search function. It uses double hashing with open addressing.
We use a trick to speed up the lookup. The table is created with one
more element available. This enables us to use the index zero special.
This index will never be used because we store the first hash index in
the field used where zero means not used. Every other value means used.
The used field can be used as a first fast comparison for equality of
the stored and the parameter value. This helps to prevent unnecessary
expensive calls of strcmp. */
unsigned long htab_hash(const char *str)
{
unsigned long hval, hval2;
unsigned long idx;
unsigned long r = 5381;
int c;
const char *sz = str;
if (str == NULL)
return 0;
// Compute main hash value (algorithm suggested by Nokia)
while ((c = *sz++) != 0)
r = ((r << 5) + r) + c;
if (r == 0)
++r;
// compute table hash: simply take the modulus
hval = r % htab_size;
if (hval == 0)
++hval;
// Try the first index
idx = hval;
if (htab_table[idx].used) {
if ((htab_table[idx].used == hval) && (safe_strcmp(str, htab_table[idx].str) == 0))
return idx; // existing hash
usbi_dbg("hash collision ('%s' vs '%s')", str, htab_table[idx].str);
// Second hash function, as suggested in [Knuth]
hval2 = 1 + hval % (htab_size - 2);
do {
// Because size is prime this guarantees to step through all available indexes
if (idx <= hval2)
idx = htab_size + idx - hval2;
else
idx -= hval2;
// If we visited all entries leave the loop unsuccessfully
if (idx == hval)
break;
// If entry is found use it.
if ((htab_table[idx].used == hval) && (safe_strcmp(str, htab_table[idx].str) == 0))
return idx;
} while (htab_table[idx].used);
}
// Not found => New entry
// If the table is full return an error
if (htab_filled >= htab_size) {
usbi_err(NULL, "hash table is full (%d entries)", htab_size);
return 0;
}
// Concurrent threads might be storing the same entry at the same time
// (eg. "simultaneous" enums from different threads) => use a mutex
usbi_mutex_lock(&htab_write_mutex);
// Just free any previously allocated string (which should be the same as
// new one). The possibility of concurrent threads storing a collision
// string (same hash, different string) at the same time is extremely low
safe_free(htab_table[idx].str);
htab_table[idx].used = hval;
htab_table[idx].str = _strdup(str);
if (htab_table[idx].str == NULL) {
usbi_err(NULL, "could not duplicate string for hash table");
usbi_mutex_unlock(&htab_write_mutex);
return 0;
}
++htab_filled;
usbi_mutex_unlock(&htab_write_mutex);
return idx;
}
static int windows_init_dlls(void)
{
DLL_GET_HANDLE(User32);
DLL_LOAD_FUNC_PREFIXED(User32, p, GetMessageA, TRUE);
DLL_LOAD_FUNC_PREFIXED(User32, p, PeekMessageA, TRUE);
DLL_LOAD_FUNC_PREFIXED(User32, p, PostThreadMessageA, TRUE);
return LIBUSB_SUCCESS;
}
static void windows_exit_dlls(void)
{
DLL_FREE_HANDLE(User32);
}
static bool windows_init_clock(struct libusb_context *ctx)
{
DWORD_PTR affinity, dummy;
HANDLE event = NULL;
LARGE_INTEGER li_frequency;
int i;
if (QueryPerformanceFrequency(&li_frequency)) {
// Load DLL imports
if (windows_init_dlls() != LIBUSB_SUCCESS) {
usbi_err(ctx, "could not resolve DLL functions");
return false;
}
// The hires frequency can go as high as 4 GHz, so we'll use a conversion
// to picoseconds to compute the tv_nsecs part in clock_gettime
hires_frequency = li_frequency.QuadPart;
hires_ticks_to_ps = UINT64_C(1000000000000) / hires_frequency;
usbi_dbg("hires timer available (Frequency: %"PRIu64" Hz)", hires_frequency);
// Because QueryPerformanceCounter might report different values when
// running on different cores, we create a separate thread for the timer
// calls, which we glue to the first available core always to prevent timing discrepancies.
if (!GetProcessAffinityMask(GetCurrentProcess(), &affinity, &dummy) || (affinity == 0)) {
usbi_err(ctx, "could not get process affinity: %s", windows_error_str(0));
return false;
}
// The process affinity mask is a bitmask where each set bit represents a core on
// which this process is allowed to run, so we find the first set bit
for (i = 0; !(affinity & (DWORD_PTR)(1 << i)); i++);
affinity = (DWORD_PTR)(1 << i);
usbi_dbg("timer thread will run on core #%d", i);
event = CreateEvent(NULL, FALSE, FALSE, NULL);
if (event == NULL) {
usbi_err(ctx, "could not create event: %s", windows_error_str(0));
return false;
}
timer_thread = (HANDLE)_beginthreadex(NULL, 0, windows_clock_gettime_threaded, (void *)event,
0, (unsigned int *)&timer_thread_id);
if (timer_thread == NULL) {
usbi_err(ctx, "unable to create timer thread - aborting");
CloseHandle(event);
return false;
}
if (!SetThreadAffinityMask(timer_thread, affinity))
usbi_warn(ctx, "unable to set timer thread affinity, timer discrepancies may arise");
// Wait for timer thread to init before continuing.
if (WaitForSingleObject(event, INFINITE) != WAIT_OBJECT_0) {
usbi_err(ctx, "failed to wait for timer thread to become ready - aborting");
CloseHandle(event);
return false;
}
CloseHandle(event);
} else {
usbi_dbg("no hires timer available on this platform");
hires_frequency = 0;
hires_ticks_to_ps = UINT64_C(0);
}
return true;
}
void windows_destroy_clock(void)
{
if (timer_thread) {
// actually the signal to quit the thread.
if (!pPostThreadMessageA(timer_thread_id, WM_TIMER_EXIT, 0, 0)
|| (WaitForSingleObject(timer_thread, INFINITE) != WAIT_OBJECT_0)) {
usbi_dbg("could not wait for timer thread to quit");
TerminateThread(timer_thread, 1);
// shouldn't happen, but we're destroying
// all objects it might have held anyway.
}
CloseHandle(timer_thread);
timer_thread = NULL;
timer_thread_id = 0;
}
}
/*
* Monotonic and real time functions
*/
static unsigned __stdcall windows_clock_gettime_threaded(void *param)
{
struct timer_request *request;
LARGE_INTEGER hires_counter;
MSG msg;
// The following call will create this thread's message queue
// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms644946.aspx
pPeekMessageA(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);
// Signal windows_init_clock() that we're ready to service requests
if (!SetEvent((HANDLE)param))
usbi_dbg("SetEvent failed for timer init event: %s", windows_error_str(0));
param = NULL;
// Main loop - wait for requests
while (1) {
if (pGetMessageA(&msg, NULL, WM_TIMER_REQUEST, WM_TIMER_EXIT) == -1) {
usbi_err(NULL, "GetMessage failed for timer thread: %s", windows_error_str(0));
return 1;
}
switch (msg.message) {
case WM_TIMER_REQUEST:
// Requests to this thread are for hires always
// Microsoft says that this function always succeeds on XP and later
// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms644904.aspx
request = (struct timer_request *)msg.lParam;
QueryPerformanceCounter(&hires_counter);
request->tp->tv_sec = (long)(hires_counter.QuadPart / hires_frequency);
request->tp->tv_nsec = (long)(((hires_counter.QuadPart % hires_frequency) / 1000) * hires_ticks_to_ps);
if (!SetEvent(request->event))
usbi_err(NULL, "SetEvent failed for timer request: %s", windows_error_str(0));
break;
case WM_TIMER_EXIT:
usbi_dbg("timer thread quitting");
return 0;
}
}
}
int windows_clock_gettime(int clk_id, struct timespec *tp)
{
struct timer_request request;
FILETIME filetime;
ULARGE_INTEGER rtime;
DWORD r;
switch (clk_id) {
case USBI_CLOCK_MONOTONIC:
if (timer_thread) {
request.tp = tp;
request.event = CreateEvent(NULL, FALSE, FALSE, NULL);
if (request.event == NULL)
return LIBUSB_ERROR_NO_MEM;
if (!pPostThreadMessageA(timer_thread_id, WM_TIMER_REQUEST, 0, (LPARAM)&request)) {
usbi_err(NULL, "PostThreadMessage failed for timer thread: %s", windows_error_str(0));
CloseHandle(request.event);
return LIBUSB_ERROR_OTHER;
}
do {
r = WaitForSingleObject(request.event, TIMER_REQUEST_RETRY_MS);
if (r == WAIT_TIMEOUT)
usbi_dbg("could not obtain a timer value within reasonable timeframe - too much load?");
else if (r == WAIT_FAILED)
usbi_err(NULL, "WaitForSingleObject failed: %s", windows_error_str(0));
} while (r == WAIT_TIMEOUT);
CloseHandle(request.event);
if (r == WAIT_OBJECT_0)
return LIBUSB_SUCCESS;
else
return LIBUSB_ERROR_OTHER;
}
// Fall through and return real-time if monotonic was not detected @ timer init
case USBI_CLOCK_REALTIME:
// We follow http://msdn.microsoft.com/en-us/library/ms724928%28VS.85%29.aspx
// with a predef epoch_time to have an epoch that starts at 1970.01.01 00:00
// Note however that our resolution is bounded by the Windows system time
// functions and is at best of the order of 1 ms (or, usually, worse)
GetSystemTimeAsFileTime(&filetime);
rtime.LowPart = filetime.dwLowDateTime;
rtime.HighPart = filetime.dwHighDateTime;
rtime.QuadPart -= epoch_time;
tp->tv_sec = (long)(rtime.QuadPart / 10000000);
tp->tv_nsec = (long)((rtime.QuadPart % 10000000) * 100);
return LIBUSB_SUCCESS;
default:
return LIBUSB_ERROR_INVALID_PARAM;
}
}
static void windows_transfer_callback(struct usbi_transfer *itransfer, uint32_t io_result, uint32_t io_size)
{
int status, istatus;
usbi_dbg("handling I/O completion with errcode %u, size %u", io_result, io_size);
switch (io_result) {
case NO_ERROR:
status = windows_copy_transfer_data(itransfer, io_size);
break;
case ERROR_GEN_FAILURE:
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:
istatus = windows_copy_transfer_data(itransfer, io_size);
if (istatus != LIBUSB_TRANSFER_COMPLETED)
usbi_dbg("Failed to copy partial data in aborted operation: %d", istatus);
usbi_dbg("detected operation aborted");
status = LIBUSB_TRANSFER_CANCELLED;
break;
default:
usbi_err(ITRANSFER_CTX(itransfer), "detected I/O error %u: %s", io_result, windows_error_str(io_result));
status = LIBUSB_TRANSFER_ERROR;
break;
}
windows_clear_transfer_priv(itransfer); // Cancel polling
if (status == LIBUSB_TRANSFER_CANCELLED)
usbi_handle_transfer_cancellation(itransfer);
else
usbi_handle_transfer_completion(itransfer, (enum libusb_transfer_status)status);
}
void windows_handle_callback(struct usbi_transfer *itransfer, uint32_t io_result, uint32_t io_size)
{
struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
switch (transfer->type) {
case LIBUSB_TRANSFER_TYPE_CONTROL:
case LIBUSB_TRANSFER_TYPE_BULK:
case LIBUSB_TRANSFER_TYPE_INTERRUPT:
case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
windows_transfer_callback(itransfer, io_result, io_size);
break;
case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
usbi_warn(ITRANSFER_CTX(itransfer), "bulk stream transfers are not yet supported on this platform");
break;
default:
usbi_err(ITRANSFER_CTX(itransfer), "unknown endpoint type %d", transfer->type);
}
}
int windows_handle_events(struct libusb_context *ctx, struct pollfd *fds, POLL_NFDS_TYPE nfds, int num_ready)
{
POLL_NFDS_TYPE i = 0;
bool found = false;
struct usbi_transfer *transfer;
struct winfd *pollable_fd = NULL;
DWORD io_size, io_result;
int r = LIBUSB_SUCCESS;
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);
if (!fds[i].revents)
continue;
num_ready--;
// Because a Windows OVERLAPPED is used for poll emulation,
// a pollable fd is created and stored with each transfer
usbi_mutex_lock(&ctx->flying_transfers_lock);
found = false;
list_for_each_entry(transfer, &ctx->flying_transfers, list, struct usbi_transfer) {
pollable_fd = windows_get_fd(transfer);
if (pollable_fd->fd == fds[i].fd) {
found = true;
break;
}
}
usbi_mutex_unlock(&ctx->flying_transfers_lock);
if (found) {
windows_get_overlapped_result(transfer, pollable_fd, &io_result, &io_size);
usbi_remove_pollfd(ctx, pollable_fd->fd);
// let handle_callback free the event using the transfer wfd
// If you don't use the transfer wfd, you run a risk of trying to free a
// newly allocated wfd that took the place of the one from the transfer.
windows_handle_callback(transfer, io_result, io_size);
} else {
usbi_err(ctx, "could not find a matching transfer for fd %d", fds[i]);
r = LIBUSB_ERROR_NOT_FOUND;
break;
}
}
usbi_mutex_unlock(&ctx->open_devs_lock);
return r;
}
int windows_common_init(struct libusb_context *ctx)
{
if (!windows_init_clock(ctx))
goto error_roll_back;
if (!htab_create(ctx, HTAB_SIZE))
goto error_roll_back;
return LIBUSB_SUCCESS;
error_roll_back:
windows_common_exit();
return LIBUSB_ERROR_NO_MEM;
}
void windows_common_exit(void)
{
htab_destroy();
windows_destroy_clock();
windows_exit_dlls();
}

View File

@ -0,0 +1,63 @@
/*
* Windows backend common header for libusb 1.0
*
* This file brings together header code common between
* the desktop Windows backends.
* Copyright © 2012-2013 RealVNC Ltd.
* Copyright © 2009-2012 Pete Batard <pete@akeo.ie>
* 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
* 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
*/
#pragma once
// Missing from MinGW
#if !defined(FACILITY_SETUPAPI)
#define FACILITY_SETUPAPI 15
#endif
typedef struct USB_CONFIGURATION_DESCRIPTOR {
UCHAR bLength;
UCHAR bDescriptorType;
USHORT wTotalLength;
UCHAR bNumInterfaces;
UCHAR bConfigurationValue;
UCHAR iConfiguration;
UCHAR bmAttributes;
UCHAR MaxPower;
} USB_CONFIGURATION_DESCRIPTOR, *PUSB_CONFIGURATION_DESCRIPTOR;
typedef struct libusb_device_descriptor USB_DEVICE_DESCRIPTOR, *PUSB_DEVICE_DESCRIPTOR;
int windows_common_init(struct libusb_context *ctx);
void windows_common_exit(void);
unsigned long htab_hash(const char *str);
int windows_clock_gettime(int clk_id, struct timespec *tp);
void windows_clear_transfer_priv(struct usbi_transfer *itransfer);
int windows_copy_transfer_data(struct usbi_transfer *itransfer, uint32_t io_size);
struct winfd *windows_get_fd(struct usbi_transfer *transfer);
void windows_get_overlapped_result(struct usbi_transfer *transfer, struct winfd *pollable_fd, DWORD *io_result, DWORD *io_size);
void windows_handle_callback(struct usbi_transfer *itransfer, uint32_t io_result, uint32_t io_size);
int windows_handle_events(struct libusb_context *ctx, struct pollfd *fds, POLL_NFDS_TYPE nfds, int num_ready);
#if defined(ENABLE_LOGGING)
const char *windows_error_str(DWORD retval);
#endif

View File

@ -0,0 +1,905 @@
/*
* windows UsbDk backend for libusb 1.0
* Copyright © 2014 Red Hat, Inc.
* Authors:
* Dmitry Fleytman <dmitry@daynix.com>
* Pavel Gurvich <pavel@daynix.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>
#if defined(USE_USBDK)
#include <windows.h>
#include <cfgmgr32.h>
#include <stdio.h>
#include "libusbi.h"
#include "windows_common.h"
#include "windows_nt_common.h"
#define ULONG64 uint64_t
#define PVOID64 uint64_t
typedef CONST WCHAR *PCWCHAR;
#define wcsncpy_s wcsncpy
#include "windows_usbdk.h"
#if !defined(STATUS_SUCCESS)
typedef LONG NTSTATUS;
#define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
#endif
#if !defined(STATUS_CANCELLED)
#define STATUS_CANCELLED ((NTSTATUS)0xC0000120L)
#endif
#if !defined(STATUS_REQUEST_CANCELED)
#define STATUS_REQUEST_CANCELED ((NTSTATUS)0xC0000703L)
#endif
#if !defined(USBD_SUCCESS)
typedef int32_t USBD_STATUS;
#define USBD_SUCCESS(Status) ((USBD_STATUS) (Status) >= 0)
#define USBD_PENDING(Status) ((ULONG) (Status) >> 30 == 1)
#define USBD_ERROR(Status) ((USBD_STATUS) (Status) < 0)
#define USBD_STATUS_STALL_PID ((USBD_STATUS) 0xc0000004)
#define USBD_STATUS_ENDPOINT_HALTED ((USBD_STATUS) 0xc0000030)
#define USBD_STATUS_BAD_START_FRAME ((USBD_STATUS) 0xc0000a00)
#define USBD_STATUS_TIMEOUT ((USBD_STATUS) 0xc0006000)
#define USBD_STATUS_CANCELED ((USBD_STATUS) 0xc0010000)
#endif
static int concurrent_usage = -1;
struct usbdk_device_priv {
USB_DK_DEVICE_INFO info;
PUSB_CONFIGURATION_DESCRIPTOR *config_descriptors;
HANDLE redirector_handle;
uint8_t active_configuration;
};
struct usbdk_transfer_priv {
USB_DK_TRANSFER_REQUEST request;
struct winfd pollable_fd;
PULONG64 IsochronousPacketsArray;
PUSB_DK_ISO_TRANSFER_RESULT IsochronousResultsArray;
};
static inline struct usbdk_device_priv *_usbdk_device_priv(struct libusb_device *dev)
{
return (struct usbdk_device_priv *)dev->os_priv;
}
static inline struct usbdk_transfer_priv *_usbdk_transfer_priv(struct usbi_transfer *itransfer)
{
return (struct usbdk_transfer_priv *)usbi_transfer_get_os_priv(itransfer);
}
static struct {
HMODULE module;
USBDK_GET_DEVICES_LIST GetDevicesList;
USBDK_RELEASE_DEVICES_LIST ReleaseDevicesList;
USBDK_START_REDIRECT StartRedirect;
USBDK_STOP_REDIRECT StopRedirect;
USBDK_GET_CONFIGURATION_DESCRIPTOR GetConfigurationDescriptor;
USBDK_RELEASE_CONFIGURATION_DESCRIPTOR ReleaseConfigurationDescriptor;
USBDK_READ_PIPE ReadPipe;
USBDK_WRITE_PIPE WritePipe;
USBDK_ABORT_PIPE AbortPipe;
USBDK_RESET_PIPE ResetPipe;
USBDK_SET_ALTSETTING SetAltsetting;
USBDK_RESET_DEVICE ResetDevice;
USBDK_GET_REDIRECTOR_SYSTEM_HANDLE GetRedirectorSystemHandle;
} usbdk_helper;
static FARPROC get_usbdk_proc_addr(struct libusb_context *ctx, LPCSTR api_name)
{
FARPROC api_ptr = GetProcAddress(usbdk_helper.module, api_name);
if (api_ptr == NULL)
usbi_err(ctx, "UsbDkHelper API %s not found, error %d", api_name, GetLastError());
return api_ptr;
}
static void unload_usbdk_helper_dll(void)
{
if (usbdk_helper.module != NULL) {
FreeLibrary(usbdk_helper.module);
usbdk_helper.module = NULL;
}
}
static int load_usbdk_helper_dll(struct libusb_context *ctx)
{
usbdk_helper.module = LoadLibraryA("UsbDkHelper");
if (usbdk_helper.module == NULL) {
usbi_err(ctx, "Failed to load UsbDkHelper.dll, error %d", GetLastError());
return LIBUSB_ERROR_NOT_FOUND;
}
usbdk_helper.GetDevicesList = (USBDK_GET_DEVICES_LIST)get_usbdk_proc_addr(ctx, "UsbDk_GetDevicesList");
if (usbdk_helper.GetDevicesList == NULL)
goto error_unload;
usbdk_helper.ReleaseDevicesList = (USBDK_RELEASE_DEVICES_LIST)get_usbdk_proc_addr(ctx, "UsbDk_ReleaseDevicesList");
if (usbdk_helper.ReleaseDevicesList == NULL)
goto error_unload;
usbdk_helper.StartRedirect = (USBDK_START_REDIRECT)get_usbdk_proc_addr(ctx, "UsbDk_StartRedirect");
if (usbdk_helper.StartRedirect == NULL)
goto error_unload;
usbdk_helper.StopRedirect = (USBDK_STOP_REDIRECT)get_usbdk_proc_addr(ctx, "UsbDk_StopRedirect");
if (usbdk_helper.StopRedirect == NULL)
goto error_unload;
usbdk_helper.GetConfigurationDescriptor = (USBDK_GET_CONFIGURATION_DESCRIPTOR)get_usbdk_proc_addr(ctx, "UsbDk_GetConfigurationDescriptor");
if (usbdk_helper.GetConfigurationDescriptor == NULL)
goto error_unload;
usbdk_helper.ReleaseConfigurationDescriptor = (USBDK_RELEASE_CONFIGURATION_DESCRIPTOR)get_usbdk_proc_addr(ctx, "UsbDk_ReleaseConfigurationDescriptor");
if (usbdk_helper.ReleaseConfigurationDescriptor == NULL)
goto error_unload;
usbdk_helper.ReadPipe = (USBDK_READ_PIPE)get_usbdk_proc_addr(ctx, "UsbDk_ReadPipe");
if (usbdk_helper.ReadPipe == NULL)
goto error_unload;
usbdk_helper.WritePipe = (USBDK_WRITE_PIPE)get_usbdk_proc_addr(ctx, "UsbDk_WritePipe");
if (usbdk_helper.WritePipe == NULL)
goto error_unload;
usbdk_helper.AbortPipe = (USBDK_ABORT_PIPE)get_usbdk_proc_addr(ctx, "UsbDk_AbortPipe");
if (usbdk_helper.AbortPipe == NULL)
goto error_unload;
usbdk_helper.ResetPipe = (USBDK_RESET_PIPE)get_usbdk_proc_addr(ctx, "UsbDk_ResetPipe");
if (usbdk_helper.ResetPipe == NULL)
goto error_unload;
usbdk_helper.SetAltsetting = (USBDK_SET_ALTSETTING)get_usbdk_proc_addr(ctx, "UsbDk_SetAltsetting");
if (usbdk_helper.SetAltsetting == NULL)
goto error_unload;
usbdk_helper.ResetDevice = (USBDK_RESET_DEVICE)get_usbdk_proc_addr(ctx, "UsbDk_ResetDevice");
if (usbdk_helper.ResetDevice == NULL)
goto error_unload;
usbdk_helper.GetRedirectorSystemHandle = (USBDK_GET_REDIRECTOR_SYSTEM_HANDLE)get_usbdk_proc_addr(ctx, "UsbDk_GetRedirectorSystemHandle");
if (usbdk_helper.GetRedirectorSystemHandle == NULL)
goto error_unload;
return LIBUSB_SUCCESS;
error_unload:
FreeLibrary(usbdk_helper.module);
usbdk_helper.module = NULL;
return LIBUSB_ERROR_NOT_FOUND;
}
static int usbdk_init(struct libusb_context *ctx)
{
int r;
if (++concurrent_usage == 0) { // First init?
r = load_usbdk_helper_dll(ctx);
if (r)
goto init_exit;
init_polling();
r = windows_common_init(ctx);
if (r)
goto init_exit;
}
// At this stage, either we went through full init successfully, or didn't need to
r = LIBUSB_SUCCESS;
init_exit:
if (!concurrent_usage && r != LIBUSB_SUCCESS) { // First init failed?
exit_polling();
windows_common_exit();
unload_usbdk_helper_dll();
}
if (r != LIBUSB_SUCCESS)
--concurrent_usage; // Not expected to call libusb_exit if we failed.
return r;
}
static int usbdk_get_session_id_for_device(struct libusb_context *ctx,
PUSB_DK_DEVICE_ID id, unsigned long *session_id)
{
char dev_identity[ARRAYSIZE(id->DeviceID) + ARRAYSIZE(id->InstanceID)];
if (sprintf(dev_identity, "%S%S", id->DeviceID, id->InstanceID) == -1) {
usbi_warn(ctx, "cannot form device identity", id->DeviceID);
return LIBUSB_ERROR_NOT_SUPPORTED;
}
*session_id = htab_hash(dev_identity);
return LIBUSB_SUCCESS;
}
static void usbdk_release_config_descriptors(struct usbdk_device_priv *p, uint8_t count)
{
uint8_t i;
for (i = 0; i < count; i++)
usbdk_helper.ReleaseConfigurationDescriptor(p->config_descriptors[i]);
free(p->config_descriptors);
p->config_descriptors = NULL;
}
static int usbdk_cache_config_descriptors(struct libusb_context *ctx,
struct usbdk_device_priv *p, PUSB_DK_DEVICE_INFO info)
{
uint8_t i;
USB_DK_CONFIG_DESCRIPTOR_REQUEST Request;
Request.ID = info->ID;
p->config_descriptors = calloc(info->DeviceDescriptor.bNumConfigurations, sizeof(PUSB_CONFIGURATION_DESCRIPTOR));
if (p->config_descriptors == NULL) {
usbi_err(ctx, "failed to allocate configuration descriptors holder");
return LIBUSB_ERROR_NO_MEM;
}
for (i = 0; i < info->DeviceDescriptor.bNumConfigurations; i++) {
ULONG Length;
Request.Index = i;
if (!usbdk_helper.GetConfigurationDescriptor(&Request, &p->config_descriptors[i], &Length)) {
usbi_err(ctx, "failed to retrieve configuration descriptors");
usbdk_release_config_descriptors(p, i);
return LIBUSB_ERROR_OTHER;
}
}
return LIBUSB_SUCCESS;
}
static inline int usbdk_device_priv_init(struct libusb_context *ctx, struct libusb_device *dev, PUSB_DK_DEVICE_INFO info)
{
struct usbdk_device_priv *p = _usbdk_device_priv(dev);
p->info = *info;
p->active_configuration = 0;
return usbdk_cache_config_descriptors(ctx, p, info);
}
static void usbdk_device_init(libusb_device *dev, PUSB_DK_DEVICE_INFO info)
{
dev->bus_number = (uint8_t)info->FilterID;
dev->port_number = (uint8_t)info->Port;
dev->parent_dev = NULL;
//Addresses in libusb are 1-based
dev->device_address = (uint8_t)(info->Port + 1);
dev->num_configurations = info->DeviceDescriptor.bNumConfigurations;
dev->device_descriptor = info->DeviceDescriptor;
switch (info->Speed) {
case LowSpeed:
dev->speed = LIBUSB_SPEED_LOW;
break;
case FullSpeed:
dev->speed = LIBUSB_SPEED_FULL;
break;
case HighSpeed:
dev->speed = LIBUSB_SPEED_HIGH;
break;
case SuperSpeed:
dev->speed = LIBUSB_SPEED_SUPER;
break;
case NoSpeed:
default:
dev->speed = LIBUSB_SPEED_UNKNOWN;
break;
}
}
static int usbdk_get_device_list(struct libusb_context *ctx, struct discovered_devs **_discdevs)
{
int r = LIBUSB_SUCCESS;
ULONG i;
struct discovered_devs *discdevs = NULL;
ULONG dev_number;
PUSB_DK_DEVICE_INFO devices;
if(!usbdk_helper.GetDevicesList(&devices, &dev_number))
return LIBUSB_ERROR_OTHER;
for (i = 0; i < dev_number; i++) {
unsigned long session_id;
struct libusb_device *dev = NULL;
if (usbdk_get_session_id_for_device(ctx, &devices[i].ID, &session_id))
continue;
dev = usbi_get_device_by_session_id(ctx, session_id);
if (dev == NULL) {
dev = usbi_alloc_device(ctx, session_id);
if (dev == NULL) {
usbi_err(ctx, "failed to allocate a new device structure");
continue;
}
usbdk_device_init(dev, &devices[i]);
if (usbdk_device_priv_init(ctx, dev, &devices[i]) != LIBUSB_SUCCESS) {
libusb_unref_device(dev);
continue;
}
}
discdevs = discovered_devs_append(*_discdevs, dev);
libusb_unref_device(dev);
if (!discdevs) {
usbi_err(ctx, "cannot append new device to list");
r = LIBUSB_ERROR_NO_MEM;
goto func_exit;
}
*_discdevs = discdevs;
}
func_exit:
usbdk_helper.ReleaseDevicesList(devices);
return r;
}
static void usbdk_exit(void)
{
if (--concurrent_usage < 0) {
windows_common_exit();
exit_polling();
unload_usbdk_helper_dll();
}
}
static int usbdk_get_device_descriptor(struct libusb_device *dev, unsigned char *buffer, int *host_endian)
{
struct usbdk_device_priv *priv = _usbdk_device_priv(dev);
memcpy(buffer, &priv->info.DeviceDescriptor, DEVICE_DESC_LENGTH);
*host_endian = 0;
return LIBUSB_SUCCESS;
}
static int usbdk_get_config_descriptor(struct libusb_device *dev, uint8_t config_index, unsigned char *buffer, size_t len, int *host_endian)
{
struct usbdk_device_priv *priv = _usbdk_device_priv(dev);
PUSB_CONFIGURATION_DESCRIPTOR config_header;
size_t size;
if (config_index >= dev->num_configurations)
return LIBUSB_ERROR_INVALID_PARAM;
config_header = (PUSB_CONFIGURATION_DESCRIPTOR)priv->config_descriptors[config_index];
size = min(config_header->wTotalLength, len);
memcpy(buffer, config_header, size);
*host_endian = 0;
return (int)size;
}
static inline int usbdk_get_active_config_descriptor(struct libusb_device *dev, unsigned char *buffer, size_t len, int *host_endian)
{
return usbdk_get_config_descriptor(dev, _usbdk_device_priv(dev)->active_configuration,
buffer, len, host_endian);
}
static int usbdk_open(struct libusb_device_handle *dev_handle)
{
struct usbdk_device_priv *priv = _usbdk_device_priv(dev_handle->dev);
priv->redirector_handle = usbdk_helper.StartRedirect(&priv->info.ID);
if (priv->redirector_handle == INVALID_HANDLE_VALUE) {
usbi_err(DEVICE_CTX(dev_handle->dev), "Redirector startup failed");
return LIBUSB_ERROR_OTHER;
}
return LIBUSB_SUCCESS;
}
static void usbdk_close(struct libusb_device_handle *dev_handle)
{
struct usbdk_device_priv *priv = _usbdk_device_priv(dev_handle->dev);
if (!usbdk_helper.StopRedirect(priv->redirector_handle)) {
struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
usbi_err(ctx, "Redirector shutdown failed");
}
}
static int usbdk_get_configuration(struct libusb_device_handle *dev_handle, int *config)
{
*config = _usbdk_device_priv(dev_handle->dev)->active_configuration;
return LIBUSB_SUCCESS;
}
static int usbdk_set_configuration(struct libusb_device_handle *dev_handle, int config)
{
UNUSED(dev_handle);
UNUSED(config);
return LIBUSB_SUCCESS;
}
static int usbdk_claim_interface(struct libusb_device_handle *dev_handle, int iface)
{
UNUSED(dev_handle);
UNUSED(iface);
return LIBUSB_SUCCESS;
}
static int usbdk_set_interface_altsetting(struct libusb_device_handle *dev_handle, int iface, int altsetting)
{
struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
struct usbdk_device_priv *priv = _usbdk_device_priv(dev_handle->dev);
if (!usbdk_helper.SetAltsetting(priv->redirector_handle, iface, altsetting)) {
usbi_err(ctx, "SetAltsetting failed: %s", windows_error_str(0));
return LIBUSB_ERROR_NO_DEVICE;
}
return LIBUSB_SUCCESS;
}
static int usbdk_release_interface(struct libusb_device_handle *dev_handle, int iface)
{
UNUSED(dev_handle);
UNUSED(iface);
return LIBUSB_SUCCESS;
}
static int usbdk_clear_halt(struct libusb_device_handle *dev_handle, unsigned char endpoint)
{
struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
struct usbdk_device_priv *priv = _usbdk_device_priv(dev_handle->dev);
if (!usbdk_helper.ResetPipe(priv->redirector_handle, endpoint)) {
usbi_err(ctx, "ResetPipe failed: %s", windows_error_str(0));
return LIBUSB_ERROR_NO_DEVICE;
}
return LIBUSB_SUCCESS;
}
static int usbdk_reset_device(struct libusb_device_handle *dev_handle)
{
struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
struct usbdk_device_priv *priv = _usbdk_device_priv(dev_handle->dev);
if (!usbdk_helper.ResetDevice(priv->redirector_handle)) {
usbi_err(ctx, "ResetDevice failed: %s", windows_error_str(0));
return LIBUSB_ERROR_NO_DEVICE;
}
return LIBUSB_SUCCESS;
}
static int usbdk_kernel_driver_active(struct libusb_device_handle *dev_handle, int iface)
{
UNUSED(dev_handle);
UNUSED(iface);
return LIBUSB_ERROR_NOT_SUPPORTED;
}
static int usbdk_attach_kernel_driver(struct libusb_device_handle *dev_handle, int iface)
{
UNUSED(dev_handle);
UNUSED(iface);
return LIBUSB_ERROR_NOT_SUPPORTED;
}
static int usbdk_detach_kernel_driver(struct libusb_device_handle *dev_handle, int iface)
{
UNUSED(dev_handle);
UNUSED(iface);
return LIBUSB_ERROR_NOT_SUPPORTED;
}
static void usbdk_destroy_device(struct libusb_device *dev)
{
struct usbdk_device_priv* p = _usbdk_device_priv(dev);
if (p->config_descriptors != NULL)
usbdk_release_config_descriptors(p, p->info.DeviceDescriptor.bNumConfigurations);
}
void windows_clear_transfer_priv(struct usbi_transfer *itransfer)
{
struct usbdk_transfer_priv *transfer_priv = _usbdk_transfer_priv(itransfer);
struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
usbi_free_fd(&transfer_priv->pollable_fd);
if (transfer->type == LIBUSB_TRANSFER_TYPE_ISOCHRONOUS) {
safe_free(transfer_priv->IsochronousPacketsArray);
safe_free(transfer_priv->IsochronousResultsArray);
}
}
static int usbdk_do_control_transfer(struct usbi_transfer *itransfer)
{
struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
struct usbdk_device_priv *priv = _usbdk_device_priv(transfer->dev_handle->dev);
struct usbdk_transfer_priv *transfer_priv = _usbdk_transfer_priv(itransfer);
struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
struct winfd wfd;
ULONG Length;
TransferResult transResult;
HANDLE sysHandle;
sysHandle = usbdk_helper.GetRedirectorSystemHandle(priv->redirector_handle);
wfd = usbi_create_fd(sysHandle, RW_READ, NULL, NULL);
// Always use the handle returned from usbi_create_fd (wfd.handle)
if (wfd.fd < 0)
return LIBUSB_ERROR_NO_MEM;
transfer_priv->request.Buffer = (PVOID64)(uintptr_t)transfer->buffer;
transfer_priv->request.BufferLength = transfer->length;
transfer_priv->request.TransferType = ControlTransferType;
transfer_priv->pollable_fd = INVALID_WINFD;
Length = (ULONG)transfer->length;
if (IS_XFERIN(transfer))
transResult = usbdk_helper.ReadPipe(priv->redirector_handle, &transfer_priv->request, wfd.overlapped);
else
transResult = usbdk_helper.WritePipe(priv->redirector_handle, &transfer_priv->request, wfd.overlapped);
switch (transResult) {
case TransferSuccess:
wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
wfd.overlapped->InternalHigh = (DWORD)Length;
break;
case TransferSuccessAsync:
break;
case TransferFailure:
usbi_err(ctx, "ControlTransfer failed: %s", windows_error_str(0));
usbi_free_fd(&wfd);
return LIBUSB_ERROR_IO;
}
// Use priv_transfer to store data needed for async polling
transfer_priv->pollable_fd = wfd;
usbi_add_pollfd(ctx, transfer_priv->pollable_fd.fd, POLLIN);
return LIBUSB_SUCCESS;
}
static int usbdk_do_bulk_transfer(struct usbi_transfer *itransfer)
{
struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
struct usbdk_device_priv *priv = _usbdk_device_priv(transfer->dev_handle->dev);
struct usbdk_transfer_priv *transfer_priv = _usbdk_transfer_priv(itransfer);
struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
struct winfd wfd;
TransferResult transferRes;
HANDLE sysHandle;
transfer_priv->request.Buffer = (PVOID64)(uintptr_t)transfer->buffer;
transfer_priv->request.BufferLength = transfer->length;
transfer_priv->request.EndpointAddress = transfer->endpoint;
switch (transfer->type) {
case LIBUSB_TRANSFER_TYPE_BULK:
transfer_priv->request.TransferType = BulkTransferType;
break;
case LIBUSB_TRANSFER_TYPE_INTERRUPT:
transfer_priv->request.TransferType = IntertuptTransferType;
break;
default:
usbi_err(ctx, "Wrong transfer type (%d) in usbdk_do_bulk_transfer. %s", transfer->type, windows_error_str(0));
return LIBUSB_ERROR_INVALID_PARAM;
}
transfer_priv->pollable_fd = INVALID_WINFD;
sysHandle = usbdk_helper.GetRedirectorSystemHandle(priv->redirector_handle);
wfd = usbi_create_fd(sysHandle, IS_XFERIN(transfer) ? RW_READ : RW_WRITE, NULL, NULL);
// Always use the handle returned from usbi_create_fd (wfd.handle)
if (wfd.fd < 0)
return LIBUSB_ERROR_NO_MEM;
if (IS_XFERIN(transfer))
transferRes = usbdk_helper.ReadPipe(priv->redirector_handle, &transfer_priv->request, wfd.overlapped);
else
transferRes = usbdk_helper.WritePipe(priv->redirector_handle, &transfer_priv->request, wfd.overlapped);
switch (transferRes) {
case TransferSuccess:
wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
break;
case TransferSuccessAsync:
break;
case TransferFailure:
usbi_err(ctx, "ReadPipe/WritePipe failed: %s", windows_error_str(0));
usbi_free_fd(&wfd);
return LIBUSB_ERROR_IO;
}
transfer_priv->pollable_fd = wfd;
usbi_add_pollfd(ctx, transfer_priv->pollable_fd.fd, IS_XFERIN(transfer) ? POLLIN : POLLOUT);
return LIBUSB_SUCCESS;
}
static int usbdk_do_iso_transfer(struct usbi_transfer *itransfer)
{
struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
struct usbdk_device_priv *priv = _usbdk_device_priv(transfer->dev_handle->dev);
struct usbdk_transfer_priv *transfer_priv = _usbdk_transfer_priv(itransfer);
struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
struct winfd wfd;
TransferResult transferRes;
int i;
HANDLE sysHandle;
transfer_priv->request.Buffer = (PVOID64)(uintptr_t)transfer->buffer;
transfer_priv->request.BufferLength = transfer->length;
transfer_priv->request.EndpointAddress = transfer->endpoint;
transfer_priv->request.TransferType = IsochronousTransferType;
transfer_priv->request.IsochronousPacketsArraySize = transfer->num_iso_packets;
transfer_priv->IsochronousPacketsArray = malloc(transfer->num_iso_packets * sizeof(ULONG64));
transfer_priv->request.IsochronousPacketsArray = (PVOID64)(uintptr_t)transfer_priv->IsochronousPacketsArray;
if (!transfer_priv->IsochronousPacketsArray) {
usbi_err(ctx, "Allocation of IsochronousPacketsArray is failed, %s", windows_error_str(0));
return LIBUSB_ERROR_IO;
}
transfer_priv->IsochronousResultsArray = malloc(transfer->num_iso_packets * sizeof(USB_DK_ISO_TRANSFER_RESULT));
transfer_priv->request.Result.IsochronousResultsArray = (PVOID64)(uintptr_t)transfer_priv->IsochronousResultsArray;
if (!transfer_priv->IsochronousResultsArray) {
usbi_err(ctx, "Allocation of isochronousResultsArray is failed, %s", windows_error_str(0));
free(transfer_priv->IsochronousPacketsArray);
return LIBUSB_ERROR_IO;
}
for (i = 0; i < transfer->num_iso_packets; i++)
transfer_priv->IsochronousPacketsArray[i] = transfer->iso_packet_desc[i].length;
transfer_priv->pollable_fd = INVALID_WINFD;
sysHandle = usbdk_helper.GetRedirectorSystemHandle(priv->redirector_handle);
wfd = usbi_create_fd(sysHandle, IS_XFERIN(transfer) ? RW_READ : RW_WRITE, NULL, NULL);
// Always use the handle returned from usbi_create_fd (wfd.handle)
if (wfd.fd < 0) {
free(transfer_priv->IsochronousPacketsArray);
free(transfer_priv->IsochronousResultsArray);
return LIBUSB_ERROR_NO_MEM;
}
if (IS_XFERIN(transfer))
transferRes = usbdk_helper.ReadPipe(priv->redirector_handle, &transfer_priv->request, wfd.overlapped);
else
transferRes = usbdk_helper.WritePipe(priv->redirector_handle, &transfer_priv->request, wfd.overlapped);
switch (transferRes) {
case TransferSuccess:
wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
break;
case TransferSuccessAsync:
break;
case TransferFailure:
usbi_err(ctx, "ReadPipe/WritePipe failed: %s", windows_error_str(0));
usbi_free_fd(&wfd);
free(transfer_priv->IsochronousPacketsArray);
free(transfer_priv->IsochronousResultsArray);
return LIBUSB_ERROR_IO;
}
transfer_priv->pollable_fd = wfd;
usbi_add_pollfd(ctx, transfer_priv->pollable_fd.fd, IS_XFERIN(transfer) ? POLLIN : POLLOUT);
return LIBUSB_SUCCESS;
}
static int usbdk_submit_transfer(struct usbi_transfer *itransfer)
{
struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
switch (transfer->type) {
case LIBUSB_TRANSFER_TYPE_CONTROL:
return usbdk_do_control_transfer(itransfer);
case LIBUSB_TRANSFER_TYPE_BULK:
case LIBUSB_TRANSFER_TYPE_INTERRUPT:
if (IS_XFEROUT(transfer) && (transfer->flags & LIBUSB_TRANSFER_ADD_ZERO_PACKET))
return LIBUSB_ERROR_NOT_SUPPORTED; //TODO: Check whether we can support this in UsbDk
else
return usbdk_do_bulk_transfer(itransfer);
case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
return usbdk_do_iso_transfer(itransfer);
default:
usbi_err(TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
return LIBUSB_ERROR_INVALID_PARAM;
}
}
static int usbdk_abort_transfers(struct usbi_transfer *itransfer)
{
struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
struct usbdk_device_priv *priv = _usbdk_device_priv(transfer->dev_handle->dev);
if (!usbdk_helper.AbortPipe(priv->redirector_handle, transfer->endpoint)) {
usbi_err(ctx, "AbortPipe failed: %s", windows_error_str(0));
return LIBUSB_ERROR_NO_DEVICE;
}
return LIBUSB_SUCCESS;
}
static int usbdk_cancel_transfer(struct usbi_transfer *itransfer)
{
struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
switch (transfer->type) {
case LIBUSB_TRANSFER_TYPE_CONTROL:
// Control transfers cancelled by IoCancelXXX() API
// No special treatment needed
return LIBUSB_SUCCESS;
case LIBUSB_TRANSFER_TYPE_BULK:
case LIBUSB_TRANSFER_TYPE_INTERRUPT:
case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
return usbdk_abort_transfers(itransfer);
default:
usbi_err(ITRANSFER_CTX(itransfer), "unknown endpoint type %d", transfer->type);
return LIBUSB_ERROR_INVALID_PARAM;
}
}
int windows_copy_transfer_data(struct usbi_transfer *itransfer, uint32_t io_size)
{
itransfer->transferred += io_size;
return LIBUSB_TRANSFER_COMPLETED;
}
struct winfd *windows_get_fd(struct usbi_transfer *transfer)
{
struct usbdk_transfer_priv *transfer_priv = _usbdk_transfer_priv(transfer);
return &transfer_priv->pollable_fd;
}
static DWORD usbdk_translate_usbd_status(USBD_STATUS UsbdStatus)
{
if (USBD_SUCCESS(UsbdStatus))
return NO_ERROR;
switch (UsbdStatus) {
case USBD_STATUS_STALL_PID:
case USBD_STATUS_ENDPOINT_HALTED:
case USBD_STATUS_BAD_START_FRAME:
return ERROR_GEN_FAILURE;
case USBD_STATUS_TIMEOUT:
return ERROR_SEM_TIMEOUT;
case USBD_STATUS_CANCELED:
return ERROR_OPERATION_ABORTED;
default:
return ERROR_FUNCTION_FAILED;
}
}
void windows_get_overlapped_result(struct usbi_transfer *transfer, struct winfd *pollable_fd, DWORD *io_result, DWORD *io_size)
{
if (HasOverlappedIoCompletedSync(pollable_fd->overlapped) // Handle async requests that completed synchronously first
|| GetOverlappedResult(pollable_fd->handle, pollable_fd->overlapped, io_size, false)) { // Regular async overlapped
struct libusb_transfer *ltransfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(transfer);
struct usbdk_transfer_priv *transfer_priv = _usbdk_transfer_priv(transfer);
if (ltransfer->type == LIBUSB_TRANSFER_TYPE_ISOCHRONOUS) {
int i;
for (i = 0; i < transfer_priv->request.IsochronousPacketsArraySize; i++) {
struct libusb_iso_packet_descriptor *lib_desc = &ltransfer->iso_packet_desc[i];
switch (transfer_priv->IsochronousResultsArray[i].TransferResult) {
case STATUS_SUCCESS:
case STATUS_CANCELLED:
case STATUS_REQUEST_CANCELED:
lib_desc->status = LIBUSB_TRANSFER_COMPLETED; // == ERROR_SUCCESS
break;
default:
lib_desc->status = LIBUSB_TRANSFER_ERROR; // ERROR_UNKNOWN_EXCEPTION;
break;
}
lib_desc->actual_length = (unsigned int)transfer_priv->IsochronousResultsArray[i].ActualLength;
}
}
*io_size = (DWORD) transfer_priv->request.Result.GenResult.BytesTransferred;
*io_result = usbdk_translate_usbd_status((USBD_STATUS) transfer_priv->request.Result.GenResult.UsbdStatus);
}
else {
*io_result = GetLastError();
}
}
static int usbdk_clock_gettime(int clk_id, struct timespec *tp)
{
return windows_clock_gettime(clk_id, tp);
}
const struct usbi_os_backend usbdk_backend = {
"Windows",
USBI_CAP_HAS_HID_ACCESS,
usbdk_init,
usbdk_exit,
usbdk_get_device_list,
NULL,
usbdk_open,
usbdk_close,
usbdk_get_device_descriptor,
usbdk_get_active_config_descriptor,
usbdk_get_config_descriptor,
NULL,
usbdk_get_configuration,
usbdk_set_configuration,
usbdk_claim_interface,
usbdk_release_interface,
usbdk_set_interface_altsetting,
usbdk_clear_halt,
usbdk_reset_device,
NULL,
NULL,
NULL, // dev_mem_alloc()
NULL, // dev_mem_free()
usbdk_kernel_driver_active,
usbdk_detach_kernel_driver,
usbdk_attach_kernel_driver,
usbdk_destroy_device,
usbdk_submit_transfer,
usbdk_cancel_transfer,
windows_clear_transfer_priv,
windows_handle_events,
NULL,
usbdk_clock_gettime,
#if defined(USBI_TIMERFD_AVAILABLE)
NULL,
#endif
sizeof(struct usbdk_device_priv),
0,
sizeof(struct usbdk_transfer_priv),
};
#endif /* USE_USBDK */

View File

@ -0,0 +1,146 @@
/*
* windows UsbDk backend for libusb 1.0
* Copyright © 2014 Red Hat, Inc.
* Authors:
* Dmitry Fleytman <dmitry@daynix.com>
* Pavel Gurvich <pavel@daynix.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
*/
#pragma once
typedef struct tag_USB_DK_DEVICE_ID {
WCHAR DeviceID[MAX_DEVICE_ID_LEN];
WCHAR InstanceID[MAX_DEVICE_ID_LEN];
} USB_DK_DEVICE_ID, *PUSB_DK_DEVICE_ID;
static inline void UsbDkFillIDStruct(USB_DK_DEVICE_ID *ID, PCWCHAR DeviceID, PCWCHAR InstanceID)
{
wcsncpy_s(ID->DeviceID, DeviceID, MAX_DEVICE_ID_LEN);
wcsncpy_s(ID->InstanceID, InstanceID, MAX_DEVICE_ID_LEN);
}
typedef struct tag_USB_DK_DEVICE_INFO {
USB_DK_DEVICE_ID ID;
ULONG64 FilterID;
ULONG64 Port;
ULONG64 Speed;
USB_DEVICE_DESCRIPTOR DeviceDescriptor;
} USB_DK_DEVICE_INFO, *PUSB_DK_DEVICE_INFO;
typedef struct tag_USB_DK_CONFIG_DESCRIPTOR_REQUEST {
USB_DK_DEVICE_ID ID;
ULONG64 Index;
} USB_DK_CONFIG_DESCRIPTOR_REQUEST, *PUSB_DK_CONFIG_DESCRIPTOR_REQUEST;
typedef struct tag_USB_DK_ISO_TRANSFER_RESULT {
ULONG64 ActualLength;
ULONG64 TransferResult;
} USB_DK_ISO_TRANSFER_RESULT, *PUSB_DK_ISO_TRANSFER_RESULT;
typedef struct tag_USB_DK_GEN_TRANSFER_RESULT {
ULONG64 BytesTransferred;
ULONG64 UsbdStatus; // USBD_STATUS code
} USB_DK_GEN_TRANSFER_RESULT, *PUSB_DK_GEN_TRANSFER_RESULT;
typedef struct tag_USB_DK_TRANSFER_RESULT {
USB_DK_GEN_TRANSFER_RESULT GenResult;
PVOID64 IsochronousResultsArray; // array of USB_DK_ISO_TRANSFER_RESULT
} USB_DK_TRANSFER_RESULT, *PUSB_DK_TRANSFER_RESULT;
typedef struct tag_USB_DK_TRANSFER_REQUEST {
ULONG64 EndpointAddress;
PVOID64 Buffer;
ULONG64 BufferLength;
ULONG64 TransferType;
ULONG64 IsochronousPacketsArraySize;
PVOID64 IsochronousPacketsArray;
USB_DK_TRANSFER_RESULT Result;
} USB_DK_TRANSFER_REQUEST, *PUSB_DK_TRANSFER_REQUEST;
typedef enum {
TransferFailure = 0,
TransferSuccess,
TransferSuccessAsync
} TransferResult;
typedef enum {
NoSpeed = 0,
LowSpeed,
FullSpeed,
HighSpeed,
SuperSpeed
} USB_DK_DEVICE_SPEED;
typedef enum {
ControlTransferType,
BulkTransferType,
IntertuptTransferType,
IsochronousTransferType
} USB_DK_TRANSFER_TYPE;
typedef BOOL (__cdecl *USBDK_GET_DEVICES_LIST)(
PUSB_DK_DEVICE_INFO *DeviceInfo,
PULONG DeviceNumber
);
typedef void (__cdecl *USBDK_RELEASE_DEVICES_LIST)(
PUSB_DK_DEVICE_INFO DeviceInfo
);
typedef HANDLE (__cdecl *USBDK_START_REDIRECT)(
PUSB_DK_DEVICE_ID DeviceId
);
typedef BOOL (__cdecl *USBDK_STOP_REDIRECT)(
HANDLE DeviceHandle
);
typedef BOOL (__cdecl *USBDK_GET_CONFIGURATION_DESCRIPTOR)(
PUSB_DK_CONFIG_DESCRIPTOR_REQUEST Request,
PUSB_CONFIGURATION_DESCRIPTOR *Descriptor,
PULONG Length
);
typedef void (__cdecl *USBDK_RELEASE_CONFIGURATION_DESCRIPTOR)(
PUSB_CONFIGURATION_DESCRIPTOR Descriptor
);
typedef TransferResult (__cdecl *USBDK_WRITE_PIPE)(
HANDLE DeviceHandle,
PUSB_DK_TRANSFER_REQUEST Request,
LPOVERLAPPED lpOverlapped
);
typedef TransferResult (__cdecl *USBDK_READ_PIPE)(
HANDLE DeviceHandle,
PUSB_DK_TRANSFER_REQUEST Request,
LPOVERLAPPED lpOverlapped
);
typedef BOOL (__cdecl *USBDK_ABORT_PIPE)(
HANDLE DeviceHandle,
ULONG64 PipeAddress
);
typedef BOOL (__cdecl *USBDK_RESET_PIPE)(
HANDLE DeviceHandle,
ULONG64 PipeAddress
);
typedef BOOL (__cdecl *USBDK_SET_ALTSETTING)(
HANDLE DeviceHandle,
ULONG64 InterfaceIdx,
ULONG64 AltSettingIdx
);
typedef BOOL (__cdecl *USBDK_RESET_DEVICE)(
HANDLE DeviceHandle
);
typedef HANDLE (__cdecl *USBDK_GET_REDIRECTOR_SYSTEM_HANDLE)(
HANDLE DeviceHandle
);

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,948 @@
/*
* Windows backend for libusb 1.0
* Copyright © 2009-2012 Pete Batard <pete@akeo.ie>
* 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
* 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
*/
#pragma once
#include "windows_common.h"
#include "windows_nt_common.h"
#if defined(_MSC_VER)
// disable /W4 MSVC warnings that are benign
#pragma warning(disable:4100) // unreferenced formal parameter
#pragma warning(disable:4127) // conditional expression is constant
#pragma warning(disable:4201) // nameless struct/union
#pragma warning(disable:4214) // bit field types other than int
#pragma warning(disable:4996) // deprecated API calls
#pragma warning(disable:28159) // more deprecated API calls
#endif
// Missing from MSVC6 setupapi.h
#if !defined(SPDRP_ADDRESS)
#define SPDRP_ADDRESS 28
#endif
#if !defined(SPDRP_INSTALL_STATE)
#define SPDRP_INSTALL_STATE 34
#endif
#define MAX_CTRL_BUFFER_LENGTH 4096
#define MAX_USB_DEVICES 256
#define MAX_USB_STRING_LENGTH 128
#define MAX_HID_REPORT_SIZE 1024
#define MAX_HID_DESCRIPTOR_SIZE 256
#define MAX_GUID_STRING_LENGTH 40
#define MAX_PATH_LENGTH 128
#define MAX_KEY_LENGTH 256
#define LIST_SEPARATOR ';'
// Handle code for HID interface that have been claimed ("dibs")
#define INTERFACE_CLAIMED ((HANDLE)(intptr_t)0xD1B5)
// Additional return code for HID operations that completed synchronously
#define LIBUSB_COMPLETED (LIBUSB_SUCCESS + 1)
// http://msdn.microsoft.com/en-us/library/ff545978.aspx
// http://msdn.microsoft.com/en-us/library/ff545972.aspx
// http://msdn.microsoft.com/en-us/library/ff545982.aspx
#if !defined(GUID_DEVINTERFACE_USB_HOST_CONTROLLER)
const GUID GUID_DEVINTERFACE_USB_HOST_CONTROLLER = { 0x3ABF6F2D, 0x71C4, 0x462A, {0x8A, 0x92, 0x1E, 0x68, 0x61, 0xE6, 0xAF, 0x27} };
#endif
#if !defined(GUID_DEVINTERFACE_USB_DEVICE)
const GUID GUID_DEVINTERFACE_USB_DEVICE = { 0xA5DCBF10, 0x6530, 0x11D2, {0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED} };
#endif
#if !defined(GUID_DEVINTERFACE_USB_HUB)
const GUID GUID_DEVINTERFACE_USB_HUB = { 0xF18A0E88, 0xC30C, 0x11D0, {0x88, 0x15, 0x00, 0xA0, 0xC9, 0x06, 0xBE, 0xD8} };
#endif
#if !defined(GUID_DEVINTERFACE_LIBUSB0_FILTER)
const GUID GUID_DEVINTERFACE_LIBUSB0_FILTER = { 0xF9F3FF14, 0xAE21, 0x48A0, {0x8A, 0x25, 0x80, 0x11, 0xA7, 0xA9, 0x31, 0xD9} };
#endif
/*
* Multiple USB API backend support
*/
#define USB_API_UNSUPPORTED 0
#define USB_API_HUB 1
#define USB_API_COMPOSITE 2
#define USB_API_WINUSBX 3
#define USB_API_HID 4
#define USB_API_MAX 5
// The following is used to indicate if the HID or composite extra props have already been set.
#define USB_API_SET (1 << USB_API_MAX)
// Sub-APIs for WinUSB-like driver APIs (WinUSB, libusbK, libusb-win32 through the libusbK DLL)
// Must have the same values as the KUSB_DRVID enum from libusbk.h
#define SUB_API_NOTSET -1
#define SUB_API_LIBUSBK 0
#define SUB_API_LIBUSB0 1
#define SUB_API_WINUSB 2
#define SUB_API_MAX 3
#define WINUSBX_DRV_NAMES {"libusbK", "libusb0", "WinUSB"}
struct windows_usb_api_backend {
const uint8_t id;
const char *designation;
const char **driver_name_list; // Driver name, without .sys, e.g. "usbccgp"
const uint8_t nb_driver_names;
int (*init)(int sub_api, struct libusb_context *ctx);
int (*exit)(int sub_api);
int (*open)(int sub_api, struct libusb_device_handle *dev_handle);
void (*close)(int sub_api, struct libusb_device_handle *dev_handle);
int (*configure_endpoints)(int sub_api, struct libusb_device_handle *dev_handle, int iface);
int (*claim_interface)(int sub_api, struct libusb_device_handle *dev_handle, int iface);
int (*set_interface_altsetting)(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting);
int (*release_interface)(int sub_api, struct libusb_device_handle *dev_handle, int iface);
int (*clear_halt)(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint);
int (*reset_device)(int sub_api, struct libusb_device_handle *dev_handle);
int (*submit_bulk_transfer)(int sub_api, struct usbi_transfer *itransfer);
int (*submit_iso_transfer)(int sub_api, struct usbi_transfer *itransfer);
int (*submit_control_transfer)(int sub_api, struct usbi_transfer *itransfer);
int (*abort_control)(int sub_api, struct usbi_transfer *itransfer);
int (*abort_transfers)(int sub_api, struct usbi_transfer *itransfer);
int (*copy_transfer_data)(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size);
};
extern const struct windows_usb_api_backend usb_api_backend[USB_API_MAX];
#define PRINT_UNSUPPORTED_API(fname) \
usbi_dbg("unsupported API call for '" \
#fname "' (unrecognized device driver)"); \
return LIBUSB_ERROR_NOT_SUPPORTED;
/*
* private structures definition
* with inline pseudo constructors/destructors
*/
// TODO (v2+): move hid desc to libusb.h?
struct libusb_hid_descriptor {
uint8_t bLength;
uint8_t bDescriptorType;
uint16_t bcdHID;
uint8_t bCountryCode;
uint8_t bNumDescriptors;
uint8_t bClassDescriptorType;
uint16_t wClassDescriptorLength;
};
#define LIBUSB_DT_HID_SIZE 9
#define HID_MAX_CONFIG_DESC_SIZE (LIBUSB_DT_CONFIG_SIZE + LIBUSB_DT_INTERFACE_SIZE \
+ LIBUSB_DT_HID_SIZE + 2 * LIBUSB_DT_ENDPOINT_SIZE)
#define HID_MAX_REPORT_SIZE 1024
#define HID_IN_EP 0x81
#define HID_OUT_EP 0x02
#define LIBUSB_REQ_RECIPIENT(request_type) ((request_type) & 0x1F)
#define LIBUSB_REQ_TYPE(request_type) ((request_type) & (0x03 << 5))
#define LIBUSB_REQ_IN(request_type) ((request_type) & LIBUSB_ENDPOINT_IN)
#define LIBUSB_REQ_OUT(request_type) (!LIBUSB_REQ_IN(request_type))
// The following are used for HID reports IOCTLs
#define HID_CTL_CODE(id) \
CTL_CODE (FILE_DEVICE_KEYBOARD, (id), METHOD_NEITHER, FILE_ANY_ACCESS)
#define HID_BUFFER_CTL_CODE(id) \
CTL_CODE (FILE_DEVICE_KEYBOARD, (id), METHOD_BUFFERED, FILE_ANY_ACCESS)
#define HID_IN_CTL_CODE(id) \
CTL_CODE (FILE_DEVICE_KEYBOARD, (id), METHOD_IN_DIRECT, FILE_ANY_ACCESS)
#define HID_OUT_CTL_CODE(id) \
CTL_CODE (FILE_DEVICE_KEYBOARD, (id), METHOD_OUT_DIRECT, FILE_ANY_ACCESS)
#define IOCTL_HID_GET_FEATURE HID_OUT_CTL_CODE(100)
#define IOCTL_HID_GET_INPUT_REPORT HID_OUT_CTL_CODE(104)
#define IOCTL_HID_SET_FEATURE HID_IN_CTL_CODE(100)
#define IOCTL_HID_SET_OUTPUT_REPORT HID_IN_CTL_CODE(101)
enum libusb_hid_request_type {
HID_REQ_GET_REPORT = 0x01,
HID_REQ_GET_IDLE = 0x02,
HID_REQ_GET_PROTOCOL = 0x03,
HID_REQ_SET_REPORT = 0x09,
HID_REQ_SET_IDLE = 0x0A,
HID_REQ_SET_PROTOCOL = 0x0B
};
enum libusb_hid_report_type {
HID_REPORT_TYPE_INPUT = 0x01,
HID_REPORT_TYPE_OUTPUT = 0x02,
HID_REPORT_TYPE_FEATURE = 0x03
};
struct hid_device_priv {
uint16_t vid;
uint16_t pid;
uint8_t config;
uint8_t nb_interfaces;
bool uses_report_ids[3]; // input, ouptput, feature
uint16_t input_report_size;
uint16_t output_report_size;
uint16_t feature_report_size;
WCHAR string[3][MAX_USB_STRING_LENGTH];
uint8_t string_index[3]; // man, prod, ser
};
struct windows_device_priv {
uint8_t depth; // distance to HCD
uint8_t port; // port number on the hub
uint8_t active_config;
struct windows_usb_api_backend const *apib;
char *path; // device interface path
int sub_api; // for WinUSB-like APIs
struct {
char *path; // each interface needs a device interface path,
struct windows_usb_api_backend const *apib; // an API backend (multiple drivers support),
int sub_api;
int8_t nb_endpoints; // and a set of endpoint addresses (USB_MAXENDPOINTS)
uint8_t *endpoint;
bool restricted_functionality; // indicates if the interface functionality is restricted
// by Windows (eg. HID keyboards or mice cannot do R/W)
} usb_interface[USB_MAXINTERFACES];
struct hid_device_priv *hid;
USB_DEVICE_DESCRIPTOR dev_descriptor;
unsigned char **config_descriptor; // list of pointers to the cached config descriptors
};
static inline struct windows_device_priv *_device_priv(struct libusb_device *dev)
{
return (struct windows_device_priv *)dev->os_priv;
}
static inline struct windows_device_priv *windows_device_priv_init(struct libusb_device *dev)
{
struct windows_device_priv *p = _device_priv(dev);
int i;
p->depth = 0;
p->port = 0;
p->path = NULL;
p->apib = &usb_api_backend[USB_API_UNSUPPORTED];
p->sub_api = SUB_API_NOTSET;
p->hid = NULL;
p->active_config = 0;
p->config_descriptor = NULL;
memset(&p->dev_descriptor, 0, sizeof(USB_DEVICE_DESCRIPTOR));
for (i = 0; i < USB_MAXINTERFACES; i++) {
p->usb_interface[i].path = NULL;
p->usb_interface[i].apib = &usb_api_backend[USB_API_UNSUPPORTED];
p->usb_interface[i].sub_api = SUB_API_NOTSET;
p->usb_interface[i].nb_endpoints = 0;
p->usb_interface[i].endpoint = NULL;
p->usb_interface[i].restricted_functionality = false;
}
return p;
}
static inline void windows_device_priv_release(struct libusb_device *dev)
{
struct windows_device_priv *p = _device_priv(dev);
int i;
safe_free(p->path);
if ((dev->num_configurations > 0) && (p->config_descriptor != NULL)) {
for (i = 0; i < dev->num_configurations; i++)
safe_free(p->config_descriptor[i]);
}
safe_free(p->config_descriptor);
safe_free(p->hid);
for (i = 0; i < USB_MAXINTERFACES; i++) {
safe_free(p->usb_interface[i].path);
safe_free(p->usb_interface[i].endpoint);
}
}
struct interface_handle_t {
HANDLE dev_handle; // WinUSB needs an extra handle for the file
HANDLE api_handle; // used by the API to communicate with the device
};
struct windows_device_handle_priv {
int active_interface;
struct interface_handle_t interface_handle[USB_MAXINTERFACES];
int autoclaim_count[USB_MAXINTERFACES]; // For auto-release
};
static inline struct windows_device_handle_priv *_device_handle_priv(
struct libusb_device_handle *handle)
{
return (struct windows_device_handle_priv *)handle->os_priv;
}
// used for async polling functions
struct windows_transfer_priv {
struct winfd pollable_fd;
uint8_t interface_number;
uint8_t *hid_buffer; // 1 byte extended data buffer, required for HID
uint8_t *hid_dest; // transfer buffer destination, required for HID
size_t hid_expected_size;
};
// used to match a device driver (including filter drivers) against a supported API
struct driver_lookup {
char list[MAX_KEY_LENGTH + 1]; // REG_MULTI_SZ list of services (driver) names
const DWORD reg_prop; // SPDRP registry key to use to retrieve list
const char* designation; // internal designation (for debug output)
};
/* OLE32 dependency */
DLL_DECLARE_HANDLE(OLE32);
DLL_DECLARE_FUNC_PREFIXED(WINAPI, HRESULT, p, CLSIDFromString, (LPCOLESTR, LPCLSID));
/* Kernel32 dependencies */
DLL_DECLARE_HANDLE(Kernel32);
/* This call is only available from XP SP2 */
DLL_DECLARE_FUNC_PREFIXED(WINAPI, BOOL, p, IsWow64Process, (HANDLE, PBOOL));
/* SetupAPI dependencies */
DLL_DECLARE_HANDLE(SetupAPI);
DLL_DECLARE_FUNC_PREFIXED(WINAPI, HDEVINFO, p, SetupDiGetClassDevsA, (const GUID*, PCSTR, HWND, DWORD));
DLL_DECLARE_FUNC_PREFIXED(WINAPI, BOOL, p, SetupDiEnumDeviceInfo, (HDEVINFO, DWORD, PSP_DEVINFO_DATA));
DLL_DECLARE_FUNC_PREFIXED(WINAPI, BOOL, p, SetupDiEnumDeviceInterfaces, (HDEVINFO, PSP_DEVINFO_DATA,
const GUID*, DWORD, PSP_DEVICE_INTERFACE_DATA));
DLL_DECLARE_FUNC_PREFIXED(WINAPI, BOOL, p, SetupDiGetDeviceInterfaceDetailA, (HDEVINFO, PSP_DEVICE_INTERFACE_DATA,
PSP_DEVICE_INTERFACE_DETAIL_DATA_A, DWORD, PDWORD, PSP_DEVINFO_DATA));
DLL_DECLARE_FUNC_PREFIXED(WINAPI, BOOL, p, SetupDiDestroyDeviceInfoList, (HDEVINFO));
DLL_DECLARE_FUNC_PREFIXED(WINAPI, HKEY, p, SetupDiOpenDevRegKey, (HDEVINFO, PSP_DEVINFO_DATA, DWORD, DWORD, DWORD, REGSAM));
DLL_DECLARE_FUNC_PREFIXED(WINAPI, BOOL, p, SetupDiGetDeviceRegistryPropertyA, (HDEVINFO,
PSP_DEVINFO_DATA, DWORD, PDWORD, PBYTE, DWORD, PDWORD));
DLL_DECLARE_FUNC_PREFIXED(WINAPI, HKEY, p, SetupDiOpenDeviceInterfaceRegKey, (HDEVINFO, PSP_DEVICE_INTERFACE_DATA, DWORD, DWORD));
/* AdvAPI32 dependencies */
DLL_DECLARE_HANDLE(AdvAPI32);
DLL_DECLARE_FUNC_PREFIXED(WINAPI, LONG, p, RegQueryValueExW, (HKEY, LPCWSTR, LPDWORD, LPDWORD, LPBYTE, LPDWORD));
DLL_DECLARE_FUNC_PREFIXED(WINAPI, LONG, p, RegCloseKey, (HKEY));
/*
* Windows DDK API definitions. Most of it copied from MinGW's includes
*/
typedef DWORD DEVNODE, DEVINST;
typedef DEVNODE *PDEVNODE, *PDEVINST;
typedef DWORD RETURN_TYPE;
typedef RETURN_TYPE CONFIGRET;
#define CR_SUCCESS 0x00000000
#define CR_NO_SUCH_DEVNODE 0x0000000D
#define USB_DEVICE_DESCRIPTOR_TYPE LIBUSB_DT_DEVICE
#define USB_CONFIGURATION_DESCRIPTOR_TYPE LIBUSB_DT_CONFIG
#define USB_STRING_DESCRIPTOR_TYPE LIBUSB_DT_STRING
#define USB_INTERFACE_DESCRIPTOR_TYPE LIBUSB_DT_INTERFACE
#define USB_ENDPOINT_DESCRIPTOR_TYPE LIBUSB_DT_ENDPOINT
#define USB_REQUEST_GET_STATUS LIBUSB_REQUEST_GET_STATUS
#define USB_REQUEST_CLEAR_FEATURE LIBUSB_REQUEST_CLEAR_FEATURE
#define USB_REQUEST_SET_FEATURE LIBUSB_REQUEST_SET_FEATURE
#define USB_REQUEST_SET_ADDRESS LIBUSB_REQUEST_SET_ADDRESS
#define USB_REQUEST_GET_DESCRIPTOR LIBUSB_REQUEST_GET_DESCRIPTOR
#define USB_REQUEST_SET_DESCRIPTOR LIBUSB_REQUEST_SET_DESCRIPTOR
#define USB_REQUEST_GET_CONFIGURATION LIBUSB_REQUEST_GET_CONFIGURATION
#define USB_REQUEST_SET_CONFIGURATION LIBUSB_REQUEST_SET_CONFIGURATION
#define USB_REQUEST_GET_INTERFACE LIBUSB_REQUEST_GET_INTERFACE
#define USB_REQUEST_SET_INTERFACE LIBUSB_REQUEST_SET_INTERFACE
#define USB_REQUEST_SYNC_FRAME LIBUSB_REQUEST_SYNCH_FRAME
#define USB_GET_NODE_INFORMATION 258
#define USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION 260
#define USB_GET_NODE_CONNECTION_NAME 261
#define USB_GET_HUB_CAPABILITIES 271
#if !defined(USB_GET_NODE_CONNECTION_INFORMATION_EX)
#define USB_GET_NODE_CONNECTION_INFORMATION_EX 274
#endif
#if !defined(USB_GET_HUB_CAPABILITIES_EX)
#define USB_GET_HUB_CAPABILITIES_EX 276
#endif
#if !defined(USB_GET_NODE_CONNECTION_INFORMATION_EX_V2)
#define USB_GET_NODE_CONNECTION_INFORMATION_EX_V2 279
#endif
#ifndef METHOD_BUFFERED
#define METHOD_BUFFERED 0
#endif
#ifndef FILE_ANY_ACCESS
#define FILE_ANY_ACCESS 0x00000000
#endif
#ifndef FILE_DEVICE_UNKNOWN
#define FILE_DEVICE_UNKNOWN 0x00000022
#endif
#ifndef FILE_DEVICE_USB
#define FILE_DEVICE_USB FILE_DEVICE_UNKNOWN
#endif
#ifndef CTL_CODE
#define CTL_CODE(DeviceType, Function, Method, Access) \
(((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method))
#endif
typedef enum USB_CONNECTION_STATUS {
NoDeviceConnected,
DeviceConnected,
DeviceFailedEnumeration,
DeviceGeneralFailure,
DeviceCausedOvercurrent,
DeviceNotEnoughPower,
DeviceNotEnoughBandwidth,
DeviceHubNestedTooDeeply,
DeviceInLegacyHub
} USB_CONNECTION_STATUS, *PUSB_CONNECTION_STATUS;
typedef enum USB_HUB_NODE {
UsbHub,
UsbMIParent
} USB_HUB_NODE;
/* Cfgmgr32.dll interface */
DLL_DECLARE_HANDLE(Cfgmgr32);
DLL_DECLARE_FUNC(WINAPI, CONFIGRET, CM_Get_Parent, (PDEVINST, DEVINST, ULONG));
DLL_DECLARE_FUNC(WINAPI, CONFIGRET, CM_Get_Child, (PDEVINST, DEVINST, ULONG));
DLL_DECLARE_FUNC(WINAPI, CONFIGRET, CM_Get_Sibling, (PDEVINST, DEVINST, ULONG));
DLL_DECLARE_FUNC(WINAPI, CONFIGRET, CM_Get_Device_IDA, (DEVINST, PCHAR, ULONG, ULONG));
#define IOCTL_USB_GET_HUB_CAPABILITIES_EX \
CTL_CODE( FILE_DEVICE_USB, USB_GET_HUB_CAPABILITIES_EX, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_USB_GET_HUB_CAPABILITIES \
CTL_CODE(FILE_DEVICE_USB, USB_GET_HUB_CAPABILITIES, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION \
CTL_CODE(FILE_DEVICE_USB, USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_USB_GET_ROOT_HUB_NAME \
CTL_CODE(FILE_DEVICE_USB, HCD_GET_ROOT_HUB_NAME, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_USB_GET_NODE_INFORMATION \
CTL_CODE(FILE_DEVICE_USB, USB_GET_NODE_INFORMATION, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX \
CTL_CODE(FILE_DEVICE_USB, USB_GET_NODE_CONNECTION_INFORMATION_EX, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX_V2 \
CTL_CODE(FILE_DEVICE_USB, USB_GET_NODE_CONNECTION_INFORMATION_EX_V2, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_USB_GET_NODE_CONNECTION_ATTRIBUTES \
CTL_CODE(FILE_DEVICE_USB, USB_GET_NODE_CONNECTION_ATTRIBUTES, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_USB_GET_NODE_CONNECTION_NAME \
CTL_CODE(FILE_DEVICE_USB, USB_GET_NODE_CONNECTION_NAME, METHOD_BUFFERED, FILE_ANY_ACCESS)
// Most of the structures below need to be packed
#pragma pack(push, 1)
typedef struct USB_INTERFACE_DESCRIPTOR {
UCHAR bLength;
UCHAR bDescriptorType;
UCHAR bInterfaceNumber;
UCHAR bAlternateSetting;
UCHAR bNumEndpoints;
UCHAR bInterfaceClass;
UCHAR bInterfaceSubClass;
UCHAR bInterfaceProtocol;
UCHAR iInterface;
} USB_INTERFACE_DESCRIPTOR, *PUSB_INTERFACE_DESCRIPTOR;
typedef struct USB_CONFIGURATION_DESCRIPTOR_SHORT {
struct {
ULONG ConnectionIndex;
struct {
UCHAR bmRequest;
UCHAR bRequest;
USHORT wValue;
USHORT wIndex;
USHORT wLength;
} SetupPacket;
} req;
USB_CONFIGURATION_DESCRIPTOR data;
} USB_CONFIGURATION_DESCRIPTOR_SHORT;
typedef struct USB_ENDPOINT_DESCRIPTOR {
UCHAR bLength;
UCHAR bDescriptorType;
UCHAR bEndpointAddress;
UCHAR bmAttributes;
USHORT wMaxPacketSize;
UCHAR bInterval;
} USB_ENDPOINT_DESCRIPTOR, *PUSB_ENDPOINT_DESCRIPTOR;
typedef struct USB_DESCRIPTOR_REQUEST {
ULONG ConnectionIndex;
struct {
UCHAR bmRequest;
UCHAR bRequest;
USHORT wValue;
USHORT wIndex;
USHORT wLength;
} SetupPacket;
// UCHAR Data[0];
} USB_DESCRIPTOR_REQUEST, *PUSB_DESCRIPTOR_REQUEST;
typedef struct USB_HUB_DESCRIPTOR {
UCHAR bDescriptorLength;
UCHAR bDescriptorType;
UCHAR bNumberOfPorts;
USHORT wHubCharacteristics;
UCHAR bPowerOnToPowerGood;
UCHAR bHubControlCurrent;
UCHAR bRemoveAndPowerMask[64];
} USB_HUB_DESCRIPTOR, *PUSB_HUB_DESCRIPTOR;
typedef struct USB_ROOT_HUB_NAME {
ULONG ActualLength;
WCHAR RootHubName[1];
} USB_ROOT_HUB_NAME, *PUSB_ROOT_HUB_NAME;
typedef struct USB_ROOT_HUB_NAME_FIXED {
ULONG ActualLength;
WCHAR RootHubName[MAX_PATH_LENGTH];
} USB_ROOT_HUB_NAME_FIXED;
typedef struct USB_NODE_CONNECTION_NAME {
ULONG ConnectionIndex;
ULONG ActualLength;
WCHAR NodeName[1];
} USB_NODE_CONNECTION_NAME, *PUSB_NODE_CONNECTION_NAME;
typedef struct USB_NODE_CONNECTION_NAME_FIXED {
ULONG ConnectionIndex;
ULONG ActualLength;
WCHAR NodeName[MAX_PATH_LENGTH];
} USB_NODE_CONNECTION_NAME_FIXED;
typedef struct USB_HUB_NAME_FIXED {
union {
USB_ROOT_HUB_NAME_FIXED root;
USB_NODE_CONNECTION_NAME_FIXED node;
} u;
} USB_HUB_NAME_FIXED;
typedef struct USB_HUB_INFORMATION {
USB_HUB_DESCRIPTOR HubDescriptor;
BOOLEAN HubIsBusPowered;
} USB_HUB_INFORMATION, *PUSB_HUB_INFORMATION;
typedef struct USB_MI_PARENT_INFORMATION {
ULONG NumberOfInterfaces;
} USB_MI_PARENT_INFORMATION, *PUSB_MI_PARENT_INFORMATION;
typedef struct USB_NODE_INFORMATION {
USB_HUB_NODE NodeType;
union {
USB_HUB_INFORMATION HubInformation;
USB_MI_PARENT_INFORMATION MiParentInformation;
} u;
} USB_NODE_INFORMATION, *PUSB_NODE_INFORMATION;
typedef struct USB_PIPE_INFO {
USB_ENDPOINT_DESCRIPTOR EndpointDescriptor;
ULONG ScheduleOffset;
} USB_PIPE_INFO, *PUSB_PIPE_INFO;
typedef struct USB_NODE_CONNECTION_INFORMATION_EX {
ULONG ConnectionIndex;
USB_DEVICE_DESCRIPTOR DeviceDescriptor;
UCHAR CurrentConfigurationValue;
UCHAR Speed;
BOOLEAN DeviceIsHub;
USHORT DeviceAddress;
ULONG NumberOfOpenPipes;
USB_CONNECTION_STATUS ConnectionStatus;
// USB_PIPE_INFO PipeList[0];
} USB_NODE_CONNECTION_INFORMATION_EX, *PUSB_NODE_CONNECTION_INFORMATION_EX;
typedef union _USB_PROTOCOLS {
ULONG ul;
struct {
ULONG Usb110:1;
ULONG Usb200:1;
ULONG Usb300:1;
ULONG ReservedMBZ:29;
};
} USB_PROTOCOLS, *PUSB_PROTOCOLS;
typedef union _USB_NODE_CONNECTION_INFORMATION_EX_V2_FLAGS {
ULONG ul;
struct {
ULONG DeviceIsOperatingAtSuperSpeedOrHigher:1;
ULONG DeviceIsSuperSpeedCapableOrHigher:1;
ULONG ReservedMBZ:30;
};
} USB_NODE_CONNECTION_INFORMATION_EX_V2_FLAGS, *PUSB_NODE_CONNECTION_INFORMATION_EX_V2_FLAGS;
typedef struct _USB_NODE_CONNECTION_INFORMATION_EX_V2 {
ULONG ConnectionIndex;
ULONG Length;
USB_PROTOCOLS SupportedUsbProtocols;
USB_NODE_CONNECTION_INFORMATION_EX_V2_FLAGS Flags;
} USB_NODE_CONNECTION_INFORMATION_EX_V2, *PUSB_NODE_CONNECTION_INFORMATION_EX_V2;
typedef struct USB_HUB_CAP_FLAGS {
ULONG HubIsHighSpeedCapable:1;
ULONG HubIsHighSpeed:1;
ULONG HubIsMultiTtCapable:1;
ULONG HubIsMultiTt:1;
ULONG HubIsRoot:1;
ULONG HubIsArmedWakeOnConnect:1;
ULONG ReservedMBZ:26;
} USB_HUB_CAP_FLAGS, *PUSB_HUB_CAP_FLAGS;
typedef struct USB_HUB_CAPABILITIES {
ULONG HubIs2xCapable:1;
} USB_HUB_CAPABILITIES, *PUSB_HUB_CAPABILITIES;
typedef struct USB_HUB_CAPABILITIES_EX {
USB_HUB_CAP_FLAGS CapabilityFlags;
} USB_HUB_CAPABILITIES_EX, *PUSB_HUB_CAPABILITIES_EX;
#pragma pack(pop)
/* winusb.dll interface */
#define SHORT_PACKET_TERMINATE 0x01
#define AUTO_CLEAR_STALL 0x02
#define PIPE_TRANSFER_TIMEOUT 0x03
#define IGNORE_SHORT_PACKETS 0x04
#define ALLOW_PARTIAL_READS 0x05
#define AUTO_FLUSH 0x06
#define RAW_IO 0x07
#define MAXIMUM_TRANSFER_SIZE 0x08
#define AUTO_SUSPEND 0x81
#define SUSPEND_DELAY 0x83
#define DEVICE_SPEED 0x01
#define LowSpeed 0x01
#define FullSpeed 0x02
#define HighSpeed 0x03
typedef enum USBD_PIPE_TYPE {
UsbdPipeTypeControl,
UsbdPipeTypeIsochronous,
UsbdPipeTypeBulk,
UsbdPipeTypeInterrupt
} USBD_PIPE_TYPE;
typedef struct {
USBD_PIPE_TYPE PipeType;
UCHAR PipeId;
USHORT MaximumPacketSize;
UCHAR Interval;
} WINUSB_PIPE_INFORMATION, *PWINUSB_PIPE_INFORMATION;
#pragma pack(1)
typedef struct {
UCHAR request_type;
UCHAR request;
USHORT value;
USHORT index;
USHORT length;
} WINUSB_SETUP_PACKET, *PWINUSB_SETUP_PACKET;
#pragma pack()
typedef void *WINUSB_INTERFACE_HANDLE, *PWINUSB_INTERFACE_HANDLE;
typedef BOOL (WINAPI *WinUsb_AbortPipe_t)(
WINUSB_INTERFACE_HANDLE InterfaceHandle,
UCHAR PipeID
);
typedef BOOL (WINAPI *WinUsb_ControlTransfer_t)(
WINUSB_INTERFACE_HANDLE InterfaceHandle,
WINUSB_SETUP_PACKET SetupPacket,
PUCHAR Buffer,
ULONG BufferLength,
PULONG LengthTransferred,
LPOVERLAPPED Overlapped
);
typedef BOOL (WINAPI *WinUsb_FlushPipe_t)(
WINUSB_INTERFACE_HANDLE InterfaceHandle,
UCHAR PipeID
);
typedef BOOL (WINAPI *WinUsb_Free_t)(
WINUSB_INTERFACE_HANDLE InterfaceHandle
);
typedef BOOL (WINAPI *WinUsb_GetAssociatedInterface_t)(
WINUSB_INTERFACE_HANDLE InterfaceHandle,
UCHAR AssociatedInterfaceIndex,
PWINUSB_INTERFACE_HANDLE AssociatedInterfaceHandle
);
typedef BOOL (WINAPI *WinUsb_GetCurrentAlternateSetting_t)(
WINUSB_INTERFACE_HANDLE InterfaceHandle,
PUCHAR AlternateSetting
);
typedef BOOL (WINAPI *WinUsb_GetDescriptor_t)(
WINUSB_INTERFACE_HANDLE InterfaceHandle,
UCHAR DescriptorType,
UCHAR Index,
USHORT LanguageID,
PUCHAR Buffer,
ULONG BufferLength,
PULONG LengthTransferred
);
typedef BOOL (WINAPI *WinUsb_GetOverlappedResult_t)(
WINUSB_INTERFACE_HANDLE InterfaceHandle,
LPOVERLAPPED lpOverlapped,
LPDWORD lpNumberOfBytesTransferred,
BOOL bWait
);
typedef BOOL (WINAPI *WinUsb_GetPipePolicy_t)(
WINUSB_INTERFACE_HANDLE InterfaceHandle,
UCHAR PipeID,
ULONG PolicyType,
PULONG ValueLength,
PVOID Value
);
typedef BOOL (WINAPI *WinUsb_GetPowerPolicy_t)(
WINUSB_INTERFACE_HANDLE InterfaceHandle,
ULONG PolicyType,
PULONG ValueLength,
PVOID Value
);
typedef BOOL (WINAPI *WinUsb_Initialize_t)(
HANDLE DeviceHandle,
PWINUSB_INTERFACE_HANDLE InterfaceHandle
);
typedef BOOL (WINAPI *WinUsb_QueryDeviceInformation_t)(
WINUSB_INTERFACE_HANDLE InterfaceHandle,
ULONG InformationType,
PULONG BufferLength,
PVOID Buffer
);
typedef BOOL (WINAPI *WinUsb_QueryInterfaceSettings_t)(
WINUSB_INTERFACE_HANDLE InterfaceHandle,
UCHAR AlternateSettingNumber,
PUSB_INTERFACE_DESCRIPTOR UsbAltInterfaceDescriptor
);
typedef BOOL (WINAPI *WinUsb_QueryPipe_t)(
WINUSB_INTERFACE_HANDLE InterfaceHandle,
UCHAR AlternateInterfaceNumber,
UCHAR PipeIndex,
PWINUSB_PIPE_INFORMATION PipeInformation
);
typedef BOOL (WINAPI *WinUsb_ReadPipe_t)(
WINUSB_INTERFACE_HANDLE InterfaceHandle,
UCHAR PipeID,
PUCHAR Buffer,
ULONG BufferLength,
PULONG LengthTransferred,
LPOVERLAPPED Overlapped
);
typedef BOOL (WINAPI *WinUsb_ResetPipe_t)(
WINUSB_INTERFACE_HANDLE InterfaceHandle,
UCHAR PipeID
);
typedef BOOL (WINAPI *WinUsb_SetCurrentAlternateSetting_t)(
WINUSB_INTERFACE_HANDLE InterfaceHandle,
UCHAR AlternateSetting
);
typedef BOOL (WINAPI *WinUsb_SetPipePolicy_t)(
WINUSB_INTERFACE_HANDLE InterfaceHandle,
UCHAR PipeID,
ULONG PolicyType,
ULONG ValueLength,
PVOID Value
);
typedef BOOL (WINAPI *WinUsb_SetPowerPolicy_t)(
WINUSB_INTERFACE_HANDLE InterfaceHandle,
ULONG PolicyType,
ULONG ValueLength,
PVOID Value
);
typedef BOOL (WINAPI *WinUsb_WritePipe_t)(
WINUSB_INTERFACE_HANDLE InterfaceHandle,
UCHAR PipeID,
PUCHAR Buffer,
ULONG BufferLength,
PULONG LengthTransferred,
LPOVERLAPPED Overlapped
);
typedef BOOL (WINAPI *WinUsb_ResetDevice_t)(
WINUSB_INTERFACE_HANDLE InterfaceHandle
);
/* /!\ These must match the ones from the official libusbk.h */
typedef enum _KUSB_FNID {
KUSB_FNID_Init,
KUSB_FNID_Free,
KUSB_FNID_ClaimInterface,
KUSB_FNID_ReleaseInterface,
KUSB_FNID_SetAltInterface,
KUSB_FNID_GetAltInterface,
KUSB_FNID_GetDescriptor,
KUSB_FNID_ControlTransfer,
KUSB_FNID_SetPowerPolicy,
KUSB_FNID_GetPowerPolicy,
KUSB_FNID_SetConfiguration,
KUSB_FNID_GetConfiguration,
KUSB_FNID_ResetDevice,
KUSB_FNID_Initialize,
KUSB_FNID_SelectInterface,
KUSB_FNID_GetAssociatedInterface,
KUSB_FNID_Clone,
KUSB_FNID_QueryInterfaceSettings,
KUSB_FNID_QueryDeviceInformation,
KUSB_FNID_SetCurrentAlternateSetting,
KUSB_FNID_GetCurrentAlternateSetting,
KUSB_FNID_QueryPipe,
KUSB_FNID_SetPipePolicy,
KUSB_FNID_GetPipePolicy,
KUSB_FNID_ReadPipe,
KUSB_FNID_WritePipe,
KUSB_FNID_ResetPipe,
KUSB_FNID_AbortPipe,
KUSB_FNID_FlushPipe,
KUSB_FNID_IsoReadPipe,
KUSB_FNID_IsoWritePipe,
KUSB_FNID_GetCurrentFrameNumber,
KUSB_FNID_GetOverlappedResult,
KUSB_FNID_GetProperty,
KUSB_FNID_COUNT,
} KUSB_FNID;
typedef struct _KLIB_VERSION {
INT Major;
INT Minor;
INT Micro;
INT Nano;
} KLIB_VERSION;
typedef KLIB_VERSION* PKLIB_VERSION;
typedef BOOL (WINAPI *LibK_GetProcAddress_t)(
PVOID *ProcAddress,
ULONG DriverID,
ULONG FunctionID
);
typedef VOID (WINAPI *LibK_GetVersion_t)(
PKLIB_VERSION Version
);
struct winusb_interface {
bool initialized;
WinUsb_AbortPipe_t AbortPipe;
WinUsb_ControlTransfer_t ControlTransfer;
WinUsb_FlushPipe_t FlushPipe;
WinUsb_Free_t Free;
WinUsb_GetAssociatedInterface_t GetAssociatedInterface;
WinUsb_GetCurrentAlternateSetting_t GetCurrentAlternateSetting;
WinUsb_GetDescriptor_t GetDescriptor;
WinUsb_GetOverlappedResult_t GetOverlappedResult;
WinUsb_GetPipePolicy_t GetPipePolicy;
WinUsb_GetPowerPolicy_t GetPowerPolicy;
WinUsb_Initialize_t Initialize;
WinUsb_QueryDeviceInformation_t QueryDeviceInformation;
WinUsb_QueryInterfaceSettings_t QueryInterfaceSettings;
WinUsb_QueryPipe_t QueryPipe;
WinUsb_ReadPipe_t ReadPipe;
WinUsb_ResetPipe_t ResetPipe;
WinUsb_SetCurrentAlternateSetting_t SetCurrentAlternateSetting;
WinUsb_SetPipePolicy_t SetPipePolicy;
WinUsb_SetPowerPolicy_t SetPowerPolicy;
WinUsb_WritePipe_t WritePipe;
WinUsb_ResetDevice_t ResetDevice;
};
/* hid.dll interface */
#define HIDP_STATUS_SUCCESS 0x110000
typedef void * PHIDP_PREPARSED_DATA;
#pragma pack(1)
typedef struct {
ULONG Size;
USHORT VendorID;
USHORT ProductID;
USHORT VersionNumber;
} HIDD_ATTRIBUTES, *PHIDD_ATTRIBUTES;
#pragma pack()
typedef USHORT USAGE;
typedef struct {
USAGE Usage;
USAGE UsagePage;
USHORT InputReportByteLength;
USHORT OutputReportByteLength;
USHORT FeatureReportByteLength;
USHORT Reserved[17];
USHORT NumberLinkCollectionNodes;
USHORT NumberInputButtonCaps;
USHORT NumberInputValueCaps;
USHORT NumberInputDataIndices;
USHORT NumberOutputButtonCaps;
USHORT NumberOutputValueCaps;
USHORT NumberOutputDataIndices;
USHORT NumberFeatureButtonCaps;
USHORT NumberFeatureValueCaps;
USHORT NumberFeatureDataIndices;
} HIDP_CAPS, *PHIDP_CAPS;
typedef enum _HIDP_REPORT_TYPE {
HidP_Input,
HidP_Output,
HidP_Feature
} HIDP_REPORT_TYPE;
typedef struct _HIDP_VALUE_CAPS {
USAGE UsagePage;
UCHAR ReportID;
BOOLEAN IsAlias;
USHORT BitField;
USHORT LinkCollection;
USAGE LinkUsage;
USAGE LinkUsagePage;
BOOLEAN IsRange;
BOOLEAN IsStringRange;
BOOLEAN IsDesignatorRange;
BOOLEAN IsAbsolute;
BOOLEAN HasNull;
UCHAR Reserved;
USHORT BitSize;
USHORT ReportCount;
USHORT Reserved2[5];
ULONG UnitsExp;
ULONG Units;
LONG LogicalMin, LogicalMax;
LONG PhysicalMin, PhysicalMax;
union {
struct {
USAGE UsageMin, UsageMax;
USHORT StringMin, StringMax;
USHORT DesignatorMin, DesignatorMax;
USHORT DataIndexMin, DataIndexMax;
} Range;
struct {
USAGE Usage, Reserved1;
USHORT StringIndex, Reserved2;
USHORT DesignatorIndex, Reserved3;
USHORT DataIndex, Reserved4;
} NotRange;
} u;
} HIDP_VALUE_CAPS, *PHIDP_VALUE_CAPS;
DLL_DECLARE_HANDLE(hid);
DLL_DECLARE_FUNC(WINAPI, BOOL, HidD_GetAttributes, (HANDLE, PHIDD_ATTRIBUTES));
DLL_DECLARE_FUNC(WINAPI, VOID, HidD_GetHidGuid, (LPGUID));
DLL_DECLARE_FUNC(WINAPI, BOOL, HidD_GetPreparsedData, (HANDLE, PHIDP_PREPARSED_DATA *));
DLL_DECLARE_FUNC(WINAPI, BOOL, HidD_FreePreparsedData, (PHIDP_PREPARSED_DATA));
DLL_DECLARE_FUNC(WINAPI, BOOL, HidD_GetManufacturerString, (HANDLE, PVOID, ULONG));
DLL_DECLARE_FUNC(WINAPI, BOOL, HidD_GetProductString, (HANDLE, PVOID, ULONG));
DLL_DECLARE_FUNC(WINAPI, BOOL, HidD_GetSerialNumberString, (HANDLE, PVOID, ULONG));
DLL_DECLARE_FUNC(WINAPI, LONG, HidP_GetCaps, (PHIDP_PREPARSED_DATA, PHIDP_CAPS));
DLL_DECLARE_FUNC(WINAPI, BOOL, HidD_SetNumInputBuffers, (HANDLE, ULONG));
DLL_DECLARE_FUNC(WINAPI, BOOL, HidD_SetFeature, (HANDLE, PVOID, ULONG));
DLL_DECLARE_FUNC(WINAPI, BOOL, HidD_GetFeature, (HANDLE, PVOID, ULONG));
DLL_DECLARE_FUNC(WINAPI, BOOL, HidD_GetPhysicalDescriptor, (HANDLE, PVOID, ULONG));
DLL_DECLARE_FUNC(WINAPI, BOOL, HidD_GetInputReport, (HANDLE, PVOID, ULONG));
DLL_DECLARE_FUNC(WINAPI, BOOL, HidD_SetOutputReport, (HANDLE, PVOID, ULONG));
DLL_DECLARE_FUNC(WINAPI, BOOL, HidD_FlushQueue, (HANDLE));
DLL_DECLARE_FUNC(WINAPI, BOOL, HidP_GetValueCaps, (HIDP_REPORT_TYPE, PHIDP_VALUE_CAPS, PULONG, PHIDP_PREPARSED_DATA));

View File

@ -34,7 +34,7 @@
static size_t usbi_locale = 0; static size_t usbi_locale = 0;
/** \ingroup misc /** \ingroup libusb_misc
* How to add a new \ref libusb_strerror() translation: * How to add a new \ref libusb_strerror() translation:
* <ol> * <ol>
* <li> Download the latest \c strerror.c from:<br> * <li> Download the latest \c strerror.c from:<br>
@ -125,7 +125,7 @@ static const char* usbi_localized_errors[ARRAYSIZE(usbi_locale_supported)][LIBUS
} }
}; };
/** \ingroup misc /** \ingroup libusb_misc
* Set the language, and only the language, not the encoding! used for * Set the language, and only the language, not the encoding! used for
* translatable libusb messages. * translatable libusb messages.
* *
@ -176,7 +176,7 @@ int API_EXPORTED libusb_setlocale(const char *locale)
return LIBUSB_SUCCESS; return LIBUSB_SUCCESS;
} }
/** \ingroup misc /** \ingroup libusb_misc
* Returns a constant string with a short description of the given error code, * Returns a constant string with a short description of the given error code,
* this description is intended for displaying to the end user and will be in * this description is intended for displaying to the end user and will be in
* the language set by libusb_setlocale(). * the language set by libusb_setlocale().

View File

@ -27,11 +27,11 @@
#include "libusbi.h" #include "libusbi.h"
/** /**
* @defgroup syncio Synchronous device I/O * @defgroup libusb_syncio Synchronous device I/O
* *
* This page documents libusb's synchronous (blocking) API for USB device I/O. * This page documents libusb's synchronous (blocking) API for USB device I/O.
* This interface is easy to use but has some limitations. More advanced users * This interface is easy to use but has some limitations. More advanced users
* may wish to consider using the \ref asyncio "asynchronous I/O API" instead. * may wish to consider using the \ref libusb_asyncio "asynchronous I/O API" instead.
*/ */
static void LIBUSB_CALL sync_transfer_cb(struct libusb_transfer *transfer) static void LIBUSB_CALL sync_transfer_cb(struct libusb_transfer *transfer)
@ -60,7 +60,7 @@ static void sync_transfer_wait_for_completion(struct libusb_transfer *transfer)
} }
} }
/** \ingroup syncio /** \ingroup libusb_syncio
* Perform a USB control transfer. * Perform a USB control transfer.
* *
* The direction of the transfer is inferred from the bmRequestType field of * The direction of the transfer is inferred from the bmRequestType field of
@ -86,17 +86,24 @@ static void sync_transfer_wait_for_completion(struct libusb_transfer *transfer)
* \returns LIBUSB_ERROR_PIPE if the control request was not supported by the * \returns LIBUSB_ERROR_PIPE if the control request was not supported by the
* device * device
* \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected
* \returns LIBUSB_ERROR_BUSY if called from event handling context
* \returns LIBUSB_ERROR_INVALID_PARAM if the transfer size is larger than
* the operating system and/or hardware can support
* \returns another LIBUSB_ERROR code on other failures * \returns another LIBUSB_ERROR code on other failures
*/ */
int API_EXPORTED libusb_control_transfer(libusb_device_handle *dev_handle, int API_EXPORTED libusb_control_transfer(libusb_device_handle *dev_handle,
uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex,
unsigned char *data, uint16_t wLength, unsigned int timeout) unsigned char *data, uint16_t wLength, unsigned int timeout)
{ {
struct libusb_transfer *transfer = libusb_alloc_transfer(0); struct libusb_transfer *transfer;
unsigned char *buffer; unsigned char *buffer;
int completed = 0; int completed = 0;
int r; int r;
if (usbi_handling_events(HANDLE_CTX(dev_handle)))
return LIBUSB_ERROR_BUSY;
transfer = libusb_alloc_transfer(0);
if (!transfer) if (!transfer)
return LIBUSB_ERROR_NO_MEM; return LIBUSB_ERROR_NO_MEM;
@ -160,10 +167,14 @@ static int do_sync_bulk_transfer(struct libusb_device_handle *dev_handle,
unsigned char endpoint, unsigned char *buffer, int length, unsigned char endpoint, unsigned char *buffer, int length,
int *transferred, unsigned int timeout, unsigned char type) int *transferred, unsigned int timeout, unsigned char type)
{ {
struct libusb_transfer *transfer = libusb_alloc_transfer(0); struct libusb_transfer *transfer;
int completed = 0; int completed = 0;
int r; int r;
if (usbi_handling_events(HANDLE_CTX(dev_handle)))
return LIBUSB_ERROR_BUSY;
transfer = libusb_alloc_transfer(0);
if (!transfer) if (!transfer)
return LIBUSB_ERROR_NO_MEM; return LIBUSB_ERROR_NO_MEM;
@ -179,7 +190,9 @@ static int do_sync_bulk_transfer(struct libusb_device_handle *dev_handle,
sync_transfer_wait_for_completion(transfer); sync_transfer_wait_for_completion(transfer);
if (transferred)
*transferred = transfer->actual_length; *transferred = transfer->actual_length;
switch (transfer->status) { switch (transfer->status) {
case LIBUSB_TRANSFER_COMPLETED: case LIBUSB_TRANSFER_COMPLETED:
r = 0; r = 0;
@ -210,7 +223,7 @@ static int do_sync_bulk_transfer(struct libusb_device_handle *dev_handle,
return r; return r;
} }
/** \ingroup syncio /** \ingroup libusb_syncio
* Perform a USB bulk transfer. The direction of the transfer is inferred from * Perform a USB bulk transfer. The direction of the transfer is inferred from
* the direction bits of the endpoint address. * the direction bits of the endpoint address.
* *
@ -236,7 +249,9 @@ static int do_sync_bulk_transfer(struct libusb_device_handle *dev_handle,
* \param length for bulk writes, the number of bytes from data to be sent. for * \param length for bulk writes, the number of bytes from data to be sent. for
* bulk reads, the maximum number of bytes to receive into the data buffer. * bulk reads, the maximum number of bytes to receive into the data buffer.
* \param transferred output location for the number of bytes actually * \param transferred output location for the number of bytes actually
* transferred. * transferred. Since version 1.0.21 (\ref LIBUSB_API_VERSION >= 0x01000105),
* it is legal to pass a NULL pointer if you do not wish to receive this
* information.
* \param timeout timeout (in millseconds) that this function should wait * \param timeout timeout (in millseconds) that this function should wait
* before giving up due to no response being received. For an unlimited * before giving up due to no response being received. For an unlimited
* timeout, use value 0. * timeout, use value 0.
@ -246,8 +261,9 @@ static int do_sync_bulk_transfer(struct libusb_device_handle *dev_handle,
* <tt>transferred</tt>) * <tt>transferred</tt>)
* \returns LIBUSB_ERROR_PIPE if the endpoint halted * \returns LIBUSB_ERROR_PIPE if the endpoint halted
* \returns LIBUSB_ERROR_OVERFLOW if the device offered more data, see * \returns LIBUSB_ERROR_OVERFLOW if the device offered more data, see
* \ref packetoverflow * \ref libusb_packetoverflow
* \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected
* \returns LIBUSB_ERROR_BUSY if called from event handling context
* \returns another LIBUSB_ERROR code on other failures * \returns another LIBUSB_ERROR code on other failures
*/ */
int API_EXPORTED libusb_bulk_transfer(struct libusb_device_handle *dev_handle, int API_EXPORTED libusb_bulk_transfer(struct libusb_device_handle *dev_handle,
@ -258,7 +274,7 @@ int API_EXPORTED libusb_bulk_transfer(struct libusb_device_handle *dev_handle,
transferred, timeout, LIBUSB_TRANSFER_TYPE_BULK); transferred, timeout, LIBUSB_TRANSFER_TYPE_BULK);
} }
/** \ingroup syncio /** \ingroup libusb_syncio
* Perform a USB interrupt transfer. The direction of the transfer is inferred * Perform a USB interrupt transfer. The direction of the transfer is inferred
* from the direction bits of the endpoint address. * from the direction bits of the endpoint address.
* *
@ -286,7 +302,9 @@ int API_EXPORTED libusb_bulk_transfer(struct libusb_device_handle *dev_handle,
* \param length for bulk writes, the number of bytes from data to be sent. for * \param length for bulk writes, the number of bytes from data to be sent. for
* bulk reads, the maximum number of bytes to receive into the data buffer. * bulk reads, the maximum number of bytes to receive into the data buffer.
* \param transferred output location for the number of bytes actually * \param transferred output location for the number of bytes actually
* transferred. * transferred. Since version 1.0.21 (\ref LIBUSB_API_VERSION >= 0x01000105),
* it is legal to pass a NULL pointer if you do not wish to receive this
* information.
* \param timeout timeout (in millseconds) that this function should wait * \param timeout timeout (in millseconds) that this function should wait
* before giving up due to no response being received. For an unlimited * before giving up due to no response being received. For an unlimited
* timeout, use value 0. * timeout, use value 0.
@ -295,8 +313,9 @@ int API_EXPORTED libusb_bulk_transfer(struct libusb_device_handle *dev_handle,
* \returns LIBUSB_ERROR_TIMEOUT if the transfer timed out * \returns LIBUSB_ERROR_TIMEOUT if the transfer timed out
* \returns LIBUSB_ERROR_PIPE if the endpoint halted * \returns LIBUSB_ERROR_PIPE if the endpoint halted
* \returns LIBUSB_ERROR_OVERFLOW if the device offered more data, see * \returns LIBUSB_ERROR_OVERFLOW if the device offered more data, see
* \ref packetoverflow * \ref libusb_packetoverflow
* \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected
* \returns LIBUSB_ERROR_BUSY if called from event handling context
* \returns another LIBUSB_ERROR code on other error * \returns another LIBUSB_ERROR code on other error
*/ */
int API_EXPORTED libusb_interrupt_transfer( int API_EXPORTED libusb_interrupt_transfer(

View File

@ -7,7 +7,7 @@
#define LIBUSB_MINOR 0 #define LIBUSB_MINOR 0
#endif #endif
#ifndef LIBUSB_MICRO #ifndef LIBUSB_MICRO
#define LIBUSB_MICRO 20 #define LIBUSB_MICRO 21
#endif #endif
#ifndef LIBUSB_NANO #ifndef LIBUSB_NANO
#define LIBUSB_NANO 0 #define LIBUSB_NANO 0

View File

@ -1 +1 @@
#define LIBUSB_NANO 11004 #define LIBUSB_NANO 11156

View File

@ -48,21 +48,24 @@
<ClCompile Include="libusb\hotplug.c" /> <ClCompile Include="libusb\hotplug.c" />
<ClCompile Include="libusb\io.c" /> <ClCompile Include="libusb\io.c" />
<ClCompile Include="libusb\os\poll_windows.c" /> <ClCompile Include="libusb\os\poll_windows.c" />
<ClCompile Include="libusb\os\threads_windows.c" /> <ClCompile Include="libusb\strerror.c" />
<ClCompile Include="libusb\os\windows_usb.c" />
<ClCompile Include="libusb\sync.c" /> <ClCompile Include="libusb\sync.c" />
<ClCompile Include="libusb\os\threads_windows.c" />
<ClCompile Include="libusb\os\windows_nt_common.c" />
<ClCompile Include="libusb\os\windows_winusb.c" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="msvc\config.h" />
<ClInclude Include="libusb\hotplug.h" /> <ClInclude Include="libusb\hotplug.h" />
<ClInclude Include="libusb\libusb.h" /> <ClInclude Include="libusb\libusb.h" />
<ClInclude Include="libusb\libusbi.h" /> <ClInclude Include="libusb\libusbi.h" />
<ClInclude Include="libusb\os\poll_windows.h" /> <ClInclude Include="libusb\os\poll_windows.h" />
<ClInclude Include="libusb\os\threads_windows.h" /> <ClInclude Include="libusb\os\threads_windows.h" />
<ClInclude Include="libusb\os\windows_common.h" />
<ClInclude Include="libusb\os\windows_usb.h" />
<ClInclude Include="libusb\version.h" /> <ClInclude Include="libusb\version.h" />
<ClInclude Include="libusb\version_nano.h" /> <ClInclude Include="libusb\version_nano.h" />
<ClInclude Include="msvc\config.h" /> <ClInclude Include="libusb\os\windows_common.h" />
<ClInclude Include="libusb\os\windows_nt_common.h" />
<ClInclude Include="libusb\os\windows_winusb.h" />
</ItemGroup> </ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets"> <ImportGroup Label="ExtensionTargets">

28
Externals/libusb/msvc/appveyor.bat vendored Normal file
View File

@ -0,0 +1,28 @@
echo on
SetLocal EnableDelayedExpansion
if [%Configuration%] NEQ [Debug] goto releasex64
if [%Configuration%] NEQ [Release] goto debugx64
:debugx64
if [%Platform%] NEQ [x64] goto debugWin32
if [%Configuration%] NEQ [Debug] exit 0
call "C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.cmd" /Debug /x64
msbuild %libusb_2010% /p:Configuration=Debug,Platform=x64 /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
:releasex64
if [%Platform%] NEQ [x64] goto releaseWin32
if [%Configuration%] NEQ [Release] exit 0
call "C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.cmd" /Release /x64
msbuild %libusb_2010% /p:Configuration=Release,Platform=x64 /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
:debugWin32
if [%Platform%] NEQ [Win32] exit 0
if [%Configuration%] NEQ [Debug] exit 0
msbuild %libusb_2010% /p:Configuration=Debug,Platform=Win32 /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
:releaseWin32
if [%Platform%] NEQ [Win32] exit 0
if [%Configuration%] NEQ [Release] exit 0
msbuild %libusb_2010% /p:Configuration=Release,Platform=Win32 /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"

View File

@ -5,10 +5,18 @@
#error "Please make sure the msvc/ directory is removed from your build path." #error "Please make sure the msvc/ directory is removed from your build path."
#endif #endif
/* Visual Studio 2015 and later defines timespec */
#if defined(_MSC_VER) && (_MSC_VER >= 1900)
#define _TIMESPEC_DEFINED 1
#endif
/* Disable: warning C4200: nonstandard extension used : zero-sized array in struct/union */ /* Disable: warning C4200: nonstandard extension used : zero-sized array in struct/union */
#pragma warning(disable:4200) #pragma warning(disable:4200)
/* Disable: warning C6258: Using TerminateThread does not allow proper thread clean up */ /* Disable: warning C6258: Using TerminateThread does not allow proper thread clean up */
#pragma warning(disable: 6258) #pragma warning(disable: 6258)
/* Disable: warning C4996: 'GetVersionA': was declared deprecated */
#pragma warning(disable: 4996)
#if defined(_PREFAST_) #if defined(_PREFAST_)
/* Disable "Banned API" errors when using the MS's WDK OACR/Prefast */ /* Disable "Banned API" errors when using the MS's WDK OACR/Prefast */
#pragma warning(disable:28719) #pragma warning(disable:28719)

View File

@ -3,20 +3,29 @@
::# you can pass the following arguments (case insensitive): ::# you can pass the following arguments (case insensitive):
::# - "DLL" to build a DLL instead of a static library ::# - "DLL" to build a DLL instead of a static library
::# - "/MT" to build a static library compatible with MSVC's /MT option (LIBCMT vs MSVCRT) ::# - "/MT" to build a static library compatible with MSVC's /MT option (LIBCMT vs MSVCRT)
::# - "USBDK" to build with UsbDk backend
if Test%BUILD_ALT_DIR%==Test goto usage if Test%BUILD_ALT_DIR%==Test goto usage
::# process commandline parameters ::# process commandline parameters
set TARGET=LIBRARY set TARGET=LIBRARY
set STATIC_LIBC= set STATIC_LIBC=
set WITH_USBDK=
set version=1.0 set version=1.0
set PWD=%~dp0 set PWD=%~dp0
set BUILD_CMD=build -bcwgZ -M2 set BUILD_CMD=build -bcwgZ -M2
:more_args
if "%1" == "" goto no_more_args if "%1" == "" goto no_more_args
::# /I for case insensitive ::# /I for case insensitive
if /I Test%1==TestDLL set TARGET=DYNLINK if /I Test%1==TestDLL set TARGET=DYNLINK
if /I Test%1==Test/MT set STATIC_LIBC=1 if /I Test%1==Test/MT set STATIC_LIBC=1
if /I Test%1==TestUSBDK set WITH_USBDK=1
shift
goto more_args
:no_more_args :no_more_args
cd ..\libusb\os cd ..\libusb\os

View File

@ -0,0 +1,174 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectName>fxload</ProjectName>
<ProjectGuid>{9E166F7A-A793-9FB6-0A67-F0AED8AE8C88}</ProjectGuid>
<RootNamespace>examples</RootNamespace>
<Keyword>Win32Proj</Keyword>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)..\$(Platform)\$(Configuration)\examples\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)..\$(Platform)\$(Configuration)\examples\$(ProjectName)\</IntDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)..\$(Platform)\$(Configuration)\examples\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)..\$(Platform)\$(Configuration)\examples\$(ProjectName)\</IntDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)..\$(Platform)\$(Configuration)\examples\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)..\$(Platform)\$(Configuration)\examples\$(ProjectName)\</IntDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)..\$(Platform)\$(Configuration)\examples\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)..\$(Platform)\$(Configuration)\examples\$(ProjectName)\</IntDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<BuildLog>
<Path>$(IntDir)$(ProjectName).htm</Path>
</BuildLog>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>.;..\examples\getopt;..\libusb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;__GNU_LIBRARY__;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<BuildLog>
<Path>$(IntDir)$(ProjectName).htm</Path>
</BuildLog>
<Midl>
<TargetEnvironment>X64</TargetEnvironment>
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>.;..\examples\getopt;..\libusb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;__GNU_LIBRARY__;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<TargetMachine>MachineX64</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<BuildLog>
<Path>$(IntDir)$(ProjectName).htm</Path>
</BuildLog>
<ClCompile>
<AdditionalIncludeDirectories>.;..\examples\getopt;..\libusb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;__GNU_LIBRARY__;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<SubSystem>Console</SubSystem>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<BuildLog>
<Path>$(IntDir)$(ProjectName).htm</Path>
</BuildLog>
<Midl>
<TargetEnvironment>X64</TargetEnvironment>
</Midl>
<ClCompile>
<AdditionalIncludeDirectories>.;..\examples\getopt;..\libusb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;__GNU_LIBRARY__;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<SubSystem>Console</SubSystem>
<TargetMachine>MachineX64</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\examples\ezusb.c" />
<ClCompile Include="..\examples\fxload.c" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include=".\libusb_static_2015.vcxproj">
<Project>{349ee8f9-7d25-4909-aaf5-ff3fade72187}</Project>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
<ProjectReference Include="getopt_2015.vcxproj">
<Project>{ae83e1b4-ce06-47ee-b7a3-c3a1d7c2d71e}</Project>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\examples\ezusb.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,136 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{AE83E1B4-CE06-47EE-B7A3-C3A1D7C2D71E}</ProjectGuid>
<RootNamespace>getopt</RootNamespace>
<ProjectName>getopt</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)..\$(Platform)\$(Configuration)\lib\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)..\$(Platform)\$(Configuration)\lib\getopt\</IntDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)..\$(Platform)\$(Configuration)\lib\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)..\$(Platform)\$(Configuration)\lib\getopt\</IntDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)..\$(Platform)\$(Configuration)\lib\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)..\$(Platform)\$(Configuration)\lib\getopt\</IntDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)..\$(Platform)\$(Configuration)\lib\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)..\$(Platform)\$(Configuration)\lib\getopt\</IntDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PreprocessorDefinitions>HAVE_STRING_H;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Lib>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Midl>
<TargetEnvironment>X64</TargetEnvironment>
</Midl>
<ClCompile>
<PreprocessorDefinitions>HAVE_STRING_H;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Lib>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<PreprocessorDefinitions>HAVE_STRING_H;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
</ClCompile>
<Lib>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Midl>
<TargetEnvironment>X64</TargetEnvironment>
</Midl>
<ClCompile>
<PreprocessorDefinitions>HAVE_STRING_H;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
</ClCompile>
<Lib>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
</Lib>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\examples\getopt\getopt.c" />
<ClCompile Include="..\examples\getopt\getopt1.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\examples\getopt\getopt.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,167 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectName>hotplugtest</ProjectName>
<ProjectGuid>{99D2AC64-DC66-4422-91CE-6715C403C9E5}</ProjectGuid>
<RootNamespace>examples</RootNamespace>
<Keyword>Win32Proj</Keyword>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)..\$(Platform)\$(Configuration)\examples\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)..\$(Platform)\$(Configuration)\examples\$(ProjectName)\</IntDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)..\$(Platform)\$(Configuration)\examples\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)..\$(Platform)\$(Configuration)\examples\$(ProjectName)\</IntDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)..\$(Platform)\$(Configuration)\examples\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)..\$(Platform)\$(Configuration)\examples\$(ProjectName)\</IntDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)..\$(Platform)\$(Configuration)\examples\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)..\$(Platform)\$(Configuration)\examples\$(ProjectName)\</IntDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<BuildLog>
<Path>$(IntDir)$(ProjectName).htm</Path>
</BuildLog>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>.;..\libusb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<BuildLog>
<Path>$(IntDir)$(ProjectName).htm</Path>
</BuildLog>
<Midl>
<TargetEnvironment>X64</TargetEnvironment>
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>.;..\libusb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<TargetMachine>MachineX64</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<BuildLog>
<Path>$(IntDir)$(ProjectName).htm</Path>
</BuildLog>
<ClCompile>
<AdditionalIncludeDirectories>.;..\libusb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<SubSystem>Console</SubSystem>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<BuildLog>
<Path>$(IntDir)$(ProjectName).htm</Path>
</BuildLog>
<Midl>
<TargetEnvironment>X64</TargetEnvironment>
</Midl>
<ClCompile>
<AdditionalIncludeDirectories>.;..\libusb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<SubSystem>Console</SubSystem>
<TargetMachine>MachineX64</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\examples\hotplugtest.c" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include=".\libusb_static_2015.vcxproj">
<Project>{349ee8f9-7d25-4909-aaf5-ff3fade72187}</Project>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -21,6 +21,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "stress", "stress_2013.vcxpr
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hotplugtest", "hotplugtest_2013.vcxproj", "{99D2AC64-DC66-4422-91CE-6715C403C9E5}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hotplugtest", "hotplugtest_2013.vcxproj", "{99D2AC64-DC66-4422-91CE-6715C403C9E5}"
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libusb-usbdk-1.0 (dll)", "libusb_usbdk_dll_2013.vcxproj", "{F53A5974-2319-48EB-A67B-27933AEDF14A}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libusb-usbdk-1.0 (static)", "libusb_usbdk_static_2013.vcxproj", "{0B3D86CF-5D70-41A9-B391-A2E7C5C969ED}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32 Debug|Win32 = Debug|Win32
@ -93,6 +97,22 @@ Global
{99D2AC64-DC66-4422-91CE-6715C403C9E5}.Release|Win32.Build.0 = Release|Win32 {99D2AC64-DC66-4422-91CE-6715C403C9E5}.Release|Win32.Build.0 = Release|Win32
{99D2AC64-DC66-4422-91CE-6715C403C9E5}.Release|x64.ActiveCfg = Release|x64 {99D2AC64-DC66-4422-91CE-6715C403C9E5}.Release|x64.ActiveCfg = Release|x64
{99D2AC64-DC66-4422-91CE-6715C403C9E5}.Release|x64.Build.0 = Release|x64 {99D2AC64-DC66-4422-91CE-6715C403C9E5}.Release|x64.Build.0 = Release|x64
{F53A5974-2319-48EB-A67B-27933AEDF14A}.Debug|Win32.ActiveCfg = Debug|Win32
{F53A5974-2319-48EB-A67B-27933AEDF14A}.Debug|Win32.Build.0 = Debug|Win32
{F53A5974-2319-48EB-A67B-27933AEDF14A}.Debug|x64.ActiveCfg = Debug|x64
{F53A5974-2319-48EB-A67B-27933AEDF14A}.Debug|x64.Build.0 = Debug|x64
{F53A5974-2319-48EB-A67B-27933AEDF14A}.Release|Win32.ActiveCfg = Release|Win32
{F53A5974-2319-48EB-A67B-27933AEDF14A}.Release|Win32.Build.0 = Release|Win32
{F53A5974-2319-48EB-A67B-27933AEDF14A}.Release|x64.ActiveCfg = Release|x64
{F53A5974-2319-48EB-A67B-27933AEDF14A}.Release|x64.Build.0 = Release|x64
{0B3D86CF-5D70-41A9-B391-A2E7C5C969ED}.Debug|Win32.ActiveCfg = Debug|Win32
{0B3D86CF-5D70-41A9-B391-A2E7C5C969ED}.Debug|Win32.Build.0 = Debug|Win32
{0B3D86CF-5D70-41A9-B391-A2E7C5C969ED}.Debug|x64.ActiveCfg = Debug|x64
{0B3D86CF-5D70-41A9-B391-A2E7C5C969ED}.Debug|x64.Build.0 = Debug|x64
{0B3D86CF-5D70-41A9-B391-A2E7C5C969ED}.Release|Win32.ActiveCfg = Release|Win32
{0B3D86CF-5D70-41A9-B391-A2E7C5C969ED}.Release|Win32.Build.0 = Release|Win32
{0B3D86CF-5D70-41A9-B391-A2E7C5C969ED}.Release|x64.ActiveCfg = Release|x64
{0B3D86CF-5D70-41A9-B391-A2E7C5C969ED}.Release|x64.Build.0 = Release|x64
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

120
Externals/libusb/msvc/libusb_2015.sln vendored Normal file
View File

@ -0,0 +1,120 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.24720.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libusb-1.0 (static)", "libusb_static_2015.vcxproj", "{349EE8F9-7D25-4909-AAF5-FF3FADE72187}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libusb-1.0 (dll)", "libusb_dll_2015.vcxproj", "{349EE8FA-7D25-4909-AAF5-FF3FADE72187}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "listdevs", "listdevs_2015.vcxproj", "{F4938DB0-3DE7-4737-9C5A-EAD1BE819F87}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xusb", "xusb_2015.vcxproj", "{3F3138D0-7AB7-4268-9BF3-1A3EA5503A11}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fxload", "fxload_2015.vcxproj", "{9E166F7A-A793-9FB6-0A67-F0AED8AE8C88}"
ProjectSection(ProjectDependencies) = postProject
{AE83E1B4-CE06-47EE-B7A3-C3A1D7C2D71E} = {AE83E1B4-CE06-47EE-B7A3-C3A1D7C2D71E}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "getopt", "getopt_2015.vcxproj", "{AE83E1B4-CE06-47EE-B7A3-C3A1D7C2D71E}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "stress", "stress_2015.vcxproj", "{53942EFF-C810-458D-B3CB-EE5CE9F1E781}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hotplugtest", "hotplugtest_2015.vcxproj", "{99D2AC64-DC66-4422-91CE-6715C403C9E5}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libusb-usbdk-1.0 (dll)", "libusb_usbdk_dll_2015.vcxproj", "{F53A5974-2319-48EB-A67B-27933AEDF14A}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libusb-usbdk-1.0 (static)", "libusb_usbdk_static_2015.vcxproj", "{0B3D86CF-5D70-41A9-B391-A2E7C5C969ED}"
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
{349EE8F9-7D25-4909-AAF5-FF3FADE72187}.Debug|Win32.ActiveCfg = Debug|Win32
{349EE8F9-7D25-4909-AAF5-FF3FADE72187}.Debug|Win32.Build.0 = Debug|Win32
{349EE8F9-7D25-4909-AAF5-FF3FADE72187}.Debug|x64.ActiveCfg = Debug|x64
{349EE8F9-7D25-4909-AAF5-FF3FADE72187}.Debug|x64.Build.0 = Debug|x64
{349EE8F9-7D25-4909-AAF5-FF3FADE72187}.Release|Win32.ActiveCfg = Release|Win32
{349EE8F9-7D25-4909-AAF5-FF3FADE72187}.Release|Win32.Build.0 = Release|Win32
{349EE8F9-7D25-4909-AAF5-FF3FADE72187}.Release|x64.ActiveCfg = Release|x64
{349EE8F9-7D25-4909-AAF5-FF3FADE72187}.Release|x64.Build.0 = Release|x64
{349EE8FA-7D25-4909-AAF5-FF3FADE72187}.Debug|Win32.ActiveCfg = Debug|Win32
{349EE8FA-7D25-4909-AAF5-FF3FADE72187}.Debug|Win32.Build.0 = Debug|Win32
{349EE8FA-7D25-4909-AAF5-FF3FADE72187}.Debug|x64.ActiveCfg = Debug|x64
{349EE8FA-7D25-4909-AAF5-FF3FADE72187}.Debug|x64.Build.0 = Debug|x64
{349EE8FA-7D25-4909-AAF5-FF3FADE72187}.Release|Win32.ActiveCfg = Release|Win32
{349EE8FA-7D25-4909-AAF5-FF3FADE72187}.Release|Win32.Build.0 = Release|Win32
{349EE8FA-7D25-4909-AAF5-FF3FADE72187}.Release|x64.ActiveCfg = Release|x64
{349EE8FA-7D25-4909-AAF5-FF3FADE72187}.Release|x64.Build.0 = Release|x64
{F4938DB0-3DE7-4737-9C5A-EAD1BE819F87}.Debug|Win32.ActiveCfg = Debug|Win32
{F4938DB0-3DE7-4737-9C5A-EAD1BE819F87}.Debug|Win32.Build.0 = Debug|Win32
{F4938DB0-3DE7-4737-9C5A-EAD1BE819F87}.Debug|x64.ActiveCfg = Debug|x64
{F4938DB0-3DE7-4737-9C5A-EAD1BE819F87}.Debug|x64.Build.0 = Debug|x64
{F4938DB0-3DE7-4737-9C5A-EAD1BE819F87}.Release|Win32.ActiveCfg = Release|Win32
{F4938DB0-3DE7-4737-9C5A-EAD1BE819F87}.Release|Win32.Build.0 = Release|Win32
{F4938DB0-3DE7-4737-9C5A-EAD1BE819F87}.Release|x64.ActiveCfg = Release|x64
{F4938DB0-3DE7-4737-9C5A-EAD1BE819F87}.Release|x64.Build.0 = Release|x64
{3F3138D0-7AB7-4268-9BF3-1A3EA5503A11}.Debug|Win32.ActiveCfg = Debug|Win32
{3F3138D0-7AB7-4268-9BF3-1A3EA5503A11}.Debug|Win32.Build.0 = Debug|Win32
{3F3138D0-7AB7-4268-9BF3-1A3EA5503A11}.Debug|x64.ActiveCfg = Debug|x64
{3F3138D0-7AB7-4268-9BF3-1A3EA5503A11}.Debug|x64.Build.0 = Debug|x64
{3F3138D0-7AB7-4268-9BF3-1A3EA5503A11}.Release|Win32.ActiveCfg = Release|Win32
{3F3138D0-7AB7-4268-9BF3-1A3EA5503A11}.Release|Win32.Build.0 = Release|Win32
{3F3138D0-7AB7-4268-9BF3-1A3EA5503A11}.Release|x64.ActiveCfg = Release|x64
{3F3138D0-7AB7-4268-9BF3-1A3EA5503A11}.Release|x64.Build.0 = Release|x64
{9E166F7A-A793-9FB6-0A67-F0AED8AE8C88}.Debug|Win32.ActiveCfg = Debug|Win32
{9E166F7A-A793-9FB6-0A67-F0AED8AE8C88}.Debug|Win32.Build.0 = Debug|Win32
{9E166F7A-A793-9FB6-0A67-F0AED8AE8C88}.Debug|x64.ActiveCfg = Debug|x64
{9E166F7A-A793-9FB6-0A67-F0AED8AE8C88}.Debug|x64.Build.0 = Debug|x64
{9E166F7A-A793-9FB6-0A67-F0AED8AE8C88}.Release|Win32.ActiveCfg = Release|Win32
{9E166F7A-A793-9FB6-0A67-F0AED8AE8C88}.Release|Win32.Build.0 = Release|Win32
{9E166F7A-A793-9FB6-0A67-F0AED8AE8C88}.Release|x64.ActiveCfg = Release|x64
{9E166F7A-A793-9FB6-0A67-F0AED8AE8C88}.Release|x64.Build.0 = Release|x64
{AE83E1B4-CE06-47EE-B7A3-C3A1D7C2D71E}.Debug|Win32.ActiveCfg = Debug|Win32
{AE83E1B4-CE06-47EE-B7A3-C3A1D7C2D71E}.Debug|Win32.Build.0 = Debug|Win32
{AE83E1B4-CE06-47EE-B7A3-C3A1D7C2D71E}.Debug|x64.ActiveCfg = Debug|x64
{AE83E1B4-CE06-47EE-B7A3-C3A1D7C2D71E}.Debug|x64.Build.0 = Debug|x64
{AE83E1B4-CE06-47EE-B7A3-C3A1D7C2D71E}.Release|Win32.ActiveCfg = Release|Win32
{AE83E1B4-CE06-47EE-B7A3-C3A1D7C2D71E}.Release|Win32.Build.0 = Release|Win32
{AE83E1B4-CE06-47EE-B7A3-C3A1D7C2D71E}.Release|x64.ActiveCfg = Release|x64
{AE83E1B4-CE06-47EE-B7A3-C3A1D7C2D71E}.Release|x64.Build.0 = Release|x64
{53942EFF-C810-458D-B3CB-EE5CE9F1E781}.Debug|Win32.ActiveCfg = Debug|Win32
{53942EFF-C810-458D-B3CB-EE5CE9F1E781}.Debug|Win32.Build.0 = Debug|Win32
{53942EFF-C810-458D-B3CB-EE5CE9F1E781}.Debug|x64.ActiveCfg = Debug|x64
{53942EFF-C810-458D-B3CB-EE5CE9F1E781}.Debug|x64.Build.0 = Debug|x64
{53942EFF-C810-458D-B3CB-EE5CE9F1E781}.Release|Win32.ActiveCfg = Release|Win32
{53942EFF-C810-458D-B3CB-EE5CE9F1E781}.Release|Win32.Build.0 = Release|Win32
{53942EFF-C810-458D-B3CB-EE5CE9F1E781}.Release|x64.ActiveCfg = Release|x64
{53942EFF-C810-458D-B3CB-EE5CE9F1E781}.Release|x64.Build.0 = Release|x64
{99D2AC64-DC66-4422-91CE-6715C403C9E5}.Debug|Win32.ActiveCfg = Debug|Win32
{99D2AC64-DC66-4422-91CE-6715C403C9E5}.Debug|Win32.Build.0 = Debug|Win32
{99D2AC64-DC66-4422-91CE-6715C403C9E5}.Debug|x64.ActiveCfg = Debug|x64
{99D2AC64-DC66-4422-91CE-6715C403C9E5}.Debug|x64.Build.0 = Debug|x64
{99D2AC64-DC66-4422-91CE-6715C403C9E5}.Release|Win32.ActiveCfg = Release|Win32
{99D2AC64-DC66-4422-91CE-6715C403C9E5}.Release|Win32.Build.0 = Release|Win32
{99D2AC64-DC66-4422-91CE-6715C403C9E5}.Release|x64.ActiveCfg = Release|x64
{99D2AC64-DC66-4422-91CE-6715C403C9E5}.Release|x64.Build.0 = Release|x64
{F53A5974-2319-48EB-A67B-27933AEDF14A}.Debug|Win32.ActiveCfg = Debug|Win32
{F53A5974-2319-48EB-A67B-27933AEDF14A}.Debug|Win32.Build.0 = Debug|Win32
{F53A5974-2319-48EB-A67B-27933AEDF14A}.Debug|x64.ActiveCfg = Debug|x64
{F53A5974-2319-48EB-A67B-27933AEDF14A}.Debug|x64.Build.0 = Debug|x64
{F53A5974-2319-48EB-A67B-27933AEDF14A}.Release|Win32.ActiveCfg = Release|Win32
{F53A5974-2319-48EB-A67B-27933AEDF14A}.Release|Win32.Build.0 = Release|Win32
{F53A5974-2319-48EB-A67B-27933AEDF14A}.Release|x64.ActiveCfg = Release|x64
{F53A5974-2319-48EB-A67B-27933AEDF14A}.Release|x64.Build.0 = Release|x64
{0B3D86CF-5D70-41A9-B391-A2E7C5C969ED}.Debug|Win32.ActiveCfg = Debug|Win32
{0B3D86CF-5D70-41A9-B391-A2E7C5C969ED}.Debug|Win32.Build.0 = Debug|Win32
{0B3D86CF-5D70-41A9-B391-A2E7C5C969ED}.Debug|x64.ActiveCfg = Debug|x64
{0B3D86CF-5D70-41A9-B391-A2E7C5C969ED}.Debug|x64.Build.0 = Debug|x64
{0B3D86CF-5D70-41A9-B391-A2E7C5C969ED}.Release|Win32.ActiveCfg = Release|Win32
{0B3D86CF-5D70-41A9-B391-A2E7C5C969ED}.Release|Win32.Build.0 = Release|Win32
{0B3D86CF-5D70-41A9-B391-A2E7C5C969ED}.Release|x64.ActiveCfg = Release|x64
{0B3D86CF-5D70-41A9-B391-A2E7C5C969ED}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -135,7 +135,7 @@ SOURCE=..\libusb\os\threads_windows.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\libusb\os\windows_usb.c SOURCE=..\libusb\os\windows_winusb.c
# End Source File # End Source File
# End Group # End Group
# Begin Group "Header Files" # Begin Group "Header Files"
@ -179,7 +179,7 @@ SOURCE=..\libusb\os\threads_windows.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\libusb\os\windows_usb.h SOURCE=..\libusb\os\windows_winusb.h
# End Source File # End Source File
# Begin Source File # Begin Source File

View File

@ -374,7 +374,7 @@
> >
</File> </File>
<File <File
RelativePath="..\libusb\os\windows_usb.c" RelativePath="..\libusb\os\windows_winusb.c"
> >
</File> </File>
</Filter> </Filter>
@ -408,7 +408,7 @@
> >
</File> </File>
<File <File
RelativePath="..\libusb\os\windows_usb.h" RelativePath="..\libusb\os\windows_winusb.h"
> >
</File> </File>
<File <File

View File

@ -146,7 +146,8 @@
<ClCompile Include="..\libusb\strerror.c" /> <ClCompile Include="..\libusb\strerror.c" />
<ClCompile Include="..\libusb\sync.c" /> <ClCompile Include="..\libusb\sync.c" />
<ClCompile Include="..\libusb\os\threads_windows.c" /> <ClCompile Include="..\libusb\os\threads_windows.c" />
<ClCompile Include="..\libusb\os\windows_usb.c" /> <ClCompile Include="..\libusb\os\windows_nt_common.c" />
<ClCompile Include="..\libusb\os\windows_winusb.c" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include=".\config.h" /> <ClInclude Include=".\config.h" />
@ -155,8 +156,11 @@
<ClInclude Include="..\libusb\libusbi.h" /> <ClInclude Include="..\libusb\libusbi.h" />
<ClInclude Include="..\libusb\os\poll_windows.h" /> <ClInclude Include="..\libusb\os\poll_windows.h" />
<ClInclude Include="..\libusb\os\threads_windows.h" /> <ClInclude Include="..\libusb\os\threads_windows.h" />
<ClInclude Include="..\libusb\os\windows_usb.h" /> <ClInclude Include="..\libusb\version.h" />
<ClInclude Include="..\libusb\version_nano.h" />
<ClInclude Include="..\libusb\os\windows_common.h" /> <ClInclude Include="..\libusb\os\windows_common.h" />
<ClInclude Include="..\libusb\os\windows_nt_common.h" />
<ClInclude Include="..\libusb\os\windows_winusb.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\libusb\libusb-1.0.def" /> <None Include="..\libusb\libusb-1.0.def" />

View File

@ -38,7 +38,7 @@
<ClCompile Include="..\libusb\os\threads_windows.c"> <ClCompile Include="..\libusb\os\threads_windows.c">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\libusb\os\windows_usb.c"> <ClCompile Include="..\libusb\os\windows_winusb.c">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
</ItemGroup> </ItemGroup>
@ -61,7 +61,7 @@
<ClInclude Include="..\libusb\os\threads_windows.h"> <ClInclude Include="..\libusb\os\threads_windows.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\libusb\os\windows_usb.h"> <ClInclude Include="..\libusb\os\windows_winusb.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\libusb\os\windows_common.h"> <ClInclude Include="..\libusb\os\windows_common.h">

View File

@ -150,18 +150,21 @@
<ClCompile Include="..\libusb\strerror.c" /> <ClCompile Include="..\libusb\strerror.c" />
<ClCompile Include="..\libusb\sync.c" /> <ClCompile Include="..\libusb\sync.c" />
<ClCompile Include="..\libusb\os\threads_windows.c" /> <ClCompile Include="..\libusb\os\threads_windows.c" />
<ClCompile Include="..\libusb\os\windows_usb.c" /> <ClCompile Include="..\libusb\os\windows_nt_common.c" />
<ClCompile Include="..\libusb\os\windows_winusb.c" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\libusb\hotplug.h" />
<ClInclude Include="..\libusb\version.h" />
<ClInclude Include="..\libusb\version_nano.h" />
<ClInclude Include=".\config.h" /> <ClInclude Include=".\config.h" />
<ClInclude Include="..\libusb\hotplug.h" />
<ClInclude Include="..\libusb\libusb.h" /> <ClInclude Include="..\libusb\libusb.h" />
<ClInclude Include="..\libusb\libusbi.h" /> <ClInclude Include="..\libusb\libusbi.h" />
<ClInclude Include="..\libusb\os\poll_windows.h" /> <ClInclude Include="..\libusb\os\poll_windows.h" />
<ClInclude Include="..\libusb\os\threads_windows.h" /> <ClInclude Include="..\libusb\os\threads_windows.h" />
<ClInclude Include="..\libusb\os\windows_usb.h" /> <ClInclude Include="..\libusb\version.h" />
<ClInclude Include="..\libusb\version_nano.h" />
<ClInclude Include="..\libusb\os\windows_common.h" />
<ClInclude Include="..\libusb\os\windows_nt_common.h" />
<ClInclude Include="..\libusb\os\windows_winusb.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\libusb\libusb-1.0.def" /> <None Include="..\libusb\libusb-1.0.def" />

View File

@ -35,7 +35,7 @@
<ClCompile Include="..\libusb\os\threads_windows.c"> <ClCompile Include="..\libusb\os\threads_windows.c">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\libusb\os\windows_usb.c"> <ClCompile Include="..\libusb\os\windows_winusb.c">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\libusb\hotplug.c"> <ClCompile Include="..\libusb\hotplug.c">
@ -58,7 +58,7 @@
<ClInclude Include="..\libusb\os\threads_windows.h"> <ClInclude Include="..\libusb\os\threads_windows.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\libusb\os\windows_usb.h"> <ClInclude Include="..\libusb\os\windows_winusb.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\libusb\version.h"> <ClInclude Include="..\libusb\version.h">

View File

@ -150,18 +150,21 @@
<ClCompile Include="..\libusb\strerror.c" /> <ClCompile Include="..\libusb\strerror.c" />
<ClCompile Include="..\libusb\sync.c" /> <ClCompile Include="..\libusb\sync.c" />
<ClCompile Include="..\libusb\os\threads_windows.c" /> <ClCompile Include="..\libusb\os\threads_windows.c" />
<ClCompile Include="..\libusb\os\windows_usb.c" /> <ClCompile Include="..\libusb\os\windows_nt_common.c" />
<ClCompile Include="..\libusb\os\windows_winusb.c" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\libusb\hotplug.h" />
<ClInclude Include="..\libusb\version.h" />
<ClInclude Include="..\libusb\version_nano.h" />
<ClInclude Include=".\config.h" /> <ClInclude Include=".\config.h" />
<ClInclude Include="..\libusb\hotplug.h" />
<ClInclude Include="..\libusb\libusb.h" /> <ClInclude Include="..\libusb\libusb.h" />
<ClInclude Include="..\libusb\libusbi.h" /> <ClInclude Include="..\libusb\libusbi.h" />
<ClInclude Include="..\libusb\os\poll_windows.h" /> <ClInclude Include="..\libusb\os\poll_windows.h" />
<ClInclude Include="..\libusb\os\threads_windows.h" /> <ClInclude Include="..\libusb\os\threads_windows.h" />
<ClInclude Include="..\libusb\os\windows_usb.h" /> <ClInclude Include="..\libusb\version.h" />
<ClInclude Include="..\libusb\version_nano.h" />
<ClInclude Include="..\libusb\os\windows_common.h" />
<ClInclude Include="..\libusb\os\windows_nt_common.h" />
<ClInclude Include="..\libusb\os\windows_winusb.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\libusb\libusb-1.0.def" /> <None Include="..\libusb\libusb-1.0.def" />

View File

@ -0,0 +1,178 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectName>libusb-1.0 (dll)</ProjectName>
<ProjectGuid>{349EE8FA-7D25-4909-AAF5-FF3FADE72187}</ProjectGuid>
<RootNamespace>libusbdll</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)..\$(Platform)\$(Configuration)\dll\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)..\$(Platform)\$(Configuration)\dll\libusb-1.0\</IntDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)..\$(Platform)\$(Configuration)\dll\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)..\$(Platform)\$(Configuration)\dll\libusb-1.0\</IntDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)..\$(Platform)\$(Configuration)\dll\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)..\$(Platform)\$(Configuration)\dll\libusb-1.0\</IntDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)..\$(Platform)\$(Configuration)\dll\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)..\$(Platform)\$(Configuration)\dll\libusb-1.0\</IntDir>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">libusb-1.0</TargetName>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">libusb-1.0</TargetName>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">libusb-1.0</TargetName>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">libusb-1.0</TargetName>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>.;..\libusb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<OutputFile>$(OutDir)libusb-1.0.dll</OutputFile>
<ModuleDefinitionFile>..\libusb\libusb-1.0.def</ModuleDefinitionFile>
<EmbedManagedResourceFile>libusb-1.0.rc;%(EmbedManagedResourceFile)</EmbedManagedResourceFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Midl>
<TargetEnvironment>X64</TargetEnvironment>
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>.;..\libusb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_WIN32;_WIN64;_DEBUG;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<OutputFile>$(OutDir)libusb-1.0.dll</OutputFile>
<ModuleDefinitionFile>..\libusb\libusb-1.0.def</ModuleDefinitionFile>
<EmbedManagedResourceFile>libusb-1.0.rc;%(EmbedManagedResourceFile)</EmbedManagedResourceFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<AdditionalIncludeDirectories>.;..\libusb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_WIN32;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<WarningLevel>Level4</WarningLevel>
</ClCompile>
<Link>
<OutputFile>$(OutDir)libusb-1.0.dll</OutputFile>
<ModuleDefinitionFile>..\libusb\libusb-1.0.def</ModuleDefinitionFile>
<EmbedManagedResourceFile>libusb-1.0.rc;%(EmbedManagedResourceFile)</EmbedManagedResourceFile>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Midl>
<TargetEnvironment>X64</TargetEnvironment>
</Midl>
<ClCompile>
<AdditionalIncludeDirectories>.;..\libusb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_WIN32;_WIN64;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<WarningLevel>Level4</WarningLevel>
</ClCompile>
<Link>
<OutputFile>$(OutDir)libusb-1.0.dll</OutputFile>
<ModuleDefinitionFile>..\libusb\libusb-1.0.def</ModuleDefinitionFile>
<EmbedManagedResourceFile>libusb-1.0.rc;%(EmbedManagedResourceFile)</EmbedManagedResourceFile>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\libusb\core.c" />
<ClCompile Include="..\libusb\descriptor.c" />
<ClCompile Include="..\libusb\hotplug.c" />
<ClCompile Include="..\libusb\io.c" />
<ClCompile Include="..\libusb\os\poll_windows.c" />
<ClCompile Include="..\libusb\strerror.c" />
<ClCompile Include="..\libusb\sync.c" />
<ClCompile Include="..\libusb\os\threads_windows.c" />
<ClCompile Include="..\libusb\os\windows_nt_common.c" />
<ClCompile Include="..\libusb\os\windows_winusb.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include=".\config.h" />
<ClInclude Include="..\libusb\hotplug.h" />
<ClInclude Include="..\libusb\libusb.h" />
<ClInclude Include="..\libusb\libusbi.h" />
<ClInclude Include="..\libusb\os\poll_windows.h" />
<ClInclude Include="..\libusb\os\threads_windows.h" />
<ClInclude Include="..\libusb\version.h" />
<ClInclude Include="..\libusb\version_nano.h" />
<ClInclude Include="..\libusb\os\windows_common.h" />
<ClInclude Include="..\libusb\os\windows_nt_common.h" />
<ClInclude Include="..\libusb\os\windows_winusb.h" />
</ItemGroup>
<ItemGroup>
<None Include="..\libusb\libusb-1.0.def" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\libusb\libusb-1.0.rc" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -12,8 +12,12 @@ USE_LIBCMT=1
USE_MSVCRT=1 USE_MSVCRT=1
!ENDIF !ENDIF
!IFDEF WITH_USBDK
BACKEND_DEFINES="/DUSE_USBDK"
!ENDIF
INCLUDES=..;..\..\msvc;$(DDK_INC_PATH) INCLUDES=..;..\..\msvc;$(DDK_INC_PATH)
C_DEFINES= $(C_DEFINES) $(LIBUSB_DEFINES) /DDDKBUILD C_DEFINES= $(C_DEFINES) $(LIBUSB_DEFINES) $(BACKEND_DEFINES) /DDDKBUILD
# http://jpassing.com/2009/10/21/ltcg-issues-with-the-win7amd64-environment-of-wdk-7600/ # 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: # prevents the following error when using the 64 bit static lib with Visual Studio 2010:
@ -34,5 +38,7 @@ SOURCES=..\core.c \
..\hotplug.c \ ..\hotplug.c \
threads_windows.c \ threads_windows.c \
poll_windows.c \ poll_windows.c \
windows_usb.c \ windows_winusb.c \
windows_usbdk.c \
windows_nt_common.c \
..\libusb-1.0.rc ..\libusb-1.0.rc

View File

@ -119,7 +119,7 @@ SOURCE=..\libusb\os\threads_windows.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\libusb\os\windows_usb.c SOURCE=..\libusb\os\windows_winusb.c
# End Source File # End Source File
# End Group # End Group
# Begin Group "Header Files" # Begin Group "Header Files"
@ -163,7 +163,7 @@ SOURCE=..\libusb\os\threads_windows.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\libusb\os\windows_usb.h SOURCE=..\libusb\os\windows_winusb.h
# End Source File # End Source File
# Begin Source File # Begin Source File

View File

@ -314,7 +314,7 @@
> >
</File> </File>
<File <File
RelativePath="..\libusb\os\windows_usb.c" RelativePath="..\libusb\os\windows_winusb.c"
> >
</File> </File>
</Filter> </Filter>
@ -348,7 +348,7 @@
> >
</File> </File>
<File <File
RelativePath="..\libusb\os\windows_usb.h" RelativePath="..\libusb\os\windows_winusb.h"
> >
</File> </File>
<File <File

View File

@ -136,19 +136,21 @@
<ClCompile Include="..\libusb\strerror.c" /> <ClCompile Include="..\libusb\strerror.c" />
<ClCompile Include="..\libusb\sync.c" /> <ClCompile Include="..\libusb\sync.c" />
<ClCompile Include="..\libusb\os\threads_windows.c" /> <ClCompile Include="..\libusb\os\threads_windows.c" />
<ClCompile Include="..\libusb\os\windows_usb.c" /> <ClCompile Include="..\libusb\os\windows_nt_common.c" />
<ClCompile Include="..\libusb\os\windows_winusb.c" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include=".\config.h" /> <ClInclude Include=".\config.h" />
<ClInclude Include="..\libusb\hotplug.h" /> <ClInclude Include="..\libusb\hotplug.h" />
<ClInclude Include="..\libusb\version.h" />
<ClInclude Include="..\libusb\version_nano.h" />
<ClInclude Include="..\libusb\libusb.h" /> <ClInclude Include="..\libusb\libusb.h" />
<ClInclude Include="..\libusb\libusbi.h" /> <ClInclude Include="..\libusb\libusbi.h" />
<ClInclude Include="..\libusb\os\poll_windows.h" /> <ClInclude Include="..\libusb\os\poll_windows.h" />
<ClInclude Include="..\libusb\os\threads_windows.h" /> <ClInclude Include="..\libusb\os\threads_windows.h" />
<ClInclude Include="..\libusb\os\windows_usb.h" /> <ClInclude Include="..\libusb\version.h" />
<ClInclude Include="..\libusb\version_nano.h" />
<ClInclude Include="..\libusb\os\windows_common.h" /> <ClInclude Include="..\libusb\os\windows_common.h" />
<ClInclude Include="..\libusb\os\windows_nt_common.h" />
<ClInclude Include="..\libusb\os\windows_winusb.h" />
</ItemGroup> </ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets"> <ImportGroup Label="ExtensionTargets">

View File

@ -32,7 +32,7 @@
<ClCompile Include="..\libusb\os\threads_windows.c"> <ClCompile Include="..\libusb\os\threads_windows.c">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\libusb\os\windows_usb.c"> <ClCompile Include="..\libusb\os\windows_winusb.c">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\libusb\hotplug.c"> <ClCompile Include="..\libusb\hotplug.c">
@ -55,7 +55,7 @@
<ClInclude Include="..\libusb\os\threads_windows.h"> <ClInclude Include="..\libusb\os\threads_windows.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\libusb\os\windows_usb.h"> <ClInclude Include="..\libusb\os\windows_winusb.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\libusb\os\windows_common.h"> <ClInclude Include="..\libusb\os\windows_common.h">

View File

@ -140,19 +140,21 @@
<ClCompile Include="..\libusb\strerror.c" /> <ClCompile Include="..\libusb\strerror.c" />
<ClCompile Include="..\libusb\sync.c" /> <ClCompile Include="..\libusb\sync.c" />
<ClCompile Include="..\libusb\os\threads_windows.c" /> <ClCompile Include="..\libusb\os\threads_windows.c" />
<ClCompile Include="..\libusb\os\windows_usb.c" /> <ClCompile Include="..\libusb\os\windows_nt_common.c" />
<ClCompile Include="..\libusb\os\windows_winusb.c" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\libusb\hotplug.h" />
<ClInclude Include="..\libusb\version.h" />
<ClInclude Include="..\libusb\version_nano.h" />
<ClInclude Include=".\config.h" /> <ClInclude Include=".\config.h" />
<ClInclude Include="..\libusb\hotplug.h" />
<ClInclude Include="..\libusb\libusb.h" /> <ClInclude Include="..\libusb\libusb.h" />
<ClInclude Include="..\libusb\libusbi.h" /> <ClInclude Include="..\libusb\libusbi.h" />
<ClInclude Include="..\libusb\os\poll_windows.h" /> <ClInclude Include="..\libusb\os\poll_windows.h" />
<ClInclude Include="..\libusb\os\threads_windows.h" /> <ClInclude Include="..\libusb\os\threads_windows.h" />
<ClInclude Include="..\libusb\os\windows_usb.h" /> <ClInclude Include="..\libusb\version.h" />
<ClInclude Include="..\libusb\version_nano.h" />
<ClInclude Include="..\libusb\os\windows_common.h" /> <ClInclude Include="..\libusb\os\windows_common.h" />
<ClInclude Include="..\libusb\os\windows_nt_common.h" />
<ClInclude Include="..\libusb\os\windows_winusb.h" />
</ItemGroup> </ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets"> <ImportGroup Label="ExtensionTargets">

View File

@ -32,7 +32,7 @@
<ClCompile Include="..\libusb\os\threads_windows.c"> <ClCompile Include="..\libusb\os\threads_windows.c">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\libusb\os\windows_usb.c"> <ClCompile Include="..\libusb\os\windows_winusb.c">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\libusb\hotplug.c"> <ClCompile Include="..\libusb\hotplug.c">
@ -55,7 +55,7 @@
<ClInclude Include="..\libusb\os\threads_windows.h"> <ClInclude Include="..\libusb\os\threads_windows.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\libusb\os\windows_usb.h"> <ClInclude Include="..\libusb\os\windows_winusb.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\libusb\os\windows_common.h"> <ClInclude Include="..\libusb\os\windows_common.h">

View File

@ -140,19 +140,21 @@
<ClCompile Include="..\libusb\strerror.c" /> <ClCompile Include="..\libusb\strerror.c" />
<ClCompile Include="..\libusb\sync.c" /> <ClCompile Include="..\libusb\sync.c" />
<ClCompile Include="..\libusb\os\threads_windows.c" /> <ClCompile Include="..\libusb\os\threads_windows.c" />
<ClCompile Include="..\libusb\os\windows_usb.c" /> <ClCompile Include="..\libusb\os\windows_nt_common.c" />
<ClCompile Include="..\libusb\os\windows_winusb.c" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\libusb\hotplug.h" />
<ClInclude Include="..\libusb\version.h" />
<ClInclude Include="..\libusb\version_nano.h" />
<ClInclude Include=".\config.h" /> <ClInclude Include=".\config.h" />
<ClInclude Include="..\libusb\hotplug.h" />
<ClInclude Include="..\libusb\libusb.h" /> <ClInclude Include="..\libusb\libusb.h" />
<ClInclude Include="..\libusb\libusbi.h" /> <ClInclude Include="..\libusb\libusbi.h" />
<ClInclude Include="..\libusb\os\poll_windows.h" /> <ClInclude Include="..\libusb\os\poll_windows.h" />
<ClInclude Include="..\libusb\os\threads_windows.h" /> <ClInclude Include="..\libusb\os\threads_windows.h" />
<ClInclude Include="..\libusb\os\windows_usb.h" /> <ClInclude Include="..\libusb\version.h" />
<ClInclude Include="..\libusb\version_nano.h" />
<ClInclude Include="..\libusb\os\windows_common.h" /> <ClInclude Include="..\libusb\os\windows_common.h" />
<ClInclude Include="..\libusb\os\windows_nt_common.h" />
<ClInclude Include="..\libusb\os\windows_winusb.h" />
</ItemGroup> </ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets"> <ImportGroup Label="ExtensionTargets">

View File

@ -0,0 +1,162 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectName>libusb-1.0 (static)</ProjectName>
<ProjectGuid>{349EE8F9-7D25-4909-AAF5-FF3FADE72187}</ProjectGuid>
<RootNamespace>libusb</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)..\$(Platform)\$(Configuration)\lib\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)..\$(Platform)\$(Configuration)\lib\libusb-1.0\</IntDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)..\$(Platform)\$(Configuration)\lib\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)..\$(Platform)\$(Configuration)\lib\libusb-1.0\</IntDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)..\$(Platform)\$(Configuration)\lib\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)..\$(Platform)\$(Configuration)\lib\libusb-1.0\</IntDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)..\$(Platform)\$(Configuration)\lib\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)..\$(Platform)\$(Configuration)\lib\libusb-1.0\</IntDir>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">libusb-1.0</TargetName>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">libusb-1.0</TargetName>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">libusb-1.0</TargetName>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">libusb-1.0</TargetName>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>.;..\libusb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
</ClCompile>
<Lib>
<OutputFile>$(OutDir)libusb-1.0.lib</OutputFile>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Midl>
<TargetEnvironment>X64</TargetEnvironment>
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>.;..\libusb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_WIN32;_WIN64;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
</ClCompile>
<Lib>
<OutputFile>$(OutDir)libusb-1.0.lib</OutputFile>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<AdditionalIncludeDirectories>.;..\libusb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_WIN32;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<WarningLevel>Level4</WarningLevel>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
</ClCompile>
<Lib>
<OutputFile>$(OutDir)libusb-1.0.lib</OutputFile>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Midl>
<TargetEnvironment>X64</TargetEnvironment>
</Midl>
<ClCompile>
<AdditionalIncludeDirectories>.;..\libusb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_WIN32;_WIN64;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<WarningLevel>Level4</WarningLevel>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
</ClCompile>
<Lib>
<OutputFile>$(OutDir)libusb-1.0.lib</OutputFile>
</Lib>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\libusb\core.c" />
<ClCompile Include="..\libusb\descriptor.c" />
<ClCompile Include="..\libusb\hotplug.c" />
<ClCompile Include="..\libusb\io.c" />
<ClCompile Include="..\libusb\os\poll_windows.c" />
<ClCompile Include="..\libusb\strerror.c" />
<ClCompile Include="..\libusb\sync.c" />
<ClCompile Include="..\libusb\os\threads_windows.c" />
<ClCompile Include="..\libusb\os\windows_nt_common.c" />
<ClCompile Include="..\libusb\os\windows_winusb.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include=".\config.h" />
<ClInclude Include="..\libusb\hotplug.h" />
<ClInclude Include="..\libusb\libusb.h" />
<ClInclude Include="..\libusb\libusbi.h" />
<ClInclude Include="..\libusb\os\poll_windows.h" />
<ClInclude Include="..\libusb\os\threads_windows.h" />
<ClInclude Include="..\libusb\version.h" />
<ClInclude Include="..\libusb\version_nano.h" />
<ClInclude Include="..\libusb\os\windows_common.h" />
<ClInclude Include="..\libusb\os\windows_nt_common.h" />
<ClInclude Include="..\libusb\os\windows_winusb.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,178 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectName>libusb-usbdk-1.0 (dll)</ProjectName>
<ProjectGuid>{F53A5974-2319-48EB-A67B-27933AEDF14A}</ProjectGuid>
<RootNamespace>libusbdll</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)..\$(Platform)\$(Configuration)\dll\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)..\$(Platform)\$(Configuration)\dll\libusb-usbdk-1.0\</IntDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)..\$(Platform)\$(Configuration)\dll\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)..\$(Platform)\$(Configuration)\dll\libusb-usbdk-1.0\</IntDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)..\$(Platform)\$(Configuration)\dll\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)..\$(Platform)\$(Configuration)\dll\libusb-usbdk-1.0\</IntDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)..\$(Platform)\$(Configuration)\dll\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)..\$(Platform)\$(Configuration)\dll\libusb-usbdk-1.0\</IntDir>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">libusb-usbdk-1.0</TargetName>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">libusb-usbdk-1.0</TargetName>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">libusb-usbdk-1.0</TargetName>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">libusb-usbdk-1.0</TargetName>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>.;..\libusb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;USE_USBDK;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<OutputFile>$(OutDir)libusb-usbdk-1.0.dll</OutputFile>
<ModuleDefinitionFile>..\libusb\libusb-1.0.def</ModuleDefinitionFile>
<EmbedManagedResourceFile>libusb-1.0.rc;%(EmbedManagedResourceFile)</EmbedManagedResourceFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Midl>
<TargetEnvironment>X64</TargetEnvironment>
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>.;..\libusb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_WIN32;_WIN64;_DEBUG;_CRT_SECURE_NO_WARNINGS;USE_USBDK;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<OutputFile>$(OutDir)libusb-usbdk-1.0.dll</OutputFile>
<ModuleDefinitionFile>..\libusb\libusb-1.0.def</ModuleDefinitionFile>
<EmbedManagedResourceFile>libusb-1.0.rc;%(EmbedManagedResourceFile)</EmbedManagedResourceFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<AdditionalIncludeDirectories>.;..\libusb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_WIN32;_LIB;_CRT_SECURE_NO_WARNINGS;USE_USBDK;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<WarningLevel>Level4</WarningLevel>
</ClCompile>
<Link>
<OutputFile>$(OutDir)libusb-usbdk-1.0.dll</OutputFile>
<ModuleDefinitionFile>..\libusb\libusb-1.0.def</ModuleDefinitionFile>
<EmbedManagedResourceFile>libusb-1.0.rc;%(EmbedManagedResourceFile)</EmbedManagedResourceFile>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Midl>
<TargetEnvironment>X64</TargetEnvironment>
</Midl>
<ClCompile>
<AdditionalIncludeDirectories>.;..\libusb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_WIN32;_WIN64;_LIB;_CRT_SECURE_NO_WARNINGS;USE_USBDK;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<WarningLevel>Level4</WarningLevel>
</ClCompile>
<Link>
<OutputFile>$(OutDir)libusb-usbdk-1.0.dll</OutputFile>
<ModuleDefinitionFile>..\libusb\libusb-1.0.def</ModuleDefinitionFile>
<EmbedManagedResourceFile>libusb-1.0.rc;%(EmbedManagedResourceFile)</EmbedManagedResourceFile>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\libusb\core.c" />
<ClCompile Include="..\libusb\descriptor.c" />
<ClCompile Include="..\libusb\hotplug.c" />
<ClCompile Include="..\libusb\io.c" />
<ClCompile Include="..\libusb\os\poll_windows.c" />
<ClCompile Include="..\libusb\strerror.c" />
<ClCompile Include="..\libusb\sync.c" />
<ClCompile Include="..\libusb\os\threads_windows.c" />
<ClCompile Include="..\libusb\os\windows_nt_common.c" />
<ClCompile Include="..\libusb\os\windows_usbdk.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include=".\config.h" />
<ClInclude Include="..\libusb\hotplug.h" />
<ClInclude Include="..\libusb\libusb.h" />
<ClInclude Include="..\libusb\libusbi.h" />
<ClInclude Include="..\libusb\os\poll_windows.h" />
<ClInclude Include="..\libusb\os\threads_windows.h" />
<ClInclude Include="..\libusb\version.h" />
<ClInclude Include="..\libusb\version_nano.h" />
<ClInclude Include="..\libusb\os\windows_common.h" />
<ClInclude Include="..\libusb\os\windows_nt_common.h" />
<ClInclude Include="..\libusb\os\windows_usbdk.h" />
</ItemGroup>
<ItemGroup>
<None Include="..\libusb\libusb-1.0.def" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\libusb\libusb-1.0.rc" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,178 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectName>libusb-usbdk-1.0 (dll)</ProjectName>
<ProjectGuid>{F53A5974-2319-48EB-A67B-27933AEDF14A}</ProjectGuid>
<RootNamespace>libusbdll</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)..\$(Platform)\$(Configuration)\dll\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)..\$(Platform)\$(Configuration)\dll\libusb-usbdk-1.0\</IntDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)..\$(Platform)\$(Configuration)\dll\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)..\$(Platform)\$(Configuration)\dll\libusb-usbdk-1.0\</IntDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)..\$(Platform)\$(Configuration)\dll\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)..\$(Platform)\$(Configuration)\dll\libusb-usbdk-1.0\</IntDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)..\$(Platform)\$(Configuration)\dll\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)..\$(Platform)\$(Configuration)\dll\libusb-usbdk-1.0\</IntDir>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">libusb-usbdk-1.0</TargetName>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">libusb-usbdk-1.0</TargetName>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">libusb-usbdk-1.0</TargetName>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">libusb-usbdk-1.0</TargetName>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>.;..\libusb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;USE_USBDK;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<OutputFile>$(OutDir)libusb-usbdk-1.0.dll</OutputFile>
<ModuleDefinitionFile>..\libusb\libusb-1.0.def</ModuleDefinitionFile>
<EmbedManagedResourceFile>libusb-1.0.rc;%(EmbedManagedResourceFile)</EmbedManagedResourceFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Midl>
<TargetEnvironment>X64</TargetEnvironment>
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>.;..\libusb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_WIN32;_WIN64;_DEBUG;_CRT_SECURE_NO_WARNINGS;USE_USBDK;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<OutputFile>$(OutDir)libusb-usbdk-1.0.dll</OutputFile>
<ModuleDefinitionFile>..\libusb\libusb-1.0.def</ModuleDefinitionFile>
<EmbedManagedResourceFile>libusb-1.0.rc;%(EmbedManagedResourceFile)</EmbedManagedResourceFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<AdditionalIncludeDirectories>.;..\libusb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_WIN32;_LIB;_CRT_SECURE_NO_WARNINGS;USE_USBDK;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<WarningLevel>Level4</WarningLevel>
</ClCompile>
<Link>
<OutputFile>$(OutDir)libusb-usbdk-1.0.dll</OutputFile>
<ModuleDefinitionFile>..\libusb\libusb-1.0.def</ModuleDefinitionFile>
<EmbedManagedResourceFile>libusb-1.0.rc;%(EmbedManagedResourceFile)</EmbedManagedResourceFile>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Midl>
<TargetEnvironment>X64</TargetEnvironment>
</Midl>
<ClCompile>
<AdditionalIncludeDirectories>.;..\libusb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_WIN32;_WIN64;_LIB;_CRT_SECURE_NO_WARNINGS;USE_USBDK;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<WarningLevel>Level4</WarningLevel>
</ClCompile>
<Link>
<OutputFile>$(OutDir)libusb-usbdk-1.0.dll</OutputFile>
<ModuleDefinitionFile>..\libusb\libusb-1.0.def</ModuleDefinitionFile>
<EmbedManagedResourceFile>libusb-1.0.rc;%(EmbedManagedResourceFile)</EmbedManagedResourceFile>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\libusb\core.c" />
<ClCompile Include="..\libusb\descriptor.c" />
<ClCompile Include="..\libusb\hotplug.c" />
<ClCompile Include="..\libusb\io.c" />
<ClCompile Include="..\libusb\os\poll_windows.c" />
<ClCompile Include="..\libusb\strerror.c" />
<ClCompile Include="..\libusb\sync.c" />
<ClCompile Include="..\libusb\os\threads_windows.c" />
<ClCompile Include="..\libusb\os\windows_nt_common.c" />
<ClCompile Include="..\libusb\os\windows_usbdk.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include=".\config.h" />
<ClInclude Include="..\libusb\hotplug.h" />
<ClInclude Include="..\libusb\libusb.h" />
<ClInclude Include="..\libusb\libusbi.h" />
<ClInclude Include="..\libusb\os\poll_windows.h" />
<ClInclude Include="..\libusb\os\threads_windows.h" />
<ClInclude Include="..\libusb\version.h" />
<ClInclude Include="..\libusb\version_nano.h" />
<ClInclude Include="..\libusb\os\windows_common.h" />
<ClInclude Include="..\libusb\os\windows_nt_common.h" />
<ClInclude Include="..\libusb\os\windows_usbdk.h" />
</ItemGroup>
<ItemGroup>
<None Include="..\libusb\libusb-1.0.def" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\libusb\libusb-1.0.rc" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,162 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectName>libusb-usbdk-1.0 (static)</ProjectName>
<ProjectGuid>{0B3D86CF-5D70-41A9-B391-A2E7C5C969ED}</ProjectGuid>
<RootNamespace>libusb</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)..\$(Platform)\$(Configuration)\lib\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)..\$(Platform)\$(Configuration)\lib\libusb-usbdk-1.0\</IntDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)..\$(Platform)\$(Configuration)\lib\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)..\$(Platform)\$(Configuration)\lib\libusb-usbdk-1.0\</IntDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)..\$(Platform)\$(Configuration)\lib\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)..\$(Platform)\$(Configuration)\lib\libusb-usbdk-1.0\</IntDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)..\$(Platform)\$(Configuration)\lib\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)..\$(Platform)\$(Configuration)\lib\libusb-usbdk-1.0\</IntDir>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">libusb-usbdk-1.0</TargetName>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">libusb-usbdk-1.0</TargetName>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">libusb-usbdk-1.0</TargetName>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">libusb-usbdk-1.0</TargetName>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>.;..\libusb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;USE_USBDK;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Lib>
<OutputFile>$(OutDir)libusb-usbdk-1.0.lib</OutputFile>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Midl>
<TargetEnvironment>X64</TargetEnvironment>
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>.;..\libusb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_WIN32;_WIN64;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;USE_USBDK;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Lib>
<OutputFile>$(OutDir)libusb-usbdk-1.0.lib</OutputFile>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<AdditionalIncludeDirectories>.;..\libusb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_WIN32;_LIB;_CRT_SECURE_NO_WARNINGS;USE_USBDK;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<WarningLevel>Level4</WarningLevel>
</ClCompile>
<Lib>
<OutputFile>$(OutDir)libusb-usbdk-1.0.lib</OutputFile>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Midl>
<TargetEnvironment>X64</TargetEnvironment>
</Midl>
<ClCompile>
<AdditionalIncludeDirectories>.;..\libusb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_WIN32;_WIN64;_LIB;_CRT_SECURE_NO_WARNINGS;USE_USBDK;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<WarningLevel>Level4</WarningLevel>
</ClCompile>
<Lib>
<OutputFile>$(OutDir)libusb-usbdk-1.0.lib</OutputFile>
</Lib>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\libusb\core.c" />
<ClCompile Include="..\libusb\descriptor.c" />
<ClCompile Include="..\libusb\hotplug.c" />
<ClCompile Include="..\libusb\io.c" />
<ClCompile Include="..\libusb\os\poll_windows.c" />
<ClCompile Include="..\libusb\strerror.c" />
<ClCompile Include="..\libusb\sync.c" />
<ClCompile Include="..\libusb\os\threads_windows.c" />
<ClCompile Include="..\libusb\os\windows_nt_common.c" />
<ClCompile Include="..\libusb\os\windows_usbdk.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include=".\config.h" />
<ClInclude Include="..\libusb\hotplug.h" />
<ClInclude Include="..\libusb\libusb.h" />
<ClInclude Include="..\libusb\libusbi.h" />
<ClInclude Include="..\libusb\os\poll_windows.h" />
<ClInclude Include="..\libusb\os\threads_windows.h" />
<ClInclude Include="..\libusb\version.h" />
<ClInclude Include="..\libusb\version_nano.h" />
<ClInclude Include="..\libusb\os\windows_common.h" />
<ClInclude Include="..\libusb\os\windows_nt_common.h" />
<ClInclude Include="..\libusb\os\windows_usbdk.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,162 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectName>libusb-usbdk-1.0 (static)</ProjectName>
<ProjectGuid>{0B3D86CF-5D70-41A9-B391-A2E7C5C969ED}</ProjectGuid>
<RootNamespace>libusb</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)..\$(Platform)\$(Configuration)\lib\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)..\$(Platform)\$(Configuration)\lib\libusb-usbdk-1.0\</IntDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)..\$(Platform)\$(Configuration)\lib\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)..\$(Platform)\$(Configuration)\lib\libusb-usbdk-1.0\</IntDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)..\$(Platform)\$(Configuration)\lib\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)..\$(Platform)\$(Configuration)\lib\libusb-usbdk-1.0\</IntDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)..\$(Platform)\$(Configuration)\lib\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)..\$(Platform)\$(Configuration)\lib\libusb-usbdk-1.0\</IntDir>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">libusb-usbdk-1.0</TargetName>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">libusb-usbdk-1.0</TargetName>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">libusb-usbdk-1.0</TargetName>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">libusb-usbdk-1.0</TargetName>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>.;..\libusb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;USE_USBDK;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Lib>
<OutputFile>$(OutDir)libusb-usbdk-1.0.lib</OutputFile>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Midl>
<TargetEnvironment>X64</TargetEnvironment>
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>.;..\libusb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_WIN32;_WIN64;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;USE_USBDK;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Lib>
<OutputFile>$(OutDir)libusb-usbdk-1.0.lib</OutputFile>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<AdditionalIncludeDirectories>.;..\libusb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_WIN32;_LIB;_CRT_SECURE_NO_WARNINGS;USE_USBDK;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<WarningLevel>Level4</WarningLevel>
</ClCompile>
<Lib>
<OutputFile>$(OutDir)libusb-usbdk-1.0.lib</OutputFile>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Midl>
<TargetEnvironment>X64</TargetEnvironment>
</Midl>
<ClCompile>
<AdditionalIncludeDirectories>.;..\libusb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_WIN32;_WIN64;_LIB;_CRT_SECURE_NO_WARNINGS;USE_USBDK;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<WarningLevel>Level4</WarningLevel>
</ClCompile>
<Lib>
<OutputFile>$(OutDir)libusb-usbdk-1.0.lib</OutputFile>
</Lib>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\libusb\core.c" />
<ClCompile Include="..\libusb\descriptor.c" />
<ClCompile Include="..\libusb\hotplug.c" />
<ClCompile Include="..\libusb\io.c" />
<ClCompile Include="..\libusb\os\poll_windows.c" />
<ClCompile Include="..\libusb\strerror.c" />
<ClCompile Include="..\libusb\sync.c" />
<ClCompile Include="..\libusb\os\threads_windows.c" />
<ClCompile Include="..\libusb\os\windows_nt_common.c" />
<ClCompile Include="..\libusb\os\windows_usbdk.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include=".\config.h" />
<ClInclude Include="..\libusb\hotplug.h" />
<ClInclude Include="..\libusb\libusb.h" />
<ClInclude Include="..\libusb\libusbi.h" />
<ClInclude Include="..\libusb\os\poll_windows.h" />
<ClInclude Include="..\libusb\os\threads_windows.h" />
<ClInclude Include="..\libusb\version.h" />
<ClInclude Include="..\libusb\version_nano.h" />
<ClInclude Include="..\libusb\os\windows_common.h" />
<ClInclude Include="..\libusb\os\windows_nt_common.h" />
<ClInclude Include="..\libusb\os\windows_usbdk.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,169 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectName>listdevs</ProjectName>
<ProjectGuid>{F4938DB0-3DE7-4737-9C5A-EAD1BE819F87}</ProjectGuid>
<RootNamespace>examples</RootNamespace>
<Keyword>Win32Proj</Keyword>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)..\$(Platform)\$(Configuration)\examples\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)..\$(Platform)\$(Configuration)\examples\$(ProjectName)\</IntDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)..\$(Platform)\$(Configuration)\examples\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)..\$(Platform)\$(Configuration)\examples\$(ProjectName)\</IntDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)..\$(Platform)\$(Configuration)\examples\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)..\$(Platform)\$(Configuration)\examples\$(ProjectName)\</IntDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)..\$(Platform)\$(Configuration)\examples\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)..\$(Platform)\$(Configuration)\examples\$(ProjectName)\</IntDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<BuildLog>
<Path>$(IntDir)$(ProjectName).htm</Path>
</BuildLog>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\libusb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>$(TargetDir)$(ProjectName).pdb</ProgramDatabaseFile>
<SubSystem>Console</SubSystem>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<BuildLog>
<Path>$(IntDir)$(ProjectName).htm</Path>
</BuildLog>
<Midl>
<TargetEnvironment>X64</TargetEnvironment>
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\libusb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>$(TargetDir)$(ProjectName).pdb</ProgramDatabaseFile>
<SubSystem>Console</SubSystem>
<TargetMachine>MachineX64</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<BuildLog>
<Path>$(IntDir)$(ProjectName).htm</Path>
</BuildLog>
<ClCompile>
<AdditionalIncludeDirectories>..\libusb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<ProgramDatabaseFile>$(TargetDir)$(ProjectName).pdb</ProgramDatabaseFile>
<SubSystem>Console</SubSystem>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<BuildLog>
<Path>$(IntDir)$(ProjectName).htm</Path>
</BuildLog>
<Midl>
<TargetEnvironment>X64</TargetEnvironment>
</Midl>
<ClCompile>
<AdditionalIncludeDirectories>..\libusb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<ProgramDatabaseFile>$(TargetDir)$(ProjectName).pdb</ProgramDatabaseFile>
<SubSystem>Console</SubSystem>
<TargetMachine>MachineX64</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\examples\listdevs.c" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include=".\libusb_static_2015.vcxproj">
<Project>{349ee8f9-7d25-4909-aaf5-ff3fade72187}</Project>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,171 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectName>stress</ProjectName>
<ProjectGuid>{53942EFF-C810-458D-B3CB-EE5CE9F1E781}</ProjectGuid>
<RootNamespace>tests</RootNamespace>
<Keyword>Win32Proj</Keyword>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)..\$(Platform)\$(Configuration)\tests\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)..\$(Platform)\$(Configuration)\tests\$(ProjectName)\</IntDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)..\$(Platform)\$(Configuration)\tests\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)..\$(Platform)\$(Configuration)\tests\$(ProjectName)\</IntDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)..\$(Platform)\$(Configuration)\tests\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)..\$(Platform)\$(Configuration)\tests\$(ProjectName)\</IntDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)..\$(Platform)\$(Configuration)\tests\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)..\$(Platform)\$(Configuration)\tests\$(ProjectName)\</IntDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<BuildLog>
<Path>$(IntDir)$(ProjectName).htm</Path>
</BuildLog>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>.;..\libusb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<BuildLog>
<Path>$(IntDir)$(ProjectName).htm</Path>
</BuildLog>
<Midl>
<TargetEnvironment>X64</TargetEnvironment>
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>.;..\libusb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<TargetMachine>MachineX64</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<BuildLog>
<Path>$(IntDir)$(ProjectName).htm</Path>
</BuildLog>
<ClCompile>
<AdditionalIncludeDirectories>.;..\libusb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<SubSystem>Console</SubSystem>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<BuildLog>
<Path>$(IntDir)$(ProjectName).htm</Path>
</BuildLog>
<Midl>
<TargetEnvironment>X64</TargetEnvironment>
</Midl>
<ClCompile>
<AdditionalIncludeDirectories>.;..\libusb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<SubSystem>Console</SubSystem>
<TargetMachine>MachineX64</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\tests\stress.c" />
<ClCompile Include="..\tests\testlib.c" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include=".\libusb_static_2015.vcxproj">
<Project>{349ee8f9-7d25-4909-aaf5-ff3fade72187}</Project>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\tests\libusb_testlib.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

167
Externals/libusb/msvc/xusb_2015.vcxproj vendored Normal file
View File

@ -0,0 +1,167 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectName>xusb</ProjectName>
<ProjectGuid>{3F3138D0-7AB7-4268-9BF3-1A3EA5503A11}</ProjectGuid>
<RootNamespace>examples</RootNamespace>
<Keyword>Win32Proj</Keyword>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)..\$(Platform)\$(Configuration)\examples\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)..\$(Platform)\$(Configuration)\examples\$(ProjectName)\</IntDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)..\$(Platform)\$(Configuration)\examples\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)..\$(Platform)\$(Configuration)\examples\$(ProjectName)\</IntDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)..\$(Platform)\$(Configuration)\examples\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)..\$(Platform)\$(Configuration)\examples\$(ProjectName)\</IntDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)..\$(Platform)\$(Configuration)\examples\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)..\$(Platform)\$(Configuration)\examples\$(ProjectName)\</IntDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<BuildLog>
<Path>$(IntDir)$(ProjectName).htm</Path>
</BuildLog>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>.;..\libusb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<BuildLog>
<Path>$(IntDir)$(ProjectName).htm</Path>
</BuildLog>
<Midl>
<TargetEnvironment>X64</TargetEnvironment>
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>.;..\libusb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<TargetMachine>MachineX64</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<BuildLog>
<Path>$(IntDir)$(ProjectName).htm</Path>
</BuildLog>
<ClCompile>
<AdditionalIncludeDirectories>.;..\libusb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<SubSystem>Console</SubSystem>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<BuildLog>
<Path>$(IntDir)$(ProjectName).htm</Path>
</BuildLog>
<Midl>
<TargetEnvironment>X64</TargetEnvironment>
</Midl>
<ClCompile>
<AdditionalIncludeDirectories>.;..\libusb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<SubSystem>Console</SubSystem>
<TargetMachine>MachineX64</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\examples\xusb.c" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include=".\libusb_static_2015.vcxproj">
<Project>{349ee8f9-7d25-4909-aaf5-ff3fade72187}</Project>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>