diff options
author | Pete Batard <pbatard@gmail.com> | 2010-03-10 13:14:51 +0000 |
---|---|---|
committer | Pete Batard <pbatard@gmail.com> | 2010-03-10 13:14:51 +0000 |
commit | fae9c17bd2405813d44186c94367d6e66d3994e6 (patch) | |
tree | 8e795a9400182bdabb61229a3791f060af1d5335 | |
parent | 4ee3179ae1e0adefc6c5d19c036c297856ebdef9 (diff) | |
download | libusb-fae9c17bd2405813d44186c94367d6e66d3994e6.tar.gz |
libusb0.sys backend integration - part 2 (Graeme Gill)c190
45 files changed, 4918 insertions, 40 deletions
@@ -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 * |