summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPete Batard <pbatard@gmail.com>2010-03-10 13:14:51 +0000
committerPete Batard <pbatard@gmail.com>2010-03-10 13:14:51 +0000
commitfae9c17bd2405813d44186c94367d6e66d3994e6 (patch)
tree8e795a9400182bdabb61229a3791f060af1d5335
parent4ee3179ae1e0adefc6c5d19c036c297856ebdef9 (diff)
downloadlibusb-fae9c17bd2405813d44186c94367d6e66d3994e6.tar.gz
libusb0.sys backend integration - part 2 (Graeme Gill)c190
-rw-r--r--AUTHORS4
-rw-r--r--COPYING_GPL340
-rw-r--r--ddk_build.cmd70
-rw-r--r--examples/lsusb_sources3
-rw-r--r--examples/makefile550
-rw-r--r--examples/xusb_sources4
-rw-r--r--libusb/os/driver/abort_endpoint.c59
-rw-r--r--libusb/os/driver/claim_interface.c58
-rw-r--r--libusb/os/driver/clear_feature.c69
-rw-r--r--libusb/os/driver/common.rc53
-rw-r--r--libusb/os/driver/dispatch.c95
-rw-r--r--libusb/os/driver/driver_api.h165
-rw-r--r--libusb/os/driver/driver_debug.c75
-rw-r--r--libusb/os/driver/driver_debug.h30
-rw-r--r--libusb/os/driver/driver_registry.c134
-rw-r--r--libusb/os/driver/get_configuration.c58
-rw-r--r--libusb/os/driver/get_descriptor.c158
-rw-r--r--libusb/os/driver/get_interface.c67
-rw-r--r--libusb/os/driver/get_status.c77
-rw-r--r--libusb/os/driver/ioctl.c332
-rw-r--r--libusb/os/driver/libusb_driver.c462
-rw-r--r--libusb/os/driver/libusb_driver.h234
-rw-r--r--libusb/os/driver/libusb_driver_rc.rc25
-rw-r--r--libusb/os/driver/makefile1
-rw-r--r--libusb/os/driver/pnp.c216
-rw-r--r--libusb/os/driver/power.c205
-rw-r--r--libusb/os/driver/release_interface.c69
-rw-r--r--libusb/os/driver/reset_device.c46
-rw-r--r--libusb/os/driver/reset_endpoint.c59
-rw-r--r--libusb/os/driver/set_configuration.c170
-rw-r--r--libusb/os/driver/set_descriptor.c77
-rw-r--r--libusb/os/driver/set_feature.c71
-rw-r--r--libusb/os/driver/set_interface.c123
-rw-r--r--libusb/os/driver/sources33
-rw-r--r--libusb/os/driver/temp13
-rw-r--r--libusb/os/driver/transfer.c238
-rw-r--r--libusb/os/driver/usbd.def35
-rw-r--r--libusb/os/driver/usbdlib_gcc.h308
-rw-r--r--libusb/os/driver/vendor_request.c138
-rw-r--r--libusb/os/makefile1
-rw-r--r--libusb/os/poll_windows.c4
-rw-r--r--libusb/os/poll_windows.h2
-rw-r--r--libusb/os/sources3
-rw-r--r--libusb/os/windows_usb.c22
-rw-r--r--libusb/os/windows_usb.h2
45 files changed, 4918 insertions, 40 deletions
diff --git a/AUTHORS b/AUTHORS
index 495a72e..93310e3 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -2,6 +2,9 @@ Copyright (C) 2007-2009 Daniel Drake <dsd@gentoo.org>
Copyright (c) 2001 Johannes Erdfelt <johannes@erdfelt.com>
Copyright (C) 2008-2010 Nathan Hjelm <hjelmn@users.sourceforge.net>
+Windows Kernel Driver:
+Stephan Meyer, <ste_meyer@web.de>
+
Other contributors:
Alex Vatchenko
Artem Egorkine
@@ -16,4 +19,5 @@ Mikhail Gusarov
Rob Walker
Toby Peterson
Vasily Khoruzhick
+Graeme W. Gill
diff --git a/COPYING_GPL b/COPYING_GPL
new file mode 100644
index 0000000..5b6e7c6
--- /dev/null
+++ b/COPYING_GPL
@@ -0,0 +1,340 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/ddk_build.cmd b/ddk_build.cmd
index e51d939..06ddcec 100644
--- a/ddk_build.cmd
+++ b/ddk_build.cmd
@@ -1,16 +1,11 @@
@echo off
-if Test%BUILD_ALT_DIR%==Test goto usage
-set version=1.0
+@rem ==================== setup ======================
-cd libusb\os
-copy /y ..\..\msvc\libusb-%version%.rc .
-@echo on
-build -cZ
-@echo off
-if errorlevel 1 goto builderror
-del libusb-%version%.rc
-cd ..\..
+@rem Compatibility with older DDK environments:
+if defined DDKBUILDENV set _BuildType=%DDKBUILDENV%
+
+if Test%BUILD_ALT_DIR%==Test goto usage
set cpudir=i386
set destType=Win32
@@ -19,8 +14,6 @@ set cpudir=amd64
set destType=x64
:isI386
-set srcPath=libusb\os\obj%BUILD_ALT_DIR%\%cpudir%
-
set dstPath=%destType%\Debug
if %_BuildType%==chk goto isDebug
set dstPath=%destType%\Release
@@ -38,9 +31,26 @@ mkdir %dstPath%\dll
if exist %dstPath%\lib goto md5
md %dstPath%\lib
:md5
-if exist %dstPath%\examples goto md6
-md %dstPath%\examples
+if exist %dstPath%\sys goto md6
+md %dstPath%\sys
:md6
+if exist %dstPath%\examples goto md7
+md %dstPath%\examples
+:md7
+
+@rem ==================== libusb ======================
+set version=1.0
+
+cd libusb\os
+copy /y ..\..\msvc\libusb-%version%.rc .
+@echo on
+build -cZ
+@echo off
+if errorlevel 1 goto builderror
+del libusb-%version%.rc
+cd ..\..
+
+set srcPath=libusb\os\obj%BUILD_ALT_DIR%\%cpudir%
@echo on
copy %srcPath%\libusb-%version%.dll %dstPath%\dll
@@ -49,12 +59,29 @@ copy %srcPath%\libusb-%version%.lib %dstPath%\lib
@echo off
-if exist examples\lsusb_ddkbuild goto md7
+@rem ==================== libusb0.sys ======================
+cd libusb\os\driver
+@echo on
+build -cZ
+@echo off
+if errorlevel 1 goto buildlsusberror
+cd ..\..\..
+
+set srcPath=libusb\os\driver\obj%BUILD_ALT_DIR%\%cpudir%
+@echo on
+
+copy %srcPath%\libusb0.sys %dstPath%\sys
+
+@echo off
+
+@rem ==================== example lsusb ======================
+if exist examples\lsusb_ddkbuild goto md8
md examples\lsusb_ddkbuild
-:md7
+:md8
cd examples\lsusb_ddkbuild
copy ..\lsusb_sources sources
+copy ..\makefile makefile
@echo on
build -cZ
@echo off
@@ -69,12 +96,14 @@ copy %srcPath%\lsusb.pdb %dstPath%\examples
@echo off
-if exist examples\xusb_ddkbuild goto md8
+@rem ==================== example xusb ======================
+if exist examples\xusb_ddkbuild goto md9
md examples\xusb_ddkbuild
-:md8
+:md9
cd examples\xusb_ddkbuild
copy ..\xusb_sources sources
+copy ..\makefile makefile
@echo on
build -cZ
@echo off
@@ -89,10 +118,9 @@ copy %srcPath%\xusb.pdb %dstPath%\examples
@echo off
-
+@rem ==================== cleanup ======================
goto done
-
:builderror
del libusb-%version%.rc
cd ..\..
@@ -113,4 +141,4 @@ goto done
echo ddk_build must be run in a WDK build environment
goto done
-:done \ No newline at end of file
+:done
diff --git a/examples/lsusb_sources b/examples/lsusb_sources
index 82ea935..6388426 100644
--- a/examples/lsusb_sources
+++ b/examples/lsusb_sources
@@ -1,7 +1,8 @@
TARGETNAME=lsusb
TARGETTYPE=PROGRAM
+TARGETPATH=obj
-_NT_TARGET_VERSION= $(_NT_TARGET_VERSION_WINXP)
+#_NT_TARGET_VERSION= $(_NT_TARGET_VERSION_WINXP)
!IFNDEF MSC_WARNING_LEVEL
diff --git a/examples/makefile b/examples/makefile
new file mode 100644
index 0000000..651377f
--- /dev/null
+++ b/examples/makefile
@@ -0,0 +1,550 @@
+# Makefile.in generated by automake 1.11 from Makefile.am.
+# examples/Makefile. Generated from Makefile.in by configure.
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+
+
+
+pkgdatadir = $(datadir)/libusb
+pkgincludedir = $(includedir)/libusb
+pkglibdir = $(libdir)/libusb
+pkglibexecdir = $(libexecdir)/libusb
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = i686-pc-mingw32
+host_triplet = i686-pc-mingw32
+noinst_PROGRAMS = xusb$(EXEEXT) lsusb$(EXEEXT) $(am__EXEEXT_1)
+subdir = examples
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__EXEEXT_1 = dpfp$(EXEEXT)
+#am__EXEEXT_1 = dpfp$(EXEEXT) \
+# dpfp_threaded$(EXEEXT)
+PROGRAMS = $(noinst_PROGRAMS)
+am_dpfp_OBJECTS = dpfp.$(OBJEXT)
+dpfp_OBJECTS = $(am_dpfp_OBJECTS)
+dpfp_DEPENDENCIES = ../libusb/libusb-1.0.la
+AM_V_lt = $(am__v_lt_$(V))
+am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY))
+am__v_lt_0 = --silent
+am_dpfp_threaded_OBJECTS = dpfp_threaded-dpfp_threaded.$(OBJEXT)
+dpfp_threaded_OBJECTS = $(am_dpfp_threaded_OBJECTS)
+dpfp_threaded_DEPENDENCIES = ../libusb/libusb-1.0.la
+dpfp_threaded_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(dpfp_threaded_CFLAGS) \
+ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+am_lsusb_OBJECTS = lsusb.$(OBJEXT)
+lsusb_OBJECTS = $(am_lsusb_OBJECTS)
+lsusb_DEPENDENCIES = ../libusb/libusb-1.0.la
+am_xusb_OBJECTS = xusb.$(OBJEXT)
+xusb_OBJECTS = $(am_xusb_OBJECTS)
+xusb_DEPENDENCIES = ../libusb/libusb-1.0.la
+DEFAULT_INCLUDES = -I. -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_$(V))
+am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY))
+am__v_CC_0 = @echo " CC " $@;
+AM_V_at = $(am__v_at_$(V))
+am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY))
+am__v_at_0 = @
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_$(V))
+am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY))
+am__v_CCLD_0 = @echo " CCLD " $@;
+AM_V_GEN = $(am__v_GEN_$(V))
+am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
+am__v_GEN_0 = @echo " GEN " $@;
+SOURCES = $(dpfp_SOURCES) $(dpfp_threaded_SOURCES) $(lsusb_SOURCES) \
+ $(xusb_SOURCES)
+DIST_SOURCES = $(dpfp_SOURCES) $(dpfp_threaded_SOURCES) \
+ $(lsusb_SOURCES) $(xusb_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = ${SHELL} /d/libusb-pbatard/missing --run aclocal-1.11
+AMTAR = ${SHELL} /d/libusb-pbatard/missing --run tar
+AM_CFLAGS = -Wshadow -std=gnu99 -Wall -Wundef -Wunused -Wstrict-prototypes -Werror-implicit-function-declaration
+AM_DEFAULT_VERBOSITY = 0
+AM_LDFLAGS = -no-undefined
+AR = ar
+AUTOCONF = ${SHELL} /d/libusb-pbatard/missing --run autoconf
+AUTOHEADER = ${SHELL} /d/libusb-pbatard/missing --run autoheader
+AUTOMAKE = ${SHELL} /d/libusb-pbatard/missing --run automake-1.11
+AWK = gawk
+CC = gcc
+CCDEPMODE = depmode=gcc3
+CFLAGS = -g -O2
+CPP = gcc -E
+CPPFLAGS =
+CYGPATH_W = echo
+DEFS = -DHAVE_CONFIG_H
+DEPDIR = .deps
+DLLTOOL = dlltool
+DSYMUTIL =
+DUMPBIN =
+ECHO_C =
+ECHO_N = -n
+ECHO_T =
+EGREP = /bin/grep -E
+EXEEXT = .exe
+FGREP = /bin/grep -F
+GREP = /bin/grep
+INSTALL = /bin/install -c
+INSTALL_DATA = ${INSTALL} -m 644
+INSTALL_PROGRAM = ${INSTALL}
+INSTALL_SCRIPT = ${INSTALL}
+INSTALL_STRIP_PROGRAM = $(install_sh) -c -s
+LD = e:/mingw/mingw32/bin/ld.exe
+LDFLAGS =
+LIBOBJS =
+LIBS = -lsetupapi -lole32
+LIBTOOL = $(SHELL) $(top_builddir)/libtool
+LIPO =
+LN_S = ln -s
+LTLIBOBJS =
+MAKEINFO = ${SHELL} /d/libusb-pbatard/missing --run makeinfo
+MKDIR_P = /bin/mkdir -p
+NM = /mingw/bin/nm
+NMEDIT =
+OBJDUMP = objdump
+OBJEXT = o
+OS_DARWIN =
+OS_LINUX =
+OS_WINDOWS =
+OTOOL =
+OTOOL64 =
+PACKAGE = libusb
+PACKAGE_BUGREPORT =
+PACKAGE_NAME = libusb
+PACKAGE_STRING = libusb 1.0.6
+PACKAGE_TARNAME = libusb
+PACKAGE_URL =
+PACKAGE_VERSION = 1.0.6
+PATH_SEPARATOR = :
+RANLIB = ranlib
+SED = /bin/sed
+SET_MAKE =
+SHELL = /bin/sh
+STRIP = strip
+VERSION = 1.0.6
+VISIBILITY_CFLAGS =
+abs_builddir = /d/libusb-pbatard/examples
+abs_srcdir = /d/libusb-pbatard/examples
+abs_top_builddir = /d/libusb-pbatard
+abs_top_srcdir = /d/libusb-pbatard
+ac_ct_CC = gcc
+ac_ct_DUMPBIN =
+am__include = include
+am__leading_dot = .
+am__quote =
+am__tar = ${AMTAR} chof - "$$tardir"
+am__untar = ${AMTAR} xf -
+bindir = ${exec_prefix}/bin
+build = i686-pc-mingw32
+build_alias =
+build_cpu = i686
+build_os = mingw32
+build_vendor = pc
+builddir = .
+datadir = ${datarootdir}
+datarootdir = ${prefix}/share
+docdir = ${datarootdir}/doc/${PACKAGE_TARNAME}
+dvidir = ${docdir}
+exec_prefix = ${prefix}
+host = i686-pc-mingw32
+host_alias =
+host_cpu = i686
+host_os = mingw32
+host_vendor = pc
+htmldir = ${docdir}
+includedir = ${prefix}/include
+infodir = ${datarootdir}/info
+install_sh = ${SHELL} /d/libusb-pbatard/install-sh
+libdir = ${exec_prefix}/lib
+libexecdir = ${exec_prefix}/libexec
+localedir = ${datarootdir}/locale
+localstatedir = ${prefix}/var
+lt_age = 0
+lt_major = 0
+lt_revision = 0
+mandir = ${datarootdir}/man
+mkdir_p = /bin/mkdir -p
+oldincludedir = /usr/include
+pdfdir = ${docdir}
+prefix = /usr/local
+program_transform_name = s,x,x,
+psdir = ${docdir}
+sbindir = ${exec_prefix}/sbin
+sharedstatedir = ${prefix}/com
+srcdir = .
+sysconfdir = ${prefix}/etc
+target_alias =
+to_host_path_cmd = func_msys_to_mingw_path_convert
+top_build_prefix = ../
+top_builddir = ..
+top_srcdir = ..
+INCLUDES = -I$(top_srcdir)
+DPFP_SRC = dpfp
+#DPFP_SRC = dpfp dpfp_threaded
+lsusb_SOURCES = lsusb.c
+lsusb_LDADD = ../libusb/libusb-1.0.la -lusb-1.0
+xusb_SOURCES = xusb.c
+xusb_LDADD = ../libusb/libusb-1.0.la -lusb-1.0
+dpfp_SOURCES = dpfp.c
+dpfp_LDADD = ../libusb/libusb-1.0.la -lusb-1.0
+dpfp_threaded_SOURCES = dpfp_threaded.c
+dpfp_threaded_CFLAGS = $(AM_CFLAGS)
+dpfp_threaded_LDADD = ../libusb/libusb-1.0.la -lusb-1.0
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu examples/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu examples/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstPROGRAMS:
+ @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+dpfp$(EXEEXT): $(dpfp_OBJECTS) $(dpfp_DEPENDENCIES)
+ @rm -f dpfp$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(dpfp_OBJECTS) $(dpfp_LDADD) $(LIBS)
+dpfp_threaded$(EXEEXT): $(dpfp_threaded_OBJECTS) $(dpfp_threaded_DEPENDENCIES)
+ @rm -f dpfp_threaded$(EXEEXT)
+ $(AM_V_CCLD)$(dpfp_threaded_LINK) $(dpfp_threaded_OBJECTS) $(dpfp_threaded_LDADD) $(LIBS)
+lsusb$(EXEEXT): $(lsusb_OBJECTS) $(lsusb_DEPENDENCIES)
+ @rm -f lsusb$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(lsusb_OBJECTS) $(lsusb_LDADD) $(LIBS)
+xusb$(EXEEXT): $(xusb_OBJECTS) $(xusb_DEPENDENCIES)
+ @rm -f xusb$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(xusb_OBJECTS) $(xusb_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+include ./$(DEPDIR)/dpfp.Po
+include ./$(DEPDIR)/dpfp_threaded-dpfp_threaded.Po
+include ./$(DEPDIR)/lsusb.Po
+include ./$(DEPDIR)/xusb.Po
+
+.c.o:
+ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+# $(AM_V_CC) \
+# source='$<' object='$@' libtool=no \
+# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
+# $(COMPILE) -c $<
+
+.c.obj:
+ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+# $(AM_V_CC) \
+# source='$<' object='$@' libtool=no \
+# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
+# $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+# $(AM_V_CC) \
+# source='$<' object='$@' libtool=yes \
+# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
+# $(LTCOMPILE) -c -o $@ $<
+
+dpfp_threaded-dpfp_threaded.o: dpfp_threaded.c
+ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dpfp_threaded_CFLAGS) $(CFLAGS) -MT dpfp_threaded-dpfp_threaded.o -MD -MP -MF $(DEPDIR)/dpfp_threaded-dpfp_threaded.Tpo -c -o dpfp_threaded-dpfp_threaded.o `test -f 'dpfp_threaded.c' || echo '$(srcdir)/'`dpfp_threaded.c
+ $(AM_V_at)$(am__mv) $(DEPDIR)/dpfp_threaded-dpfp_threaded.Tpo $(DEPDIR)/dpfp_threaded-dpfp_threaded.Po
+# $(AM_V_CC) \
+# source='dpfp_threaded.c' object='dpfp_threaded-dpfp_threaded.o' libtool=no \
+# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
+# $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dpfp_threaded_CFLAGS) $(CFLAGS) -c -o dpfp_threaded-dpfp_threaded.o `test -f 'dpfp_threaded.c' || echo '$(srcdir)/'`dpfp_threaded.c
+
+dpfp_threaded-dpfp_threaded.obj: dpfp_threaded.c
+ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dpfp_threaded_CFLAGS) $(CFLAGS) -MT dpfp_threaded-dpfp_threaded.obj -MD -MP -MF $(DEPDIR)/dpfp_threaded-dpfp_threaded.Tpo -c -o dpfp_threaded-dpfp_threaded.obj `if test -f 'dpfp_threaded.c'; then $(CYGPATH_W) 'dpfp_threaded.c'; else $(CYGPATH_W) '$(srcdir)/dpfp_threaded.c'; fi`
+ $(AM_V_at)$(am__mv) $(DEPDIR)/dpfp_threaded-dpfp_threaded.Tpo $(DEPDIR)/dpfp_threaded-dpfp_threaded.Po
+# $(AM_V_CC) \
+# source='dpfp_threaded.c' object='dpfp_threaded-dpfp_threaded.obj' libtool=no \
+# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
+# $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dpfp_threaded_CFLAGS) $(CFLAGS) -c -o dpfp_threaded-dpfp_threaded.obj `if test -f 'dpfp_threaded.c'; then $(CYGPATH_W) 'dpfp_threaded.c'; else $(CYGPATH_W) '$(srcdir)/dpfp_threaded.c'; fi`
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(PROGRAMS)
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-noinstPROGRAMS ctags distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+ pdf pdf-am ps ps-am tags uninstall uninstall-am
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/examples/xusb_sources b/examples/xusb_sources
index f69b9e0..0509bef 100644
--- a/examples/xusb_sources
+++ b/examples/xusb_sources
@@ -1,7 +1,8 @@
TARGETNAME=xusb
TARGETTYPE=PROGRAM
+TARGETPATH=obj
-_NT_TARGET_VERSION= $(_NT_TARGET_VERSION_WINXP)
+#_NT_TARGET_VERSION= $(_NT_TARGET_VERSION_WINXP)
!IFNDEF MSC_WARNING_LEVEL
@@ -16,6 +17,7 @@ USE_MSVCRT=1
UMTYPE=console
INCLUDES=..\..\msvc;..\..;$(DDK_INC_PATH)
+C_DEFINES = $(C_DEFINES) /D_MSC_VER=1200
UMLIBS=..\..\libusb\os\obj$(BUILD_ALT_DIR)\*\libusb-1.0.lib
diff --git a/libusb/os/driver/abort_endpoint.c b/libusb/os/driver/abort_endpoint.c
new file mode 100644
index 0000000..e8dd05a
--- /dev/null
+++ b/libusb/os/driver/abort_endpoint.c
@@ -0,0 +1,59 @@
+/* LIBUSB-WIN32, Generic Windows USB Library
+ * Copyright (c) 2002-2005 Stephan Meyer <ste_meyer@web.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#include "libusb_driver.h"
+
+
+
+NTSTATUS abort_endpoint(libusb_device_t *dev, int endpoint, int timeout)
+{
+ NTSTATUS status = STATUS_SUCCESS;
+ URB urb;
+
+ DEBUG_PRINT_NL();
+ DEBUG_MESSAGE("abort_endpoint(): endpoint 0x%02x\n", endpoint);
+ DEBUG_MESSAGE("abort_endpoint(): timeout %d\n", timeout);
+
+ memset(&urb, 0, sizeof(struct _URB_PIPE_REQUEST));
+
+ if(!dev->config.value)
+ {
+ DEBUG_ERROR("abort_endpoint(): invalid configuration 0");
+ return STATUS_INVALID_DEVICE_STATE;
+ }
+
+ if(!get_pipe_handle(dev, endpoint, &urb.UrbPipeRequest.PipeHandle))
+ {
+ DEBUG_ERROR("abort_endpoint(): getting endpoint pipe failed");
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ urb.UrbHeader.Length = (USHORT) sizeof(struct _URB_PIPE_REQUEST);
+ urb.UrbHeader.Function = URB_FUNCTION_ABORT_PIPE;
+
+ status = call_usbd(dev, &urb, IOCTL_INTERNAL_USB_SUBMIT_URB, timeout);
+
+ if(!NT_SUCCESS(status) || !USBD_SUCCESS(urb.UrbHeader.Status))
+ {
+ DEBUG_ERROR("abort_endpoint(): request failed: status: 0x%x, "
+ "urb-status: 0x%x", status, urb.UrbHeader.Status);
+ }
+
+ return status;
+}
diff --git a/libusb/os/driver/claim_interface.c b/libusb/os/driver/claim_interface.c
new file mode 100644
index 0000000..996750b
--- /dev/null
+++ b/libusb/os/driver/claim_interface.c
@@ -0,0 +1,58 @@
+/* LIBUSB-WIN32, Generic Windows USB Library
+ * Copyright (c) 2002-2005 Stephan Meyer <ste_meyer@web.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+
+#include "libusb_driver.h"
+
+
+
+NTSTATUS claim_interface(libusb_device_t *dev, int interface)
+{
+ DEBUG_MESSAGE("claim_interface(): interface %d", interface);
+
+ if(!dev->config.value)
+ {
+ DEBUG_ERROR("claim_interface(): device is not configured");
+ return STATUS_INVALID_DEVICE_STATE;
+ }
+
+ if(interface >= LIBUSB0_MAX_NUMBER_OF_INTERFACES)
+ {
+ DEBUG_ERROR("claim_interface(): interface number %d too high",
+ interface);
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ if(!dev->config.interfaces[interface].valid)
+ {
+ DEBUG_ERROR("claim_interface(): interface %d does not exist", interface);
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ if(dev->config.interfaces[interface].claimed)
+ {
+ DEBUG_ERROR("claim_interface(): could not claim interface %d, "
+ "interface is already claimed", interface);
+ return STATUS_DEVICE_BUSY;
+ }
+
+ dev->config.interfaces[interface].claimed = TRUE;
+
+ return STATUS_SUCCESS;
+}
diff --git a/libusb/os/driver/clear_feature.c b/libusb/os/driver/clear_feature.c
new file mode 100644
index 0000000..7dad94f
--- /dev/null
+++ b/libusb/os/driver/clear_feature.c
@@ -0,0 +1,69 @@
+/* LIBUSB-WIN32, Generic Windows USB Library
+ * Copyright (c) 2002-2005 Stephan Meyer <ste_meyer@web.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#include "libusb_driver.h"
+
+NTSTATUS clear_feature(libusb_device_t *dev,
+ int recipient, int index, int feature, int timeout)
+{
+ NTSTATUS status = STATUS_SUCCESS;
+ URB urb;
+
+ DEBUG_PRINT_NL();
+ DEBUG_MESSAGE("clear_feature(): recipient %02d", recipient);
+ DEBUG_MESSAGE("clear_feature(): index %04d", index);
+ DEBUG_MESSAGE("clear_feature(): feature %04d", feature);
+ DEBUG_MESSAGE("clear_feature(): timeout %d", timeout);
+
+
+ memset(&urb, 0, sizeof(struct _URB_CONTROL_FEATURE_REQUEST));
+
+ switch(recipient)
+ {
+ case USB_RECIP_DEVICE:
+ urb.UrbHeader.Function = URB_FUNCTION_CLEAR_FEATURE_TO_DEVICE;
+ break;
+ case USB_RECIP_INTERFACE:
+ urb.UrbHeader.Function = URB_FUNCTION_CLEAR_FEATURE_TO_INTERFACE;
+ break;
+ case USB_RECIP_ENDPOINT:
+ urb.UrbHeader.Function = URB_FUNCTION_CLEAR_FEATURE_TO_ENDPOINT;
+ break;
+ case USB_RECIP_OTHER:
+ urb.UrbHeader.Function = URB_FUNCTION_CLEAR_FEATURE_TO_OTHER;
+ break;
+ default:
+ DEBUG_ERROR("clear_feature(): invalid recipient");
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ urb.UrbHeader.Length = sizeof(struct _URB_CONTROL_FEATURE_REQUEST);
+ urb.UrbControlFeatureRequest.FeatureSelector = (USHORT)feature;
+ urb.UrbControlFeatureRequest.Index = (USHORT)index;
+
+ status = call_usbd(dev, &urb, IOCTL_INTERNAL_USB_SUBMIT_URB, timeout);
+
+ if(!NT_SUCCESS(status) || !USBD_SUCCESS(urb.UrbHeader.Status))
+ {
+ DEBUG_ERROR("set_feature(): clearing feature failed: status: 0x%x, "
+ "urb-status: 0x%x", status, urb.UrbHeader.Status);
+ }
+
+ return status;
+}
diff --git a/libusb/os/driver/common.rc b/libusb/os/driver/common.rc
new file mode 100644
index 0000000..5e515f4
--- /dev/null
+++ b/libusb/os/driver/common.rc
@@ -0,0 +1,53 @@
+/* LIBUSB-WIN32, Generic Windows USB Library
+ * Copyright (c) 2002-2005 Stephan Meyer <ste_meyer@web.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <winver.h>
+
+#define RT_MANIFEST 24
+#define ID_MANIFEST 1
+
+VS_VERSION_INFO VERSIONINFO
+FILEVERSION RC_VERSION
+PRODUCTVERSION RC_VERSION
+FILEFLAGSMASK 0x3FL
+FILEFLAGS 0x0L
+FILEOS VOS_NT_WINDOWS32
+FILETYPE RC_FILE_TYPE
+FILESUBTYPE RC_FILE_SUB_TYPE
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "CompanyName", "http://libusb-win32.sourceforge.net"
+ VALUE "FileDescription", RC_PRODUCT_STR
+ VALUE "FileVersion", RC_VERSION_STR
+ VALUE "InternalName", RC_FILE_NAME_STR
+ VALUE "LegalCopyright", "@ 2002-2005 S. Meyer, <ste_meyer@web.de>"
+ VALUE "OriginalFilename",RC_FILE_NAME_STR
+ VALUE "ProductName", RC_PRODUCT_STR
+ VALUE "ProductVersion", RC_VERSION_STR
+ END
+ END
+
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
diff --git a/libusb/os/driver/dispatch.c b/libusb/os/driver/dispatch.c
new file mode 100644
index 0000000..98cd8e8
--- /dev/null
+++ b/libusb/os/driver/dispatch.c
@@ -0,0 +1,95 @@
+/* LIBUSB-WIN32, Generic Windows USB Library
+ * Copyright (c) 2002-2005 Stephan Meyer <ste_meyer@web.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#include "libusb_driver.h"
+
+NTSTATUS DDKAPI dispatch(DEVICE_OBJECT *device_object, IRP *irp)
+{
+ libusb_device_t *dev = device_object->DeviceExtension;
+
+ switch(IoGetCurrentIrpStackLocation(irp)->MajorFunction)
+ {
+ case IRP_MJ_PNP:
+ return dispatch_pnp(dev, irp);
+
+ case IRP_MJ_POWER:
+ return dispatch_power(dev, irp);
+ }
+
+ /* since this driver may run as an upper filter we have to check whether */
+ /* the IRP is sent to this device object or to the lower one */
+ if(accept_irp(dev, irp))
+ {
+ switch(IoGetCurrentIrpStackLocation(irp)->MajorFunction)
+ {
+ case IRP_MJ_DEVICE_CONTROL:
+
+ if(dev->is_started)
+ {
+ return dispatch_ioctl(dev, irp);
+ }
+ else /* not started yet */
+ {
+ return complete_irp(irp, STATUS_INVALID_DEVICE_STATE, 0);
+ }
+
+ case IRP_MJ_CREATE:
+
+ if(dev->is_started)
+ {
+ if(InterlockedIncrement(&dev->ref_count) == 1)
+ {
+ if(dev->power_state.DeviceState != PowerDeviceD0)
+ {
+ /* power up the device, block until the call */
+ /* completes */
+ power_set_device_state(dev, PowerDeviceD0, TRUE);
+ }
+ }
+
+ return complete_irp(irp, STATUS_SUCCESS, 0);
+ }
+ else /* not started yet */
+ {
+ return complete_irp(irp, STATUS_INVALID_DEVICE_STATE, 0);
+ }
+
+ case IRP_MJ_CLOSE:
+
+ if(!InterlockedDecrement(&dev->ref_count))
+ {
+ /* release all interfaces when the last handle is closed */
+ release_all_interfaces(dev);
+ }
+ return complete_irp(irp, STATUS_SUCCESS, 0);
+
+ case IRP_MJ_CLEANUP:
+
+ return complete_irp(irp, STATUS_SUCCESS, 0);
+
+ default:
+ return complete_irp(irp, STATUS_NOT_SUPPORTED, 0);
+ }
+ }
+ else /* the IRP is for the lower device object */
+ {
+ return pass_irp_down(dev, irp, NULL, NULL);
+ }
+}
+
diff --git a/libusb/os/driver/driver_api.h b/libusb/os/driver/driver_api.h
new file mode 100644
index 0000000..44d9a66
--- /dev/null
+++ b/libusb/os/driver/driver_api.h
@@ -0,0 +1,165 @@
+/* LIBUSB-WIN32, Generic Windows USB Library
+ * Copyright (c) 2002-2005 Stephan Meyer <ste_meyer@web.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#ifndef __DRIVER_API_H__
+#define __DRIVER_API_H__
+
+enum {
+ LIBUSB0_DEBUG_OFF,
+ LIBUSB0_DEBUG_ERR,
+ LIBUSB0_DEBUG_MSG,
+};
+
+
+/* 64k */
+#define LIBUSB0_MAX_READ_WRITE 0x10000
+
+#define LIBUSB0_MAX_NUMBER_OF_DEVICES 256
+#define LIBUSB0_MAX_NUMBER_OF_CHILDREN 32
+
+#define LIBUSB0_IOCTL_SET_CONFIGURATION CTL_CODE(FILE_DEVICE_UNKNOWN,\
+0x801, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#define LIBUSB0_IOCTL_GET_CONFIGURATION CTL_CODE(FILE_DEVICE_UNKNOWN,\
+0x802, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#define LIBUSB0_IOCTL_SET_INTERFACE CTL_CODE(FILE_DEVICE_UNKNOWN,\
+0x803, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#define LIBUSB0_IOCTL_GET_INTERFACE CTL_CODE(FILE_DEVICE_UNKNOWN,\
+0x804, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#define LIBUSB0_IOCTL_SET_FEATURE CTL_CODE(FILE_DEVICE_UNKNOWN,\
+0x805, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#define LIBUSB0_IOCTL_CLEAR_FEATURE CTL_CODE(FILE_DEVICE_UNKNOWN,\
+0x806, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#define LIBUSB0_IOCTL_GET_STATUS CTL_CODE(FILE_DEVICE_UNKNOWN,\
+0x807, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#define LIBUSB0_IOCTL_SET_DESCRIPTOR CTL_CODE(FILE_DEVICE_UNKNOWN,\
+0x808, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#define LIBUSB0_IOCTL_GET_DESCRIPTOR CTL_CODE(FILE_DEVICE_UNKNOWN,\
+0x809, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#define LIBUSB0_IOCTL_INTERRUPT_OR_BULK_WRITE CTL_CODE(FILE_DEVICE_UNKNOWN,\
+0x80A, METHOD_IN_DIRECT, FILE_ANY_ACCESS)
+
+#define LIBUSB0_IOCTL_INTERRUPT_OR_BULK_READ CTL_CODE(FILE_DEVICE_UNKNOWN,\
+0x80B, METHOD_OUT_DIRECT, FILE_ANY_ACCESS)
+
+#define LIBUSB0_IOCTL_VENDOR_WRITE CTL_CODE(FILE_DEVICE_UNKNOWN,\
+0x80C, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#define LIBUSB0_IOCTL_VENDOR_READ CTL_CODE(FILE_DEVICE_UNKNOWN,\
+0x80D, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#define LIBUSB0_IOCTL_RESET_ENDPOINT CTL_CODE(FILE_DEVICE_UNKNOWN,\
+0x80E, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#define LIBUSB0_IOCTL_ABORT_ENDPOINT CTL_CODE(FILE_DEVICE_UNKNOWN,\
+0x80F, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#define LIBUSB0_IOCTL_RESET_DEVICE CTL_CODE(FILE_DEVICE_UNKNOWN,\
+0x810, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#define LIBUSB0_IOCTL_SET_DEBUG_LEVEL CTL_CODE(FILE_DEVICE_UNKNOWN,\
+0x811, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#define LIBUSB0_IOCTL_GET_VERSION CTL_CODE(FILE_DEVICE_UNKNOWN,\
+0x812, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#define LIBUSB0_IOCTL_ISOCHRONOUS_WRITE CTL_CODE(FILE_DEVICE_UNKNOWN,\
+0x813, METHOD_IN_DIRECT, FILE_ANY_ACCESS)
+
+#define LIBUSB0_IOCTL_ISOCHRONOUS_READ CTL_CODE(FILE_DEVICE_UNKNOWN,\
+0x814, METHOD_OUT_DIRECT, FILE_ANY_ACCESS)
+
+#define LIBUSB0_IOCTL_CLAIM_INTERFACE CTL_CODE(FILE_DEVICE_UNKNOWN,\
+0x815, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#define LIBUSB0_IOCTL_RELEASE_INTERFACE CTL_CODE(FILE_DEVICE_UNKNOWN,\
+0x816, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#include <pshpack1.h>
+
+
+typedef struct {
+ unsigned int timeout;
+ union {
+ struct
+ {
+ unsigned int configuration;
+ } configuration;
+ struct
+ {
+ unsigned int interface;
+ unsigned int altsetting;
+ } interface;
+ struct
+ {
+ unsigned int endpoint;
+ unsigned int packet_size;
+ } endpoint;
+ struct
+ {
+ unsigned int type;
+ unsigned int recipient;
+ unsigned int request;
+ unsigned int value;
+ unsigned int index;
+ } vendor;
+ struct
+ {
+ unsigned int recipient;
+ unsigned int feature;
+ unsigned int index;
+ } feature;
+ struct
+ {
+ unsigned int recipient;
+ unsigned int index;
+ unsigned int status;
+ } status;
+ struct
+ {
+ unsigned int type;
+ unsigned int index;
+ unsigned int language_id;
+ unsigned int recipient;
+ } descriptor;
+ struct
+ {
+ unsigned int level;
+ } debug;
+ struct
+ {
+ unsigned int major;
+ unsigned int minor;
+ unsigned int micro;
+ unsigned int nano;
+ } version;
+ };
+} libusb0_request;
+
+#include <poppack.h>
+
+#endif
diff --git a/libusb/os/driver/driver_debug.c b/libusb/os/driver/driver_debug.c
new file mode 100644
index 0000000..d10ffda
--- /dev/null
+++ b/libusb/os/driver/driver_debug.c
@@ -0,0 +1,75 @@
+/* LIBUSB-WIN32, Generic Windows USB Library
+ * Copyright (c) 2002-2005 Stephan Meyer <ste_meyer@web.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#include "libusb_driver.h"
+#include <stdio.h>
+#include <stdarg.h>
+
+int debug_level = LIBUSB0_DEBUG_MSG;
+
+void DEBUG_PRINT_NL()
+{
+#ifdef DBG
+ if(debug_level >= LIBUSB0_DEBUG_MSG)
+ DbgPrint(("\n"));
+#endif
+}
+
+void DEBUG_SET_LEVEL(int level)
+{
+#ifdef DBG
+ debug_level = level;
+#endif
+}
+
+void DEBUG_MESSAGE(const char *format, ...)
+{
+#ifdef DBG
+
+ char tmp[256];
+
+ if(debug_level >= LIBUSB0_DEBUG_MSG)
+ {
+ va_list args;
+ va_start(args, format);
+ _vsnprintf(tmp, sizeof(tmp) - 1, format, args);
+ va_end(args);
+
+ DbgPrint("LIBUSB-DRIVER - %s", tmp);
+ }
+#endif
+}
+
+void DEBUG_ERROR(const char *format, ...)
+{
+#ifdef DBG
+
+ char tmp[256];
+
+ if(debug_level >= LIBUSB0_DEBUG_ERR)
+ {
+ va_list args;
+ va_start(args, format);
+ _vsnprintf(tmp, sizeof(tmp) - 1, format, args);
+ va_end(args);
+
+ DbgPrint("LIBUSB-DRIVER - %s", tmp);
+ }
+#endif
+}
diff --git a/libusb/os/driver/driver_debug.h b/libusb/os/driver/driver_debug.h
new file mode 100644
index 0000000..a4f396f
--- /dev/null
+++ b/libusb/os/driver/driver_debug.h
@@ -0,0 +1,30 @@
+/* LIBUSB-WIN32, Generic Windows USB Library
+ * Copyright (c) 2002-2005 Stephan Meyer <ste_meyer@web.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#ifndef __LIBUSB_DEBUG_H__
+#define __LIBUSB_DEBUG_H__
+
+
+void DEBUG_PRINT_NL();
+void DEBUG_SET_LEVEL(int level);
+void DEBUG_MESSAGE(const char *format, ...);
+void DEBUG_ERROR(const char *format, ...);
+
+
+#endif
diff --git a/libusb/os/driver/driver_registry.c b/libusb/os/driver/driver_registry.c
new file mode 100644
index 0000000..aa4b5d2
--- /dev/null
+++ b/libusb/os/driver/driver_registry.c
@@ -0,0 +1,134 @@
+/* LIBUSB-WIN32, Generic Windows USB Library
+ * Copyright (c) 2002-2005 Stephan Meyer <ste_meyer@web.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#include "libusb_driver.h"
+
+/* missing in mingw's ddk headers */
+#ifndef PLUGPLAY_REGKEY_DEVICE
+#define PLUGPLAY_REGKEY_DEVICE 1
+#endif
+
+#define LIBUSB_REG_SURPRISE_REMOVAL_OK L"SurpriseRemovalOK"
+
+
+static bool_t reg_get_property(DEVICE_OBJECT *physical_device_object,
+ int property, char *data, int size);
+
+static bool_t reg_get_property(DEVICE_OBJECT *physical_device_object,
+ int property, char *data, int size)
+{
+ WCHAR tmp[512];
+ ULONG ret;
+ ULONG i;
+
+ if(!physical_device_object || !data || !size)
+ {
+ return FALSE;
+ }
+
+ memset(data, 0, size);
+ memset(tmp, 0, sizeof(tmp));
+
+ if(NT_SUCCESS(IoGetDeviceProperty(physical_device_object,
+ property,
+ sizeof(tmp) - 2,
+ tmp,
+ &ret)) && ret)
+ {
+ /* convert unicode string to normal character string */
+ for(i = 0; (i < ret/2) && (i < ((ULONG)size - 1)); i++)
+ {
+ data[i] = (char)tmp[i];
+ }
+
+ _strlwr(data);
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+bool_t reg_get_properties(libusb_device_t *dev)
+{
+ HANDLE key = NULL;
+ NTSTATUS status;
+ UNICODE_STRING name;
+ KEY_VALUE_FULL_INFORMATION *info;
+ ULONG length;
+
+ if(!dev->physical_device_object)
+ {
+ return FALSE;
+ }
+
+ /* default settings */
+ dev->surprise_removal_ok = FALSE;
+ dev->is_filter = TRUE;
+
+ status = IoOpenDeviceRegistryKey(dev->physical_device_object,
+ PLUGPLAY_REGKEY_DEVICE,
+ STANDARD_RIGHTS_ALL,
+ &key);
+ if(NT_SUCCESS(status))
+ {
+ RtlInitUnicodeString(&name, LIBUSB_REG_SURPRISE_REMOVAL_OK);
+
+ length = sizeof(KEY_VALUE_FULL_INFORMATION) + name.MaximumLength
+ + sizeof(ULONG);
+
+ info = ExAllocatePool(NonPagedPool, length);
+
+ if(info)
+ {
+ memset(info, 0, length);
+
+ status = ZwQueryValueKey(key, &name, KeyValueFullInformation,
+ info, length, &length);
+
+ if(NT_SUCCESS(status) && (info->Type == REG_DWORD))
+ {
+ ULONG val = *((ULONG *)(((char *)info) + info->DataOffset));
+
+ dev->surprise_removal_ok = val ? TRUE : FALSE;
+ dev->is_filter = FALSE;
+ }
+
+ ExFreePool(info);
+ }
+
+ ZwClose(key);
+ }
+
+ return TRUE;
+}
+
+bool_t reg_get_hardware_id(DEVICE_OBJECT *physical_device_object,
+ char *data, int size)
+{
+ if(!physical_device_object || !data || !size)
+ {
+ return FALSE;
+ }
+
+ return reg_get_property(physical_device_object, DevicePropertyHardwareID,
+ data, size);
+}
+
diff --git a/libusb/os/driver/get_configuration.c b/libusb/os/driver/get_configuration.c
new file mode 100644
index 0000000..1f4aa1e
--- /dev/null
+++ b/libusb/os/driver/get_configuration.c
@@ -0,0 +1,58 @@
+/* LIBUSB-WIN32, Generic Windows USB Library
+ * Copyright (c) 2002-2005 Stephan Meyer <ste_meyer@web.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#include "libusb_driver.h"
+
+
+NTSTATUS get_configuration(libusb_device_t *dev,
+ unsigned char *configuration, int *ret,
+ int timeout)
+{
+ NTSTATUS status = STATUS_SUCCESS;
+ URB urb;
+
+ DEBUG_PRINT_NL();
+ DEBUG_MESSAGE("get_configuration(): timeout %d", timeout);
+
+ memset(&urb, 0, sizeof(URB));
+
+ urb.UrbHeader.Function = URB_FUNCTION_GET_CONFIGURATION;
+ urb.UrbHeader.Length = sizeof(struct _URB_CONTROL_GET_CONFIGURATION_REQUEST);
+ urb.UrbControlGetConfigurationRequest.TransferBufferLength = 1;
+ urb.UrbControlGetConfigurationRequest.TransferBuffer = configuration;
+
+
+ status = call_usbd(dev, &urb, IOCTL_INTERNAL_USB_SUBMIT_URB, timeout);
+
+ if(!NT_SUCCESS(status) || !USBD_SUCCESS(urb.UrbHeader.Status))
+ {
+ DEBUG_ERROR("get_configuration(): getting configuration failed: "
+ "status: 0x%x, urb-status: 0x%x",
+ status, urb.UrbHeader.Status);
+ *ret = 0;
+ }
+ else
+ {
+ DEBUG_MESSAGE("get_configuration(): current configuration is: %d",
+ *configuration);
+ *ret = urb.UrbControlGetConfigurationRequest.TransferBufferLength;
+ }
+
+ return status;
+}
diff --git a/libusb/os/driver/get_descriptor.c b/libusb/os/driver/get_descriptor.c
new file mode 100644
index 0000000..ef1a5d8
--- /dev/null
+++ b/libusb/os/driver/get_descriptor.c
@@ -0,0 +1,158 @@
+/* LIBUSB-WIN32, Generic Windows USB Library
+ * Copyright (c) 2002-2005 Stephan Meyer <ste_meyer@web.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#include "libusb_driver.h"
+
+
+
+NTSTATUS get_descriptor(libusb_device_t *dev,
+ void *buffer, int size, int type, int recipient,
+ int index, int language_id, int *received, int timeout)
+{
+ NTSTATUS status = STATUS_SUCCESS;
+ URB urb;
+
+ DEBUG_PRINT_NL();
+ DEBUG_MESSAGE("get_descriptor(): buffer size %d", size);
+ DEBUG_MESSAGE("get_descriptor(): type %04d", type);
+ DEBUG_MESSAGE("get_descriptor(): recipient %04d", recipient);
+ DEBUG_MESSAGE("get_descriptor(): index %04d", index);
+ DEBUG_MESSAGE("get_descriptor(): language id %04d", language_id);
+ DEBUG_MESSAGE("get_descriptor(): timeout %d", timeout);
+
+
+ memset(&urb, 0, sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST));
+
+ switch(recipient)
+ {
+ case USB_RECIP_DEVICE:
+ urb.UrbHeader.Function = URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE;
+ break;
+ case USB_RECIP_INTERFACE:
+ urb.UrbHeader.Function = URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE;
+ break;
+ case USB_RECIP_ENDPOINT:
+ urb.UrbHeader.Function = URB_FUNCTION_GET_DESCRIPTOR_FROM_ENDPOINT;
+ break;
+ default:
+ DEBUG_ERROR("get_descriptor(): invalid recipient");
+ return STATUS_INVALID_PARAMETER;
+ }
+
+
+ urb.UrbHeader.Length = sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST);
+ urb.UrbControlDescriptorRequest.TransferBufferLength = size;
+ urb.UrbControlDescriptorRequest.TransferBuffer = buffer;
+ urb.UrbControlDescriptorRequest.DescriptorType = (UCHAR)type;
+ urb.UrbControlDescriptorRequest.Index = (UCHAR)index;
+ urb.UrbControlDescriptorRequest.LanguageId = (USHORT)language_id;
+
+
+ status = call_usbd(dev, &urb, IOCTL_INTERNAL_USB_SUBMIT_URB, timeout);
+
+
+ if(!NT_SUCCESS(status) || !USBD_SUCCESS(urb.UrbHeader.Status))
+ {
+ DEBUG_ERROR("get_descriptor(): getting descriptor "
+ "failed: status: 0x%x, urb-status: 0x%x",
+ status, urb.UrbHeader.Status);
+ *received = 0;
+ }
+ else
+ {
+ *received = urb.UrbControlDescriptorRequest.TransferBufferLength;
+ }
+
+ return status;
+}
+
+USB_CONFIGURATION_DESCRIPTOR *
+get_config_descriptor(libusb_device_t *dev, int value, int *size)
+{
+ NTSTATUS status;
+ USB_CONFIGURATION_DESCRIPTOR *desc = NULL;
+ USB_DEVICE_DESCRIPTOR device_descriptor;
+ int i;
+ volatile int desc_size;
+
+ status = get_descriptor(dev, &device_descriptor,
+ sizeof(USB_DEVICE_DESCRIPTOR),
+ USB_DEVICE_DESCRIPTOR_TYPE,
+ USB_RECIP_DEVICE,
+ 0, 0, size, LIBUSB0_DEFAULT_TIMEOUT);
+
+ if(!NT_SUCCESS(status) || *size != sizeof(USB_DEVICE_DESCRIPTOR))
+ {
+ DEBUG_ERROR("get_config_descriptor(): getting device descriptor failed");
+ return NULL;
+ }
+
+ if(!(desc = ExAllocatePool(NonPagedPool,
+ sizeof(USB_CONFIGURATION_DESCRIPTOR))))
+ {
+ DEBUG_ERROR("get_config_descriptor(): memory allocation error");
+ return NULL;
+ }
+
+ for(i = 0; i < device_descriptor.bNumConfigurations; i++)
+ {
+
+ if(!NT_SUCCESS(get_descriptor(dev, desc,
+ sizeof(USB_CONFIGURATION_DESCRIPTOR),
+ USB_CONFIGURATION_DESCRIPTOR_TYPE,
+ USB_RECIP_DEVICE,
+ i, 0, size, LIBUSB0_DEFAULT_TIMEOUT)))
+ {
+ DEBUG_ERROR("get_config_descriptor(): getting configuration "
+ "descriptor failed");
+ break;
+ }
+
+ if(desc->bConfigurationValue == value)
+ {
+ desc_size = desc->wTotalLength;
+ ExFreePool(desc);
+
+ if(!(desc = ExAllocatePool(NonPagedPool, desc_size)))
+ {
+ DEBUG_ERROR("get_config_descriptor(): memory allocation error");
+ break;
+ }
+
+ if(!NT_SUCCESS(get_descriptor(dev, desc, desc_size,
+ USB_CONFIGURATION_DESCRIPTOR_TYPE,
+ USB_RECIP_DEVICE,
+ i, 0, size, LIBUSB0_DEFAULT_TIMEOUT)))
+ {
+ DEBUG_ERROR("get_config_descriptor(): getting configuration "
+ "descriptor failed");
+ break;
+ }
+
+ return desc;
+ }
+ }
+
+ if(desc)
+ {
+ ExFreePool(desc);
+ }
+
+ return NULL;
+}
diff --git a/libusb/os/driver/get_interface.c b/libusb/os/driver/get_interface.c
new file mode 100644
index 0000000..de0baeb
--- /dev/null
+++ b/libusb/os/driver/get_interface.c
@@ -0,0 +1,67 @@
+/* LIBUSB-WIN32, Generic Windows USB Library
+ * Copyright (c) 2002-2005 Stephan Meyer <ste_meyer@web.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#include "libusb_driver.h"
+
+
+
+NTSTATUS get_interface(libusb_device_t *dev,
+ int interface, unsigned char *altsetting,
+ int *ret, int timeout)
+{
+ NTSTATUS status = STATUS_SUCCESS;
+ URB urb;
+
+ DEBUG_PRINT_NL();
+ DEBUG_MESSAGE("get_interface(): interface %d", interface);
+ DEBUG_MESSAGE("get_interface(): timeout %d", timeout);
+
+ if(!dev->config.value)
+ {
+ DEBUG_ERROR("get_interface(): invalid configuration 0");
+ return STATUS_INVALID_DEVICE_STATE;
+ }
+
+ memset(&urb, 0, sizeof(URB));
+
+ urb.UrbHeader.Function = URB_FUNCTION_GET_INTERFACE;
+ urb.UrbHeader.Length = sizeof(struct _URB_CONTROL_GET_INTERFACE_REQUEST);
+ urb.UrbControlGetInterfaceRequest.TransferBufferLength = 1;
+ urb.UrbControlGetInterfaceRequest.TransferBuffer = altsetting;
+ urb.UrbControlGetInterfaceRequest.Interface = (USHORT)interface;
+
+ status = call_usbd(dev, &urb, IOCTL_INTERNAL_USB_SUBMIT_URB, timeout);
+
+ if(!NT_SUCCESS(status) || !USBD_SUCCESS(urb.UrbHeader.Status))
+ {
+ DEBUG_ERROR("get_interface(): getting interface "
+ "failed: status: 0x%x, urb-status: 0x%x",
+ status, urb.UrbHeader.Status);
+ *ret = 0;
+ }
+ else
+ {
+ *ret = urb.UrbControlGetInterfaceRequest.TransferBufferLength;
+ DEBUG_MESSAGE("get_interface(): current altsetting is %d", *altsetting);
+ }
+
+ return status;
+}
+
+
diff --git a/libusb/os/driver/get_status.c b/libusb/os/driver/get_status.c
new file mode 100644
index 0000000..a60689a
--- /dev/null
+++ b/libusb/os/driver/get_status.c
@@ -0,0 +1,77 @@
+/* LIBUSB-WIN32, Generic Windows USB Library
+ * Copyright (c) 2002-2005 Stephan Meyer <ste_meyer@web.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#include "libusb_driver.h"
+
+
+
+NTSTATUS get_status(libusb_device_t *dev, int recipient,
+ int index, char *status, int *ret, int timeout)
+{
+ NTSTATUS _status = STATUS_SUCCESS;
+ URB urb;
+
+ DEBUG_PRINT_NL();
+ DEBUG_MESSAGE("get_status(): recipient %02d", recipient);
+ DEBUG_MESSAGE("get_status(): index %04d", index);
+ DEBUG_MESSAGE("get_status(): timeout %d", timeout);
+
+ memset(&urb, 0, sizeof(URB));
+
+ switch(recipient)
+ {
+ case USB_RECIP_DEVICE:
+ urb.UrbHeader.Function = URB_FUNCTION_GET_STATUS_FROM_DEVICE;
+ break;
+ case USB_RECIP_INTERFACE:
+ urb.UrbHeader.Function = URB_FUNCTION_GET_STATUS_FROM_INTERFACE;
+ break;
+ case USB_RECIP_ENDPOINT:
+ urb.UrbHeader.Function = URB_FUNCTION_GET_STATUS_FROM_ENDPOINT;
+ break;
+ case USB_RECIP_OTHER:
+ urb.UrbHeader.Function = URB_FUNCTION_GET_STATUS_FROM_OTHER;
+ break;
+ default:
+ DEBUG_ERROR("get_status(): invalid recipient");
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ urb.UrbHeader.Length = sizeof(struct _URB_CONTROL_GET_STATUS_REQUEST);
+ urb.UrbControlGetStatusRequest.TransferBufferLength = 2;
+ urb.UrbControlGetStatusRequest.TransferBuffer = status;
+ urb.UrbControlGetStatusRequest.Index = (USHORT)index;
+
+ _status = call_usbd(dev, &urb, IOCTL_INTERNAL_USB_SUBMIT_URB, timeout);
+
+ if(!NT_SUCCESS(_status) || !USBD_SUCCESS(urb.UrbHeader.Status))
+ {
+ DEBUG_ERROR("get_status(): getting status failed: "
+ "status: 0x%x, urb-status: 0x%x",
+ _status, urb.UrbHeader.Status);
+ *ret = 0;
+ }
+ else
+ {
+ *ret = urb.UrbControlGetStatusRequest.TransferBufferLength;
+ }
+
+ return _status;
+}
+
diff --git a/libusb/os/driver/ioctl.c b/libusb/os/driver/ioctl.c
new file mode 100644
index 0000000..d6fdb32
--- /dev/null
+++ b/libusb/os/driver/ioctl.c
@@ -0,0 +1,332 @@
+/* LIBUSB-WIN32, Generic Windows USB Library
+ * Copyright (c) 2002-2005 Stephan Meyer <ste_meyer@web.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#include "libusb_driver.h"
+
+
+NTSTATUS dispatch_ioctl(libusb_device_t *dev, IRP *irp)
+{
+ int ret = 0;
+ NTSTATUS status = STATUS_SUCCESS;
+
+ IO_STACK_LOCATION *stack_location = IoGetCurrentIrpStackLocation(irp);
+ ULONG control_code =
+ stack_location->Parameters.DeviceIoControl.IoControlCode;
+
+ ULONG input_buffer_length
+ = stack_location->Parameters.DeviceIoControl.InputBufferLength;
+ ULONG output_buffer_length
+ = stack_location->Parameters.DeviceIoControl.OutputBufferLength;
+ ULONG transfer_buffer_length
+ = stack_location->Parameters.DeviceIoControl.OutputBufferLength;
+
+ libusb0_request *request = (libusb0_request *)irp->AssociatedIrp.SystemBuffer;
+ char *output_buffer = (char *)irp->AssociatedIrp.SystemBuffer;
+ char *input_buffer = (char *)irp->AssociatedIrp.SystemBuffer;
+ MDL *transfer_buffer_mdl = irp->MdlAddress;
+
+ status = remove_lock_acquire(dev);
+
+ if(!NT_SUCCESS(status))
+ {
+ status = complete_irp(irp, status, 0);
+ remove_lock_release(dev);
+ return status;
+ }
+
+ if(!request || input_buffer_length < sizeof(libusb0_request)
+ || input_buffer_length > LIBUSB0_MAX_READ_WRITE
+ || output_buffer_length > LIBUSB0_MAX_READ_WRITE
+ || transfer_buffer_length > LIBUSB0_MAX_READ_WRITE)
+ {
+ DEBUG_ERROR("dispatch_ioctl(): invalid input or output buffer\n");
+
+ status = complete_irp(irp, STATUS_INVALID_PARAMETER, 0);
+ remove_lock_release(dev);
+ return status;
+ }
+
+ DEBUG_PRINT_NL();
+
+ switch(control_code)
+ {
+ case LIBUSB0_IOCTL_SET_CONFIGURATION:
+
+ status = set_configuration(dev, request->configuration.configuration,
+ request->timeout);
+ break;
+
+ case LIBUSB0_IOCTL_GET_CONFIGURATION:
+
+ if(!output_buffer || output_buffer_length < 1)
+ {
+ DEBUG_ERROR("dispatch_ioctl(), get_configuration: invalid output "
+ "buffer");
+ status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ status = get_configuration(dev, output_buffer, &ret, request->timeout);
+ break;
+
+ case LIBUSB0_IOCTL_SET_INTERFACE:
+
+ status = set_interface(dev, request->interface.interface,
+ request->interface.altsetting, request->timeout);
+ break;
+
+ case LIBUSB0_IOCTL_GET_INTERFACE:
+
+ if(!output_buffer || output_buffer_length < 1)
+ {
+ DEBUG_ERROR("dispatch_ioctl(), get_interface: invalid output "
+ "buffer");
+ status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ status = get_interface(dev, request->interface.interface,
+ output_buffer, &ret, request->timeout);
+ break;
+
+ case LIBUSB0_IOCTL_SET_FEATURE:
+
+ status = set_feature(dev, request->feature.recipient,
+ request->feature.index, request->feature.feature,
+ request->timeout);
+
+ break;
+
+ case LIBUSB0_IOCTL_CLEAR_FEATURE:
+
+ status = clear_feature(dev, request->feature.recipient,
+ request->feature.index, request->feature.feature,
+ request->timeout);
+
+ break;
+
+ case LIBUSB0_IOCTL_GET_STATUS:
+
+ if(!output_buffer || output_buffer_length < 2)
+ {
+ DEBUG_ERROR("dispatch_ioctl(), get_status: invalid output buffer");
+ status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ status = get_status(dev, request->status.recipient,
+ request->status.index, output_buffer,
+ &ret, request->timeout);
+
+ break;
+
+ case LIBUSB0_IOCTL_SET_DESCRIPTOR:
+
+ if(input_buffer_length <= sizeof(libusb0_request))
+ {
+ DEBUG_ERROR("dispatch_ioctl(), set_descriptor: invalid input "
+ "buffer");
+ status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ status = set_descriptor(dev,
+ input_buffer + sizeof(libusb0_request),
+ input_buffer_length - sizeof(libusb0_request),
+ request->descriptor.type,
+ request->descriptor.recipient,
+ request->descriptor.index,
+ request->descriptor.language_id,
+ &ret, request->timeout);
+
+ break;
+
+ case LIBUSB0_IOCTL_GET_DESCRIPTOR:
+
+ if(!output_buffer || !output_buffer_length)
+ {
+ DEBUG_ERROR("dispatch_ioctl(), get_descriptor: invalid output "
+ "buffer");
+ status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ status = get_descriptor(dev, output_buffer,
+ output_buffer_length,
+ request->descriptor.type,
+ request->descriptor.recipient,
+ request->descriptor.index,
+ request->descriptor.language_id,
+ &ret, request->timeout);
+
+ break;
+
+ case LIBUSB0_IOCTL_INTERRUPT_OR_BULK_READ:
+
+ if(!transfer_buffer_mdl)
+ {
+ DEBUG_ERROR("dispatch_ioctl(), bulk_int_read: invalid transfer "
+ "buffer");
+ status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ return transfer(dev, irp,
+ USBD_TRANSFER_DIRECTION_IN,
+ URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER,
+ request->endpoint.endpoint,
+ request->endpoint.packet_size,
+ transfer_buffer_mdl,
+ transfer_buffer_length);
+
+ case LIBUSB0_IOCTL_INTERRUPT_OR_BULK_WRITE:
+
+ /* we don't check 'transfer_buffer_mdl' here because it might be NULL */
+ /* if the DLL requests to send a zero-length packet */
+ return transfer(dev, irp,
+ USBD_TRANSFER_DIRECTION_OUT,
+ URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER,
+ request->endpoint.endpoint,
+ request->endpoint.packet_size,
+ transfer_buffer_mdl,
+ transfer_buffer_length);
+
+ case LIBUSB0_IOCTL_VENDOR_READ:
+
+ if(output_buffer_length && !output_buffer)
+ {
+ DEBUG_ERROR("dispatch_ioctl(), vendor_read: invalid output buffer");
+ status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ status = vendor_class_request(dev,
+ request->vendor.type,
+ request->vendor.recipient,
+ request->vendor.request,
+ request->vendor.value,
+ request->vendor.index,
+ output_buffer,
+ output_buffer_length,
+ USBD_TRANSFER_DIRECTION_IN,
+ &ret, request->timeout);
+ break;
+
+ case LIBUSB0_IOCTL_VENDOR_WRITE:
+
+ status =
+ vendor_class_request(dev,
+ request->vendor.type,
+ request->vendor.recipient,
+ request->vendor.request,
+ request->vendor.value,
+ request->vendor.index,
+ input_buffer_length == sizeof(libusb0_request) ?
+ NULL : input_buffer + sizeof(libusb0_request),
+ input_buffer_length - sizeof(libusb0_request),
+ USBD_TRANSFER_DIRECTION_OUT,
+ &ret, request->timeout);
+ break;
+
+ case LIBUSB0_IOCTL_RESET_ENDPOINT:
+
+ status = reset_endpoint(dev, request->endpoint.endpoint,
+ request->timeout);
+ break;
+
+ case LIBUSB0_IOCTL_ABORT_ENDPOINT:
+
+ status = abort_endpoint(dev, request->endpoint.endpoint,
+ request->timeout);
+ break;
+
+ case LIBUSB0_IOCTL_RESET_DEVICE:
+
+ status = reset_device(dev, request->timeout);
+ break;
+
+ case LIBUSB0_IOCTL_SET_DEBUG_LEVEL:
+
+ DEBUG_SET_LEVEL(request->debug.level);
+ break;
+
+ case LIBUSB0_IOCTL_GET_VERSION:
+
+ if(!request || output_buffer_length < sizeof(libusb0_request))
+ {
+ DEBUG_ERROR("dispatch_ioctl(), get_version: invalid output buffer");
+ status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ request->version.major = VERSION_MAJOR;
+ request->version.minor = VERSION_MINOR;
+ request->version.micro = VERSION_MICRO;
+ request->version.nano = VERSION_NANO;
+
+ ret = sizeof(libusb0_request);
+ break;
+
+ case LIBUSB0_IOCTL_CLAIM_INTERFACE:
+ status = claim_interface(dev, request->interface.interface);
+ break;
+
+ case LIBUSB0_IOCTL_RELEASE_INTERFACE:
+ status = release_interface(dev, request->interface.interface);
+ break;
+
+ case LIBUSB0_IOCTL_ISOCHRONOUS_READ:
+ if(!transfer_buffer_mdl)
+ {
+ DEBUG_ERROR("dispatch_ioctl(), isochronous_read: invalid transfer "
+ "buffer");
+ status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ return transfer(dev, irp, USBD_TRANSFER_DIRECTION_IN,
+ URB_FUNCTION_ISOCH_TRANSFER, request->endpoint.endpoint,
+ request->endpoint.packet_size, transfer_buffer_mdl,
+ transfer_buffer_length);
+
+ case LIBUSB0_IOCTL_ISOCHRONOUS_WRITE:
+
+ if(!transfer_buffer_mdl)
+ {
+ DEBUG_ERROR("dispatch_ioctl(), isochronous_write: invalid transfer "
+ "buffer");
+ status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ return transfer(dev, irp, USBD_TRANSFER_DIRECTION_OUT,
+ URB_FUNCTION_ISOCH_TRANSFER, request->endpoint.endpoint,
+ request->endpoint.packet_size, transfer_buffer_mdl,
+ transfer_buffer_length);
+
+ default:
+
+ status = STATUS_INVALID_PARAMETER;
+ }
+
+ status = complete_irp(irp, status, ret);
+ remove_lock_release(dev);
+
+ return status;
+}
diff --git a/libusb/os/driver/libusb_driver.c b/libusb/os/driver/libusb_driver.c
new file mode 100644
index 0000000..712bffe
--- /dev/null
+++ b/libusb/os/driver/libusb_driver.c
@@ -0,0 +1,462 @@
+/* LIBUSB-WIN32, Generic Windows USB Library
+ * Copyright (c) 2002-2005 Stephan Meyer <ste_meyer@web.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#define __LIBUSB_DRIVER_C__
+
+#include "libusb_driver.h"
+
+extern int debug_level;
+
+static void DDKAPI unload(DRIVER_OBJECT *driver_object);
+
+static NTSTATUS DDKAPI on_usbd_complete(DEVICE_OBJECT *device_object,
+ IRP *irp,
+ void *context);
+
+NTSTATUS DDKAPI DriverEntry(DRIVER_OBJECT *driver_object,
+ UNICODE_STRING *registry_path)
+{
+ int i;
+
+ DEBUG_MESSAGE("DriverEntry(): loading driver");
+
+ /* initialize global variables */
+ debug_level = LIBUSB0_DEBUG_MSG;
+
+ /* initialize the driver object's dispatch table */
+ for(i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
+ {
+ driver_object->MajorFunction[i] = dispatch;
+ }
+
+ driver_object->DriverExtension->AddDevice = add_device;
+ driver_object->DriverUnload = unload;
+
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS DDKAPI add_device(DRIVER_OBJECT *driver_object,
+ DEVICE_OBJECT *physical_device_object)
+{
+ NTSTATUS status;
+ DEVICE_OBJECT *device_object = NULL;
+ libusb_device_t *dev;
+ ULONG device_type;
+
+ UNICODE_STRING nt_device_name;
+ UNICODE_STRING symbolic_link_name;
+ WCHAR tmp_name_0[128];
+ WCHAR tmp_name_1[128];
+ char id[256];
+ int i;
+
+ /* get the hardware ID from the registry */
+ if(!reg_get_hardware_id(physical_device_object, id, sizeof(id)))
+ {
+ DEBUG_ERROR("add_device(): unable to read registry");
+ return STATUS_SUCCESS;
+ }
+
+ /* only attach the (filter) driver to USB devices, skip hubs */
+ /* and interfaces of composite devices */
+ if(!strstr(id, "usb\\") || strstr(id, "hub") || strstr(id, "&mi_"))
+ {
+ return STATUS_SUCCESS;
+ }
+
+ /* retrieve the type of the lower device object */
+ device_object = IoGetAttachedDeviceReference(physical_device_object);
+
+ if(device_object)
+ {
+ device_type = device_object->DeviceType;
+ ObDereferenceObject(device_object);
+ }
+ else
+ {
+ device_type = FILE_DEVICE_UNKNOWN;
+ }
+
+ /* try to create a new device object */
+ for(i = 1; i < LIBUSB0_MAX_NUMBER_OF_DEVICES; i++)
+ {
+ /* initialize some unicode strings */
+ _snwprintf(tmp_name_0, sizeof(tmp_name_0)/sizeof(WCHAR), L"%s%04d",
+ LIBUSB0_NT_DEVICE_NAME, i);
+ _snwprintf(tmp_name_1, sizeof(tmp_name_1)/sizeof(WCHAR), L"%s%04d",
+ LIBUSB0_SYMBOLIC_LINK_NAME, i);
+
+ RtlInitUnicodeString(&nt_device_name, tmp_name_0);
+ RtlInitUnicodeString(&symbolic_link_name, tmp_name_1);
+
+ /* create the object */
+ status = IoCreateDevice(driver_object,
+ sizeof(libusb_device_t),
+ &nt_device_name, device_type, 0, FALSE,
+ &device_object);
+
+ if(NT_SUCCESS(status))
+ {
+ DEBUG_MESSAGE("add_device(): device #%d created", i);
+ break;
+ }
+
+ device_object = NULL;
+
+ /* continue until an unused device name is found */
+ }
+
+ if(!device_object)
+ {
+ DEBUG_ERROR("add_device(): creating device failed");
+ return status;
+ }
+
+ status = IoCreateSymbolicLink(&symbolic_link_name, &nt_device_name);
+
+ if(!NT_SUCCESS(status))
+ {
+ DEBUG_ERROR("add_device(): creating symbolic link failed");
+ IoDeleteDevice(device_object);
+ return status;
+ }
+
+ /* setup the "device object" */
+ dev = device_object->DeviceExtension;
+
+ memset(dev, 0, sizeof(libusb_device_t));
+
+
+ /* attach the newly created device object to the stack */
+ dev->next_stack_device =
+ IoAttachDeviceToDeviceStack(device_object, physical_device_object);
+
+ if(!dev->next_stack_device)
+ {
+ DEBUG_ERROR("add_device(): attaching to device stack failed");
+ IoDeleteSymbolicLink(&symbolic_link_name);
+ IoDeleteDevice(device_object);
+ return STATUS_NO_SUCH_DEVICE;
+ }
+
+ dev->self = device_object;
+ dev->physical_device_object = physical_device_object;
+ dev->id = i;
+
+ /* set initial power states */
+ dev->power_state.DeviceState = PowerDeviceD0;
+ dev->power_state.SystemState = PowerSystemWorking;
+
+ /* get device properties from the registry */
+ reg_get_properties(dev);
+
+ if(dev->is_filter)
+ {
+ /* send all USB requests to the PDO in filter driver mode */
+ dev->target_device = dev->physical_device_object;
+
+ /* use the same flags as the underlying object */
+ device_object->Flags |= dev->next_stack_device->Flags
+ & (DO_BUFFERED_IO | DO_DIRECT_IO | DO_POWER_PAGABLE);
+ }
+ else
+ {
+ /* send all USB requests to the lower object in device driver mode */
+ dev->target_device = dev->next_stack_device;
+
+ device_object->Flags |= DO_DIRECT_IO | DO_POWER_PAGABLE;
+ }
+
+ clear_pipe_info(dev);
+
+ remove_lock_initialize(dev);
+
+ device_object->Flags &= ~DO_DEVICE_INITIALIZING;
+
+ return status;
+}
+
+
+VOID DDKAPI unload(DRIVER_OBJECT *driver_object)
+{
+ DEBUG_MESSAGE("unload(): unloading driver");
+}
+
+NTSTATUS complete_irp(IRP *irp, NTSTATUS status, ULONG info)
+{
+ irp->IoStatus.Status = status;
+ irp->IoStatus.Information = info;
+ IoCompleteRequest(irp, IO_NO_INCREMENT);
+
+ return status;
+}
+
+NTSTATUS call_usbd(libusb_device_t *dev, void *urb, ULONG control_code,
+ int timeout)
+{
+ KEVENT event;
+ NTSTATUS status;
+ IRP *irp;
+ IO_STACK_LOCATION *next_irp_stack;
+ LARGE_INTEGER _timeout;
+ IO_STATUS_BLOCK io_status;
+
+ if(timeout > LIBUSB0_MAX_CONTROL_TRANSFER_TIMEOUT)
+ {
+ timeout = LIBUSB0_MAX_CONTROL_TRANSFER_TIMEOUT;
+ }
+
+ KeInitializeEvent(&event, NotificationEvent, FALSE);
+
+ irp = IoBuildDeviceIoControlRequest(control_code, dev->target_device,
+ NULL, 0, NULL, 0, TRUE,
+ NULL, &io_status);
+
+ if(!irp)
+ {
+ return STATUS_NO_MEMORY;
+ }
+
+ next_irp_stack = IoGetNextIrpStackLocation(irp);
+ next_irp_stack->Parameters.Others.Argument1 = urb;
+ next_irp_stack->Parameters.Others.Argument2 = NULL;
+
+ IoSetCompletionRoutine(irp, on_usbd_complete, &event, TRUE, TRUE, TRUE);
+
+ status = IoCallDriver(dev->target_device, irp);
+
+ if(status == STATUS_PENDING)
+ {
+ _timeout.QuadPart = -(timeout * 10000);
+
+ if(KeWaitForSingleObject(&event, Executive, KernelMode,
+ FALSE, &_timeout) == STATUS_TIMEOUT)
+ {
+ DEBUG_ERROR("call_usbd(): request timed out");
+ IoCancelIrp(irp);
+ }
+ }
+
+ /* wait until completion routine is called */
+ KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
+
+ status = irp->IoStatus.Status;
+
+ /* complete the request */
+ IoCompleteRequest(irp, IO_NO_INCREMENT);
+
+ return status;
+}
+
+
+static NTSTATUS DDKAPI on_usbd_complete(DEVICE_OBJECT *device_object,
+ IRP *irp, void *context)
+{
+ KeSetEvent((KEVENT *) context, IO_NO_INCREMENT, FALSE);
+
+ return STATUS_MORE_PROCESSING_REQUIRED;
+}
+
+
+NTSTATUS pass_irp_down(libusb_device_t *dev, IRP *irp,
+ PIO_COMPLETION_ROUTINE completion_routine,
+ void *context)
+{
+ if(completion_routine)
+ {
+ IoCopyCurrentIrpStackLocationToNext(irp);
+ IoSetCompletionRoutine(irp, completion_routine, context,
+ TRUE, TRUE, TRUE);
+ }
+ else
+ {
+ IoSkipCurrentIrpStackLocation(irp);
+ }
+
+ return IoCallDriver(dev->next_stack_device, irp);
+}
+
+bool_t accept_irp(libusb_device_t *dev, IRP *irp)
+{
+ /* check if the IRP is sent to libusb's device object or to */
+ /* the lower one. This check is neccassary since the device object */
+ /* might be a filter */
+ if(irp->Tail.Overlay.OriginalFileObject)
+ {
+ return irp->Tail.Overlay.OriginalFileObject->DeviceObject
+ == dev->self ? TRUE : FALSE;
+ }
+
+ return FALSE;
+}
+
+bool_t get_pipe_handle(libusb_device_t *dev, int endpoint_address,
+ USBD_PIPE_HANDLE *pipe_handle)
+{
+ int i, j;
+
+ *pipe_handle = NULL;
+
+ for(i = 0; i < LIBUSB0_MAX_NUMBER_OF_INTERFACES; i++)
+ {
+ if(dev->config.interfaces[i].valid)
+ {
+ for(j = 0; j < LIBUSB0_MAX_NUMBER_OF_ENDPOINTS; j++)
+ {
+ if(dev->config.interfaces[i].endpoints[j].address
+ == endpoint_address)
+ {
+ *pipe_handle = dev->config.interfaces[i].endpoints[j].handle;
+
+ return !*pipe_handle ? FALSE : TRUE;
+ }
+ }
+ }
+ }
+
+ return FALSE;
+}
+
+void clear_pipe_info(libusb_device_t *dev)
+{
+ memset(dev->config.interfaces, 0 , sizeof(dev->config.interfaces));
+}
+
+bool_t update_pipe_info(libusb_device_t *dev,
+ USBD_INTERFACE_INFORMATION *interface_info)
+{
+ int i;
+ int number;
+
+ if(!interface_info)
+ {
+ return FALSE;
+ }
+
+ number = interface_info->InterfaceNumber;
+
+ if(interface_info->InterfaceNumber >= LIBUSB0_MAX_NUMBER_OF_INTERFACES)
+ {
+ return FALSE;
+ }
+
+ DEBUG_MESSAGE("update_pipe_info(): interface %d", number);
+
+ dev->config.interfaces[number].valid = TRUE;
+
+ for(i = 0; i < LIBUSB0_MAX_NUMBER_OF_ENDPOINTS; i++)
+ {
+ dev->config.interfaces[number].endpoints[i].address = 0;
+ dev->config.interfaces[number].endpoints[i].handle = NULL;
+ }
+
+ if(interface_info)
+ {
+ for(i = 0; i < (int)interface_info->NumberOfPipes
+ && i < LIBUSB0_MAX_NUMBER_OF_ENDPOINTS; i++)
+ {
+ DEBUG_MESSAGE("update_pipe_info(): endpoint address 0x%02x",
+ interface_info->Pipes[i].EndpointAddress);
+
+ dev->config.interfaces[number].endpoints[i].handle
+ = interface_info->Pipes[i].PipeHandle;
+ dev->config.interfaces[number].endpoints[i].address =
+ interface_info->Pipes[i].EndpointAddress;
+ }
+ }
+
+ return TRUE;
+}
+
+
+void remove_lock_initialize(libusb_device_t *dev)
+{
+ KeInitializeEvent(&dev->remove_lock.event, NotificationEvent, FALSE);
+ dev->remove_lock.usage_count = 1;
+ dev->remove_lock.remove_pending = FALSE;
+}
+
+
+NTSTATUS remove_lock_acquire(libusb_device_t *dev)
+{
+ InterlockedIncrement(&dev->remove_lock.usage_count);
+
+ if(dev->remove_lock.remove_pending)
+ {
+ if(InterlockedDecrement(&dev->remove_lock.usage_count) == 0)
+ {
+ KeSetEvent(&dev->remove_lock.event, 0, FALSE);
+ }
+ return STATUS_DELETE_PENDING;
+ }
+ return STATUS_SUCCESS;
+}
+
+
+void remove_lock_release(libusb_device_t *dev)
+{
+ if(InterlockedDecrement(&dev->remove_lock.usage_count) == 0)
+ {
+ KeSetEvent(&dev->remove_lock.event, 0, FALSE);
+ }
+}
+
+
+void remove_lock_release_and_wait(libusb_device_t *dev)
+{
+ dev->remove_lock.remove_pending = TRUE;
+ remove_lock_release(dev);
+ remove_lock_release(dev);
+ KeWaitForSingleObject(&dev->remove_lock.event, Executive, KernelMode,
+ FALSE, NULL);
+}
+
+
+USB_INTERFACE_DESCRIPTOR *
+find_interface_desc(USB_CONFIGURATION_DESCRIPTOR *config_desc,
+ unsigned int size, int interface_number, int altsetting)
+{
+ usb_descriptor_header_t *desc = (usb_descriptor_header_t *)config_desc;
+ char *p = (char *)desc;
+ USB_INTERFACE_DESCRIPTOR *if_desc = NULL;
+
+ if(!config_desc || (size < config_desc->wTotalLength))
+ return NULL;
+
+ while(size && desc->length <= size)
+ {
+ if(desc->type == USB_INTERFACE_DESCRIPTOR_TYPE)
+ {
+ if_desc = (USB_INTERFACE_DESCRIPTOR *)desc;
+
+ if((if_desc->bInterfaceNumber == (UCHAR)interface_number)
+ && (if_desc->bAlternateSetting == (UCHAR)altsetting))
+ {
+ return if_desc;
+ }
+ }
+
+ size -= desc->length;
+ p += desc->length;
+ desc = (usb_descriptor_header_t *)p;
+ }
+
+ return NULL;
+}
+
diff --git a/libusb/os/driver/libusb_driver.h b/libusb/os/driver/libusb_driver.h
new file mode 100644
index 0000000..7c5af5b
--- /dev/null
+++ b/libusb/os/driver/libusb_driver.h
@@ -0,0 +1,234 @@
+/* LIBUSB-WIN32, Generic Windows USB Library
+ * Copyright (c) 2002-2005 Stephan Meyer <ste_meyer@web.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#ifndef __LIBUSB_DRIVER_H__
+#define __LIBUSB_DRIVER_H__
+
+#ifdef __GNUC__
+#include <ddk/usb100.h>
+#include <ddk/usbdi.h>
+#include <ddk/winddk.h>
+#include "usbdlib_gcc.h"
+#else
+#include <wdm.h>
+#include "usbdi.h"
+#include "usbdlib.h"
+#endif
+
+#include <wchar.h>
+#include <initguid.h>
+
+#undef interface
+
+#include "driver_debug.h"
+#include "driver_api.h"
+
+/* some missing defines */
+#ifdef __GNUC__
+
+#define USBD_TRANSFER_DIRECTION_OUT 0
+#define USBD_TRANSFER_DIRECTION_BIT 0
+#define USBD_TRANSFER_DIRECTION_IN (1 << USBD_TRANSFER_DIRECTION_BIT)
+#define USBD_SHORT_TRANSFER_OK_BIT 1
+#define USBD_SHORT_TRANSFER_OK (1 << USBD_SHORT_TRANSFER_OK_BIT)
+#define USBD_START_ISO_TRANSFER_ASAP_BIT 2
+#define USBD_START_ISO_TRANSFER_ASAP (1 << USBD_START_ISO_TRANSFER_ASAP_BIT)
+
+#endif
+
+
+#define USB_RECIP_DEVICE 0x00
+#define USB_RECIP_INTERFACE 0x01
+#define USB_RECIP_ENDPOINT 0x02
+#define USB_RECIP_OTHER 0x03
+
+#define USB_TYPE_STANDARD 0x00
+#define USB_TYPE_CLASS 0x01
+#define USB_TYPE_VENDOR 0x02
+
+
+#define LIBUSB0_NT_DEVICE_NAME L"\\Device\\libusb0"
+#define LIBUSB0_SYMBOLIC_LINK_NAME L"\\DosDevices\\libusb0-"
+
+#define LIBUSB0_MAX_NUMBER_OF_ENDPOINTS 32
+#define LIBUSB0_MAX_NUMBER_OF_INTERFACES 32
+
+
+#define LIBUSB0_DEFAULT_TIMEOUT 5000
+#define LIBUSB0_MAX_CONTROL_TRANSFER_TIMEOUT 240000
+
+
+#ifndef __GNUC__
+#define DDKAPI
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#ifndef TRUE
+#define TRUE (!(FALSE))
+#endif
+
+typedef int bool_t;
+
+#include <pshpack1.h>
+
+typedef struct
+{
+ unsigned char length;
+ unsigned char type;
+} usb_descriptor_header_t;
+
+#include <poppack.h>
+
+
+typedef struct
+{
+ long usage_count;
+ int remove_pending;
+ KEVENT event;
+} libusb_remove_lock_t;
+
+typedef struct
+{
+ int address;
+ USBD_PIPE_HANDLE handle;
+} libusb_endpoint_t;
+
+typedef struct
+{
+ int valid;
+ int claimed;
+ libusb_endpoint_t endpoints[LIBUSB0_MAX_NUMBER_OF_ENDPOINTS];
+} libusb_interface_t;
+
+
+typedef struct
+{
+ DEVICE_OBJECT *self;
+ DEVICE_OBJECT *physical_device_object;
+ DEVICE_OBJECT *next_stack_device;
+ DEVICE_OBJECT *target_device;
+ libusb_remove_lock_t remove_lock;
+ LONG ref_count;
+ bool_t is_filter;
+ bool_t is_started;
+ bool_t surprise_removal_ok;
+ int id;
+ struct {
+ USBD_CONFIGURATION_HANDLE handle;
+ int value;
+ libusb_interface_t interfaces[LIBUSB0_MAX_NUMBER_OF_INTERFACES];
+ } config;
+ POWER_STATE power_state;
+ DEVICE_POWER_STATE device_power_states[PowerSystemMaximum];
+} libusb_device_t;
+
+
+
+NTSTATUS DDKAPI add_device(DRIVER_OBJECT *driver_object,
+ DEVICE_OBJECT *physical_device_object);
+
+NTSTATUS DDKAPI dispatch(DEVICE_OBJECT *device_object, IRP *irp);
+NTSTATUS dispatch_pnp(libusb_device_t *dev, IRP *irp);
+NTSTATUS dispatch_power(libusb_device_t *dev, IRP *irp);
+NTSTATUS dispatch_ioctl(libusb_device_t *dev, IRP *irp);
+
+NTSTATUS complete_irp(IRP *irp, NTSTATUS status, ULONG info);
+
+NTSTATUS call_usbd(libusb_device_t *dev, void *urb,
+ ULONG control_code, int timeout);
+NTSTATUS pass_irp_down(libusb_device_t *dev, IRP *irp,
+ PIO_COMPLETION_ROUTINE completion_routine,
+ void *context);
+
+bool_t accept_irp(libusb_device_t *dev, IRP *irp);
+
+bool_t get_pipe_handle(libusb_device_t *dev, int endpoint_address,
+ USBD_PIPE_HANDLE *pipe_handle);
+void clear_pipe_info(libusb_device_t *dev);
+bool_t update_pipe_info(libusb_device_t *dev,
+ USBD_INTERFACE_INFORMATION *interface_info);
+
+void remove_lock_initialize(libusb_device_t *dev);
+NTSTATUS remove_lock_acquire(libusb_device_t *dev);
+void remove_lock_release(libusb_device_t *dev);
+void remove_lock_release_and_wait(libusb_device_t *dev);
+
+NTSTATUS set_configuration(libusb_device_t *dev,
+ int configuration, int timeout);
+NTSTATUS get_configuration(libusb_device_t *dev,
+ unsigned char *configuration, int *ret,
+ int timeout);
+NTSTATUS set_interface(libusb_device_t *dev,
+ int interface, int altsetting, int timeout);
+NTSTATUS get_interface(libusb_device_t *dev,
+ int interface, unsigned char *altsetting,
+ int *ret, int timeout);
+NTSTATUS set_feature(libusb_device_t *dev,
+ int recipient, int index, int feature, int timeout);
+NTSTATUS clear_feature(libusb_device_t *dev,
+ int recipient, int index, int feature, int timeout);
+NTSTATUS get_status(libusb_device_t *dev, int recipient,
+ int index, char *status, int *ret, int timeout);
+NTSTATUS set_descriptor(libusb_device_t *dev,
+ void *buffer, int size,
+ int type, int recipient, int index, int language_id,
+ int *sent, int timeout);
+NTSTATUS get_descriptor(libusb_device_t *dev, void *buffer, int size,
+ int type, int recipient, int index, int language_id,
+ int *received, int timeout);
+USB_CONFIGURATION_DESCRIPTOR *
+get_config_descriptor(libusb_device_t *dev, int value, int *size);
+
+NTSTATUS transfer(libusb_device_t *dev, IRP *irp,
+ int direction, int urb_function, int endpoint,
+ int packet_size, MDL *buffer, int size);
+
+NTSTATUS vendor_class_request(libusb_device_t *dev,
+ int type, int recipient,
+ int request, int value, int index,
+ void *buffer, int size, int direction,
+ int *ret, int timeout);
+
+NTSTATUS abort_endpoint(libusb_device_t *dev, int endpoint, int timeout);
+NTSTATUS reset_endpoint(libusb_device_t *dev, int endpoint, int timeout);
+NTSTATUS reset_device(libusb_device_t *dev, int timeout);
+
+NTSTATUS claim_interface(libusb_device_t *dev, int interface);
+NTSTATUS release_interface(libusb_device_t *dev, int interface);
+NTSTATUS release_all_interfaces(libusb_device_t *dev);
+
+
+bool_t reg_get_hardware_id(DEVICE_OBJECT *physical_device_object,
+ char *data, int size);
+bool_t reg_get_properties(libusb_device_t *dev);
+
+
+void power_set_device_state(libusb_device_t *dev,
+ DEVICE_POWER_STATE device_state, bool_t block);
+
+USB_INTERFACE_DESCRIPTOR *
+find_interface_desc(USB_CONFIGURATION_DESCRIPTOR *config_desc,
+ unsigned int size, int interface_number, int altsetting);
+
+
+
+#endif
diff --git a/libusb/os/driver/libusb_driver_rc.rc b/libusb/os/driver/libusb_driver_rc.rc
new file mode 100644
index 0000000..d2d125c
--- /dev/null
+++ b/libusb/os/driver/libusb_driver_rc.rc
@@ -0,0 +1,25 @@
+/* LIBUSB-WIN32, Generic Windows USB Library
+ * Copyright (c) 2002-2005 Stephan Meyer <ste_meyer@web.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#define RC_FILE_TYPE VFT_DRV
+#define RC_FILE_SUB_TYPE VFT2_DRV_SYSTEM
+#define RC_PRODUCT_STR "LibUSB-Win32 - Kernel Driver"
+#define RC_FILE_NAME_STR "libusb0.sys"
+
+#include "common.rc"
+
diff --git a/libusb/os/driver/makefile b/libusb/os/driver/makefile
new file mode 100644
index 0000000..5acbbd2
--- /dev/null
+++ b/libusb/os/driver/makefile
@@ -0,0 +1 @@
+!INCLUDE $(NTMAKEENV)\makefile.def
diff --git a/libusb/os/driver/pnp.c b/libusb/os/driver/pnp.c
new file mode 100644
index 0000000..fb0abdc
--- /dev/null
+++ b/libusb/os/driver/pnp.c
@@ -0,0 +1,216 @@
+/* LIBUSB-WIN32, Generic Windows USB Library
+ * Copyright (c) 2002-2005 Stephan Meyer <ste_meyer@web.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#include "libusb_driver.h"
+
+
+
+static NTSTATUS DDKAPI
+on_start_complete(DEVICE_OBJECT *device_object, IRP *irp,
+ void *context);
+
+static NTSTATUS DDKAPI
+on_device_usage_notification_complete(DEVICE_OBJECT *device_object,
+ IRP *irp, void *context);
+
+static NTSTATUS DDKAPI
+on_query_capabilities_complete(DEVICE_OBJECT *device_object,
+ IRP *irp, void *context);
+
+
+NTSTATUS dispatch_pnp(libusb_device_t *dev, IRP *irp)
+{
+ NTSTATUS status = STATUS_SUCCESS;
+ IO_STACK_LOCATION *stack_location = IoGetCurrentIrpStackLocation(irp);
+ UNICODE_STRING symbolic_link_name;
+ WCHAR tmp_name[128];
+
+ status = remove_lock_acquire(dev);
+
+ if(!NT_SUCCESS(status))
+ {
+ return complete_irp(irp, status, 0);
+ }
+
+ DEBUG_PRINT_NL();
+
+ switch(stack_location->MinorFunction)
+ {
+ case IRP_MN_REMOVE_DEVICE:
+
+ DEBUG_MESSAGE("dispatch_pnp(): IRP_MN_REMOVE_DEVICE");
+
+ dev->is_started = FALSE;
+
+ /* wait until all outstanding requests are finished */
+ remove_lock_release_and_wait(dev);
+
+ status = pass_irp_down(dev, irp, NULL, NULL);
+
+ DEBUG_MESSAGE("dispatch_pnp(): deleting device #%d", dev->id);
+
+ _snwprintf(tmp_name, sizeof(tmp_name)/sizeof(WCHAR), L"%s%04d",
+ LIBUSB0_SYMBOLIC_LINK_NAME, dev->id);
+
+ /* delete the symbolic link */
+ RtlInitUnicodeString(&symbolic_link_name, tmp_name);
+ IoDeleteSymbolicLink(&symbolic_link_name);
+
+ /* delete the device object */
+ IoDetachDevice(dev->next_stack_device);
+ IoDeleteDevice(dev->self);
+
+ return status;
+
+ case IRP_MN_SURPRISE_REMOVAL:
+
+ DEBUG_MESSAGE("dispatch_pnp(): IRP_MN_SURPRISE_REMOVAL");
+ dev->is_started = FALSE;
+ break;
+
+ case IRP_MN_START_DEVICE:
+
+ DEBUG_MESSAGE("dispatch_pnp(): IRP_MN_START_DEVICE");
+
+ if(!NT_SUCCESS(set_configuration(dev, 1, 1000)))
+ {
+ DEBUG_ERROR("dispatch_pnp(): IRP_MN_START_DEVICE: selecting "
+ "configuration failed");
+ }
+
+ /* report device state to Power Manager */
+ /* power_state.DeviceState has been set to D0 by add_device() */
+ PoSetPowerState(dev->self, DevicePowerState, dev->power_state);
+
+ return pass_irp_down(dev, irp, on_start_complete, NULL);
+
+ case IRP_MN_STOP_DEVICE:
+
+ dev->is_started = FALSE;
+ DEBUG_MESSAGE("dispatch_pnp(): IRP_MN_STOP_DEVICE");
+ break;
+
+ case IRP_MN_DEVICE_USAGE_NOTIFICATION:
+
+ DEBUG_MESSAGE("dispatch_pnp(): IRP_MN_DEVICE_USAGE_NOTIFICATION");
+
+ if(!dev->self->AttachedDevice
+ || (dev->self->AttachedDevice->Flags & DO_POWER_PAGABLE))
+ {
+ dev->self->Flags |= DO_POWER_PAGABLE;
+ }
+
+ return pass_irp_down(dev, irp, on_device_usage_notification_complete,
+ NULL);
+
+ case IRP_MN_QUERY_CAPABILITIES:
+
+ DEBUG_MESSAGE("dispatch_pnp(): IRP_MN_QUERY_CAPABILITIES");
+
+ if(!dev->is_filter)
+ {
+ /* apply registry setting */
+ stack_location->Parameters.DeviceCapabilities.Capabilities
+ ->SurpriseRemovalOK = dev->surprise_removal_ok;
+ }
+
+ return pass_irp_down(dev, irp, on_query_capabilities_complete, NULL);
+
+ default:
+ ;
+ }
+
+ remove_lock_release(dev);
+ return pass_irp_down(dev, irp, NULL, NULL);
+}
+
+static NTSTATUS DDKAPI
+on_start_complete(DEVICE_OBJECT *device_object, IRP *irp, void *context)
+{
+ libusb_device_t *dev = device_object->DeviceExtension;
+
+ if(irp->PendingReturned)
+ {
+ IoMarkIrpPending(irp);
+ }
+
+ if(dev->next_stack_device->Characteristics & FILE_REMOVABLE_MEDIA)
+ {
+ device_object->Characteristics |= FILE_REMOVABLE_MEDIA;
+ }
+
+ dev->is_started = TRUE;
+
+ remove_lock_release(dev);
+
+ return STATUS_SUCCESS;
+}
+
+static NTSTATUS DDKAPI
+on_device_usage_notification_complete(DEVICE_OBJECT *device_object,
+ IRP *irp, void *context)
+{
+ libusb_device_t *dev = device_object->DeviceExtension;
+
+ if(irp->PendingReturned)
+ {
+ IoMarkIrpPending(irp);
+ }
+
+ if(!(dev->next_stack_device->Flags & DO_POWER_PAGABLE))
+ {
+ device_object->Flags &= ~DO_POWER_PAGABLE;
+ }
+
+ remove_lock_release(dev);
+
+ return STATUS_SUCCESS;
+}
+
+static NTSTATUS DDKAPI
+on_query_capabilities_complete(DEVICE_OBJECT *device_object,
+ IRP *irp, void *context)
+{
+ libusb_device_t *dev = device_object->DeviceExtension;
+ IO_STACK_LOCATION *stack_location = IoGetCurrentIrpStackLocation(irp);
+
+ if(irp->PendingReturned)
+ {
+ IoMarkIrpPending(irp);
+ }
+
+ if(NT_SUCCESS(irp->IoStatus.Status))
+ {
+ if(!dev->is_filter)
+ {
+ /* apply registry setting */
+ stack_location->Parameters.DeviceCapabilities.Capabilities
+ ->SurpriseRemovalOK = dev->surprise_removal_ok;
+ }
+
+ /* save supported device power states */
+ memcpy(dev->device_power_states, stack_location
+ ->Parameters.DeviceCapabilities.Capabilities->DeviceState,
+ sizeof(dev->device_power_states));
+ }
+
+ remove_lock_release(dev);
+
+ return STATUS_SUCCESS;
+}
diff --git a/libusb/os/driver/power.c b/libusb/os/driver/power.c
new file mode 100644
index 0000000..38cc1f6
--- /dev/null
+++ b/libusb/os/driver/power.c
@@ -0,0 +1,205 @@
+/* LIBUSB-WIN32, Generic Windows USB Library
+ * Copyright (c) 2002-2005 Stephan Meyer <ste_meyer@web.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#include "libusb_driver.h"
+
+
+static NTSTATUS DDKAPI
+on_power_state_complete(DEVICE_OBJECT *device_object,
+ IRP *irp,
+ void *context);
+
+static void DDKAPI
+on_power_set_device_state_complete(DEVICE_OBJECT *device_object,
+ UCHAR minor_function,
+ POWER_STATE power_state,
+ void *context,
+ IO_STATUS_BLOCK *io_status);
+
+NTSTATUS dispatch_power(libusb_device_t *dev, IRP *irp)
+{
+ IO_STACK_LOCATION *stack_location = IoGetCurrentIrpStackLocation(irp);
+ POWER_STATE power_state;
+ NTSTATUS status;
+
+ status = remove_lock_acquire(dev);;
+
+ if(!NT_SUCCESS(status))
+ {
+ irp->IoStatus.Status = status;
+ PoStartNextPowerIrp(irp);
+ IoCompleteRequest(irp, IO_NO_INCREMENT);
+ return status;
+ }
+
+ if(stack_location->MinorFunction == IRP_MN_SET_POWER)
+ {
+ power_state = stack_location->Parameters.Power.State;
+
+ if(stack_location->Parameters.Power.Type == SystemPowerState)
+ {
+ DEBUG_MESSAGE("dispatch_power(): IRP_MN_SET_POWER: S%d",
+ power_state.SystemState - PowerSystemWorking);
+ }
+ else
+ {
+ DEBUG_MESSAGE("dispatch_power(): IRP_MN_SET_POWER: D%d",
+ power_state.DeviceState - PowerDeviceD0);
+
+ if(power_state.DeviceState > dev->power_state.DeviceState)
+ {
+ /* device is powered down, report device state to the */
+ /* Power Manager before sending the IRP down */
+ /* (power up is handled by the completion routine) */
+ PoSetPowerState(dev->self, DevicePowerState, power_state);
+ }
+ }
+
+ /* TODO: should PoStartNextPowerIrp() be called here or from the */
+ /* completion routine? */
+ PoStartNextPowerIrp(irp);
+
+ IoCopyCurrentIrpStackLocationToNext(irp);
+ IoSetCompletionRoutine(irp,
+ on_power_state_complete,
+ dev,
+ TRUE, /* on success */
+ TRUE, /* on error */
+ TRUE);/* on cancel */
+
+ return PoCallDriver(dev->next_stack_device, irp);
+ }
+ else
+ {
+ /* pass all other power IRPs down without setting a completion routine */
+ PoStartNextPowerIrp(irp);
+ IoSkipCurrentIrpStackLocation(irp);
+ status = PoCallDriver(dev->next_stack_device, irp);
+ remove_lock_release(dev);
+
+ return status;
+ }
+}
+
+
+static NTSTATUS DDKAPI
+on_power_state_complete(DEVICE_OBJECT *device_object,
+ IRP *irp,
+ void *context)
+{
+ libusb_device_t *dev = context;
+ IO_STACK_LOCATION *stack_location = IoGetCurrentIrpStackLocation(irp);
+ POWER_STATE power_state = stack_location->Parameters.Power.State;
+ DEVICE_POWER_STATE dev_power_state;
+
+ if(irp->PendingReturned)
+ {
+ IoMarkIrpPending(irp);
+ }
+
+ if(NT_SUCCESS(irp->IoStatus.Status))
+ {
+ if(stack_location->Parameters.Power.Type == SystemPowerState)
+ {
+ DEBUG_MESSAGE("on_power_state_complete(): S%d",
+ power_state.SystemState - PowerSystemWorking);
+
+ /* save current system state */
+ dev->power_state.SystemState = power_state.SystemState;
+
+ /* set device power status correctly */
+ /* dev_power_state = power_state.SystemState == PowerSystemWorking ? */
+ /* PowerDeviceD0 : PowerDeviceD3; */
+
+ /* get supported device power state from the array reported by */
+ /* IRP_MN_QUERY_CAPABILITIES */
+ dev_power_state = dev->device_power_states[power_state.SystemState];
+
+ /* set the device power state, but don't block the thread */
+ power_set_device_state(dev, dev_power_state, FALSE);
+ }
+ else /* DevicePowerState */
+ {
+ DEBUG_MESSAGE("on_power_state_complete(): D%d",
+ power_state.DeviceState - PowerDeviceD0);
+
+ if(power_state.DeviceState <= dev->power_state.DeviceState)
+ {
+ /* device is powered up, */
+ /* report device state to Power Manager */
+ PoSetPowerState(dev->self, DevicePowerState, power_state);
+ }
+
+ /* save current device state */
+ dev->power_state.DeviceState = power_state.DeviceState;
+ }
+ }
+ else
+ {
+ DEBUG_MESSAGE("on_power_state_complete(): failed");
+ }
+
+ remove_lock_release(dev);
+
+ return STATUS_SUCCESS;
+}
+
+
+static void DDKAPI
+on_power_set_device_state_complete(DEVICE_OBJECT *device_object,
+ UCHAR minor_function,
+ POWER_STATE power_state,
+ void *context,
+ IO_STATUS_BLOCK *io_status)
+{
+ KeSetEvent((KEVENT *)context, EVENT_INCREMENT, FALSE);
+}
+
+
+void power_set_device_state(libusb_device_t *dev,
+ DEVICE_POWER_STATE device_state, bool_t block)
+{
+ NTSTATUS status;
+ KEVENT event;
+ POWER_STATE power_state;
+
+ power_state.DeviceState = device_state;
+
+ if(block) /* wait for IRP to complete */
+ {
+ KeInitializeEvent(&event, NotificationEvent, FALSE);
+
+ /* set the device power state and wait for completion */
+ status = PoRequestPowerIrp(dev->physical_device_object,
+ IRP_MN_SET_POWER,
+ power_state,
+ on_power_set_device_state_complete,
+ &event, NULL);
+
+ if(status == STATUS_PENDING)
+ {
+ KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
+ }
+ }
+ else
+ {
+ PoRequestPowerIrp(dev->physical_device_object, IRP_MN_SET_POWER,
+ power_state, NULL, NULL, NULL);
+ }
+}
diff --git a/libusb/os/driver/release_interface.c b/libusb/os/driver/release_interface.c
new file mode 100644
index 0000000..0b8987b
--- /dev/null
+++ b/libusb/os/driver/release_interface.c
@@ -0,0 +1,69 @@
+/* LIBUSB-WIN32, Generic Windows USB Library
+ * Copyright (c) 2002-2005 Stephan Meyer <ste_meyer@web.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#include "libusb_driver.h"
+
+
+
+NTSTATUS release_interface(libusb_device_t *dev, int interface)
+{
+ DEBUG_MESSAGE("release_interface(): interface %d", interface);
+
+ if(!dev->config.value)
+ {
+ DEBUG_ERROR("release_interface(): device is not configured");
+ return STATUS_INVALID_DEVICE_STATE;
+ }
+
+ if(interface >= LIBUSB0_MAX_NUMBER_OF_INTERFACES)
+ {
+ DEBUG_ERROR("release_interface(): interface number %d too high",
+ interface);
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ if(!dev->config.interfaces[interface].valid)
+ {
+ DEBUG_ERROR("release_interface(): invalid interface %02d", interface);
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ if(!dev->config.interfaces[interface].claimed)
+ {
+ DEBUG_ERROR("claim_interface(): could not release interface %d, "
+ "interface is not claimed", interface);
+ return STATUS_INVALID_DEVICE_STATE;
+ }
+
+ dev->config.interfaces[interface].claimed = FALSE;
+
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS release_all_interfaces(libusb_device_t *dev)
+{
+ int i;
+
+ for(i = 0; i < LIBUSB0_MAX_NUMBER_OF_INTERFACES; i++)
+ {
+ dev->config.interfaces[i].claimed = FALSE;
+ }
+
+ return STATUS_SUCCESS;
+}
diff --git a/libusb/os/driver/reset_device.c b/libusb/os/driver/reset_device.c
new file mode 100644
index 0000000..188408d
--- /dev/null
+++ b/libusb/os/driver/reset_device.c
@@ -0,0 +1,46 @@
+/* LIBUSB-WIN32, Generic Windows USB Library
+ * Copyright (c) 2002-2005 Stephan Meyer <ste_meyer@web.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#include "libusb_driver.h"
+
+
+NTSTATUS reset_device(libusb_device_t *dev, int timeout)
+{
+ NTSTATUS status = STATUS_SUCCESS;
+
+ DEBUG_MESSAGE("reset_device()");
+
+ status = call_usbd(dev, NULL, IOCTL_INTERNAL_USB_RESET_PORT, timeout);
+
+ if(!NT_SUCCESS(status))
+ {
+ DEBUG_ERROR("reset_device(): IOCTL_INTERNAL_USB_RESET_PORT failed: "
+ "status: 0x%x", status);
+ }
+
+ status = call_usbd(dev, NULL, IOCTL_INTERNAL_USB_CYCLE_PORT, timeout);
+
+ if(!NT_SUCCESS(status))
+ {
+ DEBUG_ERROR("reset_device(): IOCTL_INTERNAL_USB_CYCLE_PORT failed: "
+ "status: 0x%x", status);
+ }
+
+ return status;
+}
diff --git a/libusb/os/driver/reset_endpoint.c b/libusb/os/driver/reset_endpoint.c
new file mode 100644
index 0000000..bb83c15
--- /dev/null
+++ b/libusb/os/driver/reset_endpoint.c
@@ -0,0 +1,59 @@
+/* LIBUSB-WIN32, Generic Windows USB Library
+ * Copyright (c) 2002-2005 Stephan Meyer <ste_meyer@web.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#include "libusb_driver.h"
+
+
+
+NTSTATUS reset_endpoint(libusb_device_t *dev, int endpoint, int timeout)
+{
+ NTSTATUS status = STATUS_SUCCESS;
+ URB urb;
+
+ DEBUG_PRINT_NL();
+ DEBUG_MESSAGE("reset_endpoint(): endpoint 0x%02x", endpoint);
+ DEBUG_MESSAGE("reset_endpoint(): timeout %d", timeout);
+
+ if(!dev->config.value)
+ {
+ DEBUG_ERROR("reset_endpoint(): invalid configuration 0");
+ return STATUS_INVALID_DEVICE_STATE;
+ }
+
+ memset(&urb, 0, sizeof(struct _URB_PIPE_REQUEST));
+
+ urb.UrbHeader.Length = (USHORT) sizeof(struct _URB_PIPE_REQUEST);
+ urb.UrbHeader.Function = URB_FUNCTION_RESET_PIPE;
+
+ if(!get_pipe_handle(dev, endpoint, &urb.UrbPipeRequest.PipeHandle))
+ {
+ DEBUG_ERROR("reset_endpoint(): getting endpoint pipe failed");
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ status = call_usbd(dev, &urb, IOCTL_INTERNAL_USB_SUBMIT_URB, timeout);
+
+ if(!NT_SUCCESS(status) || !USBD_SUCCESS(urb.UrbHeader.Status))
+ {
+ DEBUG_ERROR("reset_endpoint(): request failed: status: 0x%x, "
+ "urb-status: 0x%x", status, urb.UrbHeader.Status);
+ }
+
+ return status;
+}
diff --git a/libusb/os/driver/set_configuration.c b/libusb/os/driver/set_configuration.c
new file mode 100644
index 0000000..e9fc7f7
--- /dev/null
+++ b/libusb/os/driver/set_configuration.c
@@ -0,0 +1,170 @@
+/* LIBUSB-WIN32, Generic Windows USB Library
+ * Copyright (c) 2002-2005 Stephan Meyer <ste_meyer@web.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#include "libusb_driver.h"
+
+
+
+NTSTATUS set_configuration(libusb_device_t *dev, int configuration,
+ int timeout)
+{
+ NTSTATUS status = STATUS_SUCCESS;
+ URB urb, *urb_ptr = NULL;
+ USB_CONFIGURATION_DESCRIPTOR *configuration_descriptor = NULL;
+ USB_INTERFACE_DESCRIPTOR *interface_descriptor = NULL;
+ USBD_INTERFACE_LIST_ENTRY *interfaces = NULL;
+ int i, j, interface_number, desc_size;
+
+ DEBUG_PRINT_NL();
+ DEBUG_MESSAGE("set_configuration(): configuration %d", configuration);
+ DEBUG_MESSAGE("set_configuration(): timeout %d", timeout);
+
+ if(dev->config.value == configuration)
+ {
+ return STATUS_SUCCESS;
+ }
+
+ memset(&urb, 0, sizeof(URB));
+
+ if(!configuration)
+ {
+ urb.UrbHeader.Function = URB_FUNCTION_SELECT_CONFIGURATION;
+ urb.UrbHeader.Length = sizeof(struct _URB_SELECT_CONFIGURATION);
+
+ status = call_usbd(dev, &urb, IOCTL_INTERNAL_USB_SUBMIT_URB, timeout);
+
+ if(!NT_SUCCESS(status) || !USBD_SUCCESS(urb.UrbHeader.Status))
+ {
+ DEBUG_ERROR("set_configuration(): setting configuration %d failed: "
+ "status: 0x%x, urb-status: 0x%x",
+ configuration, status, urb.UrbHeader.Status);
+ return status;
+ }
+
+ dev->config.handle = urb.UrbSelectConfiguration.ConfigurationHandle;
+ dev->config.value = 0;
+
+ clear_pipe_info(dev);
+
+ return status;
+ }
+
+ configuration_descriptor = get_config_descriptor(dev, configuration,
+ &desc_size);
+ if(!configuration_descriptor)
+ {
+ DEBUG_ERROR("set_configuration(): getting configuration descriptor "
+ "failed");
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ interfaces =
+ ExAllocatePool(NonPagedPool,(configuration_descriptor->bNumInterfaces + 1)
+ * sizeof(USBD_INTERFACE_LIST_ENTRY));
+
+ if(!interfaces)
+ {
+ DEBUG_ERROR("set_configuration(): memory allocation failed");
+ ExFreePool(configuration_descriptor);
+ return STATUS_NO_MEMORY;
+ }
+
+ memset(interfaces, 0, (configuration_descriptor->bNumInterfaces + 1)
+ * sizeof(USBD_INTERFACE_LIST_ENTRY));
+
+ interface_number = 0;
+
+ for(i = 0; i < configuration_descriptor->bNumInterfaces; i++)
+ {
+ for(j = interface_number; j < LIBUSB0_MAX_NUMBER_OF_INTERFACES; j++)
+ {
+ interface_descriptor =
+ find_interface_desc(configuration_descriptor, desc_size, j, 0);
+ if(interface_descriptor)
+ {
+ interface_number = ++j;
+ break;
+ }
+ }
+
+ if(!interface_descriptor)
+ {
+ DEBUG_ERROR("set_configuration(): unable to find interface "
+ "descriptor at index %d", i);
+ ExFreePool(interfaces);
+ ExFreePool(configuration_descriptor);
+ return STATUS_INVALID_PARAMETER;
+ }
+ else
+ {
+ DEBUG_MESSAGE("set_configuration(): found interface %d",
+ interface_descriptor->bInterfaceNumber);
+ interfaces[i].InterfaceDescriptor = interface_descriptor;
+ }
+ }
+
+ urb_ptr = USBD_CreateConfigurationRequestEx(configuration_descriptor,
+ interfaces);
+
+ if(!urb_ptr)
+ {
+ DEBUG_ERROR("set_configuration(): memory allocation failed");
+ ExFreePool(interfaces);
+ ExFreePool(configuration_descriptor);
+ return STATUS_NO_MEMORY;
+ }
+
+ for(i = 0; i < configuration_descriptor->bNumInterfaces; i++)
+ {
+ for(j = 0; j < (int)interfaces[i].Interface->NumberOfPipes; j++)
+ {
+ interfaces[i].Interface->Pipes[j].MaximumTransferSize
+ = LIBUSB0_MAX_READ_WRITE;
+ }
+ }
+
+ status = call_usbd(dev, urb_ptr, IOCTL_INTERNAL_USB_SUBMIT_URB, timeout);
+
+ if(!NT_SUCCESS(status) || !USBD_SUCCESS(urb_ptr->UrbHeader.Status))
+ {
+ DEBUG_ERROR("set_configuration(): setting configuration %d failed: "
+ "status: 0x%x, urb-status: 0x%x",
+ configuration, status, urb_ptr->UrbHeader.Status);
+ ExFreePool(interfaces);
+ ExFreePool(configuration_descriptor);
+ ExFreePool(urb_ptr);
+ return status;
+ }
+
+ dev->config.handle = urb_ptr->UrbSelectConfiguration.ConfigurationHandle;
+ dev->config.value = configuration;
+
+ clear_pipe_info(dev);
+
+ for(i = 0; i < configuration_descriptor->bNumInterfaces; i++)
+ {
+ update_pipe_info(dev, interfaces[i].Interface);
+ }
+
+ ExFreePool(interfaces);
+ ExFreePool(urb_ptr);
+ ExFreePool(configuration_descriptor);
+
+ return status;
+}
diff --git a/libusb/os/driver/set_descriptor.c b/libusb/os/driver/set_descriptor.c
new file mode 100644
index 0000000..70553f6
--- /dev/null
+++ b/libusb/os/driver/set_descriptor.c
@@ -0,0 +1,77 @@
+/* LIBUSB-WIN32, Generic Windows USB Library
+ * Copyright (c) 2002-2005 Stephan Meyer <ste_meyer@web.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#include "libusb_driver.h"
+
+
+
+NTSTATUS set_descriptor(libusb_device_t *dev,
+ void *buffer, int size, int type, int recipient,
+ int index, int language_id, int *sent, int timeout)
+{
+ NTSTATUS status = STATUS_SUCCESS;
+ URB urb;
+
+ DEBUG_PRINT_NL();
+ DEBUG_MESSAGE("set_descriptor(): buffer size %d", size);
+ DEBUG_MESSAGE("set_descriptor(): type %04d", type);
+ DEBUG_MESSAGE("set_descriptor(): recipient %04d", recipient);
+ DEBUG_MESSAGE("set_descriptor(): index %04d", index);
+ DEBUG_MESSAGE("set_descriptor(): language id %04d", language_id);
+ DEBUG_MESSAGE("set_descriptor(): timeout %d", timeout);
+
+ memset(&urb, 0, sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST));
+
+
+ switch(recipient)
+ {
+ case USB_RECIP_DEVICE:
+ urb.UrbHeader.Function = URB_FUNCTION_SET_DESCRIPTOR_TO_DEVICE;
+ break;
+ case USB_RECIP_INTERFACE:
+ urb.UrbHeader.Function = URB_FUNCTION_SET_DESCRIPTOR_TO_INTERFACE;
+ break;
+ case USB_RECIP_ENDPOINT:
+ urb.UrbHeader.Function = URB_FUNCTION_SET_DESCRIPTOR_TO_ENDPOINT;
+ break;
+ default:
+ DEBUG_ERROR("set_descriptor(): invalid recipient");
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ urb.UrbHeader.Length = sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST);
+ urb.UrbControlDescriptorRequest.TransferBufferLength = size;
+ urb.UrbControlDescriptorRequest.TransferBuffer = buffer;
+ urb.UrbControlDescriptorRequest.DescriptorType = (UCHAR)type;
+ urb.UrbControlDescriptorRequest.Index = (UCHAR)index;
+ urb.UrbControlDescriptorRequest.LanguageId = (USHORT)language_id;
+
+ status = call_usbd(dev, &urb, IOCTL_INTERNAL_USB_SUBMIT_URB, timeout);
+
+ if(!NT_SUCCESS(status) || !USBD_SUCCESS(urb.UrbHeader.Status))
+ {
+ DEBUG_ERROR("set_descriptor(): setting descriptor failed: status: "
+ "0x%x, urb-status: 0x%x", status, urb.UrbHeader.Status);
+ }
+ else
+ {
+ *sent = urb.UrbControlDescriptorRequest.TransferBufferLength;
+ }
+ return status;
+}
diff --git a/libusb/os/driver/set_feature.c b/libusb/os/driver/set_feature.c
new file mode 100644
index 0000000..8b06a02
--- /dev/null
+++ b/libusb/os/driver/set_feature.c
@@ -0,0 +1,71 @@
+/* LIBUSB-WIN32, Generic Windows USB Library
+ * Copyright (c) 2002-2005 Stephan Meyer <ste_meyer@web.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#include "libusb_driver.h"
+
+
+
+NTSTATUS set_feature(libusb_device_t *dev, int recipient, int index,
+ int feature, int timeout)
+{
+ NTSTATUS status = STATUS_SUCCESS;
+ URB urb;
+
+ DEBUG_PRINT_NL();
+ DEBUG_MESSAGE("set_feature(): recipient %02d", recipient);
+ DEBUG_MESSAGE("set_feature(): index %04d", index);
+ DEBUG_MESSAGE("set_feature(): feature %04d", feature);
+ DEBUG_MESSAGE("set_feature(): timeout %d", timeout);
+
+ memset(&urb, 0, sizeof(struct _URB_CONTROL_FEATURE_REQUEST));
+
+ switch(recipient)
+ {
+ case USB_RECIP_DEVICE:
+ urb.UrbHeader.Function = URB_FUNCTION_SET_FEATURE_TO_DEVICE;
+ break;
+ case USB_RECIP_INTERFACE:
+ urb.UrbHeader.Function = URB_FUNCTION_SET_FEATURE_TO_INTERFACE;
+ break;
+ case USB_RECIP_ENDPOINT:
+ urb.UrbHeader.Function = URB_FUNCTION_SET_FEATURE_TO_ENDPOINT;
+ break;
+ case USB_RECIP_OTHER:
+ urb.UrbHeader.Function = URB_FUNCTION_SET_FEATURE_TO_OTHER;
+ urb.UrbControlFeatureRequest.Index = 0;
+ break;
+ default:
+ DEBUG_ERROR("set_feature(): invalid recipient");
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ urb.UrbHeader.Length = sizeof(struct _URB_CONTROL_FEATURE_REQUEST);
+ urb.UrbControlFeatureRequest.FeatureSelector = (USHORT)feature;
+ urb.UrbControlFeatureRequest.Index = (USHORT)index;
+
+ status = call_usbd(dev, &urb, IOCTL_INTERNAL_USB_SUBMIT_URB, timeout);
+
+ if(!NT_SUCCESS(status) || !USBD_SUCCESS(urb.UrbHeader.Status))
+ {
+ DEBUG_ERROR("set_feature(): setting feature failed: status: 0x%x, "
+ "urb-status: 0x%x", status, urb.UrbHeader.Status);
+ }
+
+ return status;
+}
diff --git a/libusb/os/driver/set_interface.c b/libusb/os/driver/set_interface.c
new file mode 100644
index 0000000..d7732f6
--- /dev/null
+++ b/libusb/os/driver/set_interface.c
@@ -0,0 +1,123 @@
+/* LIBUSB-WIN32, Generic Windows USB Library
+ * Copyright (c) 2002-2005 Stephan Meyer <ste_meyer@web.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#include "libusb_driver.h"
+
+
+NTSTATUS set_interface(libusb_device_t *dev, int interface, int altsetting,
+ int timeout)
+{
+ NTSTATUS status = STATUS_SUCCESS;
+ URB *urb;
+ int i, config_size, tmp_size;
+
+ USB_CONFIGURATION_DESCRIPTOR *configuration_descriptor = NULL;
+ USB_INTERFACE_DESCRIPTOR *interface_descriptor = NULL;
+ USBD_INTERFACE_INFORMATION *interface_information = NULL;
+
+ DEBUG_PRINT_NL();
+ DEBUG_MESSAGE("set_interface(): interface %d", interface);
+ DEBUG_MESSAGE("set_interface(): altsetting %d", altsetting);
+ DEBUG_MESSAGE("set_interface(): timeout %d", timeout);
+
+ if(!dev->config.value)
+ {
+ DEBUG_ERROR("release_interface(): device is not configured");
+ return STATUS_INVALID_DEVICE_STATE;
+ }
+
+ configuration_descriptor = get_config_descriptor(dev, dev->config.value,
+ &config_size);
+ if(!configuration_descriptor)
+ {
+ DEBUG_ERROR("set_interface(): memory_allocation error");
+ return STATUS_NO_MEMORY;
+ }
+
+ interface_descriptor =
+ find_interface_desc(configuration_descriptor, config_size,
+ interface, altsetting);
+
+ if(!interface_descriptor)
+ {
+ DEBUG_ERROR("set_interface(): interface %d or altsetting %d invalid",
+ interface, altsetting);
+ ExFreePool(configuration_descriptor);
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ tmp_size = sizeof(struct _URB_SELECT_INTERFACE)
+ + interface_descriptor->bNumEndpoints
+ * sizeof(USBD_PIPE_INFORMATION);
+
+
+ urb = ExAllocatePool(NonPagedPool, tmp_size);
+
+ if(!urb)
+ {
+ DEBUG_ERROR("set_interface(): memory_allocation error");
+ ExFreePool(configuration_descriptor);
+ return STATUS_NO_MEMORY;
+ }
+
+ memset(urb, 0, tmp_size);
+
+ urb->UrbHeader.Function = URB_FUNCTION_SELECT_INTERFACE;
+ urb->UrbHeader.Length = (USHORT)tmp_size;
+
+ urb->UrbSelectInterface.ConfigurationHandle = dev->config.handle;
+ urb->UrbSelectInterface.Interface.Length =
+ sizeof(struct _USBD_INTERFACE_INFORMATION);
+ urb->UrbSelectInterface.Interface.NumberOfPipes =
+ interface_descriptor->bNumEndpoints;
+ urb->UrbSelectInterface.Interface.Length +=
+ interface_descriptor->bNumEndpoints
+ * sizeof(struct _USBD_PIPE_INFORMATION);
+
+ urb->UrbSelectInterface.Interface.InterfaceNumber = (UCHAR)interface;
+ urb->UrbSelectInterface.Interface.AlternateSetting = (UCHAR)altsetting;
+
+ interface_information = &urb->UrbSelectInterface.Interface;
+
+ for(i = 0; i < interface_descriptor->bNumEndpoints; i++)
+ {
+ interface_information->Pipes[i].MaximumTransferSize
+ = LIBUSB0_MAX_READ_WRITE;
+ }
+
+ status = call_usbd(dev, urb, IOCTL_INTERNAL_USB_SUBMIT_URB, timeout);
+
+
+ if(!NT_SUCCESS(status) || !USBD_SUCCESS(urb->UrbHeader.Status))
+ {
+ DEBUG_ERROR("set_interface(): setting interface failed: status: 0x%x, "
+ "urb-status: 0x%x", status, urb->UrbHeader.Status);
+ ExFreePool(configuration_descriptor);
+ ExFreePool(urb);
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ update_pipe_info(dev, interface_information);
+
+ ExFreePool(configuration_descriptor);
+ ExFreePool(urb);
+
+ return status;
+}
+
diff --git a/libusb/os/driver/sources b/libusb/os/driver/sources
new file mode 100644
index 0000000..7b247b1
--- /dev/null
+++ b/libusb/os/driver/sources
@@ -0,0 +1,33 @@
+TARGETNAME = libusb0
+TARGETPATH = obj
+TARGETTYPE = DRIVER
+USER_C_FLAGS = /O2
+TARGETLIBS = $(DDK_LIB_PATH)\usbd.lib
+C_DEFINES = /DVERSION_MAJOR=0 /DVERSION_MINOR=1 /DVERSION_MICRO=12 \
+ /DVERSION_NANO=1 /DRC_VERSION=0,1,12,1 \
+ /DRC_VERSION_STR="\"0.1.12.1\""
+
+SOURCES = abort_endpoint.c \
+claim_interface.c \
+clear_feature.c \
+dispatch.c \
+driver_registry.c \
+get_configuration.c \
+get_descriptor.c \
+get_interface.c \
+get_status.c \
+ioctl.c \
+libusb_driver.c \
+pnp.c \
+power.c \
+release_interface.c \
+reset_device.c \
+reset_endpoint.c \
+set_configuration.c \
+set_descriptor.c \
+set_feature.c \
+set_interface.c \
+transfer.c \
+vendor_request.c \
+driver_debug.c \
+libusb_driver_rc.rc
diff --git a/libusb/os/driver/temp b/libusb/os/driver/temp
new file mode 100644
index 0000000..6776819
--- /dev/null
+++ b/libusb/os/driver/temp
@@ -0,0 +1,13 @@
+claim_interface.c
+driver_debug.c
+driver_debug.h
+driver_registry.c
+get_descriptor.c
+ioctl.c
+libusb_driver.c
+libusb_driver.h
+pnp.bak.c
+pnp.c
+release_interface.c
+set_configuration.c
+set_interface.c
diff --git a/libusb/os/driver/transfer.c b/libusb/os/driver/transfer.c
new file mode 100644
index 0000000..c7401e9
--- /dev/null
+++ b/libusb/os/driver/transfer.c
@@ -0,0 +1,238 @@
+/* LIBUSB-WIN32, Generic Windows USB Library
+ * Copyright (c) 2002-2005 Stephan Meyer <ste_meyer@web.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#include "libusb_driver.h"
+
+
+typedef struct {
+ URB *urb;
+ int sequence;
+} context_t;
+
+static int sequence = 0;
+
+NTSTATUS DDKAPI transfer_complete(DEVICE_OBJECT *device_object,
+ IRP *irp, void *context);
+
+static NTSTATUS create_urb(libusb_device_t *dev, URB **urb, int direction,
+ int urb_function, int endpoint, int packet_size,
+ MDL *buffer, int size);
+
+NTSTATUS transfer(libusb_device_t *dev, IRP *irp,
+ int direction, int urb_function, int endpoint,
+ int packet_size, MDL *buffer, int size)
+{
+ IO_STACK_LOCATION *stack_location = NULL;
+ context_t *context;
+ NTSTATUS status = STATUS_SUCCESS;
+
+ DEBUG_PRINT_NL();
+
+ if(urb_function == URB_FUNCTION_ISOCH_TRANSFER)
+ DEBUG_MESSAGE("transfer(): isochronous transfer");
+ else
+ DEBUG_MESSAGE("transfer(): bulk or interrupt transfer");
+
+ if(direction == USBD_TRANSFER_DIRECTION_IN)
+ DEBUG_MESSAGE("transfer(): direction in");
+ else
+ DEBUG_MESSAGE("transfer(): direction out");
+
+ DEBUG_MESSAGE("transfer(): endpoint 0x%02x", endpoint);
+
+ if(urb_function == URB_FUNCTION_ISOCH_TRANSFER)
+ DEBUG_MESSAGE("transfer(): packet_size 0x%x", packet_size);
+
+ DEBUG_MESSAGE("transfer(): size %d", size);
+ DEBUG_MESSAGE("transfer(): sequence %d", sequence);
+ DEBUG_PRINT_NL();
+
+ if(!dev->config.value)
+ {
+ DEBUG_ERROR("transfer(): invalid configuration 0");
+ remove_lock_release(dev);
+ return complete_irp(irp, STATUS_INVALID_DEVICE_STATE, 0);
+ }
+
+ context = ExAllocatePool(NonPagedPool, sizeof(context_t));
+
+ if(!context)
+ {
+ remove_lock_release(dev);
+ return complete_irp(irp, STATUS_NO_MEMORY, 0);
+ }
+
+ status = create_urb(dev, &context->urb, direction, urb_function,
+ endpoint, packet_size, buffer, size);
+
+ if(!NT_SUCCESS(status))
+ {
+ ExFreePool(context);
+ remove_lock_release(dev);
+ return complete_irp(irp, status, 0);
+ }
+
+ context->sequence = sequence++;
+
+ stack_location = IoGetNextIrpStackLocation(irp);
+
+ stack_location->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
+ stack_location->Parameters.Others.Argument1 = context->urb;
+ stack_location->Parameters.DeviceIoControl.IoControlCode
+ = IOCTL_INTERNAL_USB_SUBMIT_URB;
+
+ IoSetCompletionRoutine(irp, transfer_complete, context,
+ TRUE, TRUE, TRUE);
+
+ return IoCallDriver(dev->target_device, irp);
+}
+
+
+NTSTATUS DDKAPI transfer_complete(DEVICE_OBJECT *device_object, IRP *irp,
+ void *context)
+{
+ context_t *c = (context_t *)context;
+ int transmitted = 0;
+ libusb_device_t *dev = device_object->DeviceExtension;
+
+ if(irp->PendingReturned)
+ {
+ IoMarkIrpPending(irp);
+ }
+
+ if(NT_SUCCESS(irp->IoStatus.Status)
+ && USBD_SUCCESS(c->urb->UrbHeader.Status))
+ {
+ if(c->urb->UrbHeader.Function == URB_FUNCTION_ISOCH_TRANSFER)
+ {
+ transmitted = c->urb->UrbIsochronousTransfer.TransferBufferLength;
+ }
+ if(c->urb->UrbHeader.Function == URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER)
+ {
+ transmitted
+ = c->urb->UrbBulkOrInterruptTransfer.TransferBufferLength;
+ }
+
+ DEBUG_MESSAGE("transfer_complete(): sequence %d: %d bytes transmitted",
+ c->sequence, transmitted);
+ }
+ else
+ {
+ if(irp->IoStatus.Status == STATUS_CANCELLED)
+ {
+ DEBUG_ERROR("transfer_complete(): sequence %d: timeout error",
+ c->sequence);
+ }
+ else
+ {
+ DEBUG_ERROR("transfer_complete(): sequence %d: transfer failed: "
+ "status: 0x%x, urb-status: 0x%x",
+ c->sequence, irp->IoStatus.Status,
+ c->urb->UrbHeader.Status);
+ }
+ }
+
+ ExFreePool(c->urb);
+ ExFreePool(c);
+
+ irp->IoStatus.Information = transmitted;
+
+ remove_lock_release(dev);
+
+ return STATUS_SUCCESS;
+}
+
+
+static NTSTATUS create_urb(libusb_device_t *dev, URB **urb, int direction,
+ int urb_function, int endpoint, int packet_size,
+ MDL *buffer, int size)
+{
+ USBD_PIPE_HANDLE pipe_handle = NULL;
+ int num_packets = 0;
+ int i, urb_size;
+
+ *urb = NULL;
+
+ if(!get_pipe_handle(dev, endpoint, &pipe_handle))
+ {
+ DEBUG_ERROR("create_urb(): getting endpoint pipe failed");
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ /* isochronous transfer */
+ if(urb_function == URB_FUNCTION_ISOCH_TRANSFER)
+ {
+ num_packets = (size + packet_size - 1) / packet_size;
+
+ if(num_packets > 255)
+ {
+ DEBUG_ERROR("create_urb(): transfer size too large");
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ urb_size = sizeof(struct _URB_ISOCH_TRANSFER)
+ + sizeof(USBD_ISO_PACKET_DESCRIPTOR) * num_packets;
+ }
+ else /* bulk or interrupt transfer */
+ {
+ urb_size = sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER);
+ }
+
+ *urb = ExAllocatePool(NonPagedPool, urb_size);
+
+ if(!*urb)
+ {
+ DEBUG_ERROR("create_urb(): memory allocation error");
+ return STATUS_NO_MEMORY;
+ }
+
+ memset(*urb, 0, urb_size);
+
+ (*urb)->UrbHeader.Length = (USHORT)urb_size;
+ (*urb)->UrbHeader.Function = (USHORT)urb_function;
+
+ /* isochronous transfer */
+ if(urb_function == URB_FUNCTION_ISOCH_TRANSFER)
+ {
+ (*urb)->UrbIsochronousTransfer.PipeHandle = pipe_handle;
+ (*urb)->UrbIsochronousTransfer.TransferFlags
+ = direction | USBD_SHORT_TRANSFER_OK | USBD_START_ISO_TRANSFER_ASAP;
+ (*urb)->UrbIsochronousTransfer.TransferBufferLength = size;
+ (*urb)->UrbIsochronousTransfer.TransferBufferMDL = buffer;
+ (*urb)->UrbIsochronousTransfer.NumberOfPackets = num_packets;
+
+ for(i = 0; i < num_packets; i++)
+ {
+ (*urb)->UrbIsochronousTransfer.IsoPacket[i].Offset = i * packet_size;
+ (*urb)->UrbIsochronousTransfer.IsoPacket[i].Length = packet_size;
+ }
+ }
+ /* bulk or interrupt transfer */
+ else
+ {
+ (*urb)->UrbBulkOrInterruptTransfer.PipeHandle = pipe_handle;
+ (*urb)->UrbBulkOrInterruptTransfer.TransferFlags
+ = direction | USBD_SHORT_TRANSFER_OK;
+ (*urb)->UrbBulkOrInterruptTransfer.TransferBufferLength = size;
+ (*urb)->UrbBulkOrInterruptTransfer.TransferBufferMDL = buffer;
+ }
+
+ return STATUS_SUCCESS;
+}
+
diff --git a/libusb/os/driver/usbd.def b/libusb/os/driver/usbd.def
new file mode 100644
index 0000000..5c283bb
--- /dev/null
+++ b/libusb/os/driver/usbd.def
@@ -0,0 +1,35 @@
+
+EXPORTS
+USBD_AllocateDeviceName
+USBD_CalculateUsbBandwidth
+USBD_CompleteRequest
+USBD_CreateConfigurationRequest
+USBD_CreateConfigurationRequestEx
+USBD_CreateDevice
+USBD_Debug_GetHeap
+USBD_Debug_LogEntry
+USBD_Debug_RetHeap
+USBD_Dispatch
+USBD_FreeDeviceMutex
+USBD_FreeDeviceName
+USBD_GetDeviceInformation
+USBD_GetInterfaceLength
+USBD_GetPdoRegistryParameter
+USBD_GetSuspendPowerState
+USBD_GetUSBDIVersion
+USBD_InitializeDevice
+USBD_MakePdoName
+USBD_ParseConfigurationDescriptor
+USBD_ParseConfigurationDescriptorEx
+USBD_ParseDescriptors
+USBD_QueryBusTime
+USBD_RegisterHcDeviceCapabilities
+USBD_RegisterHcFilter
+USBD_RegisterHostController
+USBD_RemoveDevice
+USBD_RestoreDevice
+USBD_SetSuspendPowerState
+USBD_WaitDeviceMutex
+USBD_CreateConfigurationRequestEx@8=_USBD_CreateConfigurationRequestEx@8
+USBD_ParseConfigurationDescriptorEx@28=_USBD_ParseConfigurationDescriptorEx@28
+USBD_ParseDescriptors@16=_USBD_ParseDescriptors@16
diff --git a/libusb/os/driver/usbdlib_gcc.h b/libusb/os/driver/usbdlib_gcc.h
new file mode 100644
index 0000000..84d9238
--- /dev/null
+++ b/libusb/os/driver/usbdlib_gcc.h
@@ -0,0 +1,308 @@
+
+#ifndef __USBDLIB_H
+#define __USBDLIB_H
+
+#if __GNUC__ >=3
+#pragma GCC system_header
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#pragma pack(push,4)
+
+
+ typedef struct _USBD_INTERFACE_LIST_ENTRY {
+ PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
+ PUSBD_INTERFACE_INFORMATION Interface;
+ } USBD_INTERFACE_LIST_ENTRY, *PUSBD_INTERFACE_LIST_ENTRY;
+
+
+#define URB_STATUS(urb) ((urb)->UrbHeader.Status)
+
+#define GET_SELECT_CONFIGURATION_REQUEST_SIZE(totalInterfaces, totalPipes) \
+ (sizeof(struct _URB_SELECT_CONFIGURATION) \
+ + ((totalInterfaces - 1) * sizeof(USBD_INTERFACE_INFORMATION)) \
+ + ((totalPipes - 1) * sizeof(USBD_PIPE_INFORMATION)))
+
+#define GET_SELECT_INTERFACE_REQUEST_SIZE(totalPipes) \
+ (sizeof(struct _URB_SELECT_INTERFACE) \
+ + ((totalPipes - 1) * sizeof(USBD_PIPE_INFORMATION)))
+
+#define GET_USBD_INTERFACE_SIZE(numEndpoints) \
+ (sizeof(USBD_INTERFACE_INFORMATION) \
+ + (sizeof(USBD_PIPE_INFORMATION)*(numEndpoints)) \
+ - sizeof(USBD_PIPE_INFORMATION))
+
+#define GET_ISO_URB_SIZE(n) (sizeof(struct _URB_ISOCH_TRANSFER) \
+ + sizeof(USBD_ISO_PACKET_DESCRIPTOR) * n)
+
+
+#define UsbBuildInterruptOrBulkTransferRequest(urb, \
+ length, \
+ pipeHandle, \
+ transferBuffer, \
+ transferBufferMDL, \
+ transferBufferLength, \
+ transferFlags, \
+ link) { \
+ (urb)->UrbHeader.Function = \
+ URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER; \
+ (urb)->UrbHeader.Length = (length); \
+ (urb)->UrbBulkOrInterruptTransfer.PipeHandle = (pipeHandle); \
+ (urb)->UrbBulkOrInterruptTransfer.TransferBufferLength = \
+ (transferBufferLength); \
+ (urb)->UrbBulkOrInterruptTransfer.TransferBufferMDL = \
+ (transferBufferMDL); \
+ (urb)->UrbBulkOrInterruptTransfer.TransferBuffer = \
+ (transferBuffer); \
+ (urb)->UrbBulkOrInterruptTransfer.TransferFlags = \
+ (transferFlags); \
+ (urb)->UrbBulkOrInterruptTransfer.UrbLink = (link); }
+
+
+#define UsbBuildGetDescriptorRequest(urb, \
+ length, \
+ descriptorType, \
+ descriptorIndex, \
+ languageId, \
+ transferBuffer, \
+ transferBufferMDL, \
+ transferBufferLength, \
+ link) { \
+ (urb)->UrbHeader.Function = \
+ URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE; \
+ (urb)->UrbHeader.Length = (length); \
+ (urb)->UrbControlDescriptorRequest.TransferBufferLength = \
+ (transferBufferLength); \
+ (urb)->UrbControlDescriptorRequest.TransferBufferMDL = \
+ (transferBufferMDL); \
+ (urb)->UrbControlDescriptorRequest.TransferBuffer = \
+ (transferBuffer); \
+ (urb)->UrbControlDescriptorRequest.DescriptorType = \
+ (descriptorType); \
+ (urb)->UrbControlDescriptorRequest.Index = (descriptorIndex); \
+ (urb)->UrbControlDescriptorRequest.LanguageId = (languageId); \
+ (urb)->UrbControlDescriptorRequest.UrbLink = (link); }
+
+
+
+#define UsbBuildGetStatusRequest(urb, \
+ op, \
+ index, \
+ transferBuffer, \
+ transferBufferMDL, \
+ link) { \
+ (urb)->UrbHeader.Function = (op); \
+ (urb)->UrbHeader.Length = \
+ sizeof(struct _URB_CONTROL_GET_STATUS_REQUEST); \
+ (urb)->UrbControlGetStatusRequest.TransferBufferLength = \
+ sizeof(USHORT); \
+ (urb)->UrbControlGetStatusRequest.TransferBufferMDL = \
+ (transferBufferMDL); \
+ (urb)->UrbControlGetStatusRequest.TransferBuffer = \
+ (transferBuffer); \
+ (urb)->UrbControlGetStatusRequest.Index = (index); \
+ (urb)->UrbControlGetStatusRequest.UrbLink = (link); }
+
+
+#define UsbBuildFeatureRequest(urb, \
+ op, \
+ featureSelector, \
+ index, \
+ link) { \
+ (urb)->UrbHeader.Function = (op); \
+ (urb)->UrbHeader.Length = \
+ sizeof(struct _URB_CONTROL_FEATURE_REQUEST); \
+ (urb)->UrbControlFeatureRequest.FeatureSelector = \
+ (featureSelector); \
+ (urb)->UrbControlFeatureRequest.Index = (index); \
+ (urb)->UrbControlFeatureRequest.UrbLink = (link); }
+
+
+
+#define UsbBuildSelectConfigurationRequest(urb, \
+ length, \
+ configurationDescriptor) { \
+ (urb)->UrbHeader.Function = URB_FUNCTION_SELECT_CONFIGURATION; \
+ (urb)->UrbHeader.Length = (length); \
+ (urb)->UrbSelectConfiguration.ConfigurationDescriptor = \
+ (configurationDescriptor); }
+
+#define UsbBuildSelectInterfaceRequest(urb, \
+ length, \
+ configurationHandle, \
+ interfaceNumber, \
+ alternateSetting) { \
+ (urb)->UrbHeader.Function = URB_FUNCTION_SELECT_INTERFACE; \
+ (urb)->UrbHeader.Length = (length); \
+ (urb)->UrbSelectInterface.Interface.AlternateSetting = \
+ (alternateSetting); \
+ (urb)->UrbSelectInterface.Interface.InterfaceNumber = \
+ (interfaceNumber); \
+ (urb)->UrbSelectInterface.ConfigurationHandle = \
+ (configurationHandle); }
+
+
+#define UsbBuildVendorRequest(urb, \
+ cmd, \
+ length, \
+ transferFlags, \
+ reservedbits, \
+ request, \
+ value, \
+ index, \
+ transferBuffer, \
+ transferBufferMDL, \
+ transferBufferLength, \
+ link) { \
+ (urb)->UrbHeader.Function = cmd; \
+ (urb)->UrbHeader.Length = (length); \
+ (urb)->UrbControlVendorClassRequest.TransferBufferLength = \
+ (transferBufferLength); \
+ (urb)->UrbControlVendorClassRequest.TransferBufferMDL = \
+ (transferBufferMDL); \
+ (urb)->UrbControlVendorClassRequest.TransferBuffer = \
+ (transferBuffer); \
+ (urb)->UrbControlVendorClassRequest.RequestTypeReservedBits = \
+ (reservedbits); \
+ (urb)->UrbControlVendorClassRequest.Request = (request); \
+ (urb)->UrbControlVendorClassRequest.Value = (value); \
+ (urb)->UrbControlVendorClassRequest.Index = (index); \
+ (urb)->UrbControlVendorClassRequest.TransferFlags = \
+ (transferFlags); \
+ (urb)->UrbControlVendorClassRequest.UrbLink = (link); }
+
+
+#define UsbBuildOsFeatureDescriptorRequest(urb, \
+ length, \
+ interface, \
+ index, \
+ transferBuffer, \
+ transferBufferMDL, \
+ transferBufferLength, \
+ link) { \
+ (urb)->UrbHeader.Function = \
+ URB_FUNCTION_GET_MS_FEATURE_DESCRIPTOR; \
+ (urb)->UrbHeader.Length = (length); \
+ (urb)->UrbOSFeatureDescriptorRequest.TransferBufferLength = \
+ (transferBufferLength); \
+ (urb)->UrbOSFeatureDescriptorRequest.TransferBufferMDL = \
+ (transferBufferMDL); \
+ (urb)->UrbOSFeatureDescriptorRequest.TransferBuffer = \
+ (transferBuffer); \
+ (urb)->UrbOSFeatureDescriptorRequest.InterfaceNumber = \
+ (interface); \
+ (urb)->UrbOSFeatureDescriptorRequest.MS_FeatureDescriptorIndex = \
+ (index); \
+ (urb)->UrbOSFeatureDescriptorRequest.UrbLink = (link); }
+
+
+ VOID
+ DDKAPI
+ USBD_Debug_LogEntry(
+ IN CHAR *Name,
+ IN ULONG Info1,
+ IN ULONG Info2,
+ IN ULONG Info3
+ );
+
+ VOID
+ DDKAPI
+ USBD_GetUSBDIVersion(
+ PUSBD_VERSION_INFORMATION VersionInformation
+ );
+
+
+ PUSB_INTERFACE_DESCRIPTOR
+ DDKAPI
+ USBD_ParseConfigurationDescriptor(
+ IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
+ IN UCHAR InterfaceNumber,
+ IN UCHAR AlternateSetting
+ );
+
+ PURB
+ DDKAPI
+ USBD_CreateConfigurationRequest(
+ IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
+ IN OUT PUSHORT Siz
+ );
+
+ PUSB_COMMON_DESCRIPTOR
+ DDKAPI
+ USBD_ParseDescriptors(
+ IN PVOID DescriptorBuffer,
+ IN ULONG TotalLength,
+ IN PVOID StartPosition,
+ IN LONG DescriptorType
+ );
+
+ PUSB_INTERFACE_DESCRIPTOR
+ DDKAPI
+ USBD_ParseConfigurationDescriptorEx(
+ IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
+ IN PVOID StartPosition,
+ IN LONG InterfaceNumber,
+ IN LONG AlternateSetting,
+ IN LONG InterfaceClass,
+ IN LONG InterfaceSubClass,
+ IN LONG InterfaceProtocol
+ );
+
+ PURB
+ DDKAPI
+ USBD_CreateConfigurationRequestEx(
+ IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
+ IN PUSBD_INTERFACE_LIST_ENTRY InterfaceList
+ );
+
+ ULONG
+ DDKAPI
+ USBD_GetInterfaceLength(
+ IN PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor,
+ IN PUCHAR BufferEnd
+ );
+
+ VOID
+ DDKAPI
+ USBD_RegisterHcFilter(
+ PDEVICE_OBJECT DeviceObject,
+ PDEVICE_OBJECT FilterDeviceObject
+ );
+
+ NTSTATUS
+ DDKAPI
+ USBD_GetPdoRegistryParameter(
+ IN PDEVICE_OBJECT PhysicalDeviceObject,
+ IN OUT PVOID Parameter,
+ IN ULONG ParameterLength,
+ IN PWCHAR KeyName,
+ IN ULONG KeyNameLength
+ );
+
+ NTSTATUS
+ DDKAPI
+ USBD_QueryBusTime(
+ IN PDEVICE_OBJECT RootHubPdo,
+ IN PULONG CurrentFrame
+ );
+
+ ULONG
+ DDKAPI
+ USBD_CalculateUsbBandwidth(
+ ULONG MaxPacketSize,
+ UCHAR EndpointType,
+ BOOLEAN LowSpeed
+ );
+
+
+#pragma pack(pop)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __USBDLIB_H */
+
diff --git a/libusb/os/driver/vendor_request.c b/libusb/os/driver/vendor_request.c
new file mode 100644
index 0000000..74b7913
--- /dev/null
+++ b/libusb/os/driver/vendor_request.c
@@ -0,0 +1,138 @@
+/* LIBUSB-WIN32, Generic Windows USB Library
+ * Copyright (c) 2002-2005 Stephan Meyer <ste_meyer@web.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#include "libusb_driver.h"
+
+
+NTSTATUS vendor_class_request(libusb_device_t *dev,
+ int type, int recipient,
+ int request, int value, int index,
+ void *buffer, int size, int direction,
+ int *ret, int timeout)
+{
+ NTSTATUS status = STATUS_SUCCESS;
+ URB urb;
+
+ *ret = 0;
+
+ DEBUG_PRINT_NL();
+
+ memset(&urb, 0, sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST));
+
+ switch(type)
+ {
+ case USB_TYPE_CLASS:
+ DEBUG_MESSAGE("vendor_class_request(): type: class");
+ switch(recipient)
+ {
+ case USB_RECIP_DEVICE:
+ DEBUG_MESSAGE("vendor_class_request(): recipient: device");
+ urb.UrbHeader.Function = URB_FUNCTION_CLASS_DEVICE;
+ break;
+ case USB_RECIP_INTERFACE:
+ DEBUG_MESSAGE("vendor_class_request(): recipient: interface");
+ urb.UrbHeader.Function = URB_FUNCTION_CLASS_INTERFACE;
+ break;
+ case USB_RECIP_ENDPOINT:
+ DEBUG_MESSAGE("vendor_class_request(): recipient: endpoint");
+ urb.UrbHeader.Function = URB_FUNCTION_CLASS_ENDPOINT;
+ break;
+ case USB_RECIP_OTHER:
+ DEBUG_MESSAGE("vendor_class_request(): recipient: other");
+ urb.UrbHeader.Function = URB_FUNCTION_CLASS_OTHER;
+ break;
+ default:
+ DEBUG_ERROR("vendor_class_request(): invalid recipient");
+ return STATUS_INVALID_PARAMETER;
+ }
+ break;
+ case USB_TYPE_VENDOR:
+ DEBUG_MESSAGE("vendor_class_request(): type: vendor");
+ switch(recipient)
+ {
+ case USB_RECIP_DEVICE:
+ DEBUG_MESSAGE("vendor_class_request(): recipient: device");
+ urb.UrbHeader.Function = URB_FUNCTION_VENDOR_DEVICE;
+ break;
+ case USB_RECIP_INTERFACE:
+ DEBUG_MESSAGE("vendor_class_request(): recipient: interface");
+ urb.UrbHeader.Function = URB_FUNCTION_VENDOR_INTERFACE;
+ break;
+ case USB_RECIP_ENDPOINT:
+ DEBUG_MESSAGE("vendor_class_request(): recipient: endpoint");
+ urb.UrbHeader.Function = URB_FUNCTION_VENDOR_ENDPOINT;
+ break;
+ case USB_RECIP_OTHER:
+ DEBUG_MESSAGE("vendor_class_request(): recipient: other");
+ urb.UrbHeader.Function = URB_FUNCTION_VENDOR_OTHER;
+ break;
+ default:
+ DEBUG_ERROR("vendor_class_request(): invalid recipient");
+ return STATUS_INVALID_PARAMETER;
+ }
+ break;
+ default:
+ DEBUG_ERROR("vendor_class_request(): invalid type");
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ DEBUG_MESSAGE("vendor_class_request(): request: 0x%02x", request);
+ DEBUG_MESSAGE("vendor_class_request(): value: 0x%04x", value);
+ DEBUG_MESSAGE("vendor_class_request(): index: 0x%04x", index);
+ DEBUG_MESSAGE("vendor_class_request(): size: %d", size);
+
+ if(direction == USBD_TRANSFER_DIRECTION_IN)
+ {
+ DEBUG_MESSAGE("vendor_class_request(): direction: in");
+ }
+ else
+ {
+ DEBUG_MESSAGE("vendor_class_request(): direction: out");
+ }
+
+ DEBUG_MESSAGE("vendor_class_request(): timeout: %d", timeout);
+
+ urb.UrbHeader.Length = sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST);
+ urb.UrbControlVendorClassRequest.TransferFlags
+ = direction | USBD_SHORT_TRANSFER_OK ;
+ urb.UrbControlVendorClassRequest.TransferBufferLength = size;
+ urb.UrbControlVendorClassRequest.TransferBufferMDL = NULL;
+ urb.UrbControlVendorClassRequest.TransferBuffer = buffer;
+ urb.UrbControlVendorClassRequest.Request = (UCHAR)request;
+ urb.UrbControlVendorClassRequest.Value = (USHORT)value;
+ urb.UrbControlVendorClassRequest.Index = (USHORT)index;
+
+ status = call_usbd(dev, &urb, IOCTL_INTERNAL_USB_SUBMIT_URB, timeout);
+
+ if(!NT_SUCCESS(status) || !USBD_SUCCESS(urb.UrbHeader.Status))
+ {
+ DEBUG_ERROR("vendor_class_request(): request failed: status: 0x%x, "
+ "urb-status: 0x%x", status, urb.UrbHeader.Status);
+ }
+ else
+ {
+ if(direction == USBD_TRANSFER_DIRECTION_IN)
+ *ret = urb.UrbControlVendorClassRequest.TransferBufferLength;
+ DEBUG_MESSAGE("vendor_class_request(): %d bytes transmitted",
+ urb.UrbControlVendorClassRequest.TransferBufferLength);
+ }
+
+ return status;
+}
+
diff --git a/libusb/os/makefile b/libusb/os/makefile
new file mode 100644
index 0000000..5acbbd2
--- /dev/null
+++ b/libusb/os/makefile
@@ -0,0 +1 @@
+!INCLUDE $(NTMAKEENV)\makefile.def
diff --git a/libusb/os/poll_windows.c b/libusb/os/poll_windows.c
index b6fed7c..a099ff7 100644
--- a/libusb/os/poll_windows.c
+++ b/libusb/os/poll_windows.c
@@ -69,7 +69,7 @@
#include <libusbi.h>
// Uncomment to debug the polling layer
-//#define DEBUG_POLL_WINDOWS
+#define DEBUG_POLL_WINDOWS
// Uncomment to have poll return with EINTR as soon as a new transfer (fd) is added
// This should result in a LIBUSB_ERROR_INTERRUPTED being returned by libusb calls,
@@ -493,7 +493,7 @@ struct winfd usbi_create_fd(HANDLE handle, int access_mode, struct libusb_contex
// NOTE: For now, usbi_fd_notification is only called on fd creation, as
// fd deletion results in a CancelIo() event, which poll should detect.
// Will see if there's an actual justification to call this on delete...
- usbi_fd_notification(ctx);
+// usbi_fd_notification(ctx);
#endif
return wfd;
}
diff --git a/libusb/os/poll_windows.h b/libusb/os/poll_windows.h
index 3c0f6c4..c31cf1e 100644
--- a/libusb/os/poll_windows.h
+++ b/libusb/os/poll_windows.h
@@ -91,6 +91,8 @@ struct winfd fd_to_winfd(int fd);
struct winfd handle_to_winfd(HANDLE handle);
struct winfd overlapped_to_winfd(OVERLAPPED* overlapped);
+void usbi_fd_notification(struct libusb_context *ctx);
+
// When building using the MSDDK and sources
#if defined(DDKBUILD)
#if !defined(timeval)
diff --git a/libusb/os/sources b/libusb/os/sources
index dc474ca..16b548b 100644
--- a/libusb/os/sources
+++ b/libusb/os/sources
@@ -1,5 +1,6 @@
TARGETNAME=libusb-1.0
TARGETTYPE=DYNLINK
+TARGETPATH=obj
DLLDEF=..\libusb-1.0.def
@@ -10,7 +11,7 @@ MSC_WARNING_LEVEL=/W3
USE_MSVCRT=1
INCLUDES=..;..\..;..\..\msvc;$(DDK_INC_PATH)
-C_DEFINES = $(C_DEFINES) /DDDKBUILD
+C_DEFINES = $(C_DEFINES) /DDDKBUILD /D_MSC_VER=1200
TARGETLIBS=$(SDK_LIB_PATH)\kernel32.lib \
$(SDK_LIB_PATH)\advapi32.lib \
diff --git a/libusb/os/windows_usb.c b/libusb/os/windows_usb.c
index bf5a1e5..689a4e1 100644
--- a/libusb/os/windows_usb.c
+++ b/libusb/os/windows_usb.c
@@ -1,7 +1,7 @@
/*
* windows backend for libusb 1.0
* Copyright (c) 2009-2010 Pete Batard <pbatard@gmail.com>
- * With contributions from Michael Plante, Orin Eman et al.
+ * With contributions from Michael Plante, Orin Eman, Graeme W. Gill et al.
* Parts of this code adapted from libusb-win32-v1 by Stephan Meyer
* Major code testing contribution by Xiaofan Chen
*
@@ -78,6 +78,8 @@ static int winusb_abort_control(struct usbi_transfer *itransfer);
static int winusb_reset_device(struct libusb_device_handle *dev_handle);
static int winusb_copy_transfer_data(struct usbi_transfer *itransfer, uint32_t io_size);
// libusb0 API prototypes
+static int libusb0_io_sync(HANDLE dev, unsigned int code, void *out, int out_size,
+ void *in, int in_size, int *ret);
static int libusb0_init(struct libusb_context *ctx);
static int libusb0_exit(void);
static int libusb0_open(struct libusb_device_handle *dev_handle);
@@ -148,7 +150,6 @@ bool api_libusb0_available = false;
bool api_hid_available = false;
#define CHECK_HID_AVAILABLE do { if (!api_hid_available) return LIBUSB_ERROR_ACCESS; } while (0)
-
/*
* Converts a WCHAR string to UTF8 (allocate returned string)
* Returns NULL on error
@@ -1872,6 +1873,7 @@ static int submit_bulk_transfer(struct usbi_transfer *itransfer)
usbi_add_pollfd(ctx, transfer_priv->pollable_fd.fd,
(short)((transfer->endpoint & LIBUSB_ENDPOINT_IN)?POLLIN:POLLOUT));
+ usbi_fd_notification(ctx);
return LIBUSB_SUCCESS;
}
@@ -1891,6 +1893,7 @@ static int submit_iso_transfer(struct usbi_transfer *itransfer)
usbi_add_pollfd(ctx, transfer_priv->pollable_fd.fd,
(short)((transfer->endpoint & LIBUSB_ENDPOINT_IN)?POLLIN:POLLOUT));
+ usbi_fd_notification(ctx);
return LIBUSB_SUCCESS;
}
@@ -1909,6 +1912,7 @@ static int submit_control_transfer(struct usbi_transfer *itransfer)
}
usbi_add_pollfd(ctx, transfer_priv->pollable_fd.fd, POLLIN);
+ usbi_fd_notification(ctx);
return LIBUSB_SUCCESS;
@@ -3101,16 +3105,15 @@ static int libusb0_claim_interface(struct libusb_device_handle *dev_handle, int
struct windows_device_priv *priv = __device_priv(dev_handle->dev);
bool is_composite = (priv->apib->id == USB_API_COMPOSITE);
HANDLE libusb0_handle;
- USB_INTERFACE_DESCRIPTOR if_desc;
- UCHAR policy;
- uint8_t endpoint_address;
- int i;
libusb0_request req;
int ret;
CHECK_LIBUSB0_AVAILABLE;
//printf("~1 libusb0 claim_interface() called\n");
+
+ libusb0_handle = handle_priv->interface_handle[0].dev_handle;
+
// interfaces for composite devices are always independent, therefore
// "alt" interfaces are only found on non-composite
if ((!is_composite) && (iface != 0)) {
@@ -3122,7 +3125,6 @@ static int libusb0_claim_interface(struct libusb_device_handle *dev_handle, int
//printf("~1 inteface 0 hasn't been claimed, so claim it\n");
#if defined(AUTO_CLAIM)
- libusb0_handle = handle_priv->interface_handle[0].dev_handle;
memset(&req, 0, sizeof(req));
req.interface.interface = 0;
@@ -3211,7 +3213,6 @@ static int libusb0_submit_iso_transfer(struct usbi_transfer *itransfer) {
struct windows_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
struct windows_device_handle_priv *handle_priv = (struct windows_device_handle_priv *)transfer->dev_handle->os_priv;
struct windows_device_priv *priv = __device_priv(transfer->dev_handle->dev);
- int num_packets = transfer->num_iso_packets;
HANDLE libusb0_handle;
bool direction_in, ret;
int current_interface;
@@ -3305,7 +3306,6 @@ static int libusb0_submit_control_transfer(struct usbi_transfer *itransfer)
int req_size;
libusb0_request *req;
struct winfd wfd;
- int ret;
CHECK_LIBUSB0_AVAILABLE;
@@ -3579,7 +3579,6 @@ static int libusb0_clear_halt(struct libusb_device_handle *dev_handle, unsigned
{
struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
struct windows_device_handle_priv *handle_priv = (struct windows_device_handle_priv *)dev_handle->os_priv;
- struct windows_device_priv *priv = __device_priv(dev_handle->dev);
HANDLE libusb0_handle;
libusb0_request req;
int ret;
@@ -3605,7 +3604,6 @@ static int libusb0_abort_control(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 windows_device_handle_priv *handle_priv = (struct windows_device_handle_priv *)transfer->dev_handle->os_priv;
- struct windows_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
HANDLE libusb0_handle;
libusb0_request req;
int ret;
@@ -3631,7 +3629,6 @@ static int libusb0_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 windows_device_handle_priv *handle_priv = (struct windows_device_handle_priv *)transfer->dev_handle->os_priv;
- struct windows_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
HANDLE libusb0_handle;
libusb0_request req;
int ret;
@@ -3656,7 +3653,6 @@ static int libusb0_reset_device(struct libusb_device_handle *dev_handle)
{
struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
struct windows_device_handle_priv *handle_priv = (struct windows_device_handle_priv *)dev_handle->os_priv;
- struct windows_device_priv *priv = __device_priv(dev_handle->dev);
HANDLE libusb0_handle;
libusb0_request req;
int ret;
diff --git a/libusb/os/windows_usb.h b/libusb/os/windows_usb.h
index 59dde57..59bb074 100644
--- a/libusb/os/windows_usb.h
+++ b/libusb/os/windows_usb.h
@@ -1,7 +1,7 @@
/*
* Windows backend for libusb 1.0
* Copyright (C) 2009-2010 Pete Batard <pbatard@gmail.com>
- * With contributions from Michael Plante, Orin Eman et al.
+ * With contributions from Michael Plante, Orin Eman, Graeme W. Gill et al.
* Parts of this code adapted from libusb-win32-v1 by Stephan Meyer
* Major code testing contribution by Xiaofan Chen
*