diff --git a/.gitattributes b/.gitattributes index 97283bde..398a2312 100644 --- a/.gitattributes +++ b/.gitattributes @@ -8,6 +8,9 @@ *.inf.in eol=crlf *.rc eol=crlf *.def eol=crlf +*.creole export-ignore .gitattributes export-ignore .gitignore export-ignore -*.creole export-ignore \ No newline at end of file +_*.sh export-ignore +_*.cmd export-ignore +appveyor.yml export-ignore diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 00000000..667c0a85 --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,73 @@ +name: CodeQL + +on: + push: + paths-ignore: + - '.gitignore' + - '.gitattributes' + - '**.cmd' + - '**.md' + - 'AUTHORS' + - 'NEWS' + - 'ChangeLog' + pull_request: + paths-ignore: + - '.gitignore' + - '.gitattributes' + - '**.cmd' + - '**.md' + - 'AUTHORS' + - 'NEWS' + - 'ChangeLog' + +env: + WDK_URL: https://go.microsoft.com/fwlink/p/?LinkID=253170 + LIBUSB0_URL: https://github.com/mcuee/libusb-win32/releases/download/release_1.4.0.0/libusb-win32-bin-1.4.0.0.zip + LIBUSBK_URL: https://github.com/mcuee/libusbk/releases/download/V3.1.0.0/libusbK-3.1.0.0-bin.7z + SOLUTION_FILE_PATH: ./libwdi.sln + TARGET_PLATFORM: x64 + BUILD_CONFIGURATION: Debug + BUILD_MACROS: '"WDK_DIR=\"../wdk/Windows Kits/8.0\";LIBUSB0_DIR=\"../libusb0\";LIBUSBK_DIR=\"../libusbk/bin\""' + +jobs: + CodeQL-Build: + runs-on: windows-latest + + permissions: + security-events: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + submodules: recursive + + - name: Download support files + shell: cmd + run: | + curl -L ${{ env.WDK_URL }} -o wdk-redist.msi + curl -L ${{ env.LIBUSB0_URL }} -o libusb0-redist.zip + curl -L ${{ env.LIBUSBK_URL }} -o libusbk-redist.7z + msiexec /a wdk-redist.msi /qn TARGETDIR=%CD%\wdk + 7z x libusb0-redist.zip + 7z x libusbk-redist.7z + del *.zip + del *.7z + move libusb-win32* libusb0 + move libusbK* libusbk + + - name: Initialize CodeQL + uses: github/codeql-action/init@v3 + with: + languages: cpp + + - name: Add MSBuild to PATH + uses: microsoft/setup-msbuild@v2 + + - name: Build + shell: cmd + run: msbuild ${{ env.SOLUTION_FILE_PATH }} /m /p:Configuration=${{ env.BUILD_CONFIGURATION}},Platform=${{ env.TARGET_PLATFORM }},BuildMacros=${{ env.BUILD_MACROS }} + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v3 diff --git a/.github/workflows/coverity.yml b/.github/workflows/coverity.yml new file mode 100644 index 00000000..a12ea6bb --- /dev/null +++ b/.github/workflows/coverity.yml @@ -0,0 +1,64 @@ +name: Coverity + +on: + push: + paths-ignore: + - '.gitignore' + - '.gitattributes' + - '**.cmd' + - '**.md' + - 'AUTHORS' + - 'NEWS' + - 'ChangeLog' + +env: + WDK_URL: https://go.microsoft.com/fwlink/p/?LinkID=253170 + LIBUSB0_URL: https://github.com/mcuee/libusb-win32/releases/download/release_1.4.0.0/libusb-win32-bin-1.4.0.0.zip + LIBUSBK_URL: https://github.com/mcuee/libusbk/releases/download/V3.1.0.0/libusbK-3.1.0.0-bin.7z + SOLUTION_FILE_PATH: ./libwdi.sln + EMAIL: pete@akeo.ie + BUILD_MACROS: '"WDK_DIR=\"../wdk/Windows Kits/8.0\";LIBUSB0_DIR=\"../libusb0\";LIBUSBK_DIR=\"../libusbk/bin\""' + +jobs: + Coverity-Build: + runs-on: windows-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + submodules: recursive + - name: Download Coverity + run: | + curl -d "token=${{ secrets.COVERITY_SCAN_TOKEN }}&project=pbatard%2Flibwdi" -L https://scan.coverity.com/download/cxx/win64 -o cov-analysis-win64.zip + 7z x cov-analysis-win64.zip + del cov-analysis-win64.zip + move cov-analysis-win64* cov-analysis-win64 + - name: Add Coverity to PATH + shell: bash + run: echo "${{ github.workspace }}/cov-analysis-win64/bin" >> $GITHUB_PATH + - name: Download support files + shell: cmd + run: | + curl -L ${{ env.WDK_URL }} -o wdk-redist.msi + curl -L ${{ env.LIBUSB0_URL }} -o libusb0-redist.zip + curl -L ${{ env.LIBUSBK_URL }} -o libusbk-redist.7z + msiexec /a wdk-redist.msi /qn TARGETDIR=%CD%\wdk + 7z x libusb0-redist.zip + 7z x libusbk-redist.7z + del *.zip + del *.7z + move libusb-win32* libusb0 + move libusbK* libusbk + - name: Add MSBuild to PATH + uses: microsoft/setup-msbuild@v2 + - name: Build with Coverity + shell: cmd + run: | + cov-configure --msvc + cov-build.exe --dir cov-int msbuild ${{ env.SOLUTION_FILE_PATH }} /m /p:Configuration=Release,Platform=x64,BuildMacros=${{ env.BUILD_MACROS }} + - name: Upload Coverity build for analysis + run: | + 7z a -r cov-int.zip cov-int + curl --form email=${{ env.EMAIL }} --form token=${{ secrets.COVERITY_SCAN_TOKEN }} --form file=@cov-int.zip --form version="${{ env.GITHUB_SHA }}" --form description="libwdi" https://scan.coverity.com/builds?project=pbatard%2Flibwdi diff --git a/.github/workflows/mingw.yml b/.github/workflows/mingw.yml new file mode 100644 index 00000000..cee6030d --- /dev/null +++ b/.github/workflows/mingw.yml @@ -0,0 +1,100 @@ +name: MinGW + +on: + push: + paths-ignore: + - '.gitignore' + - '.gitattributes' + - '**.cmd' + - '**.md' + - 'AUTHORS' + - 'NEWS' + - 'ChangeLog' + pull_request: + paths-ignore: + - '.gitignore' + - '.gitattributes' + - '**.cmd' + - '**.md' + - 'AUTHORS' + - 'NEWS' + - 'ChangeLog' + +env: + WDK_URL: https://go.microsoft.com/fwlink/p/?LinkID=253170 + LIBUSB0_URL: https://github.com/mcuee/libusb-win32/releases/download/release_1.4.0.0/libusb-win32-bin-1.4.0.0.zip + LIBUSBK_URL: https://github.com/mcuee/libusbk/releases/download/V3.1.0.0/libusbK-3.1.0.0-bin.7z + BUILD_OPTIONS: '--enable-toggable-debug --enable-examples-build --disable-debug --disable-shared' + DRIVERS_PATHS: '--with-wdkdir="wdk/Windows Kits/8.0" --with-wdfver=1011 --with-libusb0="libusb0" --with-libusbk="libusbk/bin"' + +jobs: + MinGW-Build: + runs-on: windows-latest + + strategy: + matrix: + include: + - { sys: mingw64, env: x86_64 } + - { sys: mingw32, env: i686 } + + defaults: + run: + shell: msys2 {0} + + steps: + - name: Install MinGW + uses: msys2/setup-msys2@v2 + with: + msystem: ${{ matrix.sys }} + update: true + install: >- + mingw-w64-${{ matrix.env }}-toolchain + base-devel + autotools + git + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + submodules: recursive + - name: Download support files + shell: cmd + run: | + curl -L ${{ env.WDK_URL }} -o wdk-redist.msi + curl -L ${{ env.LIBUSB0_URL }} -o libusb0-redist.zip + curl -L ${{ env.LIBUSBK_URL }} -o libusbk-redist.7z + msiexec /a wdk-redist.msi /qn TARGETDIR=%CD%\wdk + 7z x libusb0-redist.zip + 7z x libusbk-redist.7z + del *.zip + del *.7z + move libusb-win32* libusb0 + move libusbK* libusbk + - name: Build + run: | + ./bootstrap.sh + [ "${{ matrix.env }}" == "x86_64" ] && EXTRA_OPTION=--disable-32bit + ./configure --build=${{ matrix.env }}-w64-mingw32 --host=${{ matrix.env }}-w64-mingw32 ${{ env.BUILD_OPTIONS }} $EXTRA_OPTION ${{ env.DRIVERS_PATHS }} + make + mkdir -p artifacts/${{ matrix.env }} + mv examples/*.exe artifacts/${{ matrix.env }} + - name: Display SHA-256 + if: ${{ github.event_name == 'push' }} + run: sha256sum artifacts/${{ matrix.env }}/*.exe + - name: Upload artifacts + uses: actions/upload-artifact@v4 + if: ${{ github.event_name == 'push' }} + with: + name: ${{ matrix.sys }} + path: ./artifacts/*/*.exe + + Merge-Artifacts: + runs-on: windows-latest + needs: MinGW-Build + steps: + - name: Merge Artifacts + uses: actions/upload-artifact/merge@v4 + if: ${{ github.event_name == 'push' }} + with: + name: MinGW + delete-merged: true \ No newline at end of file diff --git a/.github/workflows/vs2022.yml b/.github/workflows/vs2022.yml new file mode 100644 index 00000000..e17843d7 --- /dev/null +++ b/.github/workflows/vs2022.yml @@ -0,0 +1,101 @@ +name: VS2022 + +on: + push: + paths-ignore: + - '.gitignore' + - '.gitattributes' + - '**.cmd' + - '**.md' + - 'AUTHORS' + - 'NEWS' + - 'ChangeLog' + pull_request: + paths-ignore: + - '.gitignore' + - '.gitattributes' + - '**.cmd' + - '**.md' + - 'AUTHORS' + - 'NEWS' + - 'ChangeLog' + +env: + WDK_URL: https://go.microsoft.com/fwlink/p/?LinkID=253170 + LIBUSB0_URL: https://github.com/mcuee/libusb-win32/releases/download/release_1.4.0.0/libusb-win32-bin-1.4.0.0.zip + LIBUSBK_URL: https://github.com/mcuee/libusbk/releases/download/V3.1.0.0/libusbK-3.1.0.0-bin.7z + SOLUTION_FILE_PATH: ./libwdi.sln + BUILD_MACROS: '"WDK_DIR=\"../wdk/Windows Kits/8.0\";LIBUSB0_DIR=\"../libusb0\";LIBUSBK_DIR=\"../libusbk/bin\""' + +jobs: + VS2022-Build: + runs-on: windows-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + submodules: recursive + + - name: Download support files + shell: cmd + run: | + curl -L ${{ env.WDK_URL }} -o wdk-redist.msi + curl -L ${{ env.LIBUSB0_URL }} -o libusb0-redist.zip + curl -L ${{ env.LIBUSBK_URL }} -o libusbk-redist.7z + msiexec /a wdk-redist.msi /qn TARGETDIR=%CD%\wdk + 7z x libusb0-redist.zip + 7z x libusbk-redist.7z + del *.zip + del *.7z + move libusb-win32* libusb0 + move libusbK* libusbk + + - name: Add MSBuild to PATH + uses: microsoft/setup-msbuild@v2 + + - name: Build + shell: cmd + run: | + for %%P in (Win32 x64) do ( + for %%B in (Debug Release) do ( + msbuild ${{ env.SOLUTION_FILE_PATH }} /m /p:Configuration=%%B,Platform=%%P,BuildMacros=${{ env.BUILD_MACROS }} + ) + ) + + - name: Upload artifacts + uses: actions/upload-artifact@v4 + if: ${{ github.event_name == 'push' }} + with: + name: VS2022 + path: ./*/*/examples/*.exe + + - name: Display SHA-256 + if: ${{ github.event_name == 'push' }} + run: sha256sum ./*/*/examples/*.exe + + - name: Compress release-ready version of Zadig + uses: crazy-max/ghaction-upx@v3 + if: startsWith(github.ref, 'refs/tags/') + with: + version: latest + files: ./Win32/Release/examples/zadig.exe + args: --lzma --best + + - name: Rename release-ready version of Zadig + if: startsWith(github.ref, 'refs/tags/') + shell: cmd + run: | + for /f "tokens=3" %%i in ('findstr FileVersion examples\zadig.rc') do set "ver=%%i" + set ver=%ver:"=% + for /f "tokens=1,2 delims=." %%i in ("%ver%") do set "ZADIG_VERSION=%%i.%%j" + copy Win32\Release\examples\zadig.exe zadig-%ZADIG_VERSION%.exe + sha256sum zadig-*.exe + + - name: Upload release-ready version of Zadig + uses: actions/upload-artifact@v4 + if: startsWith(github.ref, 'refs/tags/') + with: + name: Zadig + path: ./zadig-*.exe diff --git a/AUTHORS b/AUTHORS index d0e64ad2..3d4319e4 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,16 +1,28 @@ -Copyright © 2010-2016 Pete Batard -Copyright © 2010-2011 Travis Robinson +Copyright © 2010-2023 Pete Batard +Copyright © 2010-2011 Travis Robinson Other contributors: Alexander Sashnov Bob Paddock +Fred Sundvik +Georg Vienna +Giovanni Bajo +Jacob Alexander JaggedJax +Jasper van Bourgognie +Jeorg Fischer Jerome-PS +Joel Holdsworth Joseph Marshall +Josh Soerf +Karel Bilek Liam Staskawicz Louie Caulfield PhracturedBlue Ryan Pavlik +Spiro Trikaliotis +Stanley Elliott +Tim Gates Uri Lublin Vitali Lovich -Xiaofan Chen \ No newline at end of file +Xiaofan Chen diff --git a/ChangeLog b/ChangeLog index 111b6d5d..8fa92933 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,58 @@ For the latest changes, please visit: https://github.com/pbatard/libwdi/commits/master +o v1.5.1 (2024.06.13) + New features: + - libusb-win32 ARM64 driver installation support (courtesy of Peter Dons Tychsen) + Bugfixes: + - fix filter installer being potentially overwritten (courtesy of Peter Dons Tychsen) + - fix UAC not being properly triggered during driver installation (courtesy of Andrew Meyer) + Improvements: + - improve Windows edition and platform reporting + +o v1.5.0 (2023.03.01) + New features: + - ARM64 driver installation support (WinUSB, USBSer with MSVC only) + Bugfixes: + - fix MSVC compilation of the shared library + - fix MinGW compilation when using the shared library (with thanks to Joel Holdsworth) + Improvements: + - avoid symbol conflicts by using library specific prefixes where needed + - improve Zadig network support + +o v1.4.1 (2021.11.01) + New features: + - add a new 'external_inf' boolean option to wdi_options_prepare_driver + to allow the use of an external .inf instead of the embedded ones + Bugfixes: + - prevent an infinite loop when a certificate cannot be deleted + - fix the use of -w option in wdi-simple + - fix error when trying to install libusb0.sys as a filter-driver + Improvements: + - improve Windows version reporting for Windows 11 + - stop on .cat signing error if test signing is not enabled + - add an explicit error for code 0x109 (for Windows 11 Insider builds) + +o v1.4.0 (2021.09.04) + Bugfixes: + - fix breakage when providing a user driver + - work around Windows corrupting the key containers + - don't populate empty device descriptors + Improvements: + - more error reporting improvements + - remove the zadic sample + +o v1.3.1 (2020.03.30) + Bugfixes: + - fix handling of non western paths during cat file generation + - fix Windows 7 showing a "Trusted Publisher" dialog + - fix memory leaks + Improvements: + - update project files to VS2019 + - improve error reporting + - allow interface 0 for wdi-simple + - increase RSA bit key size + o v1.3.0 (2017.04.18) Bugfixes: - fix issues with extended characters in current user directory diff --git a/README.md b/README.md index 5a16034d..6c738157 100644 --- a/README.md +++ b/README.md @@ -1,19 +1,21 @@ libwdi: A Windows Driver Installation library for USB devices ============================================================= -[![Build status](https://ci.appveyor.com/api/projects/status/p9q869jayrnbfkkt?svg=true)](https://ci.appveyor.com/project/pbatard/libwdi) -[![Coverity Scan Build Status](https://scan.coverity.com/projects/2174/badge.svg)](https://scan.coverity.com/projects/pbatard-libwdi) -[![Licence](https://img.shields.io/badge/license-LGPLv3-blue.svg)](https://www.gnu.org/licenses/lgpl-3.0.en.html) +[![Build status](https://img.shields.io/github/actions/workflow/status/pbatard/libwdi/vs2022.yml?style=flat-square&label=VS2022)](https://github.com/pbatard/libwdi/actions/workflows/vs2022.yml) +[![Build status](https://img.shields.io/github/actions/workflow/status/pbatard/libwdi/mingw.yml?style=flat-square&label=MinGW)](https://github.com/pbatard/libwdi/actions/workflows/mingw.yml) +[![Coverity Scan Build Status](https://img.shields.io/coverity/scan/2174.svg?style=flat-square&label=Coverity)](https://scan.coverity.com/projects/pbatard-libwdi) +[![Github stats](https://img.shields.io/github/downloads/pbatard/libwdi/total.svg?style=flat-square&label=Downloads)](https://github.com/pbatard/libwdi/releases) +[![Licence](https://img.shields.io/badge/license-LGPLv3-blue.svg?style=flat-square&label=License)](https://www.gnu.org/licenses/lgpl-3.0.en.html) Main features ------------- * Automated inf creation, using reported USB device name * Automated catalog file creation and signing, using autogenerated certificate -* Automated driver files extraction, for both 32 and 64 bit platforms +* Automated driver files extraction, for `x86_32`, `x86_64` and `ARM64` platforms * Automated driver installation, including UAC elevation where necessary * Single library embedding all the required files -* Supports Windows platform from Windows 7 to Windows 10 +* Supports Windows platform from Windows 7 to Windows 11 Additional features ------------------- @@ -24,7 +26,7 @@ Additional features * Resolution of USB Vendor IDs, based on the data maintained by Stephen J. Gowdy at http://www.linux-usb.org/usb.ids * Fully Open Source (LGPL v3), with multiple sample applications -* Supports MinGW32, MinGW-w64, Visual Studio, WDK +* Supports MinGW32, MinGW-w64, Visual Studio Installation and Compilation ---------------------------- diff --git a/_bm.sh b/_bm.sh deleted file mode 100755 index 9d4fb79a..00000000 --- a/_bm.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/sh -# Create and upload a Zadig release -# !!!THIS SCRIPT IS FOR INTERNAL DEVELOPER USE ONLY!!! - -type -P git &>/dev/null || { echo "Git not found. Aborting." >&2; exit 1; } -type -P sed &>/dev/null || { echo "Sed not found. Aborting." >&2; exit 1; } -type -P upx &>/dev/null || { echo "UPX executable not found. Aborting." >&2; exit 1; } - -git clean -fdx -./autogen.sh --disable-shared - -zadig_version=`sed -n 's/^.*\"FileVersion\", \"\(.*\)\..*\"/\1/p' examples/zadig.rc` -echo Building Zadig v$zadig_version... - -make -j12 -make zadig_release \ No newline at end of file diff --git a/_bz.cmd b/_bz.cmd deleted file mode 100644 index 6554ea56..00000000 --- a/_bz.cmd +++ /dev/null @@ -1,13 +0,0 @@ -@echo off - -call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\Tools\VsDevCmd.bat" -arch=x86 -host_arch=amd64 -cd /d "%~dp0" -rem *** Get the version -for /f "tokens=3" %%i in ('findstr FileVersion examples\zadig.rc') do set "ver=%%i" -set ver=%ver:"=% -for /f "tokens=1,2 delims=." %%i in ("%ver%") do set "ZADIG_VERSION=%%i.%%j" -msbuild libwdi.sln /m /p:Project=Zadig;Configuration=Release,Platform=Win32 /t:Rebuild -copy Win32\Release\examples\zadig.exe zadig-%ZADIG_VERSION%.exe -upx --lzma --best zadig-%ZADIG_VERSION%.exe -"C:\Program Files (x86)\Windows Kits\10\bin\10.0.18362.0\x64\signtool" sign /v /sha1 9ce9a71ccab3b38a74781b975f1c228222cf7d3b /fd SHA256 /tr http://sha256timestamp.ws.symantec.com/sha256/timestamp zadig-%ZADIG_VERSION%.exe -pause diff --git a/_chlver.sh b/_chlver.sh index 5ab95919..1d098e9e 100755 --- a/_chlver.sh +++ b/_chlver.sh @@ -38,10 +38,6 @@ _EOF # First run sed to substitute our variable in the sed command file sed -i -e "s/@@MAJOR@@/$MAJOR/g" -e "s/@@MINOR@@/$MINOR/g" -e "s/@@MICRO@@/$MICRO/g" cmd.sed # Run sed to update the .rc version -sed -i -f cmd.sed libwdi/libwdi.rc -sed -i 's/$/\r/' libwdi/libwdi.rc -sed -i -f cmd.sed examples/zadic.rc -sed -i 's/$/\r/' examples/zadic.rc -sed -i -f cmd.sed examples/wdi-simple.rc -sed -i 's/$/\r/' examples/wdi-simple.rc +sed -b -i -f cmd.sed libwdi/libwdi.rc +sed -b -i -f cmd.sed examples/wdi-simple.rc rm cmd.sed diff --git a/_chzver.sh b/_chzver.sh index e0c2b745..54b80ed6 100644 --- a/_chzver.sh +++ b/_chzver.sh @@ -31,10 +31,8 @@ s/^\(.*\)"Zadig .*\..*\.\(.*\)"\(.*\)/\1"Zadig @@MAJOR@@.@@MINOR@@.\2"\3/ _EOF sed -i -e "s/@@MAJOR@@/$MAJOR/g" -e "s/@@MINOR@@/$MINOR/g" cmd.sed -sed -i -f cmd.sed examples/zadig.rc -sed -i 's/$/\r/' examples/zadig.rc -sed -i -f cmd.sed examples/zadig.h -sed -i 's/$/\r/' examples/zadig.h +sed -b -i -f cmd.sed examples/zadig.rc +sed -b -i -f cmd.sed examples/zadig.h rm cmd.sed diff --git a/_coverity.cmd b/_coverity.cmd deleted file mode 100644 index 6224c769..00000000 --- a/_coverity.cmd +++ /dev/null @@ -1,24 +0,0 @@ -@rem *** Internal developer script to run Coverity *** -@echo off -call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\Tools\VsDevCmd.bat" -set COV_DIR=D:\cov-analysis-win64-2017.07 -set PATH=%PATH%;%COV_DIR%\bin -set PWD=%~dp0 -set TARGET=Win32 -rmdir cov-int /s /q >NUL 2>NUL -rmdir %TARGET% /s /q >NUL 2>NUL -del cov-int.zip >NUL 2>NUL -mkdir cov-int -cov-build --dir cov-int msbuild libwdi.sln /p:Configuration=Release,Platform=%TARGET% /maxcpucount -rem *** zip script by Peter Mortensen - http://superuser.com/a/111266/286681 -echo Set objArgs = WScript.Arguments> zip.vbs -echo InputFolder = objArgs(0)>> zip.vbs -echo ZipFile = objArgs(1)>> zip.vbs -echo CreateObject("Scripting.FileSystemObject").CreateTextFile(ZipFile, True).Write "PK" ^& Chr(5) ^& Chr(6) ^& String(18, vbNullChar)>> zip.vbs -echo Set objShell = CreateObject("Shell.Application")>> zip.vbs -echo Set source = objShell.NameSpace(InputFolder)>> zip.vbs -echo objShell.NameSpace(ZipFile).CopyHere(source)>> zip.vbs -echo wScript.Sleep 8000>> zip.vbs -CScript zip.vbs %PWD%cov-int %PWD%cov-int.zip -del zip.vbs -pause diff --git a/_pre-commit.sh b/_pre-commit.sh index 1a8bf4f5..c9d79103 100644 --- a/_pre-commit.sh +++ b/_pre-commit.sh @@ -16,38 +16,45 @@ if [ -x ./_detect-amend.sh ]; then . ./_detect-amend.sh fi -VER=`git log --oneline | wc -l` +BUILD=`git rev-list HEAD --count` # adjust so that we match the github commit count -TAGVER=`expr $VER + 1` +((BUILD++)) # there may be a better way to prevent improper nano on amend. For now the detection # of a .amend file in the current directory will do if [ -f ./.amend ]; then - TAGVER=`expr $TAGVER - 1` + ((BUILD--)) rm ./.amend; fi -echo "setting nano to $TAGVER" +echo "setting nano to $BUILD" -cat > cmd.sed <<\_EOF -s/^[ \t]*FILEVERSION[ \t]*\(.*\),\(.*\),.*,0/ FILEVERSION \1,\2,@@TAGVER@@,0/ -s/^[ \t]*PRODUCTVERSION[ \t]*\(.*\),\(.*\),.*,0/ PRODUCTVERSION \1,\2,@@TAGVER@@,0/ -s/^\([ \t]*\)VALUE[ \t]*"FileVersion",[ \t]*"\(.*\)\..*"/\1VALUE "FileVersion", "\2.@@TAGVER@@"/ -s/^\([ \t]*\)VALUE[ \t]*"ProductVersion",[ \t]*"\(.*\)\..*"/\1VALUE "ProductVersion", "\2.@@TAGVER@@"/ -s/^\(.*\)"Zadig \(.*\)\..*"\(.*\)/\1"Zadig \2.@@TAGVER@@"\3/ +cat > _library.sed <<\_EOF +s/^[ \t]*FILEVERSION[ \t]*\(.*\),\(.*\),\(.*\),.*/ FILEVERSION \1,\2,\3,@@BUILD@@/ +s/^[ \t]*PRODUCTVERSION[ \t]*\(.*\),\(.*\),\(.*\),.*/ PRODUCTVERSION \1,\2,\3,@@BUILD@@/ +s/^\([ \t]*\)VALUE[ \t]*"FileVersion",[ \t]*"\(.*\)\..*"/\1VALUE "FileVersion", "\2.@@BUILD@@"/ +s/^\([ \t]*\)VALUE[ \t]*"ProductVersion",[ \t]*"\(.*\)\..*"/\1VALUE "ProductVersion", "\2.@@BUILD@@"/ +s/\xef\xbf\xbd/\xa9/ +_EOF + +cat > _zadig.sed <<\_EOF +s/^[ \t]*FILEVERSION[ \t]*\(.*\),\(.*\),.*,0/ FILEVERSION \1,\2,@@BUILD@@,0/ +s/^[ \t]*PRODUCTVERSION[ \t]*\(.*\),\(.*\),.*,0/ PRODUCTVERSION \1,\2,@@BUILD@@,0/ +s/^\([ \t]*\)VALUE[ \t]*"FileVersion",[ \t]*"\(.*\)\..*"/\1VALUE "FileVersion", "\2.@@BUILD@@"/ +s/^\([ \t]*\)VALUE[ \t]*"ProductVersion",[ \t]*"\(.*\)\..*"/\1VALUE "ProductVersion", "\2.@@BUILD@@"/ +s/^\(.*\)"Zadig \(.*\)\..*"\(.*\)/\1"Zadig \2.@@BUILD@@"\3/ +s/\xef\xbf\xbd/\xa9/ _EOF # First run sed to substitute our variable in the sed command file -sed -i -e "s/@@TAGVER@@/$TAGVER/g" cmd.sed +sed -i -e "s/@@BUILD@@/$BUILD/g" _library.sed +sed -i -e "s/@@BUILD@@/$BUILD/g" _zadig.sed # Run sed to update the nano version, and add the modified files -sed -i -f cmd.sed libwdi/libwdi.rc -sed -i 's/$/\r/' libwdi/libwdi.rc -sed -i -f cmd.sed examples/zadic.rc -sed -i 's/$/\r/' examples/zadic.rc -sed -i -f cmd.sed examples/zadig.rc -sed -i 's/$/\r/' examples/zadig.rc -sed -i -f cmd.sed examples/zadig.h -sed -i 's/$/\r/' examples/zadig.h -sed -i -f cmd.sed examples/wdi-simple.rc -sed -i 's/$/\r/' examples/wdi-simple.rc -git add libwdi/libwdi.rc examples/zadic.rc examples/zadig.rc examples/zadig.h examples/wdi-simple.rc -rm cmd.sed +sed -b -i -f _library.sed libwdi/libwdi.rc +sed -b -i -f _library.sed examples/wdi-simple.rc +# SED is an ass when it comes to replacing at the end of a line and preserving the EOL sequence +unix2dos -q libwdi/libwdi.rc +unix2dos -q examples/wdi-simple.rc +sed -b -i -f _zadig.sed examples/zadig.rc +sed -b -i -f _zadig.sed examples/zadig.h +rm _library.sed _zadig.sed +git add libwdi/libwdi.rc examples/zadig.rc examples/zadig.h examples/wdi-simple.rc diff --git a/_sign.cmd b/_sign.cmd index 804d4bd1..1da906b6 100644 --- a/_sign.cmd +++ b/_sign.cmd @@ -1,3 +1,2 @@ @echo off -"C:\Program Files (x86)\Windows Kits\10\bin\10.0.16299.0\x64\signtool" sign /v /sha1 9ce9a71ccab3b38a74781b975f1c228222cf7d3b /fd SHA256 /tr http://sha256timestamp.ws.symantec.com/sha256/timestamp %1 -exit +"C:\Program Files (x86)\Windows Kits\10\bin\10.0.22000.0\x64\signtool" sign /v /sha1 fc4686753937a93fdcd48c2bb4375e239af92dcb /fd SHA256 /tr http://timestamp.acs.microsoft.com /td SHA256 %* diff --git a/appveyor.yml b/appveyor.yml deleted file mode 100644 index f032f384..00000000 --- a/appveyor.yml +++ /dev/null @@ -1,52 +0,0 @@ -os: Visual Studio 2017 - -init: - - ps: >- - if ($env:appveyor_repo_tag -eq "true") { - Update-AppveyorBuild -Version "$env:appveyor_repo_tag_name" - } else { - Update-AppveyorBuild -Version "dev-$($env:appveyor_repo_commit.substring(0,7))" - } - - git config --global core.autocrlf input - -environment: - global: - BITS: 32 - matrix: - - CONFIGURATION: Release - COMPILER: MinGW - PLATFORM: i686 - - CONFIGURATION: Release - COMPILER: MinGW - PLATFORM: x86_64 - - CONFIGURATION: Debug - COMPILER: MSVC - PLATFORM: Win32 - - CONFIGURATION: Debug - COMPILER: MSVC - PLATFORM: x64 - - CONFIGURATION: Release - COMPILER: MSVC - PLATFORM: Win32 - - CONFIGURATION: Release - COMPILER: MSVC - PLATFORM: x64 - -build: - project: libwdi.sln - parallel: true - verbosity: detailed - -install: - - curl -o wdk10-redist.7z -L http://files.akeo.ie/appveyor/libwdi/wdk10-redist.7z - - curl -o libusb-win32-bin-1.2.6.0.zip -L http://files.akeo.ie/appveyor/libwdi/libusb-win32-bin-1.2.6.0.zip - - curl -o libusbK-3.0.7.0-bin.7z -L http://files.akeo.ie/appveyor/libwdi/libusbK-3.0.7.0-bin.7z - - 7z x wdk10-redist.7z - - 7z x libusb-win32-bin-1.2.6.0.zip - - 7z x libusbK-3.0.7.0-bin.7z - - if [%PLATFORM%]==[x86_64] set BITS=64 - - if [%PLATFORM%]==[x86_64] set EXTRA_OPTS=--disable-32bit - -build_script: - - if [%COMPILER%]==[MSVC] msbuild libwdi.sln /m /p:Configuration=%CONFIGURATION%,Platform=%PLATFORM%,BuildMacros="WDK_DIR=\"c:/projects/libwdi/wdk\";LIBUSB0_DIR=\"c:/projects/libwdi/libusb-win32-bin-1.2.6.0\";LIBUSBK_DIR=\"c:/projects/libwdi/libusbK-3.0.7.0-bin/bin\"" /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" - - if [%COMPILER%]==[MinGW] C:\msys64\usr\bin\bash -lc "export PATH=/mingw%BITS%/bin:$PATH; cd /c/projects/libwdi; ./bootstrap.sh; ./configure --build=%PLATFORM%-w64-mingw32 --host=%PLATFORM%-w64-mingw32 --enable-toggable-debug --enable-examples-build --disable-debug --disable-shared %EXTRA_OPTS% --with-wdkdir=\"C:/Projects/libwdi/wdk\" --with-wdfver=1011 --with-libusb0=\"C:/Projects/libwdi/libusb-win32-bin-1.2.6.0\" --with-libusbk=\"C:/Projects/libwdi/libusbK-3.0.7.0-bin/bin\"; make -j4" diff --git a/autogen.sh b/autogen.sh index 69cf22de..0240a25f 100755 --- a/autogen.sh +++ b/autogen.sh @@ -3,7 +3,7 @@ # rebuilds the Windows def file by exporting all LIBDWI API calls create_def() { - echo "rebuidling libwdi.def file" + echo "rebuilding libwdi.def file" echo 'LIBRARY "libwdi.dll"' > libwdi/libwdi.def echo "EXPORTS" >> libwdi/libwdi.def sed -n -e "s/.*LIBWDI_API.*\([[:blank:]]\)\(wdi.*\)(.*/ \2/p" libwdi/libwdi.c libwdi/vid_data.c libwdi/logging.c >> libwdi/libwdi.def @@ -23,6 +23,6 @@ create_def() set -e ./bootstrap.sh -./configure --enable-toggable-debug --enable-examples-build --disable-debug --with-wdkdir="C:/Program Files (x86)/Windows Kits/10" --with-wdfver=1011 --with-libusb0="D:/libusb-win32" --with-libusbk="D:/libusbK/bin" $* +./configure --enable-toggable-debug --enable-examples-build --disable-debug --with-wdkdir="C:/Program Files (x86)/Windows Kits/8.0" --with-wdfver=1011 --with-libusb0="D:/libusb-win32" --with-libusbk="D:/libusbK/bin" $* # rebuild .def, if sed is available type -P sed &>/dev/null && create_def diff --git a/configure.ac b/configure.ac index 297e8bbf..2ca98f2d 100644 --- a/configure.ac +++ b/configure.ac @@ -1,16 +1,17 @@ -AC_INIT([libwdi], [1.3.0], [libwdi-devel@lists.sourceforge.net], [libwdi], [http://libwdi.akeo.ie]) +AC_INIT([libwdi],[1.3.1],[libwdi-devel@lists.sourceforge.net],[libwdi],[http://libwdi.akeo.ie]) AM_INIT_AUTOMAKE([-Wno-portability 1.11 foreign]) AC_CONFIG_SRCDIR([libwdi/libwdi.c]) AC_CONFIG_MACRO_DIR([m4]) -AM_CONFIG_HEADER([config.h]) +AC_CONFIG_HEADERS(config.h) # Enable silent build rules by default (Automake v1.11 or later). # Disable by either passing --disable-silent-rules to configure or passing V=1 to make m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])], [AC_SUBST([AM_DEFAULT_VERBOSITY], [1])]) -AC_PREREQ([2.50]) +AC_PREREQ([2.71]) AC_PROG_CC -AC_PROG_LIBTOOL +AC_CHECK_TOOL(WINDRES, windres, :) +LT_INIT LT_LANG([Windows Resource]) AC_C_INLINE AM_PROG_CC_C_O @@ -65,14 +66,14 @@ case $host in create_import_lib="yes" LIBCONFIG_LIBADD="" LIBCONFIG_CFLAGS="" - AM_CFLAGS="-Wshadow" + AM_CFLAGS="-Wshadow -Wno-stringop-truncation" AM_LDFLAGS="-Wl,--add-stdcall-alias" ;; *) AC_MSG_ERROR([unsupported development environment]) esac -AM_CFLAGS="${AM_CFLAGS} -DWINVER=0x0601 -D_WIN32_WINNT=0x0601 -D_WIN32_IE=0x0700" +AM_CFLAGS="${AM_CFLAGS} -DWINVER=0x0601 -D_WIN32_WINNT=0x0601 -D_WIN32_IE=0x0700 -DCOBJMACROS" AM_LDFLAGS="${AM_LDFLAGS} -no-undefined -avoid-version" AM_CONDITIONAL([CREATE_IMPORT_LIB], [test "x$create_import_lib" = "xyes"]) @@ -108,19 +109,17 @@ CFLAGS="${saved_CFLAGS}" LDFLAGS="${saved_LDFLAGS}" cross_compiling=$saved_cross_compiling if test "x$cc_for_build_ok" != "xyes"; then - AC_ERROR([The build compiler cannot produce executables for this + AC_MSG_ERROR(The build compiler cannot produce executables for this platform. You might have to define the CC_FOR_BUILD environment variable. For instance, on 32 bit Windows, if using a multilib MinGW-w64 that defaults - to 64 bit executables, you would need: export CC_FOR_BUILD="gcc -m32"]) + to 64 bit executables, you would need: export CC_FOR_BUILD="gcc -m32") fi # 32 bit support saved_CFLAGS="${CFLAGS}" CFLAGS="${CFLAGS} -m32" AC_MSG_CHECKING([whether the compiler can produce 32 bit binaries]) -AC_TRY_COMPILE([], [;], - [compiler_has_m32=yes], - [compiler_has_m32=no]) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[;]])],[compiler_has_m32=yes],[compiler_has_m32=no]) if test "x$compiler_has_m32" == "xyes"; then AC_MSG_RESULT([yes]) else @@ -132,9 +131,7 @@ CFLAGS="${saved_CFLAGS}" saved_CFLAGS="${CFLAGS}" CFLAGS="${CFLAGS} -m64" AC_MSG_CHECKING([whether the compiler can produce 64 bit binaries]) -AC_TRY_COMPILE([], [;], - [compiler_has_m64=yes], - [compiler_has_m64=no]) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[;]])],[compiler_has_m64=yes],[compiler_has_m64=no]) if test "x$compiler_has_m64" == "xyes"; then AC_MSG_RESULT([yes]) else diff --git a/examples/.msvc/wdi-simple.vcxproj b/examples/.msvc/wdi-simple.vcxproj index 1d461fbd..bdece24d 100644 --- a/examples/.msvc/wdi-simple.vcxproj +++ b/examples/.msvc/wdi-simple.vcxproj @@ -29,23 +29,23 @@ Application Unicode true - v142 + v143 Application Unicode - v142 + v143 Application Unicode true - v142 + v143 Application Unicode - v142 + v143 @@ -87,13 +87,14 @@ CompileAsC - setupapi.lib;newdev.lib;%(AdditionalDependencies) + setupapi.lib;newdev.lib;ntdll.lib;%(AdditionalDependencies) %(AdditionalLibraryDirectories) true $(TargetDir)$(ProjectName).pdb Console MachineX86 RequireAdministrator + /BREPRO /DEPENDENTLOADFLAG:0x800 %(AdditionalOptions) @@ -112,12 +113,13 @@ CompileAsC - setupapi.lib;newdev.lib;%(AdditionalDependencies) + setupapi.lib;newdev.lib;ntdll.lib;%(AdditionalDependencies) %(AdditionalLibraryDirectories) true $(TargetDir)$(ProjectName).pdb Console MachineX64 + /BREPRO /DEPENDENTLOADFLAG:0x800 %(AdditionalOptions) @@ -132,7 +134,7 @@ CompileAsC - setupapi.lib;newdev.lib;%(AdditionalDependencies) + setupapi.lib;newdev.lib;ntdll.lib;%(AdditionalDependencies) %(AdditionalLibraryDirectories) false Console @@ -140,6 +142,7 @@ true MachineX86 RequireAdministrator + /BREPRO /DEPENDENTLOADFLAG:0x800 %(AdditionalOptions) @@ -157,13 +160,14 @@ CompileAsC - setupapi.lib;newdev.lib;%(AdditionalDependencies) + setupapi.lib;newdev.lib;ntdll.lib;%(AdditionalDependencies) %(AdditionalLibraryDirectories) false Console true true MachineX64 + /BREPRO /DEPENDENTLOADFLAG:0x800 %(AdditionalOptions) @@ -182,6 +186,10 @@ false + + + + diff --git a/examples/.msvc/wdi-simple.vcxproj.filters b/examples/.msvc/wdi-simple.vcxproj.filters index 28351fab..44c0e25f 100644 --- a/examples/.msvc/wdi-simple.vcxproj.filters +++ b/examples/.msvc/wdi-simple.vcxproj.filters @@ -8,6 +8,9 @@ {da31138d-56fc-4ef9-bea2-68f46be07623} + + {cac8a2f4-ad03-4bd7-9219-846a23f7392a} + @@ -19,4 +22,12 @@ Resource Files + + + Header Files + + + Header Files + + \ No newline at end of file diff --git a/examples/.msvc/wdi-simple_sources b/examples/.msvc/wdi-simple_sources deleted file mode 100644 index e2c0c601..00000000 --- a/examples/.msvc/wdi-simple_sources +++ /dev/null @@ -1,26 +0,0 @@ -TARGETNAME=wdi-simple -TARGETTYPE=PROGRAM -UMTYPE=console -UMENTRY=main - -!IFNDEF MSC_WARNING_LEVEL -MSC_WARNING_LEVEL=/W3 -!ENDIF - -USE_MSVCRT=1 - -INCLUDES=..\msvc;..\libwdi;$(DDK_INC_PATH) -C_DEFINES = $(C_DEFINES) /DDDKBUILD - -TARGETLIBS=$(SDK_LIB_PATH)\kernel32.lib \ - $(SDK_LIB_PATH)\user32.lib \ - $(SDK_LIB_PATH)\setupapi.lib \ - $(SDK_LIB_PATH)\ole32.lib \ - $(SDK_LIB_PATH)\shell32.lib \ - ..\libwdi\libwdi.lib \ - .\getopt\getopt.lib - -SXS_APPLICATION_MANIFEST=common_controls.manifest - -SOURCES=wdi-simple.c \ - wdi-simple.rc diff --git a/examples/.msvc/zadic.vcxproj b/examples/.msvc/zadic.vcxproj deleted file mode 100644 index 50e64c70..00000000 --- a/examples/.msvc/zadic.vcxproj +++ /dev/null @@ -1,190 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - zadic - {F4938DB0-3DE7-4737-9C5A-EAD1BE819F87} - zadic - Win32Proj - - - - Application - Unicode - true - v142 - - - Application - Unicode - v142 - - - Application - Unicode - true - v142 - - - Application - Unicode - v142 - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - $(SolutionDir)$(Platform)\$(Configuration)\examples\ - $(SolutionDir)$(Platform)\$(Configuration)\examples\$(ProjectName)\ - $(SolutionDir)$(Platform)\$(Configuration)\examples\ - $(SolutionDir)$(Platform)\$(Configuration)\examples\$(ProjectName)\ - $(SolutionDir)$(Platform)\$(Configuration)\examples\ - $(SolutionDir)$(Platform)\$(Configuration)\examples\$(ProjectName)\ - $(SolutionDir)$(Platform)\$(Configuration)\examples\ - $(SolutionDir)$(Platform)\$(Configuration)\examples\$(ProjectName)\ - - - - $(IntDir)$(ProjectName).htm - - - ..\..\libwdi;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreadedDebug - Level3 - ProgramDatabase - CompileAsC - - - setupapi.lib;newdev.lib;%(AdditionalDependencies) - %(AdditionalLibraryDirectories) - RequireAdministrator - true - $(TargetDir)$(ProjectName).pdb - Console - MachineX86 - - - - - $(IntDir)$(ProjectName).htm - - - X64 - - - ..\..\libwdi;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreadedDebug - Level3 - ProgramDatabase - CompileAsC - - - setupapi.lib;newdev.lib;%(AdditionalDependencies) - %(AdditionalLibraryDirectories) - RequireAdministrator - true - $(TargetDir)$(ProjectName).pdb - Console - MachineX64 - - - - - $(IntDir)$(ProjectName).htm - - - ..\..\libwdi;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreaded - Level3 - CompileAsC - - - setupapi.lib;newdev.lib;%(AdditionalDependencies) - %(AdditionalLibraryDirectories) - RequireAdministrator - false - Console - true - true - MachineX86 - - - - - $(IntDir)$(ProjectName).htm - - - X64 - - - ..\..\libwdi;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreaded - Level3 - CompileAsC - - - setupapi.lib;newdev.lib;%(AdditionalDependencies) - %(AdditionalLibraryDirectories) - RequireAdministrator - false - Console - true - true - MachineX64 - - - - - - - - - - - {9aa0e745-1a0a-4700-8ecb-6a6de9dbf8b9} - false - - - {ae83e1b4-ce06-47ee-b7a3-c3a1d7c2d71e} - false - - - - - - \ No newline at end of file diff --git a/examples/.msvc/zadic_sources b/examples/.msvc/zadic_sources deleted file mode 100644 index 4f9ea964..00000000 --- a/examples/.msvc/zadic_sources +++ /dev/null @@ -1,27 +0,0 @@ -TARGETNAME=zadic -TARGETTYPE=PROGRAM -UMTYPE=console -UMENTRY=main - -!IFNDEF MSC_WARNING_LEVEL -MSC_WARNING_LEVEL=/W3 -!ENDIF - -USE_MSVCRT=1 - -INCLUDES=..\msvc;..\libwdi;$(DDK_INC_PATH) -C_DEFINES = $(C_DEFINES) /DDDKBUILD - -TARGETLIBS=$(SDK_LIB_PATH)\kernel32.lib \ - $(SDK_LIB_PATH)\user32.lib \ - $(SDK_LIB_PATH)\setupapi.lib \ - $(SDK_LIB_PATH)\ole32.lib \ - $(SDK_LIB_PATH)\shell32.lib \ - ..\libwdi\libwdi.lib \ - .\getopt\getopt.lib - -# http://jpassing.com/2008/02/01/how-to-use-manifests-with-buildexe/ -SXS_APPLICATION_MANIFEST=elevation.manifest - -SOURCES=zadic.c \ - zadic.rc diff --git a/examples/.msvc/zadig.vcxproj b/examples/.msvc/zadig.vcxproj index 0bbd6dd3..0f47cd32 100644 --- a/examples/.msvc/zadig.vcxproj +++ b/examples/.msvc/zadig.vcxproj @@ -29,23 +29,23 @@ Application Unicode true - v142 + v143 Application Unicode - v142 + v143 Application Unicode true - v142 + v143 Application Unicode - v142 + v143 @@ -80,7 +80,7 @@ ..\..\msvc;..\..\libwdi;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;ISOLATION_AWARE_ENABLED;_CRTDBG_MAP_ALLOC;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNINGS;ISOLATION_AWARE_ENABLED;COBJMACROS;_CRTDBG_MAP_ALLOC;%(PreprocessorDefinitions) MultiThreadedDebug Level3 ProgramDatabase @@ -88,11 +88,12 @@ 4091 - setupapi.lib;comctl32.lib;wininet.lib;%(AdditionalDependencies) + setupapi.lib;comctl32.lib;wininet.lib;ntdll.lib;%(AdditionalDependencies) RequireAdministrator true Windows MachineX86 + /BREPRO /DEPENDENTLOADFLAG:0x800 %(AdditionalOptions) @@ -104,7 +105,7 @@ ..\..\msvc;..\..\libwdi;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;ISOLATION_AWARE_ENABLED;_CRTDBG_MAP_ALLOC;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNINGS;ISOLATION_AWARE_ENABLED;COBJMACROS;_CRTDBG_MAP_ALLOC;%(PreprocessorDefinitions) MultiThreadedDebug Level3 ProgramDatabase @@ -112,11 +113,12 @@ 4091 - setupapi.lib;comctl32.lib;wininet.lib;%(AdditionalDependencies) + setupapi.lib;comctl32.lib;wininet.lib;ntdll.lib;%(AdditionalDependencies) RequireAdministrator true Windows MachineX64 + /BREPRO /DEPENDENTLOADFLAG:0x800 %(AdditionalOptions) @@ -125,7 +127,7 @@ ..\..\msvc;..\..\libwdi;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;ISOLATION_AWARE_ENABLED;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNINGS;ISOLATION_AWARE_ENABLED;COBJMACROS;%(PreprocessorDefinitions) MultiThreaded Level3 ProgramDatabase @@ -133,13 +135,14 @@ 4091 - setupapi.lib;comctl32.lib;wininet.lib;%(AdditionalDependencies) + setupapi.lib;comctl32.lib;wininet.lib;ntdll.lib;%(AdditionalDependencies) RequireAdministrator false Windows true true MachineX86 + /BREPRO /DEPENDENTLOADFLAG:0x800 %(AdditionalOptions) @@ -151,14 +154,14 @@ ..\..\msvc;..\..\libwdi;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;ISOLATION_AWARE_ENABLED;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNINGS;ISOLATION_AWARE_ENABLED;COBJMACROS;%(PreprocessorDefinitions) MultiThreaded Level3 CompileAsC 4091 - setupapi.lib;comctl32.lib;wininet.lib;%(AdditionalDependencies) + setupapi.lib;comctl32.lib;wininet.lib;ntdll.lib;%(AdditionalDependencies) D:\libwdi\x64\Release\lib;%(AdditionalLibraryDirectories) RequireAdministrator false @@ -166,6 +169,7 @@ true true MachineX64 + /BREPRO /DEPENDENTLOADFLAG:0x800 %(AdditionalOptions) diff --git a/examples/.msvc/zadig_sources b/examples/.msvc/zadig_sources deleted file mode 100644 index 14f6bec2..00000000 --- a/examples/.msvc/zadig_sources +++ /dev/null @@ -1,32 +0,0 @@ -TARGETNAME=zadig -TARGETTYPE=PROGRAM -UMTYPE=windows -UMENTRY=winmain - -!IFNDEF MSC_WARNING_LEVEL -MSC_WARNING_LEVEL=/W3 -!ENDIF - -USE_MSVCRT=1 - -INCLUDES=..\msvc;..\libwdi;$(DDK_INC_PATH) -C_DEFINES = $(C_DEFINES) /DDDKBUILD /DISOLATION_AWARE_ENABLED - -TARGETLIBS=$(SDK_LIB_PATH)\kernel32.lib \ - $(SDK_LIB_PATH)\user32.lib \ - $(SDK_LIB_PATH)\setupapi.lib \ - $(SDK_LIB_PATH)\ole32.lib \ - $(SDK_LIB_PATH)\shell32.lib \ - $(SDK_LIB_PATH)\uuid.lib \ - $(SDK_LIB_PATH)\wininet.lib \ - ..\libwdi\libwdi.lib \ - -# http://jpassing.com/2008/02/01/how-to-use-manifests-with-buildexe/ -SXS_APPLICATION_MANIFEST=common_controls_and_elevation.manifest - -SOURCES=zadig.c \ - zadig_net.c \ - zadig_parser.c \ - zadig_stdlg.c \ - profile.c \ - zadig.rc diff --git a/examples/Makefile.am b/examples/Makefile.am index f4b9dae1..44c1f3db 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -1,31 +1,20 @@ AM_CPPFLAGS = -I$(top_srcdir) -noinst_PROGRAMS = zadic zadig wdi-simple +noinst_PROGRAMS = zadig wdi-simple -pkg_v_rc = $(pkg_v_rc_$(V)) -pkg_v_rc_ = $(pkg_v_rc_$(AM_DEFAULT_VERBOSITY)) -pkg_v_rc_0 = @echo " RC $@"; +AM_V_WINDRES_0 = @echo " RC $@";$(WINDRES) +AM_V_WINDRES_1 = $(WINDRES) +AM_V_WINDRES_ = $(AM_V_WINDRES_$(AM_DEFAULT_VERBOSITY)) +AM_V_WINDRES = $(AM_V_WINDRES_$(V)) -zadic_rc.o: zadic.rc - $(pkg_v_rc)$(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --tag=RC --mode=compile $(RC) $(ARCH_RCFLAGS) -i $< -o $@ - -zadic_SOURCES = zadic.c -zadic_CFLAGS = -I../libwdi $(ARCH_CFLAGS) $(AM_CFLAGS) -# static ensures that the exe can be shared as a standalone, and still allow driver installation -zadic_LDFLAGS = $(AM_LDFLAGS) -static -zadic_LDADD = zadic_rc.o -L../libwdi/.libs -lwdi - -zadig_rc.o: zadig.rc zadig_resource.h - $(pkg_v_rc)$(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --tag=RC --mode=compile $(RC) $(ARCH_RCFLAGS) -i $< -o $@ +%_rc.o: %.rc + $(AM_V_WINDRES) $(AM_RCFLAGS) -i $< -o $@ zadig_SOURCES = zadig.c zadig_net.c zadig_parser.c zadig_stdlg.c profile.c zadig_CFLAGS = -I../libwdi $(ARCH_CFLAGS) $(AM_CFLAGS) zadig_LDFLAGS = -mwindows $(AM_LDFLAGS) -static zadig_LDADD = zadig_rc.o -L../libwdi/.libs -lwdi -lwininet -luuid -lcomctl32 -wdi-simple_rc.o: wdi-simple.rc - $(pkg_v_rc)$(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --tag=RC --mode=compile $(RC) $(ARCH_RCFLAGS) -i $< -o $@ - wdi_simple_SOURCES = wdi-simple.c wdi_simple_CFLAGS = -I../libwdi $(ARCH_CFLAGS) $(AM_CFLAGS) wdi_simple_LDFLAGS = $(AM_LDFLAGS) -static diff --git a/examples/getopt/.msvc/getopt.vcproj b/examples/getopt/.msvc/getopt.vcproj deleted file mode 100644 index ecbe9c27..00000000 --- a/examples/getopt/.msvc/getopt.vcproj +++ /dev/null @@ -1,288 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/getopt/.msvc/getopt.vcxproj b/examples/getopt/.msvc/getopt.vcxproj index 7e8a8c12..054fce25 100644 --- a/examples/getopt/.msvc/getopt.vcxproj +++ b/examples/getopt/.msvc/getopt.vcxproj @@ -27,23 +27,23 @@ StaticLibrary Unicode true - v142 + v143 StaticLibrary Unicode - v142 + v143 StaticLibrary Unicode true - v142 + v143 StaticLibrary Unicode - v142 + v143 @@ -75,7 +75,6 @@ HAVE_STRING_H;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true MultiThreadedDebug Level3 ProgramDatabase @@ -83,6 +82,7 @@ true + /BREPRO %(AdditionalOptions) @@ -98,6 +98,7 @@ true + /BREPRO %(AdditionalOptions) @@ -110,6 +111,7 @@ true + /BREPRO %(AdditionalOptions) @@ -124,6 +126,7 @@ true + /BREPRO %(AdditionalOptions) diff --git a/examples/getopt/.msvc/getopt_sources b/examples/getopt/.msvc/getopt_sources deleted file mode 100644 index 3bc533df..00000000 --- a/examples/getopt/.msvc/getopt_sources +++ /dev/null @@ -1,17 +0,0 @@ -TARGETTYPE=LIBRARY -TARGETNAME=getopt - -!IFNDEF MSC_WARNING_LEVEL -MSC_WARNING_LEVEL=/W3 -!ENDIF - -USE_MSVCRT=1 - -INCLUDES=$(DDK_INC_PATH) -C_DEFINES = $(C_DEFINES) /DDDKBUILD /DHAVE_STRING_H - -TARGETLIBS=$(SDK_LIB_PATH)\kernel32.lib \ - $(SDK_LIB_PATH)\user32.lib - -SOURCES=getopt1.c \ - getopt.c diff --git a/examples/profile.c b/examples/profile.c index e4793c4a..7068e74b 100644 --- a/examples/profile.c +++ b/examples/profile.c @@ -299,6 +299,7 @@ long profile_update_file(prf_file_t prf) retval = errno; if (retval == 0) retval = ENOENT; + profile_free_node(state.root_section); return retval; } prf->upd_serial++; @@ -311,6 +312,7 @@ long profile_update_file(prf_file_t prf) (syntax_err_cb)(prf->filespec, retval, state.line_num); fclose(f); + profile_free_node(state.root_section); return retval; } } @@ -770,7 +772,7 @@ long profile_create_node(const char *name, const char *value, } /* - * This function verifies that all of the representation invarients of + * This function verifies that all of the representation invariants of * the profile are true. If not, we have a programming bug somewhere, * probably in this file. */ @@ -849,7 +851,7 @@ long profile_add_node(struct profile_node *section, const char *name, /* * Iterate through the section, returning the nodes which match - * the given name. If name is NULL, then interate through all the + * the given name. If name is NULL, then iterate through all the * nodes in the section. If section_flag is non-zero, only return the * section which matches the name; don't return relations. If value * is non-NULL, then only return relations which match the requested @@ -1382,7 +1384,7 @@ const char* profile_errtostr(long error_code) case PROF_BAD_LINK_LIST: return "Bad linked list in profile structures"; case PROF_BAD_GROUP_LVL: - return "Bad group level in profile strctures"; + return "Bad group level in profile structures"; case PROF_BAD_PARENT_PTR: return "Bad parent pointer in profile structures"; case PROF_MAGIC_ITERATOR: diff --git a/examples/wdi-simple.c b/examples/wdi-simple.c index 6a118c0f..b3496d22 100644 --- a/examples/wdi-simple.c +++ b/examples/wdi-simple.c @@ -1,6 +1,6 @@ /* * wdi-simple.c: Console Driver Installer for a single USB device -* Copyright (c) 2010-2018 Pete Batard +* Copyright (c) 2010-2021 Pete Batard * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -62,6 +62,8 @@ void usage(void) printf(" one (WinUSB, libusb-win32 or libusbK only)\n"); printf(" --filter use the libusb-win32 filter driver (requires -t1)\n"); printf("-d, --dest set the extraction directory\n"); + printf("-e, --external use the external inf specified by as source\n"); + printf(" (overrides the internal embedded inf)\n"); printf("-x, --extract extract files only (don't install)\n"); printf("-c, --cert install certificate from the\n"); printf(" embedded user files as a trusted publisher\n"); @@ -123,6 +125,7 @@ int __cdecl main(int argc, char** argv) {"progressbar", optional_argument, 0, 'b'}, {"log", required_argument, 0, 'l'}, {"timeout", required_argument, 0, 'o'}, + {"external", required_argument, 0, 'e'}, {"help", no_argument, 0, 'h'}, {0, 0, 0, 0} }; @@ -134,7 +137,7 @@ int __cdecl main(int argc, char** argv) while(1) { - c = getopt_long(argc, argv, "n:f:m:d:c:v:p:i:l:t:o:hxsb", long_options, NULL); + c = getopt_long(argc, argv, "bc:d:e:f:hi:l:m:n:o:p:st:v:wx", long_options, NULL); if (c == -1) break; switch(c) { @@ -144,23 +147,39 @@ int __cdecl main(int argc, char** argv) case 2: // --filter oid.install_filter_driver = TRUE; break; - case 'n': - dev.desc = optarg; + case 'b': + oid.hWnd = (optarg) ? (HWND)(uintptr_t)strtol(optarg, NULL, 0) : GetConsoleHwnd(); + oic.hWnd = oid.hWnd; break; - case 'm': - opd.vendor_name = optarg; + case 'c': + cert_name = optarg; + break; + case 'd': + ext_dir = optarg; + break; + case 'e': + inf_name = optarg; + opd.external_inf = TRUE; break; case 'f': inf_name = optarg; break; - case 'd': - ext_dir = optarg; + case 'h': + usage(); + exit(0); break; - case 'c': - cert_name = optarg; + case 'i': + dev.is_composite = TRUE; + dev.mi = (unsigned char)strtol(optarg, NULL, 0); break; - case 'v': - dev.vid = (unsigned short)strtol(optarg, NULL, 0); + case 'l': + log_level = (int)strtol(optarg, NULL, 0); + break; + case 'm': + opd.vendor_name = optarg; + break; + case 'n': + dev.desc = optarg; break; case 'o': oid.pending_install_timeout = (DWORD)strtoul(optarg, NULL, 0); @@ -168,34 +187,22 @@ int __cdecl main(int argc, char** argv) case 'p': dev.pid = (unsigned short)strtol(optarg, NULL, 0); break; - case 'i': - dev.is_composite = TRUE; - dev.mi = (unsigned char)strtol(optarg, NULL, 0); + case 's': + opt_silent = 1; + log_level = WDI_LOG_LEVEL_NONE; break; case 't': opd.driver_type = (int)strtol(optarg, NULL, 0); break; + case 'v': + dev.vid = (unsigned short)strtol(optarg, NULL, 0); + break; case 'w': opd.use_wcid_driver = TRUE; break; - case 'h': - usage(); - exit(0); - break; case 'x': opt_extract = 1; break; - case 's': - opt_silent = 1; - log_level = WDI_LOG_LEVEL_NONE; - break; - case 'b': - oid.hWnd = (optarg)?(HWND)(uintptr_t)strtol(optarg, NULL, 0):GetConsoleHwnd(); - oic.hWnd = oid.hWnd; - break; - case 'l': - log_level = (int)strtol(optarg, NULL, 0); - break; default: usage(); exit(0); diff --git a/examples/wdi-simple.iss b/examples/wdi-simple.iss index 91c0486b..f87f0ff0 100644 --- a/examples/wdi-simple.iss +++ b/examples/wdi-simple.iss @@ -1,5 +1,5 @@ ; This examples demonstrates how libwdi can be used in an installer script -; to automatically intall USB drivers along with your application. +; to automatically install USB drivers along with your application. ; ; Requirements: Inno Setup (http://www.jrsoftware.org/isdl.php) ; @@ -23,7 +23,7 @@ SolidCompression = yes ; Win2000 or higher MinVersion = 5,5 -; This installation requires admin priviledges. This is needed to install +; This installation requires admin privileges. This is needed to install ; drivers on windows vista and later. PrivilegesRequired = admin diff --git a/examples/wdi-simple.nsi b/examples/wdi-simple.nsi index 42b6abac..9039bb18 100644 --- a/examples/wdi-simple.nsi +++ b/examples/wdi-simple.nsi @@ -1,5 +1,5 @@ ; This examples demonstrates how libwdi can be used in an installer script -; to automatically intall USB drivers along with your application. +; to automatically install USB drivers along with your application. ; ; Requirements: Nullsoft Scriptable Install System (http://nsis.sourceforge.net/) ; diff --git a/examples/wdi-simple.rc b/examples/wdi-simple.rc index f916752a..70d7c59b 100644 --- a/examples/wdi-simple.rc +++ b/examples/wdi-simple.rc @@ -7,8 +7,8 @@ #endif VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,3,730,0 - PRODUCTVERSION 1,3,730,0 + FILEVERSION 1,5,1,791 + PRODUCTVERSION 1,5,1,791 FILEFLAGSMASK 0x17L #ifdef _DEBUG FILEFLAGS 0x1L @@ -25,13 +25,13 @@ BEGIN BEGIN VALUE "CompanyName", "akeo.ie" VALUE "FileDescription", "WDI-Simple" - VALUE "FileVersion", "1.3.730" + VALUE "FileVersion", "1.5.1.791" VALUE "InternalName", "WDI-Simple" - VALUE "LegalCopyright", "© 2010-2018 Pete Batard (LGPL v3)" - VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/lesser.html" + VALUE "LegalCopyright", "© 2010-2025 Pete Batard (LGPL v3)" + VALUE "LegalTrademarks", "https://www.gnu.org/licenses/lgpl-3.0.html" VALUE "OriginalFilename", "wdi-simple.exe" VALUE "ProductName", "WDI-Simple" - VALUE "ProductVersion", "1.3.730" + VALUE "ProductVersion", "1.5.1.791" VALUE "Comments", "http://libwdi.akeo.ie" END END diff --git a/examples/zadic.c b/examples/zadic.c deleted file mode 100644 index 943c3281..00000000 --- a/examples/zadic.c +++ /dev/null @@ -1,220 +0,0 @@ - -/* -* Zadic: Automated Driver Installer for USB devices (Console version) -* Copyright (c) 2010-2016 Pete Batard -* Copyright (c) 2015 PhracturedBlue <6xtc2h7upj@snkmail.com> -* Copyright (c) 2010 Joseph Marshall -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation; either -* version 3 of the License, or (at your option) any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -* Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General Public -* License along with this library; if not, write to the Free Software -* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -/* -* WARNING: if any part of the resulting executable name contains "setup" or "instal(l)" -* it will require UAC elevation on Vista and later, and, when run from an MSYS shell, -* will produce a "sh: Bad file number" message. -* See the paragraph on Automatic Elevation at http://helpware.net/VistaCompat.htm -*/ - -#include -#include -#include -#ifdef _MSC_VER -#include "getopt/getopt.h" -#else -#include -#endif -#include "libwdi.h" - -#define FLUSHER while(getchar() != 0x0A) -#define INF_NAME "libusb_device.inf" - -void usage(void) -{ - printf("\n"); - printf("--noprompt allows the program to end without prompting the user\n"); - printf("--usealldevices lists all usb devices instead of only driverless ones\n"); - printf("--iface sets the interface number\n"); - printf("--vid sets the VID number. You must put 0x infront of vid number\n"); - printf("--pid sets the PID number. You must put 0x infront of pid number\n"); - printf("--useinf use supplied .inf if it exists in the correct directory\n"); - printf("--create create device even if USB device is not attached. Requires a description\n"); - printf("\n"); -} - -// The following is necessary when compiled from a WDK/DDK environment -int __cdecl main(int argc, char *argv[]) -{ - int c; - struct wdi_device_info *device, *list; - char* path = "usb_driver"; - static struct wdi_options_create_list cl_options = { 0 }; - static struct wdi_options_prepare_driver pd_options = { 0 }; - - static int prompt_flag = 1; - static unsigned char use_iface = 0; - static unsigned char iface = 0; - static unsigned short vid = 0, pid = 0; - static int verbose_flag = 3; - static char *desc = NULL; - static int use_supplied_inf_flag = 0; - int r = WDI_ERROR_OTHER, option_index = 0; - - cl_options.trim_whitespaces = TRUE; - - // Parse command-line options - while(1) - { - static struct option long_options[] = { - // These options set a flag. - {"noprompt", no_argument, &prompt_flag, 0}, - {"usealldevices", no_argument, &cl_options.list_all, 1}, - {"useinf", no_argument, &use_supplied_inf_flag, 1}, - {"iface", required_argument, 0, 'a'}, - {"vid", required_argument, 0, 'b'}, - {"pid", required_argument, 0, 'c'}, - {"help", no_argument, 0, 'd'}, - {"verbose", no_argument, &verbose_flag, 0}, - {"create", required_argument,0, 'e'}, - {0, 0, 0, 0} - }; - - c = getopt_long(argc, argv, "abc:d:e:",long_options, &option_index); - // Detect the end of the options. - if (c == -1) - break; - - switch(c) - { - case 0: - // If this option set a flag, do nothing else now. - if (long_options[option_index].flag != 0) { - break; - } - printf("option %s", long_options[option_index].name); - if (optarg) { - printf (" with arg %s", optarg); - } - printf("\n"); - break; - case 'a': - iface = (unsigned char)atoi(optarg); - use_iface = 1; - printf("OPT: interface number %d\n", iface); - break; - case 'b': - vid = (unsigned short)strtol(optarg, NULL, 0); - printf("OPT: VID number %d\n", vid); - break; - case 'c': - pid = (unsigned short)strtol(optarg, NULL, 0); - printf("OPT: PID number %d\n", pid); - break; - case 'd': // getopt_long already printed an error message. - usage(); - exit(0); - break; - case 'e': //create requires a description argument - desc = optarg; - break; - default: - usage(); - abort(); - } - } - - if (desc) { - // If the device is created from scratch, override the existing device - if (vid == 0 || pid == 0) { - printf("Must specify both --vid and --pid with --create\n"); - return 1; - } - device = (struct wdi_device_info*)calloc(1, sizeof(struct wdi_device_info)); - if (device == NULL) { - printf("could not create new device_info struct for installation"); - return 1; - } - device->desc = desc; - device->vid = vid; - device->pid = pid; - if (use_iface) { - device->is_composite = 1; - device->mi = iface; - } - printf("Creating USB device: device: \"%s\" (%04X:%04X)\n", device->desc, device->vid, device->pid); - wdi_set_log_level(verbose_flag); - if (wdi_prepare_driver(device, path, INF_NAME, &pd_options) == WDI_SUCCESS) { - printf("installing wdi driver with <%s> at <%s>\n", INF_NAME, path); - r = wdi_install_driver(device, path, INF_NAME, NULL); - if (r != WDI_SUCCESS) { - printf("Failed to install driver: %s\n", wdi_strerror(r)); - } - } - free(device); - return (r == WDI_SUCCESS) ? 0 : 1; - } - - r = wdi_create_list(&list, &cl_options); - switch (r) { - case WDI_SUCCESS: - break; - case WDI_ERROR_NO_DEVICE: - printf("No driverless USB devices were found.\n"); - return 0; - default: - printf("wdi_create_list: error %s\n", wdi_strerror(r)); - return 0; - } - - for (device = list; device != NULL; device = device->next) { - printf("Found USB device: \"%s\" (%04X:%04X)\n", device->desc, device->vid, device->pid); - wdi_set_log_level(verbose_flag); - // If vid and pid have not been initialized - // prompt user to install driver for each device - if (vid == 0 || pid == 0) { - printf("Do you want to install a driver for this device (y/n)?\n"); - c = (char) getchar(); - FLUSHER; - if ((c != 'y') && (c != 'Y')) { - continue; - } - // Otherwise a specific vid and pid have been given - // so drivers will install automatically - } else { - // Is VID and PID a match for our device - if ( (device->vid != vid) || (device->pid != pid) - || (device->mi != iface) ) { - continue; - } - } - // Does the user want to use a supplied .inf - if (use_supplied_inf_flag == 0) { - if (wdi_prepare_driver(device, path, INF_NAME, &pd_options) == WDI_SUCCESS) { - printf("installing wdi driver with <%s> at <%s>\n",INF_NAME, path); - wdi_install_driver(device, path, INF_NAME, NULL); - } - } else { - printf("installing wdi driver with <%s> at <%s>\n",INF_NAME, path); - wdi_install_driver(device, path, INF_NAME, NULL); - } - } - wdi_destroy_list(list); - - // This is needed when ran in UAC mode - if (prompt_flag) { - printf("\nPress Enter to exit this program\n"); - FLUSHER; - } - return 0; -} diff --git a/examples/zadic.rc b/examples/zadic.rc deleted file mode 100644 index 5e322edf..00000000 --- a/examples/zadic.rc +++ /dev/null @@ -1,112 +0,0 @@ -// Microsoft Visual C++ generated resource script. -// -#include "zadic_resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include "afxres.h" - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// English resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL -#pragma code_page(1252) - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE -BEGIN - "zadic_resource.h\0" -END - -2 TEXTINCLUDE -BEGIN - "#include ""afxres.h""\r\n" - "\0" -END - -3 TEXTINCLUDE -BEGIN - "\r\n" - "// Must reference a manifest for visual styles and elevation\r\n" - "// Oh, and it must happen at the end, or MinGW will ignore it!\r\n" - "#if defined(__GNUC__)\r\n" - "CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST ""elevation.manifest""\r\n" - "#endif\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// Version -// - -VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,3,730,0 - PRODUCTVERSION 1,3,730,0 - FILEFLAGSMASK 0x17L -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS 0x40004L - FILETYPE 0x1L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "000904b0" - BEGIN - VALUE "CompanyName", "akeo.ie" - VALUE "FileDescription", "Zadic" - VALUE "FileVersion", "1.3.730" - VALUE "InternalName", "Zadic" - VALUE "LegalCopyright", "© 2010-2018 Pete Batard (LGPL v3)" - VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/lesser.html" - VALUE "OriginalFilename", "zadic.exe" - VALUE "ProductName", "Zadic" - VALUE "ProductVersion", "1.3.730" - VALUE "Comments", "http://libwdi.akeo.ie" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x9, 1200 - END -END - -#endif // English resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - -// Must reference a manifest for visual styles and elevation -// Oh, and it must happen at the end, or MinGW will ignore it! -#if defined(__GNUC__) -CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "elevation.manifest" -#endif - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - diff --git a/examples/zadic_resource.h b/examples/zadic_resource.h deleted file mode 100644 index c353fbce..00000000 --- a/examples/zadic_resource.h +++ /dev/null @@ -1,15 +0,0 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Visual C++ generated include file. -// Used by zadic.rc -// - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 101 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1000 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif diff --git a/examples/zadig.c b/examples/zadig.c index 4c2f6fab..580bf59c 100644 --- a/examples/zadig.c +++ b/examples/zadig.c @@ -1,6 +1,6 @@ /* * Zadig: Automated Driver Installer for USB devices (GUI version) - * Copyright (c) 2010-2020 Pete Batard + * Copyright (c) 2010-2025 Pete Batard * For more info, please visit http://libwdi.akeo.ie * * This program is free software: you can redistribute it and/or modify @@ -32,6 +32,7 @@ #include #include +#include #include #include #include @@ -82,13 +83,15 @@ WORD application_version[4]; char app_dir[MAX_PATH], driver_text[64]; char szFolderPath[MAX_PATH]; const char* driver_display_name[WDI_NB_DRIVERS] = { "WinUSB", "libusb-win32", "libusbK", "USB Serial (CDC)", "Custom (extract only)" }; -const char* driver_name[WDI_NB_DRIVERS-1] = { "WinUSB", "libusb0", "libusbK", "usbser" }; +const char* driver_name[WDI_NB_DRIVERS] = { "WinUSB", "libusb0", "libusbK", "usbser", "custom" }; struct wdi_options_create_list cl_options = { 0 }; struct wdi_options_prepare_driver pd_options = { 0 }; struct wdi_options_install_cert ic_options = { 0 }; struct wdi_options_install_driver id_options = { 0 }; struct wdi_device_info *device, *list = NULL; int current_device_index = CB_ERR; +int windows_version = WINDOWS_UNDEFINED; +char windows_version_str[128]; char* current_device_hardware_id = NULL; char* editable_desc = NULL; int default_driver_type = WDI_WINUSB; @@ -117,23 +120,24 @@ EXT_DECL(cfg_ext, "sample.cfg", __VA_GROUP__("*.cfg"), __VA_GROUP__("Zadig devic */ void w_printf_v(BOOL update_status, const char *format, va_list args) { - char str[STR_BUFFER_SIZE+2]; + char str[STR_BUFFER_SIZE + 2]; int size; size_t slen; size = safe_vsnprintf(str, STR_BUFFER_SIZE, format, args); if (size < 0) { - str[STR_BUFFER_SIZE-1] = 0; - str[STR_BUFFER_SIZE-2] = ']'; - str[STR_BUFFER_SIZE-3] = str[STR_BUFFER_SIZE-4] = str[STR_BUFFER_SIZE-5] = '.'; - str[STR_BUFFER_SIZE-6] = '['; + str[STR_BUFFER_SIZE - 1] = 0; + str[STR_BUFFER_SIZE - 2] = ']'; + str[STR_BUFFER_SIZE - 3] = str[STR_BUFFER_SIZE - 4] = str[STR_BUFFER_SIZE - 5] = '.'; + str[STR_BUFFER_SIZE - 6] = '['; } slen = safe_strlen(str); str[slen] = '\r'; - str[slen+1] = '\n'; - str[slen+2] = 0; + str[slen + 1] = '\n'; + str[slen + 2] = 0; // Also send output to debug logger + // coverity[dont_call] OutputDebugStringA(str); // Set cursor to the end of the buffer Edit_SetSel(hInfo, MAX_LOG_SIZE, MAX_LOG_SIZE); @@ -404,7 +408,8 @@ int install_driver(void) if ((pd_options.use_wcid_driver) && (dev != NULL)) { safe_free(dev->desc); } - if (need_dealloc) { + if (need_dealloc && (dev != NULL)) { + free(dev->desc); free(dev); } safe_free(inf_name); @@ -445,7 +450,7 @@ void set_filter_menu(BOOL display) mi_filter.cch = (UINT)strlen(itemddesc[has_filter_driver?1:0]); if (filter_is_displayed) { - // Always perform delete + display for Delete <-> Install toggle after successfull install/delete + // Always perform delete + display for Delete <-> Install toggle after successful install/delete DeleteMenu(hMenuSplit, IDM_SPLIT_FILTER, MF_BYCOMMAND); if (display) { InsertMenuItemA(hMenuSplit, IDM_SPLIT_EXTRACT, FALSE, &mi_filter); @@ -485,12 +490,14 @@ void set_default_driver(void) { void set_driver(void) { VS_FIXEDFILEINFO file_info; - char target_text[64]; + char target_text[64] = { 0 }; if ((pd_options.driver_type == WDI_CDC) || (pd_options.driver_type >= WDI_USER)) { - static_sprintf(target_text, "%s", driver_display_name[pd_options.driver_type]); - EnableMenuItem(hMenuOptions, IDM_CREATECAT, MF_GRAYED); - EnableMenuItem(hMenuOptions, IDM_SIGNCAT, MF_GRAYED); + if (pd_options.driver_type < WDI_NB_DRIVERS) { + static_sprintf(target_text, "%s", driver_display_name[pd_options.driver_type]); + EnableMenuItem(hMenuOptions, IDM_CREATECAT, MF_GRAYED); + EnableMenuItem(hMenuOptions, IDM_SIGNCAT, MF_GRAYED); + } } else { EnableMenuItem(hMenuOptions, IDM_CREATECAT, MF_ENABLED); EnableMenuItem(hMenuOptions, IDM_SIGNCAT, pd_options.disable_cat?MF_GRAYED:MF_ENABLED); @@ -809,6 +816,308 @@ void set_loglevel(DWORD menu_cmd) wdi_set_log_level(log_level); } +static __inline USHORT get_application_arch(void) +{ +#if defined(_M_AMD64) + return IMAGE_FILE_MACHINE_AMD64; +#elif defined(_M_IX86) + return IMAGE_FILE_MACHINE_I386; +#elif defined(_M_ARM64) + return IMAGE_FILE_MACHINE_ARM64; +#elif defined(_M_ARM) + return IMAGE_FILE_MACHINE_ARM; +#else + return IMAGE_FILE_MACHINE_UNKNOWN; +#endif +} + +static __inline const char* get_arch_name(USHORT uArch) +{ + switch (uArch) { + case IMAGE_FILE_MACHINE_AMD64: + return "x64"; + case IMAGE_FILE_MACHINE_I386: + return "x86"; + case IMAGE_FILE_MACHINE_ARM64: + return "arm64"; + case IMAGE_FILE_MACHINE_ARM: + return "arm"; + default: + return "unknown"; + } +} + +// Detect the underlying platform arch. +static USHORT get_platform_arch(void) +{ + BOOL is_64bit = FALSE, is_wow64 = FALSE; + USHORT ProcessMachine = IMAGE_FILE_MACHINE_UNKNOWN, NativeMachine = IMAGE_FILE_MACHINE_UNKNOWN; + + PF_TYPE_DECL(WINAPI, BOOL, IsWow64Process2, (HANDLE, USHORT*, USHORT*)); + PF_INIT(IsWow64Process2, Kernel32); + + if ((pfIsWow64Process2 == NULL) || + !pfIsWow64Process2(GetCurrentProcess(), &ProcessMachine, &NativeMachine)) { + // Assume same arch as the app + NativeMachine = get_application_arch(); + // Fix the Arch if we have a 32-bit app running under WOW64 + if ((sizeof(uintptr_t) < 8) && IsWow64Process(GetCurrentProcess(), &is_wow64) && is_wow64) { + if (NativeMachine == IMAGE_FILE_MACHINE_I386) + NativeMachine = IMAGE_FILE_MACHINE_AMD64; + else if (NativeMachine == IMAGE_FILE_MACHINE_ARM) + NativeMachine = IMAGE_FILE_MACHINE_ARM64; + else // I sure wanna be made aware of this scenario... + assert(FALSE); + } + dprintf("Note: Underlying Windows architecture was guessed and may be incorrect..."); + } + + return NativeMachine; +} + +static const char* get_edition(DWORD ProductType) +{ + static char unknown_edition_str[64]; + + // From: https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getproductinfo + // These values can be found in the winnt.h header. + switch (ProductType) { + case 0x00000000: return ""; // Undefined + case 0x00000001: return "Ultimate"; + case 0x00000002: return "Home Basic"; + case 0x00000003: return "Home Premium"; + case 0x00000004: return "Enterprise"; + case 0x00000005: return "Home Basic N"; + case 0x00000006: return "Business"; + case 0x00000007: return "Server Standard"; + case 0x00000008: return "Server Datacenter"; + case 0x00000009: return "Smallbusiness Server"; + case 0x0000000A: return "Server Enterprise"; + case 0x0000000B: return "Starter"; + case 0x0000000C: return "Server Datacenter (Core)"; + case 0x0000000D: return "Server Standard (Core)"; + case 0x0000000E: return "Server Enterprise (Core)"; + case 0x00000010: return "Business N"; + case 0x00000011: return "Web Server"; + case 0x00000012: return "HPC Edition"; + case 0x00000013: return "Storage Server (Essentials)"; + case 0x0000001A: return "Home Premium N"; + case 0x0000001B: return "Enterprise N"; + case 0x0000001C: return "Ultimate N"; + case 0x00000022: return "Home Server"; + case 0x00000024: return "Server Standard without Hyper-V"; + case 0x00000025: return "Server Datacenter without Hyper-V"; + case 0x00000026: return "Server Enterprise without Hyper-V"; + case 0x00000027: return "Server Datacenter without Hyper-V (Core)"; + case 0x00000028: return "Server Standard without Hyper-V (Core)"; + case 0x00000029: return "Server Enterprise without Hyper-V (Core)"; + case 0x0000002A: return "Hyper-V Server"; + case 0x0000002F: return "Starter N"; + case 0x00000030: return "Pro"; + case 0x00000031: return "Pro N"; + case 0x00000034: return "Server Solutions Premium"; + case 0x00000035: return "Server Solutions Premium (Core)"; + case 0x00000040: return "Server Hyper Core V"; + case 0x00000042: return "Starter E"; + case 0x00000043: return "Home Basic E"; + case 0x00000044: return "Premium E"; + case 0x00000045: return "Pro E"; + case 0x00000046: return "Enterprise E"; + case 0x00000047: return "Ultimate E"; + case 0x00000048: return "Enterprise (Eval)"; + case 0x0000004F: return "Server Standard (Eval)"; + case 0x00000050: return "Server Datacenter (Eval)"; + case 0x00000054: return "Enterprise N (Eval)"; + case 0x00000057: return "Thin PC"; + case 0x00000058: case 0x00000059: case 0x0000005A: case 0x0000005B: case 0x0000005C: return "Embedded"; + case 0x00000062: return "Home N"; + case 0x00000063: return "Home China"; + case 0x00000064: return "Home Single Language"; + case 0x00000065: return "Home"; + case 0x00000067: return "Pro with Media Center"; + case 0x00000069: case 0x0000006A: case 0x0000006B: case 0x0000006C: return "Embedded"; + case 0x0000006F: return "Home Connected"; + case 0x00000070: return "Pro Student"; + case 0x00000071: return "Home Connected N"; + case 0x00000072: return "Pro Student N"; + case 0x00000073: return "Home Connected Single Language"; + case 0x00000074: return "Home Connected China"; + case 0x00000079: return "Education"; + case 0x0000007A: return "Education N"; + case 0x0000007D: return "Enterprise LTSB"; + case 0x0000007E: return "Enterprise LTSB N"; + case 0x0000007F: return "Pro S"; + case 0x00000080: return "Pro S N"; + case 0x00000081: return "Enterprise LTSB (Eval)"; + case 0x00000082: return "Enterprise LTSB N (Eval)"; + case 0x0000008A: return "Pro Single Language"; + case 0x0000008B: return "Pro China"; + case 0x0000008C: return "Enterprise Subscription"; + case 0x0000008D: return "Enterprise Subscription N"; + case 0x00000091: return "Server Datacenter SA (Core)"; + case 0x00000092: return "Server Standard SA (Core)"; + case 0x00000095: return "Utility VM"; + case 0x000000A1: return "Pro for Workstations"; + case 0x000000A2: return "Pro for Workstations N"; + case 0x000000A4: return "Pro for Education"; + case 0x000000A5: return "Pro for Education N"; + case 0x000000AB: return "Enterprise G"; // I swear Microsoft are just making up editions... + case 0x000000AC: return "Enterprise G N"; + case 0x000000B2: return "Cloud"; + case 0x000000B3: return "Cloud N"; + case 0x000000B6: return "Home OS"; + case 0x000000B7: case 0x000000CB: return "Cloud E"; + case 0x000000B9: return "IoT OS"; + case 0x000000BA: case 0x000000CA: return "Cloud E N"; + case 0x000000BB: return "IoT Edge OS"; + case 0x000000BC: return "IoT Enterprise"; + case 0x000000BD: return "Lite"; + case 0x000000BF: return "IoT Enterprise S"; + case 0x000000C0: case 0x000000C2: case 0x000000C3: case 0x000000C4: case 0x000000C5: case 0x000000C6: return "XBox"; + case 0x000000C7: case 0x000000C8: case 0x00000196: case 0x00000197: case 0x00000198: return "Azure Server"; + case 0xABCDABCD: return "(Unlicensed)"; + default: + static_sprintf(unknown_edition_str, "(Unknown Edition 0x%02X)", (uint32_t)ProductType); + return unknown_edition_str; + } +} + +/* + * Modified from smartmontools' os_win32.cpp + */ +int get_windows_version(char* WindowsVersionStr, size_t WindowsVersionStrSize) +{ + OSVERSIONINFOEXA vi, vi2; + DWORD dwProductType; + const char* w = NULL; + const char* arch_name; + char* vptr; + size_t vlen; + unsigned major, minor; + int nWindowsVersion = WINDOWS_UNDEFINED, nWindowsBuildNumber = 0; + ULONGLONG major_equal, minor_equal; + BOOL ws; + + if (WindowsVersionStr == NULL || WindowsVersionStrSize < 32) + return nWindowsVersion; + safe_strcpy(WindowsVersionStr, WindowsVersionStrSize, "Windows Undefined"); + + memset(&vi, 0, sizeof(vi)); + vi.dwOSVersionInfoSize = sizeof(vi); + if (!GetVersionExA((OSVERSIONINFOA*)&vi)) { + memset(&vi, 0, sizeof(vi)); + vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA); + if (!GetVersionExA((OSVERSIONINFOA*)&vi)) + return nWindowsVersion; + } + + if (vi.dwPlatformId == VER_PLATFORM_WIN32_NT) { + + if (vi.dwMajorVersion > 6 || (vi.dwMajorVersion == 6 && vi.dwMinorVersion >= 2)) { + // Starting with Windows 8.1 Preview, GetVersionEx() does no longer report the actual OS version + // See: http://msdn.microsoft.com/en-us/library/windows/desktop/dn302074.aspx + // And starting with Windows 10 Preview 2, Windows enforces the use of the application/supportedOS + // manifest in order for VerSetConditionMask() to report the ACTUAL OS major and minor... + + major_equal = VerSetConditionMask(0, VER_MAJORVERSION, VER_EQUAL); + for (major = vi.dwMajorVersion; major <= 9; major++) { + memset(&vi2, 0, sizeof(vi2)); + vi2.dwOSVersionInfoSize = sizeof(vi2); vi2.dwMajorVersion = major; + if (!VerifyVersionInfoA(&vi2, VER_MAJORVERSION, major_equal)) + continue; + if (vi.dwMajorVersion < major) { + vi.dwMajorVersion = major; vi.dwMinorVersion = 0; + } + + minor_equal = VerSetConditionMask(0, VER_MINORVERSION, VER_EQUAL); + for (minor = vi.dwMinorVersion; minor <= 9; minor++) { + memset(&vi2, 0, sizeof(vi2)); vi2.dwOSVersionInfoSize = sizeof(vi2); + vi2.dwMinorVersion = minor; + if (!VerifyVersionInfoA(&vi2, VER_MINORVERSION, minor_equal)) + continue; + vi.dwMinorVersion = minor; + break; + } + + break; + } + } + + if (vi.dwMajorVersion <= 0xf && vi.dwMinorVersion <= 0xf) { + ws = (vi.wProductType <= VER_NT_WORKSTATION); + nWindowsVersion = vi.dwMajorVersion << 4 | vi.dwMinorVersion; + switch (nWindowsVersion) { + case WINDOWS_XP: w = "XP"; + break; + case WINDOWS_2003: w = (ws ? "XP_64" : (!GetSystemMetrics(89) ? "Server 2003" : "Server 2003_R2")); + break; + case WINDOWS_VISTA: w = (ws ? "Vista" : "Server 2008"); + break; + case WINDOWS_7: w = (ws ? "7" : "Server 2008_R2"); + break; + case WINDOWS_8: w = (ws ? "8" : "Server 2012"); + break; + case WINDOWS_8_1: w = (ws ? "8.1" : "Server 2012_R2"); + break; + case WINDOWS_10_PREVIEW1: w = (ws ? "10 (Preview 1)" : "Server 10 (Preview 1)"); + break; + // Starting with Windows 10 Preview 2, the major is the same as the public-facing version + case WINDOWS_10: + if (vi.dwBuildNumber < 20000) { + w = (ws ? "10" : ((vi.dwBuildNumber < 17763) ? "Server 2016" : "Server 2019")); + break; + } + nWindowsVersion = WINDOWS_11; + // Fall through + case WINDOWS_11: w = (ws ? "11" : "Server 2022"); + break; + default: + if (nWindowsVersion < WINDOWS_XP) + nWindowsVersion = WINDOWS_UNSUPPORTED; + else + w = "12 or later"; + break; + } + } + } + + arch_name = get_arch_name(get_platform_arch()); + + GetProductInfo(vi.dwMajorVersion, vi.dwMinorVersion, vi.wServicePackMajor, vi.wServicePackMinor, &dwProductType); + vptr = &WindowsVersionStr[sizeof("Windows ") - 1]; + vlen = WindowsVersionStrSize - sizeof("Windows ") - 1; + if (!w) + safe_sprintf(vptr, vlen, "%s %u.%u %s", (vi.dwPlatformId == VER_PLATFORM_WIN32_NT ? "NT" : "??"), + (unsigned)vi.dwMajorVersion, (unsigned)vi.dwMinorVersion, arch_name); + else if (vi.wServicePackMinor) + safe_sprintf(vptr, vlen, "%s SP%u.%u %s", w, vi.wServicePackMajor, vi.wServicePackMinor, arch_name); + else if (vi.wServicePackMajor) + safe_sprintf(vptr, vlen, "%s SP%u %s", w, vi.wServicePackMajor, arch_name); + else + safe_sprintf(vptr, vlen, "%s%s%s, %s", + w, (dwProductType != PRODUCT_UNDEFINED) ? " " : "", get_edition(dwProductType), arch_name); + + // Add the build number (including UBR if available) for Windows 8.0 and later + nWindowsBuildNumber = vi.dwBuildNumber; + if (nWindowsVersion >= 0x62) { + HKEY hCurrentVersion; + DWORD dwType = REG_DWORD, dwSize = sizeof(DWORD), dwUbr = 0; + if (RegOpenKeyExA(REGKEY_HKLM, "Software\\Microsoft\\Windows NT\\CurrentVersion", + 0, KEY_READ, &hCurrentVersion) == ERROR_SUCCESS) { + RegQueryValueExA(hCurrentVersion, "UBR", NULL, &dwType, (LPBYTE)&dwUbr, &dwSize); + RegCloseKey(hCurrentVersion); + } + + vptr = &WindowsVersionStr[safe_strlen(WindowsVersionStr)]; + vlen = WindowsVersionStrSize - safe_strlen(WindowsVersionStr) - 1; + if (dwUbr != 0) + safe_sprintf(vptr, vlen, " (Build %d.%d)", nWindowsBuildNumber, (int)dwUbr); + else + safe_sprintf(vptr, vlen, " (Build %d)", nWindowsBuildNumber); + } + return nWindowsVersion; +} + void init_dialog(HWND hDlg) { int i, err; @@ -972,7 +1281,7 @@ void init_dialog(HWND hDlg) PostMessage(hInfo, EM_LIMITTEXT, MAX_LOG_SIZE , 0); dprintf(APP_VERSION); - dprintf(WindowsVersionStr); + dprintf(windows_version_str); // Limit the input size of VID, PID, MI PostMessage(GetDlgItem(hMainDialog, IDC_VID), EM_SETLIMITTEXT, 4, 0); @@ -1031,7 +1340,7 @@ BOOL parse_ini(void) { // Set the log level profile_get_integer(profile, "general", "log_level", NULL, WDI_LOG_LEVEL_INFO, &log_level); - if ((log_level < WDI_LOG_LEVEL_DEBUG) && (log_level > WDI_LOG_LEVEL_NONE)) { + if ((log_level < WDI_LOG_LEVEL_DEBUG) || (log_level > WDI_LOG_LEVEL_NONE)) { log_level = WDI_LOG_LEVEL_INFO; } @@ -1631,6 +1940,7 @@ INT_PTR CALLBACK main_callback(HWND hDlg, UINT message, WPARAM wParam, LPARAM lP case IDM_OPEN: filepath = FileDialog(FALSE, app_dir, &cfg_ext, 0); parse_preset(filepath); + safe_free(filepath); break; case IDM_ABOUT: DialogBoxW(main_instance, MAKEINTRESOURCEW(IDD_ABOUTBOX), hMainDialog, about_callback); @@ -1749,10 +2059,10 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine } // Set the Windows version - GetWindowsVersion(); + windows_version = get_windows_version(windows_version_str, sizeof(windows_version_str)); // Alert users if they are running versions older than Windows 7 - if (nWindowsVersion < WINDOWS_7) { + if (windows_version < WINDOWS_7) { MessageBoxA(NULL, "This version of Zadig can only be run on Windows 7 or later", "Incompatible version", MB_ICONSTOP); CloseHandle(mutex); diff --git a/examples/zadig.h b/examples/zadig.h index c4301edf..a2883232 100644 --- a/examples/zadig.h +++ b/examples/zadig.h @@ -1,251 +1,259 @@ -/* - * Zadig: Automated Driver Installer for USB devices (GUI version) - * Copyright (c) 2010-2018 Pete Batard - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#pragma once - -#if defined(_MSC_VER) -// disable MSVC warnings that are benign -#pragma warning(disable:4100) // unreferenced formal parameter -#pragma warning(disable:4127) // conditional expression is constant -#pragma warning(disable:4201) // nameless struct/union -#pragma warning(disable:4214) // bit field types other than int -#pragma warning(disable:4996) // deprecated API calls -#pragma warning(disable:28159) // more deprecated API calls -#endif - -#ifndef ARRAYSIZE -#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0])) -#endif -#define _IGNORE(expr) do { (void)(expr); } while(0) - -#define APPLICATION_NAME "Zadig" -#define COMPANY_NAME "Akeo Consulting" -#define APPLICATION_URL "https://zadig.akeo.ie" -#define STR_BUFFER_SIZE 512 -#define NOTIFICATION_DELAY 1000 -#define MAX_TOOLTIPS 32 -#define MAX_LOG_SIZE 0x7FFFFFFE -#define MAX_PROGRESS (0xFFFF-1) -#define INI_NAME "zadig.ini" -#define LIBWDI_URL "https://github.com/pbatard/libwdi" -#define LIBUSB_URL "https://github.com/libusb/libusb/wiki/Windows" -#define LIBUSB0_URL "https://sourceforge.net/p/libusb-win32/wiki/Home/" -#define LIBUSBK_URL "http://libusbk.sourceforge.net/UsbK3/index.html" -#define WINUSB_URL "https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/winusb" -#define HELP_URL "https://github.com/pbatard/libwdi/wiki/Zadig" -#define WCID_URL "https://github.com/pbatard/libwdi/wiki/WCID-Devices" -#define USB_IDS_URL "http://www.linux-usb.org/usb-ids.html" -#define DARK_BLUE RGB(0,0,125) -#define BLACK RGB(0,0,0) -#define WHITE RGB(255,255,255) -#define LIGHT_GREY RGB(248,248,248) -#define SEPARATOR_GREY RGB(223,223,223) -#define FIELD_GREEN RGB(232,255,232) -#define FIELD_ORANGE RGB(255,240,200) -#define ARROW_GREEN RGB(92,228,65) -#define ARROW_ORANGE RGB(253,143,56) -#define APP_VERSION "Zadig 2.5.730" - -// These are used to flag end users about the driver they are going to replace -enum driver_type { - DT_SYSTEM, - DT_LIBUSB, - DT_UNKNOWN, - DT_NONE, - NB_DRIVER_TYPES, -}; - -// For our custom notifications -enum notification_type { - MSG_INFO, - MSG_WARNING, - MSG_ERROR, - MSG_QUESTION, -}; -typedef INT_PTR (CALLBACK *Callback_t)(HWND, UINT, WPARAM, LPARAM); -typedef struct { - WORD id; - Callback_t callback; -} notification_info; // To provide a "More info..." on notifications - -// WM_APP is not sent on focus, unlike WM_USER -enum user_message_type { - UM_REFRESH_LIST = WM_APP, - UM_DEVICE_EVENT, - UM_LOGGER_EVENT, - UM_DOWNLOAD_INIT, - UM_DOWNLOAD_EXIT, - UM_NO_UPDATE -}; - -// WCID states -enum wcid_state { - WCID_NONE, - WCID_FALSE, - WCID_TRUE, -}; - -// Timers -#define TID_MESSAGE 0x1000 - -typedef struct { - WORD version[4]; - DWORD platform_min[2]; // minimum platform version required - char* download_url; - char* release_notes; -} APPLICATION_UPDATE; - -/* - * Structure and macros used for the extensions specification of FileDialog() - * You can use: - * EXT_DECL(my_extensions, "default.std", __VA_GROUP__("*.std", "*.other"), __VA_GROUP__("Standard type", "Other Type")); - * to define an 'ext_t my_extensions' variable initialized with the relevant attributes. - */ -typedef struct ext_t { - const size_t count; - const char* filename; - const char** extension; - const char** description; -} ext_t; - -#ifndef __VA_GROUP__ -#define __VA_GROUP__(...) __VA_ARGS__ -#endif -#define EXT_X(prefix, ...) const char* _##prefix##_x[] = { __VA_ARGS__ } -#define EXT_D(prefix, ...) const char* _##prefix##_d[] = { __VA_ARGS__ } -#define EXT_DECL(var, filename, extensions, descriptions) \ - EXT_X(var, extensions); \ - EXT_D(var, descriptions); \ - ext_t var = { ARRAYSIZE(_##var##_x), filename, _##var##_x, _##var##_d } - -#define safe_free(p) do {if ((void*)p != NULL) {free((void*)p); p = NULL;}} while(0) -#define safe_min(a, b) min((size_t)(a), (size_t)(b)) -#define safe_strcp(dst, dst_max, src, count) do {memcpy(dst, src, safe_min(count, dst_max)); \ - ((char*)dst)[safe_min(count, dst_max)-1] = 0;} while(0) -#define safe_strcpy(dst, dst_max, src) safe_strcp(dst, dst_max, src, safe_strlen(src)+1) -#define static_strcpy(dst, src) safe_strcpy(dst, sizeof(dst), src) -#define safe_strncat(dst, dst_max, src, count) strncat(dst, src, safe_min(count, dst_max - safe_strlen(dst) - 1)) -#define safe_strcat(dst, dst_max, src) safe_strncat(dst, dst_max, src, safe_strlen(src)+1) -#define safe_strcmp(str1, str2) strcmp(((str1==NULL)?"":str1), ((str2==NULL)?"":str2)) -#define safe_stricmp(str1, str2) _stricmp(((str1==NULL)?"":str1), ((str2==NULL)?"":str2)) -#define safe_strncmp(str1, str2, count) strncmp(((str1==NULL)?"":str1), ((str2==NULL)?"":str2), count) -#define safe_closehandle(h) do {if (h != INVALID_HANDLE_VALUE) {CloseHandle(h); h = INVALID_HANDLE_VALUE;}} while(0) -#define safe_sprintf(dst, count, ...) do {_snprintf(dst, count, __VA_ARGS__); (dst)[(count)-1] = 0; } while(0) -#define static_sprintf(dst, ...) safe_sprintf(dst, sizeof(dst), __VA_ARGS__) -#define safe_strlen(str) ((((char*)str)==NULL)?0:strlen(str)) -#define safe_strdup _strdup -#define MF_CHECK(cond) ((cond)?MF_CHECKED:MF_UNCHECKED) -#define IGNORE_RETVAL(expr) do { (void)(expr); } while(0) - -#if defined(_MSC_VER) -#define safe_vsnprintf(buf, size, format, arg) _vsnprintf_s(buf, size, _TRUNCATE, format, arg) -#else -#define safe_vsnprintf vsnprintf -#endif - -/* - * Shared prototypes - */ -#define dprintf(...) w_printf(FALSE, __VA_ARGS__) -#define dsprintf(...) w_printf(TRUE, __VA_ARGS__) -#define vuprintf(...) if (verbose) w_printf(FALSE, __VA_ARGS__) -#define vvuprintf(...) if (verbose > 1) w_printf(FALSE, __VA_ARGS__) -void print_status(unsigned int duration, BOOL debug, const char* message); -int detect_windows_version(void); -void w_printf(BOOL update_status, const char *format, ...); -void BrowseForFolder(void); -char* FileDialog(BOOL save, char* path, const ext_t* ext, DWORD options); -BOOL FileIo(BOOL save, char* path, char** buffer, DWORD* size); -INT_PTR CALLBACK about_callback(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); -INT_PTR CALLBACK UpdateCallback(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); -void create_status_bar(void); -BOOL is_x64(void); -BOOL notification(int type, const notification_info* more_info, char* title, char* format, ...); -int run_with_progress_bar(int(*function)(void)); -char* to_valid_filename(char* name, char* ext); -HWND create_tooltip(HWND hWnd, char* message, int duration); -void destroy_tooltip(HWND hWnd); -void destroy_all_tooltips(void); -void set_title_bar_icon(HWND hDlg); -const char *WindowsErrorString(void); -void download_new_version(void); -void parse_update(char* buf, size_t len); -DWORD DownloadFile(const char* url, const char* file, HWND hProgressDialog); -HANDLE DownloadFileThreaded(const char* url, const char* file, HWND hProgressDialog); -BOOL SetUpdateCheck(void); -BOOL CheckForUpdates(BOOL force); - -/* - * Globals - */ -extern HINSTANCE main_instance; -extern HWND hDeviceList; -extern HWND hMainDialog; -extern HWND hInfo; -extern HWND hStatus; -extern WORD application_version[4]; -extern DWORD error_code; -extern char szFolderPath[MAX_PATH], app_dir[MAX_PATH]; -extern int dialog_showing; -extern BOOL installation_running; -extern APPLICATION_UPDATE update; - -/* - * typedefs for the function prototypes. Use the something like: - * PF_DECL(FormatEx); - * which translates to: - * FormatEx_t pfFormatEx = NULL; - * in your code, to declare the entrypoint and then use: - * PF_INIT(FormatEx, Fmifs); - * which translates to: - * pfFormatEx = (FormatEx_t) GetProcAddress(GetLibraryHandle("fmifs"), "FormatEx"); - * to make it accessible. - */ -#define MAX_LIBRARY_HANDLES 32 -extern HMODULE OpenedLibrariesHandle[MAX_LIBRARY_HANDLES]; -extern WORD OpenedLibrariesHandleSize; -#define OPENED_LIBRARIES_VARS HMODULE OpenedLibrariesHandle[MAX_LIBRARY_HANDLES]; WORD OpenedLibrariesHandleSize = 0 -static __inline void FreeAllLibraries(void) { - while (OpenedLibrariesHandleSize > 0) - FreeLibrary(OpenedLibrariesHandle[--OpenedLibrariesHandleSize]); -} -static __inline HMODULE GetLibraryHandle(char* szLibraryName) { - HMODULE h = NULL; - if ((h = GetModuleHandleA(szLibraryName)) == NULL) { - if (OpenedLibrariesHandleSize >= MAX_LIBRARY_HANDLES) { - dprintf("Error: MAX_LIBRARY_HANDLES is too small\n"); - } else { - h = LoadLibraryA(szLibraryName); - if (h != NULL) - OpenedLibrariesHandle[OpenedLibrariesHandleSize++] = h; - } - } - return h; -} -#define PF_TYPE(api, ret, proc, args) typedef ret (api *proc##_t)args -#define PF_DECL(proc) static proc##_t pf##proc = NULL -#define PF_TYPE_DECL(api, ret, proc, args) PF_TYPE(api, ret, proc, args); PF_DECL(proc) -#define PF_INIT(proc, name) if (pf##proc == NULL) pf##proc = \ - (proc##_t) GetProcAddress(GetLibraryHandle(#name), #proc) -#define PF_INIT_OR_OUT(proc, name) do {PF_INIT(proc, name); \ - if (pf##proc == NULL) {dprintf("Unable to locate %s() in %s.dll: %s\n", \ - #proc, #name, WindowsErrorString()); goto out;} } while(0) - -#ifndef ARRAYSIZE -#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0])) -#endif +/* + * Zadig: Automated Driver Installer for USB devices (GUI version) + * Copyright (c) 2010-2025 Pete Batard + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#if defined(_MSC_VER) +// disable MSVC warnings that are benign +#pragma warning(disable:4100) // unreferenced formal parameter +#pragma warning(disable:4127) // conditional expression is constant +#pragma warning(disable:4201) // nameless struct/union +#pragma warning(disable:4214) // bit field types other than int +#pragma warning(disable:4996) // deprecated API calls +#pragma warning(disable:28159) // more deprecated API calls +#endif + +#ifndef ARRAYSIZE +#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0])) +#endif +#define _IGNORE(expr) do { (void)(expr); } while(0) + +#define APPLICATION_NAME "Zadig" +#define COMPANY_NAME "Akeo Consulting" +#define APPLICATION_URL "https://zadig.akeo.ie" +#define STR_BUFFER_SIZE 512 +#define NOTIFICATION_DELAY 1000 +#define NET_SESSION_TIMEOUT 3500 +#define MAX_TOOLTIPS 32 +#define MAX_LOG_SIZE 0x7FFFFFFE +#define MAX_PROGRESS (0xFFFF-1) +#define INI_NAME "zadig.ini" +#define LIBWDI_URL "https://github.com/pbatard/libwdi" +#define LIBUSB_URL "https://github.com/libusb/libusb/wiki/Windows" +#define LIBUSB0_URL "https://sourceforge.net/p/libusb-win32/wiki/Home/" +#define LIBUSBK_URL "http://libusbk.sourceforge.net/UsbK3/index.html" +#define WINUSB_URL "https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/winusb" +#define HELP_URL "https://github.com/pbatard/libwdi/wiki/Zadig" +#define WCID_URL "https://github.com/pbatard/libwdi/wiki/WCID-Devices" +#define USB_IDS_URL "http://www.linux-usb.org/usb-ids.html" +#define DARK_BLUE RGB(0,0,125) +#define BLACK RGB(0,0,0) +#define WHITE RGB(255,255,255) +#define LIGHT_GREY RGB(248,248,248) +#define SEPARATOR_GREY RGB(223,223,223) +#define FIELD_GREEN RGB(232,255,232) +#define FIELD_ORANGE RGB(255,240,200) +#define ARROW_GREEN RGB(92,228,65) +#define ARROW_ORANGE RGB(253,143,56) +#define APP_VERSION "Zadig 2.9.791" + +// These are used to flag end users about the driver they are going to replace +enum driver_type { + DT_SYSTEM, + DT_LIBUSB, + DT_UNKNOWN, + DT_NONE, + NB_DRIVER_TYPES, +}; + +// For our custom notifications +enum notification_type { + MSG_INFO, + MSG_WARNING, + MSG_ERROR, + MSG_QUESTION, +}; +typedef INT_PTR (CALLBACK *Callback_t)(HWND, UINT, WPARAM, LPARAM); +typedef struct { + WORD id; + Callback_t callback; +} notification_info; // To provide a "More info..." on notifications + +// WM_APP is not sent on focus, unlike WM_USER +enum user_message_type { + UM_REFRESH_LIST = WM_APP, + UM_DEVICE_EVENT, + UM_LOGGER_EVENT, + UM_DOWNLOAD_INIT, + UM_DOWNLOAD_EXIT, + UM_NO_UPDATE +}; + +// WCID states +enum wcid_state { + WCID_NONE, + WCID_FALSE, + WCID_TRUE, +}; + +// Timers +#define TID_MESSAGE 0x1000 + +typedef struct { + WORD version[4]; + DWORD platform_min[2]; // minimum platform version required + char* download_url; + char* release_notes; +} APPLICATION_UPDATE; + +/* + * Structure and macros used for the extensions specification of FileDialog() + * You can use: + * EXT_DECL(my_extensions, "default.std", __VA_GROUP__("*.std", "*.other"), __VA_GROUP__("Standard type", "Other Type")); + * to define an 'ext_t my_extensions' variable initialized with the relevant attributes. + */ +typedef struct ext_t { + const size_t count; + const char* filename; + const char** extension; + const char** description; +} ext_t; + +#ifndef __VA_GROUP__ +#define __VA_GROUP__(...) __VA_ARGS__ +#endif +#define EXT_X(prefix, ...) const char* _##prefix##_x[] = { __VA_ARGS__ } +#define EXT_D(prefix, ...) const char* _##prefix##_d[] = { __VA_ARGS__ } +#define EXT_DECL(var, filename, extensions, descriptions) \ + EXT_X(var, extensions); \ + EXT_D(var, descriptions); \ + ext_t var = { ARRAYSIZE(_##var##_x), filename, _##var##_x, _##var##_d } + +#define safe_free(p) do {free((void*)p); p = NULL;} while(0) +#define safe_min(a, b) min((size_t)(a), (size_t)(b)) +static __inline void safe_strcp(char* dst, const size_t dst_max, const char* src, const size_t count) { + memmove(dst, src, min(count, dst_max)); + dst[min(count, dst_max) - 1] = 0; +} +#define safe_strcpy(dst, dst_max, src) safe_strcp(dst, dst_max, src, safe_strlen(src) + 1) +#define static_strcpy(dst, src) safe_strcpy(dst, sizeof(dst), src) +#define safe_strcat(dst, dst_max, src) strncat_s(dst, dst_max, src, _TRUNCATE) +#define static_strcat(dst, src) safe_strcat(dst, sizeof(dst), (src)) +#define safe_strcmp(str1, str2) strcmp(((str1==NULL)?"":str1), ((str2==NULL)?"":str2)) +#define safe_stricmp(str1, str2) _stricmp(((str1==NULL)?"":str1), ((str2==NULL)?"":str2)) +#define safe_strncmp(str1, str2, count) strncmp(((str1==NULL)?"":str1), ((str2==NULL)?"":str2), count) +#define safe_closehandle(h) do {if ((h != INVALID_HANDLE_VALUE) && (h != NULL)) {CloseHandle(h); h = INVALID_HANDLE_VALUE;}} while(0) +#define safe_sprintf(dst, count, ...) do { size_t _count = count; char* _dst = dst; _snprintf_s(_dst, _count, _TRUNCATE, __VA_ARGS__); \ + _dst[(_count) - 1] = 0; } while(0) +#define static_sprintf(dst, ...) safe_sprintf(dst, sizeof(dst), __VA_ARGS__) +#define safe_strlen(str) ((((char*)str)==NULL)?0:strlen(str)) +#define static_sprintf(dst, ...) safe_sprintf(dst, sizeof(dst), __VA_ARGS__) +#define safe_swprintf(dst, count, ...) do { size_t _count = count; wchar_t* _dst = dst; _snwprintf_s(_dst, _count, _TRUNCATE, __VA_ARGS__); \ + _dst[(_count) - 1] = 0; } while(0) +#define safe_strdup(str) ((((char*)(str))==NULL) ? NULL : _strdup(str)) +#define MF_CHECK(cond) ((cond)?MF_CHECKED:MF_UNCHECKED) +#define IGNORE_RETVAL(expr) do { (void)(expr); } while(0) + +#if defined(_MSC_VER) +#define safe_vsnprintf(buf, size, format, arg) _vsnprintf_s(buf, size, _TRUNCATE, format, arg) +#else +#define safe_vsnprintf vsnprintf +#endif + +/* + * Shared prototypes + */ +#define dprintf(...) w_printf(FALSE, __VA_ARGS__) +#define dsprintf(...) w_printf(TRUE, __VA_ARGS__) +#define vuprintf(...) if (verbose) w_printf(FALSE, __VA_ARGS__) +#define vvuprintf(...) if (verbose > 1) w_printf(FALSE, __VA_ARGS__) +void print_status(unsigned int duration, BOOL debug, const char* message); +int get_windows_version(char* WindowsVersionStr, size_t WindowsVersionStrSize); +void w_printf(BOOL update_status, const char *format, ...); +void BrowseForFolder(void); +char* FileDialog(BOOL save, char* path, const ext_t* ext, DWORD options); +BOOL FileIo(BOOL save, char* path, char** buffer, DWORD* size); +INT_PTR CALLBACK about_callback(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); +INT_PTR CALLBACK UpdateCallback(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); +void create_status_bar(void); +BOOL is_x64(void); +BOOL notification(int type, const notification_info* more_info, char* title, char* format, ...); +char* to_valid_filename(char* name, char* ext); +HWND create_tooltip(HWND hWnd, char* message, int duration); +void destroy_tooltip(HWND hWnd); +void destroy_all_tooltips(void); +void set_title_bar_icon(HWND hDlg); +const char *WindowsErrorString(void); +void download_new_version(void); +void parse_update(char* buf, size_t len); +DWORD DownloadFile(const char* url, const char* file, HWND hProgressDialog); +HANDLE DownloadFileThreaded(const char* url, const char* file, HWND hProgressDialog); +BOOL SetUpdateCheck(void); +BOOL CheckForUpdates(BOOL force); + +/* + * Globals + */ +extern HINSTANCE main_instance; +extern HWND hDeviceList; +extern HWND hMainDialog; +extern HWND hInfo; +extern HWND hStatus; +extern WORD application_version[4]; +extern DWORD error_code; +extern char szFolderPath[MAX_PATH], app_dir[MAX_PATH]; +extern int dialog_showing; +extern BOOL installation_running; +extern APPLICATION_UPDATE update; +extern int windows_version; +extern char windows_version_str[128]; + +/* + * typedefs for the function prototypes. Use the something like: + * PF_DECL(FormatEx); + * which translates to: + * FormatEx_t pfFormatEx = NULL; + * in your code, to declare the entrypoint and then use: + * PF_INIT(FormatEx, Fmifs); + * which translates to: + * pfFormatEx = (FormatEx_t) GetProcAddress(GetLibraryHandle("fmifs"), "FormatEx"); + * to make it accessible. + */ +#define MAX_LIBRARY_HANDLES 32 +extern HMODULE OpenedLibrariesHandle[MAX_LIBRARY_HANDLES]; +extern WORD OpenedLibrariesHandleSize; +#define OPENED_LIBRARIES_VARS HMODULE OpenedLibrariesHandle[MAX_LIBRARY_HANDLES]; WORD OpenedLibrariesHandleSize = 0 +static __inline void FreeAllLibraries(void) { + while (OpenedLibrariesHandleSize > 0) + FreeLibrary(OpenedLibrariesHandle[--OpenedLibrariesHandleSize]); +} +static __inline HMODULE GetLibraryHandle(char* szLibraryName) { + HMODULE h = NULL; + if ((h = GetModuleHandleA(szLibraryName)) == NULL) { + if (OpenedLibrariesHandleSize >= MAX_LIBRARY_HANDLES) { + dprintf("Error: MAX_LIBRARY_HANDLES is too small\n"); + } else { + h = LoadLibraryA(szLibraryName); + if (h != NULL) + OpenedLibrariesHandle[OpenedLibrariesHandleSize++] = h; + } + } + return h; +} +#define PF_TYPE(api, ret, proc, args) typedef ret (api *proc##_t)args +#define PF_DECL(proc) static proc##_t pf##proc = NULL +#define PF_TYPE_DECL(api, ret, proc, args) PF_TYPE(api, ret, proc, args); PF_DECL(proc) +#define PF_INIT(proc, name) if (pf##proc == NULL) pf##proc = \ + (proc##_t) GetProcAddress(GetLibraryHandle(#name), #proc) +#define PF_INIT_OR_OUT(proc, name) do {PF_INIT(proc, name); \ + if (pf##proc == NULL) {dprintf("Unable to locate %s() in %s.dll: %s\n", \ + #proc, #name, WindowsErrorString()); goto out;} } while(0) + +#ifndef ARRAYSIZE +#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0])) +#endif diff --git a/examples/zadig.rc b/examples/zadig.rc index 9838ba46..9516b61c 100644 --- a/examples/zadig.rc +++ b/examples/zadig.rc @@ -151,7 +151,7 @@ BEGIN LTEXT "WCID",IDC_STATIC_WCID,14,84,18,9,SS_NOTIFY EDITTEXT IDC_WCID_BOX,40,82,14,14,ES_READONLY | NOT WS_TABSTOP EDITTEXT IDC_WCID,55,82,44,14,ES_READONLY | NOT WS_VISIBLE | NOT WS_TABSTOP,WS_EX_TRANSPARENT - LTEXT "ð",IDC_RARR,142,44,17,14,SS_NOTIFY | SS_CENTERIMAGE | NOT WS_VISIBLE + LTEXT "",IDC_RARR,142,44,17,14,SS_NOTIFY | SS_CENTERIMAGE | NOT WS_VISIBLE EDITTEXT IDC_TARGET,162,44,98,14,ES_READONLY | NOT WS_TABSTOP CONTROL "",IDC_TARGETSPIN,"msctls_updown32",UDS_ARROWKEYS,260,44,11,14,WS_EX_TRANSPARENT CONTROL IDB_ZADIG,IDC_THIS_SPACE_FOR_RENT,"Static",SS_BITMAP | SS_CENTERIMAGE | SS_REALSIZEIMAGE,278,37,97,66 @@ -246,8 +246,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 2,5,730,0 - PRODUCTVERSION 2,5,730,0 + FILEVERSION 2,9,791,0 + PRODUCTVERSION 2,9,791,0 FILEFLAGSMASK 0x17L #ifdef _DEBUG FILEFLAGS 0x1L @@ -264,14 +264,14 @@ BEGIN BEGIN VALUE "CompanyName", "akeo.ie" VALUE "FileDescription", "Zadig" - VALUE "FileVersion", "2.5.730" + VALUE "FileVersion", "2.9.791" VALUE "InternalName", "Zadig" - VALUE "LegalCopyright", "© 2010-2018 Pete Batard (GPL v3)" - VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html" + VALUE "LegalCopyright", "© 2010-2025 Pete Batard (GPL v3)" + VALUE "LegalTrademarks", "https://www.gnu.org/licenses/gpl-3.0.html" VALUE "OriginalFilename", "zadig.exe" VALUE "ProductName", "Zadig" - VALUE "ProductVersion", "2.5.730" - VALUE "Comments", "http://libwdi.akeo.ie" + VALUE "ProductVersion", "2.9.791" + VALUE "Comments", "https://zadig.akeo.ie" END END BLOCK "VarFileInfo" diff --git a/examples/zadig_license.h b/examples/zadig_license.h index a08182ce..d4daddcf 100644 --- a/examples/zadig_license.h +++ b/examples/zadig_license.h @@ -1,6 +1,6 @@ /* * Zadig: Automated Driver Installer for USB devices (GUI version) - * Copyright (c) 2010-2020 Pete Batard + * Copyright (c) 2010-2025 Pete Batard * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,7 +21,7 @@ const char* about_blurb_format = "{\\b\\fs20Zadig - The Automated Driver Installer}\\line\n" "\\fs18Version %d.%d (Build %d)\\line\n" "\\line\n" -"Copyright © 2010-2020 Pete Batard / Akeo\\line\n" +"Copyright © 2010-2025 Pete Batard / Akeo\\line\n" APPLICATION_URL "\\line\n" "\\line\n" "Report bugs or request enhancements at:\\line\n" @@ -32,7 +32,7 @@ APPLICATION_URL "\\line\n" const char* additional_copyrights = "{\\rtf1\\ansi\n" "Windows Driver Installer library, libwdi:\\line\n" -"Copyright © 2010-2020 by Pete Batard et al.\\line\n" +"Copyright © 2010-2025 by Pete Batard et al.\\line\n" "GNU Lesser General Public License (LGPL) v3 or later\\line\n" "https://github.com/pbatard/libwdi/wiki\\line\n" "\\line\n" diff --git a/examples/zadig_net.c b/examples/zadig_net.c index 67c3d1f4..2878be6c 100644 --- a/examples/zadig_net.c +++ b/examples/zadig_net.c @@ -1,7 +1,7 @@ /* * Zadig: Automated Driver Installer for USB devices (GUI version) * Networking functionality (web file download, check for update, etc.) - * Copyright © 2012-2017 Pete Batard + * Copyright © 2012-2024 Pete Batard * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -25,6 +25,7 @@ #include #include +#include #include #include #include @@ -36,18 +37,36 @@ #include "zadig_registry.h" #include "zadig_resource.h" +#if defined(__MINGW32__) +#define INetworkListManager_get_IsConnectedToInternet INetworkListManager_IsConnectedToInternet +#endif + /* Maximum download chunk size, in bytes */ #define DOWNLOAD_BUFFER_SIZE 10240 /* Default delay between update checks (1 day) */ -#define DEFAULT_UPDATE_INTERVAL (24*3600) +#define DEFAULT_UPDATE_INTERVAL (24 * 3600) DWORD error_code; -APPLICATION_UPDATE update = { {0,0,0,0}, {0,0}, NULL, NULL }; +APPLICATION_UPDATE update = { { 0,0,0,0 }, { 0,0 }, NULL, NULL }; static BOOL force_update = FALSE; static BOOL force_update_check = FALSE; static BOOL update_check_in_progress = FALSE; +static const char* GetAppArchName(void) { +#if defined(_M_AMD64) + return "x64"; +#elif defined(_M_IX86) + return "x86"; +#elif defined(_M_ARM64) + return "arm64"; +#elif defined(_M_ARM) + return "arm"; +#else + return "unknown"; +#endif +} + /* MinGW is missing some of those */ #if !defined(ERROR_INTERNET_DISCONNECTED) #define ERROR_INTERNET_DISCONNECTED (INTERNET_ERROR_BASE + 163) @@ -243,6 +262,69 @@ const char* WinInetErrorString(void) } } +static __inline BOOL is_WOW64(void) +{ + BOOL ret = FALSE; + IsWow64Process(GetCurrentProcess(), &ret); + return ret; +} + +/* + * Open an Internet session + */ +static HINTERNET GetInternetSession(int num_retries) +{ + int i; + char agent[64]; + BOOL decodingSupport = TRUE; + VARIANT_BOOL InternetConnection = VARIANT_FALSE; + DWORD dwFlags, dwTimeout = NET_SESSION_TIMEOUT, dwProtocolSupport = HTTP_PROTOCOL_FLAG_HTTP2; + HINTERNET hSession = NULL; + HRESULT hr = S_FALSE; + INetworkListManager* pNetworkListManager; + + // Create a NetworkListManager Instance to check the network connection + IGNORE_RETVAL(CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE)); + hr = CoCreateInstance(&CLSID_NetworkListManager, NULL, CLSCTX_ALL, + &IID_INetworkListManager, (LPVOID*)&pNetworkListManager); + if (hr == S_OK) { + for (i = 0; i <= num_retries; i++) { + hr = INetworkListManager_get_IsConnectedToInternet(pNetworkListManager, &InternetConnection); + if (hr == S_OK && InternetConnection == VARIANT_TRUE) + break; + // INetworkListManager may fail with ERROR_SERVICE_DEPENDENCY_FAIL if the DHCP service + // is not running, in which case we must fall back to using InternetGetConnectedState(). + // See https://github.com/pbatard/rufus/issues/1801. + if (hr == HRESULT_FROM_WIN32(ERROR_SERVICE_DEPENDENCY_FAIL)) { + if (InternetGetConnectedState(&dwFlags, 0)) { + InternetConnection = VARIANT_TRUE; + break; + } + } + Sleep(1000); + } + } + if (InternetConnection == VARIANT_FALSE) { + SetLastError(ERROR_INTERNET_DISCONNECTED); + goto out; + } + static_sprintf(agent, APPLICATION_NAME "/%d.%d.%d (Windows NT %d.%d%s)", + application_version[0], application_version[1], application_version[2], + windows_version >> 4, windows_version & 0x0F, is_WOW64() ? "; WOW64" : ""); + hSession = InternetOpenA(agent, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); + // Set the timeouts + InternetSetOptionA(hSession, INTERNET_OPTION_CONNECT_TIMEOUT, (LPVOID)&dwTimeout, sizeof(dwTimeout)); + InternetSetOptionA(hSession, INTERNET_OPTION_SEND_TIMEOUT, (LPVOID)&dwTimeout, sizeof(dwTimeout)); + InternetSetOptionA(hSession, INTERNET_OPTION_RECEIVE_TIMEOUT, (LPVOID)&dwTimeout, sizeof(dwTimeout)); + // Enable gzip and deflate decoding schemes + InternetSetOptionA(hSession, INTERNET_OPTION_HTTP_DECODING, (LPVOID)&decodingSupport, sizeof(decodingSupport)); + // Enable HTTP/2 protocol support + InternetSetOptionA(hSession, INTERNET_OPTION_ENABLE_HTTP_PROTOCOL, (LPVOID)&dwProtocolSupport, sizeof(dwProtocolSupport)); + +out: + return hSession; +} + /* * Download a file from an URL * Mostly taken from http://support.microsoft.com/kb/234913 @@ -255,17 +337,16 @@ DWORD DownloadFile(const char* url, const char* file, HWND hProgressDialog) HWND hProgressBar = NULL; BOOL r = FALSE; LONG progress_style; - DWORD dwFlags, dwSize, dwWritten, dwDownloaded, dwTotalSize; + DWORD dwSize, dwWritten, dwDownloaded, dwTotalSize; DWORD DownloadStatus; HANDLE hFile = INVALID_HANDLE_VALUE; const char* accept_types[] = {"*/*\0", NULL}; unsigned char buf[DOWNLOAD_BUFFER_SIZE]; - char agent[64], hostname[64], urlpath[128], msg[MAX_PATH]; + char hostname[64], urlpath[128], msg[MAX_PATH]; HINTERNET hSession = NULL, hConnection = NULL, hRequest = NULL; URL_COMPONENTSA UrlParts = {sizeof(URL_COMPONENTSA), NULL, 1, (INTERNET_SCHEME)0, hostname, sizeof(hostname), 0, NULL, 1, urlpath, sizeof(urlpath), NULL, 1}; size_t last_slash; - int i; DownloadStatus = 404; if (hProgressDialog != NULL) { @@ -301,19 +382,7 @@ DWORD DownloadFile(const char* url, const char* file, HWND hProgressDialog) hostname[sizeof(hostname)-1] = 0; // Open an Internet session - for (i=5; (i>0) && (!InternetGetConnectedState(&dwFlags, 0)); i--) { - Sleep(1000); - } - if (i <= 0) { - // http://msdn.microsoft.com/en-us/library/windows/desktop/aa384702.aspx is wrong... - SetLastError(ERROR_INTERNET_NOT_INITIALIZED); - dprintf("Network is unavailable: %s\n", WinInetErrorString()); - goto out; - } - static_sprintf(agent, APPLICATION_NAME "/%d.%d.%d (Windows NT %d.%d%s)", - application_version[0], application_version[1], application_version[2], - nWindowsVersion>>4, nWindowsVersion&0x0F, is_x64()?"; WOW64":""); - hSession = InternetOpenA(agent, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); + hSession = GetInternetSession(5); if (hSession == NULL) { dprintf("Could not open Internet session: %s\n", WinInetErrorString()); goto out; @@ -376,7 +445,7 @@ DWORD DownloadFile(const char* url, const char* file, HWND hProgressDialog) dprintf("Error writing file '%s': %s\n", &file[last_slash], WinInetErrorString()); goto out; } else if (dwDownloaded != dwWritten) { - dprintf("Error writing file '%s': Only %d/%d bytes written\n", dwWritten, dwDownloaded); + dprintf("Error writing file '%s': Only %d/%d bytes written\n", &file[last_slash], dwWritten, dwDownloaded); goto out; } } @@ -434,8 +503,8 @@ HANDLE DownloadFileThreaded(const char* url, const char* file, HWND hProgressDia static __inline uint64_t to_uint64_t(uint16_t x[4]) { int i; uint64_t ret = 0; - for (i=0; i<4; i++) - ret = (ret<<16) + x[i]; + for (i = 0; i < 4; i++) + ret = (ret << 16) + x[i]; return ret; } @@ -448,16 +517,16 @@ static DWORD WINAPI CheckForUpdatesThread(LPVOID param) int status = 0; const char* server_url = APPLICATION_URL "/"; int i, j, k, verbose = 0, verpos[4]; - static const char* archname[] = {"win_x86", "win_x64"}; - static const char* channel[] = {"release", "beta"}; // release channel - const char* accept_types[] = {"*/*\0", NULL}; - DWORD dwFlags, dwSize, dwDownloaded, dwTotalSize, dwStatus; + static const char* archname[] = { "win_x86", "win_x64" }; + static const char* channel[] = { "release", "beta" }; // release channel + const char* accept_types[] = { "*/*\0", NULL }; + DWORD dwSize, dwDownloaded, dwTotalSize, dwStatus; char* buf = NULL; - char agent[64], hostname[64], urlpath[128]; - OSVERSIONINFOA os_version = {sizeof(OSVERSIONINFOA), 0, 0, 0, 0, ""}; + char hostname[64], urlpath[128]; + OSVERSIONINFOA os_version = { sizeof(OSVERSIONINFOA), 0, 0, 0, 0, "" }; HINTERNET hSession = NULL, hConnection = NULL, hRequest = NULL; - URL_COMPONENTSA UrlParts = {sizeof(URL_COMPONENTSA), NULL, 1, (INTERNET_SCHEME)0, - hostname, sizeof(hostname), 0, NULL, 1, urlpath, sizeof(urlpath), NULL, 1}; + URL_COMPONENTSA UrlParts = { sizeof(URL_COMPONENTSA), NULL, 1, (INTERNET_SCHEME)0, + hostname, sizeof(hostname), 0, NULL, 1, urlpath, sizeof(urlpath), NULL, 1 }; SYSTEMTIME ServerTime, LocalTime; FILETIME FileTime; int64_t local_time = 0, reg_time, server_time, update_interval; @@ -472,7 +541,7 @@ static DWORD WINAPI CheckForUpdatesThread(LPVOID param) // It would of course be a lot nicer to use a timer and wake the thread, but my // development time is limited and this is FASTER to implement. do { - for (i=0; (i<30) && (!force_update_check); i++) + for (i = 0; (i < 30) && (!force_update_check); i++) Sleep(500); } while ((!force_update_check) && ((installation_running || (dialog_showing>0)))); if (!force_update_check) { @@ -506,14 +575,10 @@ static DWORD WINAPI CheckForUpdatesThread(LPVOID param) goto out; } - if ((!InternetCrackUrlA(server_url, (DWORD)safe_strlen(server_url), 0, &UrlParts)) || (!InternetGetConnectedState(&dwFlags, 0))) + if (!InternetCrackUrlA(server_url, (DWORD)safe_strlen(server_url), 0, &UrlParts)) goto out; - hostname[sizeof(hostname)-1] = 0; - - static_sprintf(agent, APPLICATION_NAME "/%d.%d.%d (Windows NT %d.%d%s)", - application_version[0], application_version[1], application_version[2], - nWindowsVersion >> 4, nWindowsVersion & 0x0F, is_x64() ? "; WOW64" : ""); - hSession = InternetOpenA(agent, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); + hostname[sizeof(hostname) - 1] = 0; + hSession = GetInternetSession(5); if (hSession == NULL) goto out; hConnection = InternetConnectA(hSession, UrlParts.lpszHostName, UrlParts.nPort, NULL, NULL, INTERNET_SERVICE_HTTP, 0, (DWORD_PTR)NULL); @@ -523,17 +588,17 @@ static DWORD WINAPI CheckForUpdatesThread(LPVOID param) status++; // 2 releases_only = !GetRegistryKeyBool(REGKEY_HKCU, REGKEY_INCLUDE_BETAS); - for (k=0; (k<(releases_only?1:(int)ARRAYSIZE(channel))) && (!found_new_version); k++) { + for (k = 0; (k < (releases_only ? 1 : (int)ARRAYSIZE(channel))) && (!found_new_version); k++) { dprintf("Checking %s channel...\n", channel[k]); // At this stage we can query the server for various update version files. // We first try to lookup for "___.ver" // and then remove each each of the components until we find our match. For instance, we may first // look for _win_x64_6.2.ver (Win8 x64) but only get a match for _win_x64_6.ver (Vista x64 or later) // This allows sunsetting OS versions (eg XP) or providing different downloads for different archs/groups. - static_sprintf(urlpath, "%s%s%s_%s_%ld.%ld.ver", APPLICATION_NAME, (k==0)?"":"_", - (k==0)?"":channel[k], archname[is_x64()?1:0], os_version.dwMajorVersion, os_version.dwMinorVersion); + static_sprintf(urlpath, "%s%s%s_win_%s_%lu.%lu.ver", APPLICATION_NAME, (k == 0) ? "" : "_", + (k == 0) ? "" : channel[k], GetAppArchName(), os_version.dwMajorVersion, os_version.dwMinorVersion); vuprintf("Base update check: %s\n", urlpath); - for (i=0, j=(int)safe_strlen(urlpath)-5; (j>0)&&(i0) && (i= ARRAYSIZE(channel))) + if ((releases_only) || (k + 1 >= ARRAYSIZE(channel))) goto out; continue; } @@ -580,7 +645,7 @@ static DWORD WINAPI CheckForUpdatesThread(LPVOID param) if ( (!HttpQueryInfoA(hRequest, HTTP_QUERY_DATE|HTTP_QUERY_FLAG_SYSTEMTIME, (LPVOID)&ServerTime, &dwSize, NULL)) || (!SystemTimeToFileTime(&ServerTime, &FileTime)) ) goto out; - server_time = ((((int64_t)FileTime.dwHighDateTime)<<32) + FileTime.dwLowDateTime) / 10000000; + server_time = ((((int64_t)FileTime.dwHighDateTime) << 32) + FileTime.dwLowDateTime) / 10000000; vvuprintf("Server time: %" PRId64 "\n", server_time); // Always store the server response time - the only clock we trust! WriteRegistryKey64(REGKEY_HKCU, REGKEY_LAST_UPDATE, server_time); @@ -624,15 +689,18 @@ static DWORD WINAPI CheckForUpdatesThread(LPVOID param) out: safe_free(buf); - if (hRequest) InternetCloseHandle(hRequest); - if (hConnection) InternetCloseHandle(hConnection); - if (hSession) InternetCloseHandle(hSession); + if (hRequest) + InternetCloseHandle(hRequest); + if (hConnection) + InternetCloseHandle(hConnection); + if (hSession) + InternetCloseHandle(hSession); switch(status) { case 1: print_status(3000, TRUE, "Updates: Unable to connect to the internet"); break; case 2: - print_status(3000, TRUE, "Updates: Unable to acces version data"); + print_status(3000, TRUE, "Updates: Unable to access version data"); break; case 3: case 4: diff --git a/libwdi.sln b/libwdi.sln index 550384fb..c5f15f9d 100644 --- a/libwdi.sln +++ b/libwdi.sln @@ -1,6 +1,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.26228.9 +# Visual Studio Version 17 +VisualStudioVersion = 17.5.33414.496 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "examples", "examples", "{CE152D17-B7D5-4ECA-9C6B-BFA86ACBFF75}" EndProject @@ -12,8 +12,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "embedder", "libwdi\.msvc\em EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wdi-simple", "examples\.msvc\wdi-simple.vcxproj", "{84C746FC-0B8B-40C5-9FB0-5EDC8377506D}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zadic", "examples\.msvc\zadic.vcxproj", "{F4938DB0-3DE7-4737-9C5A-EAD1BE819F87}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zadig", "examples\.msvc\zadig.vcxproj", "{F7F7842F-2912-454E-ADF5-0B22987946E2}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libwdi (dll)", "libwdi\.msvc\libwdi_dll.vcxproj", "{79275348-41A4-4D07-8990-4068C9594A2C}" @@ -22,6 +20,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "installer_x86", "libwdi\.ms EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "installer_x64", "libwdi\.msvc\installer_x64.vcxproj", "{E5A56EE0-182F-470F-8CDC-8C1B7B86EE26}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "installer_arm64", "libwdi\.msvc\installer_arm64.vcxproj", "{6AC16F78-F266-4AE0-BD63-550A55F54C15}" +EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "getopt", "examples\getopt\.msvc\getopt.vcxproj", "{AE83E1B4-CE06-47EE-B7A3-C3A1D7C2D71E}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "detect_64build", "libwdi\.msvc\detect_64build.vcxproj", "{5FAEF8F7-C809-4A68-862F-F8BC6E775B61}" @@ -58,14 +58,6 @@ Global {84C746FC-0B8B-40C5-9FB0-5EDC8377506D}.Release|Win32.Build.0 = Release|Win32 {84C746FC-0B8B-40C5-9FB0-5EDC8377506D}.Release|x64.ActiveCfg = Release|x64 {84C746FC-0B8B-40C5-9FB0-5EDC8377506D}.Release|x64.Build.0 = Release|x64 - {F4938DB0-3DE7-4737-9C5A-EAD1BE819F87}.Debug|Win32.ActiveCfg = Debug|Win32 - {F4938DB0-3DE7-4737-9C5A-EAD1BE819F87}.Debug|Win32.Build.0 = Debug|Win32 - {F4938DB0-3DE7-4737-9C5A-EAD1BE819F87}.Debug|x64.ActiveCfg = Debug|x64 - {F4938DB0-3DE7-4737-9C5A-EAD1BE819F87}.Debug|x64.Build.0 = Debug|x64 - {F4938DB0-3DE7-4737-9C5A-EAD1BE819F87}.Release|Win32.ActiveCfg = Release|Win32 - {F4938DB0-3DE7-4737-9C5A-EAD1BE819F87}.Release|Win32.Build.0 = Release|Win32 - {F4938DB0-3DE7-4737-9C5A-EAD1BE819F87}.Release|x64.ActiveCfg = Release|x64 - {F4938DB0-3DE7-4737-9C5A-EAD1BE819F87}.Release|x64.Build.0 = Release|x64 {F7F7842F-2912-454E-ADF5-0B22987946E2}.Debug|Win32.ActiveCfg = Debug|Win32 {F7F7842F-2912-454E-ADF5-0B22987946E2}.Debug|Win32.Build.0 = Debug|Win32 {F7F7842F-2912-454E-ADF5-0B22987946E2}.Debug|x64.ActiveCfg = Debug|x64 @@ -92,6 +84,14 @@ Global {E5A56EE0-182F-470F-8CDC-8C1B7B86EE26}.Release|Win32.Build.0 = Release|x64 {E5A56EE0-182F-470F-8CDC-8C1B7B86EE26}.Release|x64.ActiveCfg = Release|x64 {E5A56EE0-182F-470F-8CDC-8C1B7B86EE26}.Release|x64.Build.0 = Release|x64 + {6AC16F78-F266-4AE0-BD63-550A55F54C15}.Debug|Win32.ActiveCfg = Debug|ARM64 + {6AC16F78-F266-4AE0-BD63-550A55F54C15}.Debug|Win32.Build.0 = Debug|ARM64 + {6AC16F78-F266-4AE0-BD63-550A55F54C15}.Debug|x64.ActiveCfg = Debug|ARM64 + {6AC16F78-F266-4AE0-BD63-550A55F54C15}.Debug|x64.Build.0 = Debug|ARM64 + {6AC16F78-F266-4AE0-BD63-550A55F54C15}.Release|Win32.ActiveCfg = Release|ARM64 + {6AC16F78-F266-4AE0-BD63-550A55F54C15}.Release|Win32.Build.0 = Release|ARM64 + {6AC16F78-F266-4AE0-BD63-550A55F54C15}.Release|x64.ActiveCfg = Release|ARM64 + {6AC16F78-F266-4AE0-BD63-550A55F54C15}.Release|x64.Build.0 = Release|ARM64 {AE83E1B4-CE06-47EE-B7A3-C3A1D7C2D71E}.Debug|Win32.ActiveCfg = Debug|Win32 {AE83E1B4-CE06-47EE-B7A3-C3A1D7C2D71E}.Debug|Win32.Build.0 = Debug|Win32 {AE83E1B4-CE06-47EE-B7A3-C3A1D7C2D71E}.Debug|x64.ActiveCfg = Debug|x64 @@ -115,8 +115,10 @@ Global GlobalSection(NestedProjects) = preSolution {B1F3B94A-4EC4-406E-9CBF-056E1EA03DE0} = {CE152D17-B7D5-4ECA-9C6B-BFA86ACBFF75} {84C746FC-0B8B-40C5-9FB0-5EDC8377506D} = {CE152D17-B7D5-4ECA-9C6B-BFA86ACBFF75} - {F4938DB0-3DE7-4737-9C5A-EAD1BE819F87} = {CE152D17-B7D5-4ECA-9C6B-BFA86ACBFF75} {F7F7842F-2912-454E-ADF5-0B22987946E2} = {CE152D17-B7D5-4ECA-9C6B-BFA86ACBFF75} {AE83E1B4-CE06-47EE-B7A3-C3A1D7C2D71E} = {B1F3B94A-4EC4-406E-9CBF-056E1EA03DE0} EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {31CAC804-E47E-4336-B896-016DFB1117CB} + EndGlobalSection EndGlobal diff --git a/libwdi/.msvc/detect_64build.vcxproj b/libwdi/.msvc/detect_64build.vcxproj index 8a2a4c8f..8dab22df 100644 --- a/libwdi/.msvc/detect_64build.vcxproj +++ b/libwdi/.msvc/detect_64build.vcxproj @@ -27,22 +27,22 @@ Utility Unicode - v142 + v143 Utility Unicode - v142 + v143 Utility Unicode - v142 + v143 Utility Unicode - v142 + v143 diff --git a/libwdi/.msvc/embedder.vcxproj b/libwdi/.msvc/embedder.vcxproj index 88aa0f8a..4f46f62d 100644 --- a/libwdi/.msvc/embedder.vcxproj +++ b/libwdi/.msvc/embedder.vcxproj @@ -21,12 +21,12 @@ Application Unicode true - v142 + v143 Application Unicode - v142 + v143 @@ -67,6 +67,7 @@ $(TargetDir)$(ProjectName).pdb Console MachineX86 + /BREPRO /DEPENDENTLOADFLAG:0x800 %(AdditionalOptions) @@ -92,6 +93,7 @@ true true MachineX86 + /BREPRO /DEPENDENTLOADFLAG:0x800 %(AdditionalOptions) diff --git a/libwdi/.msvc/embedder_sources b/libwdi/.msvc/embedder_sources deleted file mode 100644 index d4646a52..00000000 --- a/libwdi/.msvc/embedder_sources +++ /dev/null @@ -1,19 +0,0 @@ -TARGETNAME=embedder -TARGETTYPE=PROGRAM - -!IFNDEF MSC_WARNING_LEVEL -MSC_WARNING_LEVEL=/W3 -!ENDIF - -USE_MSVCRT=1 - -UMTYPE=console -UMBASE=0x01000000 - -INCLUDES=..\msvc;$(DDK_INC_PATH) -C_DEFINES = $(C_DEFINES) /DDDKBUILD - -TARGETLIBS=$(SDK_LIB_PATH)\kernel32.lib \ - $(SDK_LIB_PATH)\user32.lib - -SOURCES=embedder.c diff --git a/libwdi/.msvc/installer_arm64.vcxproj b/libwdi/.msvc/installer_arm64.vcxproj new file mode 100644 index 00000000..58e9ee02 --- /dev/null +++ b/libwdi/.msvc/installer_arm64.vcxproj @@ -0,0 +1,116 @@ + + + + + Debug + ARM64 + + + Release + ARM64 + + + + installer_arm64 + {6AC16F78-F266-4AE0-BD63-550A55F54C15} + installerarm64 + + + + Application + Unicode + true + v143 + + + Application + Unicode + v143 + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + $(SolutionDir)$(Platform)\$(Configuration)\helper\ + $(SolutionDir)$(Platform)\$(Configuration)\helper\installer_arm64\ + $(SolutionDir)$(Platform)\$(Configuration)\helper\ + $(SolutionDir)$(Platform)\$(Configuration)\helper\installer_arm64\ + + + + ARM64 + + + Disabled + ..\..\msvc;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + MultiThreadedDebug + Level3 + ProgramDatabase + CompileAsC + + + newdev.lib;setupapi.lib;%(AdditionalDependencies) + $(OutDir)installer_arm64.exe + true + Console + + + + + ARM64 + + + MinSpace + ..\..\msvc;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + MultiThreaded + Level3 + CompileAsC + + + newdev.lib;setupapi.lib;%(AdditionalDependencies) + $(OutDir)installer_arm64.exe + false + Console + true + true + + + + + CompileAsC + + + /BREPRO /DEPENDENTLOADFLAG:0x800 %(AdditionalOptions) + + + + + CompileAsC + + + /BREPRO /DEPENDENTLOADFLAG:0x800 %(AdditionalOptions) + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/.msvc/zadic.vcxproj.filters b/libwdi/.msvc/installer_arm64.vcxproj.filters similarity index 57% rename from examples/.msvc/zadic.vcxproj.filters rename to libwdi/.msvc/installer_arm64.vcxproj.filters index c9163e03..6f4141ba 100644 --- a/examples/.msvc/zadic.vcxproj.filters +++ b/libwdi/.msvc/installer_arm64.vcxproj.filters @@ -5,18 +5,22 @@ {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - {7cc83e36-4fef-4def-ae65-6698cd4ecdad} + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd - + Source Files - - Resource Files - + + Header Files + + + Header Files + \ No newline at end of file diff --git a/libwdi/.msvc/installer_x64.vcxproj b/libwdi/.msvc/installer_x64.vcxproj index aba916b2..47227cfa 100644 --- a/libwdi/.msvc/installer_x64.vcxproj +++ b/libwdi/.msvc/installer_x64.vcxproj @@ -1,18 +1,10 @@  - - Debug - Win32 - Debug x64 - - Release - Win32 - Release x64 @@ -22,39 +14,22 @@ installer_x64 {E5A56EE0-182F-470F-8CDC-8C1B7B86EE26} installerx64 - Win32Proj - - Application - v142 - - - Application - v142 - Application Unicode true - v142 + v143 Application Unicode - v142 + v143 - - - - - - - - @@ -78,7 +53,7 @@ Disabled ..\..\msvc;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS; _WIN64;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNINGS;_WIN64;%(PreprocessorDefinitions) MultiThreadedDebug Level3 ProgramDatabase @@ -90,6 +65,7 @@ true Console MachineX64 + /BREPRO /DEPENDENTLOADFLAG:0x800 %(AdditionalOptions) @@ -99,7 +75,7 @@ MinSpace ..\..\msvc;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS; _WIN64;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNINGS;_WIN64;%(PreprocessorDefinitions) MultiThreaded Level3 CompileAsC @@ -112,6 +88,7 @@ true true MachineX64 + /BREPRO /DEPENDENTLOADFLAG:0x800 %(AdditionalOptions) diff --git a/libwdi/.msvc/installer_x64_sources b/libwdi/.msvc/installer_x64_sources deleted file mode 100644 index 7ff972bb..00000000 --- a/libwdi/.msvc/installer_x64_sources +++ /dev/null @@ -1,24 +0,0 @@ -TARGETNAME=installer_x64 -TARGETTYPE=PROGRAM - -_NT_TARGET_VERSION= $(_NT_TARGET_VERSION_WINXP) - -!IFNDEF MSC_WARNING_LEVEL -MSC_WARNING_LEVEL=/W3 -!ENDIF - -USE_MSVCRT=1 - -UMTYPE=console -UMBASE=0x01000000 - -INCLUDES=..\msvc;$(DDK_INC_PATH) -C_DEFINES = $(C_DEFINES) /DDDKBUILD - -TARGETLIBS=$(SDK_LIB_PATH)\kernel32.lib \ - $(SDK_LIB_PATH)\user32.lib \ - $(SDK_LIB_PATH)\newdev.lib \ - $(SDK_LIB_PATH)\ole32.lib \ - $(SDK_LIB_PATH)\setupapi.lib - -SOURCES=installer.c diff --git a/libwdi/.msvc/installer_x86.vcxproj b/libwdi/.msvc/installer_x86.vcxproj index 0221308f..f157d844 100644 --- a/libwdi/.msvc/installer_x86.vcxproj +++ b/libwdi/.msvc/installer_x86.vcxproj @@ -14,19 +14,18 @@ installer_x86 {9B1C561E-F95B-4849-A7AA-A4350E227C20} installerx86 - Win32Proj Application Unicode true - v142 + v143 Application Unicode - v142 + v143 @@ -52,7 +51,6 @@ Disabled ..\..\msvc;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true MultiThreadedDebug Level3 ProgramDatabase @@ -64,6 +62,7 @@ true Console MachineX86 + /BREPRO /DEPENDENTLOADFLAG:0x800 %(AdditionalOptions) @@ -83,6 +82,7 @@ true true MachineX86 + /BREPRO /DEPENDENTLOADFLAG:0x800 %(AdditionalOptions) diff --git a/libwdi/.msvc/installer_x86_sources b/libwdi/.msvc/installer_x86_sources deleted file mode 100644 index c9e41817..00000000 --- a/libwdi/.msvc/installer_x86_sources +++ /dev/null @@ -1,24 +0,0 @@ -TARGETNAME=installer_x86 -TARGETTYPE=PROGRAM - -_NT_TARGET_VERSION= $(_NT_TARGET_VERSION_WINXP) - -!IFNDEF MSC_WARNING_LEVEL -MSC_WARNING_LEVEL=/W3 -!ENDIF - -USE_MSVCRT=1 - -UMTYPE=console -UMBASE=0x01000000 - -INCLUDES=..\msvc;$(DDK_INC_PATH) -C_DEFINES = $(C_DEFINES) /DDDKBUILD - -TARGETLIBS=$(SDK_LIB_PATH)\kernel32.lib \ - $(SDK_LIB_PATH)\user32.lib \ - $(SDK_LIB_PATH)\newdev.lib \ - $(SDK_LIB_PATH)\ole32.lib \ - $(SDK_LIB_PATH)\setupapi.lib - -SOURCES=installer.c diff --git a/libwdi/.msvc/libwdi_dll.vcxproj b/libwdi/.msvc/libwdi_dll.vcxproj index 5c031627..f9601ee4 100644 --- a/libwdi/.msvc/libwdi_dll.vcxproj +++ b/libwdi/.msvc/libwdi_dll.vcxproj @@ -28,22 +28,22 @@ DynamicLibrary Unicode true - v142 + v143 DynamicLibrary Unicode - v142 + v143 DynamicLibrary Unicode - v142 + v143 DynamicLibrary Unicode - v142 + v143 @@ -89,11 +89,10 @@ embedder embedded.h Disabled ..\..\msvc;%(AdditionalIncludeDirectories) - DEBUG;_DEBUG;_WIN32;_LIB;_CRT_SECURE_NO_WARNINGS;DLL_EXPORT;%(PreprocessorDefinitions) + DEBUG;_DEBUG;_WIN32;_LIB;_CRT_SECURE_NO_WARNINGS;LIBWDI_DLL_EXPORT;%(PreprocessorDefinitions) MultiThreadedDebugDLL Level3 ProgramDatabase - false CompileAsC @@ -104,6 +103,7 @@ embedder embedded.h $(OutDir)libwdi.dll ../libwdi.def ../libwdi.rc;%(EmbedManagedResourceFile) + /BREPRO %(AdditionalOptions) @@ -115,11 +115,10 @@ embedder embedded.h Disabled ..\..\msvc;%(AdditionalIncludeDirectories) - DEBUG;_DEBUG;_WIN32;_WIN64;_LIB;_CRT_SECURE_NO_WARNINGS;DLL_EXPORT;%(PreprocessorDefinitions) + DEBUG;_DEBUG;_WIN32;_WIN64;_LIB;_CRT_SECURE_NO_WARNINGS;LIBWDI_DLL_EXPORT;%(PreprocessorDefinitions) MultiThreadedDebugDLL Level3 ProgramDatabase - false CompileAsC @@ -130,6 +129,7 @@ embedder embedded.h $(OutDir)libwdi.dll ../libwdi.def ../libwdi.rc;%(EmbedManagedResourceFile) + /BREPRO %(AdditionalOptions) @@ -141,10 +141,9 @@ embedder embedded.h MinSpace ..\..\msvc;%(AdditionalIncludeDirectories) - _WIN32;_LIB;_CRT_SECURE_NO_WARNINGS;DLL_EXPORT;%(PreprocessorDefinitions) + _WIN32;_LIB;_CRT_SECURE_NO_WARNINGS;LIBWDI_DLL_EXPORT;%(PreprocessorDefinitions) MultiThreadedDLL Level3 - false CompileAsC @@ -155,6 +154,7 @@ embedder embedded.h $(OutDir)libwdi.dll ../libwdi.def ../libwdi.rc;%(EmbedManagedResourceFile) + /BREPRO %(AdditionalOptions) @@ -166,10 +166,9 @@ embedder embedded.h MinSpace ..\..\msvc;%(AdditionalIncludeDirectories) - _WIN32;_WIN64;_LIB;_CRT_SECURE_NO_WARNINGS;DLL_EXPORT;%(PreprocessorDefinitions) + _WIN32;_WIN64;_LIB;_CRT_SECURE_NO_WARNINGS;LIBWDI_DLL_EXPORT;%(PreprocessorDefinitions) MultiThreadedDLL Level3 - false CompileAsC @@ -180,6 +179,7 @@ embedder embedded.h $(OutDir)libwdi.dll ../libwdi.def ../libwdi.rc;%(EmbedManagedResourceFile) + /BREPRO %(AdditionalOptions) @@ -217,6 +217,9 @@ embedder embedded.h {792d44d5-28a7-4eb3-b84b-8021fe3189f9} false + + {6ac16f78-f266-4ae0-bd63-550a55f54c15} + {e5a56ee0-182f-470f-8cdc-8c1b7b86ee26} false diff --git a/libwdi/.msvc/libwdi_sources b/libwdi/.msvc/libwdi_sources deleted file mode 100644 index 8938310e..00000000 --- a/libwdi/.msvc/libwdi_sources +++ /dev/null @@ -1,32 +0,0 @@ -#TARGETTYPE is not defined, to allow selection between static lib or DLL with ddk_build -TARGETNAME=libwdi -DLLDEF=libwdi.def - -!IFNDEF MSC_WARNING_LEVEL -MSC_WARNING_LEVEL=/W3 -!ENDIF - -USE_MSVCRT=1 - -INCLUDES=..\msvc;$(DDK_INC_PATH) -C_DEFINES = $(C_DEFINES) /DDDKBUILD $(DLL_DEFINES) -LINKER_FLAGS=/ignore:4006 - -# naked calls to 'build' ignores SOURCELIBS => we can't create a static lib -# that includes dependencies without calling the linker externally :( - -TARGETLIBS=$(SDK_LIB_PATH)\kernel32.lib \ - $(SDK_LIB_PATH)\advapi32.lib \ - $(SDK_LIB_PATH)\user32.lib \ - $(SDK_LIB_PATH)\shell32.lib \ - $(SDK_LIB_PATH)\setupapi.lib \ - $(SDK_LIB_PATH)\ole32.lib - -SOURCES= \ - logging.c \ - libwdi.c \ - libwdi_dlg.c \ - pki.c \ - tokenizer.c \ - vid_data.c \ - libwdi.rc diff --git a/libwdi/.msvc/libwdi_static.vcxproj b/libwdi/.msvc/libwdi_static.vcxproj index 9d2dcd6a..5f34e793 100644 --- a/libwdi/.msvc/libwdi_static.vcxproj +++ b/libwdi/.msvc/libwdi_static.vcxproj @@ -28,22 +28,22 @@ StaticLibrary Unicode true - v142 + v143 StaticLibrary Unicode - v142 + v143 StaticLibrary Unicode - v142 + v143 StaticLibrary Unicode - v142 + v143 @@ -89,7 +89,6 @@ embedder embedded.h ..\..\msvc;%(AdditionalIncludeDirectories) DEBUG;_DEBUG;_WIN32;_CRTDBG_MAP_ALLOC;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true MultiThreadedDebug Level3 ProgramDatabase @@ -101,6 +100,7 @@ embedder embedded.h $(OutDir)libwdi.lib + /BREPRO %(AdditionalOptions) @@ -123,6 +123,7 @@ embedder embedded.h $(OutDir)libwdi.lib + /BREPRO %(AdditionalOptions) @@ -144,6 +145,7 @@ embedder embedded.h $(OutDir)libwdi.lib + /BREPRO %(AdditionalOptions) @@ -165,6 +167,7 @@ embedder embedded.h $(OutDir)libwdi.lib + /BREPRO %(AdditionalOptions) @@ -203,6 +206,9 @@ embedder embedded.h {792d44d5-28a7-4eb3-b84b-8021fe3189f9} false + + {6ac16f78-f266-4ae0-bd63-550a55f54c15} + {e5a56ee0-182f-470f-8cdc-8c1b7b86ee26} false diff --git a/libwdi/Makefile.am b/libwdi/Makefile.am index 404b01c7..21965888 100644 --- a/libwdi/Makefile.am +++ b/libwdi/Makefile.am @@ -50,7 +50,7 @@ libwdi_rc.lo: libwdi.rc libwdi_la_CFLAGS = $(ARCH_CFLAGS) $(VISIBILITY_CFLAGS) $(AM_CFLAGS) libwdi_la_LDLAGS = $(AM_LDFLAGS) -libwdi_la_LIBADD = libwdi_rc.lo -lsetupapi -lole32 +libwdi_la_LIBADD = libwdi_rc.lo -lsetupapi -lole32 -lntdll libwdi_la_SOURCES = $(LIB_SRC) libwdi_la_HEADERS = $(LIB_HDR) libwdi_ladir = $(includedir) diff --git a/libwdi/embedder.c b/libwdi/embedder.c index e5d7c50c..ba65b3e6 100644 --- a/libwdi/embedder.c +++ b/libwdi/embedder.c @@ -89,7 +89,7 @@ void dump_buffer_hex(FILE* fd, unsigned char *buffer, size_t size) fprintf(fd, "0x00"); } - for (i=0; i + * Copyright (c) 2010-2023 Pete Batard * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -52,9 +52,11 @@ #if defined(_DEBUG) #define INSTALLER_PATH_32 SOLUTIONDIR "\\Win32\\Debug\\helper" #define INSTALLER_PATH_64 SOLUTIONDIR "\\x64\\Debug\\helper" +#define INSTALLER_PATH_ARM SOLUTIONDIR "\\arm64\\Debug\\helper" #else #define INSTALLER_PATH_32 SOLUTIONDIR "\\Win32\\Release\\helper" #define INSTALLER_PATH_64 SOLUTIONDIR "\\x64\\Release\\helper" +#define INSTALLER_PATH_ARM SOLUTIONDIR "\\arm64\\Release\\helper" #endif #else #if !defined(SOLUTIONDIR) @@ -64,4 +66,5 @@ // as it won't run from ANYWHERE ELSE! Use the one from .libs instead. #define INSTALLER_PATH_32 SOLUTIONDIR #define INSTALLER_PATH_64 SOLUTIONDIR +#define INSTALLER_PATH_ARM SOLUTIONDIR #endif diff --git a/libwdi/embedder_files.h b/libwdi/embedder_files.h index 9b8bb121..001a3540 100644 --- a/libwdi/embedder_files.h +++ b/libwdi/embedder_files.h @@ -1,7 +1,7 @@ /* * embedder : converts binary resources into a .h include * "If you can think of a better way to get ice, I'd like to hear it." - * Copyright (c) 2010-2017 Pete Batard + * Copyright (c) 2010-2023 Pete Batard * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -55,8 +55,8 @@ struct emb embeddable_fixed[] = { // libusb0 #if defined(LIBUSB0_DIR) - { 0, LIBUSB0_DIR "\\bin\\x86\\libusb0_x86.dll", "x86" }, { 0, LIBUSB0_DIR "\\bin\\x86\\install-filter.exe", "x86" }, + { 0, LIBUSB0_DIR "\\bin\\x86\\libusb0_x86.dll", "x86" }, # if defined(LIBUSBK_DIR) # if defined(OPT_M32) { 1, "libusb0.dll", "x86" }, // reuse @@ -73,6 +73,11 @@ struct emb embeddable_fixed[] = { { 0, LIBUSB0_DIR "\\bin\\amd64\\libusb0.sys", "amd64" }, { 0, LIBUSB0_DIR "\\bin\\amd64\\install-filter.exe", "amd64" }, # endif // OPT_M64 +# if defined(OPT_ARM) + { 0, LIBUSB0_DIR "\\bin\\arm64\\libusb0.dll", "arm64" }, + { 0, LIBUSB0_DIR "\\bin\\arm64\\libusb0.sys", "arm64" }, + { 0, LIBUSB0_DIR "\\bin\\arm64\\install-filter.exe", "arm64" }, +# endif // OPT_ARM { 0, LIBUSB0_DIR "\\installer_license.txt", "license\\libusb0" }, #endif // LIBUSB0_DIR @@ -125,6 +130,9 @@ struct emb embeddable_fixed[] = { #if defined(OPT_M64) { 0, INSTALLER_PATH_64 "\\installer_x64.exe", "." }, #endif +#if defined(OPT_ARM) + { 0, INSTALLER_PATH_ARM "\\installer_arm64.exe", "." }, +#endif // inf templates for the tokenizer ("" directory means no extraction) { 0, "winusb.inf.in", "" }, { 0, "libusb0.inf.in", "" }, diff --git a/libwdi/installer.c b/libwdi/installer.c index 531dfa0c..b9964ecf 100644 --- a/libwdi/installer.c +++ b/libwdi/installer.c @@ -1,6 +1,6 @@ /* - * Library for WinUSB/libusb automated driver installation - * Copyright (c) 2010-2013 Pete Batard + * Library for USB automated driver installation + * Copyright (c) 2010-2022 Pete Batard * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -104,12 +104,12 @@ void plog_v(const char *format, va_list args) buffer[0] = IC_PRINT_MESSAGE; - size = safe_vsnprintf(buffer+1, STR_BUFFER_SIZE-1, format, args); + size = safe_vsnprintf(buffer + 1, STR_BUFFER_SIZE - 1, format, args); if (size < 0) { - buffer[STR_BUFFER_SIZE-1] = 0; - size = STR_BUFFER_SIZE-2; + buffer[STR_BUFFER_SIZE - 1] = 0; + size = STR_BUFFER_SIZE - 2; } - WriteFile(pipe_handle, buffer, (DWORD)size+2, &junk, NULL); + WriteFile(pipe_handle, buffer, (DWORD)min(size + 2, STR_BUFFER_SIZE), &junk, NULL); } void plog(const char *format, ...) @@ -365,12 +365,12 @@ static __inline char* xlocale_to_utf8(const char* str) } // +1 for extra leading byte - if ((ustr = (char*)calloc(size+1, 1)) == NULL) { + if ((ustr = (char*)calloc((size_t)size + 1, 1)) == NULL) { free(wstr); return NULL; } - if (wchar_to_utf8_no_alloc(wstr, ustr+1, size) != size) { + if (wchar_to_utf8_no_alloc(wstr, ustr + 1, size) != size) { free(ustr); free(wstr); return NULL; @@ -480,7 +480,7 @@ void __cdecl syslog_reader_thread(void* param) if (size != 0) { // Read from file and add a zero terminator - buffer = malloc(size+1); + buffer = malloc((size_t)size + 1); if (buffer == NULL) { plog("could not allocate buffer to read syslog"); goto out; @@ -526,7 +526,7 @@ void __cdecl syslog_reader_thread(void* param) _endthread(); } -static char *windows_error_str(uint32_t retval) +static char *wdi_windows_error_str(uint32_t retval) { static char err_string[STR_BUFFER_SIZE]; @@ -635,9 +635,12 @@ static __inline int process_error(DWORD r, char* path) { return WDI_ERROR_CAT_MISSING; case ERROR_NO_AUTHENTICODE_CATALOG: case ERROR_DRIVER_STORE_ADD_FAILED: - case ERROR_AUTHENTICODE_PUBLISHER_NOT_TRUSTED: plog("Invalid CAT file signature or operation cancelled by user."); return WDI_ERROR_USER_CANCEL; + case ERROR_AUTHENTICODE_PUBLISHER_NOT_TRUSTED: + case ERROR_CERTIFICATE_AUTHORITY_NOT_TRUSTED: + plog("This version of Windows is refusing to trust the installed certificate."); + return WDI_ERROR_NOT_SUPPORTED; case ERROR_NO_DRIVER_SELECTED: plog("The driver is not compatible with this version of Windows."); return WDI_ERROR_NOT_SUPPORTED; @@ -674,7 +677,7 @@ static __inline int process_error(DWORD r, char* path) { return WDI_ERROR_OTHER; default: plog("Unhandled error 0x%X (%d)", r, r); - plog(windows_error_str(r)); + plog(wdi_windows_error_str(r)); return WDI_ERROR_OTHER; } } @@ -686,7 +689,7 @@ BOOL disable_system_restore(BOOL enabled) LONG r; DWORD disp, regtype, val, val_size=sizeof(DWORD); HRESULT hr; - IGroupPolicyObject* pLGPO; + IGroupPolicyObject* pLGPO = NULL; static DWORD original_val = -1; // -1 = key doesn't exist HKEY machine_key = NULL, disable_system_restore_key = NULL; // MSVC is finicky about these ones => redefine them diff --git a/libwdi/installer.h b/libwdi/installer.h index 92c8d1e5..3e210e2b 100644 --- a/libwdi/installer.h +++ b/libwdi/installer.h @@ -1,6 +1,7 @@ /* - * Library for WinUSB/libusb automated driver installation - * Copyright (c) 2010-2013 Pete Batard + * Library for USB automated driver installation + * Copyright (c) 2010-2022 Pete Batard + * For more info, please visit http://libwdi.akeo.ie * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -39,24 +40,28 @@ #define INSTALLER_PIPE_NAME "\\\\.\\pipe\\libwdi-installer" -#define safe_free(p) do {if (p != NULL) {free((void*)p); p = NULL;}} while(0) +#define safe_free(p) do {free((void*)p); p = NULL;} while(0) #define safe_min(a, b) min((size_t)(a), (size_t)(b)) -#define safe_strcp(dst, dst_max, src, count) do {memcpy(dst, src, safe_min(count, dst_max)); \ - ((char*)dst)[safe_min(count, dst_max)-1] = 0;} while(0) -#define safe_strcpy(dst, dst_max, src) safe_strcp(dst, dst_max, src, safe_strlen(src)+1) +static __inline void safe_strcp(char* dst, const size_t dst_max, const char* src, const size_t count) { + memmove(dst, src, min(count, dst_max)); + dst[min(count, dst_max) - 1] = 0; +} +#define safe_strcpy(dst, dst_max, src) safe_strcp(dst, dst_max, src, safe_strlen(src) + 1) #define static_strcpy(dst, src) safe_strcpy(dst, sizeof(dst), src) -#define safe_strncat(dst, dst_max, src, count) strncat(dst, src, safe_min(count, dst_max - safe_strlen(dst) - 1)) -#define safe_strcat(dst, dst_max, src) safe_strncat(dst, dst_max, src, safe_strlen(src)+1) -#define static_strcat(dst, src) safe_strcat(dst, sizeof(dst), src) +#define safe_strcat(dst, dst_max, src) strncat_s(dst, dst_max, src, _TRUNCATE) +#define static_strcat(dst, src) safe_strcat(dst, sizeof(dst), (src)) #define safe_strcmp(str1, str2) strcmp(((str1==NULL)?"":str1), ((str2==NULL)?"":str2)) #define safe_stricmp(str1, str2) _stricmp(((str1==NULL)?"":str1), ((str2==NULL)?"":str2)) #define safe_strncmp(str1, str2, count) strncmp(((str1==NULL)?"":str1), ((str2==NULL)?"":str2), count) -#define safe_closehandle(h) do {if (h != INVALID_HANDLE_VALUE) {CloseHandle(h); h = INVALID_HANDLE_VALUE;}} while(0) -#define safe_sprintf(dst, count, ...) do {_snprintf(dst, count, __VA_ARGS__); (dst)[(count)-1] = 0; } while(0) +#define safe_closehandle(h) do {if ((h != INVALID_HANDLE_VALUE) && (h != NULL)) {CloseHandle(h); h = INVALID_HANDLE_VALUE;}} while(0) +#define safe_sprintf(dst, count, ...) do { size_t _count = count; char* _dst = dst; _snprintf_s(_dst, _count, _TRUNCATE, __VA_ARGS__); \ + _dst[(_count) - 1] = 0; } while(0) +#define static_sprintf(dst, ...) safe_sprintf(dst, sizeof(dst), __VA_ARGS__) #define safe_strlen(str) ((((char*)str)==NULL)?0:strlen(str)) -#define static_sprintf(dest, format, ...) safe_sprintf(dest, sizeof(dest), format, __VA_ARGS__) -#define safe_swprintf _snwprintf -#define safe_strdup _strdup +#define static_sprintf(dst, ...) safe_sprintf(dst, sizeof(dst), __VA_ARGS__) +#define safe_swprintf(dst, count, ...) do { size_t _count = count; wchar_t* _dst = dst; _snwprintf_s(_dst, _count, _TRUNCATE, __VA_ARGS__); \ + _dst[(_count) - 1] = 0; } while(0) +#define safe_strdup(str) ((((char*)(str))==NULL) ? NULL : _strdup(str)) #ifndef ARRAYSIZE #define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0])) #endif @@ -83,6 +88,17 @@ enum installer_code { IC_INSTALLER_COMPLETED, }; +/* Helper function to isolate a filename from a path */ +static __inline const char* filename(const char* path) +{ + int i; + if (path == NULL) + return NULL; + i = (int)strlen(path); + while ((--i >= 0) && (path[i] != '\\') && (path[i] != '/')); + return (const char*)&path[i + 1]; +} + /* Helper functions to access DLLs */ static __inline HMODULE GetLibraryHandle(char* szDLLName) { @@ -142,6 +158,9 @@ typedef RETURN_TYPE CONFIGRET; #ifndef ERROR_AUTHENTICODE_PUBLISHER_NOT_TRUSTED #define ERROR_AUTHENTICODE_PUBLISHER_NOT_TRUSTED 0xE0000243 #endif +#ifndef ERROR_CERTIFICATE_AUTHORITY_NOT_TRUSTED +#define ERROR_CERTIFICATE_AUTHORITY_NOT_TRUSTED 0x00000109 +#endif #ifndef ERROR_FILE_HASH_NOT_IN_CATALOG #define ERROR_FILE_HASH_NOT_IN_CATALOG 0xE000024B #endif diff --git a/libwdi/libusb0.inf.in b/libwdi/libusb0.inf.in index 3a6d9fdc..ad0efc3a 100644 --- a/libwdi/libusb0.inf.in +++ b/libwdi/libusb0.inf.in @@ -23,7 +23,7 @@ HKR,,,0,"libusb-win32 devices" HKR,,Icon,,-20 [Manufacturer] -%VendorName% = Devices, NT, NTAMD64 +%VendorName% = Devices, NT, NTAMD64, NTARM64 ;-------------------------------------------------------------------------- ; libusb-win32 files @@ -42,7 +42,10 @@ libusb0.sys = 1,amd64 libusb0.dll = 1,amd64 #LK_DLL# #LK_EQ_X64# libusb0_x86.dll = 1,x86 -#LK_X86_DLL# #LK_EQ_X86# + +[SourceDisksFiles.arm64] +libusb0.sys = 1,arm64 +libusb0.dll = 1,arm64 [DestinationDirs] libusb_files_sys = 10,system32\drivers @@ -73,6 +76,8 @@ CopyFiles = libusb_files_sys, libusb_files_dll_x86 [LIBUSB_WIN32_DEV.NTAMD64] CopyFiles = libusb_files_sys, libusb_files_dll, libusb_files_dll_wow64 +[LIBUSB_WIN32_DEV.NTARM64] +CopyFiles = libusb_files_sys, libusb_files_dll [LIBUSB_WIN32_DEV.NT.HW] DelReg = libusb_del_reg_hw AddReg = libusb_add_reg_hw @@ -81,12 +86,19 @@ AddReg = libusb_add_reg_hw DelReg = libusb_del_reg_hw AddReg = libusb_add_reg_hw +[LIBUSB_WIN32_DEV.NTARM64.HW] +DelReg = libusb_del_reg_hw +AddReg = libusb_add_reg_hw + [LIBUSB_WIN32_DEV.NT.Services] AddService = libusb0, 0x00000002, libusb_add_service [LIBUSB_WIN32_DEV.NTAMD64.Services] AddService = libusb0, 0x00000002, libusb_add_service +[LIBUSB_WIN32_DEV.NTARM64.Services] +AddService = libusb0, 0x00000002, libusb_add_service + ; Older versions of this .inf file installed filter drivers. They are not ; needed any more and must be removed [libusb_del_reg_hw] @@ -129,3 +141,6 @@ ServiceBinary = %12%\libusb0.sys [Devices.NTAMD64] %DeviceName% = LIBUSB_WIN32_DEV.NTAMD64, USB\%DeviceID% + +[Devices.NTARM64] +%DeviceName% = LIBUSB_WIN32_DEV.NTARM64, USB\%DeviceID% diff --git a/libwdi/libusbk.inf.in b/libwdi/libusbk.inf.in index 5707984d..c6351d3e 100644 --- a/libwdi/libusbk.inf.in +++ b/libwdi/libusbk.inf.in @@ -58,7 +58,7 @@ AddReg=#USE_DEVICE_INTERFACE_GUID# [AddDeviceInterfaceGUID] HKR,,DeviceInterfaceGUIDs, 0x10000,%DeviceGUID% -; ========== Driver/Servce section ============== +; ========== Driver/Service section ============== [LUsbK_Device.NT.Services] Addservice=libusbK,2,LUsbK_AddService diff --git a/libwdi/libwdi.c b/libwdi/libwdi.c index d565651d..1501b45d 100644 --- a/libwdi/libwdi.c +++ b/libwdi/libwdi.c @@ -1,6 +1,6 @@ /* * Library for USB automated driver installation - * Copyright (c) 2010-2017 Pete Batard + * Copyright (c) 2010-2023 Pete Batard * Parts of the code from libusb by Daniel Drake, Johannes Erdfelt et al. * For more info, please visit http://libwdi.akeo.ie * @@ -38,6 +38,8 @@ #include #include #include +#include +#include #include "installer.h" #include "libwdi.h" @@ -54,49 +56,210 @@ static BOOL filter_driver = FALSE; static DWORD timeout = DEFAULT_TIMEOUT; static HANDLE pipe_handle = INVALID_HANDLE_VALUE; static VS_FIXEDFILEINFO driver_version[WDI_NB_DRIVERS-1] = { {0}, {0}, {0}, {0} }; -static const char* driver_name[WDI_NB_DRIVERS-1] = {"winusbcoinstaller2.dll", "libusb0.sys", "libusbK.sys", ""}; +static const char* driver_name[WDI_NB_DRIVERS-1] = {"winusbcoinstaller2.dll", "libusb0.dll", "libusbK.dll", ""}; static const char* inf_template[WDI_NB_DRIVERS-1] = {"winusb.inf.in", "libusb0.inf.in", "libusbk.inf.in", "usbser.inf.in"}; static const char* cat_template[WDI_NB_DRIVERS-1] = {"winusb.cat.in", "libusb0.cat.in", "libusbk.cat.in", "usbser.cat.in"}; static const char* ms_compat_id[WDI_NB_DRIVERS-1] = {"MS_COMP_WINUSB", "MS_COMP_LIBUSB0", "MS_COMP_LIBUSBK", "MS_COMP_USBSER"}; int nWindowsVersion = WINDOWS_UNDEFINED; +int nWindowsBuildNumber = -1; char WindowsVersionStr[128] = "Windows "; // Detect Windows version #define GET_WINDOWS_VERSION do { if (nWindowsVersion == WINDOWS_UNDEFINED) GetWindowsVersion(); } while(0) -BOOL is_x64(void) +static __inline USHORT GetApplicationArch(void) { - BOOL ret = FALSE; - // Detect if we're running a 32 or 64 bit system - if (sizeof(uintptr_t) < 8) { - IsWow64Process(GetCurrentProcess(), &ret); - } else { - ret = TRUE; +#if defined(_M_AMD64) + return IMAGE_FILE_MACHINE_AMD64; +#elif defined(_M_IX86) + return IMAGE_FILE_MACHINE_I386; +#elif defined(_M_ARM64) + return IMAGE_FILE_MACHINE_ARM64; +#elif defined(_M_ARM) + return IMAGE_FILE_MACHINE_ARM; +#else + return IMAGE_FILE_MACHINE_UNKNOWN; +#endif +} + +static __inline const char* GetArchName(USHORT uArch) +{ + switch (uArch) { + case IMAGE_FILE_MACHINE_AMD64: + return "x64"; + case IMAGE_FILE_MACHINE_I386: + return "x86"; + case IMAGE_FILE_MACHINE_ARM64: + return "arm64"; + case IMAGE_FILE_MACHINE_ARM: + return "arm"; + default: + return "unknown"; } - return ret; } -// From smartmontools os_win32.cpp +// Detect the underlying platform arch. +static USHORT GetPlatformArch(void) +{ + BOOL is_64bit = FALSE, is_wow64 = FALSE; + USHORT ProcessMachine = IMAGE_FILE_MACHINE_UNKNOWN, NativeMachine = IMAGE_FILE_MACHINE_UNKNOWN; + + PF_DECL_LIBRARY(Kernel32); + PF_TYPE_DECL(WINAPI, BOOL, IsWow64Process2, (HANDLE, USHORT*, USHORT*)); + PF_LOAD_LIBRARY(Kernel32); + PF_INIT(IsWow64Process2, Kernel32); + + if ((pfIsWow64Process2 == NULL) || + !pfIsWow64Process2(GetCurrentProcess(), &ProcessMachine, &NativeMachine)) { + // Assume same arch as the app + NativeMachine = GetApplicationArch(); + // Fix the Arch if we have a 32-bit app running under WOW64 + if ((sizeof(uintptr_t) < 8) && IsWow64Process(GetCurrentProcess(), &is_wow64) && is_wow64) { + if (NativeMachine == IMAGE_FILE_MACHINE_I386) + NativeMachine = IMAGE_FILE_MACHINE_AMD64; + else if (NativeMachine == IMAGE_FILE_MACHINE_ARM) + NativeMachine = IMAGE_FILE_MACHINE_ARM64; + else // I sure wanna be made aware of this scenario... + assert(FALSE); + } + wdi_warn("Note: Underlying Windows architecture was guessed and may be incorrect..."); + } + + PF_FREE_LIBRARY(Kernel32); + return NativeMachine; +} + +static const char* GetEdition(DWORD ProductType) +{ + static char unknown_edition_str[64]; + + // From: https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getproductinfo + // These values can be found in the winnt.h header. + switch (ProductType) { + case 0x00000000: return ""; // Undefined + case 0x00000001: return "Ultimate"; + case 0x00000002: return "Home Basic"; + case 0x00000003: return "Home Premium"; + case 0x00000004: return "Enterprise"; + case 0x00000005: return "Home Basic N"; + case 0x00000006: return "Business"; + case 0x00000007: return "Server Standard"; + case 0x00000008: return "Server Datacenter"; + case 0x00000009: return "Smallbusiness Server"; + case 0x0000000A: return "Server Enterprise"; + case 0x0000000B: return "Starter"; + case 0x0000000C: return "Server Datacenter (Core)"; + case 0x0000000D: return "Server Standard (Core)"; + case 0x0000000E: return "Server Enterprise (Core)"; + case 0x00000010: return "Business N"; + case 0x00000011: return "Web Server"; + case 0x00000012: return "HPC Edition"; + case 0x00000013: return "Storage Server (Essentials)"; + case 0x0000001A: return "Home Premium N"; + case 0x0000001B: return "Enterprise N"; + case 0x0000001C: return "Ultimate N"; + case 0x00000022: return "Home Server"; + case 0x00000024: return "Server Standard without Hyper-V"; + case 0x00000025: return "Server Datacenter without Hyper-V"; + case 0x00000026: return "Server Enterprise without Hyper-V"; + case 0x00000027: return "Server Datacenter without Hyper-V (Core)"; + case 0x00000028: return "Server Standard without Hyper-V (Core)"; + case 0x00000029: return "Server Enterprise without Hyper-V (Core)"; + case 0x0000002A: return "Hyper-V Server"; + case 0x0000002F: return "Starter N"; + case 0x00000030: return "Pro"; + case 0x00000031: return "Pro N"; + case 0x00000034: return "Server Solutions Premium"; + case 0x00000035: return "Server Solutions Premium (Core)"; + case 0x00000040: return "Server Hyper Core V"; + case 0x00000042: return "Starter E"; + case 0x00000043: return "Home Basic E"; + case 0x00000044: return "Premium E"; + case 0x00000045: return "Pro E"; + case 0x00000046: return "Enterprise E"; + case 0x00000047: return "Ultimate E"; + case 0x00000048: return "Enterprise (Eval)"; + case 0x0000004F: return "Server Standard (Eval)"; + case 0x00000050: return "Server Datacenter (Eval)"; + case 0x00000054: return "Enterprise N (Eval)"; + case 0x00000057: return "Thin PC"; + case 0x00000058: case 0x00000059: case 0x0000005A: case 0x0000005B: case 0x0000005C: return "Embedded"; + case 0x00000062: return "Home N"; + case 0x00000063: return "Home China"; + case 0x00000064: return "Home Single Language"; + case 0x00000065: return "Home"; + case 0x00000067: return "Pro with Media Center"; + case 0x00000069: case 0x0000006A: case 0x0000006B: case 0x0000006C: return "Embedded"; + case 0x0000006F: return "Home Connected"; + case 0x00000070: return "Pro Student"; + case 0x00000071: return "Home Connected N"; + case 0x00000072: return "Pro Student N"; + case 0x00000073: return "Home Connected Single Language"; + case 0x00000074: return "Home Connected China"; + case 0x00000079: return "Education"; + case 0x0000007A: return "Education N"; + case 0x0000007D: return "Enterprise LTSB"; + case 0x0000007E: return "Enterprise LTSB N"; + case 0x0000007F: return "Pro S"; + case 0x00000080: return "Pro S N"; + case 0x00000081: return "Enterprise LTSB (Eval)"; + case 0x00000082: return "Enterprise LTSB N (Eval)"; + case 0x0000008A: return "Pro Single Language"; + case 0x0000008B: return "Pro China"; + case 0x0000008C: return "Enterprise Subscription"; + case 0x0000008D: return "Enterprise Subscription N"; + case 0x00000091: return "Server Datacenter SA (Core)"; + case 0x00000092: return "Server Standard SA (Core)"; + case 0x00000095: return "Utility VM"; + case 0x000000A1: return "Pro for Workstations"; + case 0x000000A2: return "Pro for Workstations N"; + case 0x000000A4: return "Pro for Education"; + case 0x000000A5: return "Pro for Education N"; + case 0x000000AB: return "Enterprise G"; // I swear Microsoft are just making up editions... + case 0x000000AC: return "Enterprise G N"; + case 0x000000B2: return "Cloud"; + case 0x000000B3: return "Cloud N"; + case 0x000000B6: return "Home OS"; + case 0x000000B7: case 0x000000CB: return "Cloud E"; + case 0x000000B9: return "IoT OS"; + case 0x000000BA: case 0x000000CA: return "Cloud E N"; + case 0x000000BB: return "IoT Edge OS"; + case 0x000000BC: return "IoT Enterprise"; + case 0x000000BD: return "Lite"; + case 0x000000BF: return "IoT Enterprise S"; + case 0x000000C0: case 0x000000C2: case 0x000000C3: case 0x000000C4: case 0x000000C5: case 0x000000C6: return "XBox"; + case 0x000000C7: case 0x000000C8: case 0x00000196: case 0x00000197: case 0x00000198: return "Azure Server"; + case 0xABCDABCD: return "(Unlicensed)"; + default: + static_sprintf(unknown_edition_str, "(Unknown Edition 0x%02X)", (uint32_t)ProductType); + return unknown_edition_str; + } +} + +/* + * Modified from smartmontools' os_win32.cpp + */ void GetWindowsVersion(void) { OSVERSIONINFOEXA vi, vi2; - const char* w = 0; - const char* w64 = "32 bit"; - char *vptr, build_number[10] = ""; + DWORD dwProductType; + const char* w = NULL; + const char* arch_name; + char* vptr; size_t vlen; unsigned major, minor; ULONGLONG major_equal, minor_equal; BOOL ws; nWindowsVersion = WINDOWS_UNDEFINED; - safe_strcpy(WindowsVersionStr, sizeof(WindowsVersionStr), "Windows Undefined"); + static_strcpy(WindowsVersionStr, "Windows Undefined"); memset(&vi, 0, sizeof(vi)); vi.dwOSVersionInfoSize = sizeof(vi); - if (!GetVersionExA((OSVERSIONINFOA *)&vi)) { + if (!GetVersionExA((OSVERSIONINFOA*)&vi)) { memset(&vi, 0, sizeof(vi)); vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA); - if (!GetVersionExA((OSVERSIONINFOA *)&vi)) + if (!GetVersionExA((OSVERSIONINFOA*)&vi)) return; } @@ -136,89 +299,113 @@ void GetWindowsVersion(void) ws = (vi.wProductType <= VER_NT_WORKSTATION); nWindowsVersion = vi.dwMajorVersion << 4 | vi.dwMinorVersion; switch (nWindowsVersion) { - case 0x61: w = (ws ? "7" : "2008_R2"); + case WINDOWS_XP: w = "XP"; + break; + case WINDOWS_2003: w = (ws ? "XP_64" : (!GetSystemMetrics(89) ? "Server 2003" : "Server 2003_R2")); break; - case 0x62: w = (ws ? "8" : "2012"); + case WINDOWS_VISTA: w = (ws ? "Vista" : "Server 2008"); break; - case 0x63: w = (ws ? "8.1" : "2012_R2"); + case WINDOWS_7: w = (ws ? "7" : "Server 2008_R2"); break; - case 0x64: w = (ws ? "10 (Preview 1)" : "Server 10 (Preview 1)"); + case WINDOWS_8: w = (ws ? "8" : "Server 2012"); + break; + case WINDOWS_8_1: w = (ws ? "8.1" : "Server 2012_R2"); + break; + case WINDOWS_10_PREVIEW1: w = (ws ? "10 (Preview 1)" : "Server 10 (Preview 1)"); break; // Starting with Windows 10 Preview 2, the major is the same as the public-facing version - case 0xA0: w = (ws ? "10" : "Server 10"); + case WINDOWS_10: + if (vi.dwBuildNumber < 20000) { + w = (ws ? "10" : ((vi.dwBuildNumber < 17763) ? "Server 2016" : "Server 2019")); + break; + } + nWindowsVersion = WINDOWS_11; + // Fall through + case WINDOWS_11: w = (ws ? "11" : "Server 2022"); break; default: - if (nWindowsVersion < 0x61) + if (nWindowsVersion < WINDOWS_XP) nWindowsVersion = WINDOWS_UNSUPPORTED; else - w = "11 or later"; + w = "12 or later"; break; } } } - if (is_x64()) - w64 = "64-bit"; + arch_name = GetArchName(GetPlatformArch()); + GetProductInfo(vi.dwMajorVersion, vi.dwMinorVersion, vi.wServicePackMajor, vi.wServicePackMinor, &dwProductType); vptr = &WindowsVersionStr[sizeof("Windows ") - 1]; vlen = sizeof(WindowsVersionStr) - sizeof("Windows ") - 1; if (!w) safe_sprintf(vptr, vlen, "%s %u.%u %s", (vi.dwPlatformId == VER_PLATFORM_WIN32_NT ? "NT" : "??"), - (unsigned)vi.dwMajorVersion, (unsigned)vi.dwMinorVersion, w64); + (unsigned)vi.dwMajorVersion, (unsigned)vi.dwMinorVersion, arch_name); else if (vi.wServicePackMinor) - safe_sprintf(vptr, vlen, "%s SP%u.%u %s", w, vi.wServicePackMajor, vi.wServicePackMinor, w64); + safe_sprintf(vptr, vlen, "%s SP%u.%u %s", w, vi.wServicePackMajor, vi.wServicePackMinor, arch_name); else if (vi.wServicePackMajor) - safe_sprintf(vptr, vlen, "%s SP%u %s", w, vi.wServicePackMajor, w64); + safe_sprintf(vptr, vlen, "%s SP%u %s", w, vi.wServicePackMajor, arch_name); else - safe_sprintf(vptr, vlen, "%s %s", w, w64); + safe_sprintf(vptr, vlen, "%s%s%s, %s", + w, (dwProductType != PRODUCT_UNDEFINED) ? " " : "", GetEdition(dwProductType), arch_name); - // Add the build number for Windows 8.0 and later + // Add the build number (including UBR if available) for Windows 8.0 and later + nWindowsBuildNumber = vi.dwBuildNumber; if (nWindowsVersion >= 0x62) { - ReadRegistryStr(REGKEY_HKLM, "Microsoft\\Windows NT\\CurrentVersion\\CurrentBuildNumber", build_number, sizeof(build_number)); - if (build_number[0] != 0) { - safe_strcat(WindowsVersionStr, sizeof(WindowsVersionStr), " (Build "); - safe_strcat(WindowsVersionStr, sizeof(WindowsVersionStr), build_number); - safe_strcat(WindowsVersionStr, sizeof(WindowsVersionStr), ")"); - } + HKEY hCurrentVersion; + DWORD dwType = REG_DWORD, dwSize = sizeof(DWORD), dwUbr = 0; + if (RegOpenKeyExA(REGKEY_HKLM, "Software\\Microsoft\\Windows NT\\CurrentVersion", + 0, KEY_READ, &hCurrentVersion) == ERROR_SUCCESS) { + RegQueryValueExA(hCurrentVersion, "UBR", NULL, &dwType, (LPBYTE)&dwUbr, &dwSize); + RegCloseKey(hCurrentVersion); + } + + vptr = &WindowsVersionStr[safe_strlen(WindowsVersionStr)]; + vlen = sizeof(WindowsVersionStr) - safe_strlen(WindowsVersionStr) - 1; + if (dwUbr != 0) + safe_sprintf(vptr, vlen, " (Build %d.%d)", nWindowsBuildNumber, (int)dwUbr); + else + safe_sprintf(vptr, vlen, " (Build %d)", nWindowsBuildNumber); } - } + /* * Converts a windows error to human readable string * uses retval as errorcode, or, if 0, use GetLastError() */ -char *windows_error_str(uint32_t retval) +char *wdi_windows_error_str(DWORD retval) { -static char err_string[STR_BUFFER_SIZE]; - - DWORD size; - size_t i; - uint32_t error_code, format_error; + static char err_string[STR_BUFFER_SIZE]; + DWORD size, presize, error_code, format_error; - error_code = retval?retval:GetLastError(); + error_code = retval ? retval : GetLastError(); - static_sprintf(err_string, "[#%08X] ", error_code); + static_sprintf(err_string, "[0x%08lX] ", error_code); + presize = (DWORD)strlen(err_string); - size = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error_code, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), &err_string[safe_strlen(err_string)], - STR_BUFFER_SIZE - (DWORD)safe_strlen(err_string), NULL); + size = FormatMessageU(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, + HRESULT_CODE(error_code), MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), + &err_string[presize], (DWORD)(sizeof(err_string) - strlen(err_string)), NULL); if (size == 0) { format_error = GetLastError(); - if (format_error) - static_sprintf(err_string, "Windows error code %u (FormatMessage error code %u)", + if ((format_error) && (format_error != ERROR_MR_MID_NOT_FOUND) && (format_error != ERROR_MUI_FILE_NOT_LOADED)) + static_sprintf(err_string, "Windows error code 0x%08lX (FormatMessage error code 0x%08lX)", error_code, format_error); else - static_sprintf(err_string, "Unknown error code %u", error_code); + static_sprintf(err_string, "Windows error code 0x%08lX", error_code); } else { - // Remove CR/LF terminators - for (i=safe_strlen(err_string)-1; ((err_string[i]==0x0A) || (err_string[i]==0x0D)); i--) { - err_string[i] = 0; - } + // Microsoft may suffix CRLF to error messages, which we need to remove... + assert(presize > 2); + size += presize - 2; + // Cannot underflow if the above assert passed since our first char is neither of the following + while ((err_string[size] == 0x0D) || (err_string[size] == 0x0A) || (err_string[size] == 0x20)) + err_string[size--] = 0; } + + SetLastError(error_code); // Make sure we don't change the errorcode on exit return err_string; } - // Retrieve the SID of the current user. The returned PSID must be freed by the caller using LocalFree() static PSID GetSid(void) { TOKEN_USER* tu = NULL; @@ -228,13 +415,13 @@ static PSID GetSid(void) { char* psid_string = NULL; if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token)) { - wdi_err("OpenProcessToken failed: %s", windows_error_str(0)); + wdi_err("OpenProcessToken failed: %s", wdi_windows_error_str(0)); return NULL; } if (!GetTokenInformation(token, TokenUser, tu, 0, &len)) { if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { - wdi_err("GetTokenInformation (pre) failed: %s", windows_error_str(0)); + wdi_err("GetTokenInformation (pre) failed: %s", wdi_windows_error_str(0)); return NULL; } tu = (TOKEN_USER*)calloc(1, len); @@ -250,11 +437,11 @@ static PSID GetSid(void) { * The workaround? Convert to string then back to PSID */ if (!ConvertSidToStringSidA(tu->User.Sid, &psid_string)) { - wdi_err("unable to convert SID to string: %s", windows_error_str(0)); + wdi_err("Unable to convert SID to string: %s", wdi_windows_error_str(0)); ret = NULL; } else { if (!ConvertStringSidToSidA(psid_string, &ret)) { - wdi_err("unable to convert string back to SID: %s", windows_error_str(0)); + wdi_err("Unable to convert string back to SID: %s", wdi_windows_error_str(0)); ret = NULL; } // MUST use LocalFree() @@ -262,7 +449,7 @@ static PSID GetSid(void) { } } else { ret = NULL; - wdi_err("GetTokenInformation (real) failed: %s", windows_error_str(0)); + wdi_err("GetTokenInformation (real) failed: %s", wdi_windows_error_str(0)); } free(tu); return ret; @@ -288,7 +475,7 @@ static int check_dir(const char* path, BOOL create) case ERROR_PATH_NOT_FOUND: break; default: - wdi_err("unable to read file attributes %s", windows_error_str(0)); + wdi_err("Unable to read file attributes %s", wdi_windows_error_str(0)); return WDI_ERROR_ACCESS; } } else { @@ -297,13 +484,13 @@ static int check_dir(const char* path, BOOL create) return WDI_SUCCESS; } else { // File with the same name as the dir we want to create - wdi_err("%s is a file, not a directory", path); + wdi_err("'%s' is a file, not a directory", path); return WDI_ERROR_ACCESS; } } if (!create) { - wdi_err("%s doesn't exist", path); + wdi_err("'%s' does not exist", path); return WDI_ERROR_ACCESS; } @@ -317,7 +504,7 @@ static int check_dir(const char* path, BOOL create) s_attr.lpSecurityDescriptor = &s_desc; ps = &s_attr; } else { - wdi_err("could not set security descriptor: %s", windows_error_str(0)); + wdi_err("Could not set security descriptor: %s", wdi_windows_error_str(0)); } // SHCreateDirectoryEx creates subdirectories as required @@ -326,7 +513,7 @@ static int check_dir(const char* path, BOOL create) // A relative path was used => Convert to full full_path = (char*)malloc(MAX_PATH); if (full_path == NULL) { - wdi_err("could not allocate buffer to convert relative path"); + wdi_err("Could not allocate buffer to convert relative path"); if (sid != NULL) LocalFree(sid); return WDI_ERROR_RESOURCE; } @@ -342,10 +529,10 @@ static int check_dir(const char* path, BOOL create) case ERROR_SUCCESS: return WDI_SUCCESS; case ERROR_FILENAME_EXCED_RANGE: - wdi_err("directory name is too long %s", path); + wdi_err("Directory name '%s' is too long", path); return WDI_ERROR_INVALID_PARAM; default: - wdi_err("unable to create directory %s (%s)", path, windows_error_str(0)); + wdi_err("Unable to create directory '%s' (%s)", path, wdi_windows_error_str(0)); return WDI_ERROR_ACCESS; } @@ -394,7 +581,7 @@ static FILE *fopen_as_userU(const char *filename, const char *mode) s_attr.lpSecurityDescriptor = &s_desc; ps = &s_attr; } else { - wdi_err("could not set security descriptor: %s", windows_error_str(0)); + wdi_err("Could not set security descriptor: %s", wdi_windows_error_str(0)); } handle = CreateFileU(filename, access_mode, FILE_SHARE_READ, @@ -462,7 +649,7 @@ int get_version_info(int driver_type, VS_FIXEDFILEINFO* driver_info) // First, we need a physical file => extract it tmpdir = getenvU("TEMP"); if (tmpdir == NULL) { - wdi_warn("unable to use TEMP to extract file"); + wdi_warn("Unable to use TEMP to extract file"); r = WDI_ERROR_RESOURCE; goto out; } @@ -480,7 +667,7 @@ int get_version_info(int driver_type, VS_FIXEDFILEINFO* driver_info) fd = fopen_as_userU(filename, "w"); if (fd == NULL) { - wdi_warn("failed to create file '%s' (%s)", filename, windows_error_str(0)); + wdi_warn("Failed to create file '%s' (%s)", filename, wdi_windows_error_str(0)); r = WDI_ERROR_RESOURCE; goto out; } @@ -503,7 +690,7 @@ int get_version_info(int driver_type, VS_FIXEDFILEINFO* driver_info) memcpy(&driver_version[driver_type], file_info, sizeof(VS_FIXEDFILEINFO)); memcpy(driver_info, file_info, sizeof(VS_FIXEDFILEINFO)); } else { - wdi_warn("unable to allocate buffer for version info"); + wdi_warn("Unable to allocate buffer for version info"); r = WDI_ERROR_RESOURCE; } safe_free(wfilename); @@ -517,8 +704,13 @@ int get_version_info(int driver_type, VS_FIXEDFILEINFO* driver_info) // Find out if the driver selected is actually embedded in this version of the library +// or supported by the underlying platform architecture. BOOL LIBWDI_API wdi_is_driver_supported(int driver_type, VS_FIXEDFILEINFO* driver_info) { +#if (defined(LIBUSB0_DIR) || defined(LIBUSBK_DIR)) + USHORT platform_arch = GetPlatformArch(); +#endif + if (driver_type < WDI_USER) { // github issue #40 if (driver_type != WDI_CDC) { // The CDC driver does not have embedded binaries @@ -538,13 +730,13 @@ BOOL LIBWDI_API wdi_is_driver_supported(int driver_type, VS_FIXEDFILEINFO* drive #endif case WDI_LIBUSB0: #if defined(LIBUSB0_DIR) - return TRUE; + return (platform_arch == IMAGE_FILE_MACHINE_ARM64 || platform_arch == IMAGE_FILE_MACHINE_AMD64 || platform_arch == IMAGE_FILE_MACHINE_I386); #else return FALSE; #endif case WDI_LIBUSBK: #if defined(LIBUSBK_DIR) - return TRUE; + return (platform_arch == IMAGE_FILE_MACHINE_AMD64 || platform_arch == IMAGE_FILE_MACHINE_I386); #else return FALSE; #endif @@ -557,7 +749,7 @@ BOOL LIBWDI_API wdi_is_driver_supported(int driver_type, VS_FIXEDFILEINFO* drive case WDI_CDC: return TRUE; default: - wdi_err("unknown driver type"); + wdi_err("Unknown driver type"); return FALSE; } } @@ -570,7 +762,7 @@ BOOL LIBWDI_API wdi_is_file_embedded(const char* path, const char* name) { int i; - for (i=0; idriver != NULL) { // Only produce a warning for non-driverless devices - wdi_warn("could not read driver version"); + wdi_warn("Could not read driver version"); } // Retrieve device ID. This is needed to re-enumerate our device and force // the final driver installation cr = pfCM_Get_Device_IDA(dev_info_data.DevInst, strbuf, STR_BUFFER_SIZE, 0); if (cr != CR_SUCCESS) { - wdi_err("could not retrieve simple path for device %d: CR error %d", i, cr); + wdi_err("Could not retrieve simple path for device %d: CR error %d", i, cr); continue; } else { wdi_dbg("%s USB device (%d): %s", @@ -843,13 +1036,14 @@ int LIBWDI_API wdi_create_list(struct wdi_device_info** list, // The information we want ("Bus reported device description") is accessed // through DEVPKEY_Device_BusReportedDeviceDesc + desc[0] = 0; if (!SetupDiGetDevicePropertyW(dev_info, &dev_info_data, &DEVPKEY_Device_BusReportedDeviceDesc, &devprop_type, (BYTE*)desc, 2*MAX_DESC_LENGTH, &size, 0)) { // fallback to SPDRP_DEVICEDESC (USB hubs still use it) if (!SetupDiGetDeviceRegistryPropertyW(dev_info, &dev_info_data, SPDRP_DEVICEDESC, - ®_type, (BYTE*)desc, 2*MAX_DESC_LENGTH, &size)) { - wdi_dbg("could not read device description for %d: %s", - i, windows_error_str(0)); + ®_type, (BYTE*)desc, 2*MAX_DESC_LENGTH, &size) || (desc[0] == 0)) { + wdi_dbg("Could not read device description for %d: %s", + i, wdi_windows_error_str(0)); safe_swprintf(desc, MAX_DESC_LENGTH, L"Unknown Device #%d", unknown_count++); } } @@ -864,7 +1058,7 @@ int LIBWDI_API wdi_create_list(struct wdi_device_info** list, switch(j) { case 0: if (sscanf(token, "VID_%04X", &tmp) != 1) { - wdi_err("could not convert VID string"); + wdi_err("Could not convert VID string"); } else { device_info->vid = (unsigned short)tmp; } @@ -872,14 +1066,14 @@ int LIBWDI_API wdi_create_list(struct wdi_device_info** list, break; case 1: if (sscanf(token, "PID_%04X", &tmp) != 1) { - wdi_err("could not convert PID string"); + wdi_err("Could not convert PID string"); } else { device_info->pid = (unsigned short)tmp; } break; case 2: if (sscanf(token, "MI_%02X", &tmp) != 1) { - wdi_err("could not convert MI string"); + wdi_err("Could not convert MI string"); } else { device_info->is_composite = TRUE; device_info->mi = (unsigned char)tmp; @@ -890,7 +1084,7 @@ int LIBWDI_API wdi_create_list(struct wdi_device_info** list, } break; default: - wdi_err("unexpected case"); + wdi_err("Program assertion failed - Unexpected case"); break; } } @@ -983,13 +1177,13 @@ static int extract_binaries(const char* path) safe_strcat(filename, MAX_PATH, resource[i].name); if ( (safe_strlen(path) + safe_strlen(resource[i].subdir) + safe_strlen(resource[i].name)) > (MAX_PATH - 3)) { - wdi_err("qualified path is too long: '%s'", filename); + wdi_err("Qualified path is too long: '%s'", filename); return WDI_ERROR_RESOURCE; } fd = fopen_as_userU(filename, "w"); if (fd == NULL) { - wdi_err("failed to create file '%s' (%s)", filename, windows_error_str(0)); + wdi_err("Could not create file '%s' (%s)", filename, wdi_windows_error_str(0)); return WDI_ERROR_RESOURCE; } @@ -997,13 +1191,13 @@ static int extract_binaries(const char* path) fclose(fd); } - wdi_info("successfully extracted driver files to %s", path); + wdi_info("Successfully extracted driver files to '%s'", path); return WDI_SUCCESS; } -// tokenizes a resource stored in resource.h -static long tokenize_internal(const char* resource_name, char** dst, const token_entity_t* token_entities, - const char* tok_prefix, const char* tok_suffix, int recursive) +// tokenizes a resource stored in resource.h and write it to file +static long wdi_tokenize_resource(const char* resource_name, char** dst, const token_entity_t* token_entities, + const char* tok_prefix, const char* tok_suffix, int recursive) { int i; @@ -1020,11 +1214,50 @@ static long tokenize_internal(const char* resource_name, char** dst, const token return -ERROR_RESOURCE_DATA_NOT_FOUND; } +// tokenizes an external file pointed by into destination file +static long wdi_tokenize_file(const char* src, char** dst, const token_entity_t* token_entities, + const char* tok_prefix, const char* tok_suffix, int recursive) +{ + FILE* fd = NULL; + long size, ret = -ERROR_RESOURCE_DATA_NOT_FOUND; + char* buffer = NULL; + + fd = fopen(src, "r"); + if (fd == NULL) + goto out; + fseek(fd, 0L, SEEK_END); + size = ftell(fd); + if (size < 0) + goto out; + fseek(fd, 0L, SEEK_SET); + // +1 for NUL terminator since we pass the whole file as a text string + buffer = (char*)calloc(size + 1, 1); + if (buffer == NULL) { + wdi_err("Could not allocate tokenization buffer"); + ret = WDI_ERROR_RESOURCE; + goto out; + } + if (fread(buffer, 1, size, fd) != size) { + wdi_err("Could not read file to tokenize"); + ret = -ERROR_RESOURCE_DATA_NOT_FOUND; + goto out; + } + ret = tokenize_string(buffer, size, dst, token_entities, tok_prefix, tok_suffix, recursive); + +out: + free(buffer); + if (fd) + fclose(fd); + return ret; +} + #define CAT_LIST_MAX_ENTRIES 16 // Create an inf and extract coinstallers in the directory pointed by path int LIBWDI_API wdi_prepare_driver(struct wdi_device_info* device_info, const char* path, - const char* inf_name, struct wdi_options_prepare_driver* options) + const char* inf, struct wdi_options_prepare_driver* options) { + PF_DECL_LIBRARY(Ntdll); + PF_TYPE_DECL(NTAPI, NTSTATUS, NtQuerySystemInformation, (SYSTEM_INFORMATION_CLASS, PVOID, ULONG, PULONG)); const wchar_t bom = 0xFEFF; #if defined(ENABLE_DEBUG_LOGGING) || defined(INCLUDE_DEBUG_LOGGING) const char* driver_display_name[WDI_NB_DRIVERS] = { "WinUSB", "libusb0.sys", "libusbK.sys", "Generic USB CDC", "user driver" }; @@ -1033,34 +1266,39 @@ int LIBWDI_API wdi_prepare_driver(struct wdi_device_info* device_info, const cha const char* vendor_name = NULL; const char* cat_list[CAT_LIST_MAX_ENTRIES+1]; char drv_path[MAX_PATH], inf_path[MAX_PATH], cat_path[MAX_PATH], hw_id[40], cert_subject[64]; - char *strguid, *token, *cat_name = NULL, *dst = NULL, *cat_in_copy = NULL; + char *strguid, *token, *cat_name = NULL, *dst = NULL, *inf_name; wchar_t *wdst = NULL; int i, nb_entries, driver_type = WDI_WINUSB, r = WDI_ERROR_OTHER; long inf_file_size, cat_file_size; - BOOL is_android_device = FALSE; + BOOL is_android_device = FALSE, is_test_signing_enabled = FALSE; FILE* fd; GUID guid; SYSTEMTIME system_time; FILETIME file_time, local_time; + SYSTEM_CODEINTEGRITY_INFORMATION sci = { 0 }; + ULONG dwcbSz = 0; MUTEX_START; GET_WINDOWS_VERSION; if (nWindowsVersion < WINDOWS_7) { - wdi_err("this version of Windows is no longer supported"); + wdi_err("This version of Windows is no longer supported"); r = WDI_ERROR_NOT_SUPPORTED; goto out; } - if ((device_info == NULL) || (inf_name == NULL)) { - wdi_err("one of the required parameter is NULL"); + if ((device_info == NULL) || (inf == NULL)) { + wdi_err("One of the required parameter is NULL"); r = WDI_ERROR_INVALID_PARAM; goto out; } + // If we are dealing with a path (e.g. option 'external_inf'), remove the directory part + inf_name = (char*)filename(inf); + // Check the inf file provided and create the cat file name - if (strcmp(inf_name+safe_strlen(inf_name)-4, inf_ext) != 0) { - wdi_err("inf name provided must have a '.inf' extension"); + if (strcmp(inf_name + safe_strlen(inf_name) - 4, inf_ext) != 0) { + wdi_err("Inf name provided must have a '.inf' extension"); r = WDI_ERROR_INVALID_PARAM; goto out; } @@ -1071,13 +1309,13 @@ int LIBWDI_API wdi_prepare_driver(struct wdi_device_info* device_info, const cha // Try to use the user's temp dir char* tmp = getenvU("TEMP"); if (tmp == NULL) { - wdi_err("no path provided and unable to use TEMP"); + wdi_err("No path provided and unable to use TEMP"); r = WDI_ERROR_INVALID_PARAM; goto out; } else { static_strcpy(drv_path, tmp); free(tmp); - wdi_info("no path provided - extracting to '%s'", drv_path); + wdi_info("No path provided - extracting to '%s'", drv_path); } } @@ -1092,14 +1330,14 @@ int LIBWDI_API wdi_prepare_driver(struct wdi_device_info* device_info, const cha } // Ensure driver_type is what we expect - if ( (driver_type < 0) || (driver_type > WDI_USER) ) { - wdi_err("unknown type"); + if ((driver_type < 0) || (driver_type > WDI_USER)) { + wdi_err("Program assertion failed - Unknown driver type"); r = WDI_ERROR_INVALID_PARAM; goto out; } if (!wdi_is_driver_supported(driver_type, &driver_version[driver_type])) { - for (driver_type=0; driver_typedesc == NULL) { - wdi_err("no device ID was given for the device - aborting"); + wdi_err("No device ID was given for the device - aborting"); r = WDI_ERROR_INVALID_PARAM; goto out; } @@ -1144,7 +1382,7 @@ int LIBWDI_API wdi_prepare_driver(struct wdi_device_info* device_info, const cha // Populate the inf and cat names & paths if ( (strlen(drv_path) >= MAX_PATH) || (strlen(inf_name) >= MAX_PATH) || ((strlen(drv_path) + strlen(inf_name)) > (MAX_PATH - 2)) ) { - wdi_err("qualified path for inf file is too long: '%s\\%s", drv_path, inf_name); + wdi_err("Qualified path for inf file is too long: '%s\\%s", drv_path, inf_name); r = WDI_ERROR_RESOURCE; goto out; } @@ -1153,7 +1391,7 @@ int LIBWDI_API wdi_prepare_driver(struct wdi_device_info* device_info, const cha safe_strcat(inf_path, sizeof(inf_path), inf_name); safe_strcpy(cat_path, sizeof(cat_path), inf_path); if (safe_strlen(cat_path) < 4) { - wdi_err("qualified path for inf file is too short: '%s", cat_path); + wdi_err("Qualified path for inf file is too short: '%s", cat_path); r = WDI_ERROR_RESOURCE; goto out; } @@ -1203,7 +1441,7 @@ int LIBWDI_API wdi_prepare_driver(struct wdi_device_info* device_info, const cha } else if ((options != NULL) && (options->device_guid != NULL)) { strguid = options->device_guid; } else if (is_android_device) { - wdi_info("using Android Device Interface GUID"); + wdi_info("Using Android Device Interface GUID"); strguid = (char*)android_device_guid; } else { IGNORE_RETVAL(CoCreateGuid(&guid)); @@ -1228,7 +1466,7 @@ int LIBWDI_API wdi_prepare_driver(struct wdi_device_info* device_info, const cha // Extra check, in case somebody modifies our code if ((driver_type < 0) && (driver_type >= WDI_USER)) { - wdi_err("program assertion failed - driver_version[] index out of range"); + wdi_err("Program assertion failed - driver_version[] index out of range"); r = WDI_ERROR_OTHER; goto out; } @@ -1247,12 +1485,15 @@ int LIBWDI_API wdi_prepare_driver(struct wdi_device_info* device_info, const cha (int)driver_version[driver_type].dwFileVersionMS>>16, (int)driver_version[driver_type].dwFileVersionMS&0xFFFF, (int)driver_version[driver_type].dwFileVersionLS>>16, (int)driver_version[driver_type].dwFileVersionLS&0xFFFF); - // Tokenize the file - if ((inf_file_size = tokenize_internal(inf_template[driver_type], - &dst, inf_entities, "#", "#", 0)) > 0) { + // Tokenize the inf + if ((options != NULL) && (options->external_inf)) + inf_file_size = wdi_tokenize_file(inf, &dst, inf_entities, "#", "#", 0); + else + inf_file_size = wdi_tokenize_resource(inf_template[driver_type], &dst, inf_entities, "#", "#", 0); + if (inf_file_size > 0) { fd = fopen_as_userU(inf_path, "w"); if (fd == NULL) { - wdi_err("failed to create file: %s", inf_path); + wdi_err("Failed to create file: %s", inf_path); r = WDI_ERROR_ACCESS; goto out; } @@ -1260,7 +1501,7 @@ int LIBWDI_API wdi_prepare_driver(struct wdi_device_info* device_info, const cha // non-English locale to display properly in device manager. UTF-8 will not do. wdst = utf8_to_wchar(dst); if (wdst == NULL) { - wdi_err("could not convert '%s' to UTF-16", dst); + wdi_err("Could not convert '%s' to UTF-16", dst); safe_free(dst); r = WDI_ERROR_RESOURCE; goto out; @@ -1271,11 +1512,11 @@ int LIBWDI_API wdi_prepare_driver(struct wdi_device_info* device_info, const cha safe_free(wdst); safe_free(dst); } else { - wdi_err("could not tokenize inf file (%d)", inf_file_size); + wdi_err("Could not tokenize inf file (%d)", inf_file_size); r = WDI_ERROR_ACCESS; goto out; } - wdi_info("successfully created '%s'", inf_path); + wdi_info("Successfully created '%s'", inf_path); if (IsUserAnAdmin()) { // Try to create and self-sign the cat file to remove security prompts @@ -1287,9 +1528,9 @@ int LIBWDI_API wdi_prepare_driver(struct wdi_device_info* device_info, const cha wdi_info("Creating and self-signing a .cat file..."); // Tokenize the cat file (for WDF version) - if ((cat_file_size = tokenize_internal(cat_template[driver_type], + if ((cat_file_size = wdi_tokenize_resource(cat_template[driver_type], &dst, inf_entities, "#", "#", 0)) <= 0) { - wdi_err("could not tokenize inf file (%d)", inf_file_size); + wdi_err("Could not tokenize cat file (%d)", cat_file_size); r = WDI_ERROR_ACCESS; goto out; } @@ -1306,7 +1547,7 @@ int LIBWDI_API wdi_prepare_driver(struct wdi_device_info* device_info, const cha continue; cat_list[nb_entries++] = token; if (nb_entries >= CAT_LIST_MAX_ENTRIES) { - wdi_warn("more than %d cat entries - ignoring the rest", CAT_LIST_MAX_ENTRIES); + wdi_warn("More than %d cat entries - ignoring the rest", CAT_LIST_MAX_ENTRIES); break; } } while ((token = strtok(NULL, "\n\r")) != NULL); @@ -1319,14 +1560,31 @@ int LIBWDI_API wdi_prepare_driver(struct wdi_device_info* device_info, const cha ms_compat_id[driver_type]:inf_entities[DEVICE_HARDWARE_ID].replace); static_sprintf(cert_subject, "CN=%s (libwdi autogenerated)", hw_id); - // Failures on the following aren't fatal errors + // Check if testsigning is enabled + // https://social.msdn.microsoft.com/Forums/Windowsapps/en-US/e6c1be93-7003-4594-b8e4-18ab4a75d273/detecting-testsigning-onoff-via-api + PF_INIT(NtQuerySystemInformation, Ntdll); + if (pfNtQuerySystemInformation != NULL) { + sci.Length = sizeof(sci); + if (pfNtQuerySystemInformation((SYSTEM_INFORMATION_CLASS)0x67, &sci, sizeof(sci), &dwcbSz) >= 0 && dwcbSz == sizeof(sci)) + is_test_signing_enabled = !!(sci.CodeIntegrityOptions & 0x02); + wdi_info("Test signing is: %s", is_test_signing_enabled ? "Enabled" : "Disabled"); + } + + // Failures on the following are fatal on Windows 10 when test signing is not enabled if (!CreateCat(cat_path, hw_id, drv_path, cat_list, nb_entries)) { - wdi_warn("could not create cat file"); + if (nWindowsVersion >= WINDOWS_10 && !is_test_signing_enabled) { + wdi_err("Could not create cat file"); + return WDI_ERROR_CAT_MISSING; + } + wdi_warn("Could not create cat file"); } else if ((options != NULL) && (!options->disable_signing) && (!SelfSignFile(cat_path, (options->cert_subject != NULL)?options->cert_subject:cert_subject))) { - wdi_warn("could not sign cat file"); + if (nWindowsVersion >= WINDOWS_10 && !is_test_signing_enabled) { + wdi_err("Could not sign cat file"); + return WDI_ERROR_UNSIGNED; + } + wdi_warn("Could not sign cat file"); } - safe_free(cat_in_copy); safe_free(dst); } else { wdi_info("No .cat file generated (missing elevated privileges)"); @@ -1348,7 +1606,7 @@ static int process_message(char* buffer, DWORD size) return WDI_ERROR_INVALID_PARAM; if (current_device == NULL) { - wdi_err("program assertion failed - no current device"); + wdi_err("Program assertion failed - no current device"); return WDI_ERROR_NOT_FOUND; } @@ -1366,71 +1624,85 @@ static int process_message(char* buffer, DWORD size) switch(buffer[0]) { case IC_GET_DEVICE_ID: - wdi_dbg("got request for device_id"); + wdi_dbg("Got request for device_id"); if (current_device->device_id != NULL) { WriteFile(pipe_handle, current_device->device_id, (DWORD)safe_strlen(current_device->device_id), &tmp, NULL); } else { - wdi_dbg("no device_id - sending empty string"); + wdi_dbg("No device_id - sending empty string"); WriteFile(pipe_handle, "\0", 1, &tmp, NULL); } break; case IC_GET_HARDWARE_ID: - wdi_dbg("got request for hardware_id"); + wdi_dbg("Got request for hardware_id"); if (current_device->hardware_id != NULL) { WriteFile(pipe_handle, current_device->hardware_id, (DWORD)safe_strlen(current_device->hardware_id), &tmp, NULL); } else { - wdi_dbg("no hardware_id - sending empty string"); + wdi_dbg("No hardware_id - sending empty string"); WriteFile(pipe_handle, "\0", 1, &tmp, NULL); } break; case IC_PRINT_MESSAGE: if (size < 2) { - wdi_err("print_message: no data"); + wdi_err("Print_message: no data"); return WDI_ERROR_NOT_FOUND; } wdi_log(WDI_LOG_LEVEL_DEBUG, "installer process", "%s", buffer+1); break; case IC_SYSLOG_MESSAGE: if (size < 2) { - wdi_err("syslog_message: no data"); + wdi_err("Syslog_message: no data"); return WDI_ERROR_NOT_FOUND; } wdi_log(WDI_LOG_LEVEL_DEBUG, "syslog", "%s", buffer+1); break; case IC_SET_STATUS: if (size < 2) { - wdi_err("set status: no data"); + wdi_err("Set status: no data"); return WDI_ERROR_NOT_FOUND; } return (int)buffer[1]; break; case IC_SET_TIMEOUT_INFINITE: - wdi_dbg("switching timeout to infinite"); + wdi_dbg("Switching timeout to infinite"); timeout = INFINITE; break; case IC_SET_TIMEOUT_DEFAULT: - wdi_dbg("switching timeout back to finite"); + wdi_dbg("Switching timeout back to finite"); timeout = DEFAULT_TIMEOUT; break; case IC_INSTALLER_COMPLETED: - wdi_dbg("installer process completed"); + wdi_dbg("Installer process completed"); break; case IC_GET_USER_SID: if (ConvertSidToStringSidA(GetSid(), &sid_str)) { WriteFile(pipe_handle, sid_str, (DWORD)safe_strlen(sid_str), &tmp, NULL); LocalFree(sid_str); } else { - wdi_warn("no user_sid - sending empty string"); + wdi_warn("No user_sid - sending empty string"); WriteFile(pipe_handle, "\0", 1, &tmp, NULL); } break; default: - wdi_err("unrecognized installer message"); + wdi_err("Unrecognized installer message"); return WDI_ERROR_NOT_FOUND; } return WDI_SUCCESS; } +static const char* get_installer_arch(USHORT uArch) +{ + switch (uArch) { + case IMAGE_FILE_MACHINE_AMD64: + return "x64"; + case IMAGE_FILE_MACHINE_I386: + return "x86"; + case IMAGE_FILE_MACHINE_ARM64: + return "arm64"; + default: + return "unknown_arch"; + } +} + // Run the elevated installer static int install_driver_internal(void* arglist) { @@ -1441,13 +1713,13 @@ static int install_driver_internal(void* arglist) STARTUPINFOA si; PROCESS_INFORMATION pi; SECURITY_ATTRIBUTES sa; - char path[MAX_PATH], exename[MAX_PATH], exeargs[MAX_PATH]; HANDLE stdout_w = INVALID_HANDLE_VALUE; HANDLE handle[3] = { INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE }; OVERLAPPED overlapped; - int r; DWORD err, rd_count, to_read, offset, bufsize = LOGBUF_SIZE; - BOOL is_x64 = FALSE; + USHORT platform_arch = GetPlatformArch(); + int r; + char path[MAX_PATH], exename[MAX_PATH], exeargs[MAX_PATH], installer_name[32] = { 0 }; char *buffer = NULL, *new_buffer; const char* filter_name = "libusb0"; @@ -1455,7 +1727,7 @@ static int install_driver_internal(void* arglist) GET_WINDOWS_VERSION; if (nWindowsVersion < WINDOWS_7) { - wdi_err("this version of Windows is no longer supported"); + wdi_err("This version of Windows is no longer supported"); r = WDI_ERROR_NOT_SUPPORTED; goto out; } @@ -1474,13 +1746,13 @@ static int install_driver_internal(void* arglist) char* tmp = getenvU("TEMP"); static_strcpy(path, tmp); free(tmp); - wdi_info("no path provided - installing from '%s'", path); + wdi_info("No path provided - installing from '%s'", path); } else { static_strcpy(path, params->path); } if ((params->device_info == NULL) || (params->inf_name == NULL)) { - wdi_err("one of the required parameter is NULL"); + wdi_err("One of the required parameter is NULL"); r = WDI_ERROR_INVALID_PARAM; goto out; } @@ -1488,7 +1760,7 @@ static int install_driver_internal(void* arglist) // Detect if another installation is in process if ((params->options != NULL) && (pfCMP_WaitNoPendingInstallEvents != NULL)) { if (pfCMP_WaitNoPendingInstallEvents(params->options->pending_install_timeout) == WAIT_TIMEOUT) { - wdi_warn("timeout expired while waiting for another pending installation - aborting"); + wdi_warn("Timeout expired while waiting for another pending installation - aborting"); r = WDI_ERROR_PENDING_INSTALLATION; goto out; } @@ -1496,21 +1768,11 @@ static int install_driver_internal(void* arglist) wdi_dbg("CMP_WaitNoPendingInstallEvents not available"); } - // Detect whether if we should run the 64 bit installer, without - // relying on external libs - if (sizeof(uintptr_t) < 8) { - // This application is not 64 bit, but it might be 32 bit - // running in WOW64 - IsWow64Process(GetCurrentProcess(), &is_x64); - } else { - is_x64 = TRUE; - } - // Use a pipe to communicate with our installer pipe_handle = CreateNamedPipeA(INSTALLER_PIPE_NAME, PIPE_ACCESS_DUPLEX|FILE_FLAG_OVERLAPPED, PIPE_TYPE_MESSAGE|PIPE_READMODE_MESSAGE, 1, 4096, 4096, 0, NULL); if (pipe_handle == INVALID_HANDLE_VALUE) { - wdi_err("could not create read pipe: %s", windows_error_str(0)); + wdi_err("Could not create read pipe: %s", wdi_windows_error_str(0)); r = WDI_ERROR_RESOURCE; goto out; } @@ -1525,13 +1787,15 @@ static int install_driver_internal(void* arglist) overlapped.hEvent = handle[0]; if (!filter_driver) { - // Why do we need two installers? Glad you asked. If you try to run the x86 installer on an x64 + // Why do we need multiple installers? Glad you asked. If you try to run the x86 installer on an x64 // system, you will get a "System does not work under WOW64 and requires 64-bit version" message. - static_sprintf(exename, "\"%s\\installer_x%s.exe\"", path, is_x64?"64":"86"); + // And of course, Windows ARM64 won't let you use an x86 installer either... + static_sprintf(installer_name, "installer_%s.exe", get_installer_arch(platform_arch)); static_sprintf(exeargs, "\"%s\"", params->inf_name); } else { // Use libusb-win32's filter driver installer - static_sprintf(exename, "\"%s\\%s\\\\install-filter.exe\"", path, is_x64?"amd64":"x86"); + static_strcpy(installer_name, "install-filter.exe"); + static_strcat(path, (platform_arch == IMAGE_FILE_MACHINE_AMD64) ? "\\amd64" : "\\x86"); if (safe_stricmp(current_device->upper_filter, filter_name) == 0) { // Device already has the libusb-win32 filter => remove static_strcpy(exeargs, "uninstall -d="); @@ -1546,26 +1810,29 @@ static int install_driver_internal(void* arglist) stdout_w = CreateFileA(INSTALLER_PIPE_NAME, GENERIC_WRITE, FILE_SHARE_WRITE, &sa, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED, NULL); if (stdout_w == INVALID_HANDLE_VALUE) { - wdi_err("could not create stdout endpoint: %s", windows_error_str(0)); + wdi_err("Could not create stdout endpoint: %s", wdi_windows_error_str(0)); r = WDI_ERROR_RESOURCE; goto out; } } - // At this stage, if either the 32 or 64 bit installer version is missing, + static_sprintf(exename, "\"%s\\%s\"", path, installer_name); + + // At this stage, if the installer for the relevant arch is missing, // it is the application developer's fault... if (GetFileAttributesU(exename) == INVALID_FILE_ATTRIBUTES) { - wdi_err("this application does not contain the required %s bit installer", is_x64?"64":"32"); - wdi_err("please contact the application provider for a %s bit compatible version", is_x64?"64":"32"); - r = WDI_ERROR_NOT_FOUND; goto out; + wdi_err("This application does not contain the required %s installer", installer_name); + wdi_err("Please contact the application provider for a compatible version"); + r = WDI_ERROR_NOT_FOUND; + goto out; } - if (IsUserAnAdmin()) { + if (!IsUserAnAdmin()) { // Take care of UAC with ShellExecuteEx + runas shExecInfo.cbSize = sizeof(SHELLEXECUTEINFOA); shExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS; shExecInfo.hwnd = NULL; shExecInfo.lpVerb = "runas"; - shExecInfo.lpFile = filter_driver?"install-filter.exe":(is_x64?"installer_x64.exe":"installer_x86.exe"); + shExecInfo.lpFile = installer_name; shExecInfo.lpParameters = exeargs; shExecInfo.lpDirectory = path; shExecInfo.lpClass = NULL; @@ -1581,15 +1848,15 @@ static int install_driver_internal(void* arglist) case ERROR_SUCCESS: break; case ERROR_CANCELLED: - wdi_info("operation cancelled by the user"); + wdi_info("Operation cancelled by the user or due to missing data"); r = WDI_ERROR_USER_CANCEL; goto out; case ERROR_FILE_NOT_FOUND: - wdi_info("could not find installer executable"); + wdi_info("Could not find installer executable"); r = WDI_ERROR_NOT_FOUND; goto out; default: - wdi_err("ShellExecuteEx failed: %s", windows_error_str(err)); + wdi_err("ShellExecuteEx failed: %s", wdi_windows_error_str(err)); r = WDI_ERROR_NEEDS_ADMIN; goto out; } @@ -1611,7 +1878,7 @@ static int install_driver_internal(void* arglist) static_strcat(exename, " "); static_strcat(exename, exeargs); if (!CreateProcessU(NULL, exename, NULL, NULL, TRUE, CREATE_NO_WINDOW, NULL, path, &si, &pi)) { - wdi_err("CreateProcess failed: %s", windows_error_str(0)); + wdi_err("CreateProcess failed: %s", wdi_windows_error_str(0)); r = WDI_ERROR_NEEDS_ADMIN; goto out; } handle[1] = pi.hProcess; @@ -1622,7 +1889,7 @@ static int install_driver_internal(void* arglist) offset = 0; buffer = (char*)malloc(bufsize); if (buffer == NULL) { - wdi_err("unable to alloc buffer: aborting"); + wdi_err("Unable to allocate buffer: aborting"); r = WDI_ERROR_RESOURCE; goto out; } @@ -1661,10 +1928,10 @@ static int install_driver_internal(void* arglist) r = check_completion(handle[1]); goto out; case ERROR_MORE_DATA: bufsize *= 2; - wdi_dbg("message overflow (async) - increasing buffer size to %d bytes", bufsize); + wdi_dbg("Message overflow (async) - increasing buffer size to %d bytes", bufsize); new_buffer = (char*)realloc(buffer, bufsize); if (new_buffer == NULL) { - wdi_err("unable to realloc buffer: aborting"); + wdi_err("Unable to realloc buffer: aborting"); r = WDI_ERROR_RESOURCE; } else { buffer = new_buffer; @@ -1672,21 +1939,21 @@ static int install_driver_internal(void* arglist) } break; default: - wdi_err("could not read from pipe (async): %s", windows_error_str(0)); + wdi_err("Could not read from pipe (async): %s", wdi_windows_error_str(0)); break; } } break; case WAIT_TIMEOUT: // Lost contact - wdi_err("installer failed to respond - aborting"); + wdi_err("Installer failed to respond - aborting"); TerminateProcess(handle[1], 0); r = WDI_ERROR_TIMEOUT; goto out; case WAIT_OBJECT_0+1: // installer process terminated r = check_completion(handle[1]); goto out; default: - wdi_err("could not read from pipe (wait): %s", windows_error_str(0)); + wdi_err("Could not read from pipe (wait): %s", wdi_windows_error_str(0)); break; } break; @@ -1703,7 +1970,7 @@ static int install_driver_internal(void* arglist) } break; default: - wdi_err("could not read from pipe (sync): %s", windows_error_str(0)); + wdi_err("Could not read from pipe (sync): %s", wdi_windows_error_str(0)); break; } } @@ -1724,19 +1991,21 @@ static int install_driver_internal(void* arglist) } int LIBWDI_API wdi_install_driver(struct wdi_device_info* device_info, const char* path, - const char* inf_name, struct wdi_options_install_driver* options) + const char* inf, struct wdi_options_install_driver* options) { struct install_driver_params params; params.device_info = device_info; - params.inf_name = inf_name; params.options = options; params.path = path; + // If we are dealing with a path (e.g. option 'external_inf'), remove the directory part + params.inf_name = filename(inf); + if ((options == NULL) || (options->hWnd == NULL)) { - wdi_dbg("using standard mode"); + wdi_dbg("Using standard mode"); return install_driver_internal((void*)¶ms); } - wdi_dbg("using progress bar mode"); + wdi_dbg("Using progress bar mode"); return run_with_progress_bar(options->hWnd, install_driver_internal, (void*)¶ms); } @@ -1751,7 +2020,7 @@ int LIBWDI_API wdi_install_trusted_certificate(const char* cert_name, GET_WINDOWS_VERSION; if (nWindowsVersion < WINDOWS_7) { - wdi_err("this version of Windows is no longer supported"); + wdi_err("This version of Windows is no longer supported"); r = WDI_ERROR_NOT_SUPPORTED; goto out; } @@ -1768,7 +2037,7 @@ int LIBWDI_API wdi_install_trusted_certificate(const char* cert_name, } } if (i == nb_resources) { - wdi_err("unable to locate certificate '%s' in embedded resources", cert_name); + wdi_err("Unable to locate certificate '%s' in embedded resources", cert_name); r = WDI_ERROR_NOT_FOUND; goto out; } @@ -1779,16 +2048,16 @@ int LIBWDI_API wdi_install_trusted_certificate(const char* cert_name, } if (!AddCertToTrustedPublisher((BYTE*)resource[i].data, (DWORD)resource[i].size, disable_warning, hWnd)) { - wdi_warn("could not add certificate '%s' as Trusted Publisher", cert_name); + wdi_warn("Could not add certificate '%s' as Trusted Publisher", cert_name); r = WDI_ERROR_RESOURCE; goto out; } - wdi_info("certificate '%s' successfully added as Trusted Publisher", cert_name); + wdi_info("Certificate '%s' successfully added as Trusted Publisher", cert_name); r = WDI_SUCCESS; goto out; } - wdi_err("this call must be run with elevated privileges"); + wdi_err("This call must be run with elevated privileges"); r = WDI_ERROR_NEEDS_ADMIN; out: return r; diff --git a/libwdi/libwdi.h b/libwdi/libwdi.h index da22ea4f..9e043cc3 100644 --- a/libwdi/libwdi.h +++ b/libwdi/libwdi.h @@ -1,6 +1,6 @@ /* * Library for USB automated driver installation - * Copyright (c) 2010-2017 Pete Batard + * Copyright (c) 2010-2021 Pete Batard * Parts of the code from libusb by Daniel Drake, Johannes Erdfelt et al. * * This library is free software; you can redistribute it and/or @@ -25,7 +25,7 @@ */ #define WDI_MAX_STRLEN 200 -#if defined(DLL_EXPORT) +#if defined(LIBWDI_DLL_EXPORT) #define LIBWDI_EXP __declspec(dllexport) #else #define LIBWDI_EXP @@ -201,6 +201,8 @@ struct wdi_options_prepare_driver { char* cert_subject; /** Install a generic driver, for WCID devices, to allow for automated installation */ BOOL use_wcid_driver; + /** Use an externally provided inf file */ + BOOL external_inf; }; // wdi_install_driver options: diff --git a/libwdi/libwdi.rc b/libwdi/libwdi.rc index 27b689f8..c2a97173 100644 --- a/libwdi/libwdi.rc +++ b/libwdi/libwdi.rc @@ -50,8 +50,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,3,730,0 - PRODUCTVERSION 1,3,730,0 + FILEVERSION 1,5,1,791 + PRODUCTVERSION 1,5,1,791 FILEFLAGSMASK 0x17L #ifdef _DEBUG FILEFLAGS 0x1L @@ -68,13 +68,13 @@ BEGIN BEGIN VALUE "CompanyName", "akeo.ie" VALUE "FileDescription", "libwdi: Windows Driver Installer Library" - VALUE "FileVersion", "1.3.730" + VALUE "FileVersion", "1.5.1.791" VALUE "InternalName", "libwdi" - VALUE "LegalCopyright", "© 2010-2017 Pete Batard (LGPL v3)" - VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/lesser.html" + VALUE "LegalCopyright", "© 2010-2025 Pete Batard (LGPL v3)" + VALUE "LegalTrademarks", "https://www.gnu.org/licenses/lgpl-3.0.html" VALUE "OriginalFilename", "libwdi" VALUE "ProductName", "libwdi" - VALUE "ProductVersion", "1.3.730" + VALUE "ProductVersion", "1.5.1.791" VALUE "Comments", "http://libwdi.akeo.ie" END END diff --git a/libwdi/libwdi_dlg.c b/libwdi/libwdi_dlg.c index 56e5e9f3..8488cceb 100644 --- a/libwdi/libwdi_dlg.c +++ b/libwdi/libwdi_dlg.c @@ -87,12 +87,12 @@ static int (*progress_function)(void*); static void* progress_arglist; static HANDLE progress_mutex = INVALID_HANDLE_VALUE; -// Work around for GDI calls (would require end user apps linking with Gdi32 othwerwise) +// Work around for GDI calls (would require end user apps linking with Gdi32 otherwise) PF_TYPE_DECL(WINAPI, HFONT, CreateFontA, (int, int, int, int, int, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, LPCSTR)); PF_TYPE_DECL(WINAPI, HGDIOBJ, GetStockObject, (int)); PF_TYPE_DECL(WINAPI, int, SetBkMode, (HDC, int)); -extern char *windows_error_str(uint32_t retval); +extern char *wdi_windows_error_str(uint32_t retval); /* * Detect if a Windows Security prompt is active, by enumerating the @@ -189,7 +189,7 @@ static void init_children(HWND hDlg) app_instance, NULL); if (hProgressBar == NULL) { - wdi_err("Unable to create progress bar: %s", windows_error_str(0)); + wdi_err("Unable to create progress bar: %s", wdi_windows_error_str(0)); } // Start progress animation @@ -205,7 +205,7 @@ static void init_children(HWND hDlg) app_instance, NULL); if (hProgressBar == NULL) { - wdi_err("Unable to create progress text: %s", windows_error_str(0)); + wdi_err("Unable to create progress text: %s", wdi_windows_error_str(0)); } // Set the font to MS Dialog default @@ -383,7 +383,7 @@ int run_with_progress_bar(HWND hWnd, int(*function)(void*), void* arglist) { wc.hbrBackground = GetSysColorBrush(COLOR_3DFACE); if (!RegisterClassEx(&wc)) { - wdi_err("can't register class %s", windows_error_str(0)); + wdi_err("can't register class %s", wdi_windows_error_str(0)); msg.wParam = WDI_ERROR_RESOURCE; goto out; } @@ -395,7 +395,7 @@ int run_with_progress_bar(HWND hWnd, int(*function)(void*), void* arglist) { WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_CAPTION | WS_POPUP | WS_VISIBLE | WS_THICKFRAME, 100, 100, 287, 102, hWnd, NULL, app_instance, NULL); if (hDlg == NULL) { - wdi_err("Unable to create progress dialog: %s", windows_error_str(0)); + wdi_err("Unable to create progress dialog: %s", wdi_windows_error_str(0)); msg.wParam = WDI_ERROR_RESOURCE; goto out; } diff --git a/libwdi/logging.c b/libwdi/logging.c index 6f33c6be..15f18af2 100644 --- a/libwdi/logging.c +++ b/libwdi/logging.c @@ -47,7 +47,7 @@ static DWORD log_messages_pipe_size = 0; // Global debug level static int global_log_level = WDI_LOG_LEVEL_INFO; -extern char *windows_error_str(uint32_t retval); +extern char *wdi_windows_error_str(uint32_t retval); static void write_to_pipe(const char* buffer, DWORD size, enum wdi_log_level level) { @@ -204,7 +204,7 @@ static int create_logger(DWORD buffsize) logger_rd_handle = CreateNamedPipeA(LOGGER_PIPE_NAME, PIPE_ACCESS_INBOUND, PIPE_TYPE_MESSAGE|PIPE_READMODE_MESSAGE, 1, buffsize, buffsize, 0, NULL); if (logger_rd_handle == INVALID_HANDLE_VALUE) { - fprintf(stderr, "could not create logger pipe for reading: %s\n", windows_error_str(0)); + fprintf(stderr, "could not create logger pipe for reading: %s\n", wdi_windows_error_str(0)); return WDI_ERROR_RESOURCE; } @@ -212,7 +212,7 @@ static int create_logger(DWORD buffsize) logger_wr_handle = CreateFileA(LOGGER_PIPE_NAME, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (logger_wr_handle == INVALID_HANDLE_VALUE) { - fprintf(stderr, "could not create logger pipe for writing: %s\n", windows_error_str(0)); + fprintf(stderr, "could not create logger pipe for writing: %s\n", wdi_windows_error_str(0)); CloseHandle(logger_rd_handle); logger_rd_handle = INVALID_HANDLE_VALUE; return WDI_ERROR_RESOURCE; diff --git a/libwdi/msapi_utf8.h b/libwdi/msapi_utf8.h index 9ace267b..71d8ebf7 100644 --- a/libwdi/msapi_utf8.h +++ b/libwdi/msapi_utf8.h @@ -1,9 +1,12 @@ /* * MSAPI_UTF8: Common API calls using UTF-8 strings - * Compensating for what Microsoft should have done a long long time ago. - * Also see https://utf8everywhere.org + * Compensating for what Microsoft should have done a long long time ago, that they + * ONLY started to do in mid-2019 (What the £%^& took them so long?!?), as per: + * https://docs.microsoft.com/en-us/windows/uwp/design/globalizing/use-utf8-code-page * - * Copyright © 2010-2019 Pete Batard + * See also: https://utf8everywhere.org + * + * Copyright © 2010-2023 Pete Batard * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -29,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -87,7 +91,7 @@ static __inline char* wchar_to_utf8(const wchar_t* wstr) // Convert the empty string too if (wstr[0] == 0) - return calloc(1, 1); + return (char*)calloc(1, 1); // Find out the size we need to allocate for our converted string size = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL); @@ -119,7 +123,7 @@ static __inline wchar_t* utf8_to_wchar(const char* str) // Convert the empty string too if (str[0] == 0) - return calloc(1, sizeof(wchar_t)); + return (wchar_t*)calloc(1, sizeof(wchar_t)); // Find out the size we need to allocate for our converted string size = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0); @@ -313,6 +317,18 @@ static __inline HMODULE LoadLibraryU(LPCSTR lpFileName) return ret; } +static __inline HMODULE LoadLibraryExU(LPCSTR lpFileName, HANDLE hFile, DWORD dwFlags) +{ + HMODULE ret; + DWORD err = ERROR_INVALID_DATA; + wconvert(lpFileName); + ret = LoadLibraryExW(wlpFileName, hFile, dwFlags); + err = GetLastError(); + wfree(lpFileName); + SetLastError(err); + return ret; +} + static __inline int DrawTextU(HDC hDC, LPCSTR lpText, int nCount, LPRECT lpRect, UINT uFormat) { int ret; @@ -328,19 +344,19 @@ static __inline int DrawTextU(HDC hDC, LPCSTR lpText, int nCount, LPRECT lpRect, static __inline int GetWindowTextU(HWND hWnd, char* lpString, int nMaxCount) { int ret = 0; - DWORD err = ERROR_INVALID_DATA; + DWORD err = ERROR_INVALID_PARAMETER; + if (lpString == NULL || nMaxCount < 1) + goto out; // Handle the empty string as GetWindowTextW() returns 0 then - if ((lpString != NULL) && (nMaxCount > 0)) - lpString[0] = 0; - // coverity[returned_null] + lpString[0] = 0; walloc(lpString, nMaxCount); ret = GetWindowTextW(hWnd, wlpString, nMaxCount); err = GetLastError(); - // coverity[var_deref_model] - if ( (ret != 0) && ((ret = wchar_to_utf8_no_alloc(wlpString, lpString, nMaxCount)) == 0) ) { + if ((ret != 0) && ((ret = wchar_to_utf8_no_alloc(wlpString, lpString, nMaxCount)) == 0)) err = GetLastError(); - } wfree(lpString); + lpString[nMaxCount - 1] = 0; +out: SetLastError(err); return ret; } @@ -367,7 +383,7 @@ static __inline int GetWindowTextLengthU(HWND hWnd) ret = GetWindowTextLengthW(hWnd); err = GetLastError(); if (ret == 0) goto out; - wbuf = calloc(ret, sizeof(wchar_t)); + wbuf = (wchar_t* )calloc(ret, sizeof(wchar_t)); err = GetLastError(); if (wbuf == NULL) { err = ERROR_OUTOFMEMORY; ret = 0; goto out; @@ -439,7 +455,7 @@ static __inline int ComboBox_GetLBTextU(HWND hCtrl, int index, char* lpString) size = (int)SendMessageW(hCtrl, CB_GETLBTEXTLEN, (WPARAM)index, (LPARAM)0); if (size < 0) return size; - wlpString = (wchar_t*)calloc(size+1, sizeof(wchar_t)); + wlpString = (wchar_t*)calloc((size_t)size + 1, sizeof(wchar_t)); size = (int)SendMessageW(hCtrl, CB_GETLBTEXT, (WPARAM)index, (LPARAM)wlpString); err = GetLastError(); if (size > 0) @@ -452,7 +468,7 @@ static __inline int ComboBox_GetLBTextU(HWND hCtrl, int index, char* lpString) static __inline DWORD CharUpperBuffU(char* lpString, DWORD len) { DWORD ret; - wchar_t *wlpString = calloc(len, sizeof(wchar_t)); + wchar_t *wlpString = (wchar_t*)calloc(len, sizeof(wchar_t)); if (wlpString == NULL) return 0; utf8_to_wchar_no_alloc(lpString, wlpString, len); @@ -567,13 +583,27 @@ static __inline BOOL GetTextExtentPointU(HDC hdc, const char* lpString, LPSIZE l return ret; } +// A UTF-8 alternative to MS GetCurrentDirectory() since the latter is useless for +// apps installed from the App Store... static __inline DWORD GetCurrentDirectoryU(DWORD nBufferLength, char* lpBuffer) { - DWORD ret = 0, err = ERROR_INVALID_DATA; + DWORD i, ret = 0, err = ERROR_INVALID_DATA; // coverity[returned_null] walloc(lpBuffer, nBufferLength); - ret = GetCurrentDirectoryW(nBufferLength, wlpBuffer); + if (wlpBuffer == NULL) { + SetLastError(ERROR_OUTOFMEMORY); + return 0; + } + ret = GetModuleFileNameW(NULL, wlpBuffer, nBufferLength); err = GetLastError(); + if (ret > 0) { + for (i = ret - 1; i > 0; i--) { + if (wlpBuffer[i] == L'\\') { + wlpBuffer[i] = 0; + break; + } + } + } if ((ret != 0) && ((ret = wchar_to_utf8_no_alloc(wlpBuffer, lpBuffer, nBufferLength)) == 0)) { err = GetLastError(); } @@ -677,6 +707,47 @@ static __inline DWORD GetModuleFileNameExU(HANDLE hProcess, HMODULE hModule, cha return ret; } +static __inline DWORD GetFinalPathNameByHandleU(HANDLE hFile, char* lpszFilePath, DWORD cchFilePath, DWORD dwFlags) +{ + DWORD ret = 0, err = ERROR_INVALID_DATA; + walloc(lpszFilePath, cchFilePath); + ret = GetFinalPathNameByHandleW(hFile, wlpszFilePath, cchFilePath, dwFlags); + err = GetLastError(); + if ((ret != 0) + && ((ret = wchar_to_utf8_no_alloc(wlpszFilePath, lpszFilePath, cchFilePath)) == 0)) { + err = GetLastError(); + } + wfree(lpszFilePath); + SetLastError(err); + return ret; +} + +static __inline DWORD GetFileVersionInfoSizeU(const char* lpFileName, LPDWORD lpdwHandle) +{ + DWORD ret = 0, err = ERROR_INVALID_DATA; + wconvert(lpFileName); + ret = GetFileVersionInfoSizeW(wlpFileName, lpdwHandle); + err = GetLastError(); + wfree(lpFileName); + SetLastError(err); + return ret; +} + +static __inline BOOL GetFileVersionInfoU(const char* lpFileName, DWORD dwHandle, DWORD dwLen, LPVOID lpData) +{ + BOOL ret = FALSE; + DWORD err = ERROR_INVALID_DATA; + wconvert(lpFileName); + if (dwHandle != 0) + SetLastError(ERROR_INVALID_PARAMETER); + else + ret = GetFileVersionInfoW(wlpFileName, dwHandle, dwLen, lpData); + err = GetLastError(); + wfree(lpFileName); + SetLastError(err); + return ret; +} + static __inline DWORD GetFullPathNameU(const char* lpFileName, DWORD nBufferLength, char* lpBuffer, char** lpFilePart) { DWORD ret = 0, err = ERROR_INVALID_DATA; @@ -752,7 +823,7 @@ static __inline int SHDeleteDirectoryExU(HWND hwnd, const char* pszPath, FILEOP_ int ret; // String needs to be double NULL terminated, so we just use the length of the UTF-8 string // which is always expected to be larger than our UTF-16 one, and add 2 chars for good measure. - size_t wpszPath_len = strlen(pszPath) + 2; + size_t wpszPath_len = (pszPath == NULL) ? 0 : strlen(pszPath) + 2; // coverity[returned_null] walloc(pszPath, wpszPath_len); SHFILEOPSTRUCTW shfo = { hwnd, FO_DELETE, wpszPath, NULL, fFlags, FALSE, NULL, NULL }; @@ -878,10 +949,10 @@ static __inline BOOL WINAPI GetOpenSaveFileNameU(LPOPENFILENAMEA lpofn, BOOL sav } wofn.nMaxCustFilter = lpofn->nMaxCustFilter; wofn.nFilterIndex = lpofn->nFilterIndex; - wofn.lpstrFile = calloc(lpofn->nMaxFile, sizeof(wchar_t)); + wofn.lpstrFile = (LPWSTR)calloc(lpofn->nMaxFile, sizeof(wchar_t)); utf8_to_wchar_no_alloc(lpofn->lpstrFile, wofn.lpstrFile, lpofn->nMaxFile); wofn.nMaxFile = lpofn->nMaxFile; - wofn.lpstrFileTitle = calloc(lpofn->nMaxFileTitle, sizeof(wchar_t)); + wofn.lpstrFileTitle = (LPWSTR)calloc(lpofn->nMaxFileTitle, sizeof(wchar_t)); utf8_to_wchar_no_alloc(lpofn->lpstrFileTitle, wofn.lpstrFileTitle, lpofn->nMaxFileTitle); wofn.nMaxFileTitle = lpofn->nMaxFileTitle; wofn.lpstrInitialDir = utf8_to_wchar(lpofn->lpstrInitialDir); @@ -1024,7 +1095,7 @@ static __inline int _openU(const char *filename, int oflag , int pmode) } #endif -static __inline int _unlinkU(const char *path) +static __inline int _unlinkU(const char* path) { int ret; wconvert(path); @@ -1042,6 +1113,26 @@ static __inline int _stat64U(const char *path, struct __stat64 *buffer) return ret; } +static __inline int _accessU(const char* path, int mode) +{ + int ret; + wconvert(path); + ret = _waccess(wpath, mode); + wfree(path); + return ret; +} + +static __inline const char* _filenameU(const char* path) +{ + int i; + if (path == NULL) + return NULL; + for (i = (int)strlen(path) - 1; i >= 0; i--) + if ((path[i] == '/') || (path[i] == '\\')) + return &path[i + 1]; + return path; +} + // returned UTF-8 string must be freed static __inline char* getenvU(const char* varname) { @@ -1050,7 +1141,7 @@ static __inline char* getenvU(const char* varname) wchar_t* wbuf = NULL; // _wgetenv() is *BROKEN* in MS compilers => use GetEnvironmentVariableW() DWORD dwSize = GetEnvironmentVariableW(wvarname, wbuf, 0); - wbuf = calloc(dwSize, sizeof(wchar_t)); + wbuf = (wchar_t*)calloc(dwSize, sizeof(wchar_t)); if (wbuf == NULL) { wfree(varname); return NULL; @@ -1072,6 +1163,73 @@ static __inline int _mkdirU(const char* dirname) return ret; } +// This version of _mkdirU creates all needed directories along the way +static __inline int _mkdirExU(const char* dirname) +{ + int ret = -1, trailing_slash = -1; + size_t i, len; + wconvert(dirname); + len = wcslen(wdirname); + while (trailing_slash && (len > 0)) { + if ((wdirname[len - 1] == '\\') || (wdirname[len - 1] == '/')) + wdirname[--len] = 0; + else + trailing_slash = 0; + } + for (i = 0; i < len; i++) + if ((wdirname[i] == '\\') || (wdirname[i] == '/')) + wdirname[i] = 0; + for (i = 0; i < len; ) { + if ((_wmkdir(wdirname) < 0) && (errno != EEXIST) && (errno != EACCES)) + goto out; + i = wcslen(wdirname); + wdirname[i] = '\\'; + } + ret = 0; +out: + wfree(dirname); + return ret; +} + +static __inline int _rmdirU(const char* dirname) +{ + wconvert(dirname); + int ret; + ret = _wrmdir(wdirname); + wfree(dirname); + return ret; +} + +static __inline BOOL MoveFileU(const char* lpExistingFileName, const char* lpNewFileName) +{ + wconvert(lpExistingFileName); + wconvert(lpNewFileName); + BOOL ret = MoveFileW(wlpExistingFileName, wlpNewFileName); + wfree(lpNewFileName); + wfree(lpExistingFileName); + return ret; +} + +static __inline BOOL MoveFileExU(const char* lpExistingFileName, const char* lpNewFileName, DWORD dwFlags) +{ + wconvert(lpExistingFileName); + wconvert(lpNewFileName); + BOOL ret = MoveFileExW(wlpExistingFileName, wlpNewFileName, dwFlags); + wfree(lpNewFileName); + wfree(lpExistingFileName); + return ret; +} + +static __inline BOOL CreateSymbolicLinkU(const char* lpSymlinkFileName, const char* lpTargetFileName, DWORD dwFlags) +{ + wconvert(lpSymlinkFileName); + wconvert(lpTargetFileName); + BOOL ret = CreateSymbolicLinkW(wlpSymlinkFileName, wlpTargetFileName, dwFlags); + wfree(lpTargetFileName); + wfree(lpSymlinkFileName); + return ret; +} + // The following expects PropertyBuffer to contain a single Unicode string static __inline BOOL SetupDiGetDeviceRegistryPropertyU(HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, DWORD Property, PDWORD PropertyRegDataType, PBYTE PropertyBuffer, DWORD PropertyBufferSize, PDWORD RequiredSize) @@ -1094,6 +1252,33 @@ static __inline BOOL SetupDiGetDeviceRegistryPropertyU(HDEVINFO DeviceInfoSet, P return ret; } +// NB: This does not support the ERROR_INSUFFICIENT_BUFFER dance to retrieve the required buffer size +static __inline BOOL GetUserNameU(LPSTR lpBuffer, LPDWORD pcbBuffer) +{ + BOOL ret; + DWORD err, size; + if (lpBuffer == NULL || pcbBuffer == NULL) { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + size = *pcbBuffer; + // coverity[returned_null] + walloc(lpBuffer, size); + ret = GetUserNameW(wlpBuffer, &size); + err = GetLastError(); + if (ret) { + *pcbBuffer = (DWORD)wchar_to_utf8_no_alloc(wlpBuffer, lpBuffer, size); + if (*pcbBuffer == 0) + err = GetLastError(); + else + // Reported size includes the NUL terminator + (*pcbBuffer)++; + } + wfree(lpBuffer); + SetLastError(err); + return ret; +} + static __inline BOOL GetVolumeInformationU(LPCSTR lpRootPathName, LPSTR lpVolumeNameBuffer, DWORD nVolumeNameSize, LPDWORD lpVolumeSerialNumber, LPDWORD lpMaximumComponentLength, LPDWORD lpFileSystemFlags, LPSTR lpFileSystemNameBuffer, DWORD nFileSystemNameSize) diff --git a/libwdi/pki.c b/libwdi/pki.c index 3bc90404..2b100553 100644 --- a/libwdi/pki.c +++ b/libwdi/pki.c @@ -1,6 +1,6 @@ /* * libwdi: Library for automated Windows Driver Installation - PKI part - * Copyright (c) 2011-2017 Pete Batard + * Copyright (c) 2011-2023 Pete Batard * For more info, please visit http://libwdi.akeo.ie * * This library is free software; you can redistribute it and/or @@ -28,10 +28,8 @@ #include #include #include -#include #include #include -#include #include "mssign32.h" #include @@ -188,17 +186,6 @@ typedef PCCERT_CONTEXT (WINAPI *CertCreateSelfSignCertificate_t)( #ifndef szOID_PKIX_POLICY_QUALIFIER_CPS #define szOID_PKIX_POLICY_QUALIFIER_CPS "1.3.6.1.5.5.7.2.1" #endif -typedef struct _CERT_ALT_NAME_ENTRY_URL { - DWORD dwAltNameChoice; - union { - LPWSTR pwszURL; - }; -} CERT_ALT_NAME_ENTRY_URL, *PCERT_ALT_NAME_ENTRY_URL; - -typedef struct _CERT_ALT_NAME_INFO_URL { - DWORD cAltEntry; - PCERT_ALT_NAME_ENTRY_URL rgAltEntry; -} CERT_ALT_NAME_INFO_URL, *PCERT_ALT_NAME_INFO_URL; typedef struct _CERT_POLICY_QUALIFIER_INFO_REDEF { LPSTR pszPolicyQualifierId; @@ -376,7 +363,9 @@ typedef BOOL (WINAPI *CryptCATAdminCalcHashFromFileHandle_t)( DWORD dwFlags ); -extern char *windows_error_str(uint32_t retval); +extern char *wdi_windows_error_str(uint32_t retval); +extern int nWindowsVersion; +extern void GetWindowsVersion(void); /* * FormatMessage does not handle PKI errors @@ -386,31 +375,41 @@ char* winpki_error_str(uint32_t retval) static char error_string[64]; uint32_t error_code = retval ? retval : GetLastError(); + if (error_code == 0x800706D9) + return "This system is missing required cryptographic services."; + if (error_code == 0x80070020) + return "Sharing violation - Some data handles to this file are still open."; + if ((error_code >> 16) != 0x8009) - return windows_error_str(error_code); + return wdi_windows_error_str(error_code); switch (error_code) { case NTE_BAD_UID: return "Bad UID."; case NTE_BAD_KEYSET: - return "The key container could not be opened."; + return "Keyset does not exist."; case NTE_KEYSET_ENTRY_BAD: - return "The requested key container is corrupted."; + return "Keyset as registered is invalid."; case NTE_BAD_FLAGS: + return "Invalid flags specified."; case NTE_BAD_KEYSET_PARAM: + return "The Keyset parameter is invalid."; case NTE_BAD_PROV_TYPE: + return "Invalid provider type specified."; case NTE_EXISTS: - return "Invalid parameter."; + return "Object already exists."; case NTE_BAD_SIGNATURE: - return "This system's cryptographic DLL has been tampered with."; + return "Invalid Signature."; case NTE_PROVIDER_DLL_FAIL: + return "Provider DLL failed to initialize correctly."; case NTE_SIGNATURE_FILE_BAD: + return "The digital signature file is corrupt."; case NTE_PROV_DLL_NOT_FOUND: - return "This system's cryptographic DLL can not be loaded."; + return "Provider DLL could not be found."; case NTE_KEYSET_NOT_DEF: - return "The requested provider does not exist."; + return "The keyset is not defined."; case NTE_NO_MEMORY: - return "Out of memory."; + return "Insufficient memory available for the operation."; case CRYPT_E_MSG_ERROR: return "An error occurred while performing an operation on a cryptographic message."; case CRYPT_E_UNKNOWN_ALGO: @@ -438,9 +437,11 @@ char* winpki_error_str(uint32_t retval) case CRYPT_E_NO_MATCH: return "Cannot find the requested object."; case CRYPT_E_UNEXPECTED_MSG_TYPE: + return "The certificate does not have a property that references a private key."; case CRYPT_E_NO_KEY_PROPERTY: + return "Cannot find the private key to use for decryption."; case CRYPT_E_NO_DECRYPT_CERT: - return "Private key or certificate issue"; + return "Cannot find the certificate to use for decryption."; case CRYPT_E_BAD_MSG: return "Not a cryptographic message."; case CRYPT_E_NO_SIGNER: @@ -448,21 +449,25 @@ char* winpki_error_str(uint32_t retval) case CRYPT_E_REVOKED: return "The certificate is revoked."; case CRYPT_E_NO_REVOCATION_DLL: + return "No Dll or exported function was found to verify revocation."; case CRYPT_E_NO_REVOCATION_CHECK: + return "The revocation function was unable to check revocation for the certificate."; case CRYPT_E_REVOCATION_OFFLINE: + return "The revocation function was unable to check revocation because the revocation server was offline."; case CRYPT_E_NOT_IN_REVOCATION_DATABASE: - return "Cannot check certificate revocation."; + return "The certificate is not in the revocation server's database."; case CRYPT_E_INVALID_NUMERIC_STRING: case CRYPT_E_INVALID_PRINTABLE_STRING: case CRYPT_E_INVALID_IA5_STRING: case CRYPT_E_INVALID_X500_STRING: - case CRYPT_E_NOT_CHAR_STRING: + case CRYPT_E_NOT_CHAR_STRING: return "Invalid string."; case CRYPT_E_SECURITY_SETTINGS: return "The cryptographic operation failed due to a local security option setting."; case CRYPT_E_NO_VERIFY_USAGE_CHECK: + return "The called function was unable to do a usage check on the subject."; case CRYPT_E_VERIFY_USAGE_OFFLINE: - return "Cannot complete usage check."; + return "Since the server was offline, the called function was unable to complete the usage check."; case CRYPT_E_NO_TRUSTED_SIGNER: return "None of the signers of the cryptographic message or certificate trust list is trusted."; default: @@ -578,14 +583,18 @@ BOOL RemoveCertFromStore(LPCSTR szCertSubject, LPCSTR szStoreName) if ( (!pfCertStrToNameA(X509_ASN_ENCODING, szCertSubject, CERT_X500_NAME_STR, NULL, NULL, &certNameBlob.cbData, NULL)) || ((certNameBlob.pbData = (BYTE*)malloc(certNameBlob.cbData)) == NULL) || (!pfCertStrToNameA(X509_ASN_ENCODING, szCertSubject, CERT_X500_NAME_STR, NULL, certNameBlob.pbData, &certNameBlob.cbData, NULL)) ) { - wdi_warn("Failed to encode'%s': %s", szCertSubject, winpki_error_str(0)); + wdi_warn("Failed to encode '%s': %s", szCertSubject, winpki_error_str(0)); goto out; } pCertContext = NULL; while ((pCertContext = pfCertFindCertificateInStore(hSystemStore, X509_ASN_ENCODING, 0, CERT_FIND_SUBJECT_NAME, (const void*)&certNameBlob, NULL)) != NULL) { - pfCertDeleteCertificateFromStore(pCertContext); + if (!pfCertDeleteCertificateFromStore(pCertContext)) { + wdi_warn("Failed to delete certificate '%s' from '%s' store: %s", + szCertSubject, szStoreName, winpki_error_str(0)); + goto out; + } wdi_info("Deleted existing certificate '%s' from '%s' store", szCertSubject, szStoreName); } r = TRUE; @@ -699,7 +708,7 @@ PCCERT_CONTEXT CreateSelfSignedCert(LPCSTR szCertSubject) PF_DECL(CertCreateSelfSignCertificate); PF_DECL(CertFreeCertificateContext); - DWORD dwSize; + DWORD dwSize = 0; HCRYPTPROV hCSP = 0; HCRYPTKEY hKey = 0; PCCERT_CONTEXT pCertContext = NULL; @@ -714,9 +723,10 @@ PCCERT_CONTEXT CreateSelfSignedCert(LPCSTR szCertSubject) // Code Signing Enhanced Key Usage LPSTR szCertPolicyElementId = "1.3.6.1.5.5.7.3.3"; // szOID_PKIX_KP_CODE_SIGNING; CERT_ENHKEY_USAGE certEnhKeyUsage = { 1, &szCertPolicyElementId }; - // Alternate Name (URL) - CERT_ALT_NAME_ENTRY_URL certAltNameEntry = { CERT_ALT_NAME_URL, {L"http://libwdi.akeo.ie"} }; - CERT_ALT_NAME_INFO_URL certAltNameInfo = { 1, &certAltNameEntry }; + // Abuse Alt Name to insert ourselves in the e-mail field + CERT_ALT_NAME_ENTRY certAltNameEntry = { CERT_ALT_NAME_RFC822_NAME, + { (PCERT_OTHER_NAME)L"Created by libwdi (http://libwdi.akeo.ie)" } }; + CERT_ALT_NAME_INFO certAltNameInfo = { 1, &certAltNameEntry }; // Certificate Policies CERT_POLICY_QUALIFIER_INFO_REDEF certPolicyQualifier; CERT_POLICY_INFO_REDEF certPolicyInfo = { "1.3.6.1.5.5.7.2.1", 1, &certPolicyQualifier }; @@ -741,11 +751,11 @@ PCCERT_CONTEXT CreateSelfSignedCert(LPCSTR szCertSubject) certExtension[0].Value.cbData = dwSize; certExtension[0].Value.pbData = pbEnhKeyUsage; - // Set URL as Alt Name parameter + // Set Alt Name parameter if ( (!pfCryptEncodeObject(X509_ASN_ENCODING, X509_ALTERNATE_NAME, (LPVOID)&certAltNameInfo, NULL, &dwSize)) || ((pbAltNameInfo = (BYTE*)malloc(dwSize)) == NULL) || (!pfCryptEncodeObject(X509_ASN_ENCODING, X509_ALTERNATE_NAME, (LPVOID)&certAltNameInfo, pbAltNameInfo, &dwSize)) ) { - wdi_warn("Could not setup URL: %s", winpki_error_str(0)); + wdi_warn("Could not set Alt Name: %s", winpki_error_str(0)); goto out; } certExtension[1].pszObjId = szOID_SUBJECT_ALT_NAME; @@ -784,11 +794,11 @@ PCCERT_CONTEXT CreateSelfSignedCert(LPCSTR szCertSubject) if (CryptAcquireContextW(&hCSP, wszKeyContainer, NULL, PROV_RSA_FULL, CRYPT_MACHINE_KEYSET|CRYPT_SILENT)) { wdi_dbg("Acquired existing key container"); - } else if ( (GetLastError() == NTE_BAD_KEYSET) + } else if ( (GetLastError() == NTE_BAD_KEYSET || GetLastError() == NTE_KEYSET_ENTRY_BAD) && (CryptAcquireContextW(&hCSP, wszKeyContainer, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET|CRYPT_MACHINE_KEYSET|CRYPT_SILENT)) ) { wdi_dbg("Created new key container"); } else { - wdi_warn("Could not obtain a key container: %s", winpki_error_str(0)); + wdi_warn("Could not obtain a key container: %s (0x%08X)", winpki_error_str(0), GetLastError()); goto out; } @@ -975,7 +985,7 @@ BOOL SelfSignFile(LPCSTR szFileName, LPCSTR szCertSubject) signerFileInfo.cbSize = sizeof(SIGNER_FILE_INFO); wszFileName = UTF8toWCHAR(szFileName); if (wszFileName == NULL) { - wdi_warn("Unable to convert '%s' to UTF16"); + wdi_warn("Unable to convert '%s' to UTF16", szFileName); goto out; } signerFileInfo.pwszFileName = wszFileName; @@ -1025,7 +1035,7 @@ BOOL SelfSignFile(LPCSTR szFileName, LPCSTR szCertSubject) // Sign file with cert hResult = pfSignerSignEx(0, &signerSubjectInfo, &signerCert, &signerSignatureInfo, NULL, NULL, NULL, NULL, &pSignerContext); if (hResult != S_OK) { - wdi_warn("SignerSignEx failed. hResult #%X, error %s", hResult, winpki_error_str(0)); + wdi_warn("SignerSignEx failed: %s", winpki_error_str(hResult)); goto out; } r = TRUE; @@ -1353,7 +1363,7 @@ BOOL CreateCat(LPCSTR szCatPath, LPCSTR szHWID, LPCSTR szSearchDir, LPCSTR* szFi goto out; } // Make sure the list entries are all lowercase - szLocalFileList = (LPSTR *)malloc(cFileList*sizeof(LPSTR)); + szLocalFileList = (LPSTR *)calloc(cFileList, sizeof(LPSTR)); if (szLocalFileList == NULL) { wdi_warn("Unable allocate local file list"); goto out; diff --git a/libwdi/stdfn.h b/libwdi/stdfn.h index d86b2945..fbed6fbd 100644 --- a/libwdi/stdfn.h +++ b/libwdi/stdfn.h @@ -1,6 +1,6 @@ /* * Library for USB automated driver installation -* Copyright (c) 2010-2017 Pete Batard +* Copyright (c) 2010-2023 Pete Batard * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -32,19 +32,18 @@ enum WindowsVersion { WINDOWS_UNDEFINED = -1, WINDOWS_UNSUPPORTED = 0, - WINDOWS_7 = 0x61, - WINDOWS_8 = 0x62, - WINDOWS_8_1 = 0x63, + WINDOWS_XP = 0x51, + WINDOWS_2003 = 0x52, // Also XP_64 + WINDOWS_VISTA = 0x60, // Also Server 2008 + WINDOWS_7 = 0x61, // Also Server 2008_R2 + WINDOWS_8 = 0x62, // Also Server 2012 + WINDOWS_8_1 = 0x63, // Also Server 2012_R2 WINDOWS_10_PREVIEW1 = 0x64, - WINDOWS_10 = 0xA0, + WINDOWS_10 = 0xA0, // Also Server 2016, also Server 2019 + WINDOWS_11 = 0xB0, // Also Server 2022 WINDOWS_MAX }; -extern int nWindowsVersion; -extern char WindowsVersionStr[128]; - -void GetWindowsVersion(void); - /* Read a string registry key value */ static __inline BOOL ReadRegistryStr(HKEY key_root, const char* key_name, char* str, DWORD len) { diff --git a/libwdi/tokenizer.c b/libwdi/tokenizer.c index e1126308..b82f2e95 100644 --- a/libwdi/tokenizer.c +++ b/libwdi/tokenizer.c @@ -77,8 +77,8 @@ long tokenize_string(const char* src, // text to bo tokenized long src_count, // length of src char** dst, // destination buffer (must be freed) const token_entity_t* token_entities, // match/replace token list - const char* tok_prefix, // the token prefix exmpl:"$(" - const char* tok_suffix, // the token suffix exmpl:")" + const char* tok_prefix, // the token prefix example:"$(" + const char* tok_suffix, // the token suffix example:")" int recursive) // allows tokenzing tokens in tokens { const token_entity_t* next_match; diff --git a/libwdi/usbser.inf.in b/libwdi/usbser.inf.in index 800b064b..afb87711 100644 --- a/libwdi/usbser.inf.in +++ b/libwdi/usbser.inf.in @@ -1,5 +1,5 @@ ; #INF_FILENAME# -; Copyright (c) 2016 Pete Batard (GNU LGPL) +; Copyright (c) 2016-2023 Pete Batard (GNU LGPL) ; Based on the USB CDC .inf sample file provided by James Stephanick ; at https://community.freescale.com/message/493287#493287 ; With acknowledgement to Sensics, Inc. , @@ -22,7 +22,7 @@ CatalogFile = #CAT_FILENAME# DriverVer = #DRIVER_DATE#, 1.0.0.0 [Manufacturer] -%VendorName% = DeviceList,NTx86,NTamd64,NTarm +%VendorName% = DeviceList,NTx86,NTamd64,NTarm64 [DeviceList.NTx86] %DeviceName% = UsbSer_Install, USB\%DeviceID% @@ -30,7 +30,7 @@ DriverVer = #DRIVER_DATE#, 1.0.0.0 [DeviceList.NTamd64] %DeviceName% = UsbSer_Install, USB\%DeviceID% -[DeviceList.NTarm] +[DeviceList.NTarm64] %DeviceName% = UsbSer_Install, USB\%DeviceID% [UsbSer_Install] diff --git a/libwdi/vid_data.c b/libwdi/vid_data.c index a8d7952a..282ec20a 100644 --- a/libwdi/vid_data.c +++ b/libwdi/vid_data.c @@ -29,7 +29,7 @@ struct vendor_name { /* * http://www.linux-usb.org/usb.ids - * Version: 2020.03.25 + * Version: 2024.03.18 */ static struct vendor_name usb_vendor[] = { { 0x0001, "Fry's Electronics" }, @@ -37,10 +37,13 @@ static struct vendor_name usb_vendor[] = { { 0x0003, "Club Mac" }, { 0x0004, "Nebraska Furniture Mart" }, { 0x0011, "Unknown" }, + { 0x001f, "Walmart" }, + { 0x0040, "Anyware Corporation" }, + { 0x0042, "DMT" }, { 0x0053, "Planex" }, { 0x0078, "Microntek" }, { 0x0079, "DragonRise Inc." }, - { 0x0080, "Assmann Electronic GmbH" }, + { 0x0080, "Unknown" }, { 0x0085, "Boeye Technology Co., Ltd." }, { 0x0102, "miniSTREAK" }, { 0x0105, "Trust International B.V." }, @@ -50,11 +53,13 @@ static struct vendor_name usb_vendor[] = { { 0x0200, "TP-Link" }, { 0x0204, "Chipsbank Microelectronics Co., Ltd" }, { 0x0218, "Hangzhou Worlde" }, + { 0x0231, "Sonuus Limited" }, { 0x02ad, "HUMAX Co., Ltd." }, { 0x0303, "Mini Automation Controller" }, { 0x0324, "OCZ Technology Inc" }, { 0x0325, "OCZ Technology Inc" }, { 0x0386, "LTS" }, + { 0x03c3, "ZWO" }, { 0x03d9, "Shenzhen Sinote Tech-Electron Co., Ltd" }, { 0x03da, "Bernd Walter Computer Technology" }, { 0x03e7, "Intel" }, @@ -122,7 +127,7 @@ static struct vendor_name usb_vendor[] = { { 0x042d, "Micronics" }, { 0x042e, "Acer, Inc." }, { 0x042f, "Molex, Inc." }, - { 0x0430, "Sun Microsystems, Inc." }, + { 0x0430, "Fujitsu Component Limited" }, { 0x0431, "Itac Systems, Inc." }, { 0x0432, "Unisys Corp." }, { 0x0433, "Alps Electric, Inc." }, @@ -169,7 +174,7 @@ static struct vendor_name usb_vendor[] = { { 0x0464, "AMP/Tycoelectronics Corp." }, { 0x0467, "AT&T Paradyne" }, { 0x0468, "Wieson Technologies Co., Ltd" }, - { 0x046a, "Cherry GmbH" }, + { 0x046a, "CHERRY" }, { 0x046b, "American Megatrends, Inc." }, { 0x046c, "Toshiba Corp., Digital Media Equipment" }, { 0x046d, "Logitech, Inc." }, @@ -487,7 +492,7 @@ static struct vendor_name usb_vendor[] = { { 0x05b5, "Dialogic Corp." }, { 0x05b6, "Proxima Corp." }, { 0x05b7, "Medianix Semiconductor, Inc." }, - { 0x05b8, "Agiler, Inc." }, + { 0x05b8, "SYSGRATION" }, { 0x05b9, "Philips Research Laboratories" }, { 0x05ba, "DigitalPersona, Inc." }, { 0x05bb, "Grey Cell Systems" }, @@ -672,6 +677,7 @@ static struct vendor_name usb_vendor[] = { { 0x068a, "Pertech, Inc." }, { 0x068b, "Potrans International, Inc." }, { 0x068e, "CH Products, Inc." }, + { 0x068f, "Nihon KOHDEN" }, { 0x0690, "Golden Bridge Electech, Inc." }, { 0x0693, "Hagiwara Sys-Com Co., Ltd" }, { 0x0694, "Lego Group" }, @@ -819,11 +825,12 @@ static struct vendor_name usb_vendor[] = { { 0x0776, "Inalways Corp." }, { 0x0777, "Comda Enterprise Corp." }, { 0x0778, "Volex, Inc." }, - { 0x0779, "Fairchild Semiconductor" }, + { 0x0779, "ON Semiconductor (formerly Fairchild)" }, { 0x077a, "Sankyo Seiki Mfg. Co., Ltd" }, { 0x077b, "Linksys" }, { 0x077c, "Forward Electronics Co., Ltd" }, { 0x077d, "Griffin Technology" }, + { 0x077e, "Softing AG" }, { 0x077f, "Well Excellent & Most Corp." }, { 0x0780, "Sagem Monetel GmbH" }, { 0x0781, "SanDisk Corp." }, @@ -879,6 +886,7 @@ static struct vendor_name usb_vendor[] = { { 0x07cb, "Kingmax Technology, Inc." }, { 0x07cc, "Carry Computer Eng., Co., Ltd" }, { 0x07cd, "Elektor" }, + { 0x07ce, "Nidec Copal" }, { 0x07cf, "Casio Computer Co., Ltd" }, { 0x07d0, "Dazzle" }, { 0x07d1, "D-Link System" }, @@ -926,6 +934,7 @@ static struct vendor_name usb_vendor[] = { { 0x081b, "Indigita Corp." }, { 0x081c, "Mipsys" }, { 0x081e, "AlphaSmart, Inc." }, + { 0x081f, "Manta" }, { 0x0822, "Reudo Corp." }, { 0x0825, "GC Protronics" }, { 0x0826, "Data Transit" }, @@ -1149,6 +1158,7 @@ static struct vendor_name usb_vendor[] = { { 0x09aa, "Intersil Corp." }, { 0x09ab, "Japan Cash Machine Co., Ltd." }, { 0x09ae, "Tripp Lite" }, + { 0x09b0, "Fargo" }, { 0x09b2, "Franklin Electronic Publishers, Inc." }, { 0x09b3, "Altius Solutions, Inc." }, { 0x09b4, "MDS Telephone Systems" }, @@ -1171,8 +1181,8 @@ static struct vendor_name usb_vendor[] = { { 0x09d1, "NeoMagic, Inc." }, { 0x09d2, "Vreelin Engineering, Inc." }, { 0x09d3, "Com One" }, - { 0x09d7, "NovAtel Inc." }, - { 0x09d8, "ELATEC" }, + { 0x09d7, "Hexagon NovAtel Inc." }, + { 0x09d8, "ELATEC GmbH" }, { 0x09d9, "KRF Tech, Ltd" }, { 0x09da, "A4Tech Co., Ltd." }, { 0x09db, "Measurement Computing Corp." }, @@ -1217,6 +1227,7 @@ static struct vendor_name usb_vendor[] = { { 0x0a2c, "AK-Modul-Bus Computer GmbH" }, { 0x0a34, "TG3 Electronics, Inc." }, { 0x0a35, "Radikal Technologies" }, + { 0x0a38, "IRIS sa" }, { 0x0a39, "Gilat Satellite Networks, Ltd" }, { 0x0a3a, "PentaMedia Co., Ltd" }, { 0x0a3c, "NTT DoCoMo, Inc." }, @@ -1240,7 +1251,7 @@ static struct vendor_name usb_vendor[] = { { 0x0a5b, "EAsics NV" }, { 0x0a5c, "Broadcom Corp." }, { 0x0a5d, "Diatrend Corp." }, - { 0x0a5f, "Zebra" }, + { 0x0a5f, "Zebra Technologies" }, { 0x0a62, "MPMan" }, { 0x0a66, "ClearCube Technology" }, { 0x0a67, "Medeli Electronics Co., Ltd" }, @@ -1451,6 +1462,7 @@ static struct vendor_name usb_vendor[] = { { 0x0bf6, "Addonics Technologies, Inc." }, { 0x0bf7, "Sunny Giken, Inc." }, { 0x0bf8, "Fujitsu Siemens Computers" }, + { 0x0bfb, "Grass Valley Group" }, { 0x0bfd, "Kvaser AB" }, { 0x0c00, "FireFly Mouse Mat" }, { 0x0c04, "MOTO Development Group, Inc." }, @@ -1470,6 +1482,7 @@ static struct vendor_name usb_vendor[] = { { 0x0c1a, "Silicon Motion, Inc." }, { 0x0c1b, "MIPS Technologies" }, { 0x0c1c, "Hang Zhou Silan Electronics Co., Ltd" }, + { 0x0c1f, "Magicard" }, { 0x0c22, "Tally Printer Corp." }, { 0x0c23, "Lernout + Hauspie" }, { 0x0c24, "Taiyo Yuden" }, @@ -1488,6 +1501,7 @@ static struct vendor_name usb_vendor[] = { { 0x0c3c, "Radius Co., Ltd" }, { 0x0c3d, "Innocom, Inc." }, { 0x0c3e, "Nextcell, Inc." }, + { 0x0c40, "ELMCU" }, { 0x0c44, "Motorola iDEN" }, { 0x0c45, "Microdia" }, { 0x0c46, "WaveRider Communications, Inc." }, @@ -1535,6 +1549,7 @@ static struct vendor_name usb_vendor[] = { { 0x0c99, "Innochips Co., Ltd" }, { 0x0c9a, "Hanwool Robotics Corp." }, { 0x0c9b, "Jobin Yvon, Inc." }, + { 0x0c9c, "Brand Innovators BV" }, { 0x0c9d, "SemTek" }, { 0x0ca2, "Zyfer" }, { 0x0ca3, "Sega Corp." }, @@ -1542,6 +1557,7 @@ static struct vendor_name usb_vendor[] = { { 0x0ca5, "BAE Systems Canada, Inc." }, { 0x0ca6, "Castles Technology Co., Ltd" }, { 0x0ca7, "Information Systems Laboratories" }, + { 0x0caa, "Allied Telesis KK." }, { 0x0cad, "Motorola CGISS" }, { 0x0cae, "Ascom Business Systems, Ltd" }, { 0x0caf, "Buslink" }, @@ -1608,6 +1624,7 @@ static struct vendor_name usb_vendor[] = { { 0x0d18, "coaXmedia" }, { 0x0d19, "Hank Connection Industrial Co., Ltd" }, { 0x0d28, "NXP" }, + { 0x0d2f, "Andamiro" }, { 0x0d32, "Leo Hui Electric Wire & Cable Co., Ltd" }, { 0x0d33, "AirSpeak, Inc." }, { 0x0d34, "Rearden Steel Technologies" }, @@ -1636,6 +1653,7 @@ static struct vendor_name usb_vendor[] = { { 0x0d55, "ASKA Technologies, Inc." }, { 0x0d56, "AVLAB Technology, Inc." }, { 0x0d57, "Solomon Microtech, Ltd" }, + { 0x0d59, "TRC Simulators b.v." }, { 0x0d5c, "SMC Networks, Inc." }, { 0x0d5e, "Myacom, Ltd" }, { 0x0d5f, "CSI, Inc." }, @@ -1748,12 +1766,14 @@ static struct vendor_name usb_vendor[] = { { 0x0e17, "Walex Electronic, Ltd" }, { 0x0e1a, "Unisys" }, { 0x0e1b, "Crewave" }, + { 0x0e1e, "Green Hills Software" }, { 0x0e20, "Pegasus Technologies Ltd." }, { 0x0e21, "Cowon Systems, Inc." }, { 0x0e22, "Symbian Ltd." }, { 0x0e23, "Liou Yuane Enterprise Co., Ltd" }, { 0x0e25, "VinChip Systems, Inc." }, { 0x0e26, "J-Phone East Co., Ltd" }, + { 0x0e2e, "Brady Worldwide, Inc." }, { 0x0e30, "HeartMath LLC" }, { 0x0e34, "Micro Computer Control Corp." }, { 0x0e35, "3Pea Technologies, Inc." }, @@ -1884,6 +1904,7 @@ static struct vendor_name usb_vendor[] = { { 0x0f41, "RDC Semiconductor Co., Ltd" }, { 0x0f42, "Nital Consulting Services, Inc." }, { 0x0f44, "Polhemus" }, + { 0x0f49, "Evolis SA" }, { 0x0f4b, "St. John Technology Co., Ltd" }, { 0x0f4c, "WorldWide Cable Opto Corp." }, { 0x0f4d, "Microtune, Inc." }, @@ -2086,6 +2107,7 @@ static struct vendor_name usb_vendor[] = { { 0x10f0, "Nexio Co., Ltd" }, { 0x10f1, "Importek" }, { 0x10f5, "Turtle Beach" }, + { 0x10f8, "Cesys GmbH" }, { 0x10fb, "Pictos Technologies, Inc." }, { 0x10fd, "Anubis Electronics, Ltd" }, { 0x10fe, "Thrane & Thrane" }, @@ -2153,6 +2175,7 @@ static struct vendor_name usb_vendor[] = { { 0x11be, "R&D International NV" }, { 0x11c0, "Betop" }, { 0x11c5, "Inmax" }, + { 0x11c9, "Nacon" }, { 0x11ca, "VeriFone Inc" }, { 0x11db, "Topfield Co., Ltd." }, { 0x11e6, "K.I. Technology Co. Ltd." }, @@ -2165,8 +2188,10 @@ static struct vendor_name usb_vendor[] = { { 0x120f, "Magellan" }, { 0x1210, "DigiTech" }, { 0x121e, "Jungsoft Co., Ltd" }, + { 0x121f, "Panini S.p.A." }, { 0x1220, "TC Electronic" }, { 0x1221, "Unknown manufacturer" }, + { 0x1222, "TiPro" }, { 0x1223, "SKYCABLE ENTERPRISE. CO., LTD." }, { 0x1228, "Datapaq Limited" }, { 0x1230, "Chipidea-Microelectronica, S.A." }, @@ -2174,10 +2199,12 @@ static struct vendor_name usb_vendor[] = { { 0x1234, "Brain Actuated Technologies" }, { 0x1235, "Focusrite-Novation" }, { 0x1241, "Belkin" }, + { 0x1243, "Holtek Semiconductor, Inc." }, { 0x124a, "AirVast" }, { 0x124b, "Nyko (Honey Bee)" }, { 0x124c, "MXI - Memory Experts International, Inc." }, { 0x125c, "Apogee Inc." }, + { 0x125d, "JMicron" }, { 0x125f, "A-DATA Technology Co., Ltd." }, { 0x1260, "Standard Microsystems Corp." }, { 0x1264, "Covidien Energy-based Devices" }, @@ -2208,6 +2235,7 @@ static struct vendor_name usb_vendor[] = { { 0x12cf, "DEXIN" }, { 0x12d1, "Huawei Technologies Co., Ltd." }, { 0x12d2, "LINE TECH INDUSTRIAL CO., LTD." }, + { 0x12d3, "LINAK" }, { 0x12d6, "EMS Dr. Thomas Wuensche" }, { 0x12d7, "BETTER WIRE FACTORY CO., LTD." }, { 0x12d8, "Araneus Information Systems Oy" }, @@ -2218,6 +2246,7 @@ static struct vendor_name usb_vendor[] = { { 0x12f7, "Memorex Products, Inc." }, { 0x12fd, "AIN Comm. Technology Co., Ltd" }, { 0x12ff, "Fascinating Electronics, Inc." }, + { 0x1306, "FM20 Barcode Scanner" }, { 0x1307, "Transcend Information, Inc." }, { 0x1308, "Shuttle, Inc." }, { 0x1310, "Roper" }, @@ -2236,6 +2265,7 @@ static struct vendor_name usb_vendor[] = { { 0x134c, "PanJit International Inc." }, { 0x134e, "Digby's Bitpile, Inc. DBA D Bit" }, { 0x1357, "P&E Microcomputer Systems" }, + { 0x135e, "Insta GmbH" }, { 0x135f, "Control Development Inc." }, { 0x1366, "SEGGER" }, { 0x136b, "STEC" }, @@ -2245,12 +2275,13 @@ static struct vendor_name usb_vendor[] = { { 0x1376, "Vimtron Electronics Co., Ltd." }, { 0x1377, "Sennheiser electronic GmbH & Co. KG" }, { 0x137b, "SCAPS GmbH" }, + { 0x137c, "YASKAWA ELECTRIC CORP." }, { 0x1385, "Netgear, Inc" }, { 0x138a, "Validity Sensors, Inc." }, { 0x138e, "Jungo LTD" }, { 0x1390, "TOMTOM B.V." }, { 0x1391, "IdealTEK, Inc." }, - { 0x1395, "Sennheiser Communications" }, + { 0x1395, "DSEA A/S" }, { 0x1397, "BEHRINGER International GmbH" }, { 0x1398, "Q-tec" }, { 0x13ad, "Baltech" }, @@ -2276,10 +2307,11 @@ static struct vendor_name usb_vendor[] = { { 0x13ec, "Zydacron" }, { 0x13ee, "MosArt" }, { 0x13fd, "Initio Corporation" }, - { 0x13fe, "Kingston Technology Company Inc." }, + { 0x13fe, "Phison Electronics Corp." }, { 0x1400, "Axxion Group Corp." }, { 0x1402, "Bowe Bell & Howell" }, { 0x1403, "Sitronix" }, + { 0x1404, "Fundamental Software, Inc." }, { 0x1409, "IDS Imaging Development Systems GmbH" }, { 0x140e, "Telechips, Inc." }, { 0x1410, "Novatel Wireless" }, @@ -2306,6 +2338,7 @@ static struct vendor_name usb_vendor[] = { { 0x1460, "Tatung Co." }, { 0x1461, "Staccato Communications" }, { 0x1462, "Micro Star International" }, + { 0x146b, "BigBen Interactive" }, { 0x1472, "Huawei-3Com" }, { 0x147a, "Formosa Industrial Computing, Inc." }, { 0x147e, "Upek" }, @@ -2341,6 +2374,8 @@ static struct vendor_name usb_vendor[] = { { 0x14f7, "TechniSat Digital GmbH" }, { 0x1500, "Ellisys" }, { 0x1501, "Pine-Tum Enterprise Co., Ltd." }, + { 0x1504, "Bixolon CO LTD" }, + { 0x1508, "Fibocom" }, { 0x1509, "First International Computer, Inc." }, { 0x1513, "medMobile" }, { 0x1514, "Actel" }, @@ -2386,7 +2421,7 @@ static struct vendor_name usb_vendor[] = { { 0x15ba, "Olimex Ltd." }, { 0x15c0, "XL Imaging" }, { 0x15c2, "SoundGraph Inc." }, - { 0x15c5, "Advance Multimedia Internet Technology Inc. (AMIT)" }, + { 0x15c5, "Pressure Profile Systems, Inc." }, { 0x15c6, "Laboratoires MXM" }, { 0x15c8, "KTF Technologies" }, { 0x15c9, "D-Box Technologies" }, @@ -2417,6 +2452,7 @@ static struct vendor_name usb_vendor[] = { { 0x162f, "WiQuest Communications, Inc." }, { 0x1630, "2Wire, Inc." }, { 0x1631, "Good Way Technology" }, + { 0x1633, "AIM GmbH" }, { 0x1645, "Entrega [hex]" }, { 0x1649, "SofTec Microsystems" }, { 0x164a, "ChipX" }, @@ -2431,6 +2467,7 @@ static struct vendor_name usb_vendor[] = { { 0x166a, "Clipsal" }, { 0x1677, "China Huada Integrated Circuit Design (Group) Co., Ltd. (CIDC Group)" }, { 0x1679, "Total Phase" }, + { 0x167b, "Pure Digital Technologies, Inc." }, { 0x1680, "Golden Bridge Electech Inc." }, { 0x1681, "Prevo Technologies, Inc." }, { 0x1682, "Maxwise Production Enterprise Ltd." }, @@ -2462,8 +2499,9 @@ static struct vendor_name usb_vendor[] = { { 0x16dc, "Wiener, Plein & Baus" }, { 0x16de, "Telemecanique" }, { 0x16df, "King Billion Electronics Co., Ltd." }, - { 0x16f0, "GN ReSound A/S" }, + { 0x16f0, "GN Hearing A/S" }, { 0x16f5, "Futurelogic Inc." }, + { 0x1702, "FDI-MATELEC" }, { 0x1706, "BlueView Technologies, Inc." }, { 0x1707, "ARTIMI" }, { 0x170b, "Swissonic" }, @@ -2475,7 +2513,7 @@ static struct vendor_name usb_vendor[] = { { 0x172f, "Waltop International Corp." }, { 0x1733, "Cellink Technology Co., Ltd" }, { 0x1736, "CANON IMAGING SYSTEM TECHNOLOGIES INC." }, - { 0x1737, "Linksys" }, + { 0x1737, "802.11g Adapter [Linksys WUSB54GC v3]" }, { 0x173a, "Roche" }, { 0x173d, "QSENN" }, { 0x1740, "Senao" }, @@ -2487,14 +2525,17 @@ static struct vendor_name usb_vendor[] = { { 0x1756, "ENENSYS Technologies" }, { 0x1759, "LucidPort Technology, Inc." }, { 0x1761, "ASUSTek Computer, Inc. (wrong ID)" }, + { 0x1770, "MSI" }, { 0x1772, "System Level Solutions, Inc." }, { 0x1776, "Arowana" }, + { 0x1777, "Microscan Systems, Inc." }, { 0x177f, "Sweex" }, { 0x1781, "Multiple Vendors" }, { 0x1782, "Spreadtrum Communications Inc." }, { 0x1784, "TopSeed Technology Corp." }, { 0x1787, "ATI AIB" }, { 0x1788, "ShenZhen Litkconn Technology Co., Ltd." }, + { 0x178e, "ASUSTek Computer, Inc. (wrong ID)" }, { 0x1796, "Printrex, Inc." }, { 0x1797, "JALCO CO., LTD." }, { 0x1799, "Thales Norway A/S" }, @@ -2517,7 +2558,7 @@ static struct vendor_name usb_vendor[] = { { 0x17ef, "Lenovo" }, { 0x17f4, "WaveSense" }, { 0x17f5, "K.K. Rocky" }, - { 0x17f6, "Unicomp, Inc" }, + { 0x17f6, "Unicomp, Inc." }, { 0x1809, "Advantech" }, { 0x1822, "Twinhan" }, { 0x1831, "Gwo Jinn Industries Co., Ltd." }, @@ -2525,6 +2566,7 @@ static struct vendor_name usb_vendor[] = { { 0x183d, "VIVOphone" }, { 0x1843, "Vaisala" }, { 0x1849, "ASRock Incorporation" }, + { 0x184f, "K2L GmbH" }, { 0x1852, "GYROCOM C&C Co., LTD" }, { 0x1854, "Memory Devices Ltd." }, { 0x185b, "Compro" }, @@ -2556,6 +2598,7 @@ static struct vendor_name usb_vendor[] = { { 0x18e8, "Qcom" }, { 0x18ea, "Matrox Graphics, Inc." }, { 0x18ec, "Arkmicro Technologies Inc." }, + { 0x18ef, "ELV Elektronik AG" }, { 0x18f8, "[Maxxter]" }, { 0x18fb, "Scriptel Corporation" }, { 0x18fd, "FineArch Inc." }, @@ -2567,10 +2610,12 @@ static struct vendor_name usb_vendor[] = { { 0x191c, "Innovative Technology LTD" }, { 0x1923, "FitLinxx" }, { 0x1926, "NextWindow" }, + { 0x1928, "Proceq SA" }, { 0x192f, "Avago Technologies, Pte." }, { 0x1930, "Shenzhen Xianhe Technology Co., Ltd." }, { 0x1931, "Ningbo Broad Telecommunication Co., Ltd." }, { 0x1934, "Feature Integration Technology Inc. (Fintek)" }, + { 0x1935, "Elektron Music Machines" }, { 0x1938, "Meinberg Funkuhren GmbH & Co. KG" }, { 0x1941, "Dream Link" }, { 0x1943, "Sensoray Co., Inc." }, @@ -2580,22 +2625,27 @@ static struct vendor_name usb_vendor[] = { { 0x1953, "Ironkey Inc." }, { 0x1954, "Radiient Technologies" }, { 0x195d, "Itron Technology iONE" }, + { 0x1963, "IK Multimedia" }, { 0x1965, "Uniden Corporation" }, { 0x1967, "CASIO HITACHI Mobile Communications Co., Ltd." }, { 0x196b, "Wispro Technology Inc." }, { 0x1970, "Dane-Elec Corp. USA" }, + { 0x1973, "Spectralink Corporation" }, { 0x1975, "Dongguan Guneetal Wire & Cable Co., Ltd." }, { 0x1976, "Chipsbrand Microelectronics (HK) Co., Ltd." }, { 0x1977, "T-Logic" }, { 0x197d, "Leuze electronic" }, + { 0x1980, "Storage Appliance Corporation" }, { 0x1989, "Nuconn Technology Corp." }, { 0x198f, "Beceem Communications Inc." }, { 0x1990, "Acron Precision Industrial Co., Ltd." }, { 0x1995, "Trillium Technology Pty. Ltd." }, { 0x1996, "PixeLINK" }, + { 0x1997, "Shenzhen Riitek Technology Co., Ltd" }, { 0x199b, "MicroStrain, Inc." }, { 0x199e, "The Imaging Source Europe GmbH" }, { 0x199f, "Benica Corporation" }, + { 0x19a5, "HARRIS Corp." }, { 0x19a8, "Biforst Technology Inc." }, { 0x19ab, "Bodelin" }, { 0x19af, "S Life" }, @@ -2607,6 +2657,7 @@ static struct vendor_name usb_vendor[] = { { 0x19c2, "Futuba" }, { 0x19ca, "Mindtribe" }, { 0x19cf, "Parrot SA" }, + { 0x19d1, "BYD" }, { 0x19d2, "ZTE WCDMA Technologies MSM" }, { 0x19db, "KFI Printers" }, { 0x19e1, "WeiDuan Electronic Accessory (S.Z.) Co., Ltd." }, @@ -2614,6 +2665,7 @@ static struct vendor_name usb_vendor[] = { { 0x19ef, "Pak Heng Technology (Shenzhen) Co., Ltd." }, { 0x19f7, "RODE Microphones" }, { 0x19fa, "Gampaq Co.Ltd" }, + { 0x19fd, "MTI Instruments Inc." }, { 0x19ff, "Dynex" }, { 0x1a08, "Bellwood International, Inc." }, { 0x1a0a, "USB-IF non-workshop" }, @@ -2632,6 +2684,7 @@ static struct vendor_name usb_vendor[] = { { 0x1a4b, "SafeBoot International B.V." }, { 0x1a5a, "Tandberg Data" }, { 0x1a61, "Abbott Diabetes Care" }, + { 0x1a64, "Mastervolt" }, { 0x1a6a, "Spansion Inc." }, { 0x1a6d, "SamYoung Electronics Co., Ltd" }, { 0x1a6e, "Global Unichip Corp." }, @@ -2640,6 +2693,7 @@ static struct vendor_name usb_vendor[] = { { 0x1a79, "Bayer Health Care LLC" }, { 0x1a7b, "Lumberg Connect GmbH & Co. KG" }, { 0x1a7c, "Evoluent" }, + { 0x1a7e, "Meltec Systementwicklung" }, { 0x1a81, "Holtek Semiconductor, Inc." }, { 0x1a86, "QinHeng Electronics" }, { 0x1a89, "Dynalith Systems Co., Ltd." }, @@ -2649,25 +2703,31 @@ static struct vendor_name usb_vendor[] = { { 0x1aa4, "Data Drive Thru, Inc." }, { 0x1aa5, "UBeacon Technologies, Inc." }, { 0x1aa6, "eFortune Technology Corp." }, + { 0x1aab, "Silvercreations Software AG" }, { 0x1aad, "KeeTouch" }, { 0x1ab1, "Rigol Technologies" }, + { 0x1ab2, "Allied Vision" }, { 0x1acb, "Salcomp Plc" }, { 0x1acc, "Midiplus Co, Ltd." }, { 0x1ad1, "Desay Wire Co., Ltd." }, { 0x1ad4, "APS" }, - { 0x1adb, "SEL C662 Serial Cable" }, + { 0x1adb, "Schweitzer Engineering Laboratories, Inc" }, { 0x1ae4, "ic-design Reinhard Gottinger GmbH" }, { 0x1ae7, "X-TENSIONS" }, { 0x1aed, "High Top Precision Electronic Co., Ltd." }, { 0x1aef, "Conntech Electronic (Suzhou) Corporation" }, { 0x1af1, "Connect One Ltd." }, + { 0x1af3, "Kingsis Technology Corporation" }, { 0x1afe, "A. Eberle GmbH & Co. KG" }, { 0x1b04, "Meilhaus Electronic GmbH" }, { 0x1b0e, "BLUTRONICS S.r.l." }, + { 0x1b12, "Eventide" }, { 0x1b1c, "Corsair" }, + { 0x1b1e, "General Imaging / General Electric" }, { 0x1b1f, "eQ-3 Entwicklung GmbH" }, { 0x1b20, "MStar Semiconductor, Inc." }, { 0x1b22, "WiLinx Corp." }, + { 0x1b24, "Telegent Systems, Inc." }, { 0x1b26, "Cellex Power Products, Inc." }, { 0x1b27, "Current Electronics Inc." }, { 0x1b28, "NAVIsis Inc." }, @@ -2704,6 +2764,8 @@ static struct vendor_name usb_vendor[] = { { 0x1bad, "Harmonix Music" }, { 0x1bae, "Vuzix Corporation" }, { 0x1bbb, "T & A Mobile Phones" }, + { 0x1bbd, "Videology Imaging Solutions, Inc." }, + { 0x1bc0, "Beijing Senseshield Technology Co.,Ltd." }, { 0x1bc4, "Ford Motor Co." }, { 0x1bc5, "AVIXE Technology (China) Ltd." }, { 0x1bc7, "Telit Wireless Solutions" }, @@ -2711,6 +2773,7 @@ static struct vendor_name usb_vendor[] = { { 0x1bcf, "Sunplus Innovation Technology Inc." }, { 0x1bd0, "Hangzhou Riyue Electronic Co., Ltd." }, { 0x1bd5, "BG Systems, Inc." }, + { 0x1bda, "University Of Southampton" }, { 0x1bde, "P-TWO INDUSTRIES, INC." }, { 0x1bef, "Shenzhen Tongyuan Network-Communication Cables Co., Ltd" }, { 0x1bf0, "RealVision Inc." }, @@ -2719,9 +2782,11 @@ static struct vendor_name usb_vendor[] = { { 0x1bfd, "TouchPack" }, { 0x1c02, "Kreton Corporation" }, { 0x1c04, "QNAP System Inc." }, + { 0x1c05, "Shenxhen Stager Electric" }, { 0x1c0c, "Ionics EMS, Inc." }, { 0x1c0d, "Relm Wireless" }, { 0x1c10, "Lanterra Industrial Co., Ltd." }, + { 0x1c11, "Input Club Inc." }, { 0x1c13, "ALECTRONIC LIMITED" }, { 0x1c1a, "Datel Electronics Ltd." }, { 0x1c1b, "Volkswagen of America, Inc." }, @@ -2731,6 +2796,7 @@ static struct vendor_name usb_vendor[] = { { 0x1c22, "ZHONGSHAN CHIANG YU ELECTRIC CO., LTD." }, { 0x1c26, "Shanghai Haiying Electronics Co., Ltd." }, { 0x1c27, "HuiYang D & S Cable Co., Ltd." }, + { 0x1c28, "PMD Technologies" }, { 0x1c29, "Elster GmbH" }, { 0x1c31, "LS Cable Ltd." }, { 0x1c34, "SpringCard" }, @@ -2739,15 +2805,20 @@ static struct vendor_name usb_vendor[] = { { 0x1c3e, "Wep Peripherals" }, { 0x1c40, "EZPrototypes" }, { 0x1c49, "Cherng Weei Technology Corp." }, + { 0x1c4b, "Geratherm Medical AG" }, { 0x1c4f, "SiGma Micro" }, + { 0x1c57, "Zalman Tech Co., Ltd." }, { 0x1c6b, "Philips & Lite-ON Digital Solutions Corporation" }, { 0x1c6c, "Skydigital Inc." }, + { 0x1c71, "Humanware Inc" }, { 0x1c73, "AMT" }, + { 0x1c75, "Arturia" }, { 0x1c77, "Kaetat Industrial Co., Ltd." }, { 0x1c78, "Datascope Corp." }, { 0x1c79, "Unigen Corporation" }, { 0x1c7a, "LighTuning Technology Inc." }, { 0x1c7b, "LUXSHARE PRECISION INDUSTRY (SHENZHEN) CO., LTD." }, + { 0x1c82, "Atracsys" }, { 0x1c83, "Schomaecker GmbH" }, { 0x1c87, "2N TELEKOMUNIKACE a.s." }, { 0x1c88, "Somagic, Inc." }, @@ -2782,6 +2853,7 @@ static struct vendor_name usb_vendor[] = { { 0x1d09, "TechFaith Wireless Technology Limited" }, { 0x1d0a, "Johnson Controls, Inc. The Automotive Business Unit" }, { 0x1d0b, "HAN HUA CABLE & WIRE TECHNOLOGY (J.X.) CO., LTD." }, + { 0x1d0d, "TDKMedia" }, { 0x1d0f, "Sonix Technology Co., Ltd." }, { 0x1d14, "ALPHA-SAT TECHNOLOGY LIMITED" }, { 0x1d17, "C-Thru Music Ltd." }, @@ -2797,34 +2869,51 @@ static struct vendor_name usb_vendor[] = { { 0x1d5b, "Smartronix, Inc." }, { 0x1d5c, "Fresco Logic" }, { 0x1d6b, "Linux Foundation" }, + { 0x1d88, "Mahr GmbH" }, { 0x1d90, "Citizen" }, { 0x1d9d, "Sigma Sport" }, + { 0x1dd2, "Leo Bodnar Electronics Ltd" }, + { 0x1dd3, "Dajc Inc." }, { 0x1de1, "Actions Microelectronics Co." }, + { 0x1de6, "MICRORISC s.r.o." }, + { 0x1df7, "SDRplay" }, { 0x1e0e, "Qualcomm / Option" }, { 0x1e10, "Point Grey Research, Inc." }, { 0x1e17, "Mirion Technologies Dosimetry Services Division" }, { 0x1e1d, "Kanguru Solutions" }, { 0x1e1f, "INVIA" }, { 0x1e29, "Festo AG & Co. KG" }, + { 0x1e2d, "Gemalto M2M GmbH" }, { 0x1e3d, "Chipsbank Microelectronics Co., Ltd" }, { 0x1e41, "Cleverscope" }, + { 0x1e44, "SHIMANO INC." }, { 0x1e4e, "Cubeternet" }, { 0x1e54, "TypeMatrix" }, { 0x1e68, "TrekStor GmbH & Co. KG" }, { 0x1e71, "NZXT" }, { 0x1e74, "Coby Electronics Corporation" }, + { 0x1e7b, "Zurich Instruments" }, { 0x1e7d, "ROCCAT" }, + { 0x1e8e, "Airbus Defence and Space" }, + { 0x1e91, "Other World Computing" }, { 0x1ea7, "SHARKOON Technologies GmbH" }, + { 0x1eab, "Fujian Newland Computer Co., Ltd" }, + { 0x1eaf, "Leaflabs" }, + { 0x1eb8, "Modacom Co., Ltd." }, { 0x1ebb, "NuCORE Technology, Inc." }, + { 0x1ecb, "AMTelecom" }, + { 0x1ed8, "FENDER MUSICAL INSTRUMENTS CORPORATION" }, { 0x1eda, "AirTies Wireless Networks" }, { 0x1edb, "Blackmagic design" }, { 0x1ee8, "ONDA COMMUNICATION S.p.a." }, { 0x1ef6, "EADS Deutschland GmbH" }, + { 0x1f0c, "CMX Systems" }, { 0x1f28, "Cal-Comp" }, - { 0x1f3a, "Onda (unverified)" }, + { 0x1f3a, "Allwinner Technology" }, { 0x1f44, "The Neat Company" }, { 0x1f48, "H-TRONIC GmbH" }, { 0x1f4d, "G-Tek Electronics Group" }, + { 0x1f52, "Systems & Electronic Development FZCO (SEDCO)" }, { 0x1f6f, "Aliph" }, { 0x1f75, "Innostor Technology Corporation" }, { 0x1f82, "TANDBERG" }, @@ -2832,18 +2921,29 @@ static struct vendor_name usb_vendor[] = { { 0x1f87, "Stantum" }, { 0x1f9b, "Ubiquiti Networks, Inc." }, { 0x1fab, "Samsung Opto-Electroncs Co., Ltd." }, + { 0x1fac, "Franklin Wireless" }, + { 0x1fae, "Lumidigm" }, + { 0x1fb2, "Withings" }, + { 0x1fba, "DERMALOG Identification Systems GmbH" }, { 0x1fbd, "Delphin Technology AG" }, { 0x1fc9, "NXP Semiconductors" }, { 0x1fde, "ILX Lightwave Corporation" }, { 0x1fe7, "Vertex Wireless Co., Ltd." }, { 0x1ff7, "CVT Electronics.Co.,Ltd" }, + { 0x1ffb, "Pololu Corporation" }, { 0x1fff, "Ideofy Inc." }, + { 0x2000, "CMX Systems" }, { 0x2001, "D-Link Corp." }, { 0x2002, "DAP Technologies" }, { 0x2003, "detectomat" }, + { 0x2006, "LenovoMobile" }, + { 0x2009, "iStorage" }, { 0x200c, "Reloop" }, { 0x2013, "PCTV Systems" }, + { 0x2018, "Deutsche Telekom AG" }, { 0x2019, "PLANEX" }, + { 0x201e, "Haier" }, + { 0x203a, "PARALLELS" }, { 0x203d, "Encore Electronics Inc." }, { 0x2040, "Hauppauge" }, { 0x2047, "Texas Instruments" }, @@ -2856,100 +2956,376 @@ static struct vendor_name usb_vendor[] = { { 0x20b1, "XMOS Ltd" }, { 0x20b3, "Hanvon" }, { 0x20b7, "Qi Hardware" }, + { 0x20bc, "ShenZhen ShanWan Technology Co., Ltd." }, { 0x20ce, "Minicircuits" }, { 0x20df, "Simtec Electronics" }, + { 0x20f0, "L3Harris Technologies" }, { 0x20f1, "NET New Electronic Technology GmbH" }, { 0x20f4, "TRENDnet" }, { 0x20f7, "XIMEA" }, { 0x2100, "RT Systems" }, { 0x2101, "ActionStar" }, + { 0x2104, "Tobii Technology AB" }, + { 0x2107, "RDING TECH CO.,LTD" }, { 0x2109, "VIA Labs, Inc." }, { 0x2113, "Softkinetic" }, + { 0x2116, "KT Tech" }, + { 0x211f, "CELOT Corporation" }, + { 0x2123, "Cheeky Dream" }, + { 0x2125, "Fiberpro Inc." }, + { 0x2133, "signotec GmbH" }, { 0x2149, "Advanced Silicon S.A." }, - { 0x2162, "Creative (?)" }, + { 0x214b, "Huasheng Electronics" }, + { 0x214e, "Swiftpoint" }, + { 0x2162, "Broadxent (Creative Labs)" }, + { 0x2166, "JVC Kenwood" }, { 0x2184, "GW Instek" }, + { 0x2188, "No brand" }, + { 0x219c, "Seal One AG" }, { 0x21a1, "Emotiv Systems Pty. Ltd." }, + { 0x21a4, "Electronic Arts Inc." }, + { 0x21a9, "Saleae, Inc." }, + { 0x21ab, "Planeta Informatica" }, + { 0x21b4, "AudioQuest" }, { 0x21d6, "Agecodagis SARL" }, { 0x2207, "Fuzhou Rockchip Electronics Company" }, + { 0x221a, "ZTEX GmbH" }, { 0x2222, "MacAlly" }, + { 0x2226, "Copper Mountain technologies" }, { 0x2227, "SAMWOO Enterprise" }, + { 0x222a, "ILI Technology Corp." }, + { 0x2230, "Plugable" }, { 0x2232, "Silicon Motion" }, { 0x2233, "RadioShack Corporation" }, { 0x2237, "Kobo Inc." }, + { 0x2245, "Aspeed Technology, Inc." }, { 0x224f, "APDM" }, + { 0x2256, "Faderfox" }, { 0x225d, "Morpho" }, + { 0x226e, "DISPLAX" }, { 0x228d, "8D Technologies inc." }, + { 0x22a4, "VERZO Technology" }, { 0x22a6, "Pie Digital, Inc." }, + { 0x22a7, "Fortinet Technologies" }, + { 0x22b1, "Secret Labs LLC" }, { 0x22b8, "Motorola PCS" }, { 0x22b9, "eTurboTouch Technology, Inc." }, { 0x22ba, "Technology Innovation Holdings, Ltd" }, { 0x22c9, "StepOver GmbH" }, { 0x22cd, "Kinova Robotics Inc." }, + { 0x22d4, "Laview Technology" }, + { 0x22d9, "OPPO Electronics Corp." }, + { 0x22db, "Phase One" }, + { 0x22dc, "Mellanox Technologies" }, + { 0x22de, "WeTelecom Incorporated" }, + { 0x22df, "Medicom MTD, Ltd" }, { 0x22e0, "secunet Security Networks AG" }, + { 0x22e8, "Cambridge Audio" }, { 0x2304, "Pinnacle Systems, Inc." }, + { 0x2309, "TimeLink Technology Co., Ltd" }, + { 0x230d, "Teracom" }, + { 0x2314, "INQ Mobile" }, { 0x2318, "Shining Technologies, Inc. [hex]" }, + { 0x2319, "Tronsmart" }, + { 0x232b, "Pantum Ltd." }, + { 0x232e, "EA Elektro-Automatik GmbH & Co. KG" }, + { 0x2340, "Teleepoch" }, { 0x2341, "Arduino SA" }, + { 0x2349, "P2 Engineering Group, LLC" }, + { 0x234b, "Free Software Initiative of Japan" }, { 0x2357, "TP-Link" }, + { 0x2366, "Bitmanufaktur GmbH" }, + { 0x2367, "Teenage Engineering" }, + { 0x2368, "Peterson Electro-Musical Products Inc." }, + { 0x236a, "SiBEAM" }, { 0x2373, "Pumatronix Ltda" }, { 0x2375, "Digit@lway, Inc." }, + { 0x2378, "OnLive" }, + { 0x237d, "Cradlepoint" }, + { 0x2386, "Raydium Corporation" }, + { 0x238b, "Hytera Communications" }, + { 0x239a, "Adafruit" }, + { 0x23a0, "BIFIT" }, + { 0x23a6, "Tronical Components GmbH" }, + { 0x23b4, "Dental Wings Inc." }, + { 0x23c7, "Gemini" }, + { 0x23fc, "SesKion GmbH" }, + { 0x2405, "Custom Computer Services, Inc" }, { 0x2406, "SANHO Digital Electronics Co., Ltd." }, + { 0x2420, "IRiver" }, + { 0x242e, "Vossloh-Schwabe Deutschland GmbH" }, + { 0x2433, "ASETEK" }, { 0x2443, "Aessent Technology Ltd" }, + { 0x2457, "Ocean Optics Inc." }, + { 0x2458, "Bluegiga Technologies" }, + { 0x245f, "Chord Electronics Limited" }, + { 0x2464, "Nest" }, + { 0x2466, "Fractal Audio Systems" }, + { 0x2476, "YEI Technology" }, { 0x2478, "Tripp-Lite" }, { 0x248a, "Maxxter" }, { 0x249c, "M2Tech s.r.l." }, + { 0x24a4, "Primare AB" }, + { 0x24ae, "Shenzhen Rapoo Technology Co., Ltd." }, + { 0x24c0, "Chaney Instrument" }, + { 0x24c6, "ThrustMaster, Inc." }, + { 0x24cf, "Lytro, Inc." }, + { 0x24dc, "Aladdin R.D." }, + { 0x24e0, "Yoctopuce Sarl" }, { 0x24e1, "Paratronic" }, + { 0x24e3, "K-Touch" }, + { 0x24ea, "Meva" }, + { 0x24ed, "Zen Group" }, + { 0x24f0, "Metadot" }, + { 0x24ff, "Acroname Inc." }, + { 0x2500, "Ettus Research LLC" }, { 0x2516, "Cooler Master Co., Ltd." }, + { 0x2520, "ANA-U GmbH" }, + { 0x2527, "Software Bisque" }, + { 0x2537, "Norelsys" }, + { 0x2544, "Energy Micro AS" }, + { 0x2546, "Ravensburger" }, { 0x2548, "Pulse-Eight" }, + { 0x254e, "SHF Communication Technologies AG" }, + { 0x2554, "ASSA ABLOY AB" }, + { 0x2555, "Basis Science Inc." }, + { 0x255e, "Beijing Bonxeon Technology Co., Ltd." }, + { 0x2560, "e-con Systems" }, + { 0x2563, "ShenZhen ShanWan Technology Co., Ltd." }, + { 0x256b, "Perreaux Industries Ltd" }, + { 0x256f, "3Dconnexion" }, + { 0x2573, "ESI Audiotechnik GmbH" }, + { 0x2574, "AVer Information, Inc." }, + { 0x2575, "Weida Hi-Tech Co., Ltd." }, + { 0x2576, "AFO Co., Ltd." }, + { 0x2578, "Pluscom" }, + { 0x2581, "Plug-up" }, + { 0x258d, "Sequans Communications" }, + { 0x259a, "TriQuint Semiconductor" }, + { 0x25a7, "Areson Technology Corp" }, { 0x25b5, "FlatFrog" }, + { 0x25bb, "Brunner Elektronik AG" }, + { 0x25bf, "Elegant Invention" }, + { 0x25c4, "ARCAM" }, + { 0x25c6, "Vitus Audio (AVA Group A/S)" }, + { 0x25c8, "Visual Planet Ltd" }, + { 0x25da, "Netatmo" }, + { 0x25dd, "Bit4id Srl" }, + { 0x25e3, "Lumigon" }, + { 0x25f0, "ShanWan" }, + { 0x25fb, "Pentax Ricoh Imaging Co., Ltd" }, + { 0x2604, "Tenda" }, + { 0x2625, "MilDef AB" }, + { 0x2626, "Aruba Networks" }, + { 0x262a, "SAVITECH Corp." }, { 0x2632, "TwinMOS" }, { 0x2639, "Xsens" }, + { 0x264a, "Thermaltake" }, { 0x2650, "Electronics For Imaging, Inc. [hex]" }, { 0x2659, "Sundtek" }, + { 0x2662, "Moog Music Inc." }, + { 0x266e, "Silicon Integrated Systems" }, + { 0x2672, "GoPro" }, { 0x2676, "Basler AG" }, + { 0x2685, "Cardo Peripheral Systems LTD" }, + { 0x2687, "Fitbit Inc." }, + { 0x2689, "StepOver International GmbH" }, + { 0x268b, "Dimension Engineering" }, + { 0x26a9, "Research Industrial Systems Engineering" }, + { 0x26aa, "Yaesu Musen" }, + { 0x26b5, "Electrocompaniet" }, + { 0x26bd, "Integral Memory" }, + { 0x26e2, "Ingenieurbuero Dietzsch und Thiele, PartG" }, + { 0x26f2, "Micromega" }, + { 0x2707, "Bardac Corporation" }, + { 0x270d, "Rosand Technologies" }, { 0x2717, "Xiaomi Inc." }, + { 0x272a, "StarLeaf Ltd." }, + { 0x272c, "Signum Systems" }, { 0x2730, "Citizen" }, { 0x2735, "DigitalWay" }, { 0x273f, "Hughski Limited" }, + { 0x2756, "Victor Hasselblad AB" }, + { 0x2759, "Philip Morris Products S.A." }, + { 0x2765, "Firstbeat Technologies, Ltd." }, + { 0x2766, "LifeScan" }, { 0x2770, "NHJ, Ltd" }, + { 0x27a8, "Square, Inc." }, { 0x27b8, "ThingM" }, + { 0x27bd, "Codethink Ltd." }, + { 0x27c0, "Cadwell Laboratories, Inc." }, { 0x27c6, "Shenzhen Goodix Technology Co.,Ltd." }, + { 0x27d4, "Blackstar Amplification Limited" }, + { 0x27dd, "Mindeo" }, + { 0x27f2, "Softnautics LLP" }, + { 0x2803, "StarLine LLC." }, + { 0x2806, "SIMPASS" }, + { 0x2817, "Signal Hound, Inc." }, + { 0x2818, "Codex Digital Limited" }, { 0x2821, "ASUSTek Computer Inc." }, + { 0x2822, "REFLEXdigital" }, + { 0x2833, "Oculus VR, Inc." }, + { 0x2836, "OUYA" }, + { 0x286b, "STANEO SAS" }, + { 0x2886, "Seeed Technology Co., Ltd." }, + { 0x2890, "Teknic, Inc" }, { 0x2899, "Toptronic Industrial Co., Ltd" }, { 0x289b, "Dracal/Raphnet technologies" }, + { 0x289d, "Seek Thermal, Inc." }, + { 0x28bd, "XP-Pen" }, + { 0x28c7, "Ultimaker B.V." }, + { 0x28d4, "Devialet" }, { 0x28de, "Valve Software" }, + { 0x28e0, "PT. Prasimax Inovasi Teknologi" }, + { 0x28e9, "GDMicroelectronics" }, + { 0x28f3, "Clover Network, Inc." }, + { 0x28f9, "Profitap HQ BV" }, + { 0x290c, "R. Hamilton & Co. Ltd." }, + { 0x2912, "Audioengine" }, + { 0x2916, "Yota Devices" }, { 0x2931, "Jolla Oy" }, { 0x2939, "Zaber Technologies Inc." }, + { 0x2957, "Obsidian Research Corporation" }, + { 0x2961, "Miselu" }, + { 0x296b, "Xacti Corporation" }, + { 0x2972, "FiiO Electronics Technology" }, + { 0x298d, "Next Biometrics" }, + { 0x29bd, "Silicon Works" }, + { 0x29c1, "Taztag" }, + { 0x29c2, "Lewitt GmbH" }, + { 0x29c3, "Noviga" }, + { 0x29e2, "Huatune Technology (Shanghai) Co., Ltd." }, + { 0x29e7, "Brunel University" }, + { 0x29e8, "4Links Limited" }, + { 0x29ea, "Kinesis Corporation" }, + { 0x29f1, "Canaan Creative Co., Ltd" }, { 0x2a03, "dog hunter AG" }, + { 0x2a0e, "Shenzhen DreamSource Technology Co., Ltd." }, + { 0x2a13, "Grabba International" }, + { 0x2a19, "Numato Systems Pvt. Ltd" }, + { 0x2a1d, "Oxford Nanopore Technologies plc" }, { 0x2a37, "RTD Embedded Technologies, Inc." }, + { 0x2a39, "RME" }, + { 0x2a3c, "Trinamic Motion Control GmbH & Co KG" }, { 0x2a45, "Meizu Corp." }, + { 0x2a47, "Mundo Reader, S.L." }, + { 0x2a4b, "EMULEX Corporation" }, + { 0x2a62, "Flymaster Avionics" }, + { 0x2a6e, "Bare Conductive" }, + { 0x2a70, "OnePlus Technology (Shenzhen) Co., Ltd." }, + { 0x2a88, "DFU Technology Ltd" }, + { 0x2a8d, "Keysight Technologies, Inc." }, + { 0x2ab6, "T+A elektroakustik GmbH & Co KG, Germany" }, { 0x2ac7, "Ultrahaptics Ltd." }, + { 0x2ad1, "Picotronic GmbH" }, + { 0x2ae5, "Fairphone B.V." }, + { 0x2aec, "Ambiq Micro, Inc." }, + { 0x2af4, "ROLI Ltd." }, + { 0x2b03, "STEREOLABS" }, + { 0x2b0e, "LeEco" }, + { 0x2b23, "Red Hat, Inc." }, { 0x2b24, "KeepKey LLC" }, + { 0x2b3e, "NewAE Technology Inc." }, + { 0x2b4c, "ZUK" }, + { 0x2bc5, "Orbbec 3D Technology International, Inc" }, + { 0x2bcc, "InoTec GmbH Organisationssysteme" }, + { 0x2bd6, "Coroware, Inc." }, + { 0x2bd8, "ROPEX Industrie-Elektronik GmbH" }, { 0x2c02, "Planex Communications" }, { 0x2c1a, "Dolphin Peripherals" }, { 0x2c23, "Supermicro Computer Incorporated" }, + { 0x2c4e, "Mercucys INC" }, + { 0x2c4f, "Canon Electronic Business Machines Co., Ltd." }, + { 0x2c55, "Magic Leap, Inc." }, { 0x2c7c, "Quectel Wireless Solutions Co., Ltd." }, + { 0x2c97, "Ledger" }, + { 0x2c99, "Prusa" }, + { 0x2c9c, "Vayyar Imaging Ltd." }, + { 0x2c9d, "Nod Inc" }, + { 0x2ca3, "DJI Technology Co., Ltd." }, + { 0x2cb7, "Fibocom" }, + { 0x2cc0, "Hangzhou Zero Zero Infinity Technology Co., Ltd." }, + { 0x2cc2, "Lautsprecher Teufel GmbH" }, + { 0x2ccf, "Hypersecu" }, + { 0x2cd9, "Cambrionix Ltd" }, { 0x2cdc, "Sea & Sun Technology GmbH" }, + { 0x2ce5, "InX8 Inc [AKiTiO]" }, + { 0x2cf0, "Nuand LLC" }, + { 0x2d1f, "Wacom Taiwan Information Co. Ltd." }, + { 0x2d25, "Kronegger GmbH." }, + { 0x2d2d, "proxmark.org" }, + { 0x2d37, "Zhuhai Poskey Technology Co.,Ltd" }, + { 0x2d6b, "NetUP Inc." }, + { 0x2d81, "Evollve Inc." }, + { 0x2d84, "Zhuhai Poskey Technology Co.,Ltd" }, + { 0x2dc8, "8BitDo" }, { 0x2dcf, "Dialog Semiconductor" }, + { 0x2def, "Kirale Technologies" }, + { 0x2df2, "LIPS Corporation" }, + { 0x2e04, "HMD Global" }, + { 0x2e0e, "Hatteland Display AS" }, + { 0x2e24, "Hyperkin" }, + { 0x2e3b, "uSens Inc." }, + { 0x2e57, "MEGWARE Computer Vertrieb und Service GmbH" }, + { 0x2e69, "Swift Navigation" }, + { 0x2e95, "SCUF Gaming" }, + { 0x2ecc, "ASR Microelectronics" }, + { 0x2f76, "KeyXentic Inc." }, + { 0x2fad, "Definium Technologies" }, + { 0x2fb0, "Infocrypt" }, { 0x2fb2, "Fujitsu, Ltd" }, + { 0x2fc0, "Sensidyne, LP" }, + { 0x2fc6, "Comtrue Inc." }, + { 0x2fe0, "Xaptum, Inc." }, + { 0x2fe3, "NordicSemiconductor" }, + { 0x2fe7, "ELGIN S.A." }, + { 0x2feb, "Beijing Veikk E-Commerce Co., Ltd." }, + { 0x2ff4, "Quixant Plc" }, { 0x3016, "Boundary Devices, LLC" }, + { 0x3036, "Control iD" }, + { 0x3037, "Beijing Chushifengmang Technology Development Co.,Ltd." }, + { 0x3057, "Kingsis Corporation" }, + { 0x308f, "Input Club" }, { 0x30a4, "Blues Wireless" }, { 0x30c2, "UNPARALLEL Innovation, Lda" }, { 0x30c9, "Luxvisions Innotech Limited" }, { 0x30ee, "Fujitsu Connected Technologies Limited" }, + { 0x30f2, "Varex Imaging" }, + { 0x3111, "Hiperscan GmbH" }, + { 0x3112, "Meteca SA" }, { 0x3125, "Eagletron" }, { 0x3136, "Navini Networks" }, + { 0x3145, "SafeLogic Inc." }, + { 0x3147, "Tanvas, Inc." }, + { 0x316c, "SigmaSense, LLC" }, + { 0x316d, "Purism, SPC" }, + { 0x316e, "SPECINFOSYSTEMS" }, + { 0x3171, "8086 Consultancy" }, { 0x3176, "Whanam Electronics Co., Ltd" }, { 0x3195, "Link Instruments" }, + { 0x3197, "Katusha" }, + { 0x31c9, "BeiJing LanXum Computer Technology Co., Ltd." }, + { 0x3200, "Alcatel-Lucent Enterprise" }, + { 0x3219, "Smak Tecnologia e Automacao LTDA" }, + { 0x321c, "Premio, Inc." }, + { 0x324c, "CUPRIS Ltd." }, + { 0x326d, "Agile Display Solutions Co., Ltd" }, { 0x3275, "VidzMedia Pte Ltd" }, + { 0x3293, "Unhuman Inc." }, + { 0x32b3, "TEXA" }, + { 0x3310, "MUDITA Sp. z o.o." }, { 0x3333, "InLine" }, { 0x3334, "AEI" }, { 0x3340, "Yakumo" }, { 0x3344, "Leaguer Microelectronics (LME)" }, + { 0x3384, "System76" }, + { 0x348f, "ISY" }, { 0x3504, "Micro Star" }, { 0x3538, "Power Quotient International Co., Ltd" }, { 0x3579, "DIVA" }, { 0x357d, "Sharkoon" }, { 0x3636, "InVibro" }, + { 0x3767, "Fanatec" }, { 0x3838, "WEM" }, { 0x3923, "National Instruments Corp." }, { 0x40bb, "I-O Data" }, @@ -2965,6 +3341,7 @@ static struct vendor_name usb_vendor[] = { { 0x4572, "Shuttle, Inc." }, { 0x4586, "Panram" }, { 0x4670, "EMS Production" }, + { 0x46f4, "QEMU" }, { 0x4752, "Miditech" }, { 0x4757, "GW Instek" }, { 0x4766, "Aceeca" }, @@ -2972,12 +3349,14 @@ static struct vendor_name usb_vendor[] = { { 0x4971, "SimpleTech" }, { 0x4d46, "Musical Fidelity" }, { 0x5032, "Grandtec" }, - { 0x5041, "Linksys (?)" }, { 0x50c2, "Averatec (?)" }, + { 0x5131, "MSR" }, { 0x5173, "Sweex" }, { 0x5219, "I-Tetra" }, + { 0x5332, "Clearly Superior Technologies, Inc." }, { 0x5345, "Owon" }, { 0x534c, "SatoshiLabs" }, + { 0x534d, "MacroSilicon" }, { 0x5354, "Meyer Instruments (MIS)" }, { 0x544d, "Transmeta Corp." }, { 0x5543, "UC-Logic Technology Corp." }, @@ -2986,71 +3365,95 @@ static struct vendor_name usb_vendor[] = { { 0x5654, "Gotview" }, { 0x5656, "Uni-Trend Group Limited" }, { 0x595a, "IRTOUCHSYSTEMS Co. Ltd." }, - { 0x5986, "Acer, Inc" }, + { 0x5986, "Bison Electronics Inc." }, { 0x59e3, "Nonolith Labs" }, { 0x5a57, "Zinwell" }, { 0x6000, "Beholder International Ltd." }, { 0x601a, "Ingenic Semiconductor Ltd." }, + { 0x6022, "Xektek" }, { 0x6189, "Sitecom" }, { 0x6244, "LightingSoft AG" }, { 0x6253, "TwinHan Technology Co., Ltd" }, { 0x636c, "CoreLogic, Inc." }, - { 0x6472, "Unknown (Sony?)" }, + { 0x6472, "Sony Corp." }, { 0x6547, "Arkmicro Technologies Inc." }, + { 0x6557, "Emtec" }, { 0x6615, "IRTOUCHSYSTEMS Co. Ltd." }, { 0x6666, "Prototype product Vendor ID" }, { 0x6677, "WiseGroup, Ltd." }, + { 0x675d, "Humanscale" }, { 0x6891, "3Com" }, { 0x695c, "Opera1" }, { 0x6993, "Yealink Network Technology Co., Ltd." }, { 0x6a75, "Shanghai Jujo Electronics Co., Ltd" }, { 0x7104, "CME (Central Music Co.)" }, { 0x726c, "StackFoundry LLC" }, + { 0x7302, "Solinftec" }, { 0x734c, "TBS Technologies China" }, { 0x7373, "Beijing STONE Technology Co. Ltd." }, { 0x7392, "Edimax Technology Co., Ltd" }, + { 0x73d8, "Progeny Dental Equipment Specialists" }, + { 0x7669, "Venable Instruments" }, + { 0x7825, "Other World Computing" }, + { 0x8070, "ACCES I/O Products, Inc." }, { 0x8086, "Intel Corp." }, { 0x8087, "Intel Corp." }, { 0x80ee, "VirtualBox" }, { 0x8282, "Keio" }, + { 0x8301, "Hapurs" }, { 0x8341, "EGO Systems, Inc." }, { 0x8564, "Transcend Information, Inc." }, { 0x8644, "Intenso GmbG" }, { 0x8e06, "CH Products, Inc." }, + { 0x8ea3, "Doosl" }, { 0x9016, "Sitecom" }, { 0x9022, "TeVii Technology Ltd." }, { 0x9148, "GeoLab, Ltd" }, + { 0x9516, "Studiologic" }, { 0x9710, "MosChip Semiconductor" }, { 0x9849, "Bestmedia CD Recordable GmbH & Co. KG" }, + { 0x9886, "Astro Gaming" }, { 0x9999, "Odeon" }, { 0x99fa, "Grandtec" }, { 0x9ac4, "J. Westhues" }, { 0x9e88, "Marvell Semiconductor, Inc." }, + { 0xa014, "Insignia (Best Buy)" }, + { 0xa108, "Ingenic Semiconductor Co.,Ltd" }, { 0xa128, "AnMo Electronics Corp. / Dino-Lite (?)" }, { 0xa168, "AnMo Electronics Corporation" }, - { 0xa600, "Asix" }, + { 0xa466, "Haikou Xingong Electronics Co.,Ltd" }, + { 0xa600, "ASIX s.r.o." }, { 0xa727, "3Com" }, + { 0xa88a, "Clas Ohlsson" }, { 0xaaaa, "MXT" }, - { 0xabcd, "Unknown" }, + { 0xab12, "aplic" }, + { 0xabcd, "LogiLink" }, { 0xb58e, "Blue Microphones" }, + { 0xba77, "Clockmaker" }, { 0xc216, "Card Device Expert Co., LTD" }, { 0xc251, "Keil Software, Inc." }, + { 0xc502, "AGPTek" }, { 0xcace, "CACE Technologies Inc." }, { 0xcd12, "SMART TECHNOLOGY INDUSTRIAL LTD." }, { 0xd208, "Ultimarc" }, { 0xd209, "Ultimarc" }, { 0xd904, "LogiLink" }, + { 0xe2b7, "Jie Li" }, { 0xe4e4, "Xorcom Ltd." }, { 0xeb03, "MakingThings" }, { 0xeb1a, "eMPIA Technology, Inc." }, { 0xeb2a, "KWorld" }, { 0xef18, "SMART TECHNOLOGY INDUSTRIAL LTD." }, { 0xf003, "Hewlett Packard" }, + { 0xf007, "Teslong" }, { 0xf182, "Leap Motion" }, + { 0xf3f0, "CCT, Inc" }, { 0xf4ec, "Atten Electronics / Siglent Technologies" }, { 0xf4ed, "Shenzhen Siglent Co., Ltd." }, { 0xf766, "Hama" }, + { 0xfa11, "DyingLight" }, { 0xfc08, "Conrad Electronic SE" }, + { 0xff00, "Power Delivery" }, { 0xffee, "FNK Tech" }, }; diff --git a/libwdi/winusb.inf.in b/libwdi/winusb.inf.in index 662abb33..0c0774eb 100644 --- a/libwdi/winusb.inf.in +++ b/libwdi/winusb.inf.in @@ -1,5 +1,5 @@ ; #INF_FILENAME# -; Copyright (c) 2010-2016 Pete Batard (GNU LGPL) +; Copyright (c) 2010-2023 Pete Batard (GNU LGPL) [Strings] DeviceName = "#DEVICE_DESCRIPTION#" VendorName = "#DEVICE_MANUFACTURER#" @@ -23,7 +23,7 @@ HKR,,,0,"Universal Serial Bus devices" HKR,,Icon,,-20 [Manufacturer] -%VendorName% = libusbDevice_WinUSB,NTx86,NTamd64,NTarm +%VendorName% = libusbDevice_WinUSB,NTx86,NTamd64,NTarm64 [libusbDevice_WinUSB.NTx86] %DeviceName% = USB_Install, USB\%DeviceID% @@ -31,7 +31,7 @@ HKR,,Icon,,-20 [libusbDevice_WinUSB.NTamd64] %DeviceName% = USB_Install, USB\%DeviceID% -[libusbDevice_WinUSB.NTarm] +[libusbDevice_WinUSB.NTarm64] %DeviceName% = USB_Install, USB\%DeviceID% [USB_Install] @@ -64,10 +64,17 @@ AddReg = #USE_DEVICE_INTERFACE_GUID# [AddDeviceInterfaceGUID] HKR,,DeviceInterfaceGUIDs,0x10000,%DeviceGUID% -[USB_Install.CoInstallers] +[USB_Install.NTx86.CoInstallers] AddReg = CoInstallers_AddReg CopyFiles = CoInstallers_CopyFiles +[USB_Install.NTamd64.CoInstallers] +AddReg = CoInstallers_AddReg +CopyFiles = CoInstallers_CopyFiles + +[USB_Install.NTarm64.CoInstallers] +; + [CoInstallers_AddReg] HKR,,CoInstallers32,0x00010000,"WdfCoInstaller#WDF_VERSION#.dll,WdfCoInstaller","WinUSBCoInstaller2.dll" @@ -89,6 +96,5 @@ WdfCoInstaller#WDF_VERSION#.dll = 1,x86 WinUSBCoInstaller2.dll = 1,amd64 WdfCoInstaller#WDF_VERSION#.dll = 1,amd64 -[SourceDisksFiles.arm] -WinUSBCoInstaller2.dll = 1,arm -WdfCoInstaller#WDF_VERSION#.dll = 1,arm +[SourceDisksFiles.arm64] +; \ No newline at end of file diff --git a/msvc/config.h b/msvc/config.h index c97d4995..c44d3779 100644 --- a/msvc/config.h +++ b/msvc/config.h @@ -16,12 +16,14 @@ #endif /* - * Embed WinUSB driver files from the following WDK location + * Embed WinUSB driver files from the following WDK location. + * If needed, you can obtain the WDK redistributable components from: + * https://go.microsoft.com/fwlink/p/?LinkID=253170 * NB: You must also make sure the WDF_VER, COINSTALLER_DIR and X64_DIR - * match your WinUSB redist directrories + * match your WinUSB redist directories. */ #ifndef WDK_DIR -#define WDK_DIR "C:/Program Files (x86)/Windows Kits/10" +#define WDK_DIR "C:/Program Files (x86)/Windows Kits/8.0" #endif /* WDK WDF coinstaller version */ @@ -54,6 +56,9 @@ /* 64 bit support */ #define OPT_M64 +/* ARM64 support */ +#define OPT_ARM + /* Debug message logging */ //#define ENABLE_DEBUG_LOGGING diff --git a/msvc/stdint.h b/msvc/stdint.h index 5d5329a9..e0c8b0c7 100644 --- a/msvc/stdint.h +++ b/msvc/stdint.h @@ -239,7 +239,7 @@ typedef unsigned long long uintmax_t; /* 7.18.4.1 Macros for minimum-width integer constants - Accoding to Douglas Gwyn : + According to Douglas Gwyn : "This spec was changed in ISO/IEC 9899:1999 TC1; in ISO/IEC 9899:1999 as initially published, the expansion was required to be an integer constant of precisely matching type, which diff --git a/wdk_build.cmd b/wdk_build.cmd deleted file mode 100644 index 33ea4d8c..00000000 --- a/wdk_build.cmd +++ /dev/null @@ -1,185 +0,0 @@ -@echo off -rem default builds static library. -rem you can pass the following arguments (case insensitive): -rem - "DLL" to build a DLL instead of a static library -rem - "no_samples" to build the library only - -if not Test%DDK_TARGET_OS%==TestWin7 goto unsupported - -if Test%BUILD_ALT_DIR%==Test goto usage -rem /M 2 for multiple cores -set BUILD_CMD=build -bcwgZ -M2 -set PWD=%~dp0 - -rem process commandline parameters -set TARGET=LIBRARY -set BUILD_SAMPLES=YES - -:more_args -if "%1" == "" goto no_more_args -rem /I for case insensitive -if /I Test%1==TestDLL set TARGET=DYNLINK -if /I Test%1==Testno_samples set BUILD_SAMPLES=NO -rem - shift the arguments and examine %1 again -shift -goto more_args -:no_more_args - -rem Set DDK_DIR (=BASEDIR with escaped backslashes) -set DDK_DIR=%BASEDIR:\=\\% -rem Set target platform type -set ORG_BUILD_ALT_DIR=%BUILD_ALT_DIR% -set ORG_BUILDARCH=%_BUILDARCH% -set ORG_PATH=%PATH% -set ORG_BUILD_DEFAULT_TARGETS=%BUILD_DEFAULT_TARGETS% - -set ARCH_DIR=%_BUILDARCH% -if /I Test%_BUILDARCH%==Testx86 set ARCH_DIR=i386 - -if /I Test%_BUILDARCH%==Testamd64 goto x86_64 -echo #define NO_BUILD64> libwdi\build64.h -goto main_start -:x86_64 -echo #define BUILD64> libwdi\build64.h - -:main_start -cd libwdi -set srcPath=obj%BUILD_ALT_DIR%\%cpudir% - -del Makefile.hide >NUL 2>&1 -if EXIST Makefile ren Makefile Makefile.hide - -set 386=1 -set AMD64= -set BUILD_DEFAULT_TARGETS=-386 -set _AMD64bit= -set _BUILDARCH=x86 -set PATH=%BASEDIR%\bin\x86;%BASEDIR%\bin\x86\x86 - -copy .msvc\embedder_sources sources >NUL 2>&1 -@echo on -%BUILD_CMD% -@echo off -if errorlevel 1 goto builderror -copy obj%BUILD_ALT_DIR%\i386\embedder.exe . >NUL 2>&1 - -copy .msvc\installer_x86_sources sources >NUL 2>&1 -@echo on -%BUILD_CMD% -@echo off -if errorlevel 1 goto builderror -copy obj%BUILD_ALT_DIR%\i386\installer_x86.exe . >NUL 2>&1 - -set 386= -set AMD64=1 -set BUILD_DEFAULT_TARGETS=-amd64 -set _AMD64bit=true -set _BUILDARCH=AMD64 -set PATH=%BASEDIR%\bin\x86\amd64;%BASEDIR%\bin\x86 - -copy .msvc\installer_x64_sources sources >NUL 2>&1 -@echo on -%BUILD_CMD% -@echo off -if errorlevel 1 goto builderror -copy obj%BUILD_ALT_DIR%\amd64\installer_x64.exe . >NUL 2>&1 - -if /I Test%ORG_BUILDARCH%==TestAMD64 goto restorePath -set 386=1 -set AMD64= -set BUILD_DEFAULT_TARGETS=-386 -set _AMD64bit= -set _BUILDARCH=x86 - -:restorePath -set PATH=%ORG_PATH% - -echo. -echo Embedding binary resources -embedder.exe embedded.h - -rem DLL or static lib selection (must use concatenation) -echo TARGETTYPE=%TARGET% > target -copy target+.msvc\libwdi_sources sources >NUL 2>&1 -del target -@echo on -%BUILD_CMD% -@echo off -if errorlevel 1 goto builderror -copy obj%BUILD_ALT_DIR%\%ARCH_DIR%\libwdi.lib . >NUL 2>&1 -copy obj%BUILD_ALT_DIR%\%ARCH_DIR%\libwdi.dll . >NUL 2>&1 - -if EXIST Makefile.hide ren Makefile.hide Makefile -cd .. -if Test%BUILD_SAMPLES%==TestNO goto done -cd examples\getopt - -del Makefile.hide >NUL 2>&1 -if EXIST Makefile ren Makefile Makefile.hide -copy .msvc\getopt_sources sources >NUL 2>&1 -@echo on -%BUILD_CMD% -@echo off -if errorlevel 1 goto builderror -copy obj%BUILD_ALT_DIR%\%ARCH_DIR%\getopt.lib . >NUL 2>&1 - -if EXIST Makefile.hide ren Makefile.hide Makefile -cd .. - -del Makefile.hide >NUL 2>&1 -if EXIST Makefile ren Makefile Makefile.hide -rem Work around MS's VC++ and WDK weird icompatibilities with regards to rc files -echo #include ^ > afxres.h -echo #ifndef IDC_STATIC >> afxres.h -echo #define IDC_STATIC -1 >> afxres.h -echo #endif >> afxres.h -copy .msvc\zadic_sources sources >NUL 2>&1 -@echo on -%BUILD_CMD% -@echo off -if errorlevel 1 goto builderror -copy obj%BUILD_ALT_DIR%\%ARCH_DIR%\zadic.exe . >NUL 2>&1 - -copy .msvc\zadig_sources sources >NUL 2>&1 -@echo on -%BUILD_CMD% -@echo off -if errorlevel 1 goto builderror -del afxres.h -copy obj%BUILD_ALT_DIR%\%ARCH_DIR%\zadig.exe . >NUL 2>&1 - -copy .msvc\wdi-simple_sources sources >NUL 2>&1 -@echo on -%BUILD_CMD% -@echo off -if errorlevel 1 goto builderror -copy obj%BUILD_ALT_DIR%\%ARCH_DIR%\wdi-simple.exe . >NUL 2>&1 - -if EXIST Makefile.hide ren Makefile.hide Makefile -cd .. - -goto done - -:builderror -if EXIST Makefile.hide ren Makefile.hide Makefile -if EXIST afxres.h del afxres.h -echo Build failed -goto done - -:usage -echo wdk_build must be run in a Windows Driver Kit build environment -pause -goto done - -:done -set BUILD_ALT_DIR=%ORG_BUILD_ALT_DIR% -set _BUILDARCH=%ORG_BUILDARCH% -set PATH=%ORG_PATH% -set BUILD_DEFAULT_TARGETS=%ORG_BUILD_DEFAULT_TARGETS% -cd %PWD% -goto out - -:unsupported -echo Only Windows 7 or later is supported - -:out