├── .gitignore ├── CMakeLists.txt ├── LICENSE ├── README ├── cmake_modules └── Findlibusb-1.0.cmake ├── include ├── config.h.in ├── libnv3p.h ├── libnvfblob.h ├── linux │ ├── libnvusb.h │ └── wheelie_os.h ├── osx │ ├── libnvusb.h │ └── wheelie_os.h ├── payloads.h ├── shared.h ├── wheelie.h └── win32 │ ├── getopt.h │ ├── libnvusb.h │ ├── wheelie_os.h │ └── winusb │ ├── POPPACK.H │ ├── PSHPACK1.H │ ├── usb.h │ ├── usb100.h │ ├── usb200.h │ ├── winusb.h │ └── winusbio.h ├── libnv3p └── libnv3p.c ├── libnvfblob └── libnvfblob.c ├── os └── win32 │ ├── README.txt │ ├── getopt.c │ └── getopt_long.c ├── usb ├── linux │ └── libnvusb.c ├── osx │ └── libnvusb.c └── win32 │ └── libnvusb.c └── wheelie.c /.gitignore: -------------------------------------------------------------------------------- 1 | wheelie 2 | build 3 | bin 4 | include/config.h 5 | CMakeCache.txt 6 | CMakeFiles/ 7 | Makefile 8 | cmake_install.cmake 9 | 10 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(wheelie) 2 | 3 | cmake_minimum_required(VERSION 2.6) 4 | 5 | if(BUILD_32BIT) 6 | set (CMAKE_C_FLAGS "-m32") 7 | set (CMAKE_LD_FLAGS "-m32") 8 | endif(BUILD_32BIT) 9 | 10 | SET(EXECUTABLE_OUTPUT_PATH bin) 11 | SET(LIBRARY_OUTPUT_PATH bin/lib) 12 | set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules/") 13 | SET(CMAKE_BUILD_TYPE Debug) 14 | 15 | SET(SHARED_SOURCES include/payloads.h include/wheelie.h) 16 | SET(WHEELIE_SOURCES wheelie.c ${SHARED_SOURCES}) 17 | 18 | IF(${CMAKE_SYSTEM_NAME} MATCHES "Linux") 19 | Find_Package(libusb-1.0 REQUIRED) 20 | # ${LIBUSB_1_INCLUDE_DIRS} is set manually in CMake on windows 21 | # so we still need the include dir! 22 | INCLUDE_DIRECTORIES(${LIBUSB_1_INCLUDE_DIRS}) 23 | 24 | SET(LIBNVUSB_SOURCES usb/linux/libnvusb.c include/linux/libnvusb.h) 25 | SET(USBLIBS ${LIBUSB_1_LIBRARIES}) 26 | INCLUDE_DIRECTORIES(include/linux) 27 | 28 | ENDIF(${CMAKE_SYSTEM_NAME} MATCHES "Linux") 29 | 30 | IF(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") 31 | SET(LIBNVUSB_SOURCES usb/osx/libnvusb.c include/osx/libnvusb.h) 32 | INCLUDE_DIRECTORIES(include/osx) 33 | find_library(IOKIT NAMES IOKit) 34 | find_library(COREFOUNDATION NAMES CoreFoundation) 35 | SET(USBLIBS ${IOKIT} ${COREFOUNDATION}) 36 | ENDIF(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") 37 | 38 | IF(WIN32) 39 | SET(LIBNVUSB_SOURCES usb/win32/libnvusb.c include/win32/libnvusb.h) 40 | #FIND_PATH(WINUSB_INCLUDE ddk/winusb.h HINTS C:/WinDDK/7600.16385.1/inc) 41 | INCLUDE_DIRECTORIES( include/win32/winusb ) 42 | find_library(WINUSB_LIB winusb HINTS C:/WinDDK/7600.16385.1/lib/win7/amd64) 43 | find_library(SETUPAPI_LIB setupapi HINTS C:/WinDDK/7600.16385.1/lib/win7/amd64) 44 | SET(USBLIBS ${WINUSB_LIB} ${SETUPAPI_LIB}) 45 | ENDIF(WIN32) 46 | 47 | 48 | SET(LIBNV3P_SOURCES libnv3p/libnv3p.c include/libnv3p.h) 49 | SET(LIBNVFBLOB_SOURCES libnvfblob/libnvfblob.c include/libnvfblob.h) 50 | 51 | INCLUDE_DIRECTORIES(include) 52 | 53 | IF(WIN32) 54 | INCLUDE_DIRECTORIES(include/win32) 55 | SET(WHEELIE_SOURCES ${WHEELIE_SOURCES} include/win32/getopt.h os/win32/getopt.c os/win32/getopt_long.c) 56 | ADD_DEFINITIONS(/D _CRT_SECURE_NO_WARNINGS) 57 | ENDIF(WIN32) 58 | 59 | SET(WHEELIE_VERSION 0.2) 60 | 61 | # Should get this from USB library subproject? 62 | SET(USB_VERSION 0.1) 63 | SET(USB_ABI 0.1) 64 | 65 | # Should come from nv3p subproject 66 | SET(NV3P_VERSION 0.1) 67 | SET(NV3P_ABI 0.1) 68 | 69 | # Do debug prints 70 | OPTION(DEBUGOUTPUT "Print extra debug messages" OFF) 71 | OPTION(STATIC_COMPILE "Compile wheelie statically" OFF) 72 | OPTION(BUILD_32BIT "Build 32-bit version" OFF) 73 | 74 | ADD_LIBRARY(nvusb ${LIBNVUSB_SOURCES}) 75 | 76 | ADD_LIBRARY(nv3p ${LIBNV3P_SOURCES}) 77 | 78 | ADD_LIBRARY(nvfblob ${LIBNVFBLOB_SOURCES}) 79 | TARGET_LINK_LIBRARIES(nv3p nvusb nvfblob) 80 | 81 | ADD_EXECUTABLE(wheelie ${WHEELIE_SOURCES}) 82 | 83 | 84 | 85 | if(STATIC_COMPILE) 86 | 87 | message(STATUS "Statically Linked") 88 | 89 | find_library(LIBUSB_1_STATIC_LIBRARIES NAMES libusb-1.0.a PATHS /usr/lib /usr/local/lib /opt/local/lib /sw/lib) 90 | ADD_LIBRARY(libusb STATIC IMPORTED) 91 | set_property(TARGET libusb PROPERTY IMPORTED_LOCATION ${LIBUSB_1_STATIC_LIBRARIES}) 92 | 93 | find_library(LIBPTHREAD_LIBRARY NAMES libpthread.a PATHS /usr/lib /usr/local/lib /opt/local/lib /sw/lib) 94 | ADD_LIBRARY(libpthread STATIC IMPORTED) 95 | set_property(TARGET libpthread PROPERTY IMPORTED_LOCATION ${LIBPTHREAD_LIBRARY}) 96 | 97 | TARGET_LINK_LIBRARIES(nvusb libusb) 98 | TARGET_LINK_LIBRARIES(wheelie nv3p nvusb libusb libpthread -static -lrt) 99 | 100 | else(STATIC_COMPILE) 101 | 102 | message(STATUS "Dynamically Linked") 103 | 104 | TARGET_LINK_LIBRARIES(nvusb ${USBLIBS}) 105 | TARGET_LINK_LIBRARIES(wheelie nv3p nvusb nvfblob ${USBLIBS}) 106 | 107 | endif(STATIC_COMPILE) 108 | 109 | 110 | 111 | configure_file(${CMAKE_SOURCE_DIR}/include/config.h.in ${CMAKE_SOURCE_DIR}/include/config.h @ONLY) 112 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | _ _ _ _____ _ __ __ _ _ 2 | /\ | | (_) | | __ \ | | | \/ | | | (_) 3 | / \ _ __ __| |_ __ ___ _ __| | |__) |___ ___ | |_ | \ / | ___ | |__ _ 4 | / /\ \ | '_ \ / _` | '__/ _ \| |/ _` | _ // _ \ / _ \| __| | |\/| |/ _ \| '_ \| | 5 | / ____ \| | | | (_| | | | (_) | | (_| | | \ \ (_) | (_) | |_ _| | | | (_) | |_) | | 6 | /_/ \_\_| |_|\__,_|_| \___/|_|\__,_|_| \_\___/ \___/ \__(_)_| |_|\___/|_.__/|_| 7 | 8 | 9 | 10 | Wheelie 0.2 11 | Nvidia Tegra 2/3 APX/nv3p protocol implementation. 12 | 13 | * Supports bootstrapping a pre-encrypted bootloader from USB BootROM (APX) 14 | * Supports tegra 2/3 Pre-JB Bootloader 15 | * Support pre-encrypted blobs 16 | * Linux, Windows and OS X (OS X is beta-quality) support 17 | * Functionality 18 | * Bootstrap 19 | * Flash Bootloader 20 | * Raw-flash parts of the flash 21 | 22 | Authors: 23 | * RaYmAn (@DroidRay, github.com/EnJens) 24 | * Bumble-Bee (@BumbleDroid, github.com/BuzzBumbleBee) 25 | * Lilstevie (@littlesteve, github.com/lilstevie) 26 | * kmdm (github.com/kmdm) 27 | * IEF (@ief_tm github.com/IEF) 28 | -------------------------------------------------------------------------------- /cmake_modules/Findlibusb-1.0.cmake: -------------------------------------------------------------------------------- 1 | # - Try to find libusb-1.0 2 | # Once done this will define 3 | # 4 | # LIBUSB_1_FOUND - system has libusb 5 | # LIBUSB_1_INCLUDE_DIRS - the libusb include directory 6 | # LIBUSB_1_LIBRARIES - Link these to use libusb 7 | # LIBUSB_1_DEFINITIONS - Compiler switches required for using libusb 8 | # 9 | # Adapted from cmake-modules Google Code project 10 | # 11 | # Copyright (c) 2006 Andreas Schneider 12 | # 13 | # (Changes for libusb) Copyright (c) 2008 Kyle Machulis 14 | # 15 | # Redistribution and use is allowed according to the terms of the New BSD license. 16 | # 17 | # CMake-Modules Project New BSD License 18 | # 19 | # Redistribution and use in source and binary forms, with or without 20 | # modification, are permitted provided that the following conditions are met: 21 | # 22 | # * Redistributions of source code must retain the above copyright notice, this 23 | # list of conditions and the following disclaimer. 24 | # 25 | # * Redistributions in binary form must reproduce the above copyright notice, 26 | # this list of conditions and the following disclaimer in the 27 | # documentation and/or other materials provided with the distribution. 28 | # 29 | # * Neither the name of the CMake-Modules Project nor the names of its 30 | # contributors may be used to endorse or promote products derived from this 31 | # software without specific prior written permission. 32 | # 33 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 34 | # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 35 | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 36 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 37 | # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 38 | # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 39 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 40 | # ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 41 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 42 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 43 | # 44 | 45 | 46 | if (LIBUSB_1_LIBRARIES AND LIBUSB_1_INCLUDE_DIRS) 47 | # in cache already 48 | set(LIBUSB_FOUND TRUE) 49 | else (LIBUSB_1_LIBRARIES AND LIBUSB_1_INCLUDE_DIRS) 50 | find_path(LIBUSB_1_INCLUDE_DIR 51 | NAMES 52 | libusb.h 53 | PATHS 54 | /usr/include 55 | /usr/local/include 56 | /opt/local/include 57 | /sw/include 58 | PATH_SUFFIXES 59 | libusb-1.0 60 | ) 61 | 62 | find_library(LIBUSB_1_LIBRARY 63 | NAMES 64 | usb-1.0 65 | PATHS 66 | /usr/lib 67 | /usr/local/lib 68 | /opt/local/lib 69 | /sw/lib 70 | ) 71 | 72 | set(LIBUSB_1_INCLUDE_DIRS 73 | ${LIBUSB_1_INCLUDE_DIR} 74 | ) 75 | set(LIBUSB_1_LIBRARIES 76 | ${LIBUSB_1_LIBRARY} 77 | ) 78 | 79 | if (LIBUSB_1_INCLUDE_DIRS AND LIBUSB_1_LIBRARIES) 80 | set(LIBUSB_1_FOUND TRUE) 81 | endif (LIBUSB_1_INCLUDE_DIRS AND LIBUSB_1_LIBRARIES) 82 | 83 | if (LIBUSB_1_FOUND) 84 | if (NOT libusb_1_FIND_QUIETLY) 85 | message(STATUS "Found libusb-1.0:") 86 | message(STATUS " - Includes: ${LIBUSB_1_INCLUDE_DIRS}") 87 | message(STATUS " - Libraries: ${LIBUSB_1_LIBRARIES}") 88 | endif (NOT libusb_1_FIND_QUIETLY) 89 | else (LIBUSB_1_FOUND) 90 | if (libusb_1_FIND_REQUIRED) 91 | message(FATAL_ERROR "Could not find libusb") 92 | endif (libusb_1_FIND_REQUIRED) 93 | endif (LIBUSB_1_FOUND) 94 | 95 | # show the LIBUSB_1_INCLUDE_DIRS and LIBUSB_1_LIBRARIES variables only in the advanced view 96 | mark_as_advanced(LIBUSB_1_INCLUDE_DIRS LIBUSB_1_LIBRARIES) 97 | 98 | endif (LIBUSB_1_LIBRARIES AND LIBUSB_1_INCLUDE_DIRS) 99 | -------------------------------------------------------------------------------- /include/config.h.in: -------------------------------------------------------------------------------- 1 | #ifndef _WHEELIE_CONFIG_H_ 2 | #define _WHEELIE_CONFIG_H_ 3 | 4 | #define WHEELIE_VERSION "@WHEELIE_VERSION@" 5 | #define USB_VERSION "@USB_VERSION@" 6 | #define USB_ABI "@USB_ABI@" 7 | #define NV3P_VERSION "@NV3P_VERSION@" 8 | #define NV3P_ABI "@NV3P_ABI@" 9 | #cmakedefine DEBUGOUTPUT 10 | 11 | #endif /* _WHEELIE_CONFIG_H_ */ -------------------------------------------------------------------------------- /include/libnv3p.h: -------------------------------------------------------------------------------- 1 | /* libnv3p.h - Library for Nv3p communications. 2 | * 3 | * Copyright (C) 2015 androidroot.mobi 4 | * 5 | * This file is part of libnv3p. 6 | * 7 | * libnvusb is free software; you can redistribute it and/or modify it 8 | * under the terms of the GNU General Public License v2 as published by the 9 | * Free Software Foundation. 10 | * 11 | * libnvusb is distributed in the hope that it will be useful, but 12 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 14 | * more details. 15 | 16 | * You should have received a copy of the GNU General Public License along with 17 | * this program; if not, write to the Free Software Foundation, Inc., 18 | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | 22 | #include 23 | 24 | #include "libnvusb.h" 25 | 26 | #define PACKET_HEADER_LEN 12 27 | #define PACKET_COMMAND_HEADER_LEN 8 28 | #define PACKET_DATA_HEADER_LEN 4 29 | #define PACKET_CHECKSUM_LEN 4 30 | #define PACKET_ACK_LEN 0 31 | #define PACKET_NACK_LEN 4 32 | #define NV3P_VERS 0x1 33 | #define STRING_MAX 32 34 | 35 | #define NV3P_COMMAND 0x1 36 | #define NV3P_DATA 0x2 37 | #define NV3P_ACK 0x4 38 | #define NV3P_NACK 0x5 39 | 40 | #define NV3P_COMMAND_GETINFO 0x1 41 | #define NV3P_COMMAND_GETINFO_LEN 56 42 | #define NV3P_COMMAND_SENDBCT 0x5 43 | #define NV3P_COMMAND_SENDBL 0x6 44 | #define NV3P_COMMAND_SENDODM 0x7 // Remap? 45 | #define NV3P_COMMAND_STATUS 0x0a 46 | #define NV3P_COMMAND_PARTITION_TABLE 0x13 47 | #define NV3P_COMMAND_SYNCRONIZE 0x19 48 | #define NV3P_COMMAND_RAWWRITE 0x1F 49 | 50 | typedef void (*nv3p_status_callback_t) (size_t, size_t); 51 | 52 | typedef struct{ 53 | uint32_t start; 54 | uint32_t size; 55 | } nv3p_rawargs; 56 | 57 | typedef struct{ 58 | uint64_t filesize; 59 | uint32_t loadaddr; 60 | uint32_t entry; 61 | } nv3p_blargs; 62 | 63 | typedef struct{ 64 | uint32_t filesize; 65 | } nv3p_bctargs; 66 | 67 | typedef struct{ 68 | uint32_t odmdata; 69 | } nv3p_odmargs; 70 | 71 | 72 | typedef struct nv3p_header_t{ 73 | uint32_t version; 74 | uint32_t type; 75 | uint32_t sequence; 76 | }nv3p_header; 77 | 78 | 79 | typedef struct nv3p_body_t{ 80 | uint32_t length; 81 | uint32_t command; 82 | union 83 | { 84 | nv3p_blargs blargs; 85 | nv3p_bctargs bctargs; 86 | nv3p_odmargs odmargs; 87 | nv3p_rawargs rawargs; 88 | }; 89 | } nv3p_body; 90 | 91 | // Max command packet length is header + body + checksum 92 | // There might be a longer command, 93 | // but this is the longest command we've reversed so far. 94 | #define NV3P_MAX_COMMAND_LEN (sizeof(nv3p_header) + sizeof(nv3p_body) + sizeof(int)) 95 | 96 | typedef struct nv3p_chipid_t{ 97 | uint16_t id; 98 | uint8_t major; 99 | uint8_t minor; 100 | }nv3p_chipid; 101 | 102 | // TODO: Figure out rest of bootdevice options 103 | #define NV3P_PLATFORM_BOOTDEVICE_EMMC 0x2d 104 | 105 | typedef struct nv3p_platinfo_t{ 106 | uint64_t chipuid[2]; 107 | struct nv3p_chipid_t chipid; 108 | uint32_t sku; 109 | uint32_t version; 110 | // Most of these fields are essentially unknowns, 111 | // but they are printed by nvflash as names that match these. 112 | uint32_t bootdevice; 113 | uint32_t opmode; 114 | uint32_t devstrap; 115 | uint32_t fuse; 116 | uint32_t sdramstrap; 117 | uint32_t devicekeyStatus; 118 | uint8_t hdcp; 119 | uint8_t macrovision; 120 | uint8_t secureboot; 121 | } nv3p_platinfo; 122 | 123 | typedef struct{ 124 | struct nv3p_header_t header; 125 | struct nv3p_body_t body; 126 | uint32_t checksum; 127 | } nv3p_packet; 128 | 129 | 130 | int nv3p_send_command(nvDevice_t nvdev, uint32_t command, uint8_t *args); 131 | 132 | uint8_t nv3p_command_response(nvDevice_t nvdev, uint32_t command, uint8_t *packet); 133 | 134 | int nv3p_wait_status(nvDevice_t nvdev); 135 | 136 | int nv3p_send_file(nvDevice_t nvdev, char *filename, uint64_t filesize, nv3p_status_callback_t status_callback); 137 | 138 | int nv3p_send_buffer(nvDevice_t nvdev, uint8_t *data, int32_t dataLen, nv3p_status_callback_t status_callback); 139 | int nv3p_send_data(nvDevice_t nvdev, uint8_t *data, int32_t dataLen); 140 | void nv3p_set_ics_protocol(int flag); 141 | -------------------------------------------------------------------------------- /include/libnvfblob.h: -------------------------------------------------------------------------------- 1 | /* libnvfblob.c - Library for parsing nvflash style blobs. 2 | * 3 | * Copyright (C) 2015 androidroot.mobi 4 | * 5 | * This file is part of libnvfblob. 6 | * 7 | * Wheelie is free software; you can redistribute it and/or modify it 8 | * under the terms of the GNU General Public License v2 as published by the 9 | * Free Software Foundation. 10 | * 11 | * Wheelie is distributed in the hope that it will be useful, but 12 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 14 | * more details. 15 | 16 | * You should have received a copy of the GNU General Public License along with 17 | * this program; if not, write to the Free Software Foundation, Inc., 18 | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef LIBNVFBLOB_H 22 | #define LIBNVFBLOB_H 23 | #include 24 | 25 | #define NVFBLOB_HASH_SIZE 16 26 | 27 | typedef struct { 28 | enum { 29 | NVFBLOB_TYPE_VERSION = 0x01, 30 | NVFBLOB_TYPE_RCMVER, 31 | NVFBLOB_TYPE_RCMDLEXEC, 32 | NVFBLOB_TYPE_BLHASH, 33 | NVFBLOB_TYPE_EXT_WHEELIE_BCTC = 0x7F000000, 34 | NVFBLOB_TYPE_EXT_WHEELIE_BCTR, 35 | NVFBLOB_TYPE_EXT_WHEELIE_BL, 36 | NVFBLOB_TYPE_EXT_WHEELIE_ODMDATA, 37 | NVFBLOB_TYPE_EXT_WHEELIE_CPU_ID, 38 | NVFBLOB_TYPE_FORCE32 = 0x7FFFFFFF 39 | } type; 40 | uint32_t length; 41 | uint32_t reserved1; 42 | uint32_t reserved2; 43 | unsigned char hash[NVFBLOB_HASH_SIZE]; 44 | } nvfblob_header_t; 45 | 46 | typedef void * nvfblob_file_t; 47 | 48 | nvfblob_file_t nvfblob_open(const char *); 49 | int nvfblob_alloc_read(nvfblob_file_t, uint32_t, unsigned char **, size_t *); 50 | void nvfblob_alloc_free(unsigned char **); 51 | int nvfblob_close(nvfblob_file_t); 52 | #endif 53 | -------------------------------------------------------------------------------- /include/linux/libnvusb.h: -------------------------------------------------------------------------------- 1 | /* libnvusb.c - Library for nvusb functions 2 | * 3 | * Copyright (C) 2015 androidroot.mobi 4 | * 5 | * This file is part of libnvusb. 6 | * 7 | * libnvusb is free software; you can redistribute it and/or modify it 8 | * under the terms of the GNU General Public License v2 as published by the 9 | * Free Software Foundation. 10 | * 11 | * libnvusb is distributed in the hope that it will be useful, but 12 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 14 | * more details. 15 | 16 | * You should have received a copy of the GNU General Public License along with 17 | * this program; if not, write to the Free Software Foundation, Inc., 18 | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef _LIBNVUSB_H_ 22 | #define _LIBNVUSB_H_ 23 | #include 24 | 25 | #define USB_MINIMUM_READ_LENGTH 64 26 | #ifndef MAX 27 | #define MAX(x,y) (((x) > (y)) ? (x) : (y)) 28 | #endif 29 | #ifndef MIN 30 | #define MIN(x,y) (((x) < (y)) ? (x) : (y)) 31 | #endif 32 | 33 | struct nvDevice; 34 | typedef struct nvDevice* nvDevice_t; 35 | 36 | struct nvDevice{ 37 | 38 | int nvDeviceDetected; 39 | libusb_device_handle * nvDeviceID; 40 | libusb_device * nvDeviceIDGet; 41 | int nvDeviceRead; 42 | uint8_t nvDeviceEndpointIn; 43 | uint8_t nvDeviceEndpointOut; 44 | uint32_t nvSequence; 45 | uint32_t nvRecSequence; 46 | // Buffer to store data 47 | // Bulk reads have to be minimum 64 bytes, so 48 | uint8_t remainingData[USB_MINIMUM_READ_LENGTH]; 49 | int32_t remainingSize; 50 | }; 51 | 52 | int nvusb_detect_device(int prodid, int32_t vendid, nvDevice_t* pnvdev); 53 | 54 | int nvusb_get_chipuid(nvDevice_t nvdev); 55 | 56 | int nvusb_send(nvDevice_t nvdev, uint8_t *buffer, int32_t size); 57 | 58 | int nvusb_receive(nvDevice_t nvdev, uint8_t *buffer, int32_t size); 59 | 60 | int nvusb_receive_unbuffered(nvDevice_t nvdev, uint8_t *buffer, int32_t size); 61 | 62 | void nvusb_device_close(nvDevice_t* nvdev); 63 | 64 | void nvusb_versions(); 65 | 66 | #endif /* _LIBNVUSB_H_ */ 67 | -------------------------------------------------------------------------------- /include/linux/wheelie_os.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AndroidRoot/wheelie/f7c5aca395be584524d6d7c9fafcffb022e911fa/include/linux/wheelie_os.h -------------------------------------------------------------------------------- /include/osx/libnvusb.h: -------------------------------------------------------------------------------- 1 | /* libnvusb.c - Library for nvusb functions 2 | * 3 | * Copyright (C) 2015 androidroot.mobi 4 | * 5 | * This file is part of libnvusb. 6 | * 7 | * libnvusb is free software; you can redistribute it and/or modify it 8 | * under the terms of the GNU General Public License v2 as published by the 9 | * Free Software Foundation. 10 | * 11 | * libnvusb is distributed in the hope that it will be useful, but 12 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 14 | * more details. 15 | 16 | * You should have received a copy of the GNU General Public License along with 17 | * this program; if not, write to the Free Software Foundation, Inc., 18 | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef _LIBNVUSB_H_ 22 | #define _LIBNVUSB_H_ 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | #define USB_MINIMUM_READ_LENGTH 64 31 | #ifndef MAX 32 | #define MAX(x,y) (((x) > (y)) ? (x) : (y)) 33 | #endif 34 | #ifndef MIN 35 | #define MIN(x,y) (((x) < (y)) ? (x) : (y)) 36 | #endif 37 | 38 | struct nvDevice; 39 | typedef struct nvDevice* nvDevice_t; 40 | 41 | struct nvDevice{ 42 | 43 | int nvDeviceDetected; 44 | void * nvDeviceID; 45 | void * nvDeviceIDGet; 46 | int nvDeviceRead; 47 | uint8_t nvDeviceEndpointIn; 48 | uint8_t nvDeviceEndpointOut; 49 | uint32_t nvSequence; 50 | uint32_t nvRecSequence; 51 | IOUSBDeviceInterface ** deviceinterface; /* interface to device, NULL = no interface */ 52 | IOUSBInterfaceInterface ** interface; // Arg. OSX 53 | // Buffer to store data 54 | // Bulk reads have to be minimum 64 bytes, so 55 | uint8_t remainingData[USB_MINIMUM_READ_LENGTH]; 56 | int32_t remainingSize; 57 | }; 58 | 59 | int nvusb_detect_device(int prodid, int32_t vendid, nvDevice_t* pnvdev); 60 | 61 | int nvusb_get_chipuid(nvDevice_t nvdev); 62 | 63 | int nvusb_send(nvDevice_t nvdev, uint8_t *buffer, int32_t size); 64 | 65 | int nvusb_receive(nvDevice_t nvdev, uint8_t *buffer, int32_t size); 66 | 67 | int nvusb_receive_unbuffered(nvDevice_t nvdev, uint8_t *buffer, int32_t size); 68 | 69 | void nvusb_device_close(nvDevice_t* nvdev); 70 | 71 | void nvusb_versions(); 72 | 73 | #endif /* _LIBNVUSB_H_ */ 74 | -------------------------------------------------------------------------------- /include/osx/wheelie_os.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AndroidRoot/wheelie/f7c5aca395be584524d6d7c9fafcffb022e911fa/include/osx/wheelie_os.h -------------------------------------------------------------------------------- /include/shared.h: -------------------------------------------------------------------------------- 1 | /* libnvfblob.c - Library for parsing nvflash style blobs. 2 | * 3 | * Copyright (C) 2015 androidroot.mobi 4 | * 5 | * This file is part of wheelie. 6 | * 7 | * Wheelie is free software; you can redistribute it and/or modify it 8 | * under the terms of the GNU General Public License v2 as published by the 9 | * Free Software Foundation. 10 | * 11 | * Wheelie is distributed in the hope that it will be useful, but 12 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 14 | * more details. 15 | 16 | * You should have received a copy of the GNU General Public License along with 17 | * this program; if not, write to the Free Software Foundation, Inc., 18 | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef _WHEELIE_SHARED_H_ 22 | #define _WHEELIE_SHARED_H_ 23 | 24 | #include "wheelie_os.h" 25 | 26 | #ifdef DEBUGOUTPUT 27 | #define DEBUGPRINT(...) { printf(__VA_ARGS__); } 28 | #else 29 | #define DEBUGPRINT(...) 30 | #endif 31 | 32 | #endif /* _WHEELIE_SHARED_H_ */ 33 | -------------------------------------------------------------------------------- /include/wheelie.h: -------------------------------------------------------------------------------- 1 | /* wheelie.h - Preflight for nvflash 2 | * 3 | * Copyright (C) 2015 androidroot.mobi 4 | * 5 | * This file is part of Wheelie. 6 | * 7 | * Wheelie is free software; you can redistribute it and/or modify it 8 | * under the terms of the GNU General Public License v2 as published by the 9 | * Free Software Foundation. 10 | * 11 | * Wheelie is distributed in the hope that it will be useful, but 12 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 14 | * more details. 15 | 16 | * You should have received a copy of the GNU General Public License along with 17 | * this program; if not, write to the Free Software Foundation, Inc., 18 | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #include 22 | 23 | int filetest(const char* filename, size_t *filesize){ 24 | struct stat info; 25 | int ret = -1; 26 | uint32_t fsize; 27 | 28 | ret = stat(filename, &info); 29 | fsize = info.st_size; 30 | *filesize = fsize; 31 | if(ret == 0){ 32 | return 1; 33 | }else{ 34 | return 0; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /include/win32/getopt.h: -------------------------------------------------------------------------------- 1 | /* $NetBSD: getopt.h,v 1.4 2000/07/07 10:43:54 ad Exp $ */ 2 | /* $FreeBSD: src/include/getopt.h,v 1.1 2002/09/29 04:14:30 eric Exp $ */ 3 | 4 | /*- 5 | * Copyright (c) 2000 The NetBSD Foundation, Inc. 6 | * All rights reserved. 7 | * 8 | * This code is derived from software contributed to The NetBSD Foundation 9 | * by Dieter Baron and Thomas Klausner. 10 | * 11 | * Redistribution and use in source and binary forms, with or without 12 | * modification, are permitted provided that the following conditions 13 | * are met: 14 | * 1. Redistributions of source code must retain the above copyright 15 | * notice, this list of conditions and the following disclaimer. 16 | * 2. Redistributions in binary form must reproduce the above copyright 17 | * notice, this list of conditions and the following disclaimer in the 18 | * documentation and/or other materials provided with the distribution. 19 | * 3. All advertising materials mentioning features or use of this software 20 | * must display the following acknowledgement: 21 | * This product includes software developed by the NetBSD 22 | * Foundation, Inc. and its contributors. 23 | * 4. Neither the name of The NetBSD Foundation nor the names of its 24 | * contributors may be used to endorse or promote products derived 25 | * from this software without specific prior written permission. 26 | * 27 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 28 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 29 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 30 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 31 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 32 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 33 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 34 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 35 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 36 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 37 | * POSSIBILITY OF SUCH DAMAGE. 38 | */ 39 | 40 | #ifndef _GETOPT_H_ 41 | #define _GETOPT_H_ 42 | 43 | #ifdef _WIN32 44 | /* from */ 45 | # ifdef __cplusplus 46 | # define __BEGIN_DECLS extern "C" { 47 | # define __END_DECLS } 48 | # else 49 | # define __BEGIN_DECLS 50 | # define __END_DECLS 51 | # endif 52 | # define __P(args) args 53 | #endif 54 | 55 | /*#ifndef _WIN32 56 | #include 57 | #include 58 | #endif*/ 59 | 60 | /*#ifdef _WIN32 61 | # if !defined(GETOPT_API) 62 | # define GETOPT_API __declspec(dllimport) 63 | # endif 64 | #endif*/ 65 | #ifndef GETOPT_API 66 | #define GETOPT_API 67 | #endif 68 | 69 | /* 70 | * Gnu like getopt_long() and BSD4.4 getsubopt()/optreset extensions 71 | */ 72 | #if !defined(_POSIX_SOURCE) && !defined(_XOPEN_SOURCE) 73 | #define no_argument 0 74 | #define required_argument 1 75 | #define optional_argument 2 76 | 77 | struct option { 78 | /* name of long option */ 79 | const char *name; 80 | /* 81 | * one of no_argument, required_argument, and optional_argument: 82 | * whether option takes an argument 83 | */ 84 | int has_arg; 85 | /* if not NULL, set *flag to val when option found */ 86 | int *flag; 87 | /* if flag not NULL, value to set *flag to; else return value */ 88 | int val; 89 | }; 90 | 91 | __BEGIN_DECLS 92 | GETOPT_API int getopt_long __P((int, char * const *, const char *, 93 | const struct option *, int *)); 94 | __END_DECLS 95 | #endif 96 | 97 | #ifdef _WIN32 98 | /* These are global getopt variables */ 99 | __BEGIN_DECLS 100 | 101 | GETOPT_API extern int opterr, /* if error message should be printed */ 102 | optind, /* index into parent argv vector */ 103 | optopt, /* character checked for validity */ 104 | optreset; /* reset getopt */ 105 | GETOPT_API extern char* optarg; /* argument associated with option */ 106 | 107 | /* Original getopt */ 108 | GETOPT_API int getopt __P((int, char * const *, const char *)); 109 | 110 | __END_DECLS 111 | #endif 112 | 113 | #endif /* !_GETOPT_H_ */ 114 | -------------------------------------------------------------------------------- /include/win32/libnvusb.h: -------------------------------------------------------------------------------- 1 | /* libnvusb.c - Library for nvusb functions 2 | * 3 | * Copyright (C) 2015 androidroot.mobi 4 | * 5 | * This file is part of libnvusb. 6 | * 7 | * libnvusb is free software; you can redistribute it and/or modify it 8 | * under the terms of the GNU General Public License v2 as published by the 9 | * Free Software Foundation. 10 | * 11 | * libnvusb is distributed in the hope that it will be useful, but 12 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 14 | * more details. 15 | 16 | * You should have received a copy of the GNU General Public License along with 17 | * this program; if not, write to the Free Software Foundation, Inc., 18 | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef _LIBNVUSB_H_ 22 | #define _LIBNVUSB_H_ 23 | 24 | #define WIN32_LEAN_AND_MEAN 25 | #include 26 | 27 | #define USB_MINIMUM_READ_LENGTH 64 28 | #ifndef MAX 29 | #define MAX(x,y) (((x) > (y)) ? (x) : (y)) 30 | #endif 31 | #ifndef MIN 32 | #define MIN(x,y) (((x) < (y)) ? (x) : (y)) 33 | #endif 34 | 35 | struct nvDevice; 36 | typedef struct nvDevice* nvDevice_t; 37 | 38 | struct nvDevice{ 39 | 40 | int nvDeviceDetected; 41 | int nvDeviceRead; 42 | // Defined as void pointers to not infect libnvusb.h with WinUSB stuff. 43 | void* nvAPX; 44 | void* nvWinUSBAPX; 45 | uint8_t nvDeviceEndpointIn; 46 | uint8_t nvDeviceEndpointOut; 47 | uint32_t nvSequence; 48 | uint32_t nvRecSequence; 49 | 50 | // Buffer to store data 51 | // Bulk reads have to be minimum 64 bytes, so 52 | uint8_t remainingData[USB_MINIMUM_READ_LENGTH]; 53 | int32_t remainingSize; 54 | }; 55 | 56 | int nvusb_detect_device(int prodid, int32_t vendid, nvDevice_t* pnvdev); 57 | 58 | int nvusb_send(nvDevice_t nvdev, uint8_t *buffer, int32_t size); 59 | 60 | int nvusb_receive(nvDevice_t nvdev, uint8_t *buffer, int32_t size); 61 | 62 | int nvusb_receive_unbuffered(nvDevice_t nvdev, uint8_t *buffer, int32_t size); 63 | 64 | void nvusb_device_close(nvDevice_t* nvdev); 65 | 66 | void nvusb_versions(); 67 | 68 | #endif /* _LIBNVUSB_H_ */ 69 | -------------------------------------------------------------------------------- /include/win32/wheelie_os.h: -------------------------------------------------------------------------------- 1 | /* libnvfblob.c - Library for parsing nvflash style blobs. 2 | * 3 | * Copyright (C) 2015 androidroot.mobi 4 | * 5 | * This file is part of wheelie. 6 | * 7 | * Wheelie is free software; you can redistribute it and/or modify it 8 | * under the terms of the GNU General Public License v2 as published by the 9 | * Free Software Foundation. 10 | * 11 | * Wheelie is distributed in the hope that it will be useful, but 12 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 14 | * more details. 15 | 16 | * You should have received a copy of the GNU General Public License along with 17 | * this program; if not, write to the Free Software Foundation, Inc., 18 | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | 22 | #ifndef _WHEELIE_OS_H_ 23 | #define _WHEELIE_OS_H_ 24 | 25 | #include 26 | 27 | typedef UINT8 uint8_t; 28 | typedef UINT16 uint16_t; 29 | typedef UINT32 uint32_t; 30 | typedef UINT64 uint64_t; 31 | typedef INT8 int8_t; 32 | typedef INT16 int16_t; 33 | typedef INT32 int32_t; 34 | typedef INT64 int64_t; 35 | 36 | //typedef SIZE_T size_t; 37 | #define _SSIZE_T_DEFINED 1 38 | typedef SSIZE_T ssize_t; 39 | 40 | #define usleep(x) Sleep((x)/1000) 41 | #endif 42 | -------------------------------------------------------------------------------- /include/win32/winusb/POPPACK.H: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (c) Microsoft Corporation. All rights reserved. 4 | 5 | Module Name: 6 | 7 | poppack.h 8 | 9 | Abstract: 10 | 11 | This file turns packing of structures off. (That is, it enables 12 | automatic alignment of structure fields.) An include file is needed 13 | because various compilers do this in different ways. 14 | 15 | poppack.h is the complement to pshpack?.h. An inclusion of poppack.h 16 | MUST ALWAYS be preceded by an inclusion of one of pshpack?.h, in one-to-one 17 | correspondence. 18 | 19 | For Microsoft compatible compilers, this file uses the pop option 20 | to the pack pragma so that it can restore the previous saved by the 21 | pshpack?.h include file. 22 | 23 | --*/ 24 | 25 | #if ! (defined(lint) || defined(RC_INVOKED)) 26 | #if ( _MSC_VER >= 800 && !defined(_M_I86)) || defined(_PUSHPOP_SUPPORTED) 27 | #pragma warning(disable:4103) 28 | #if !(defined( MIDL_PASS )) || defined( __midl ) 29 | #pragma pack(pop) 30 | #else 31 | #pragma pack() 32 | #endif 33 | #else 34 | #pragma pack() 35 | #endif 36 | #endif /* ! (defined(lint) || defined(RC_INVOKED)) */ 37 | 38 | -------------------------------------------------------------------------------- /include/win32/winusb/PSHPACK1.H: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (c) Microsoft Corporation. All rights reserved. 4 | 5 | Module Name: 6 | 7 | pshpack1.h 8 | 9 | Abstract: 10 | 11 | This file turns 1 byte packing of structures on. (That is, it disables 12 | automatic alignment of structure fields.) An include file is needed 13 | because various compilers do this in different ways. For Microsoft 14 | compatible compilers, this files uses the push option to the pack pragma 15 | so that the poppack.h include file can restore the previous packing 16 | reliably. 17 | 18 | The file poppack.h is the complement to this file. 19 | 20 | --*/ 21 | 22 | #if ! (defined(lint) || defined(RC_INVOKED)) 23 | #if ( _MSC_VER >= 800 && !defined(_M_I86)) || defined(_PUSHPOP_SUPPORTED) 24 | #pragma warning(disable:4103) 25 | #if !(defined( MIDL_PASS )) || defined( __midl ) 26 | #pragma pack(push,1) 27 | #else 28 | #pragma pack(1) 29 | #endif 30 | #else 31 | #pragma pack(1) 32 | #endif 33 | #endif /* ! (defined(lint) || defined(RC_INVOKED)) */ 34 | 35 | -------------------------------------------------------------------------------- /include/win32/winusb/usb.h: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (c) Microsoft Corporation. All rights reserved. 4 | 5 | Module Name: 6 | 7 | USB.H 8 | 9 | Abstract: 10 | 11 | structures and APIs for USB drivers. 12 | 13 | Environment: 14 | 15 | Kernel & user mode 16 | 17 | Revision History: 18 | 19 | 09-29-95 : created 20 | 02-10-04 : Updated to include header versioning 21 | 22 | --*/ 23 | 24 | #ifndef __USB_H__ 25 | #define __USB_H__ 26 | 27 | 28 | 29 | /* 30 | This file is equivalent to USBDI.H with extensions supported by 31 | usbport.sys for eUSB. 32 | 33 | This file replaces usbdi.h and is compatible with older versions 34 | of the USB stack. 35 | */ 36 | 37 | #ifdef OSR21_COMPAT 38 | #pragma message("WARNING: OSR21_COMPAT SWITCH NOT SUPPORTED") 39 | #endif 40 | 41 | #ifndef _NTDDK_ 42 | #ifndef _WDMDDK_ 43 | typedef PVOID PIRP; 44 | typedef PVOID PMDL; 45 | #endif 46 | #endif 47 | 48 | #define USBDI_VERSION 0x00000600 49 | 50 | #include "usb200.h" 51 | #ifdef _WDMDDK_ 52 | #endif 53 | 54 | /* 55 | Microsoft Extended Port Attribute Flags 56 | */ 57 | #if _MSC_VER >= 1200 58 | #pragma warning(push) 59 | #endif 60 | #pragma warning(disable:4201) // named type definition in parentheses 61 | #pragma warning(disable:4214) // named type definition in parentheses 62 | 63 | #define USB_PORTATTR_NO_CONNECTOR 0x00000001 64 | #define USB_PORTATTR_SHARED_USB2 0x00000002 65 | #define USB_PORTATTR_MINI_CONNECTOR 0x00000004 66 | #define USB_PORTATTR_OEM_CONNECTOR 0x00000008 67 | 68 | /* dynamic attributes */ 69 | #define USB_PORTATTR_OWNED_BY_CC 0x01000000 70 | #define USB_PORTATTR_NO_OVERCURRENT_UI 0x02000000 71 | 72 | 73 | /* define USB controller flavors: 74 | These are all known HW implementations that require special 75 | hacks. 76 | */ 77 | 78 | typedef enum _USB_CONTROLLER_FLAVOR { 79 | 80 | USB_HcGeneric = 0, 81 | 82 | OHCI_Generic = 100, 83 | OHCI_Hydra, 84 | OHCI_NEC, 85 | 86 | UHCI_Generic = 200, 87 | UHCI_Piix4 = 201, 88 | UHCI_Piix3 = 202, 89 | UHCI_Ich2 = 203, 90 | UHCI_Reserved204 = 204, // was ich2_2 91 | UHCI_Ich1 = 205, 92 | UHCI_Ich3m = 206, 93 | UHCI_Ich4 = 207, 94 | UHCI_Ich5 = 208, 95 | UHCI_Ich6 = 209, 96 | 97 | UHCI_Intel = 249, 98 | 99 | //these VIA revs require special handling in the uhci miniport 100 | UHCI_VIA = 250, 101 | UHCI_VIA_x01 = 251, 102 | UHCI_VIA_x02 = 252, 103 | UHCI_VIA_x03 = 253, 104 | UHCI_VIA_x04 = 254, 105 | 106 | UHCI_VIA_x0E_FIFO = 264, 107 | 108 | EHCI_Generic = 1000, 109 | EHCI_NEC = 2000, 110 | EHCI_Lucent = 3000 111 | 112 | } USB_CONTROLLER_FLAVOR; 113 | 114 | 115 | // 116 | // USB defined structures and constants 117 | // (see chapter 9 of USB specification) 118 | // 119 | 120 | #define USB_DEFAULT_DEVICE_ADDRESS 0 121 | #define USB_DEFAULT_ENDPOINT_ADDRESS 0 122 | 123 | // 124 | // max packet size (bytes) for default endpoint 125 | // until SET_ADDRESS command is received. 126 | // 127 | 128 | #define USB_DEFAULT_MAX_PACKET 64 129 | 130 | // 131 | // USBD interface structures and constants 132 | // 133 | 134 | 135 | #define URB_FROM_IRP(Irp) ((IoGetCurrentIrpStackLocation(Irp))->Parameters.Others.Argument1) 136 | 137 | // 138 | // URB request codes 139 | // 140 | 141 | #define URB_FUNCTION_SELECT_CONFIGURATION 0x0000 142 | #define URB_FUNCTION_SELECT_INTERFACE 0x0001 143 | #define URB_FUNCTION_ABORT_PIPE 0x0002 144 | #define URB_FUNCTION_TAKE_FRAME_LENGTH_CONTROL 0x0003 145 | #define URB_FUNCTION_RELEASE_FRAME_LENGTH_CONTROL 0x0004 146 | #define URB_FUNCTION_GET_FRAME_LENGTH 0x0005 147 | #define URB_FUNCTION_SET_FRAME_LENGTH 0x0006 148 | #define URB_FUNCTION_GET_CURRENT_FRAME_NUMBER 0x0007 149 | #define URB_FUNCTION_CONTROL_TRANSFER 0x0008 150 | #define URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER 0x0009 151 | #define URB_FUNCTION_ISOCH_TRANSFER 0x000A 152 | #define URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE 0x000B 153 | #define URB_FUNCTION_SET_DESCRIPTOR_TO_DEVICE 0x000C 154 | #define URB_FUNCTION_SET_FEATURE_TO_DEVICE 0x000D 155 | #define URB_FUNCTION_SET_FEATURE_TO_INTERFACE 0x000E 156 | #define URB_FUNCTION_SET_FEATURE_TO_ENDPOINT 0x000F 157 | #define URB_FUNCTION_CLEAR_FEATURE_TO_DEVICE 0x0010 158 | #define URB_FUNCTION_CLEAR_FEATURE_TO_INTERFACE 0x0011 159 | #define URB_FUNCTION_CLEAR_FEATURE_TO_ENDPOINT 0x0012 160 | #define URB_FUNCTION_GET_STATUS_FROM_DEVICE 0x0013 161 | #define URB_FUNCTION_GET_STATUS_FROM_INTERFACE 0x0014 162 | #define URB_FUNCTION_GET_STATUS_FROM_ENDPOINT 0x0015 163 | #define URB_FUNCTION_RESERVED_0X0016 0x0016 164 | #define URB_FUNCTION_VENDOR_DEVICE 0x0017 165 | #define URB_FUNCTION_VENDOR_INTERFACE 0x0018 166 | #define URB_FUNCTION_VENDOR_ENDPOINT 0x0019 167 | #define URB_FUNCTION_CLASS_DEVICE 0x001A 168 | #define URB_FUNCTION_CLASS_INTERFACE 0x001B 169 | #define URB_FUNCTION_CLASS_ENDPOINT 0x001C 170 | #define URB_FUNCTION_RESERVE_0X001D 0x001D 171 | // previously URB_FUNCTION_RESET_PIPE 172 | #define URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL 0x001E 173 | #define URB_FUNCTION_CLASS_OTHER 0x001F 174 | #define URB_FUNCTION_VENDOR_OTHER 0x0020 175 | #define URB_FUNCTION_GET_STATUS_FROM_OTHER 0x0021 176 | #define URB_FUNCTION_CLEAR_FEATURE_TO_OTHER 0x0022 177 | #define URB_FUNCTION_SET_FEATURE_TO_OTHER 0x0023 178 | #define URB_FUNCTION_GET_DESCRIPTOR_FROM_ENDPOINT 0x0024 179 | #define URB_FUNCTION_SET_DESCRIPTOR_TO_ENDPOINT 0x0025 180 | #define URB_FUNCTION_GET_CONFIGURATION 0x0026 181 | #define URB_FUNCTION_GET_INTERFACE 0x0027 182 | #define URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE 0x0028 183 | #define URB_FUNCTION_SET_DESCRIPTOR_TO_INTERFACE 0x0029 184 | 185 | // USB 2.0 calls start at 0x0030 186 | 187 | #if (_WIN32_WINNT >= 0x0501) 188 | 189 | #define URB_FUNCTION_GET_MS_FEATURE_DESCRIPTOR 0x002A 190 | #define URB_FUNCTION_SYNC_RESET_PIPE 0x0030 191 | #define URB_FUNCTION_SYNC_CLEAR_STALL 0x0031 192 | 193 | #endif 194 | 195 | #if (_WIN32_WINNT >= 0x0600) 196 | 197 | #define URB_FUNCTION_CONTROL_TRANSFER_EX 0x0032 198 | #define URB_FUNCTION_RESERVE_0X0033 0x0033 199 | #define URB_FUNCTION_RESERVE_0X0034 0x0034 200 | 201 | #endif 202 | 203 | // Reserve 0x002B-0x002F 204 | #define URB_FUNCTION_RESERVE_0X002B 0x002B 205 | #define URB_FUNCTION_RESERVE_0X002C 0x002C 206 | #define URB_FUNCTION_RESERVE_0X002D 0x002D 207 | #define URB_FUNCTION_RESERVE_0X002E 0x002E 208 | #define URB_FUNCTION_RESERVE_0X002F 0x002F 209 | 210 | 211 | // for backward drivers 212 | #define URB_FUNCTION_RESET_PIPE \ 213 | URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL 214 | 215 | /* Control Pipe Function Groupings 216 | 217 | These functions correspond to the standard commands 218 | on the default pipe, direction is implied 219 | 220 | 221 | URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE 222 | URB_FUNCTION_GET_DESCRIPTOR_FROM_ENDPOINT 223 | URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE 224 | 225 | URB_FUNCTION_SET_DESCRIPTOR_TO_DEVICE 226 | URB_FUNCTION_SET_DESCRIPTOR_TO_ENDPOINT 227 | URB_FUNCTION_SET_DESCRIPTOR_TO_INTERFACE 228 | 229 | URB_FUNCTION_SET_FEATURE_TO_DEVICE 230 | URB_FUNCTION_SET_FEATURE_TO_INTERFACE 231 | URB_FUNCTION_SET_FEATURE_TO_ENDPOINT 232 | URB_FUNCTION_SET_FEATURE_TO_OTHER 233 | 234 | URB_FUNCTION_CLEAR_FEATURE_TO_DEVICE 235 | URB_FUNCTION_CLEAR_FEATURE_TO_INTERFACE 236 | URB_FUNCTION_CLEAR_FEATURE_TO_ENDPOINT 237 | URB_FUNCTION_CLEAR_FEATURE_TO_OTHER 238 | 239 | URB_FUNCTION_GET_STATUS_FROM_DEVICE 240 | URB_FUNCTION_GET_STATUS_FROM_INTERFACE 241 | URB_FUNCTION_GET_STATUS_FROM_ENDPOINT 242 | URB_FUNCTION_GET_STATUS_FROM_OTHER 243 | 244 | URB_FUNCTION_VENDOR_DEVICE 245 | URB_FUNCTION_VENDOR_INTERFACE 246 | URB_FUNCTION_VENDOR_ENDPOINT 247 | URB_FUNCTION_VENDOR_OTHER 248 | 249 | URB_FUNCTION_CLASS_DEVICE 250 | URB_FUNCTION_CLASS_INTERFACE 251 | URB_FUNCTION_CLASS_ENDPOINT 252 | URB_FUNCTION_CLASS_OTHER 253 | 254 | */ 255 | 256 | // 257 | // Values for URB TransferFlags Field 258 | // 259 | 260 | /* 261 | Set if data moves device->host 262 | */ 263 | #define USBD_TRANSFER_DIRECTION 0x00000001 264 | /* 265 | This bit if not set indicates that a short packet, and hence, 266 | a short transfer is an error condition 267 | */ 268 | #define USBD_SHORT_TRANSFER_OK 0x00000002 269 | /* 270 | Subit the iso transfer on the next frame 271 | */ 272 | #define USBD_START_ISO_TRANSFER_ASAP 0x00000004 273 | #define USBD_DEFAULT_PIPE_TRANSFER 0x00000008 274 | 275 | 276 | #define USBD_TRANSFER_DIRECTION_FLAG(flags) ((flags) & USBD_TRANSFER_DIRECTION) 277 | 278 | #define USBD_TRANSFER_DIRECTION_OUT 0 279 | #define USBD_TRANSFER_DIRECTION_IN 1 280 | 281 | #define VALID_TRANSFER_FLAGS_MASK (USBD_SHORT_TRANSFER_OK | \ 282 | USBD_TRANSFER_DIRECTION | \ 283 | USBD_START_ISO_TRANSFER_ASAP | \ 284 | USBD_DEFAULT_PIPE_TRANSFER) 285 | 286 | #define USBD_ISO_START_FRAME_RANGE 1024 287 | 288 | typedef LONG USBD_STATUS; 289 | 290 | // 291 | // USBD status codes 292 | // 293 | // Status values are 32 bit values layed out as follows: 294 | // 295 | // 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 296 | // 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 297 | // +---+---------------------------+-------------------------------+ 298 | // | S | Status Code | 299 | // +---+---------------------------+-------------------------------+ 300 | // 301 | // where 302 | // 303 | // S - is the state code 304 | // 305 | // 00 - completed with success 306 | // 01 - request is pending 307 | // 11, 10 - completed with error 308 | // 309 | // 310 | // Code - is the status code 311 | // 312 | 313 | // 314 | // Generic test for success on any status value (non-negative numbers 315 | // indicate success). 316 | // 317 | 318 | #define USBD_SUCCESS(Status) ((USBD_STATUS)(Status) >= 0) 319 | 320 | // 321 | // Generic test for pending status value. 322 | // 323 | 324 | #define USBD_PENDING(Status) ((ULONG)(Status) >> 30 == 1) 325 | 326 | // 327 | // Generic test for error on any status value. 328 | // 329 | 330 | #define USBD_ERROR(Status) ((USBD_STATUS)(Status) < 0) 331 | 332 | // 333 | // Macro to check the status code only 334 | // 335 | // 336 | //define USBD_STATUS(Status) ((ULONG)(Status) & 0x0FFFFFFFL) 337 | 338 | // the high order bits (0xC) will always be set on an error 339 | 340 | #define USBD_STATUS_SUCCESS ((USBD_STATUS)0x00000000L) 341 | #define USBD_STATUS_PENDING ((USBD_STATUS)0x40000000L) 342 | // 343 | //#define USBD_STATUS_ERROR ((USBD_STATUS)0xC0000000L) 344 | 345 | 346 | // The following are defined for backward compatibility with the usb 1.0 stack 347 | 348 | 349 | // 350 | // HC (Hardware) status codes range 0x00000001 - 0x000000FF 351 | // 352 | 353 | #define USBD_STATUS_CRC ((USBD_STATUS)0xC0000001L) 354 | #define USBD_STATUS_BTSTUFF ((USBD_STATUS)0xC0000002L) 355 | #define USBD_STATUS_DATA_TOGGLE_MISMATCH ((USBD_STATUS)0xC0000003L) 356 | #define USBD_STATUS_STALL_PID ((USBD_STATUS)0xC0000004L) 357 | #define USBD_STATUS_DEV_NOT_RESPONDING ((USBD_STATUS)0xC0000005L) 358 | #define USBD_STATUS_PID_CHECK_FAILURE ((USBD_STATUS)0xC0000006L) 359 | #define USBD_STATUS_UNEXPECTED_PID ((USBD_STATUS)0xC0000007L) 360 | #define USBD_STATUS_DATA_OVERRUN ((USBD_STATUS)0xC0000008L) 361 | #define USBD_STATUS_DATA_UNDERRUN ((USBD_STATUS)0xC0000009L) 362 | #define USBD_STATUS_RESERVED1 ((USBD_STATUS)0xC000000AL) 363 | #define USBD_STATUS_RESERVED2 ((USBD_STATUS)0xC000000BL) 364 | #define USBD_STATUS_BUFFER_OVERRUN ((USBD_STATUS)0xC000000CL) 365 | #define USBD_STATUS_BUFFER_UNDERRUN ((USBD_STATUS)0xC000000DL) 366 | #define USBD_STATUS_NOT_ACCESSED ((USBD_STATUS)0xC000000FL) 367 | #define USBD_STATUS_FIFO ((USBD_STATUS)0xC0000010L) 368 | 369 | #define USBD_STATUS_XACT_ERROR ((USBD_STATUS)0xC0000011L) 370 | #define USBD_STATUS_BABBLE_DETECTED ((USBD_STATUS)0xC0000012L) 371 | #define USBD_STATUS_DATA_BUFFER_ERROR ((USBD_STATUS)0xC0000013L) 372 | 373 | // 374 | // returned by HCD if a transfer is submitted to an endpoint that is 375 | // stalled 376 | // 377 | #define USBD_STATUS_ENDPOINT_HALTED ((USBD_STATUS)0xC0000030L) 378 | 379 | // 380 | // Software status codes 381 | // 382 | #define USBD_STATUS_INVALID_URB_FUNCTION ((USBD_STATUS)0x80000200L) 383 | #define USBD_STATUS_INVALID_PARAMETER ((USBD_STATUS)0x80000300L) 384 | 385 | // 386 | // returned if client driver attempts to close an endpoint/interface 387 | // or configuration with outstanding transfers. 388 | // 389 | #define USBD_STATUS_ERROR_BUSY ((USBD_STATUS)0x80000400L) 390 | // 391 | // returned by USBD if it cannot complete a URB request, typically this 392 | // will be returned in the URB status field when the Irp is completed 393 | // with a more specific NT error code in the irp.status field. 394 | // 395 | //#define USBD_STATUS_REQUEST_FAILED ((USBD_STATUS)0x80000500L) 396 | 397 | #define USBD_STATUS_INVALID_PIPE_HANDLE ((USBD_STATUS)0x80000600L) 398 | 399 | // returned when there is not enough bandwidth avialable 400 | // to open a requested endpoint 401 | #define USBD_STATUS_NO_BANDWIDTH ((USBD_STATUS)0x80000700L) 402 | // 403 | // generic HC error 404 | // 405 | #define USBD_STATUS_INTERNAL_HC_ERROR ((USBD_STATUS)0x80000800L) 406 | // 407 | // returned when a short packet terminates the transfer 408 | // ie USBD_SHORT_TRANSFER_OK bit not set 409 | // 410 | #define USBD_STATUS_ERROR_SHORT_TRANSFER ((USBD_STATUS)0x80000900L) 411 | // 412 | // returned if the requested start frame is not within 413 | // USBD_ISO_START_FRAME_RANGE of the current USB frame, 414 | // note that the stall bit is set 415 | // 416 | #define USBD_STATUS_BAD_START_FRAME ((USBD_STATUS)0xC0000A00L) 417 | // 418 | // returned by HCD if all packets in an iso transfer complete with an error 419 | // 420 | #define USBD_STATUS_ISOCH_REQUEST_FAILED ((USBD_STATUS)0xC0000B00L) 421 | // 422 | // returned by USBD if the frame length control for a given 423 | // HC is already taken by anothe driver 424 | // 425 | #define USBD_STATUS_FRAME_CONTROL_OWNED ((USBD_STATUS)0xC0000C00L) 426 | // 427 | // returned by USBD if the caller does not own frame length control and 428 | // attempts to release or modify the HC frame length 429 | // 430 | #define USBD_STATUS_FRAME_CONTROL_NOT_OWNED ((USBD_STATUS)0xC0000D00L) 431 | 432 | // 433 | // additonal software error codes added for usb 2.0 434 | // 435 | 436 | // 437 | // returned for APIS not supported/implemented 438 | // 439 | #define USBD_STATUS_NOT_SUPPORTED ((USBD_STATUS)0xC0000E00L) 440 | 441 | #define USBD_STATUS_INAVLID_CONFIGURATION_DESCRIPTOR \ 442 | ((USBD_STATUS)0xC0000F00L) 443 | 444 | #define USBD_STATUS_INVALID_CONFIGURATION_DESCRIPTOR \ 445 | ((USBD_STATUS)0xC0000F00L) 446 | 447 | #define USBD_STATUS_INSUFFICIENT_RESOURCES ((USBD_STATUS)0xC0001000L) 448 | 449 | #define USBD_STATUS_SET_CONFIG_FAILED ((USBD_STATUS)0xC0002000L) 450 | 451 | #define USBD_STATUS_BUFFER_TOO_SMALL ((USBD_STATUS)0xC0003000L) 452 | 453 | #define USBD_STATUS_INTERFACE_NOT_FOUND ((USBD_STATUS)0xC0004000L) 454 | 455 | #define USBD_STATUS_INAVLID_PIPE_FLAGS ((USBD_STATUS)0xC0005000L) 456 | 457 | #define USBD_STATUS_TIMEOUT ((USBD_STATUS)0xC0006000L) 458 | 459 | #define USBD_STATUS_DEVICE_GONE ((USBD_STATUS)0xC0007000L) 460 | 461 | #define USBD_STATUS_STATUS_NOT_MAPPED ((USBD_STATUS)0xC0008000L) 462 | 463 | // returned when urb is intercepted or handled by the hub driver 464 | #define USBD_STATUS_HUB_INTERNAL_ERROR ((USBD_STATUS)0xC0009000L) 465 | 466 | 467 | // 468 | // set when a transfers is completed due to an AbortPipe request from 469 | // the client driver 470 | // 471 | // 472 | #define USBD_STATUS_CANCELED ((USBD_STATUS)0xC0010000L) 473 | 474 | // 475 | // extended isochronous error codes, these errors appear in the 476 | // packet status field of an isochronous transfer 477 | // 478 | 479 | 480 | // for some reason the controller did not access the TD asocated with this 481 | // packet 482 | #define USBD_STATUS_ISO_NOT_ACCESSED_BY_HW ((USBD_STATUS)0xC0020000L) 483 | // controller reported an error in the TD 484 | // since TD errors are controoler specific they are reorted 485 | // generically with this error code 486 | #define USBD_STATUS_ISO_TD_ERROR ((USBD_STATUS)0xC0030000L) 487 | // the packet was submitted in time by the client but 488 | // failed to reach the miniport in time 489 | #define USBD_STATUS_ISO_NA_LATE_USBPORT ((USBD_STATUS)0xC0040000L) 490 | // the packet was not sent because the client submitted it too late 491 | // to transmit 492 | #define USBD_STATUS_ISO_NOT_ACCESSED_LATE ((USBD_STATUS)0xC0050000L) 493 | 494 | // new parameter validation status codes 495 | #define USBD_STATUS_BAD_DESCRIPTOR ((USBD_STATUS)0xC0100000L) 496 | #define USBD_STATUS_BAD_DESCRIPTOR_BLEN ((USBD_STATUS)0xC0100001L) 497 | #define USBD_STATUS_BAD_DESCRIPTOR_TYPE ((USBD_STATUS)0xC0100002L) 498 | #define USBD_STATUS_BAD_INTERFACE_DESCRIPTOR ((USBD_STATUS)0xC0100003L) 499 | #define USBD_STATUS_BAD_ENDPOINT_DESCRIPTOR ((USBD_STATUS)0xC0100004L) 500 | #define USBD_STATUS_BAD_INTERFACE_ASSOC_DESCRIPTOR ((USBD_STATUS)0xC0100005L) 501 | #define USBD_STATUS_BAD_CONFIG_DESC_LENGTH ((USBD_STATUS)0xC0100006L) 502 | #define USBD_STATUS_BAD_NUMBER_OF_INTERFACES ((USBD_STATUS)0xC0100007L) 503 | #define USBD_STATUS_BAD_NUMBER_OF_ENDPOINTS ((USBD_STATUS)0xC0100008L) 504 | #define USBD_STATUS_BAD_ENDPOINT_ADDRESS ((USBD_STATUS)0xC0100009L) 505 | 506 | 507 | 508 | typedef PVOID USBD_PIPE_HANDLE; 509 | typedef PVOID USBD_CONFIGURATION_HANDLE; 510 | typedef PVOID USBD_INTERFACE_HANDLE; 511 | 512 | // 513 | // Value used to indicate the default max transfer size 514 | // 515 | 516 | /* 517 | MAX TRANSFER SIZE 518 | 519 | Specified during select_configuration or 520 | selec_interface. This is the largest 521 | transfer a client driver will do to an 522 | endpoint. 523 | 524 | This value may be from 0x00000001 to 525 | 0xFFFFFFFF (1 to 4GB) 526 | 527 | */ 528 | // 529 | 530 | #if (_WIN32_WINNT >= 0x0501) 531 | 532 | // 533 | // For windows XP and later 534 | // 535 | 536 | #define USBD_DEFAULT_MAXIMUM_TRANSFER_SIZE 0xFFFFFFFF 537 | 538 | #else 539 | 540 | // 541 | // For Windows 2000 542 | // 543 | 544 | #define USBD_DEFAULT_MAXIMUM_TRANSFER_SIZE PAGE_SIZE 545 | 546 | #endif 547 | 548 | // 549 | // structure returned from USBD_GetVersion function 550 | // 551 | 552 | typedef struct _USBD_VERSION_INFORMATION { 553 | ULONG USBDI_Version; //BCD usb interface version number 554 | ULONG Supported_USB_Version; //BCD USB spec version number 555 | } USBD_VERSION_INFORMATION, *PUSBD_VERSION_INFORMATION; 556 | 557 | typedef enum _USBD_PIPE_TYPE { 558 | UsbdPipeTypeControl, 559 | UsbdPipeTypeIsochronous, 560 | UsbdPipeTypeBulk, 561 | UsbdPipeTypeInterrupt 562 | } USBD_PIPE_TYPE; 563 | 564 | #define USBD_PIPE_DIRECTION_IN(pipeInformation) ((pipeInformation)->EndpointAddress & \ 565 | USB_ENDPOINT_DIRECTION_MASK) 566 | 567 | typedef struct _USBD_DEVICE_INFORMATION { 568 | ULONG OffsetNext; 569 | PVOID UsbdDeviceHandle; 570 | USB_DEVICE_DESCRIPTOR DeviceDescriptor; 571 | } USBD_DEVICE_INFORMATION, *PUSBD_DEVICE_INFORMATION; 572 | 573 | // 574 | // URB request structures 575 | // 576 | 577 | // 578 | // USBD pipe information structure, this structure 579 | // is returned for each pipe opened thru an 580 | // SELECT_CONFIGURATION or SELECT_INTERFACE request. 581 | // 582 | 583 | typedef struct _USBD_PIPE_INFORMATION { 584 | // 585 | // OUTPUT 586 | // These fields are filled in by USBD 587 | // 588 | USHORT MaximumPacketSize; // Maximum packet size for this pipe 589 | UCHAR EndpointAddress; // 8 bit USB endpoint address (includes direction) 590 | // taken from endpoint descriptor 591 | UCHAR Interval; // Polling interval in ms if interrupt pipe 592 | 593 | USBD_PIPE_TYPE PipeType; // PipeType identifies type of transfer valid for this pipe 594 | USBD_PIPE_HANDLE PipeHandle; 595 | 596 | // 597 | // INPUT 598 | // These fields are filled in by the client driver 599 | // 600 | ULONG MaximumTransferSize; // Maximum size for a single request 601 | // in bytes. 602 | ULONG PipeFlags; 603 | } USBD_PIPE_INFORMATION, *PUSBD_PIPE_INFORMATION; 604 | 605 | // 606 | // values for PipeFlags field in USBD_PIPE_INFORMATION field 607 | // 608 | 609 | // override the enpoint max_packet size 610 | // with the value in pipe_information 611 | // field 612 | #define USBD_PF_CHANGE_MAX_PACKET 0x00000001 613 | // optimize for short packets 614 | // 'bulk optimization #1' 615 | #define USBD_PF_SHORT_PACKET_OPT 0x00000002 616 | // optimize transfers for use 617 | // with 'real time threads 618 | #define USBD_PF_ENABLE_RT_THREAD_ACCESS 0x00000004 619 | // causes the driver to allocate map 620 | // map more transfers in the queue. 621 | #define USBD_PF_MAP_ADD_TRANSFERS 0x00000008 622 | 623 | #define USBD_PF_VALID_MASK (USBD_PF_CHANGE_MAX_PACKET | \ 624 | USBD_PF_SHORT_PACKET_OPT | \ 625 | USBD_PF_ENABLE_RT_THREAD_ACCESS | \ 626 | USBD_PF_MAP_ADD_TRANSFERS) 627 | 628 | 629 | // 630 | // USBD interface information structure, this structure 631 | // is returned for each interface opened thru an 632 | // SELECT_CONFIGURATION or SELECT_INTERFACE request. 633 | // 634 | 635 | typedef struct _USBD_INTERFACE_INFORMATION { 636 | USHORT Length; // Length of this structure, including 637 | // all pipe information structures that 638 | // follow. 639 | // 640 | // INPUT 641 | // 642 | // Interface number and Alternate setting this 643 | // structure is associated with 644 | // 645 | UCHAR InterfaceNumber; 646 | UCHAR AlternateSetting; 647 | 648 | // 649 | // OUTPUT 650 | // These fields are filled in by USBD 651 | // 652 | UCHAR Class; 653 | UCHAR SubClass; 654 | UCHAR Protocol; 655 | UCHAR Reserved; 656 | 657 | USBD_INTERFACE_HANDLE InterfaceHandle; 658 | ULONG NumberOfPipes; 659 | 660 | // 661 | // INPUT/OUPUT 662 | // see PIPE_INFORMATION 663 | 664 | USBD_PIPE_INFORMATION Pipes[1]; 665 | } USBD_INTERFACE_INFORMATION, *PUSBD_INTERFACE_INFORMATION; 666 | 667 | // 668 | // work space provided for HCDs 669 | // 670 | 671 | struct _URB_HCD_AREA { 672 | PVOID Reserved8[8]; 673 | }; 674 | 675 | struct _URB_HEADER { 676 | // 677 | // Fields filled in by client driver 678 | // 679 | USHORT Length; 680 | USHORT Function; 681 | USBD_STATUS Status; 682 | // 683 | // Fields used only by USBD 684 | // 685 | PVOID UsbdDeviceHandle; // device handle assigned to this device 686 | // by USBD 687 | ULONG UsbdFlags; // flags field reserved for USBD use. 688 | }; 689 | 690 | struct _URB_SELECT_INTERFACE { 691 | struct _URB_HEADER Hdr; // function code indicates get or set. 692 | USBD_CONFIGURATION_HANDLE ConfigurationHandle; 693 | 694 | // client must input AlternateSetting & Interface Number 695 | // class driver returns interface and handle 696 | // for new alternate setting 697 | USBD_INTERFACE_INFORMATION Interface; 698 | }; 699 | 700 | struct _URB_SELECT_CONFIGURATION { 701 | struct _URB_HEADER Hdr; // function code indicates get or set. 702 | // NULL indicates to set the device 703 | // to the 'unconfigured' state 704 | // ie set to configuration 0 705 | PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor; 706 | USBD_CONFIGURATION_HANDLE ConfigurationHandle; 707 | USBD_INTERFACE_INFORMATION Interface; 708 | }; 709 | 710 | // 711 | // This structure used for ABORT_PIPE & RESET_PIPE 712 | // 713 | 714 | struct _URB_PIPE_REQUEST { 715 | struct _URB_HEADER Hdr; // function code indicates get or set. 716 | USBD_PIPE_HANDLE PipeHandle; 717 | ULONG Reserved; 718 | }; 719 | 720 | // 721 | // This structure used for 722 | // TAKE_FRAME_LENGTH_CONTROL & 723 | // RELEASE_FRAME_LENGTH_CONTROL 724 | // 725 | 726 | struct _URB_FRAME_LENGTH_CONTROL { 727 | struct _URB_HEADER Hdr; // function code indicates get or set. 728 | }; 729 | 730 | struct _URB_GET_FRAME_LENGTH { 731 | struct _URB_HEADER Hdr; // function code indicates get or set. 732 | ULONG FrameLength; 733 | ULONG FrameNumber; 734 | }; 735 | 736 | struct _URB_SET_FRAME_LENGTH { 737 | struct _URB_HEADER Hdr; // function code indicates get or set. 738 | LONG FrameLengthDelta; 739 | }; 740 | 741 | struct _URB_GET_CURRENT_FRAME_NUMBER { 742 | struct _URB_HEADER Hdr; // function code indicates get or set. 743 | ULONG FrameNumber; 744 | }; 745 | 746 | // 747 | // Structures for specific control transfers 748 | // on the default pipe. 749 | // 750 | 751 | // GET_DESCRIPTOR 752 | // SET_DESCRIPTOR 753 | 754 | struct _URB_CONTROL_DESCRIPTOR_REQUEST { 755 | struct _URB_HEADER Hdr; // function code indicates get or set. 756 | PVOID Reserved; 757 | ULONG Reserved0; 758 | ULONG TransferBufferLength; 759 | PVOID TransferBuffer; 760 | PMDL TransferBufferMDL; // *optional* 761 | struct _URB *UrbLink; // *reserved MBZ* 762 | struct _URB_HCD_AREA hca; // fields for HCD use 763 | USHORT Reserved1; 764 | UCHAR Index; 765 | UCHAR DescriptorType; 766 | USHORT LanguageId; 767 | USHORT Reserved2; 768 | }; 769 | 770 | // GET_STATUS 771 | 772 | struct _URB_CONTROL_GET_STATUS_REQUEST { 773 | struct _URB_HEADER Hdr; // function code indicates get or set. 774 | PVOID Reserved; 775 | ULONG Reserved0; 776 | ULONG TransferBufferLength; 777 | PVOID TransferBuffer; 778 | PMDL TransferBufferMDL; // *optional* 779 | struct _URB *UrbLink; // *reserved MBZ* 780 | struct _URB_HCD_AREA hca; // fields for HCD use 781 | UCHAR Reserved1[4]; 782 | USHORT Index; // zero, interface or endpoint 783 | USHORT Reserved2; 784 | }; 785 | 786 | // SET_FEATURE 787 | // CLEAR_FEATURE 788 | 789 | struct _URB_CONTROL_FEATURE_REQUEST { 790 | struct _URB_HEADER Hdr; // function code indicates get or set. 791 | PVOID Reserved; 792 | ULONG Reserved2; 793 | ULONG Reserved3; 794 | PVOID Reserved4; 795 | PMDL Reserved5; 796 | struct _URB *UrbLink; // *reserved MBZ* 797 | struct _URB_HCD_AREA hca; // fields for HCD use 798 | USHORT Reserved0; 799 | USHORT FeatureSelector; 800 | USHORT Index; // zero, interface or endpoint 801 | USHORT Reserved1; 802 | }; 803 | 804 | // VENDOR & CLASS 805 | 806 | struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST { 807 | struct _URB_HEADER Hdr; // function code indicates get or set. 808 | PVOID Reserved; 809 | ULONG TransferFlags; 810 | ULONG TransferBufferLength; 811 | PVOID TransferBuffer; 812 | PMDL TransferBufferMDL; // *optional* 813 | struct _URB *UrbLink; // *reserved MBZ* 814 | struct _URB_HCD_AREA hca; // fields for HCD use 815 | UCHAR RequestTypeReservedBits; 816 | UCHAR Request; 817 | USHORT Value; 818 | USHORT Index; 819 | USHORT Reserved1; 820 | }; 821 | 822 | 823 | struct _URB_CONTROL_GET_INTERFACE_REQUEST { 824 | struct _URB_HEADER Hdr; // function code indicates get or set. 825 | PVOID Reserved; 826 | ULONG Reserved0; 827 | ULONG TransferBufferLength; 828 | PVOID TransferBuffer; 829 | PMDL TransferBufferMDL; // *optional* 830 | struct _URB *UrbLink; // *reserved MBZ* 831 | struct _URB_HCD_AREA hca; // fields for HCD use 832 | UCHAR Reserved1[4]; 833 | USHORT Interface; 834 | USHORT Reserved2; 835 | }; 836 | 837 | 838 | struct _URB_CONTROL_GET_CONFIGURATION_REQUEST { 839 | struct _URB_HEADER Hdr; // function code indicates get or set. 840 | PVOID Reserved; 841 | ULONG Reserved0; 842 | ULONG TransferBufferLength; 843 | PVOID TransferBuffer; 844 | PMDL TransferBufferMDL; // *optional* 845 | struct _URB *UrbLink; // *resrved MBZ* 846 | struct _URB_HCD_AREA hca; // fields for HCD use 847 | UCHAR Reserved1[8]; 848 | }; 849 | 850 | #if (_WIN32_WINNT >= 0x0501) 851 | 852 | // Microsoft OS Descriptor APIs 853 | // supported in windows XP and later 854 | 855 | #define OS_STRING_DESCRIPTOR_INDEX 0xEE 856 | 857 | #define MS_GENRE_DESCRIPTOR_INDEX 0x0001 858 | #define MS_POWER_DESCRIPTOR_INDEX 0x0002 859 | 860 | #define MS_OS_STRING_SIGNATURE L"MSFT100" 861 | 862 | #define MS_OS_FLAGS_CONTAINERID 0x02 863 | 864 | typedef struct _OS_STRING { 865 | UCHAR bLength; 866 | UCHAR bDescriptorType; 867 | WCHAR MicrosoftString[7]; 868 | UCHAR bVendorCode; 869 | union { 870 | UCHAR bPad; 871 | UCHAR bFlags; 872 | }; 873 | } OS_STRING, *POS_STRING; 874 | 875 | struct _URB_OS_FEATURE_DESCRIPTOR_REQUEST { 876 | struct _URB_HEADER Hdr; // function code indicates get or set. 877 | PVOID Reserved; 878 | ULONG Reserved0; 879 | ULONG TransferBufferLength; 880 | PVOID TransferBuffer; 881 | PMDL TransferBufferMDL; // *optional* 882 | struct _URB *UrbLink; // *optional* link to next urb request 883 | // if this is a chain of commands 884 | struct _URB_HCD_AREA hca; // fields for HCD use 885 | UCHAR Recipient:5; // Recipient {Device,Interface,Endpoint} 886 | UCHAR Reserved1:3; 887 | UCHAR Reserved2; 888 | UCHAR InterfaceNumber; // wValue - high byte 889 | UCHAR MS_PageIndex; // wValue - low byte 890 | USHORT MS_FeatureDescriptorIndex; // wIndex field 891 | USHORT Reserved3; 892 | }; 893 | 894 | #endif 895 | 896 | // 897 | // request format for a control transfer on 898 | // the non-default pipe. 899 | // 900 | 901 | struct _URB_CONTROL_TRANSFER { 902 | struct _URB_HEADER Hdr; // function code indicates get or set. 903 | USBD_PIPE_HANDLE PipeHandle; 904 | ULONG TransferFlags; 905 | ULONG TransferBufferLength; 906 | PVOID TransferBuffer; 907 | PMDL TransferBufferMDL; // *optional* 908 | struct _URB *UrbLink; // *reserved MBZ* 909 | struct _URB_HCD_AREA hca; // fields for HCD use 910 | UCHAR SetupPacket[8]; 911 | }; 912 | 913 | #if (_WIN32_WINNT >= 0x0600) 914 | 915 | // 916 | // Suported for Windows Longhorn and later 917 | // 918 | 919 | struct _URB_CONTROL_TRANSFER_EX { 920 | struct _URB_HEADER Hdr; 921 | USBD_PIPE_HANDLE PipeHandle; 922 | ULONG TransferFlags; 923 | ULONG TransferBufferLength; 924 | PVOID TransferBuffer; 925 | PMDL TransferBufferMDL; // *optional* 926 | ULONG Timeout; // *optional* timeout in milliseconds 927 | // for this request, 0 = no timeout 928 | #ifdef WIN64 929 | ULONG Pad; 930 | #endif 931 | struct _URB_HCD_AREA hca; // fields for HCD use 932 | UCHAR SetupPacket[8]; 933 | }; 934 | 935 | #endif 936 | 937 | struct _URB_BULK_OR_INTERRUPT_TRANSFER { 938 | struct _URB_HEADER Hdr; // function code indicates get or set. 939 | USBD_PIPE_HANDLE PipeHandle; 940 | ULONG TransferFlags; // note: the direction bit will be set by USBD 941 | ULONG TransferBufferLength; 942 | PVOID TransferBuffer; 943 | PMDL TransferBufferMDL; // *optional* 944 | struct _URB *UrbLink; // *optional* link to next urb request 945 | // if this is a chain of commands 946 | struct _URB_HCD_AREA hca; // fields for HCD use 947 | }; 948 | 949 | 950 | // 951 | // ISO Transfer request 952 | // 953 | // TransferBufferMDL must point to a single virtually 954 | // contiguous buffer. 955 | // 956 | // StartFrame - the frame to send/receive the first packet of 957 | // the request. 958 | // 959 | // NumberOfPackets - number of packets to send in this request 960 | // 961 | // 962 | // IsoPacket Array 963 | // 964 | // Input: Offset - offset of the packet from the beginig 965 | // of the client buffer. 966 | // Output: Length - is set to the actual length of the packet 967 | // (For IN transfers). 968 | // Status: error that occurred during transmission or 969 | // reception of the packet. 970 | // 971 | 972 | typedef struct _USBD_ISO_PACKET_DESCRIPTOR { 973 | ULONG Offset; // INPUT Offset of the packet from the begining of the 974 | // buffer. 975 | 976 | ULONG Length; // OUTPUT length of data received (for in). 977 | // OUTPUT 0 for OUT. 978 | USBD_STATUS Status; // status code for this packet. 979 | } USBD_ISO_PACKET_DESCRIPTOR, *PUSBD_ISO_PACKET_DESCRIPTOR; 980 | 981 | struct _URB_ISOCH_TRANSFER { 982 | // 983 | // This block is the same as CommonTransfer 984 | // 985 | struct _URB_HEADER Hdr; // function code indicates get or set. 986 | USBD_PIPE_HANDLE PipeHandle; 987 | ULONG TransferFlags; 988 | ULONG TransferBufferLength; 989 | PVOID TransferBuffer; 990 | PMDL TransferBufferMDL; // *optional* 991 | struct _URB *UrbLink; // *optional* link to next urb request 992 | // if this is a chain of commands 993 | struct _URB_HCD_AREA hca; // fields for HCD use 994 | 995 | // 996 | // this block contains transfer fields 997 | // specific to isochronous transfers 998 | // 999 | 1000 | // 32 bit frame number to begin this transfer on, must be within 1000 1001 | // frames of the current USB frame or an error is returned. 1002 | 1003 | // START_ISO_TRANSFER_ASAP flag in transferFlags: 1004 | // If this flag is set and no transfers have been submitted 1005 | // for the pipe then the transfer will begin on the next frame 1006 | // and StartFrame will be updated with the frame number the transfer 1007 | // was started on. 1008 | // If this flag is set and the pipe has active transfers then 1009 | // the transfer will be queued to begin on the frame after the 1010 | // last transfer queued is completed. 1011 | // 1012 | ULONG StartFrame; 1013 | // number of packets that make up this request 1014 | ULONG NumberOfPackets; 1015 | // number of packets that completed with errors 1016 | ULONG ErrorCount; 1017 | USBD_ISO_PACKET_DESCRIPTOR IsoPacket[1]; 1018 | }; 1019 | 1020 | 1021 | typedef struct _URB { 1022 | union { 1023 | struct _URB_HEADER 1024 | UrbHeader; 1025 | struct _URB_SELECT_INTERFACE 1026 | UrbSelectInterface; 1027 | struct _URB_SELECT_CONFIGURATION 1028 | UrbSelectConfiguration; 1029 | struct _URB_PIPE_REQUEST 1030 | UrbPipeRequest; 1031 | struct _URB_FRAME_LENGTH_CONTROL 1032 | UrbFrameLengthControl; 1033 | struct _URB_GET_FRAME_LENGTH 1034 | UrbGetFrameLength; 1035 | struct _URB_SET_FRAME_LENGTH 1036 | UrbSetFrameLength; 1037 | struct _URB_GET_CURRENT_FRAME_NUMBER 1038 | UrbGetCurrentFrameNumber; 1039 | struct _URB_CONTROL_TRANSFER 1040 | UrbControlTransfer; 1041 | 1042 | #if (_WIN32_WINNT >= 0x0600) 1043 | 1044 | struct _URB_CONTROL_TRANSFER_EX 1045 | UrbControlTransferEx; 1046 | 1047 | #endif 1048 | 1049 | struct _URB_BULK_OR_INTERRUPT_TRANSFER 1050 | UrbBulkOrInterruptTransfer; 1051 | struct _URB_ISOCH_TRANSFER 1052 | UrbIsochronousTransfer; 1053 | 1054 | // for standard control transfers on the default pipe 1055 | struct _URB_CONTROL_DESCRIPTOR_REQUEST 1056 | UrbControlDescriptorRequest; 1057 | struct _URB_CONTROL_GET_STATUS_REQUEST 1058 | UrbControlGetStatusRequest; 1059 | struct _URB_CONTROL_FEATURE_REQUEST 1060 | UrbControlFeatureRequest; 1061 | struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST 1062 | UrbControlVendorClassRequest; 1063 | struct _URB_CONTROL_GET_INTERFACE_REQUEST 1064 | UrbControlGetInterfaceRequest; 1065 | struct _URB_CONTROL_GET_CONFIGURATION_REQUEST 1066 | UrbControlGetConfigurationRequest; 1067 | 1068 | #if (_WIN32_WINNT >= 0x0501) 1069 | 1070 | struct _URB_OS_FEATURE_DESCRIPTOR_REQUEST 1071 | UrbOSFeatureDescriptorRequest; 1072 | #endif 1073 | 1074 | }; 1075 | } URB, *PURB; 1076 | 1077 | #if _MSC_VER >= 1200 1078 | #pragma warning(pop) 1079 | #endif 1080 | 1081 | 1082 | #endif /* __USB_H__ */ 1083 | 1084 | -------------------------------------------------------------------------------- /include/win32/winusb/usb100.h: -------------------------------------------------------------------------------- 1 | #ifndef __USB100_H__ 2 | #define __USB100_H__ 3 | 4 | 5 | #include 6 | 7 | 8 | //bmRequest.Dir 9 | #define BMREQUEST_HOST_TO_DEVICE 0 10 | #define BMREQUEST_DEVICE_TO_HOST 1 11 | 12 | //bmRequest.Type 13 | #define BMREQUEST_STANDARD 0 14 | #define BMREQUEST_CLASS 1 15 | #define BMREQUEST_VENDOR 2 16 | 17 | //bmRequest.Recipient 18 | #define BMREQUEST_TO_DEVICE 0 19 | #define BMREQUEST_TO_INTERFACE 1 20 | #define BMREQUEST_TO_ENDPOINT 2 21 | #define BMREQUEST_TO_OTHER 3 22 | 23 | 24 | #define MAXIMUM_USB_STRING_LENGTH 255 25 | 26 | // values for the bits returned by the USB GET_STATUS command 27 | #define USB_GETSTATUS_SELF_POWERED 0x01 28 | #define USB_GETSTATUS_REMOTE_WAKEUP_ENABLED 0x02 29 | 30 | 31 | #define USB_DEVICE_DESCRIPTOR_TYPE 0x01 32 | #define USB_CONFIGURATION_DESCRIPTOR_TYPE 0x02 33 | #define USB_STRING_DESCRIPTOR_TYPE 0x03 34 | #define USB_INTERFACE_DESCRIPTOR_TYPE 0x04 35 | #define USB_ENDPOINT_DESCRIPTOR_TYPE 0x05 36 | 37 | // descriptor types defined by DWG documents 38 | #define USB_RESERVED_DESCRIPTOR_TYPE 0x06 39 | #define USB_CONFIG_POWER_DESCRIPTOR_TYPE 0x07 40 | #define USB_INTERFACE_POWER_DESCRIPTOR_TYPE 0x08 41 | 42 | #define USB_DESCRIPTOR_MAKE_TYPE_AND_INDEX(d, i) ((USHORT)((USHORT)d<<8 | i)) 43 | 44 | // 45 | // Values for bmAttributes field of an 46 | // endpoint descriptor 47 | // 48 | 49 | #define USB_ENDPOINT_TYPE_MASK 0x03 50 | 51 | #define USB_ENDPOINT_TYPE_CONTROL 0x00 52 | #define USB_ENDPOINT_TYPE_ISOCHRONOUS 0x01 53 | #define USB_ENDPOINT_TYPE_BULK 0x02 54 | #define USB_ENDPOINT_TYPE_INTERRUPT 0x03 55 | 56 | 57 | // 58 | // definitions for bits in the bmAttributes field of a 59 | // configuration descriptor. 60 | // 61 | #define USB_CONFIG_POWERED_MASK 0xc0 62 | 63 | #define USB_CONFIG_BUS_POWERED 0x80 64 | #define USB_CONFIG_SELF_POWERED 0x40 65 | #define USB_CONFIG_REMOTE_WAKEUP 0x20 66 | 67 | // 68 | // Endpoint direction bit, stored in address 69 | // 70 | 71 | #define USB_ENDPOINT_DIRECTION_MASK 0x80 72 | 73 | // test direction bit in the bEndpointAddress field of 74 | // an endpoint descriptor. 75 | #define USB_ENDPOINT_DIRECTION_OUT(addr) (!((addr) & USB_ENDPOINT_DIRECTION_MASK)) 76 | #define USB_ENDPOINT_DIRECTION_IN(addr) ((addr) & USB_ENDPOINT_DIRECTION_MASK) 77 | 78 | // 79 | // USB defined request codes 80 | // see chapter 9 of the USB 1.0 specifcation for 81 | // more information. 82 | // 83 | 84 | // These are the correct values based on the USB 1.0 85 | // specification 86 | 87 | #define USB_REQUEST_GET_STATUS 0x00 88 | #define USB_REQUEST_CLEAR_FEATURE 0x01 89 | 90 | #define USB_REQUEST_SET_FEATURE 0x03 91 | 92 | #define USB_REQUEST_SET_ADDRESS 0x05 93 | #define USB_REQUEST_GET_DESCRIPTOR 0x06 94 | #define USB_REQUEST_SET_DESCRIPTOR 0x07 95 | #define USB_REQUEST_GET_CONFIGURATION 0x08 96 | #define USB_REQUEST_SET_CONFIGURATION 0x09 97 | #define USB_REQUEST_GET_INTERFACE 0x0A 98 | #define USB_REQUEST_SET_INTERFACE 0x0B 99 | #define USB_REQUEST_SYNC_FRAME 0x0C 100 | 101 | 102 | // 103 | // defined USB device classes 104 | // 105 | 106 | 107 | #define USB_DEVICE_CLASS_RESERVED 0x00 108 | #define USB_DEVICE_CLASS_AUDIO 0x01 109 | #define USB_DEVICE_CLASS_COMMUNICATIONS 0x02 110 | #define USB_DEVICE_CLASS_HUMAN_INTERFACE 0x03 111 | #define USB_DEVICE_CLASS_MONITOR 0x04 112 | #define USB_DEVICE_CLASS_PHYSICAL_INTERFACE 0x05 113 | #define USB_DEVICE_CLASS_POWER 0x06 114 | #define USB_DEVICE_CLASS_PRINTER 0x07 115 | #define USB_DEVICE_CLASS_STORAGE 0x08 116 | #define USB_DEVICE_CLASS_HUB 0x09 117 | #define USB_DEVICE_CLASS_VENDOR_SPECIFIC 0xFF 118 | 119 | // 120 | // USB Core defined Feature selectors 121 | // 122 | 123 | #define USB_FEATURE_ENDPOINT_STALL 0x0000 124 | #define USB_FEATURE_REMOTE_WAKEUP 0x0001 125 | 126 | // 127 | // USB DWG defined Feature selectors 128 | // 129 | 130 | #define USB_FEATURE_INTERFACE_POWER_D0 0x0002 131 | #define USB_FEATURE_INTERFACE_POWER_D1 0x0003 132 | #define USB_FEATURE_INTERFACE_POWER_D2 0x0004 133 | #define USB_FEATURE_INTERFACE_POWER_D3 0x0005 134 | 135 | typedef struct _USB_DEVICE_DESCRIPTOR { 136 | UCHAR bLength; 137 | UCHAR bDescriptorType; 138 | USHORT bcdUSB; 139 | UCHAR bDeviceClass; 140 | UCHAR bDeviceSubClass; 141 | UCHAR bDeviceProtocol; 142 | UCHAR bMaxPacketSize0; 143 | USHORT idVendor; 144 | USHORT idProduct; 145 | USHORT bcdDevice; 146 | UCHAR iManufacturer; 147 | UCHAR iProduct; 148 | UCHAR iSerialNumber; 149 | UCHAR bNumConfigurations; 150 | } USB_DEVICE_DESCRIPTOR, *PUSB_DEVICE_DESCRIPTOR; 151 | 152 | typedef struct _USB_ENDPOINT_DESCRIPTOR { 153 | UCHAR bLength; 154 | UCHAR bDescriptorType; 155 | UCHAR bEndpointAddress; 156 | UCHAR bmAttributes; 157 | USHORT wMaxPacketSize; 158 | UCHAR bInterval; 159 | } USB_ENDPOINT_DESCRIPTOR, *PUSB_ENDPOINT_DESCRIPTOR; 160 | 161 | typedef struct _USB_CONFIGURATION_DESCRIPTOR { 162 | UCHAR bLength; 163 | UCHAR bDescriptorType; 164 | USHORT wTotalLength; 165 | UCHAR bNumInterfaces; 166 | UCHAR bConfigurationValue; 167 | UCHAR iConfiguration; 168 | UCHAR bmAttributes; 169 | UCHAR MaxPower; 170 | } USB_CONFIGURATION_DESCRIPTOR, *PUSB_CONFIGURATION_DESCRIPTOR; 171 | 172 | typedef struct _USB_INTERFACE_DESCRIPTOR { 173 | UCHAR bLength; 174 | UCHAR bDescriptorType; 175 | UCHAR bInterfaceNumber; 176 | UCHAR bAlternateSetting; 177 | UCHAR bNumEndpoints; 178 | UCHAR bInterfaceClass; 179 | UCHAR bInterfaceSubClass; 180 | UCHAR bInterfaceProtocol; 181 | UCHAR iInterface; 182 | } USB_INTERFACE_DESCRIPTOR, *PUSB_INTERFACE_DESCRIPTOR; 183 | 184 | typedef struct _USB_STRING_DESCRIPTOR { 185 | UCHAR bLength; 186 | UCHAR bDescriptorType; 187 | WCHAR bString[1]; 188 | } USB_STRING_DESCRIPTOR, *PUSB_STRING_DESCRIPTOR; 189 | 190 | typedef struct _USB_COMMON_DESCRIPTOR { 191 | UCHAR bLength; 192 | UCHAR bDescriptorType; 193 | } USB_COMMON_DESCRIPTOR, *PUSB_COMMON_DESCRIPTOR; 194 | 195 | 196 | // 197 | // Standard USB HUB definitions 198 | // 199 | // See Chapter 11 USB core specification 200 | // 201 | 202 | typedef struct _USB_HUB_DESCRIPTOR { 203 | UCHAR bDescriptorLength; // Length of this descriptor 204 | UCHAR bDescriptorType; // Hub configuration type 205 | UCHAR bNumberOfPorts; // number of ports on this hub 206 | USHORT wHubCharacteristics; // Hub Charateristics 207 | UCHAR bPowerOnToPowerGood; // port power on till power good in 2ms 208 | UCHAR bHubControlCurrent; // max current in mA 209 | // 210 | // room for 255 ports power control and removable bitmask 211 | UCHAR bRemoveAndPowerMask[64]; 212 | } USB_HUB_DESCRIPTOR, *PUSB_HUB_DESCRIPTOR; 213 | 214 | 215 | // 216 | // Structures defined by various DWG feature documents 217 | // 218 | 219 | 220 | // 221 | // See DWG USB Feature Specification: Interface Power Management 222 | // 223 | 224 | #define USB_SUPPORT_D0_COMMAND 0x01 225 | #define USB_SUPPORT_D1_COMMAND 0x02 226 | #define USB_SUPPORT_D2_COMMAND 0x04 227 | #define USB_SUPPORT_D3_COMMAND 0x08 228 | 229 | #define USB_SUPPORT_D1_WAKEUP 0x10 230 | #define USB_SUPPORT_D2_WAKEUP 0x20 231 | 232 | 233 | typedef struct _USB_CONFIGURATION_POWER_DESCRIPTOR { 234 | UCHAR bLength; 235 | UCHAR bDescriptorType; 236 | UCHAR SelfPowerConsumedD0[3]; 237 | UCHAR bPowerSummaryId; 238 | UCHAR bBusPowerSavingD1; 239 | UCHAR bSelfPowerSavingD1; 240 | UCHAR bBusPowerSavingD2; 241 | UCHAR bSelfPowerSavingD2; 242 | UCHAR bBusPowerSavingD3; 243 | UCHAR bSelfPowerSavingD3; 244 | USHORT TransitionTimeFromD1; 245 | USHORT TransitionTimeFromD2; 246 | USHORT TransitionTimeFromD3; 247 | } USB_CONFIGURATION_POWER_DESCRIPTOR, *PUSB_CONFIGURATION_POWER_DESCRIPTOR; 248 | 249 | 250 | typedef struct _USB_INTERFACE_POWER_DESCRIPTOR { 251 | UCHAR bLength; 252 | UCHAR bDescriptorType; 253 | UCHAR bmCapabilitiesFlags; 254 | UCHAR bBusPowerSavingD1; 255 | UCHAR bSelfPowerSavingD1; 256 | UCHAR bBusPowerSavingD2; 257 | UCHAR bSelfPowerSavingD2; 258 | UCHAR bBusPowerSavingD3; 259 | UCHAR bSelfPowerSavingD3; 260 | USHORT TransitionTimeFromD1; 261 | USHORT TransitionTimeFromD2; 262 | USHORT TransitionTimeFromD3; 263 | } USB_INTERFACE_POWER_DESCRIPTOR, *PUSB_INTERFACE_POWER_DESCRIPTOR; 264 | 265 | 266 | #include 267 | 268 | 269 | #endif /* __USB100_H__ */ 270 | 271 | -------------------------------------------------------------------------------- /include/win32/winusb/usb200.h: -------------------------------------------------------------------------------- 1 | #ifndef __USB200_H__ 2 | #define __USB200_H__ 3 | 4 | #include "usb100.h" 5 | 6 | 7 | #include 8 | 9 | 10 | #if _MSC_VER >= 1200 11 | #pragma warning(push) 12 | #endif 13 | #pragma warning (disable:4201) 14 | #pragma warning(disable:4214) // named type definition in parentheses 15 | 16 | typedef enum _USB_DEVICE_SPEED { 17 | UsbLowSpeed = 0, 18 | UsbFullSpeed, 19 | UsbHighSpeed 20 | } USB_DEVICE_SPEED; 21 | 22 | typedef enum _USB_DEVICE_TYPE { 23 | Usb11Device = 0, 24 | Usb20Device 25 | } USB_DEVICE_TYPE; 26 | 27 | 28 | // standard definitions for the port status 29 | // word of the HUB port register 30 | 31 | #define USB_PORT_STATUS_CONNECT 0x0001 32 | #define USB_PORT_STATUS_ENABLE 0x0002 33 | #define USB_PORT_STATUS_SUSPEND 0x0004 34 | #define USB_PORT_STATUS_OVER_CURRENT 0x0008 35 | #define USB_PORT_STATUS_RESET 0x0010 36 | #define USB_PORT_STATUS_POWER 0x0100 37 | #define USB_PORT_STATUS_LOW_SPEED 0x0200 38 | #define USB_PORT_STATUS_HIGH_SPEED 0x0400 39 | 40 | typedef union _BM_REQUEST_TYPE { 41 | struct _BM { 42 | UCHAR Recipient:2; 43 | UCHAR Reserved:3; 44 | UCHAR Type:2; 45 | UCHAR Dir:1; 46 | }; 47 | UCHAR B; 48 | } BM_REQUEST_TYPE, *PBM_REQUEST_TYPE; 49 | 50 | typedef struct _USB_DEFAULT_PIPE_SETUP_PACKET { 51 | BM_REQUEST_TYPE bmRequestType; 52 | UCHAR bRequest; 53 | 54 | union _wValue { 55 | struct { 56 | UCHAR LowByte; 57 | UCHAR HiByte; 58 | }; 59 | USHORT W; 60 | } wValue; 61 | 62 | union _wIndex { 63 | struct { 64 | UCHAR LowByte; 65 | UCHAR HiByte; 66 | }; 67 | USHORT W; 68 | } wIndex; 69 | USHORT wLength; 70 | } USB_DEFAULT_PIPE_SETUP_PACKET, *PUSB_DEFAULT_PIPE_SETUP_PACKET; 71 | 72 | // setup packet is eight bytes -- defined by spec 73 | C_ASSERT(sizeof(USB_DEFAULT_PIPE_SETUP_PACKET) == 8); 74 | 75 | 76 | #define USB_DEVICE_QUALIFIER_DESCRIPTOR_TYPE 0x06 77 | #define USB_OTHER_SPEED_CONFIGURATION_DESCRIPTOR_TYPE 0x07 78 | 79 | typedef struct _USB_DEVICE_QUALIFIER_DESCRIPTOR { 80 | UCHAR bLength; 81 | UCHAR bDescriptorType; 82 | USHORT bcdUSB; 83 | UCHAR bDeviceClass; 84 | UCHAR bDeviceSubClass; 85 | UCHAR bDeviceProtocol; 86 | UCHAR bMaxPacketSize0; 87 | UCHAR bNumConfigurations; 88 | UCHAR bReserved; 89 | } USB_DEVICE_QUALIFIER_DESCRIPTOR, *PUSB_DEVICE_QUALIFIER_DESCRIPTOR; 90 | 91 | 92 | typedef union _USB_HIGH_SPEED_MAXPACKET { 93 | struct _MP { 94 | USHORT MaxPacket:11; /* 0..10 */ 95 | USHORT HSmux:2; /* 11..12 */ 96 | USHORT Reserved:3; /* 13..15 */ 97 | }; 98 | USHORT us; 99 | } USB_HIGH_SPEED_MAXPACKET, *PUSB_HIGH_SPEED_MAXPACKET; 100 | 101 | #define USB_INTERFACE_ASSOCIATION_DESCRIPTOR_TYPE 0x0B 102 | 103 | typedef struct _USB_INTERFACE_ASSOCIATION_DESCRIPTOR { 104 | 105 | UCHAR bLength; 106 | UCHAR bDescriptorType; 107 | UCHAR bFirstInterface; 108 | UCHAR bInterfaceCount; 109 | UCHAR bFunctionClass; 110 | UCHAR bFunctionSubClass; 111 | UCHAR bFunctionProtocol; 112 | UCHAR iFunction; 113 | 114 | } USB_INTERFACE_ASSOCIATION_DESCRIPTOR, *PUSB_INTERFACE_ASSOCIATION_DESCRIPTOR; 115 | 116 | 117 | #if _MSC_VER >= 1200 118 | #pragma warning(pop) 119 | #endif 120 | 121 | 122 | 123 | #include 124 | 125 | #endif // __USB200_H__ 126 | 127 | -------------------------------------------------------------------------------- /include/win32/winusb/winusb.h: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (c) 2002 Microsoft Corporation 4 | 5 | Module Name: 6 | 7 | wusb.h 8 | 9 | Abstract: 10 | 11 | Public interface to winusb.dll 12 | 13 | Environment: 14 | 15 | Kernel Mode Only 16 | 17 | Notes: 18 | 19 | THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY 20 | KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR 22 | PURPOSE. 23 | 24 | Copyright (c) 2001 Microsoft Corporation. All Rights Reserved. 25 | 26 | 27 | Revision History: 28 | 29 | 11/19/2002 : created 30 | 31 | Authors: 32 | 33 | --*/ 34 | 35 | #ifndef __WUSB_H__ 36 | #define __WUSB_H__ 37 | 38 | #ifdef __cplusplus 39 | extern "C" { 40 | #endif 41 | 42 | #if(NTDDI_VERSION >= NTDDI_WINXP) 43 | 44 | #include 45 | 46 | 47 | typedef PVOID WINUSB_INTERFACE_HANDLE, *PWINUSB_INTERFACE_HANDLE; 48 | 49 | 50 | #pragma pack(1) 51 | 52 | typedef struct _WINUSB_SETUP_PACKET { 53 | UCHAR RequestType; 54 | UCHAR Request; 55 | USHORT Value; 56 | USHORT Index; 57 | USHORT Length; 58 | } WINUSB_SETUP_PACKET, *PWINUSB_SETUP_PACKET; 59 | 60 | #pragma pack() 61 | 62 | 63 | 64 | BOOL __stdcall 65 | WinUsb_Initialize( 66 | __in HANDLE DeviceHandle, 67 | __out PWINUSB_INTERFACE_HANDLE InterfaceHandle 68 | ); 69 | 70 | 71 | BOOL __stdcall 72 | WinUsb_Free( 73 | __in WINUSB_INTERFACE_HANDLE InterfaceHandle 74 | ); 75 | 76 | 77 | BOOL __stdcall 78 | WinUsb_GetAssociatedInterface( 79 | __in WINUSB_INTERFACE_HANDLE InterfaceHandle, 80 | __in UCHAR AssociatedInterfaceIndex, 81 | __out PWINUSB_INTERFACE_HANDLE AssociatedInterfaceHandle 82 | ); 83 | 84 | 85 | 86 | BOOL __stdcall 87 | WinUsb_GetDescriptor( 88 | __in WINUSB_INTERFACE_HANDLE InterfaceHandle, 89 | __in UCHAR DescriptorType, 90 | __in UCHAR Index, 91 | __in USHORT LanguageID, 92 | __out_bcount_part_opt(BufferLength, *LengthTransferred) PUCHAR Buffer, 93 | __in ULONG BufferLength, 94 | __out PULONG LengthTransferred 95 | ); 96 | 97 | BOOL __stdcall 98 | WinUsb_QueryInterfaceSettings( 99 | __in WINUSB_INTERFACE_HANDLE InterfaceHandle, 100 | __in UCHAR AlternateInterfaceNumber, 101 | __out PUSB_INTERFACE_DESCRIPTOR UsbAltInterfaceDescriptor 102 | ); 103 | 104 | BOOL __stdcall 105 | WinUsb_QueryDeviceInformation( 106 | __in WINUSB_INTERFACE_HANDLE InterfaceHandle, 107 | __in ULONG InformationType, 108 | __inout PULONG BufferLength, 109 | __out_bcount(*BufferLength) PVOID Buffer 110 | ); 111 | 112 | BOOL __stdcall 113 | WinUsb_SetCurrentAlternateSetting( 114 | __in WINUSB_INTERFACE_HANDLE InterfaceHandle, 115 | __in UCHAR SettingNumber 116 | ); 117 | 118 | BOOL __stdcall 119 | WinUsb_GetCurrentAlternateSetting( 120 | __in WINUSB_INTERFACE_HANDLE InterfaceHandle, 121 | __out PUCHAR SettingNumber 122 | ); 123 | 124 | 125 | BOOL __stdcall 126 | WinUsb_QueryPipe( 127 | __in WINUSB_INTERFACE_HANDLE InterfaceHandle, 128 | __in UCHAR AlternateInterfaceNumber, 129 | __in UCHAR PipeIndex, 130 | __out PWINUSB_PIPE_INFORMATION PipeInformation 131 | ); 132 | 133 | 134 | BOOL __stdcall 135 | WinUsb_SetPipePolicy( 136 | __in WINUSB_INTERFACE_HANDLE InterfaceHandle, 137 | __in UCHAR PipeID, 138 | __in ULONG PolicyType, 139 | __in ULONG ValueLength, 140 | __in_bcount(ValueLength) PVOID Value 141 | ); 142 | 143 | BOOL __stdcall 144 | WinUsb_GetPipePolicy( 145 | __in WINUSB_INTERFACE_HANDLE InterfaceHandle, 146 | __in UCHAR PipeID, 147 | __in ULONG PolicyType, 148 | __inout PULONG ValueLength, 149 | __out_bcount(*ValueLength) PVOID Value 150 | ); 151 | 152 | BOOL __stdcall 153 | WinUsb_ReadPipe( 154 | __in WINUSB_INTERFACE_HANDLE InterfaceHandle, 155 | __in UCHAR PipeID, 156 | __out_bcount_part_opt(BufferLength,*LengthTransferred) PUCHAR Buffer, 157 | __in ULONG BufferLength, 158 | __out_opt PULONG LengthTransferred, 159 | __in_opt LPOVERLAPPED Overlapped 160 | ); 161 | 162 | BOOL __stdcall 163 | WinUsb_WritePipe( 164 | __in WINUSB_INTERFACE_HANDLE InterfaceHandle, 165 | __in UCHAR PipeID, 166 | __in_bcount(BufferLength) PUCHAR Buffer, 167 | __in ULONG BufferLength, 168 | __out_opt PULONG LengthTransferred, 169 | __in_opt LPOVERLAPPED Overlapped 170 | ); 171 | 172 | BOOL __stdcall 173 | WinUsb_ControlTransfer( 174 | __in WINUSB_INTERFACE_HANDLE InterfaceHandle, 175 | __in WINUSB_SETUP_PACKET SetupPacket, 176 | __out_bcount_part_opt(BufferLength, *LengthTransferred) PUCHAR Buffer, 177 | __in ULONG BufferLength, 178 | __out_opt PULONG LengthTransferred, 179 | __in_opt LPOVERLAPPED Overlapped 180 | ); 181 | 182 | BOOL __stdcall 183 | WinUsb_ResetPipe( 184 | __in WINUSB_INTERFACE_HANDLE InterfaceHandle, 185 | __in UCHAR PipeID 186 | ); 187 | 188 | BOOL __stdcall 189 | WinUsb_AbortPipe( 190 | __in WINUSB_INTERFACE_HANDLE InterfaceHandle, 191 | __in UCHAR PipeID 192 | ); 193 | 194 | BOOL __stdcall 195 | WinUsb_FlushPipe( 196 | __in WINUSB_INTERFACE_HANDLE InterfaceHandle, 197 | __in UCHAR PipeID 198 | ); 199 | 200 | BOOL __stdcall 201 | WinUsb_SetPowerPolicy( 202 | __in WINUSB_INTERFACE_HANDLE InterfaceHandle, 203 | __in ULONG PolicyType, 204 | __in ULONG ValueLength, 205 | __in_bcount(ValueLength) PVOID Value 206 | ); 207 | 208 | BOOL __stdcall 209 | WinUsb_GetPowerPolicy( 210 | __in WINUSB_INTERFACE_HANDLE InterfaceHandle, 211 | __in ULONG PolicyType, 212 | __inout PULONG ValueLength, 213 | __out_bcount(*ValueLength) PVOID Value 214 | ); 215 | 216 | BOOL __stdcall 217 | WinUsb_GetOverlappedResult( 218 | __in WINUSB_INTERFACE_HANDLE InterfaceHandle, 219 | __in LPOVERLAPPED lpOverlapped, 220 | __out LPDWORD lpNumberOfBytesTransferred, 221 | __in BOOL bWait 222 | ); 223 | 224 | 225 | PUSB_INTERFACE_DESCRIPTOR __stdcall 226 | WinUsb_ParseConfigurationDescriptor( 227 | __in PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, 228 | __in PVOID StartPosition, 229 | __in LONG InterfaceNumber, 230 | __in LONG AlternateSetting, 231 | __in LONG InterfaceClass, 232 | __in LONG InterfaceSubClass, 233 | __in LONG InterfaceProtocol 234 | ); 235 | 236 | PUSB_COMMON_DESCRIPTOR __stdcall 237 | WinUsb_ParseDescriptors( 238 | __in_bcount(TotalLength) PVOID DescriptorBuffer, 239 | __in ULONG TotalLength, 240 | __in PVOID StartPosition, 241 | __in LONG DescriptorType 242 | ); 243 | 244 | 245 | #endif // (NTDDI_VERSION >= NTDDI_WINXP) 246 | 247 | #ifdef __cplusplus 248 | } 249 | #endif 250 | 251 | 252 | #endif //__WUSB_H__ 253 | 254 | -------------------------------------------------------------------------------- /include/win32/winusb/winusbio.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | 3 | Copyright (c) 2002 Microsoft Corporation 4 | 5 | Module Name: 6 | 7 | wusbio.h 8 | 9 | Abstract: 10 | 11 | Public header for WINUSB 12 | 13 | Environment: 14 | 15 | User and Kernel Mode 16 | 17 | Notes: 18 | 19 | THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY 20 | KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR 22 | PURPOSE. 23 | 24 | Copyright (c) 2001 Microsoft Corporation. All Rights Reserved. 25 | 26 | 27 | Revision History: 28 | 29 | 11/12/2002 : created 30 | 31 | 32 | ****************************************************************************/ 33 | 34 | #ifndef __WUSBIO_H__ 35 | #define __WUSBIO_H__ 36 | 37 | #if(NTDDI_VERSION >= NTDDI_WINXP) 38 | 39 | #include 40 | 41 | // Pipe policy types 42 | #define SHORT_PACKET_TERMINATE 0x01 43 | #define AUTO_CLEAR_STALL 0x02 44 | #define PIPE_TRANSFER_TIMEOUT 0x03 45 | #define IGNORE_SHORT_PACKETS 0x04 46 | #define ALLOW_PARTIAL_READS 0x05 47 | #define AUTO_FLUSH 0x06 48 | #define RAW_IO 0x07 49 | #define MAXIMUM_TRANSFER_SIZE 0x08 50 | #define RESET_PIPE_ON_RESUME 0x09 51 | 52 | // Power policy types 53 | // 54 | // Add 0x80 for Power policy types in order to prevent overlap with 55 | // Pipe policy types to prevent "accidentally" setting the wrong value for the 56 | // wrong type. 57 | // 58 | #define AUTO_SUSPEND 0x81 59 | #define SUSPEND_DELAY 0x83 60 | 61 | // Device Information types 62 | #define DEVICE_SPEED 0x01 63 | 64 | // Device Speeds 65 | #define LowSpeed 0x01 66 | #define FullSpeed 0x02 67 | #define HighSpeed 0x03 68 | 69 | // {DA812BFF-12C3-46a2-8E2B-DBD3B7834C43} 70 | #include 71 | DEFINE_GUID(WinUSB_TestGuid, 0xda812bff, 0x12c3, 0x46a2, 0x8e, 0x2b, 0xdb, 0xd3, 0xb7, 0x83, 0x4c, 0x43); 72 | 73 | 74 | typedef struct _WINUSB_PIPE_INFORMATION { 75 | USBD_PIPE_TYPE PipeType; 76 | UCHAR PipeId; 77 | USHORT MaximumPacketSize; 78 | UCHAR Interval; 79 | } WINUSB_PIPE_INFORMATION, *PWINUSB_PIPE_INFORMATION; 80 | 81 | #endif // (NTDDI_VERSION >= NTDDI_WINXP) 82 | 83 | #endif // __WUSBIO_H__ 84 | 85 | 86 | -------------------------------------------------------------------------------- /libnv3p/libnv3p.c: -------------------------------------------------------------------------------- 1 | /* libnv3p.c - Library for Nv3p communications. 2 | * 3 | * Copyright (C) 2015 androidroot.mobi 4 | * 5 | * This file is part of libnv3p. 6 | * 7 | * Wheelie is free software; you can redistribute it and/or modify it 8 | * under the terms of the GNU General Public License v2 as published by the 9 | * Free Software Foundation. 10 | * 11 | * Wheelie is distributed in the hope that it will be useful, but 12 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 14 | * more details. 15 | 16 | * You should have received a copy of the GNU General Public License along with 17 | * this program; if not, write to the Free Software Foundation, Inc., 18 | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #include 22 | #include 23 | #include "config.h" 24 | #include "shared.h" 25 | 26 | #include "libnv3p.h" 27 | 28 | /* FIXME: MASSIVE FUCKING KLUDGE. */ 29 | static int ICS_MODE = 0; 30 | 31 | static void generate_header(uint32_t version, uint32_t type, uint32_t sequence, uint8_t *packet){ 32 | 33 | nv3p_header *hdr = (nv3p_header*)packet; 34 | hdr->version = version; 35 | hdr->type = type; 36 | hdr->sequence = sequence; 37 | return; 38 | 39 | } 40 | 41 | static uint32_t generate_checksum(uint8_t *packet, uint32_t length){ 42 | 43 | uint32_t i; 44 | uint32_t sum; 45 | uint8_t *tmp; 46 | 47 | sum = 0; 48 | tmp = packet; 49 | for( i = 0; i < length; i++ ){ 50 | sum += *tmp; 51 | tmp++; 52 | } 53 | 54 | return sum; 55 | 56 | } 57 | 58 | static int32_t nv3p_send_ack(nvDevice_t nvdev, uint32_t type, int32_t sequence){ 59 | 60 | const uint32_t length = PACKET_HEADER_LEN + PACKET_CHECKSUM_LEN; 61 | uint8_t packet[PACKET_HEADER_LEN + PACKET_CHECKSUM_LEN]; 62 | uint32_t *checksum = (uint32_t*)&packet[PACKET_HEADER_LEN]; 63 | int ret = 0; 64 | 65 | 66 | generate_header(NV3P_VERS, NV3P_ACK, sequence, packet); 67 | 68 | *checksum = generate_checksum(packet, length - PACKET_CHECKSUM_LEN); 69 | *checksum = ~(*checksum) + 1; 70 | 71 | // TODO: Error handling 72 | ret = nvusb_send(nvdev, packet, length); 73 | 74 | return 0; 75 | 76 | } 77 | 78 | static uint32_t remap_command(uint32_t command) 79 | { 80 | if(ICS_MODE > 0 && command >= NV3P_COMMAND_SENDBL) { 81 | DEBUGPRINT("Remapped command %d to %d...\n", 82 | command, command + ICS_MODE); 83 | command += ICS_MODE; 84 | } 85 | 86 | return command; 87 | } 88 | 89 | static int32_t nv3p_get_ack(nvDevice_t nvdev) 90 | { 91 | char packet[1024] = {0}; 92 | int packet_len = PACKET_HEADER_LEN; 93 | 94 | nv3p_header *header = &packet[0]; 95 | int *recv_checksum, *error, checksum; 96 | 97 | /* Receive the header. */ 98 | nvusb_receive(nvdev, &packet[0], PACKET_HEADER_LEN); 99 | 100 | if(header->version != (uint32_t)NV3P_VERS){ 101 | DEBUGPRINT("Nv3p version mismatch\n"); 102 | return -2; 103 | } 104 | 105 | if(header->sequence != nvdev->nvSequence) { 106 | DEBUGPRINT("Unexpected sequence number: %d, expected: %d\n", 107 | header->sequence, nvdev->nvSequence); 108 | return -5; 109 | } 110 | 111 | switch(header->type){ 112 | case NV3P_ACK: 113 | break; 114 | case NV3P_NACK: 115 | error = (int *)&packet[packet_len]; 116 | nvusb_receive(nvdev, &packet[packet_len], 4); // FIXME: Hardcoded 4. 117 | packet_len += 4; 118 | break; 119 | default: 120 | DEBUGPRINT("Unknown header type received: %d\n", header->type); 121 | return -4; 122 | break; 123 | } 124 | 125 | /* Receive the checksum. */ 126 | recv_checksum = &packet[packet_len]; 127 | nvusb_receive(nvdev, &packet[packet_len], PACKET_CHECKSUM_LEN); 128 | packet_len += PACKET_CHECKSUM_LEN; 129 | 130 | /* Checksum verification of packet */ 131 | checksum = generate_checksum(packet, packet_len - PACKET_CHECKSUM_LEN); 132 | 133 | // usually we do two-complement of checksum. 134 | // By leaving it out, recv_checksum == -checksum 135 | checksum += *recv_checksum; 136 | 137 | if(checksum != 0x0){ 138 | DEBUGPRINT("Invalid checksum received: %d\n", *recv_checksum); 139 | return -1; 140 | } 141 | 142 | if(header->type == NV3P_NACK) { 143 | return *error; 144 | } 145 | 146 | return 0; 147 | } 148 | 149 | #define FILE_BUFFER_SIZE (1024*64) 150 | int nv3p_send_file(nvDevice_t nvdev, char *filename, uint64_t filesize, nv3p_status_callback_t status_callback){ 151 | uint8_t buffer[FILE_BUFFER_SIZE]; // 64KB transfers 152 | size_t left = (size_t)filesize; 153 | size_t total_read=0; 154 | 155 | 156 | FILE *file = fopen(filename, "rb"); 157 | 158 | while(left > 0) 159 | { 160 | size_t wanted = MIN(FILE_BUFFER_SIZE, left); 161 | size_t read; 162 | DEBUGPRINT("Reading %ld bytes\n", wanted); 163 | read = fread(buffer, 1, wanted, file); 164 | 165 | DEBUGPRINT("Got %ld bytes\n", read); 166 | left -= read; 167 | total_read += read; 168 | DEBUGPRINT("Sending bytes to device\n"); 169 | nv3p_send_data(nvdev, buffer, read); 170 | DEBUGPRINT("Notifying of status\n"); 171 | if(status_callback) 172 | status_callback(total_read, (size_t)filesize); 173 | }; 174 | fclose(file); 175 | return 1; 176 | 177 | } 178 | 179 | int nv3p_send_buffer(nvDevice_t nvdev, uint8_t *data, int32_t dataLen, 180 | nv3p_status_callback_t status_callback) 181 | { 182 | size_t left = (size_t)dataLen, wanted; 183 | 184 | while(left > 0) { 185 | wanted = MIN(FILE_BUFFER_SIZE, left); 186 | nv3p_send_data(nvdev, data, wanted); 187 | data += wanted; 188 | left -= wanted; 189 | 190 | if(status_callback) 191 | status_callback(dataLen - left, (size_t)dataLen); 192 | } 193 | 194 | return 1; 195 | } 196 | 197 | int nv3p_send_data(nvDevice_t nvdev, uint8_t *data, int32_t dataLen) { 198 | uint8_t *tmp; 199 | uint8_t packet[PACKET_HEADER_LEN + PACKET_DATA_HEADER_LEN]; 200 | uint32_t length = PACKET_HEADER_LEN + PACKET_DATA_HEADER_LEN; 201 | uint32_t checksum; 202 | int ret; 203 | 204 | /* Generate packet header */ 205 | 206 | generate_header(NV3P_VERS, NV3P_DATA, nvdev->nvSequence, packet); 207 | tmp = packet + PACKET_HEADER_LEN; 208 | 209 | *(uint32_t*)tmp = dataLen; 210 | tmp += PACKET_DATA_HEADER_LEN; 211 | 212 | // Checksum headers + data - since checksum is essentially 213 | // just a sum, we can do it seperately 214 | checksum = generate_checksum(packet, length); 215 | checksum += generate_checksum(data, dataLen); 216 | // Take two's complement of the result. 217 | checksum = ~checksum + 1; 218 | 219 | // Send the three parts seperate because it's easier. 220 | // Alternative we need to construct a single buffer in memory 221 | // and copy stuff around. This also matches usb dumps from nvflash. 222 | // Send Header, including dataLength 223 | ret = nvusb_send(nvdev, packet, length); 224 | if(ret != 0) 225 | return ret; 226 | 227 | // Send actual data 228 | ret = nvusb_send(nvdev, data, dataLen); 229 | if(ret != 0) 230 | return ret; 231 | 232 | // Send checksum 233 | ret = nvusb_send(nvdev, (uint8_t*)&checksum, PACKET_CHECKSUM_LEN); 234 | if(ret != 0) 235 | return ret; 236 | 237 | 238 | ret = nv3p_get_ack(nvdev); 239 | if(ret != 0) 240 | return ret; 241 | 242 | nvdev->nvSequence++; 243 | 244 | return ret; 245 | } 246 | 247 | 248 | int nv3p_send_command(nvDevice_t nvdev, uint32_t command, uint8_t *args){ 249 | 250 | uint8_t *tmp; 251 | uint8_t packet[NV3P_MAX_COMMAND_LEN]; 252 | uint32_t length = 0; 253 | uint32_t checksum; 254 | nv3p_body *bdy; 255 | int ret; 256 | 257 | /* Generate packet header */ 258 | 259 | generate_header(NV3P_VERS, NV3P_COMMAND, nvdev->nvSequence, packet); 260 | 261 | tmp = packet + PACKET_HEADER_LEN; 262 | 263 | /* Generate packet body */ 264 | 265 | bdy = (nv3p_body*)tmp; 266 | 267 | switch(command){ 268 | case NV3P_COMMAND_GETINFO: 269 | case NV3P_COMMAND_SYNCRONIZE: 270 | { 271 | length = 0; 272 | bdy->length = length; 273 | bdy->command = command; 274 | break; 275 | } 276 | case NV3P_COMMAND_SENDBCT: 277 | { 278 | uint32_t filesize = *(int*) args; 279 | length = 4; 280 | bdy->length = length; 281 | bdy->command = command; 282 | bdy->bctargs.filesize = filesize; 283 | break; 284 | } 285 | case NV3P_COMMAND_SENDODM: 286 | { 287 | uint32_t odmdata = *(int*) args; 288 | length = 4; 289 | bdy->length = length; 290 | bdy->command = command; 291 | bdy->odmargs.odmdata = odmdata; 292 | break; 293 | } 294 | case NV3P_COMMAND_SENDBL: 295 | { 296 | nv3p_blargs *bl = (nv3p_blargs*)args; 297 | length = 16; 298 | bdy->length = length; 299 | bdy->command = command; 300 | bdy->blargs.filesize = bl->filesize; 301 | bdy->blargs.loadaddr = bl->loadaddr; 302 | bdy->blargs.entry = bl->entry; 303 | break; 304 | } 305 | 306 | case NV3P_COMMAND_RAWWRITE: 307 | { 308 | nv3p_rawargs *raw = (nv3p_rawargs*)args; 309 | length = 8; 310 | bdy->length = length; 311 | bdy->command = command; 312 | bdy->rawargs.start = raw->start; 313 | bdy->rawargs.size = raw->size; 314 | break; 315 | } 316 | default: 317 | return -1; 318 | } 319 | 320 | bdy->command = remap_command(bdy->command); 321 | 322 | length += PACKET_HEADER_LEN; 323 | length += PACKET_COMMAND_HEADER_LEN; 324 | 325 | checksum = generate_checksum(packet, length); 326 | checksum = ~checksum + 1; 327 | 328 | tmp = packet + length; 329 | 330 | memcpy(tmp, &checksum, sizeof(checksum)); 331 | tmp += sizeof(checksum); 332 | 333 | length += PACKET_CHECKSUM_LEN; 334 | 335 | 336 | ret = nvusb_send(nvdev, packet, length); 337 | if(ret != 0) 338 | return ret; 339 | 340 | ret = nv3p_get_ack(nvdev); 341 | if(ret != 0) 342 | return ret; 343 | 344 | nvdev->nvSequence++; 345 | 346 | return ret; 347 | } 348 | 349 | uint8_t nv3p_command_response(nvDevice_t nvdev, uint32_t command, uint8_t *packet){ 350 | 351 | uint32_t length = 0; 352 | const uint32_t hlen = PACKET_HEADER_LEN + PACKET_CHECKSUM_LEN; 353 | uint32_t recv_checksum = 0, checksum, hdrchecksum; 354 | uint8_t header[PACKET_HEADER_LEN + PACKET_CHECKSUM_LEN]; 355 | // uint8_t *tmp; 356 | nv3p_header *hdr; 357 | 358 | switch(command){ 359 | 360 | case NV3P_COMMAND_GETINFO: 361 | // GetInfo appears to return 48 bytes. 362 | // For now only, the most important ones are mapped out. 363 | length = NV3P_COMMAND_GETINFO_LEN; 364 | break; 365 | 366 | case NV3P_COMMAND_RAWWRITE: 367 | length = 8; 368 | break; 369 | // These "commands" appear to not return any data 370 | case NV3P_COMMAND_SENDBL: 371 | case NV3P_COMMAND_SENDBCT: 372 | case NV3P_COMMAND_SENDODM: 373 | case NV3P_COMMAND_SYNCRONIZE: 374 | return 0; 375 | default: 376 | return 0x1; 377 | } 378 | 379 | /* Get return data header */ 380 | nvusb_receive(nvdev, header, hlen); 381 | 382 | hdr = (nv3p_header*)header; 383 | 384 | if(hdr->type != NV3P_DATA) 385 | return 0x2; 386 | if(hdr->version != NV3P_VERS) 387 | printf("Unknown NV3P version: %d\n", hdr->version); 388 | 389 | hdrchecksum = generate_checksum(header, hlen); 390 | /* Get return data for command */ 391 | nvusb_receive(nvdev, packet, length); 392 | 393 | recv_checksum = generate_checksum(packet, length) + hdrchecksum; 394 | 395 | nvusb_receive(nvdev, (uint8_t*)&checksum, 4); 396 | 397 | if(checksum + recv_checksum != 0x0){ 398 | return 0x3; 399 | } 400 | 401 | if(hdr->sequence != nvdev->nvRecSequence){ 402 | return 0x4; 403 | } 404 | 405 | nv3p_send_ack(nvdev, NV3P_ACK, hdr->sequence); 406 | 407 | nvdev->nvRecSequence++; 408 | 409 | return 0; 410 | 411 | }; 412 | 413 | int nv3p_wait_status(nvDevice_t nvdev){ 414 | const uint32_t hlen = PACKET_HEADER_LEN; 415 | uint8_t header[PACKET_HEADER_LEN]; 416 | nv3p_header *hdr = (nv3p_header*)header; 417 | uint8_t lencmd[8]; 418 | uint32_t *length = (uint32_t*)lencmd; 419 | uint32_t *cmd = (uint32_t*)&lencmd[4]; 420 | uint8_t buffer[128]; // We don't technically need 128 bytes - find actual value 421 | 422 | nvusb_receive(nvdev, header, hlen); 423 | nvusb_receive(nvdev, lencmd, 8); 424 | 425 | DEBUGPRINT("Received hdr v%d with type %d\n", hdr->version, hdr->type); 426 | DEBUGPRINT("Packet with len %d and Command %d\n", *length, *cmd); 427 | 428 | if(*length > 0 && *length <= 1024) 429 | { 430 | char *string = (char*)buffer; 431 | uint32_t *status1 = (uint32_t*)&buffer[32]; 432 | uint32_t *status2 = (uint32_t*)&buffer[36]; 433 | 434 | nvusb_receive(nvdev, buffer, *length); 435 | 436 | if(hdr->type == 5) { 437 | DEBUGPRINT("NACK PACKET RECEIVED, error: 0x%08x\n", 438 | (uint32_t)*buffer); 439 | return (uint32_t)*buffer; 440 | } 441 | 442 | 443 | DEBUGPRINT("Message: %.*s\n", 32, string); 444 | DEBUGPRINT("Status1: %u, Status2 = 0x%X\n", *status1, *status2); 445 | } 446 | fflush(stdout); 447 | nv3p_send_ack(nvdev, NV3P_ACK, hdr->sequence); 448 | 449 | nvdev->nvRecSequence++; 450 | return 0; 451 | }; 452 | 453 | void nv3p_set_ics_protocol(int flag) 454 | { 455 | ICS_MODE = flag; 456 | } 457 | -------------------------------------------------------------------------------- /libnvfblob/libnvfblob.c: -------------------------------------------------------------------------------- 1 | /* libnvfblob.c - Library for parsing nvflash style blobs. 2 | * 3 | * Copyright (C) 2015 androidroot.mobi 4 | * 5 | * This file is part of libnv3p. 6 | * 7 | * Wheelie is free software; you can redistribute it and/or modify it 8 | * under the terms of the GNU General Public License v2 as published by the 9 | * Free Software Foundation. 10 | * 11 | * Wheelie is distributed in the hope that it will be useful, but 12 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 14 | * more details. 15 | 16 | * You should have received a copy of the GNU General Public License along with 17 | * this program; if not, write to the Free Software Foundation, Inc., 18 | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | #include "libnvfblob.h" 26 | 27 | nvfblob_file_t nvfblob_open(const char *filename) 28 | { 29 | return (nvfblob_file_t)fopen(filename, "rb"); 30 | } 31 | 32 | int nvfblob_close(nvfblob_file_t handle) 33 | { 34 | return fclose((FILE *)handle); 35 | } 36 | 37 | int nvfblob_alloc_read(nvfblob_file_t handle, uint32_t type, 38 | unsigned char **buf, size_t *length) 39 | { 40 | FILE *fp = (FILE *)handle; 41 | nvfblob_header_t header = {0}; 42 | 43 | /* Initialise *buf to the NULL pointer so we don't end up 44 | * attempting to free an uninitialised pointer due to a 45 | * failure condition. */ 46 | *buf = NULL; 47 | 48 | /* Always start at the beginning of the file. */ 49 | fseek(fp, 0, SEEK_SET); 50 | 51 | do { 52 | /* Read the blob header from the file. */ 53 | if(fread(&header, sizeof(header), 1, fp) != 1) { 54 | goto fail; 55 | } 56 | 57 | /* Check if we've found the requested type. */ 58 | if(header.type == type) { 59 | *length = header.length; 60 | 61 | /* Allocate memory for the data. */ 62 | if(!(*buf = (unsigned char*)malloc(*length))) { 63 | goto fail; 64 | } 65 | 66 | /* Read the data from the blob file. */ 67 | if(fread(*buf, sizeof(unsigned char), *length, fp) != *length) { 68 | goto fail; 69 | } 70 | 71 | return 1; 72 | } else { 73 | /* Advance the file pointer to the next blob header. */ 74 | fseek(fp, header.length, SEEK_CUR); 75 | } 76 | } while(!feof(fp)); 77 | 78 | /* End of the file and we haven't found the requested type. */ 79 | errno = EINVAL; 80 | 81 | fail: 82 | if(*buf) free(*buf); 83 | *buf = NULL; 84 | *length = 0; 85 | return 0; 86 | } 87 | 88 | void nvfblob_alloc_free(unsigned char **buf) 89 | { 90 | free(*buf); 91 | *buf = NULL; 92 | } 93 | 94 | #ifdef DEBUG_STANDALONE 95 | /* Quick implementation for testing purposes. 96 | * 97 | * $ gcc -I../include/ -DDEBUG_STANDALONE -o nvfblob libnvfblob.c 98 | */ 99 | int main(int argc, char **argv) 100 | { 101 | unsigned char *buf; 102 | size_t len; 103 | 104 | FILE *out; 105 | nvfblob_file_t blob; 106 | 107 | if(argc != 4) { 108 | fprintf(stderr, "Usage: %s \n", argv[0]); 109 | return 1; 110 | } 111 | 112 | if(!(blob = nvfblob_open(argv[1]))) { 113 | perror("failed to open blob file"); 114 | return 1; 115 | } 116 | 117 | if(!nvfblob_alloc_read(blob, atoi(argv[2]), &buf, &len)) { 118 | perror("failed to read blob/find requested type"); 119 | return 1; 120 | } 121 | 122 | if(!(out = fopen(argv[3], "w"))) { 123 | perror("failed to open output file"); 124 | return 1; 125 | } 126 | 127 | if(fwrite(buf, sizeof(unsigned char), len, out) != len) { 128 | perror("failed to write data to output file"); 129 | return 1; 130 | } 131 | 132 | nvfblob_alloc_free(&buf); 133 | nvfblob_close(blob); 134 | } 135 | #endif 136 | -------------------------------------------------------------------------------- /os/win32/README.txt: -------------------------------------------------------------------------------- 1 | GetOpt routines ported from BSD-licensed sources, see comments. -------------------------------------------------------------------------------- /os/win32/getopt.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1987, 1993, 1994 3 | * The Regents of the University of California. All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 3. All advertising materials mentioning features or use of this software 14 | * must display the following acknowledgement: 15 | * This product includes software developed by the University of 16 | * California, Berkeley and its contributors. 17 | * 4. Neither the name of the University nor the names of its contributors 18 | * may be used to endorse or promote products derived from this software 19 | * without specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 | * SUCH DAMAGE. 32 | */ 33 | 34 | /*#if defined(LIBC_SCCS) && !defined(lint) 35 | static char sccsid[] = "@(#)getopt.c 8.3 (Berkeley) 4/27/95"; 36 | #endif /* LIBC_SCCS and not lint 37 | #include 38 | //__FBSDID("$FreeBSD: src/lib/libc/stdlib/getopt.c,v 1.6 2002/03/29 22:43:42 markm Exp $"); 39 | 40 | #include "namespace.h"*/ 41 | #include 42 | #include 43 | #include 44 | /*#include "un-namespace.h"*/ 45 | 46 | /*#include "libc_private.h"*/ 47 | 48 | int opterr = 1, /* if error message should be printed */ 49 | optind = 1, /* index into parent argv vector */ 50 | optopt, /* character checked for validity */ 51 | optreset; /* reset getopt */ 52 | char *optarg; /* argument associated with option */ 53 | 54 | #define BADCH (int)'?' 55 | #define BADARG (int)':' 56 | #define EMSG "" 57 | 58 | /* 59 | * getopt -- 60 | * Parse argc/argv argument vector. 61 | */ 62 | int 63 | getopt(nargc, nargv, ostr) 64 | int nargc; 65 | char * const *nargv; 66 | const char *ostr; 67 | { 68 | static char *place = EMSG; /* option letter processing */ 69 | char *oli; /* option letter list index */ 70 | 71 | if (optreset || !*place) { /* update scanning pointer */ 72 | optreset = 0; 73 | if (optind >= nargc || *(place = nargv[optind]) != '-') { 74 | place = EMSG; 75 | return (-1); 76 | } 77 | if (place[1] && *++place == '-') { /* found "--" */ 78 | ++optind; 79 | place = EMSG; 80 | return (-1); 81 | } 82 | } /* option letter okay? */ 83 | if ((optopt = (int)*place++) == (int)':' || 84 | !(oli = strchr(ostr, optopt))) { 85 | /* 86 | * if the user didn't specify '-' as an option, 87 | * assume it means -1. 88 | */ 89 | if (optopt == (int)'-') 90 | return (-1); 91 | if (!*place) 92 | ++optind; 93 | if (opterr && *ostr != ':' && optopt != BADCH) 94 | (void)fprintf(stderr, "%s: illegal option -- %c\n", 95 | "progname", optopt); 96 | return (BADCH); 97 | } 98 | if (*++oli != ':') { /* don't need argument */ 99 | optarg = NULL; 100 | if (!*place) 101 | ++optind; 102 | } 103 | else { /* need an argument */ 104 | if (*place) /* no white space */ 105 | optarg = place; 106 | else if (nargc <= ++optind) { /* no arg */ 107 | place = EMSG; 108 | if (*ostr == ':') 109 | return (BADARG); 110 | if (opterr) 111 | (void)fprintf(stderr, 112 | "%s: option requires an argument -- %c\n", 113 | "progname", optopt); 114 | return (BADCH); 115 | } 116 | else /* white space */ 117 | optarg = nargv[optind]; 118 | place = EMSG; 119 | ++optind; 120 | } 121 | return (optopt); /* dump back option letter */ 122 | } 123 | -------------------------------------------------------------------------------- /os/win32/getopt_long.c: -------------------------------------------------------------------------------- 1 | /* $NetBSD: getopt_long.c,v 1.15 2002/01/31 22:43:40 tv Exp $ */ 2 | /* $FreeBSD: src/lib/libc/stdlib/getopt_long.c,v 1.2 2002/10/16 22:18:42 alfred Exp $ */ 3 | 4 | /*- 5 | * Copyright (c) 2000 The NetBSD Foundation, Inc. 6 | * All rights reserved. 7 | * 8 | * This code is derived from software contributed to The NetBSD Foundation 9 | * by Dieter Baron and Thomas Klausner. 10 | * 11 | * Redistribution and use in source and binary forms, with or without 12 | * modification, are permitted provided that the following conditions 13 | * are met: 14 | * 1. Redistributions of source code must retain the above copyright 15 | * notice, this list of conditions and the following disclaimer. 16 | * 2. Redistributions in binary form must reproduce the above copyright 17 | * notice, this list of conditions and the following disclaimer in the 18 | * documentation and/or other materials provided with the distribution. 19 | * 3. All advertising materials mentioning features or use of this software 20 | * must display the following acknowledgement: 21 | * This product includes software developed by the NetBSD 22 | * Foundation, Inc. and its contributors. 23 | * 4. Neither the name of The NetBSD Foundation nor the names of its 24 | * contributors may be used to endorse or promote products derived 25 | * from this software without specific prior written permission. 26 | * 27 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 28 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 29 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 30 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 31 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 32 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 33 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 34 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 35 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 36 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 37 | * POSSIBILITY OF SUCH DAMAGE. 38 | */ 39 | 40 | 41 | #include 42 | #include 43 | #include 44 | 45 | #ifdef _WIN32 46 | 47 | /* Windows needs warnx(). We change the definition though: 48 | * 1. (another) global is defined, opterrmsg, which holds the error message 49 | * 2. errors are always printed out on stderr w/o the program name 50 | * Note that opterrmsg always gets set no matter what opterr is set to. The 51 | * error message will not be printed if opterr is 0 as usual. 52 | */ 53 | 54 | #include 55 | #include 56 | 57 | //GETOPT_API extern char opterrmsg[128]; 58 | char opterrmsg[128]; /* last error message is stored here */ 59 | 60 | static void warnx(int print_error, const char *fmt, ...) 61 | { 62 | va_list ap; 63 | va_start(ap, fmt); 64 | if (fmt != NULL) 65 | _vsnprintf(opterrmsg, 128, fmt, ap); 66 | else 67 | opterrmsg[0]='\0'; 68 | va_end(ap); 69 | if (print_error) { 70 | fprintf(stderr, opterrmsg); 71 | fprintf(stderr, "\n"); 72 | } 73 | } 74 | 75 | #endif /*_WIN32*/ 76 | 77 | /* not part of the original file */ 78 | #ifndef _DIAGASSERT 79 | #define _DIAGASSERT(X) 80 | #endif 81 | 82 | #if HAVE_CONFIG_H && !HAVE_GETOPT_LONG && !HAVE_DECL_OPTIND 83 | #define REPLACE_GETOPT 84 | #endif 85 | 86 | #ifdef REPLACE_GETOPT 87 | #ifdef __weak_alias 88 | __weak_alias(getopt,_getopt) 89 | #endif 90 | int opterr = 1; /* if error message should be printed */ 91 | int optind = 1; /* index into parent argv vector */ 92 | int optopt = '?'; /* character checked for validity */ 93 | int optreset; /* reset getopt */ 94 | char *optarg; /* argument associated with option */ 95 | #elif HAVE_CONFIG_H && !HAVE_DECL_OPTRESET 96 | static int optreset; 97 | #endif 98 | 99 | #ifdef __weak_alias 100 | __weak_alias(getopt_long,_getopt_long) 101 | #endif 102 | 103 | #if !HAVE_GETOPT_LONG 104 | #define IGNORE_FIRST (*options == '-' || *options == '+') 105 | #define PRINT_ERROR ((opterr) && ((*options != ':') \ 106 | || (IGNORE_FIRST && options[1] != ':'))) 107 | #define IS_POSIXLY_CORRECT (getenv("POSIXLY_CORRECT") != NULL) 108 | #define PERMUTE (!IS_POSIXLY_CORRECT && !IGNORE_FIRST) 109 | /* XXX: GNU ignores PC if *options == '-' */ 110 | #define IN_ORDER (!IS_POSIXLY_CORRECT && *options == '-') 111 | 112 | /* return values */ 113 | #define BADCH (int)'?' 114 | #define BADARG ((IGNORE_FIRST && options[1] == ':') \ 115 | || (*options == ':') ? (int)':' : (int)'?') 116 | #define INORDER (int)1 117 | 118 | #define EMSG "" 119 | 120 | static int getopt_internal(int, char * const *, const char *); 121 | static int gcd(int, int); 122 | static void permute_args(int, int, int, char * const *); 123 | 124 | static char *place = EMSG; /* option letter processing */ 125 | 126 | /* XXX: set optreset to 1 rather than these two */ 127 | static int nonopt_start = -1; /* first non option argument (for permute) */ 128 | static int nonopt_end = -1; /* first option after non options (for permute) */ 129 | 130 | /* Error messages */ 131 | static const char recargchar[] = "option requires an argument -- %c"; 132 | static const char recargstring[] = "option requires an argument -- %s"; 133 | static const char ambig[] = "ambiguous option -- %.*s"; 134 | static const char noarg[] = "option doesn't take an argument -- %.*s"; 135 | static const char illoptchar[] = "unknown option -- %c"; 136 | static const char illoptstring[] = "unknown option -- %s"; 137 | 138 | 139 | /* 140 | * Compute the greatest common divisor of a and b. 141 | */ 142 | static int 143 | gcd(int a, int b) 144 | { 145 | int c; 146 | 147 | c = a % b; 148 | while (c != 0) { 149 | a = b; 150 | b = c; 151 | c = a % b; 152 | } 153 | 154 | return b; 155 | } 156 | 157 | /* 158 | * Exchange the block from nonopt_start to nonopt_end with the block 159 | * from nonopt_end to opt_end (keeping the same order of arguments 160 | * in each block). 161 | */ 162 | static void 163 | permute_args(int panonopt_start, int panonopt_end, int opt_end, char * const *nargv) 164 | { 165 | int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos; 166 | char *swap; 167 | 168 | _DIAGASSERT(nargv != NULL); 169 | 170 | /* 171 | * compute lengths of blocks and number and size of cycles 172 | */ 173 | nnonopts = panonopt_end - panonopt_start; 174 | nopts = opt_end - panonopt_end; 175 | ncycle = gcd(nnonopts, nopts); 176 | cyclelen = (opt_end - panonopt_start) / ncycle; 177 | 178 | for (i = 0; i < ncycle; i++) { 179 | cstart = panonopt_end+i; 180 | pos = cstart; 181 | for (j = 0; j < cyclelen; j++) { 182 | if (pos >= panonopt_end) 183 | pos -= nnonopts; 184 | else 185 | pos += nopts; 186 | swap = nargv[pos]; 187 | /* LINTED const cast */ 188 | ((char **) nargv)[pos] = nargv[cstart]; 189 | /* LINTED const cast */ 190 | ((char **)nargv)[cstart] = swap; 191 | } 192 | } 193 | } 194 | 195 | /* 196 | * getopt_internal -- 197 | * Parse argc/argv argument vector. Called by user level routines. 198 | * Returns -2 if -- is found (can be long option or end of options marker). 199 | */ 200 | static int 201 | getopt_internal(int nargc, char * const * nargv, const char* options) 202 | { 203 | char *oli; /* option letter list index */ 204 | int optchar; 205 | 206 | _DIAGASSERT(nargv != NULL); 207 | _DIAGASSERT(options != NULL); 208 | 209 | optarg = NULL; 210 | 211 | /* 212 | * XXX Some programs (like rsyncd) expect to be able to 213 | * XXX re-initialize optind to 0 and have getopt_long(3) 214 | * XXX properly function again. Work around this braindamage. 215 | */ 216 | if (optind == 0) 217 | optind = 1; 218 | 219 | if (optreset) 220 | nonopt_start = nonopt_end = -1; 221 | start: 222 | if (optreset || !*place) { /* update scanning pointer */ 223 | optreset = 0; 224 | if (optind >= nargc) { /* end of argument vector */ 225 | place = EMSG; 226 | if (nonopt_end != -1) { 227 | /* do permutation, if we have to */ 228 | permute_args(nonopt_start, nonopt_end, 229 | optind, nargv); 230 | optind -= nonopt_end - nonopt_start; 231 | } 232 | else if (nonopt_start != -1) { 233 | /* 234 | * If we skipped non-options, set optind 235 | * to the first of them. 236 | */ 237 | optind = nonopt_start; 238 | } 239 | nonopt_start = nonopt_end = -1; 240 | return -1; 241 | } 242 | if ((*(place = nargv[optind]) != '-') 243 | || (place[1] == '\0')) { /* found non-option */ 244 | place = EMSG; 245 | if (IN_ORDER) { 246 | /* 247 | * GNU extension: 248 | * return non-option as argument to option 1 249 | */ 250 | optarg = nargv[optind++]; 251 | return INORDER; 252 | } 253 | if (!PERMUTE) { 254 | /* 255 | * if no permutation wanted, stop parsing 256 | * at first non-option 257 | */ 258 | return -1; 259 | } 260 | /* do permutation */ 261 | if (nonopt_start == -1) 262 | nonopt_start = optind; 263 | else if (nonopt_end != -1) { 264 | permute_args(nonopt_start, nonopt_end, 265 | optind, nargv); 266 | nonopt_start = optind - 267 | (nonopt_end - nonopt_start); 268 | nonopt_end = -1; 269 | } 270 | optind++; 271 | /* process next argument */ 272 | goto start; 273 | } 274 | if (nonopt_start != -1 && nonopt_end == -1) 275 | nonopt_end = optind; 276 | if (place[1] && *++place == '-') { /* found "--" */ 277 | place++; 278 | return -2; 279 | } 280 | } 281 | if ((optchar = (int)*place++) == (int)':' || 282 | (oli = (char*)strchr(options + (IGNORE_FIRST ? 1 : 0), optchar)) == NULL) { 283 | /* option letter unknown or ':' */ 284 | if (!*place) 285 | ++optind; 286 | #ifndef _WIN32 287 | if (PRINT_ERROR) 288 | warnx(illoptchar, optchar); 289 | #else 290 | warnx(PRINT_ERROR, illoptchar, optchar); 291 | #endif 292 | optopt = optchar; 293 | return BADCH; 294 | } 295 | if (optchar == 'W' && oli[1] == ';') { /* -W long-option */ 296 | /* XXX: what if no long options provided (called by getopt)? */ 297 | if (*place) 298 | return -2; 299 | 300 | if (++optind >= nargc) { /* no arg */ 301 | place = EMSG; 302 | #ifndef _WIN32 303 | if (PRINT_ERROR) 304 | warnx(recargchar, optchar); 305 | #else 306 | warnx(PRINT_ERROR, recargchar, optchar); 307 | #endif 308 | optopt = optchar; 309 | return BADARG; 310 | } else /* white space */ 311 | place = nargv[optind]; 312 | /* 313 | * Handle -W arg the same as --arg (which causes getopt to 314 | * stop parsing). 315 | */ 316 | return -2; 317 | } 318 | if (*++oli != ':') { /* doesn't take argument */ 319 | if (!*place) 320 | ++optind; 321 | } else { /* takes (optional) argument */ 322 | optarg = NULL; 323 | if (*place) /* no white space */ 324 | optarg = place; 325 | /* XXX: disable test for :: if PC? (GNU doesn't) */ 326 | else if (oli[1] != ':') { /* arg not optional */ 327 | if (++optind >= nargc) { /* no arg */ 328 | place = EMSG; 329 | #ifndef _WIN32 330 | if (PRINT_ERROR) 331 | warnx(recargchar, optchar); 332 | #else 333 | warnx(PRINT_ERROR, recargchar, optchar); 334 | #endif 335 | optopt = optchar; 336 | return BADARG; 337 | } else 338 | optarg = nargv[optind]; 339 | } 340 | place = EMSG; 341 | ++optind; 342 | } 343 | /* dump back option letter */ 344 | return optchar; 345 | } 346 | 347 | #ifdef REPLACE_GETOPT 348 | /* 349 | * getopt -- 350 | * Parse argc/argv argument vector. 351 | * 352 | * [eventually this will replace the real getopt] 353 | */ 354 | int 355 | getopt(nargc, nargv, options) 356 | int nargc; 357 | char * const *nargv; 358 | const char *options; 359 | { 360 | int retval; 361 | 362 | _DIAGASSERT(nargv != NULL); 363 | _DIAGASSERT(options != NULL); 364 | 365 | if ((retval = getopt_internal(nargc, nargv, options)) == -2) { 366 | ++optind; 367 | /* 368 | * We found an option (--), so if we skipped non-options, 369 | * we have to permute. 370 | */ 371 | if (nonopt_end != -1) { 372 | permute_args(nonopt_start, nonopt_end, optind, 373 | nargv); 374 | optind -= nonopt_end - nonopt_start; 375 | } 376 | nonopt_start = nonopt_end = -1; 377 | retval = -1; 378 | } 379 | return retval; 380 | } 381 | #endif 382 | 383 | /* 384 | * getopt_long -- 385 | * Parse argc/argv argument vector. 386 | */ 387 | int 388 | getopt_long(int nargc, char * const *nargv, const char *options, const struct option *long_options, int *idx) 389 | { 390 | int retval; 391 | 392 | _DIAGASSERT(nargv != NULL); 393 | _DIAGASSERT(options != NULL); 394 | _DIAGASSERT(long_options != NULL); 395 | /* idx may be NULL */ 396 | 397 | if ((retval = getopt_internal(nargc, nargv, options)) == -2) { 398 | char *current_argv, *has_equal; 399 | size_t current_argv_len; 400 | int i, match; 401 | 402 | current_argv = place; 403 | match = -1; 404 | 405 | optind++; 406 | place = EMSG; 407 | 408 | if (*current_argv == '\0') { /* found "--" */ 409 | /* 410 | * We found an option (--), so if we skipped 411 | * non-options, we have to permute. 412 | */ 413 | if (nonopt_end != -1) { 414 | permute_args(nonopt_start, nonopt_end, 415 | optind, nargv); 416 | optind -= nonopt_end - nonopt_start; 417 | } 418 | nonopt_start = nonopt_end = -1; 419 | return -1; 420 | } 421 | if ((has_equal = strchr(current_argv, '=')) != NULL) { 422 | /* argument found (--option=arg) */ 423 | current_argv_len = has_equal - current_argv; 424 | has_equal++; 425 | } else 426 | current_argv_len = strlen(current_argv); 427 | 428 | for (i = 0; long_options[i].name; i++) { 429 | /* find matching long option */ 430 | if (strncmp(current_argv, long_options[i].name, 431 | current_argv_len)) 432 | continue; 433 | 434 | if (strlen(long_options[i].name) == 435 | (unsigned)current_argv_len) { 436 | /* exact match */ 437 | match = i; 438 | break; 439 | } 440 | if (match == -1) /* partial match */ 441 | match = i; 442 | else { 443 | /* ambiguous abbreviation */ 444 | #ifndef _WIN32 445 | if (PRINT_ERROR) 446 | warnx(ambig, (int)current_argv_len, 447 | current_argv); 448 | #else 449 | warnx(PRINT_ERROR, ambig, (int)current_argv_len, 450 | current_argv); 451 | #endif 452 | optopt = 0; 453 | return BADCH; 454 | } 455 | } 456 | if (match != -1) { /* option found */ 457 | if (long_options[match].has_arg == no_argument 458 | && has_equal) { 459 | #ifndef _WIN32 460 | if (PRINT_ERROR) 461 | warnx(noarg, (int)current_argv_len, 462 | current_argv); 463 | #else 464 | warnx(PRINT_ERROR, noarg, (int)current_argv_len, 465 | current_argv); 466 | #endif 467 | /* 468 | * XXX: GNU sets optopt to val regardless of 469 | * flag 470 | */ 471 | if (long_options[match].flag == NULL) 472 | optopt = long_options[match].val; 473 | else 474 | optopt = 0; 475 | return BADARG; 476 | } 477 | if (long_options[match].has_arg == required_argument || 478 | long_options[match].has_arg == optional_argument) { 479 | if (has_equal) 480 | optarg = has_equal; 481 | else if (long_options[match].has_arg == 482 | required_argument) { 483 | /* 484 | * optional argument doesn't use 485 | * next nargv 486 | */ 487 | optarg = nargv[optind++]; 488 | } 489 | } 490 | if ((long_options[match].has_arg == required_argument) 491 | && (optarg == NULL)) { 492 | /* 493 | * Missing argument; leading ':' 494 | * indicates no error should be generated 495 | */ 496 | #ifndef _WIN32 497 | if (PRINT_ERROR) 498 | warnx(recargstring, current_argv); 499 | #else 500 | warnx(PRINT_ERROR, recargstring, current_argv); 501 | #endif 502 | /* 503 | * XXX: GNU sets optopt to val regardless 504 | * of flag 505 | */ 506 | if (long_options[match].flag == NULL) 507 | optopt = long_options[match].val; 508 | else 509 | optopt = 0; 510 | --optind; 511 | return BADARG; 512 | } 513 | } else { /* unknown option */ 514 | #ifndef _WIN32 515 | if (PRINT_ERROR) 516 | warnx(illoptstring, current_argv); 517 | #else 518 | warnx(PRINT_ERROR, illoptstring, current_argv); 519 | #endif 520 | optopt = 0; 521 | return BADCH; 522 | } 523 | if (long_options[match].flag) { 524 | *long_options[match].flag = long_options[match].val; 525 | retval = 0; 526 | } else 527 | retval = long_options[match].val; 528 | if (idx) 529 | *idx = match; 530 | } 531 | return retval; 532 | } 533 | #endif /* !GETOPT_LONG */ 534 | -------------------------------------------------------------------------------- /usb/linux/libnvusb.c: -------------------------------------------------------------------------------- 1 | /* libnvusb.c - Library for nvusb functions 2 | * 3 | * Copyright (C) 2015 androidroot.mobi 4 | * 5 | * This file is part of libnvusb. 6 | * 7 | * libnvusb is free software; you can redistribute it and/or modify it 8 | * under the terms of the GNU General Public License v2 as published by the 9 | * Free Software Foundation. 10 | * 11 | * libnvusb is distributed in the hope that it will be useful, but 12 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 14 | * more details. 15 | 16 | * You should have received a copy of the GNU General Public License along with 17 | * this program; if not, write to the Free Software Foundation, Inc., 18 | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #include 22 | #include 23 | #include 24 | #ifndef _WIN32 25 | #include 26 | #endif 27 | 28 | #include "config.h" 29 | #include "shared.h" 30 | #include "libnvusb.h" 31 | 32 | static int32_t getEndpoints(struct libusb_config_descriptor *config, uint8_t *ep_in, uint8_t *ep_out){ 33 | int32_t i; 34 | int32_t ret=-2; 35 | for(i=0; iinterface[0].altsetting[0].bNumEndpoints; i++){ 36 | if((config->interface[0].altsetting[0].endpoint[i].bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_IN){ 37 | *ep_in = config->interface[0].altsetting[0].endpoint[i].bEndpointAddress; 38 | ret++; 39 | }else{ 40 | *ep_out = config->interface[0].altsetting[0].endpoint[i].bEndpointAddress; 41 | ret++; 42 | } 43 | } 44 | return ret; 45 | } 46 | 47 | int nvusb_detect_device(int vendid, int32_t prodid, nvDevice_t* pnvdev){ 48 | // declarations 49 | int err; 50 | libusb_device **list; 51 | libusb_device *dev = NULL; 52 | nvDevice_t nvdev; 53 | ssize_t cnt; 54 | ssize_t i = 0; 55 | int ret = 0; 56 | struct libusb_config_descriptor *config = NULL; 57 | 58 | // Code 59 | *pnvdev = NULL; 60 | libusb_init(NULL); 61 | nvdev = (nvDevice_t) malloc(sizeof(struct nvDevice)); 62 | memset(nvdev, 0, sizeof(struct nvDevice)); 63 | libusb_set_debug(NULL, 3); 64 | cnt = libusb_get_device_list(NULL, &list); 65 | if (cnt < 0) 66 | ret = -2; 67 | for (i = 0; i < cnt; i++) { 68 | libusb_device *device = list[i]; 69 | struct libusb_device_descriptor desc; 70 | libusb_get_device_descriptor(device, &desc); 71 | if (desc.idVendor == vendid && desc.idProduct == prodid) { 72 | dev = device; 73 | ret = 0; 74 | break; 75 | }else{ 76 | ret = -1; 77 | } 78 | } 79 | 80 | if(ret == 0){ 81 | err = libusb_open(dev, &nvdev->nvDeviceID); 82 | if(err) 83 | return -3; 84 | 85 | err = libusb_claim_interface(nvdev->nvDeviceID, 0); 86 | if(err) 87 | return -4; 88 | libusb_free_device_list(list, 1); 89 | nvdev->nvDeviceIDGet = libusb_get_device(nvdev->nvDeviceID); 90 | 91 | err = libusb_get_active_config_descriptor(nvdev->nvDeviceIDGet, &config); 92 | if(err) 93 | return -5; 94 | getEndpoints(config, &nvdev->nvDeviceEndpointIn, &nvdev->nvDeviceEndpointOut); 95 | memset(nvdev->remainingData, 0, USB_MINIMUM_READ_LENGTH); 96 | nvdev->remainingSize = 0; 97 | } 98 | 99 | nvdev->nvSequence = 0; 100 | nvdev->nvRecSequence = 0; 101 | *pnvdev = nvdev; 102 | 103 | return ret; 104 | } 105 | 106 | int nvusb_send(nvDevice_t nvdev, uint8_t *buffer, int32_t size){ 107 | 108 | int ret; 109 | int written; 110 | ret = libusb_bulk_transfer(nvdev->nvDeviceID, nvdev->nvDeviceEndpointOut, buffer, size, &written, 0); 111 | if(ret) 112 | printf("Error sending data (%d): %s\n", ret, libusb_error_name(ret)); 113 | // Reset buffered data if we send data 114 | nvdev->remainingSize = 0; 115 | 116 | return ret; 117 | } 118 | 119 | static int32_t nvusb_receive_internal(nvDevice_t nvdev, uint8_t *buffer, int32_t size, int32_t *read){ 120 | 121 | int ret; 122 | ret = libusb_bulk_transfer(nvdev->nvDeviceID, nvdev->nvDeviceEndpointIn, buffer, size, read, 0); 123 | 124 | return ret; 125 | } 126 | 127 | int nvusb_receive_unbuffered(nvDevice_t nvdev, uint8_t *buffer, int32_t size){ 128 | 129 | int read; 130 | int ret = nvusb_receive_internal(nvdev, buffer, size, &read); 131 | if(ret) 132 | printf("Error receiving data (%d): %s\n", ret, libusb_error_name(ret)); 133 | return ret; 134 | } 135 | 136 | int nvusb_receive(nvDevice_t nvdev, uint8_t *buffer, int32_t size){ 137 | int32_t ret, read, remaining=size; 138 | uint8_t *currBuf = buffer; 139 | uint8_t localBuf[USB_MINIMUM_READ_LENGTH]; 140 | if(size <= nvdev->remainingSize) 141 | { 142 | memcpy(currBuf, &nvdev->remainingData, size); 143 | memmove(nvdev->remainingData, &nvdev->remainingData[size], nvdev->remainingSize); 144 | nvdev->remainingSize -= size; 145 | return size; 146 | } 147 | if(nvdev->remainingSize > 0) 148 | { 149 | memcpy(currBuf, nvdev->remainingData, nvdev->remainingSize); 150 | remaining -= nvdev->remainingSize; 151 | currBuf += nvdev->remainingSize; 152 | nvdev->remainingSize = 0; 153 | } 154 | ret = nvusb_receive_internal(nvdev, localBuf, MAX(USB_MINIMUM_READ_LENGTH, remaining), &read); 155 | memcpy(currBuf, localBuf, MIN(remaining, read)); 156 | if(remaining < read) 157 | { 158 | memcpy(nvdev->remainingData, &localBuf[remaining], read-remaining); 159 | nvdev->remainingSize = read-remaining; 160 | } 161 | // Not quite correct necessarily. 162 | // We could theoretically have gotten less bytes than we asked for. 163 | return size; 164 | } 165 | 166 | void nvusb_device_close(nvDevice_t *nvdev){ 167 | 168 | libusb_release_interface((*nvdev)->nvDeviceID, 0); 169 | libusb_close((*nvdev)->nvDeviceID); 170 | libusb_exit(NULL); 171 | free(*nvdev); 172 | nvdev = NULL; 173 | return; 174 | 175 | } 176 | 177 | 178 | void nvusb_versions(){ 179 | 180 | printf("USB library version is %s and is ABI version %s\n", USB_VERSION, USB_ABI); 181 | 182 | } 183 | -------------------------------------------------------------------------------- /usb/osx/libnvusb.c: -------------------------------------------------------------------------------- 1 | /* libnvusb.c - Library for nvusb functions 2 | * 3 | * Copyright (C) 2015 androidroot.mobi 4 | * 5 | * This file is part of libnvusb. 6 | * 7 | * libnvusb is free software; you can redistribute it and/or modify it 8 | * under the terms of the GNU General Public License v2 as published by the 9 | * Free Software Foundation. 10 | * 11 | * libnvusb is distributed in the hope that it will be useful, but 12 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 14 | * more details. 15 | 16 | * You should have received a copy of the GNU General Public License along with 17 | * this program; if not, write to the Free Software Foundation, Inc., 18 | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #include 22 | #include 23 | #include 24 | #ifndef _WIN32 25 | #include 26 | #endif 27 | #include 28 | 29 | #include "config.h" 30 | #include "shared.h" 31 | #include "libnvusb.h" 32 | 33 | static int32_t getEndpoints(IOUSBInterfaceInterface **interface, uint8_t *ep_in, uint8_t *ep_out){ 34 | kern_return_t kr; 35 | UInt8 interfaceNumEndpoints; 36 | int pipeRef; 37 | 38 | kr = (*interface)->GetNumEndpoints(interface, 39 | &interfaceNumEndpoints); 40 | for (pipeRef = 1; pipeRef <= interfaceNumEndpoints; pipeRef++) 41 | { 42 | IOReturn kr2; 43 | UInt8 direction; 44 | UInt8 number; 45 | UInt8 transferType; 46 | UInt16 maxPacketSize; 47 | UInt8 interval; 48 | kr2 = (*interface)->GetPipeProperties(interface, 49 | pipeRef, &direction, 50 | &number, &transferType, 51 | &maxPacketSize, &interval); 52 | if(transferType == kUSBBulk) 53 | { 54 | if(direction == kUSBIn) 55 | *ep_in = pipeRef; 56 | if(direction == kUSBOut) 57 | *ep_out = pipeRef; 58 | } 59 | } 60 | DEBUGPRINT("Ep_In = %d, Ep_Out = %d\n", *ep_in, *ep_out); 61 | return 0; 62 | } 63 | 64 | IOUSBInterfaceInterface **FindInterface(IOUSBDeviceInterface **device) 65 | { 66 | IOUSBFindInterfaceRequest request; 67 | io_iterator_t iterator; 68 | io_service_t usbInterface; 69 | HRESULT result; 70 | IOReturn kr; 71 | IOCFPlugInInterface **plugInInterface = NULL; 72 | IOUSBInterfaceInterface **interface = NULL; 73 | SInt32 score; 74 | 75 | request.bInterfaceClass = kIOUSBFindInterfaceDontCare; 76 | request.bInterfaceSubClass = kIOUSBFindInterfaceDontCare; 77 | request.bInterfaceProtocol = kIOUSBFindInterfaceDontCare; 78 | request.bAlternateSetting = kIOUSBFindInterfaceDontCare; 79 | 80 | //Get an iterator for the interfaces on the device 81 | kr = (*device)->CreateInterfaceIterator(device, 82 | &request, &iterator); 83 | if (usbInterface = IOIteratorNext(iterator)) 84 | { 85 | //Create an intermediate plug-in 86 | kr = IOCreatePlugInInterfaceForService(usbInterface, 87 | kIOUSBInterfaceUserClientTypeID, 88 | kIOCFPlugInInterfaceID, 89 | &plugInInterface, &score); 90 | //Release the usbInterface object after getting the plug-in 91 | kr = IOObjectRelease(usbInterface); 92 | result = (*plugInInterface)->QueryInterface(plugInInterface, 93 | CFUUIDGetUUIDBytes(kIOUSBInterfaceInterfaceID), 94 | (LPVOID *) &interface); 95 | //No longer need the intermediate plug-in 96 | (*plugInInterface)->Release(plugInInterface); 97 | } 98 | return interface; 99 | } 100 | 101 | int nvusb_detect_device(int vendid, int32_t prodid, nvDevice_t* pnvdev){ 102 | // declarations 103 | int ret=0; 104 | CFMutableDictionaryRef matchingDict; 105 | CFNumberRef numberRef; 106 | kern_return_t kr; 107 | io_iterator_t gAddedIter; 108 | io_service_t usbDevice; 109 | SInt32 score; 110 | HRESULT res; 111 | 112 | *pnvdev = NULL; 113 | nvDevice_t nvdev; 114 | nvdev = (nvDevice_t) malloc(sizeof(struct nvDevice)); 115 | memset(nvdev, 0, sizeof(struct nvDevice)); 116 | 117 | matchingDict = IOServiceMatching(kIOUSBDeviceClassName); 118 | if(matchingDict == NULL) 119 | { 120 | ret = -1; 121 | goto error; 122 | } 123 | 124 | numberRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &vendid); 125 | CFDictionarySetValue(matchingDict, 126 | CFSTR(kUSBVendorID), 127 | numberRef); 128 | CFRelease(numberRef); 129 | 130 | // Create a CFNumber for the idProduct and set the value in the dictionary 131 | numberRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &prodid); 132 | CFDictionarySetValue(matchingDict, 133 | CFSTR(kUSBProductID), 134 | numberRef); 135 | CFRelease(numberRef); 136 | numberRef = NULL; 137 | 138 | kr = IOServiceGetMatchingServices(kIOMasterPortDefault, matchingDict, &gAddedIter); 139 | // We only support one apx mode device connected at a time 140 | if((usbDevice = IOIteratorNext(gAddedIter))) { 141 | IOCFPlugInInterface **plugInInterface = NULL; 142 | kr = IOCreatePlugInInterfaceForService(usbDevice, kIOUSBDeviceUserClientTypeID, kIOCFPlugInInterfaceID, 143 | &plugInInterface, &score); 144 | res = (*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID), 145 | (LPVOID*) &nvdev->deviceinterface); 146 | (*plugInInterface)->Release(plugInInterface); 147 | nvdev->interface = FindInterface(nvdev->deviceinterface); 148 | kr = IOObjectRelease(usbDevice); 149 | kr = (*nvdev->deviceinterface)->USBDeviceOpen(nvdev->deviceinterface); 150 | 151 | kr = (*nvdev->interface)->USBInterfaceOpen(nvdev->interface); 152 | getEndpoints(nvdev->interface, &nvdev->nvDeviceEndpointIn, &nvdev->nvDeviceEndpointOut); 153 | // We only use synchronous IO, so close device 154 | kr = (*nvdev->deviceinterface)->USBDeviceClose(nvdev->deviceinterface); 155 | kr = (*nvdev->deviceinterface)->Release(nvdev->deviceinterface); 156 | 157 | } 158 | IOObjectRelease(gAddedIter); 159 | if(nvdev->deviceinterface == NULL || nvdev->interface == NULL) 160 | { 161 | ret = -1; 162 | goto error; 163 | } 164 | memset(nvdev->remainingData, 0, USB_MINIMUM_READ_LENGTH); 165 | nvdev->remainingSize = 0; 166 | 167 | nvdev->nvSequence = 0; 168 | nvdev->nvRecSequence = 0; 169 | 170 | *pnvdev = nvdev; 171 | 172 | goto exit; 173 | 174 | error: 175 | free(nvdev); 176 | *pnvdev = NULL; 177 | 178 | exit: 179 | return ret; 180 | } 181 | 182 | int nvusb_send(nvDevice_t nvdev, uint8_t *buffer, int32_t size){ 183 | 184 | int ret=0; 185 | int written; 186 | IOUSBInterfaceInterface **interface = (IOUSBInterfaceInterface**)nvdev->interface; 187 | DEBUGPRINT("Writing %d bytes to endpoint %d\n", size, nvdev->nvDeviceEndpointOut); 188 | ret = (*interface)->WritePipe(interface, nvdev->nvDeviceEndpointOut, buffer, size); 189 | DEBUGPRINT("Result %d\n", ret); 190 | // Reset buffered data if we send data 191 | nvdev->remainingSize = 0; 192 | 193 | return ret; 194 | } 195 | 196 | static int32_t nvusb_receive_internal(nvDevice_t nvdev, uint8_t *buffer, int32_t size, int32_t *read){ 197 | int ret=0; 198 | IOUSBInterfaceInterface **interface = (IOUSBInterfaceInterface**)nvdev->interface; 199 | *read = size; 200 | (*interface)->ReadPipe(interface, nvdev->nvDeviceEndpointIn, buffer, (UInt32*)read); 201 | return ret; 202 | } 203 | 204 | int nvusb_receive_unbuffered(nvDevice_t nvdev, uint8_t *buffer, int32_t size){ 205 | 206 | int read; 207 | return nvusb_receive_internal(nvdev, buffer, size, &read); 208 | } 209 | 210 | int nvusb_receive(nvDevice_t nvdev, uint8_t *buffer, int32_t size){ 211 | int32_t ret, read, remaining=size; 212 | uint8_t *currBuf = buffer; 213 | uint8_t localBuf[USB_MINIMUM_READ_LENGTH]; 214 | if(size <= nvdev->remainingSize) 215 | { 216 | memcpy(currBuf, &nvdev->remainingData, size); 217 | memmove(nvdev->remainingData, &nvdev->remainingData[size], nvdev->remainingSize); 218 | nvdev->remainingSize -= size; 219 | return size; 220 | } 221 | if(nvdev->remainingSize > 0) 222 | { 223 | memcpy(currBuf, nvdev->remainingData, nvdev->remainingSize); 224 | remaining -= nvdev->remainingSize; 225 | currBuf += nvdev->remainingSize; 226 | nvdev->remainingSize = 0; 227 | } 228 | ret = nvusb_receive_internal(nvdev, localBuf, MAX(USB_MINIMUM_READ_LENGTH, remaining), &read); 229 | memcpy(currBuf, localBuf, MIN(remaining, read)); 230 | if(remaining < read) 231 | { 232 | memcpy(nvdev->remainingData, &localBuf[remaining], read-remaining); 233 | nvdev->remainingSize = read-remaining; 234 | } 235 | // Not quite correct necessarily. 236 | // We could theoretically have gotten less bytes than we asked for. 237 | return size; 238 | } 239 | 240 | void nvusb_device_close(nvDevice_t *nvdev){ 241 | 242 | return; 243 | 244 | } 245 | 246 | 247 | void nvusb_versions(){ 248 | 249 | printf("USB library version is %s and is ABI version %s\n", USB_VERSION, USB_ABI); 250 | 251 | } 252 | -------------------------------------------------------------------------------- /usb/win32/libnvusb.c: -------------------------------------------------------------------------------- 1 | /* libnvusb.c - Library for nvusb functions 2 | * 3 | * Copyright (C) 2015 androidroot.mobi 4 | * 5 | * This file is part of libnvusb. 6 | * 7 | * libnvusb is free software; you can redistribute it and/or modify it 8 | * under the terms of the GNU General Public License v2 as published by the 9 | * Free Software Foundation. 10 | * 11 | * libnvusb is distributed in the hope that it will be useful, but 12 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 14 | * more details. 15 | 16 | * You should have received a copy of the GNU General Public License along with 17 | * this program; if not, write to the Free Software Foundation, Inc., 18 | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | #define WIN32_LEAN_AND_MEAN 21 | 22 | #include 23 | #include 24 | #include 25 | #ifndef _WIN32 26 | #include 27 | #endif 28 | 29 | #include "config.h" 30 | #include "shared.h" 31 | 32 | 33 | // Include Windows headers 34 | #include 35 | #include 36 | #include 37 | #include 38 | 39 | // Include WinUSB headers 40 | #include 41 | #include 42 | #include 43 | #include "libnvusb.h" 44 | //{36fc9e60-c465-11cf-8056-444553540000} 45 | static const GUID GUID_CLASS_APX = {0x36fc9e60L, 0xc465, 0x11cf, {0x80, 0x56, 0x36, 0xE6, 0xD7, 0x20, 0x46, 0x00}}; 46 | static const GUID GUID_DEVINTERFACE_APX = {0xEAD8C4F6L, 0x6102, 0x45c7, {0xAA, 0x66, 0x36, 0xE6, 0xD7, 0x20, 0x46, 0x00}}; 47 | 48 | static int32_t getEndpoints(WINUSB_INTERFACE_HANDLE hDeviceHandle, uint8_t *ep_in, uint8_t *ep_out){ 49 | int32_t i; 50 | int32_t ret=-2; 51 | USB_INTERFACE_DESCRIPTOR InterfaceDescriptor; 52 | WINUSB_PIPE_INFORMATION Pipe; 53 | 54 | memset(&InterfaceDescriptor, 0, sizeof(USB_INTERFACE_DESCRIPTOR)); 55 | memset(&Pipe, 0, sizeof(WINUSB_PIPE_INFORMATION)); 56 | 57 | ret = WinUsb_QueryInterfaceSettings(hDeviceHandle, 0, &InterfaceDescriptor); 58 | 59 | if (ret) 60 | { 61 | for (i = 0; i < InterfaceDescriptor.bNumEndpoints; i++) 62 | { 63 | ret = WinUsb_QueryPipe(hDeviceHandle, 0, i, &Pipe); 64 | 65 | if (ret) 66 | { 67 | if (Pipe.PipeType == UsbdPipeTypeBulk) 68 | { 69 | if (USB_ENDPOINT_DIRECTION_IN(Pipe.PipeId)) 70 | { 71 | DEBUGPRINT("Endpoint index: %d Pipe type: Bulk Pipe ID: %c.\n", i, Pipe.PipeType, Pipe.PipeId); 72 | *ep_in = Pipe.PipeId; 73 | } 74 | if (USB_ENDPOINT_DIRECTION_OUT(Pipe.PipeId)) 75 | { 76 | DEBUGPRINT("Endpoint index: %d Pipe type: Bulk Pipe ID: %c.\n", i, Pipe.PipeType, Pipe.PipeId); 77 | *ep_out = Pipe.PipeId; 78 | } 79 | } 80 | } 81 | else 82 | { 83 | continue; 84 | } 85 | } 86 | } 87 | return ret; 88 | } 89 | 90 | static char* getDevicePath(const GUID* guid) 91 | { 92 | char * ret = NULL; 93 | int i; 94 | SP_DEVICE_INTERFACE_DATA currentInterface; 95 | HDEVINFO devices; 96 | devices = SetupDiGetClassDevs(guid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); 97 | if(devices == INVALID_HANDLE_VALUE) { 98 | return NULL; 99 | } 100 | 101 | currentInterface.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); 102 | for(i = 0; SetupDiEnumDeviceInterfaces(devices, NULL, &GUID_DEVINTERFACE_APX, i, ¤tInterface); i++) { 103 | DWORD requiredSize = 0; 104 | PSP_DEVICE_INTERFACE_DETAIL_DATA details; 105 | SetupDiGetDeviceInterfaceDetail(devices, ¤tInterface, NULL, 0, &requiredSize, NULL); 106 | details = (PSP_DEVICE_INTERFACE_DETAIL_DATA) malloc(requiredSize); 107 | details->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); 108 | if(!SetupDiGetDeviceInterfaceDetail(devices, ¤tInterface, details, requiredSize, NULL, NULL)) { 109 | free(details); 110 | break; 111 | } else { 112 | char* result = (char *) malloc(requiredSize); 113 | char* pathEnd = NULL; 114 | memcpy((void*) result, details->DevicePath, requiredSize); 115 | ret=0; 116 | free(details); 117 | ret = result; 118 | break; 119 | 120 | } 121 | } 122 | SetupDiDestroyDeviceInfoList(devices); 123 | return ret; 124 | } 125 | 126 | int nvusb_detect_device(int vendid, int32_t prodid, nvDevice_t* pnvdev){ 127 | // declarations 128 | int ret=-1,i; 129 | char * nvAPXPath; 130 | 131 | nvDevice_t nvdev = (nvDevice_t)malloc(sizeof(struct nvDevice)); 132 | memset(nvdev, 0, sizeof(struct nvDevice)); 133 | 134 | nvAPXPath = getDevicePath(&GUID_DEVINTERFACE_APX); 135 | if(nvAPXPath == NULL) 136 | { 137 | DEBUGPRINT("Error getting devicePath: %d\n", ret); 138 | return -1; 139 | } 140 | 141 | nvdev->nvAPX = CreateFile(nvAPXPath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); 142 | if(nvdev->nvAPX == INVALID_HANDLE_VALUE) 143 | { 144 | DEBUGPRINT("Error %d.", GetLastError()); 145 | free(nvAPXPath); 146 | return -2; 147 | } 148 | free(nvAPXPath); 149 | ret = WinUsb_Initialize(nvdev->nvAPX, &nvdev->nvWinUSBAPX); 150 | if(!ret) 151 | { 152 | DEBUGPRINT("Error %d.", GetLastError()); 153 | CloseHandle(nvdev->nvAPX); 154 | return -3; 155 | } 156 | 157 | getEndpoints(nvdev->nvWinUSBAPX, &nvdev->nvDeviceEndpointIn, &nvdev->nvDeviceEndpointOut); 158 | 159 | *pnvdev = nvdev; 160 | return ret; 161 | } 162 | 163 | int nvusb_send(nvDevice_t nvdev, uint8_t *buffer, int32_t size){ 164 | 165 | int ret=-1; 166 | ULONG written=0; 167 | 168 | ret = WinUsb_WritePipe(nvdev->nvWinUSBAPX, nvdev->nvDeviceEndpointOut, buffer, size, &written, NULL); 169 | if(!ret) 170 | { 171 | DEBUGPRINT("Error writing data %d\n", GetLastError()); 172 | return -1; 173 | } 174 | // Reset buffered data if we send data 175 | nvdev->remainingSize = 0; 176 | 177 | return 0; 178 | } 179 | 180 | static int32_t nvusb_receive_internal(nvDevice_t nvdev, uint8_t *buffer, int32_t size, int32_t *read){ 181 | int ret=-1; 182 | ULONG readdata=0; 183 | ret = WinUsb_ReadPipe(nvdev->nvWinUSBAPX, nvdev->nvDeviceEndpointIn, buffer, size, &readdata, NULL); 184 | if(!ret) 185 | { 186 | int err = GetLastError(); 187 | DEBUGPRINT("Error reading data %d\n", err); 188 | switch(err) 189 | { 190 | case ERROR_INVALID_HANDLE: 191 | DEBUGPRINT("ERROR_INVALID_HANDLE\n"); 192 | break; 193 | case ERROR_IO_PENDING: 194 | DEBUGPRINT("ERROR_IO_PENDING\n"); 195 | break; 196 | case ERROR_NOT_ENOUGH_MEMORY: 197 | DEBUGPRINT("ERROR_NOT_ENOUGH_MEMORY\n"); 198 | break; 199 | case ERROR_SEM_TIMEOUT: 200 | DEBUGPRINT("ERROR_SEM_TIMEOUT\n"); 201 | break; 202 | default: 203 | DEBUGPRINT("Uknown error!\n"); 204 | break; 205 | } 206 | return -1; 207 | } 208 | *read = (int32_t)readdata; 209 | return 0; 210 | } 211 | 212 | int nvusb_receive_unbuffered(nvDevice_t nvdev, uint8_t *buffer, int32_t size){ 213 | 214 | int read; 215 | // Reset buffered data if we receive unbuffered.s 216 | nvdev->remainingSize = 0; 217 | return nvusb_receive_internal(nvdev, buffer, size, &read); 218 | } 219 | 220 | int nvusb_receive(nvDevice_t nvdev, uint8_t *buffer, int32_t size){ 221 | int32_t ret, read, remaining=size; 222 | uint8_t *currBuf = buffer; 223 | uint8_t localBuf[USB_MINIMUM_READ_LENGTH]; 224 | if(size <= nvdev->remainingSize) 225 | { 226 | memcpy(currBuf, &nvdev->remainingData, size); 227 | memmove(nvdev->remainingData, &nvdev->remainingData[size], nvdev->remainingSize); 228 | nvdev->remainingSize -= size; 229 | return size; 230 | } 231 | if(nvdev->remainingSize > 0) 232 | { 233 | memcpy(currBuf, nvdev->remainingData, nvdev->remainingSize); 234 | remaining -= nvdev->remainingSize; 235 | currBuf += nvdev->remainingSize; 236 | nvdev->remainingSize = 0; 237 | } 238 | ret = nvusb_receive_internal(nvdev, localBuf, MAX(USB_MINIMUM_READ_LENGTH, remaining), &read); 239 | memcpy(currBuf, localBuf, MIN(remaining, read)); 240 | if(remaining < read) 241 | { 242 | memcpy(nvdev->remainingData, &localBuf[remaining], read-remaining); 243 | nvdev->remainingSize = read-remaining; 244 | } 245 | // Not quite correct necessarily. 246 | // We could theoretically have gotten less bytes than we asked for. 247 | return size; 248 | } 249 | 250 | void nvusb_device_close(nvDevice_t *nvdev){ 251 | WinUsb_Free((*nvdev)->nvWinUSBAPX); 252 | CloseHandle((*nvdev)->nvAPX); 253 | free(*nvdev); 254 | nvdev = NULL; 255 | return; 256 | 257 | } 258 | 259 | 260 | void nvusb_versions(){ 261 | 262 | printf("USB library version is %s and is ABI version %s\n", USB_VERSION, USB_ABI); 263 | 264 | } 265 | -------------------------------------------------------------------------------- /wheelie.c: -------------------------------------------------------------------------------- 1 | /* wheelie.c - Preflight for nvflash 2 | * 3 | * Copyright (C) 2015 androidroot.mobi 4 | * 5 | * This file is part of Wheelie. 6 | * 7 | * Wheelie is free software; you can redistribute it and/or modify it 8 | * under the terms of the GNU General Public License v2 as published by the 9 | * Free Software Foundation. 10 | * 11 | * Wheelie is distributed in the hope that it will be useful, but 12 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 14 | * more details. 15 | 16 | * You should have received a copy of the GNU General Public License along with 17 | * this program; if not, write to the Free Software Foundation, Inc., 18 | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #include 22 | #include 23 | #include 24 | #ifndef _WIN32 25 | #include 26 | #endif 27 | #include 28 | #include 29 | 30 | /* Includes for wheelie functions and payloads */ 31 | 32 | #include "config.h" 33 | #include "shared.h" 34 | #include "wheelie.h" 35 | #include "libnv3p.h" 36 | #include "libnvfblob.h" 37 | 38 | #define VENDOR_ID 0x955 39 | #define TEGRA2_PRODUCT_ID 0x7820 40 | #define TEGRA33_PRODUCT_ID 0x7330 41 | #define TEGRA30_PRODUCT_ID 0x7030 42 | 43 | static void usage() { 44 | printf("Usage: wheelie --blob \n\n"); 45 | printf("Argument Description\n\n"); 46 | printf("-v or --version Display version information\n"); 47 | printf("-h or --help Display this menu\n"); 48 | printf("-b or --blob Specify blob file to use\n"); 49 | printf("-U or --unbrick Flash bricksafe image\n"); 50 | exit(0); 51 | } 52 | 53 | void file_transfer_cb(size_t transferred, size_t total){ 54 | size_t percent = (size_t)(((float)transferred/(float)total)*100.0); 55 | printf("\rSending file: %lu %%", (unsigned long)percent); 56 | if(transferred == total) 57 | printf("\n"); 58 | } 59 | 60 | int main(int argc, char * const* argv) { 61 | int32_t device = -1; 62 | int32_t ret; 63 | uint64_t chipuid_rcm; 64 | nvDevice_t nvdev; 65 | uint8_t *buf ,*blptr; 66 | size_t bufsize, bricksafe_size; 67 | uint32_t rawsize; 68 | char *blobfile = NULL; 69 | char *bricksafe = NULL; 70 | nv3p_blargs blargs; 71 | nv3p_rawargs rawargs; 72 | uint64_t responsedata = -1; 73 | uint32_t response = (uint32_t)responsedata; 74 | int32_t c; 75 | uint8_t r_data[NV3P_COMMAND_GETINFO_LEN]; 76 | int32_t status; 77 | int32_t recovery_mode = 0; 78 | int32_t upload_bricksafe = 0; 79 | nv3p_platinfo *platform; 80 | char* cpu_type; 81 | nvfblob_file_t blob; 82 | 83 | setbuf(stdout, NULL); 84 | 85 | printf("Wheelie %s - Preflight for nvflash.\n", WHEELIE_VERSION); 86 | printf("Copyright (c) 2011-2012 androidroot.mobi\n"); 87 | printf("========================================\n\n"); 88 | 89 | while (1) 90 | { 91 | static struct option long_options[] = { 92 | {"version", no_argument, 0, 'v'}, 93 | {"help", no_argument, 0, 'h'}, 94 | {"blob", required_argument, 0, 'b'}, 95 | {"recovery", required_argument, 0, 'r'}, 96 | {"unbrick", required_argument, 0, 'U'}, 97 | {0, 0, 0, 0} 98 | }; 99 | 100 | int32_t option_index = 0; 101 | 102 | c = -1; 103 | c = getopt_long (argc, argv, "vhb:rU:", 104 | long_options, &option_index); 105 | 106 | if (c == -1) break; 107 | 108 | switch(c) { 109 | 110 | case 'v': 111 | printf("Wheelie version is %s\n", WHEELIE_VERSION); 112 | nvusb_versions(); 113 | printf("Nv3P library version is %s and is ABI version %s\n\n", NV3P_VERSION, NV3P_ABI); 114 | exit(0); 115 | 116 | case 'h': 117 | usage(); 118 | break; 119 | 120 | case 'b': 121 | blobfile = optarg; 122 | break; 123 | 124 | case 'r': 125 | recovery_mode = 1; 126 | break; 127 | 128 | case 'U': 129 | /* Unbricking implies recovery */ 130 | recovery_mode = 1; 131 | upload_bricksafe = 1; 132 | bricksafe = optarg; 133 | break; 134 | 135 | case '?': 136 | if (isprint(optopt)) 137 | usage(); 138 | else 139 | usage(); 140 | return 1; 141 | 142 | default: 143 | abort(); 144 | } 145 | } 146 | 147 | if(!blobfile) { 148 | printf("[-] You must specify --blob.\n"); 149 | exit(0); 150 | } 151 | 152 | if(!(blob = nvfblob_open(blobfile))) { 153 | printf("[-] Failed to open blob file: %s\n", blobfile); 154 | exit(0); 155 | } 156 | 157 | printf("Waiting for device in APX mode...\n"); 158 | while(device < 0) { 159 | device = nvusb_detect_device(VENDOR_ID, TEGRA2_PRODUCT_ID, &nvdev); 160 | usleep(250000); 161 | if(device >= 0) break; 162 | device = nvusb_detect_device(VENDOR_ID, TEGRA33_PRODUCT_ID, &nvdev); 163 | usleep(250000); 164 | if(device >= 0) break; 165 | device = nvusb_detect_device(VENDOR_ID, TEGRA30_PRODUCT_ID, &nvdev); 166 | usleep(250000); 167 | } 168 | 169 | // Receive chipuid - first thing sent after poweron in APX mode. 170 | // We have to receive the exact number of bytes RCM sends 171 | // Sadly, we have no clue what the second value means. 172 | nvusb_receive_unbuffered(nvdev, (uint8_t*)&chipuid_rcm, sizeof(uint64_t)); 173 | printf("[=] Chip UID: 0x%llx\n", (unsigned long long)chipuid_rcm); 174 | DEBUGPRINT("Asking for Rcm version\n"); 175 | 176 | if(!nvfblob_alloc_read(blob, NVFBLOB_TYPE_RCMVER, &buf, &bufsize)){ 177 | printf("[-] Failed to read RCMVERS from blob file.\n"); 178 | exit(0); 179 | } 180 | 181 | if(nvusb_send(nvdev, buf, bufsize) != 0) { 182 | 183 | printf("[-] RCM_Send communication failure.\n"); 184 | exit(0); 185 | } 186 | 187 | nvfblob_alloc_free(&buf); 188 | 189 | if(nvusb_receive_unbuffered(nvdev, (uint8_t*)&responsedata, 8) != 0) { 190 | 191 | printf("[-] RCM_Receive communication failure.\n"); 192 | exit(0); 193 | } 194 | response = (uint32_t)responsedata; 195 | 196 | if(response != 0x20001 && response != 0x30001) { 197 | if(response == 0x4) { 198 | printf("[-] Incorrect BLOB selected. nverror: 0x%x.\n", response); 199 | exit(0); 200 | } else { 201 | printf("[-] Unknown error or incorrect RCM protocol version. nverror: 0x%x.\n", response); 202 | exit(0); 203 | } 204 | } 205 | 206 | printf("[=] RCM Version: 0x%x\n\n", response); 207 | 208 | if(!nvfblob_alloc_read(blob, NVFBLOB_TYPE_RCMDLEXEC, 209 | &buf, &bufsize)) { 210 | printf("[-] Failed to read RCMDLEXEC message from blob file.\n"); 211 | exit(0); 212 | } 213 | 214 | DEBUGPRINT("Sending buf\n"); 215 | if(nvusb_send(nvdev, (uint8_t*)buf, bufsize) != 0) { 216 | 217 | printf("[-] RCM_Send communication failure.\n"); 218 | exit(0); 219 | } 220 | 221 | nvfblob_alloc_free(&buf); 222 | 223 | DEBUGPRINT("Receiving response\n"); 224 | if(nvusb_receive_unbuffered(nvdev, (uint8_t*)&responsedata, sizeof(uint64_t)) != 0) { 225 | 226 | printf("[-] RCM_Receive communication failure.\n"); 227 | exit(0); 228 | } 229 | response = (uint32_t)responsedata; 230 | DEBUGPRINT("Got response 0x%x\n", response); 231 | if(response != 0x0) { 232 | 233 | printf("[-] Miniloader upload failed with error: 0x%x.\n", response); 234 | exit(0); 235 | } 236 | 237 | DEBUGPRINT("Sending getinfo command\n"); 238 | ret = nv3p_send_command(nvdev, NV3P_COMMAND_GETINFO, NULL); 239 | if(ret != 0){ 240 | printf("[-] Error %d sending command\n", ret); 241 | exit(0); 242 | } 243 | 244 | 245 | ret = nv3p_command_response(nvdev, NV3P_COMMAND_GETINFO, r_data); 246 | if(ret != 0){ 247 | printf("[-] Error %d receiving response from command\n", ret); 248 | exit(0); 249 | } 250 | status = nv3p_wait_status(nvdev); 251 | platform = (nv3p_platinfo*)r_data; 252 | 253 | if(platform->chipid.id == 0x20){ 254 | cpu_type = "Tegra 2"; 255 | blargs.loadaddr = 0x108000; 256 | blargs.entry = blargs.loadaddr; 257 | }else if(platform->chipid.id == 0x30){ 258 | cpu_type = "Tegra 3"; 259 | blargs.loadaddr = 0x80108000; 260 | blargs.entry = blargs.loadaddr; 261 | //nv3p_set_ics_protocol(1); 262 | }else{ 263 | cpu_type = "Unknown"; 264 | } 265 | 266 | /* if(chipuid_rcm != platform->chipuid){ 267 | printf("[-] Data returned was invalid\n"); 268 | exit(0); 269 | }*/ 270 | 271 | if(!strcmp(cpu_type, "Unknown")){ 272 | printf("[-] CPU type 0x%x is unknown\n", platform->chipid.id); 273 | exit(0); 274 | } 275 | 276 | printf("[=] CPU Model: %s\n", cpu_type); 277 | if(platform->chipid.id == 0x20 || recovery_mode) 278 | { 279 | if(!nvfblob_alloc_read(blob, NVFBLOB_TYPE_EXT_WHEELIE_BCTR, 280 | &buf, &bufsize)) { 281 | printf("[-] Failed to read (recovery) BCT from blob file.\n"); 282 | exit(0); 283 | } 284 | 285 | // Send BCT 286 | printf("[+] Sending BCT\n"); 287 | ret = nv3p_send_command(nvdev, NV3P_COMMAND_SENDBCT,(uint8_t*)&bufsize); 288 | DEBUGPRINT("nv3p_send_command (BCT) returned %d\n", ret); 289 | DEBUGPRINT("Sending BCT with size %lu\n", bufsize); 290 | ret = nv3p_send_buffer(nvdev, buf, bufsize, &file_transfer_cb); 291 | status = nv3p_wait_status(nvdev); 292 | DEBUGPRINT("Sent BCT with result: %d\n", status); 293 | 294 | nvfblob_alloc_free(&buf); 295 | 296 | if(!nvfblob_alloc_read(blob, NVFBLOB_TYPE_EXT_WHEELIE_ODMDATA, 297 | &buf, &bufsize)) { 298 | printf("[-] Failed to read ODMDATA from blob file.\n"); 299 | exit(0); 300 | } 301 | 302 | printf("[+] Sending ODMData 0x%X\n", (uint32_t)*buf); 303 | nv3p_send_command(nvdev, NV3P_COMMAND_SENDODM, (uint8_t*)&buf); 304 | DEBUGPRINT("Waiting for result...\n"); 305 | status = nv3p_wait_status(nvdev); 306 | DEBUGPRINT("Sent ODM with result: %d\n", status); 307 | 308 | nvfblob_alloc_free(&buf); 309 | } 310 | 311 | if(!nvfblob_alloc_read(blob, NVFBLOB_TYPE_EXT_WHEELIE_BL, &blptr, 312 | &blargs.filesize)) { 313 | printf("[-] Failed to read BL from blob file.\n"); 314 | exit(0); 315 | } 316 | 317 | printf("[+] Sending bootloader...\n"); 318 | DEBUGPRINT("Sending uploadbl command\n"); 319 | ret = nv3p_send_command(nvdev, NV3P_COMMAND_SENDBL, (uint8_t*)&blargs); 320 | if(ret != 0){ 321 | printf("[-] Error %d sending command\n", ret); 322 | exit(0); 323 | } 324 | status = nv3p_wait_status(nvdev); 325 | 326 | if(platform->chipid.id == 0x30) { 327 | DEBUGPRINT("Reading blhash\n"); 328 | if(!nvfblob_alloc_read(blob, NVFBLOB_TYPE_BLHASH, &buf, 329 | &bufsize)) { 330 | printf("[-] Failed to read BLHash from blob file.\n"); 331 | exit(0); 332 | } 333 | DEBUGPRINT("Sending BLHash\n"); 334 | ret = nv3p_send_buffer(nvdev, buf, bufsize, NULL); 335 | if(ret != 1) { 336 | printf("[-] Failed sending BLHash\n"); 337 | exit(0); 338 | } 339 | 340 | nvfblob_alloc_free(&buf); 341 | } 342 | 343 | 344 | DEBUGPRINT("Sending bootloader file (size=%llu)\n", blargs.filesize); 345 | 346 | ret = nv3p_send_buffer(nvdev, blptr, blargs.filesize, &file_transfer_cb); 347 | status = nv3p_wait_status(nvdev); 348 | DEBUGPRINT("Sent bootloader with result: %d\n", status); 349 | 350 | nvfblob_alloc_free(&blptr); 351 | 352 | /* Receive sequence needs to be reset after changing from miniloader 353 | * to bootloader nv3p server. For some reason they seem to keep seperate 354 | * packet counters */ 355 | nvdev->nvRecSequence = 1; 356 | 357 | if(upload_bricksafe == 1) 358 | { 359 | DEBUGPRINT("Sending Bricksafe image\n") 360 | printf("[+] Sending bricksafe image\n"); 361 | if(filetest(bricksafe, &bufsize) == 0) 362 | { 363 | printf("[-] Error %s not found\n", bricksafe); 364 | exit(0); 365 | } else if(bufsize == 0) { 366 | printf("[-] Error: Read bricksafe image as 0 bytes!\n"); 367 | exit(0); 368 | } 369 | 370 | bricksafe_size = bufsize; 371 | 372 | /* We need to tell the bootloader where to start, and how many 373 | * sectors the raw write should be.*/ 374 | rawargs.start = 0; 375 | rawargs.size = 2944; 376 | 377 | ret = nv3p_send_command(nvdev, NV3P_COMMAND_RAWWRITE, (uint8_t*)&rawargs); 378 | if(ret != 0) 379 | { 380 | printf("[-] Error %d sending command\n", ret); 381 | exit(0); 382 | } 383 | 384 | ret = nv3p_command_response(nvdev, NV3P_COMMAND_RAWWRITE, (uint8_t*)&rawsize); 385 | if(ret != 0) 386 | { 387 | printf("[-] Error %d receiving response from command\n", ret); 388 | exit(0); 389 | } 390 | 391 | if(rawsize > (uint32_t)bricksafe_size) 392 | { 393 | printf("[-] Error %d is smaller than required: %d\n", 394 | (uint32_t)bricksafe_size, rawsize); 395 | exit(0); 396 | } 397 | 398 | ret = nv3p_send_file(nvdev, bricksafe, rawsize, &file_transfer_cb); 399 | if(ret != 1) 400 | { 401 | printf("[-] Error %d sending file\n", ret); 402 | exit(0); 403 | } 404 | 405 | status = nv3p_wait_status(nvdev); 406 | 407 | printf("[!] Done - restart your device now\n"); 408 | } else { 409 | DEBUGPRINT("Sending sync command\n"); 410 | ret = nv3p_send_command(nvdev, NV3P_COMMAND_SYNCRONIZE, NULL); 411 | if(ret < 0) { 412 | printf("[-] Error %d sending command\n", ret); 413 | exit(0); 414 | } else if(ret > 0) { 415 | printf("[*] Warning - unexpected response to sync command: %d\n", 416 | ret); 417 | } 418 | 419 | status = nv3p_wait_status(nvdev); 420 | DEBUGPRINT("Send sync with result: %d\n", status); 421 | 422 | printf("[!] Done - your device should now be ready for nvflash\n"); 423 | } 424 | 425 | nvusb_device_close(&nvdev); 426 | exit(0); 427 | } 428 | --------------------------------------------------------------------------------