diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000..6ff6995 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,418 @@ +name: CI/CD + +on: + push: + pull_request: + workflow_dispatch: + release: + types: [published] + +jobs: +# Release builds + build_release_macos: + name: Release build (macOS universal, static Qt 6.5.0) + runs-on: macos-latest + steps: + - uses: actions/checkout@v3 + - name: Get Qt + uses: actions/checkout@v3 + with: + repository: LongSoft/qt-6-static-universal-macos + path: qt + lfs: true + - name: Unpack Qt + shell: bash + working-directory: qt + run: sudo 7z x qt-6.5.0-static-universal-macos.7z -o/opt + - name: Create build directory + run: cmake -E make_directory ${{runner.workspace}}/build + - name: Configure everything + working-directory: ${{runner.workspace}}/build + run: cmake -DCMAKE_PREFIX_PATH="/opt/qt-6.5.0-static-universal-macos" -DCMAKE_OSX_ARCHITECTURES="x86_64;arm64" -DCMAKE_OSX_DEPLOYMENT_TARGET="11.0" ../UEFITool + - name: Build everything + working-directory: ${{runner.workspace}}/build + shell: bash + run: cmake --build . --config Release + - name: Create dist directory + run: cmake -E make_directory ${{runner.workspace}}/UEFITool/dist + - name: Signed archive everything + if: github.repository_owner == 'LongSoft' + working-directory: ${{runner.workspace}}/build + env: + MAC_CERTIFICATE_PASSWORD: ${{ secrets.MAC_CERTIFICATE_PASSWORD }} + MAC_ACCOUNT_NAME: ${{ secrets.MAC_ACCOUNT_NAME }} + MAC_ACCOUNT_PASSWORD: ${{ secrets.MAC_ACCOUNT_PASSWORD }} + shell: bash + run: | + UEFITOOL_VER=$(cat ../UEFITool/version.h | grep PROGRAM_VERSION | cut -d'"' -f2 | sed 's/NE alpha /A/') ; \ + codesign -fs - UEFIExtract/UEFIExtract + codesign -fs - UEFIFind/UEFIFind + zip -qryj ../UEFITool/dist/UEFIExtract_NE_${UEFITOOL_VER}_universal_mac.zip ./UEFIExtract/UEFIExtract + zip -qryj ../UEFITool/dist/UEFIFind_NE_${UEFITOOL_VER}_universal_mac.zip ./UEFIFind/UEFIFind + brew install create-dmg || exit 1 + curl -OL "https://github.com/acidanthera/ocbuild/raw/master/codesign/appsign.sh" || exit 1 + chmod a+x appsign.sh || exit 1 + "$(pwd)/appsign.sh" ./UEFITool/UEFITool.app ../UEFITool/dist/UEFITool_NE_${UEFITOOL_VER}_universal_mac.dmg + - name: Archive everything + if: github.repository_owner != 'LongSoft' + working-directory: ${{runner.workspace}}/build + shell: bash + run: | + UEFITOOL_VER=$(cat ../UEFITool/version.h | grep PROGRAM_VERSION | cut -d'"' -f2 | sed 's/NE alpha /A/') ; \ + codesign -fs - UEFIExtract/UEFIExtract + codesign -fs - UEFIFind/UEFIFind + zip -qryj ../UEFITool/dist/UEFIExtract_NE_${UEFITOOL_VER}_universal_mac.zip ./UEFIExtract/UEFIExtract + zip -qryj ../UEFITool/dist/UEFIFind_NE_${UEFITOOL_VER}_universal_mac.zip ./UEFIFind/UEFIFind + cd UEFITool + codesign -fs - --deep UEFITool.app + zip -qry ../../UEFITool/dist/UEFITool_NE_${UEFITOOL_VER}_universal_mac.zip ./UEFITool.app + - name: Upload to artifacts + uses: actions/upload-artifact@v4 + with: + name: macOS builds + path: dist/* + - name: Upload to releases + if: github.event_name == 'release' + uses: svenstaro/upload-release-action@v2 + with: + repo_token: ${{ secrets.GITHUB_TOKEN }} + file: dist/* + tag: ${{ github.ref }} + file_glob: true + + build_release_linux: + name: Release build (Linux x64, shared Qt 6) + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v3 + - name: Get Qt + run: | + sudo apt update + sudo apt-get install -qq zip cmake libgl1-mesa-dev qt6-base-dev + - name: Create build directory + run: cmake -E make_directory ${{runner.workspace}}/build + - name: Configure everything + working-directory: ${{runner.workspace}}/build + run: cmake ../UEFITool + - name: Build everything + working-directory: ${{runner.workspace}}/build + shell: bash + run: cmake --build . --config Release + - name: Create dist directory + run: cmake -E make_directory ${{runner.workspace}}/UEFITool/dist + - name: Archive everything + working-directory: ${{runner.workspace}}/build + shell: bash + run: | + UEFITOOL_VER=$(cat ../UEFITool/version.h | grep PROGRAM_VERSION | cut -d'"' -f2 | sed 's/NE alpha /A/') ; \ + zip -qryj ../UEFITool/dist/UEFIExtract_NE_${UEFITOOL_VER}_x64_linux.zip ./UEFIExtract/uefiextract + zip -qryj ../UEFITool/dist/UEFIFind_NE_${UEFITOOL_VER}_x64_linux.zip ./UEFIFind/uefifind + zip -qryj ../UEFITool/dist/UEFITool_NE_${UEFITOOL_VER}_x64_linux.zip ./UEFITool/uefitool + - name: Upload to artifacts + uses: actions/upload-artifact@v4 + with: + name: Linux builds + path: dist/*.zip + - name: Upload to releases + if: github.event_name == 'release' + uses: svenstaro/upload-release-action@v2 + with: + repo_token: ${{ secrets.GITHUB_TOKEN }} + file: dist/*.zip + tag: ${{ github.ref }} + file_glob: true + + build_release_freebsd: + name: Release build (FreeBSD x64, shared Qt 6) + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Build on FreeBSD inside Ubuntu VM + id: test + uses: cross-platform-actions/action@v0.27.0 + with: + operating_system: freebsd + version: '13.3' + shell: sh + run: | + sudo pkg install -y zip cmake qt6-base + mkdir dist + mkdir build + cd build + cmake .. + cmake --build . --config Release + UEFITOOL_VER=$(cat ../version.h | grep PROGRAM_VERSION | cut -d'"' -f2 | sed 's/NE alpha /A/') ; \ + zip -qryj ../dist/UEFIExtract_NE_${UEFITOOL_VER}_x64_freebsd.zip ./UEFIExtract/uefiextract + zip -qryj ../dist/UEFIFind_NE_${UEFITOOL_VER}_x64_freebsd.zip ./UEFIFind/uefifind + zip -qryj ../dist/UEFITool_NE_${UEFITOOL_VER}_x64_freebsd.zip ./UEFITool/uefitool + - name: Upload to artifacts + uses: actions/upload-artifact@v4 + with: + name: FreeBSD builds + path: dist/*.zip + - name: Upload to releases + if: github.event_name == 'release' + uses: svenstaro/upload-release-action@v2 + with: + repo_token: ${{ secrets.GITHUB_TOKEN }} + file: dist/*.zip + tag: ${{ github.ref }} + file_glob: true + + build_release_windows_32: + name: Release build (Win32, static Qt 5.6.3) + runs-on: windows-2019 + steps: + - uses: actions/checkout@v3 + - name: Get Qt 5.6.3 + uses: actions/checkout@v3 + with: + repository: LongSoft/qt-5.6.3-static-x86-msvc2017 + path: qt5 + lfs: true + - name: Unpack Qt 5.6.3 + shell: bash + working-directory: qt5 + run: 7z x qt-5.6.3-static-x86-msvc2017.7z -o../.. + - name: Create dist directory + shell: bash + run: mkdir dist + - name: Create UEFIExtract build directory + run: cmake -E make_directory ${{runner.workspace}}/build/UEFIExtract + - name: Configure UEFIExtract + shell: bash + working-directory: ${{runner.workspace}}/build/UEFIExtract + run: cmake -G "Visual Studio 16 2019" -A Win32 -T "v141_xp" -DCMAKE_MSVC_RUNTIME_LIBRARY="MultiThreaded" ../../UEFITool/UEFIExtract/ + - name: Build UEFIExtract + working-directory: ${{runner.workspace}}/build/UEFIExtract + shell: bash + run: cmake --build . --config Release + - name: Archive UEFIExtract + working-directory: ${{runner.workspace}}/build/UEFIExtract/Release + shell: bash + run: | + UEFITOOL_VER=$(cat ../../../UEFITool/version.h | grep PROGRAM_VERSION | cut -d'"' -f2 | sed 's/NE alpha /A/') ; \ + 7z a ../../../UEFITool/dist/UEFIExtract_NE_${UEFITOOL_VER}_win32.zip UEFIExtract.exe + - name: Create UEFIFind build directory + run: cmake -E make_directory ${{runner.workspace}}/build/UEFIFind + - name: Configure UEFIFind + working-directory: ${{runner.workspace}}/build/UEFIFind + shell: bash + run: cmake -G "Visual Studio 16 2019" -A Win32 -T "v141_xp" -DCMAKE_MSVC_RUNTIME_LIBRARY="MultiThreaded" ../../UEFITool/UEFIFind/ + - name: Build UEFIFind + working-directory: ${{runner.workspace}}/build/UEFIFind + shell: bash + run: cmake --build . --config Release + - name: Archive UEFIFind + working-directory: ${{runner.workspace}}/build/UEFIFind/Release + shell: bash + run: | + UEFITOOL_VER=$(cat ../../../UEFITool/version.h | grep PROGRAM_VERSION | cut -d'"' -f2 | sed 's/NE alpha /A/') ; \ + 7z a ../../../UEFITool/dist/UEFIFind_NE_${UEFITOOL_VER}_win32.zip UEFIFind.exe + - name: Create UEFITool build directory + run: cmake -E make_directory ${{runner.workspace}}/build/UEFITool + - name: Configure UEFITool + shell: bash + working-directory: ${{runner.workspace}}/build/UEFITool + run: ../../qt-5.6.3-static-x86-msvc2017/bin/qmake.exe -tp vc ../../UEFITool/UEFITool/ + - name: Build UEFITool + working-directory: ${{runner.workspace}}/build/UEFITool + shell: cmd + run: | + call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars32.bat" + msbuild -t:Rebuild -p:PlatformToolset=v141_xp;Configuration=Release + - name: Archive UEFITool + working-directory: ${{runner.workspace}}/build/UEFITool/release + shell: bash + run: | + UEFITOOL_VER=$(cat ../../../UEFITool/version.h | grep PROGRAM_VERSION | cut -d'"' -f2 | sed 's/NE alpha /A/') ; \ + 7z a ../../../UEFITool/dist/UEFITool_NE_${UEFITOOL_VER}_win32.zip UEFITool.exe + - name: Upload to artifacts + uses: actions/upload-artifact@v4 + with: + name: Windows 32-bit builds + path: dist/*.zip + - name: Upload to releases + if: github.event_name == 'release' + uses: svenstaro/upload-release-action@v2 + with: + repo_token: ${{ secrets.GITHUB_TOKEN }} + file: dist/*.zip + tag: ${{ github.ref }} + file_glob: true + + build_release_windows_64: + name: Release build (Win64, static Qt 6.5.0) + runs-on: windows-2022 + steps: + - uses: actions/checkout@v3 + - name: Get Qt 6.5.0 + uses: actions/checkout@v3 + with: + repository: LongSoft/qt-6-static-x64-msvc2022 + path: qt6 + lfs: true + - name: Unpack Qt 6.5.0 + shell: bash + working-directory: qt6 + run: 7z x qt-6.5.0-static-x64-msvc2022.7z -o../.. + - name: Create build directory + run: cmake -E make_directory ${{runner.workspace}}/build + - name: Configure everything + working-directory: ${{runner.workspace}}/build + shell: cmd + run: cmake -DCMAKE_PREFIX_PATH="D:\a\UEFITool\qt-6.5.0-static-x64-msvc2022" -DCMAKE_MSVC_RUNTIME_LIBRARY="MultiThreaded" -A x64 ../UEFITool + - name: Build everything + working-directory: ${{runner.workspace}}/build + shell: bash + run: cmake --build . --config Release + - name: Create dist directory + run: cmake -E make_directory ${{runner.workspace}}/UEFITool/dist + - name: Archive everything + working-directory: ${{runner.workspace}}/build + shell: bash + run: | + UEFITOOL_VER=$(cat ../UEFITool/version.h | grep PROGRAM_VERSION | cut -d'"' -f2 | sed 's/NE alpha /A/') ; \ + 7z a ../UEFITool/dist/UEFIExtract_NE_${UEFITOOL_VER}_win64.zip ./UEFIExtract/Release/UEFIExtract.exe + 7z a ../UEFITool/dist/UEFIFind_NE_${UEFITOOL_VER}_win64.zip ./UEFIFind/Release/UEFIFind.exe + 7z a ../UEFITool/dist/UEFITool_NE_${UEFITOOL_VER}_win64.zip ./UEFITool/Release/UEFITool.exe + - name: Upload to artifacts + uses: actions/upload-artifact@v4 + with: + name: Windows 64-bit builds + path: dist/*.zip + - name: Upload to releases + if: github.event_name == 'release' + uses: svenstaro/upload-release-action@v2 + with: + repo_token: ${{ secrets.GITHUB_TOKEN }} + file: dist/*.zip + tag: ${{ github.ref }} + file_glob: true + +# Build Tests + build_test_linux_meson: + name: Meson build system test (shared Qt 5) + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v3 + - name: Get Deps + run: | + sudo apt update + sudo apt-get install -qq cmake meson zlib1g-dev qtbase5-dev + - name: Configure build + run: mkdir build-meson && meson ./build-meson + - name: Build everything + run: ninja -C build-meson + + build_test_windows_mingw: + name: MinGW compiler test (shared Qt 6.5.0) + runs-on: windows-latest + steps: + - uses: actions/checkout@v3 + - name: Install Qt + uses: jurplel/install-qt-action@v3 + with: + version: '6.5.0' + host: 'windows' + target: 'desktop' + arch: 'win64_mingw' + - name: Build everything + run: | + cmake -G "MinGW Makefiles" -B build . + cmake --build build --parallel + + build_test_linux_fuzzer: + name: Fuzzer build test (Clang, Linux x64) + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v3 + - name: Create build directory + run: cmake -E make_directory ${{runner.workspace}}/build + - name: Configure everything + working-directory: ${{runner.workspace}}/build + run: CC=/usr/bin/clang CXX=/usr/bin/clang++ cmake ../UEFITool/fuzzing + - name: Build everything + working-directory: ${{runner.workspace}}/build + shell: bash + run: cmake --build . + - name: Create dist directory + run: cmake -E make_directory ${{runner.workspace}}/dist + - name: Archive everything + working-directory: ${{runner.workspace}}/build + shell: bash + run: | + UEFITOOL_VER=$(cat ../UEFITool/version.h | grep PROGRAM_VERSION | cut -d'"' -f2 | sed 's/NE alpha /A/') ; \ + zip -qryj ../dist/ffsparser_fuzzer_NE_${UEFITOOL_VER}_x64_linux.zip ./ffsparser_fuzzer + - name: Upload to artifacts + uses: actions/upload-artifact@v4 + with: + name: Fuzzer + path: ${{runner.workspace}}/dist/*.zip + +# Static Analysis + build_analyze_linux_coverity: + env: + PROJECT_TYPE: TOOL + JOB_TYPE: COVERITY + if: github.repository_owner == 'LongSoft' && github.event_name != 'pull_request' + name: Coverity Static Analysis (shared Qt 6.5.0) + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Install Qt + uses: jurplel/install-qt-action@v3 + with: + version: '6.5.0' + host: 'linux' + target: 'desktop' + - name: Create build directory + run: cmake -E make_directory ${{runner.workspace}}/build + - name: Configure everything + working-directory: ${{runner.workspace}}/build + run: cmake ../UEFITool + - name: Run Coverity + working-directory: ${{runner.workspace}}/build + run: | + src=$(/usr/bin/curl -Lfs https://raw.githubusercontent.com/acidanthera/ocbuild/master/coverity/covstrap-linux.sh) && eval "$src" || exit 1 + env: + COVERITY_SCAN_TOKEN: ${{ secrets.COVERITY_SCAN_TOKEN }} + COVERITY_SCAN_EMAIL: ${{ secrets.COVERITY_SCAN_EMAIL }} + COVERITY_BUILD_COMMAND: cmake --build . + + build_analyze_linux_sonarcloud: + if: github.repository_owner == 'LongSoft' && github.event_name != 'pull_request' + name: SonarCloud Static Analysis (shared Qt 6.5.0) + runs-on: ubuntu-latest + env: + BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis + - name: Install Qt + uses: jurplel/install-qt-action@v3 + with: + version: '6.5.0' + host: 'linux' + target: 'desktop' + - name: Install JDK 17 + uses: actions/setup-java@v3 + with: + distribution: 'zulu' + java-version: 17 + - name: Install build-wrapper + uses: SonarSource/sonarcloud-github-c-cpp@v2 + - name: Run build-wrapper + run: | + cmake -B build . + build-wrapper-linux-x86-64 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} cmake --build build + - name: SonarQube Scan + uses: SonarSource/sonarqube-scan-action@v4.2.1 + env: + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + SONAR_ROOT_CERT: ${{ secrets.SONAR_ROOT_CERT }} + with: + # Consult https://docs.sonarsource.com/sonarqube-server/latest/analyzing-source-code/scanners/sonarscanner/ for more information and options + args: > + --define sonar.cfamily.compile-commands="${{ env.BUILD_WRAPPER_OUT_DIR }}/compile_commands.json" diff --git a/.gitignore b/.gitignore index 1a4afc2..5fa200e 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ ################# moc_*.* ui_*.* +qrc_*.* ################# ## Qt Creator @@ -231,3 +232,23 @@ pip-log.txt ############# *.o Makefile + +uefitool_plugin_import.cpp +UEFITool.app/ +UEFITool/XCBuildData +UEFIDump/UEFIDump +UEFIExtract/UEFIExtract +UEFIExtract/guids.csv +UEFIFind/UEFIFind +.qmake.stash +CMakeCache.txt +CMakeFiles +cmake_install.cmake +DerivedData +*.xcodeproj +compile_commands.json +CMakeScripts +UEFITool/qrc_uefitool.cpp +XcodeQT5 +XcodeQT6 +*.dSYM diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..eae7c2d --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,7 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) + +PROJECT(UEFITool_everything) + +ADD_SUBDIRECTORY(UEFIExtract) +ADD_SUBDIRECTORY(UEFIFind) +ADD_SUBDIRECTORY(UEFITool) diff --git a/README.md b/README.md index 3854eef..1f5a9f4 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,8 @@ UEFITool is a viewer and editor of firmware images conforming to UEFI Platform Interface (PI) Specifications. -![UEFITool icon](https://raw.githubusercontent.com/LongSoft/UEFITool/new_engine/UEFITool/icons/uefitool_64x64.png "UEFITool icon") -![Coverity badge](https://scan.coverity.com/projects/1812/badge.svg?flat=1 "Coverity badge") +![UEFITool icon](https://raw.githubusercontent.com/LongSoft/UEFITool/new_engine/UEFITool/icons/uefitool_64x64.png "UEFITool icon") +![CI Status](https://github.com/LongSoft/UEFITool/actions/workflows/main.yml/badge.svg?branch=new_engine) [![Scan Status](https://scan.coverity.com/projects/17209/badge.svg?flat=1)](https://scan.coverity.com/projects/17209) [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=LongSoft_UEFITool&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=LongSoft_UEFITool) ## Very Brief Introduction to UEFI @@ -29,28 +29,37 @@ The missing parts are in development and the version with a new engine will be m There are some other projects that use UEFITool's engine: * UEFIExtract, which uses ffsParser to parse supplied firmware image into a tree structure and dumps the parsed structure recursively on the FS. Jethro Beekman's [tree](https://github.com/jethrogb/uefireverse) utility can be used to work with the extracted tree. -* UEFIDump, a variation of UEFIExtract that dumps all leaf items into one .dump folder without any hierarchy. This tool is a PoC for non-Qt engine usage. -* UEFIFind, which uses ffsParser to find image elements containing a specified pattern. It was developed for [UBU](http://www.win-raid.com/t154f16-Tool-Guide-News-quot-UEFI-BIOS-Updater-quot-UBU.html) project. -* [OZMTool](https://github.com/tuxuser/UEFITool/tree/OZM/OZMTool), which uses UEFITool's engine to perform various "hackintosh"-related firmware modifications. +* UEFIFind, which uses ffsParser to find image elements containing a specified pattern. It was developed for [UBU](https://winraid.level1techs.com/t/tool-guide-news-uefi-bios-updater-ubu/30357) project. ## Alternatives Right now there are some alternatives to UEFITool that you could find useful too: -* **[PhoenixTool](http://forums.mydigitallife.info/threads/13194-Tool-to-Insert-Replace-SLIC-in-Phoenix-Insyde-Dell-EFI-BIOSes)** by [AndyP](http://forums.mydigitallife.info/members/39295-andyp). Windows-only freeware GUI application written in C#. Used mostly for SLIC-related modifications, but it not limited to this task. Requires Microsoft .NET 3.5 to work properly. Supports unpacking firmware images from various vendor-specific formats like encrypted HP update files and Dell installers. +* **[FMMT](https://github.com/tianocore/edk2/tree/master/BaseTools/Source/Python/FMMT)** by TianoCore. Python-based open source toolset for modifying EDK2-based UEFI firmware images. Does not support any IBV customizations, but is _official_, and lives in EDK2 repository. +* **[Fiano](https://github.com/linuxboot/fiano)** by Google and Facebook. Go-based cross-platform open source toolset for modifying UEFI firmware images. +* **[PhoenixTool](https://forums.mydigitallife.net/threads/tool-to-insert-replace-slic-in-phoenix-insyde-dell-efi-bioses.13194)** by [AndyP](https://forums.mydigitallife.net/members/andyp.39295). Windows-only freeware GUI application written in C#. Used mostly for SLIC-related modifications, but it not limited to this task. Requires Microsoft .NET 3.5 to work properly. Supports unpacking firmware images from various vendor-specific formats like encrypted HP update files and Dell installers. * **[uefi-firmware-parser](https://github.com/theopolis/uefi-firmware-parser)** by [Teddy Reed](https://github.com/theopolis). Cross-platform open source console application written in Python. Very tinker-friendly due to use of Python. Can be used in scripts to automate firmware patching. * **[Chipsec](https://github.com/chipsec/chipsec)** by Intel. Cross-platform partially open source console application written in Python and C. Can be used to test Intel-based platforms for various security-related misconfigurations, but also has NVRAM parser and other components aimed to firmware modification. -* **MMTool** by AMI. Windows-only proprietary application available to AMI clients. Works only with Aptio4- and AptioV-based firmware images, but has some interesting features including OptionROM replacement and microcode update. Must be licensed from AMI. -* **H2OEZE** by Insyde. Windows-only proprietary application available to Insyde clients. Works only with InsydeH2O-based firmware images. Must be licensed from Insyde. -* **SCT BIOS Editor** by Phoenix. Windows-only proprietary application available to Phoenix clients. Works only with Phoenix SCT-based firmware images. Must be licensed from Phoenix. ## Installation -You can either use [pre-built binaries for Windows and OSX](https://github.com/LongSoft/UEFITool/releases) or build a binary yourself. -* To build a binary that uses Qt library (UEFITool, UEFIExtract, UEFIFind) you need a C++ compiler and an instance of Qt4/Qt5 library. Install both of them, get the sources, generate makefiles using qmake (`qmake UEFITool.pro`) and use your system's make command on that generated files (i.e. `nmake release`, `make release` and so on). -* To build a binary that doesn't use Qt (UEFIDump), you need a C++ compiler and CMAKE utility to generate a makefile for your OS and build environment. Install both of them, get the sources, generate makefiles using cmake (`cmake UEFIDump`) and use your system's make command on that generated files (i.e. `nmake release`, `make release` and so on). +You can either use [pre-built binaries](https://github.com/LongSoft/UEFITool/releases) or build a binary yourself. +* To build a binary that uses Qt library (UEFITool) you need a C++ compiler and an instance of [Qt5 or Qt6](https://www.qt.io) library. Install both of them, get the sources, generate makefiles using qmake (`qmake ./UEFITool/uefitool.pro`) and use your system's make command on that generated files (i.e. `nmake release`, `make release` and so on). Qt6-based builds can also use CMAKE as an altearnative build system. +* To build a binary that doesn't use Qt (UEFIExtract, UEFIFind), you need a C++ compiler and [CMAKE](https://cmake.org) utility to generate a makefile for your OS and build environment. Install both of them, get the sources, generate makefiles using cmake (`cmake UEFIExtract`) and use your system's make command on that generated files (i.e. `nmake release`, `make release` and so on). Non-Qt builds can also use Meson as an alternative build system. ## Known issues +* Image editing is currently only possible using an outdated and unsupported UEFITool 0.28 (`old_engine` branch) and the tools based on it (`UEFIReplace`, `UEFIPatch`). This is the top priority [issue #67](https://github.com/LongSoft/UEFITool/issues/67), which is being worked on, albeit slowly (due to the amount of coding and testing required to implement it correctly). * Some vendor-specific firmware update files can be opened incorrectly or can't be opened at all. This includes encrypted HP update files, Dell HDR and EXE files, some InsydeFlash FD files and so on. Enabling support for such files will require massive amount of reverse-engineering which is almost pointless because the updated image can be obtained from BIOS chip where it's already decrypted and unpacked. -* Intel Firmware Interface Table (FIT) editing is not supported right now. FIT contains pointers to various image components that must be loaded before executing the first CPU instruction from the BIOS chip. Those components include CPU microcode updates, binaries and settings used by BIOS Guard and Boot Guard technologies and some other stuff. More information on FIT can be obtained [here](http://downloadmirror.intel.com/18931/eng/Intel%20TXT%20LAB%20Handout.pdf). -* Builder code is still not ready, but I'm working hard on it. +* Intel Firmware Interface Table (FIT) editing is not supported right now. FIT contains pointers to various image components that must be loaded before executing the first CPU instruction from the BIOS chip. Those components include CPU microcode updates, binaries and settings used by BIOS Guard and Boot Guard technologies and some other stuff. More information on FIT can be obtained [here](https://edc.intel.com/content/www/us/en/design/products-and-solutions/software-and-services/firmware-and-bios/firmware-interface-table/firmware-interface-table/). +* Windows builds of `UEFIExtract` and `UEFIFind` might encouter an issue with folder paths being longer than 260 bytes (`MAX_PATH`) on some input files (see [issue #363](https://github.com/LongSoft/UEFITool/issues/363)). This is a [known Windows limitation](https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation?tabs=registry), that can be fixed by enabling long paths support via Windows Registry and adding a manifest to the executable file that requires such support. `UEFIExtract` has the required manifest additions since version `A67`, and the required registry file is provided by Microsoft on the page linked above, but this workaround is only awailable starting with Windows 10 build 1067. + +## Bug repellents + +* [Coverity Scan](https://scan.coverity.com/projects/17209) - static analyzer for C, C++, C#, JavaScript, Ruby, or Python code. +* [SonarCloud](https://sonarcloud.io/project/overview?id=LongSoft_UEFITool) - cloud-based source code analysis service. + +## GUID Database + +Every new release includes an update to the database of known UEFI-related GUIDs build with help of [Linux Vendor Firmware Service](https://fwupd.org). + +You can download the up-to-date version of that database using [this link](https://fwupd.org/lvfs/shards/export/csv). diff --git a/UEFIDump/CMakeLists.txt b/UEFIDump/CMakeLists.txt deleted file mode 100644 index 723e0af..0000000 --- a/UEFIDump/CMakeLists.txt +++ /dev/null @@ -1,48 +0,0 @@ -PROJECT(UEFIDump) - -SET(PROJECT_SOURCES - uefidump_main.cpp - uefidump.cpp - ../common/types.cpp - ../common/descriptor.cpp - ../common/ffs.cpp - ../common/nvram.cpp - ../common/ffsparser.cpp - ../common/ffsreport.cpp - ../common/peimage.cpp - ../common/treeitem.cpp - ../common/treemodel.cpp - ../common/utility.cpp - ../common/LZMA/LzmaDecompress.c - ../common/LZMA/SDK/C/LzmaDec.c - ../common/Tiano/EfiTianoDecompress.c - ../common/ustring.cpp - ../bstrlib/bstrlib.c - ../bstrlib/bstrwrap.cpp -) - -SET(PROJECT_HEADERS - uefidump.h - ../common/basetypes.h - ../common/descriptor.h - ../common/gbe.h - ../common/me.h - ../common/ffs.h - ../common/fit.h - ../common/nvram.h - ../common/ffsparser.h - ../common/ffsreport.h - ../common/peimage.h - ../common/types.h - ../common/treeitem.h - ../common/treemodel.h - ../common/utility.h - ../common/LZMA/LzmaDecompress.h - ../common/Tiano/EfiTianoDecompress.h - ../common/ubytearray.h - ../common/ustring.h - ../bstrlib/bstrlib.h - ../bstrlib/bstrwrap.h -) - -ADD_EXECUTABLE(UEFIDump ${PROJECT_SOURCES} ${PROJECT_HEADERS}) \ No newline at end of file diff --git a/UEFIDump/uefidump.cpp b/UEFIDump/uefidump.cpp deleted file mode 100644 index c8daf79..0000000 --- a/UEFIDump/uefidump.cpp +++ /dev/null @@ -1,204 +0,0 @@ -/* ffsdumper.cpp - -Copyright (c) 2015, Nikolaj Schlej. All rights reserved. -This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -*/ - -#include "uefidump.h" -#include "../common/ffs.h" -#include -#include -#include -#include -#include - -#ifdef WIN32 -#include -bool isExistOnFs(const UString & path) { - struct _stat buf; - return (_stat((const char*)path.toLocal8Bit(), &buf) == 0); -} - -bool makeDirectory(const UString & dir) { - return (_mkdir((const char*)dir.toLocal8Bit()) == 0); -} - -bool changeDirectory(const UString & dir) { - return (_chdir((const char*)dir.toLocal8Bit()) == 0); -} -#else -#include -bool isExistOnFs(const UString & path) { - struct stat buf; - return (stat((const char*)path.toLocal8Bit(), &buf) == 0); -} - -bool makeDirectory(const UString & dir) { - return (mkdir((const char*)dir.toLocal8Bit(), ACCESSPERMS) == 0); -} - -bool changeDirectory(const UString & dir) { - return (chdir((const char*)dir.toLocal8Bit()) == 0); -} -#endif - -USTATUS UEFIDumper::dump(const UByteArray & buffer, const UString & inPath, const UString & guid) -{ - UString path = UString(inPath) + UString(".dump"); - UString reportPath = UString(inPath) + UString(".report.txt"); - - if (initialized) { - // Check if called with a different buffer as before - if (buffer != currentBuffer) { - // Reinitalize if so - initialized = false; - } - } - - if (!initialized) { - // Fill currentBuffer - currentBuffer = buffer; - - // Parse FFS structure - USTATUS result = ffsParser.parse(buffer); - if (result) - return result; - // Show ffsParser messages - std::vector > messages = ffsParser.getMessages(); - for (size_t i = 0; i < messages.size(); i++) { - std::cout << messages[i].first << std::endl; - } - - // Show FIT table - std::vector > fitTable = ffsParser.getFitTable(); - if (fitTable.size()) { - std::cout << "-------------------------------------------------------------------" << std::endl; - std::cout << " Address | Size | Ver | CS | Type " << std::endl; - std::cout << "-------------------------------------------------------------------" << std::endl; - for (size_t i = 0; i < fitTable.size(); i++) { - std::cout << (const char*)fitTable[i][0].toLocal8Bit() << " | " - << (const char*)fitTable[i][1].toLocal8Bit() << " | " - << (const char*)fitTable[i][2].toLocal8Bit() << " | " - << (const char*)fitTable[i][3].toLocal8Bit() << " | " - << (const char*)fitTable[i][4].toLocal8Bit() << std::endl; - } - } - - // Create ffsReport - FfsReport ffsReport(&model); - std::vector report = ffsReport.generate(); - if (report.size()) { - std::ofstream ofs; - ofs.open((const char*)reportPath, std::ofstream::out); - for (size_t i = 0; i < report.size(); i++) { - ofs << (const char*)report[i].toLocal8Bit() << std::endl; - } - ofs.close(); - } - - initialized = true; - } - - // Check for dump directory existence - if (isExistOnFs(path)) - return U_DIR_ALREADY_EXIST; - - // Create dump directory and cd to it - if (!makeDirectory(path)) - return U_DIR_CREATE; - - if (!changeDirectory(path)) - return U_DIR_CHANGE; - - dumped = false; - UINT8 result = recursiveDump(model.index(0,0)); - if (result) - return result; - else if (!dumped) - return U_ITEM_NOT_FOUND; - - return U_SUCCESS; -} - -USTATUS UEFIDumper::recursiveDump(const UModelIndex & index) -{ - if (!index.isValid()) - return U_INVALID_PARAMETER; - - //UByteArray itemHeader = model.header(index); - //UByteArray fileHeader = model.header(model.findParentOfType(index, Types::File)); - - //if (guid.length() == 0 || - // (itemHeader.size() >= sizeof (EFI_GUID) && guidToUString(*(const EFI_GUID*)itemHeader.constData()) == guid) || - // (fileHeader.size() >= sizeof(EFI_GUID) && guidToUString(*(const EFI_GUID*)fileHeader.constData()) == guid)) { - - // Construct file name - UString orgName = uniqueItemName(index); - UString name = orgName; - bool nameFound = false; - for (int i = 1; i < 1000; ++i) { - if (!isExistOnFs(name + UString("_info.txt"))) { - nameFound = true; - break; - } - name = orgName + UString("_") + usprintf("%03d", i); - } - - if (!nameFound) - return U_INVALID_PARAMETER; //TODO: replace with proper errorCode - - // Add header and body only for leaf sections - if (model.rowCount(index) == 0) { - // Header - UByteArray data = model.header(index); - if (!data.isEmpty()) { - std::ofstream file; - UString str = name + UString("_header.bin"); - file.open((const char*)str, std::ios::out | std::ios::binary); - file.write(data.constData(), data.size()); - file.close(); - } - - // Body - data = model.body(index); - if (!data.isEmpty()) { - std::ofstream file; - UString str = name + UString("_body.bin"); - file.open((const char*)str, std::ios::out | std::ios::binary); - file.write(data.constData(), data.size()); - file.close(); - } - } - // Info - UString info = "Type: " + itemTypeToUString(model.type(index)) + "\n" + - "Subtype: " + itemSubtypeToUString(model.type(index), model.subtype(index)) + "\n"; - if (model.text(index).length() > 0) - info += "Text: " + model.text(index) + "\n"; - info += model.info(index) + "\n"; - - std::ofstream file; - UString str = name + UString("_info.txt"); - file.open((const char*)str, std::ios::out); - file.write((const char*)info, info.length()); - file.close(); - - dumped = true; - //} - - // Process child items - UINT8 result; - for (int i = 0; i < model.rowCount(index); i++) { - result = recursiveDump(index.child(i, 0)); - if (result) - return result; - } - - return U_SUCCESS; -} diff --git a/UEFIDump/uefidump_main.cpp b/UEFIDump/uefidump_main.cpp deleted file mode 100644 index 4fcbedf..0000000 --- a/UEFIDump/uefidump_main.cpp +++ /dev/null @@ -1,35 +0,0 @@ -/* uefidump_main.cpp - -Copyright (c) 2016, Nikolaj Schlej. All rights reserved. -This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -*/ -#include -#include - -#include "uefidump.h" - -int main(int argc, char *argv[]) -{ - - if (argc > 1) { - std::ifstream inputFile; - inputFile.open(argv[1], std::ios::in | std::ios::binary); - std::vector buffer(std::istreambuf_iterator(inputFile), - (std::istreambuf_iterator())); - inputFile.close(); - - UEFIDumper uefidumper; - return (uefidumper.dump(buffer, UString(argv[1])) != U_SUCCESS); - } - - std::cout << "UEFIDump 0.1.1" << std::endl << std::endl - << "Usage: UEFIDump imagefile" << std::endl; - return 0; -} diff --git a/UEFIExtract/CMakeLists.txt b/UEFIExtract/CMakeLists.txt new file mode 100644 index 0000000..ac174d7 --- /dev/null +++ b/UEFIExtract/CMakeLists.txt @@ -0,0 +1,92 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) + +PROJECT(UEFIExtract) + +SET(CMAKE_CXX_STANDARD 11) +SET(CMAKE_CXX_STANDARD_REQUIRED ON) +SET(CMAKE_CXX_EXTENSIONS OFF) + +SET(PROJECT_SOURCES + uefiextract_main.cpp + ffsdumper.cpp + uefidump.cpp + ../common/guiddatabase.cpp + ../common/types.cpp + ../common/filesystem.cpp + ../common/descriptor.cpp + ../common/ffs.cpp + ../common/nvram.cpp + ../common/nvramparser.cpp + ../common/meparser.cpp + ../common/ffsparser.cpp + ../common/fitparser.cpp + ../common/ffsreport.cpp + ../common/peimage.cpp + ../common/treeitem.cpp + ../common/treemodel.cpp + ../common/utility.cpp + ../common/LZMA/LzmaDecompress.c + ../common/LZMA/SDK/C/Bra.c + ../common/LZMA/SDK/C/Bra86.c + ../common/LZMA/SDK/C/CpuArch.c + ../common/LZMA/SDK/C/LzmaDec.c + ../common/Tiano/EfiTianoDecompress.c + ../common/ustring.cpp + ../common/bstrlib/bstrlib.c + ../common/bstrlib/bstrwrap.cpp + ../common/generated/ami_nvar.cpp + ../common/generated/apple_sysf.cpp + ../common/generated/dell_dvar.cpp + ../common/generated/edk2_vss.cpp + ../common/generated/edk2_vss2.cpp + ../common/generated/edk2_ftw.cpp + ../common/generated/insyde_fdc.cpp + ../common/generated/insyde_fdm.cpp + ../common/generated/ms_slic_marker.cpp + ../common/generated/ms_slic_pubkey.cpp + ../common/generated/phoenix_flm.cpp + ../common/generated/phoenix_evsa.cpp + ../common/generated/intel_acbp_v1.cpp + ../common/generated/intel_acbp_v2.cpp + ../common/generated/intel_keym_v1.cpp + ../common/generated/intel_keym_v2.cpp + ../common/generated/intel_acm.cpp + ../common/kaitai/kaitaistream.cpp + ../common/digest/sha1.c + ../common/digest/sha256.c + ../common/digest/sha512.c + ../common/digest/sm3.c + ../common/zlib/adler32.c + ../common/zlib/compress.c + ../common/zlib/crc32.c + ../common/zlib/deflate.c + ../common/zlib/gzclose.c + ../common/zlib/gzlib.c + ../common/zlib/gzread.c + ../common/zlib/gzwrite.c + ../common/zlib/inflate.c + ../common/zlib/infback.c + ../common/zlib/inftrees.c + ../common/zlib/inffast.c + ../common/zlib/trees.c + ../common/zlib/uncompr.c + ../common/zlib/zutil.c +) + +ADD_DEFINITIONS( + -DU_ENABLE_NVRAM_PARSING_SUPPORT + -DU_ENABLE_ME_PARSING_SUPPORT + -DU_ENABLE_FIT_PARSING_SUPPORT + -DU_ENABLE_GUID_DATABASE_SUPPORT +) + +ADD_EXECUTABLE(UEFIExtract ${PROJECT_SOURCES} uefiextract.manifest) + +IF(UNIX) + SET_TARGET_PROPERTIES(UEFIExtract PROPERTIES OUTPUT_NAME uefiextract) +ENDIF() + +INSTALL( + TARGETS UEFIExtract + RUNTIME DESTINATION bin +) diff --git a/UEFIExtract/ffsdumper.cpp b/UEFIExtract/ffsdumper.cpp index 07ee5ca..030904a 100644 --- a/UEFIExtract/ffsdumper.cpp +++ b/UEFIExtract/ffsdumper.cpp @@ -13,80 +13,218 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include "ffsdumper.h" -USTATUS FfsDumper::dump(const QModelIndex & root, const QString & path, const bool dumpAll, const QString & guid) +#include + +USTATUS FfsDumper::dump(const UModelIndex & root, const UString & path, const DumpMode dumpMode, const UINT8 sectionType, const UString & guid) { dumped = false; - UINT8 result = recursiveDump(root, path, dumpAll, guid); - if (result) + counterHeader = counterBody = counterRaw = counterInfo = 0; + fileList.clear(); + + if (changeDirectory(path)) { + printf("Directory \"%s\" already exists.\n", (const char*)path.toLocal8Bit()); + return U_DIR_ALREADY_EXIST; + } + + currentPath = path; + + USTATUS result = recursiveDump(root, path, dumpMode, sectionType, guid); + if (result) { + printf("Error %zu returned from recursiveDump (directory \"%s\").\n", result, (const char*)path.toLocal8Bit()); return result; - else if (!dumped) + } else if (!dumped) { + if (removeDirectory(path)) { + printf("Removed directory \"%s\" since nothing was dumped.\n", (const char*)path.toLocal8Bit()); + } return U_ITEM_NOT_FOUND; + } + return U_SUCCESS; } -USTATUS FfsDumper::recursiveDump(const QModelIndex & index, const QString & path, const bool dumpAll, const QString & guid) +USTATUS FfsDumper::recursiveDump(const UModelIndex & index, const UString & path, const DumpMode dumpMode, const UINT8 sectionType, const UString & guid) { if (!index.isValid()) return U_INVALID_PARAMETER; - QDir dir; if (guid.isEmpty() || - guidToUString(*(const EFI_GUID*)model->header(index).constData()) == guid || - guidToUString(*(const EFI_GUID*)model->header(model->findParentOfType(index, Types::File)).constData()) == guid) { + (model->subtype(index) == EFI_SECTION_FREEFORM_SUBTYPE_GUID && + guidToUString(readUnaligned((const EFI_GUID*)(model->header(index).constData() + sizeof(EFI_COMMON_SECTION_HEADER)))) == guid) || + guidToUString(readUnaligned((const EFI_GUID*)model->header(index).constData())) == guid || + guidToUString(readUnaligned((const EFI_GUID*)model->header(model->findParentOfType(index, Types::File)).constData())) == guid) { - if (dir.cd(path)) - return U_DIR_ALREADY_EXIST; - - if (!dir.mkpath(path)) + if (!changeDirectory(path) && !makeDirectory(path)) { + printf("Cannot use directory \"%s\" (recursiveDump part 1).\n", (const char*)path.toLocal8Bit()); return U_DIR_CREATE; + } - QFile file; - if (dumpAll || model->rowCount(index) == 0) { // Dump if leaf item or dumpAll is true - if (!model->header(index).isEmpty()) { - file.setFileName(QObject::tr("%1/header.bin").arg(path)); - if (!file.open(QFile::WriteOnly)) + if (currentPath != path) { + counterHeader = counterBody = counterUncData = counterRaw = counterInfo = 0; + currentPath = path; + } + + if (fileList.count(index) == 0 + && (dumpMode == DUMP_ALL || model->rowCount(index) == 0) + && (sectionType == IgnoreSectionType || model->subtype(index) == sectionType)) { + + if ((dumpMode == DUMP_ALL || dumpMode == DUMP_CURRENT || dumpMode == DUMP_HEADER) + && !model->hasEmptyHeader(index)) { + fileList.insert(index); + + UString filename; + if (counterHeader == 0) + filename = usprintf("%s/header.bin", path.toLocal8Bit()); + else + filename = usprintf("%s/header_%d.bin", path.toLocal8Bit(), counterHeader); + counterHeader++; + + std::ofstream file(filename.toLocal8Bit(), std::ofstream::binary); + if (!file) { + printf("Cannot open header \"%s\".\n", (const char*)filename.toLocal8Bit()); return U_FILE_OPEN; + } - file.write(model->header(index)); - file.close(); + const UByteArray &data = model->header(index); + file.write(data.constData(), data.size()); + + dumped = true; } - if (!model->body(index).isEmpty()) { - file.setFileName(QObject::tr("%1/body.bin").arg(path)); - if (!file.open(QFile::WriteOnly)) - return U_FILE_OPEN; + if ((dumpMode == DUMP_ALL || dumpMode == DUMP_CURRENT || dumpMode == DUMP_BODY) + && !model->hasEmptyBody(index)) { + fileList.insert(index); + UString filename; + if (counterBody == 0) + filename = usprintf("%s/body.bin", path.toLocal8Bit()); + else + filename = usprintf("%s/body_%d.bin", path.toLocal8Bit(), counterBody); + counterBody++; - file.write(model->body(index)); - file.close(); + std::ofstream file(filename.toLocal8Bit(), std::ofstream::binary); + if (!file) { + printf("Cannot open body \"%s\".\n", (const char*)filename.toLocal8Bit()); + return U_FILE_OPEN; + } + + const UByteArray &data = model->body(index); + file.write(data.constData(), data.size()); + + dumped = true; + } + + if ((dumpMode == DUMP_ALL || dumpMode == DUMP_CURRENT || dumpMode == DUMP_UNC_DATA) + && !model->hasEmptyUncompressedData(index)) { + fileList.insert(index); + UString filename; + if (counterUncData == 0) + filename = usprintf("%s/unc_data.bin", path.toLocal8Bit()); + else + filename = usprintf("%s/unc_data_%d.bin", path.toLocal8Bit(), counterUncData); + counterUncData++; + + std::ofstream file(filename.toLocal8Bit(), std::ofstream::binary); + if (!file) { + printf("Cannot open uncompressed data \"%s\".\n", (const char*)filename.toLocal8Bit()); + return U_FILE_OPEN; + } + + const UByteArray &data = model->uncompressedData(index); + file.write(data.constData(), data.size()); + + dumped = true; + } + + if (dumpMode == DUMP_FILE) { + UModelIndex fileIndex = index; + if (model->type(fileIndex) != Types::File) { + fileIndex = model->findParentOfType(index, Types::File); + if (!fileIndex.isValid()) + fileIndex = index; + } + + // We may select parent file during ffs extraction. + if (fileList.count(fileIndex) == 0) { + fileList.insert(fileIndex); + + UString filename; + if (counterRaw == 0) + filename = usprintf("%s/file.ffs", path.toLocal8Bit()); + else + filename = usprintf("%s/file_%d.ffs", path.toLocal8Bit(), counterRaw); + counterRaw++; + + std::ofstream file(filename.toLocal8Bit(), std::ofstream::binary); + if (!file) { + printf("Cannot open file \"%s\".\n", (const char*)filename.toLocal8Bit()); + return U_FILE_OPEN; + } + + const UByteArray &headerData = model->header(fileIndex); + const UByteArray &bodyData = model->body(fileIndex); + const UByteArray &tailData = model->tail(fileIndex); + + file.write(headerData.constData(), headerData.size()); + file.write(bodyData.constData(), bodyData.size()); + file.write(tailData.constData(), tailData.size()); + + dumped = true; + } } } - // Always dump info - QString info = QObject::tr("Type: %1\nSubtype: %2\n%3%4\n") - .arg(itemTypeToUString(model->type(index))) - .arg(itemSubtypeToUString(model->type(index), model->subtype(index))) - .arg(model->text(index).isEmpty() ? QObject::tr("") : QObject::tr("Text: %1\n").arg(model->text(index))) - .arg(model->info(index)); - file.setFileName(QObject::tr("%1/info.txt").arg(path)); - if (!file.open(QFile::Text | QFile::WriteOnly)) - return U_FILE_OPEN; + // Always dump info unless explicitly prohibited + if ((dumpMode == DUMP_ALL || dumpMode == DUMP_CURRENT || dumpMode == DUMP_INFO) + && (sectionType == IgnoreSectionType || model->subtype(index) == sectionType)) { + UString info = usprintf("Type: %s\nSubtype: %s\n%s%s\n", + itemTypeToUString(model->type(index)).toLocal8Bit(), + itemSubtypeToUString(model->type(index), model->subtype(index)).toLocal8Bit(), + (model->text(index).isEmpty() ? UString("") : + usprintf("Text: %s\n", model->text(index).toLocal8Bit())).toLocal8Bit(), + model->info(index).toLocal8Bit()); - file.write(info.toLatin1()); - file.close(); - dumped = true; + UString filename; + if (counterInfo == 0) + filename = usprintf("%s/info.txt", path.toLocal8Bit()); + else + filename = usprintf("%s/info_%d.txt", path.toLocal8Bit(), counterInfo); + counterInfo++; + + std::ofstream file(filename.toLocal8Bit()); + if (!file) { + printf("Cannot open info \"%s\".\n", (const char*)filename.toLocal8Bit()); + return U_FILE_OPEN; + } + + file << info.toLocal8Bit(); + + dumped = true; + } } - UINT8 result; + USTATUS result; + for (int i = 0; i < model->rowCount(index); i++) { - QModelIndex childIndex = index.child(i, 0); + UModelIndex childIndex = index.child(i, 0); bool useText = FALSE; if (model->type(childIndex) != Types::Volume) useText = !model->text(childIndex).isEmpty(); - QString childPath = QString("%1/%2 %3").arg(path).arg(i).arg(useText ? model->text(childIndex) : model->name(childIndex)); - result = recursiveDump(childIndex, childPath, dumpAll, guid); - if (result) + UString childPath = path; + if (dumpMode == DUMP_ALL || dumpMode == DUMP_CURRENT) { + if (!changeDirectory(path) && !makeDirectory(path)) { + printf("Cannot use directory \"%s\" (recursiveDump part 2).\n", (const char*)path.toLocal8Bit()); + return U_DIR_CREATE; + } + + UString name = usprintf("%d %s", i, (useText ? model->text(childIndex) : model->name(childIndex)).toLocal8Bit()); + fixFileName (name, false); + childPath = usprintf("%s/%s", path.toLocal8Bit(), name.toLocal8Bit()); + } + result = recursiveDump(childIndex, childPath, dumpMode, sectionType, guid); + if (result) { + printf("Error %zu returned from recursiveDump (child directory \"%s\").\n", result, (const char*)childPath.toLocal8Bit()); return result; + } } return U_SUCCESS; diff --git a/UEFIExtract/ffsdumper.h b/UEFIExtract/ffsdumper.h index f45946e..007cf11 100644 --- a/UEFIExtract/ffsdumper.h +++ b/UEFIExtract/ffsdumper.h @@ -14,27 +14,42 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #ifndef FFSDUMPER_H #define FFSDUMPER_H -#include -#include -#include -#include -#include +#include #include "../common/basetypes.h" +#include "../common/ustring.h" #include "../common/treemodel.h" #include "../common/ffs.h" +#include "../common/filesystem.h" +#include "../common/utility.h" class FfsDumper { public: - explicit FfsDumper(TreeModel * treeModel) : model(treeModel), dumped(false) {} + enum DumpMode { + DUMP_CURRENT, + DUMP_ALL, + DUMP_BODY, + DUMP_UNC_DATA, + DUMP_HEADER, + DUMP_INFO, + DUMP_FILE + }; + + static const UINT8 IgnoreSectionType = 0xFF; + + explicit FfsDumper(TreeModel * treeModel) : model(treeModel), dumped(false), + counterHeader(0), counterBody(0), counterUncData(0), counterRaw(0), counterInfo(0) {} ~FfsDumper() {}; - USTATUS dump(const QModelIndex & root, const QString & path, const bool dumpAll = false, const QString & guid = QString()); + USTATUS dump(const UModelIndex & root, const UString & path, const DumpMode dumpMode = DUMP_CURRENT, const UINT8 sectionType = IgnoreSectionType, const UString & guid = UString()); private: - USTATUS recursiveDump(const QModelIndex & root, const QString & path, const bool dumpAll, const QString & guid); + USTATUS recursiveDump(const UModelIndex & root, const UString & path, const DumpMode dumpMode, const UINT8 sectionType, const UString & guid); TreeModel* model; + UString currentPath; bool dumped; + int counterHeader, counterBody, counterUncData, counterRaw, counterInfo; + std::set fileList; }; #endif // FFSDUMPER_H diff --git a/UEFIExtract/meson.build b/UEFIExtract/meson.build new file mode 100644 index 0000000..327b1df --- /dev/null +++ b/UEFIExtract/meson.build @@ -0,0 +1,17 @@ +executable( + 'UEFIExtract', + sources: [ + 'uefiextract_main.cpp', + 'ffsdumper.cpp', + 'uefidump.cpp', + ], + link_with: [ + lzma, + bstrlib, + uefitoolcommon, + ], + dependencies: [ + zlib, + ], + install: true, +) diff --git a/UEFIExtract/uefidump.cpp b/UEFIExtract/uefidump.cpp new file mode 100644 index 0000000..1f10d93 --- /dev/null +++ b/UEFIExtract/uefidump.cpp @@ -0,0 +1,151 @@ +/* ffsdumper.cpp + +Copyright (c) 2018, LongSoft. All rights reserved. +This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +*/ + +#include "uefidump.h" +#include "../common/ffs.h" +#include "../common/utility.h" +#include "../common/filesystem.h" +#include +#include +#include +#include + +USTATUS UEFIDumper::dump(const UByteArray & buffer, const UString & inPath, const UString & guid) +{ + UString path = UString(inPath) + UString(".dump"); + UString reportPath = UString(inPath) + UString(".report.txt"); + + if (initialized) { + // Check if called with a different buffer as before + if (buffer != currentBuffer) { + // Reinitalize if so + initialized = false; + } + } + + if (!initialized) { + // Fill currentBuffer + currentBuffer = buffer; + + // Parse FFS structure + USTATUS result = ffsParser.parse(buffer); + if (result) + return result; + + ffsParser.outputInfo(); + + // Create ffsReport + FfsReport ffsReport(&model); + std::vector report = ffsReport.generate(); + if (report.size()) { + std::ofstream ofs; + ofs.open(reportPath, std::ofstream::out); + for (size_t i = 0; i < report.size(); i++) { + ofs << report[i].toLocal8Bit() << std::endl; + } + ofs.close(); + } + + initialized = true; + } + + // Check for dump directory existence + if (isExistOnFs(path)) + return U_DIR_ALREADY_EXIST; + + // Create dump directory and cd to it + if (!makeDirectory(path)) + return U_DIR_CREATE; + + if (!changeDirectory(path)) + return U_DIR_CHANGE; + + dumped = false; + USTATUS result = recursiveDump(model.index(0,0)); + if (result) + return result; + else if (!dumped) + return U_ITEM_NOT_FOUND; + + return U_SUCCESS; +} + +USTATUS UEFIDumper::recursiveDump(const UModelIndex & index) +{ + if (!index.isValid()) + return U_INVALID_PARAMETER; + + // Construct file name + UString orgName = uniqueItemName(index); + UString name = orgName; + bool nameFound = false; + for (int i = 1; i < 1000; ++i) { + if (!isExistOnFs(name + UString("_info.txt"))) { + nameFound = true; + break; + } + name = orgName + UString("_") + usprintf("%03d", i); + } + + if (!nameFound) { + printf("Cannot find unique name for \"%s\".\n", (const char*)orgName.toLocal8Bit()); + return U_INVALID_PARAMETER; //TODO: replace with proper errorCode + } + + // Add header and body only for leaf sections + if (model.rowCount(index) == 0) { + // Header + UByteArray data = model.header(index); + if (!data.isEmpty()) { + std::ofstream file; + UString str = name + UString("_header.bin"); + file.open(str.toLocal8Bit(), std::ios::out | std::ios::binary); + file.write(data.constData(), data.size()); + file.close(); + } + + // Body + data = model.body(index); + if (!data.isEmpty()) { + std::ofstream file; + UString str = name + UString("_body.bin"); + file.open(str.toLocal8Bit(), std::ios::out | std::ios::binary); + file.write(data.constData(), data.size()); + file.close(); + } + } + // Info + UString info = "Type: " + itemTypeToUString(model.type(index)) + "\n" + + "Subtype: " + itemSubtypeToUString(model.type(index), model.subtype(index)) + "\n"; + if (model.text(index).length() > 0) + info += "Text: " + model.text(index) + "\n"; + info += model.info(index) + "\n"; + + std::ofstream file; + UString str = name + UString("_info.txt"); + file.open(str.toLocal8Bit(), std::ios::out); + file.write(info.toLocal8Bit(), info.length()); + file.close(); + + dumped = true; + + // Process child items + USTATUS result; + for (int i = 0; i < model.rowCount(index); i++) { + result = recursiveDump(index.child(i, 0)); + if (result) + return result; + } + + return U_SUCCESS; +} diff --git a/UEFIDump/uefidump.h b/UEFIExtract/uefidump.h similarity index 95% rename from UEFIDump/uefidump.h rename to UEFIExtract/uefidump.h index 058d062..5802d5c 100644 --- a/UEFIDump/uefidump.h +++ b/UEFIExtract/uefidump.h @@ -1,6 +1,6 @@ /* uefidump.h -Copyright (c) 2016, Nikolaj Schlej. All rights reserved. +Copyright (c) 2018, LongSoft. All rights reserved. This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at diff --git a/UEFIExtract/uefiextract.manifest b/UEFIExtract/uefiextract.manifest new file mode 100644 index 0000000..9e1a8e3 --- /dev/null +++ b/UEFIExtract/uefiextract.manifest @@ -0,0 +1,8 @@ + + + + + true + + + \ No newline at end of file diff --git a/UEFIExtract/uefiextract.pro b/UEFIExtract/uefiextract.pro deleted file mode 100644 index c9a86f7..0000000 --- a/UEFIExtract/uefiextract.pro +++ /dev/null @@ -1,46 +0,0 @@ -QT += core -QT -= gui - -TARGET = UEFIExtract -TEMPLATE = app -CONFIG += console -CONFIG -= app_bundle - -SOURCES += \ - uefiextract_main.cpp \ - ffsdumper.cpp \ - ../common/types.cpp \ - ../common/descriptor.cpp \ - ../common/ffs.cpp \ - ../common/nvram.cpp \ - ../common/ffsparser.cpp \ - ../common/ffsreport.cpp \ - ../common/peimage.cpp \ - ../common/treeitem.cpp \ - ../common/treemodel.cpp \ - ../common/utility.cpp \ - ../common/LZMA/LzmaDecompress.c \ - ../common/LZMA/SDK/C/LzmaDec.c \ - ../common/Tiano/EfiTianoDecompress.c \ - ../common/ustring.cpp - -HEADERS += \ - ffsdumper.h \ - ../common/basetypes.h \ - ../common/descriptor.h \ - ../common/gbe.h \ - ../common/me.h \ - ../common/ffs.h \ - ../common/nvram.h \ - ../common/ffsparser.h \ - ../common/ffsreport.h \ - ../common/peimage.h \ - ../common/types.h \ - ../common/treeitem.h \ - ../common/treemodel.h \ - ../common/utility.h \ - ../common/LZMA/LzmaDecompress.h \ - ../common/Tiano/EfiTianoDecompress.h \ - ../common/ubytearray.h \ - ../common/ustring.h - diff --git a/UEFIExtract/uefiextract_main.cpp b/UEFIExtract/uefiextract_main.cpp index 1263ff7..e0ccab2 100644 --- a/UEFIExtract/uefiextract_main.cpp +++ b/UEFIExtract/uefiextract_main.cpp @@ -1,5 +1,5 @@ /* uefiextract_main.cpp -Copyright (c) 2016, Nikolaj Schlej. All rights reserved. +Copyright (c) 2018, LongSoft. All rights reserved. This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -7,125 +7,213 @@ http://opensource.org/licenses/bsd-license.php THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. */ -#include -#include -#include #include +#include +#include +#include +#include "../version.h" +#include "../common/basetypes.h" +#include "../common/ustring.h" +#include "../common/filesystem.h" #include "../common/ffsparser.h" #include "../common/ffsreport.h" +#include "../common/guiddatabase.h" #include "ffsdumper.h" +#include "uefidump.h" + +enum ReadType { + READ_INPUT, + READ_OUTPUT, + READ_MODE, + READ_SECTION +}; + +void print_usage() +{ + std::cout << "UEFIExtract " PROGRAM_VERSION << std::endl + << "Usage: UEFIExtract {-h | --help | -v | --version} - show help and/or version information." << std::endl + << " UEFIExtract imagefile - generate report and GUID database, then dump only leaf tree items into .dump folder." << std::endl + << " UEFIExtract imagefile all - generate report and GUID database, then dump all tree items into .dump folder." << std::endl + << " UEFIExtract imagefile unpack - generate report, then dump all tree items into a single .dump folder (legacy UEFIDump compatibility mode)." << std::endl + << " UEFIExtract imagefile dump - only generate dump, no report or GUID database needed." << std::endl + << " UEFIExtract imagefile report - only generate report, no dump or GUID database needed." << std::endl + << " UEFIExtract imagefile guids - only generate GUID database, no dump or report needed." << std::endl + << " UEFIExtract imagefile GUID_1 ... [ -o FILE_1 ... ] [ -m MODE_1 ... ] [ -t TYPE_1 ... ] -" << std::endl + << " Dump only FFS file(s) with specific GUID(s), without report or GUID database." << std::endl + << " Type is section type or FF to ignore. Mode is one of: all, body, unc_data, header, info, file." << std::endl + << " Return value is a bit mask where 0 at position N means that file with GUID_N was found and unpacked, 1 otherwise." << std::endl; +} int main(int argc, char *argv[]) { - QCoreApplication a(argc, argv); - a.setOrganizationName("CodeRush"); - a.setOrganizationDomain("coderush.me"); - a.setApplicationName("UEFIExtract"); + initGuidDatabase("guids.csv"); - if (a.arguments().length() > 32) { - std::cout << "Too many arguments" << std::endl; + if (argc <= 1) { + print_usage(); return 1; } - - if (a.arguments().length() > 1) { - // Check that input file exists - QString path = a.arguments().at(1); - QFileInfo fileInfo(path); - if (!fileInfo.exists()) - return U_FILE_OPEN; - - // Open the input file - QFile inputFile; - inputFile.setFileName(path); - if (!inputFile.open(QFile::ReadOnly)) - return U_FILE_OPEN; - - // Read and close the file - QByteArray buffer = inputFile.readAll(); - inputFile.close(); - - // Create model and ffsParser - TreeModel model; - FfsParser ffsParser(&model); - // Parse input buffer - USTATUS result = ffsParser.parse(buffer); - if (result) - return result; - - // Show ffsParser's messages - std::vector > messages = ffsParser.getMessages(); - for (size_t i = 0; i < messages.size(); i++) { - std::cout << messages[i].first.toLatin1().constData() << std::endl; + + // Help and version + if (argc == 2) { + UString arg = UString(argv[1]); + if (arg == UString("-h") || arg == UString("--help")) { + print_usage(); + return 0; } - - // Get last VTF - std::vector > fitTable = ffsParser.getFitTable(); - if (fitTable.size()) { - std::cout << "-------------------------------------------------------------------" << std::endl; - std::cout << " Address | Size | Ver | CS | Type " << std::endl; - std::cout << "-------------------------------------------------------------------" << std::endl; - for (size_t i = 0; i < fitTable.size(); i++) { - std::cout << fitTable[i][0].toLatin1().constData() << " | " - << fitTable[i][1].toLatin1().constData() << " | " - << fitTable[i][2].toLatin1().constData() << " | " - << fitTable[i][3].toLatin1().constData() << " | " - << fitTable[i][4].toLatin1().constData() << std::endl; - } - } - - - // Create ffsDumper - FfsDumper ffsDumper(&model); - - // Dump only leaf elements, no report - if (a.arguments().length() == 3 && a.arguments().at(2) == QString("dump")) { - return (ffsDumper.dump(model.index(0, 0), fileInfo.fileName().append(".dump")) != U_SUCCESS); - } - else if (a.arguments().length() > 3 || - (a.arguments().length() == 3 && a.arguments().at(2) != QString("all") && a.arguments().at(2) != QString("report"))) { // Dump specific files, without report - UINT32 returned = 0; - for (int i = 2; i < a.arguments().length(); i++) { - result = ffsDumper.dump(model.index(0, 0), fileInfo.fileName().append(".dump"), true, a.arguments().at(i)); - if (result) - returned |= (1 << (i - 1)); - } - return returned; - } - - // Create ffsReport - FfsReport ffsReport(&model); - std::vector report = ffsReport.generate(); - if (report.size()) { - QFile file; - file.setFileName(fileInfo.fileName().append(".report.txt")); - if (file.open(QFile::Text | QFile::WriteOnly)) { - for (size_t i = 0; i < report.size(); i++) { - file.write(report[i].toLatin1().append('\n')); - } - file.close(); - } - } - - // Dump all non-leaf elements, with report, default - if (a.arguments().length() == 2) { - return (ffsDumper.dump(model.index(0, 0), fileInfo.fileName().append(".dump")) != U_SUCCESS); - } - else if (a.arguments().length() == 3 && a.arguments().at(2) == QString("all")) { // Dump every elementm with report - return (ffsDumper.dump(model.index(0, 0), fileInfo.fileName().append(".dump"), true) != U_SUCCESS); - } - else if (a.arguments().length() == 3 && a.arguments().at(2) == QString("report")) { // Skip dumping + else if (arg == UString("-v") || arg == UString("--version")) { + std::cout << PROGRAM_VERSION << std::endl; return 0; } } + + // Check that input file exists + USTATUS result; + UByteArray buffer; + UString path = getAbsPath(argv[1]); + if (false == readFileIntoBuffer(path, buffer)) + return U_FILE_OPEN; + + // Hack to support legacy UEFIDump mode + if (argc == 3 && !std::strcmp(argv[2], "unpack")) { + UEFIDumper uefidumper; + return (uefidumper.dump(buffer, UString(argv[1])) != U_SUCCESS); + } + + // Create model and ffsParser + TreeModel model; + FfsParser ffsParser(&model); + // Parse input buffer + result = ffsParser.parse(buffer); + if (result) + return (int)result; + + ffsParser.outputInfo(); + + // Create ffsDumper + FfsDumper ffsDumper(&model); + + // Dump only leaf elements, no report or GUID database + if (argc == 3 && !std::strcmp(argv[2], "dump")) { + return (ffsDumper.dump(model.index(0, 0), path + UString(".dump")) != U_SUCCESS); + } + // Dump named GUIDs found in the image, no dump or report + else if (argc == 3 && !std::strcmp(argv[2], "guids")) { + GuidDatabase db = guidDatabaseFromTreeRecursive(&model, model.index(0, 0)); + if (!db.empty()) { + return (int)guidDatabaseExportToFile(path + UString(".guids.csv"), db); + } + } + // Generate report, no dump or GUID database + else if (argc == 3 && !std::strcmp(argv[2], "report")) { + FfsReport ffsReport(&model); + std::vector report = ffsReport.generate(); + if (report.size()) { + std::ofstream file; + file.open((path + UString(".report.txt")).toLocal8Bit()); + for (size_t i = 0; i < report.size(); i++) + file << report[i].toLocal8Bit() << '\n'; + return 0; + } + return 1; + } + // Either default or all mode + else if (argc == 2 || (argc == 3 && !std::strcmp(argv[2], "all"))) { + // Generate report + FfsReport ffsReport(&model); + std::vector report = ffsReport.generate(); + if (report.size()) { + std::ofstream file; + file.open((path + UString(".report.txt")).toLocal8Bit()); + for (size_t i = 0; i < report.size(); i++) + file << report[i].toLocal8Bit() << '\n'; + } + + // Create GUID database + GuidDatabase db = guidDatabaseFromTreeRecursive(&model, model.index(0, 0)); + if (!db.empty()) { + guidDatabaseExportToFile(path + UString(".guids.csv"), db); + } + + // Dump all non-leaf elements, with report and GUID database, default + if (argc == 2) { + return (ffsDumper.dump(model.index(0, 0), path + UString(".dump")) != U_SUCCESS); + } + else if (argc == 3 && !std::strcmp(argv[2], "all")) { // Dump every element with report and GUID database + return (ffsDumper.dump(model.index(0, 0), path + UString(".dump"), FfsDumper::DUMP_ALL) != U_SUCCESS); + } + } + // Dump specific files, without report or GUID database + else { + std::vector inputs, outputs; + std::vector modes; + std::vector sectionTypes; + ReadType readType = READ_INPUT; + for (int i = 2; i < argc; i++) { + const char *arg = argv[i]; + if (!std::strcmp(arg, "-i")) { + readType = READ_INPUT; + continue; + } else if (!std::strcmp(arg, "-o")) { + readType = READ_OUTPUT; + continue; + } else if (!std::strcmp(arg, "-m")) { + readType = READ_MODE; + continue; + } else if (!std::strcmp(arg, "-t")) { + readType = READ_SECTION; + continue; + } + + if (readType == READ_INPUT) { + inputs.push_back(arg); + } else if (readType == READ_OUTPUT) { + outputs.push_back(getAbsPath(arg)); + } else if (readType == READ_MODE) { + if (!std::strcmp(arg, "all")) + modes.push_back(FfsDumper::DUMP_ALL); + else if (!std::strcmp(arg, "body")) + modes.push_back(FfsDumper::DUMP_BODY); + else if (!std::strcmp(arg, "unc_data")) + modes.push_back(FfsDumper::DUMP_UNC_DATA); + else if (!std::strcmp(arg, "header")) + modes.push_back(FfsDumper::DUMP_HEADER); + else if (!std::strcmp(arg, "info")) + modes.push_back(FfsDumper::DUMP_INFO); + else if (!std::strcmp(arg, "file")) + modes.push_back(FfsDumper::DUMP_FILE); + else + return U_INVALID_PARAMETER; + } else if (readType == READ_SECTION) { + char *converted = const_cast(arg); + UINT8 sectionType = (UINT8)std::strtol(arg, &converted, 16); + if (converted == arg) + return U_INVALID_PARAMETER; + sectionTypes.push_back(sectionType); + } + } + if (inputs.empty() || (!outputs.empty() && inputs.size() != outputs.size()) || + (!modes.empty() && inputs.size() != modes.size()) || + (!sectionTypes.empty() && inputs.size() != sectionTypes.size())) + return U_INVALID_PARAMETER; + + USTATUS lastError = U_SUCCESS; + for (size_t i = 0; i < inputs.size(); i++) { + UString outPath = outputs.empty() ? path + UString(".dump") : outputs[i]; + FfsDumper::DumpMode mode = modes.empty() ? FfsDumper::DUMP_ALL : modes[i]; + UINT8 type = sectionTypes.empty() ? FfsDumper::IgnoreSectionType : sectionTypes[i]; + result = ffsDumper.dump(model.index(0, 0), outPath, mode, type, inputs[i]); + if (result) { + std::cout << "Guid " << inputs[i].toLocal8Bit() << " failed with " << result << " code!" << std::endl; + lastError = result; + } + } + + return (int)lastError; + } + // If parameters are different, show version and usage information - std::cout << "UEFIExtract 0.13.0" << std::endl << std::endl - << "Usage: UEFIExtract imagefile - generate report and dump only leaf tree items into .dump folder." << std::endl - << " UEFIExtract imagefile all - generate report and dump all tree items." << std::endl - << " UEFIExtract imagefile dump - only generate dump, no report needed." << std::endl - << " UEFIExtract imagefile report - only generate report, no dump needed." << std::endl - << " UEFIExtract imagefile GUID_1 GUID_2 ... GUID_31 - dump only FFS file(s) with specific GUID(s), without report." << std::endl - << "Return value is a bit mask where 0 at position N means that file with GUID_N was found and unpacked, 1 otherwise." << std::endl; + print_usage(); return 1; -} \ No newline at end of file +} diff --git a/UEFIFind/CMakeLists.txt b/UEFIFind/CMakeLists.txt new file mode 100644 index 0000000..c7f0a8f --- /dev/null +++ b/UEFIFind/CMakeLists.txt @@ -0,0 +1,82 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) + +PROJECT(UEFIFind) + +SET(CMAKE_CXX_STANDARD 11) +SET(CMAKE_CXX_STANDARD_REQUIRED ON) +SET(CMAKE_CXX_EXTENSIONS OFF) + +SET(PROJECT_SOURCES + uefifind_main.cpp + uefifind.cpp + ../common/guiddatabase.cpp + ../common/types.cpp + ../common/filesystem.cpp + ../common/descriptor.cpp + ../common/ffs.cpp + ../common/nvram.cpp + ../common/nvramparser.cpp + ../common/ffsparser.cpp + ../common/fitparser.cpp + ../common/peimage.cpp + ../common/treeitem.cpp + ../common/treemodel.cpp + ../common/utility.cpp + ../common/LZMA/LzmaDecompress.c + ../common/LZMA/SDK/C/Bra.c + ../common/LZMA/SDK/C/Bra86.c + ../common/LZMA/SDK/C/CpuArch.c + ../common/LZMA/SDK/C/LzmaDec.c + ../common/Tiano/EfiTianoDecompress.c + ../common/ustring.cpp + ../common/bstrlib/bstrlib.c + ../common/bstrlib/bstrwrap.cpp + ../common/generated/ami_nvar.cpp + ../common/generated/apple_sysf.cpp + ../common/generated/dell_dvar.cpp + ../common/generated/edk2_vss.cpp + ../common/generated/edk2_vss2.cpp + ../common/generated/edk2_ftw.cpp + ../common/generated/insyde_fdc.cpp + ../common/generated/insyde_fdm.cpp + ../common/generated/ms_slic_marker.cpp + ../common/generated/ms_slic_pubkey.cpp + ../common/generated/phoenix_flm.cpp + ../common/generated/phoenix_evsa.cpp + ../common/generated/intel_acbp_v1.cpp + ../common/generated/intel_acbp_v2.cpp + ../common/generated/intel_keym_v1.cpp + ../common/generated/intel_keym_v2.cpp + ../common/generated/intel_acm.cpp + ../common/kaitai/kaitaistream.cpp + ../common/digest/sha1.c + ../common/digest/sha256.c + ../common/digest/sha512.c + ../common/digest/sm3.c + ../common/zlib/adler32.c + ../common/zlib/compress.c + ../common/zlib/crc32.c + ../common/zlib/deflate.c + ../common/zlib/gzclose.c + ../common/zlib/gzlib.c + ../common/zlib/gzread.c + ../common/zlib/gzwrite.c + ../common/zlib/inflate.c + ../common/zlib/infback.c + ../common/zlib/inftrees.c + ../common/zlib/inffast.c + ../common/zlib/trees.c + ../common/zlib/uncompr.c + ../common/zlib/zutil.c +) + +ADD_EXECUTABLE(UEFIFind ${PROJECT_SOURCES} uefifind.manifest) + +IF(UNIX) + SET_TARGET_PROPERTIES(UEFIFind PROPERTIES OUTPUT_NAME uefifind) +ENDIF() + +INSTALL( + TARGETS UEFIFind + RUNTIME DESTINATION bin +) diff --git a/UEFIFind/meson.build b/UEFIFind/meson.build new file mode 100644 index 0000000..ec5a8aa --- /dev/null +++ b/UEFIFind/meson.build @@ -0,0 +1,16 @@ +executable( + 'UEFIFind', + sources: [ + 'uefifind_main.cpp', + 'uefifind.cpp', + ], + link_with: [ + lzma, + bstrlib, + uefitoolcommon, + ], + dependencies: [ + zlib, + ], + install: true, +) diff --git a/UEFIFind/uefifind.cpp b/UEFIFind/uefifind.cpp index ba6a376..5b2d848 100644 --- a/UEFIFind/uefifind.cpp +++ b/UEFIFind/uefifind.cpp @@ -12,6 +12,9 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. */ #include "uefifind.h" +#include +#include + UEFIFind::UEFIFind() { @@ -27,25 +30,13 @@ UEFIFind::~UEFIFind() model = NULL; } -USTATUS UEFIFind::init(const QString & path) +USTATUS UEFIFind::init(const UString & path) { - USTATUS result; - - fileInfo = QFileInfo(path); - - if (!fileInfo.exists()) + UByteArray buffer; + if (false == readFileIntoBuffer(path, buffer)) return U_FILE_OPEN; - QFile inputFile; - inputFile.setFileName(path); - - if (!inputFile.open(QFile::ReadOnly)) - return U_FILE_OPEN; - - QByteArray buffer = inputFile.readAll(); - inputFile.close(); - - result = ffsParser->parse(buffer); + USTATUS result = ffsParser->parse(buffer); if (result) return result; @@ -53,10 +44,78 @@ USTATUS UEFIFind::init(const QString & path) return U_SUCCESS; } -USTATUS UEFIFind::find(const UINT8 mode, const bool count, const QString & hexPattern, QString & result) +USTATUS UEFIFind::findFileRecursive(const UModelIndex index, const UString & hexPattern, const UINT8 mode, std::set > & files) { - QModelIndex root = model->index(0, 0); - std::set > files; + if (!index.isValid()) + return U_SUCCESS; + + if (hexPattern.isEmpty()) + return U_INVALID_PARAMETER; + + const char *hexPatternRaw = hexPattern.toLocal8Bit(); + std::vector pattern, patternMask; + if (!makePattern(hexPatternRaw, pattern, patternMask)) + return U_INVALID_PARAMETER; + + // Check for "all substrings" pattern + size_t count = 0; + for (size_t i = 0; i < patternMask.size(); i++) + if (patternMask[i] == 0) + count++; + if (count == patternMask.size()) + return U_SUCCESS; + + bool hasChildren = (model->rowCount(index) > 0); + for (int i = 0; i < model->rowCount(index); i++) { + findFileRecursive(index.model()->index(i, index.column(), index), hexPattern, mode, files); + } + + // TODO: handle a case where an item has both compressed and uncompressed bodies + UByteArray data; + if (hasChildren) { + if (mode == SEARCH_MODE_HEADER) + data = model->header(index); + else if (mode == SEARCH_MODE_ALL) + data = model->header(index) + model->body(index); + } + else { + if (mode == SEARCH_MODE_HEADER) + data = model->header(index); + else if (mode == SEARCH_MODE_BODY) + data = model->body(index); + else + data = model->header(index) + model->body(index); + } + + const UINT8 *rawData = reinterpret_cast(data.constData()); + INTN offset = findPattern(pattern.data(), patternMask.data(), pattern.size(), rawData, data.size(), 0); + + // For patterns that cross header|body boundary, skip patterns entirely located in body, since + // children search above has already found them. + if (hasChildren && mode == SEARCH_MODE_ALL && offset >= model->header(index).size()) { + offset = -1; + } + + if (offset >= 0) { + if (model->type(index) != Types::File) { + UModelIndex parentFile = model->findParentOfType(index, Types::File); + if (model->type(index) == Types::Section && model->subtype(index) == EFI_SECTION_FREEFORM_SUBTYPE_GUID) + files.insert(std::pair(parentFile, index)); + else + files.insert(std::pair(parentFile, UModelIndex())); + } + else { + files.insert(std::pair(index, UModelIndex())); + } + } + + return U_SUCCESS; +} + +USTATUS UEFIFind::find(const UINT8 mode, const bool count, const UString & hexPattern, UString & result) +{ + UModelIndex root = model->index(0, 0); + std::set > files; result.clear(); @@ -66,78 +125,24 @@ USTATUS UEFIFind::find(const UINT8 mode, const bool count, const QString & hexPa if (count) { if (!files.empty()) - result.append(QString("%1\n").arg(files.size())); + result += usprintf("%lu\n", files.size()); return U_SUCCESS; } - for (std::set >::const_iterator citer = files.cbegin(); citer != files.cend(); ++citer) { - QByteArray data(16, '\x00'); - std::pair indexes = *citer; + for (std::set >::const_iterator citer = files.begin(); citer != files.end(); ++citer) { + UByteArray data(16, '\x00'); + std::pair indexes = *citer; if (!model->hasEmptyHeader(indexes.first)) data = model->header(indexes.first).left(16); - result.append(guidToUString(*(const EFI_GUID*)data.constData())); + result += guidToUString(readUnaligned((const EFI_GUID*)data.constData())); // Special case of freeform subtype GUID files if (indexes.second.isValid() && model->subtype(indexes.second) == EFI_SECTION_FREEFORM_SUBTYPE_GUID) { - data = model->header(indexes.second).left(sizeof(EFI_FREEFORM_SUBTYPE_GUID_SECTION)); - result.append(" ").append(guidToUString(*(const EFI_GUID*)(data.constData() + sizeof(EFI_COMMON_SECTION_HEADER)))); + data = model->header(indexes.second); + result += UString(" ") + (guidToUString(readUnaligned((const EFI_GUID*)(data.constData() + sizeof(EFI_COMMON_SECTION_HEADER))))); } - result.append("\n"); + result += UString("\n"); } return U_SUCCESS; } - -USTATUS UEFIFind::findFileRecursive(const QModelIndex index, const QString & hexPattern, const UINT8 mode, std::set > & files) -{ - if (!index.isValid()) - return U_SUCCESS; - - if (hexPattern.isEmpty()) - return U_INVALID_PARAMETER; - - // Check for "all substrings" pattern - if (hexPattern.count('.') == hexPattern.length()) - return U_SUCCESS; - - bool hasChildren = (model->rowCount(index) > 0); - for (int i = 0; i < model->rowCount(index); i++) { - findFileRecursive(index.child(i, index.column()), hexPattern, mode, files); - } - - QByteArray data; - if (hasChildren) { - if (mode == SEARCH_MODE_HEADER || mode == SEARCH_MODE_ALL) - data.append(model->header(index)); - } - else { - if (mode == SEARCH_MODE_HEADER) - data.append(model->header(index)); - else if (mode == SEARCH_MODE_BODY) - data.append(model->body(index)); - else - data.append(model->header(index)).append(model->body(index)); - } - - QString hexBody = QString(data.toHex()); - QRegExp regexp = QRegExp(QString(hexPattern), Qt::CaseInsensitive); - INT32 offset = regexp.indexIn(hexBody); - while (offset >= 0) { - if (offset % 2 == 0) { - if (model->type(index) != Types::File) { - QModelIndex ffs = model->findParentOfType(index, Types::File); - if (model->type(index) == Types::Section && model->subtype(index) == EFI_SECTION_FREEFORM_SUBTYPE_GUID) - files.insert(std::pair(ffs, index)); - else - files.insert(std::pair(ffs, QModelIndex())); - } - else - files.insert(std::pair(index, QModelIndex())); - - break; - } - offset = regexp.indexIn(hexBody, offset + 1); - } - - return U_SUCCESS; -} \ No newline at end of file diff --git a/UEFIFind/uefifind.h b/UEFIFind/uefifind.h index 69cd1a5..6b572bb 100644 --- a/UEFIFind/uefifind.h +++ b/UEFIFind/uefifind.h @@ -14,19 +14,15 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #ifndef UEFIFIND_H #define UEFIFIND_H +#include #include -#include -#include -#include -#include -#include -#include -#include - #include "../common/basetypes.h" +#include "../common/ustring.h" +#include "../common/filesystem.h" #include "../common/ffsparser.h" #include "../common/ffs.h" +#include "../common/utility.h" class UEFIFind { @@ -34,16 +30,14 @@ public: explicit UEFIFind(); ~UEFIFind(); - USTATUS init(const QString & path); - USTATUS find(const UINT8 mode, const bool count, const QString & hexPattern, QString & result); + USTATUS init(const UString & path); + USTATUS find(const UINT8 mode, const bool count, const UString & hexPattern, UString & result); private: - USTATUS findFileRecursive(const QModelIndex index, const QString & hexPattern, const UINT8 mode, std::set > & files); - QString guidToQString(const UINT8* guid); + USTATUS findFileRecursive(const UModelIndex index, const UString & hexPattern, const UINT8 mode, std::set > & files); FfsParser* ffsParser; TreeModel* model; - QFileInfo fileInfo; bool initDone; }; diff --git a/UEFIFind/uefifind.manifest b/UEFIFind/uefifind.manifest new file mode 100644 index 0000000..af77ac4 --- /dev/null +++ b/UEFIFind/uefifind.manifest @@ -0,0 +1,8 @@ + + + + + true + + + \ No newline at end of file diff --git a/UEFIFind/uefifind.pro b/UEFIFind/uefifind.pro deleted file mode 100644 index 30b7374..0000000 --- a/UEFIFind/uefifind.pro +++ /dev/null @@ -1,42 +0,0 @@ -QT += core -QT -= gui - -TARGET = UEFIFind -TEMPLATE = app -CONFIG += console -CONFIG -= app_bundle - -SOURCES += uefifind_main.cpp \ - uefifind.cpp \ - ../common/types.cpp \ - ../common/descriptor.cpp \ - ../common/ffs.cpp \ - ../common/nvram.cpp \ - ../common/ffsparser.cpp \ - ../common/peimage.cpp \ - ../common/treeitem.cpp \ - ../common/treemodel.cpp \ - ../common/utility.cpp \ - ../common/LZMA/LzmaDecompress.c \ - ../common/LZMA/SDK/C/LzmaDec.c \ - ../common/Tiano/EfiTianoDecompress.c \ - ../common/ustring.cpp - -HEADERS += uefifind.h \ - ../common/basetypes.h \ - ../common/descriptor.h \ - ../common/gbe.h \ - ../common/me.h \ - ../common/ffs.h \ - ../common/nvram.h \ - ../common/ffsparser.h \ - ../common/peimage.h \ - ../common/types.h \ - ../common/treeitem.h \ - ../common/treemodel.h \ - ../common/utility.h \ - ../common/LZMA/LzmaDecompress.h \ - ../common/Tiano/EfiTianoDecompress.h \ - ../common/ustring.h \ - ../common/ubytearray.h - diff --git a/UEFIFind/uefifind_main.cpp b/UEFIFind/uefifind_main.cpp index a6a991d..8b54118 100644 --- a/UEFIFind/uefifind_main.cpp +++ b/UEFIFind/uefifind_main.cpp @@ -1,6 +1,6 @@ /* uefifind_main.cpp -Copyright (c) 2016, Nikolaj Schlej. All rights reserved. +Copyright (c) 2018, LongSoft. All rights reserved. This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -10,49 +10,77 @@ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. */ -#include #include +#include +#include +#include + +#include "../version.h" +#include "../common/guiddatabase.h" #include "uefifind.h" +void print_usage() +{ + std::cout << "UEFIFind " PROGRAM_VERSION << std::endl << + "Usage: UEFIFind {-h | --help | -v | -version}" << std::endl << + " UEFIFind imagefile {header | body | all} {list | count} pattern" << std::endl << + " UEFIFind imagefile file patternsfile" << std::endl; +} + int main(int argc, char *argv[]) { - QCoreApplication a(argc, argv); - a.setOrganizationName("CodeRush"); - a.setOrganizationDomain("coderush.me"); - a.setApplicationName("UEFIFind"); - UEFIFind w; - UINT8 result; + USTATUS result; + + if (argc == 1) { + print_usage(); + return U_SUCCESS; + } + else if (argc == 2) { + UString arg = argv[1]; + if (arg == UString("-h") || arg == UString("--help")) { + print_usage(); + return U_SUCCESS; + } + else if (arg == UString("-v") || arg == UString("--version")) { + std::cout << PROGRAM_VERSION << std::endl; + return U_SUCCESS; + } + } + else if (argc == 5) { + UString inputArg = argv[1]; + UString modeArg = argv[2]; + UString subModeArg = argv[3]; + UString patternArg = argv[4]; - if (a.arguments().length() == 5) { // Get search mode UINT8 mode; - if (a.arguments().at(1) == QString("header")) + if (modeArg == UString("header")) mode = SEARCH_MODE_HEADER; - else if (a.arguments().at(1) == QString("body")) + else if (modeArg == UString("body")) mode = SEARCH_MODE_BODY; - else if (a.arguments().at(1) == QString("all")) + else if (modeArg == UString("all")) mode = SEARCH_MODE_ALL; else return U_INVALID_PARAMETER; // Get result type bool count; - if (a.arguments().at(2) == QString("list")) + if (subModeArg == UString("list")) count = false; - else if (a.arguments().at(2) == QString("count")) + else if (subModeArg == UString("count")) count = true; else return U_INVALID_PARAMETER; // Parse input file - result = w.init(a.arguments().at(4)); + result = w.init(inputArg); if (result) return result; // Go find the supplied pattern - QString found; - result = w.find(mode, count, a.arguments().at(3), found); + UString found; + result = w.find(mode, count, patternArg, found); if (result) return result; @@ -61,82 +89,93 @@ int main(int argc, char *argv[]) return U_ITEM_NOT_FOUND; // Print result - std::cout << found.toStdString(); + std::cout << found.toLocal8Bit(); return U_SUCCESS; } - else if (a.arguments().length() == 4) { + else if (argc == 4) { + UString inputArg = argv[1]; + UString modeArg = argv[2]; + UString patternArg = argv[3]; + // Get search mode - if (a.arguments().at(1) != QString("file")) + if (modeArg != UString("file")) return U_INVALID_PARAMETER; // Open patterns file - QFileInfo fileInfo(a.arguments().at(2)); - if (!fileInfo.exists()) + if (!isExistOnFs(patternArg)) return U_FILE_OPEN; - QFile patternsFile; - patternsFile.setFileName(a.arguments().at(2)); - if (!patternsFile.open(QFile::ReadOnly)) + std::ifstream patternsFile(patternArg.toLocal8Bit()); + if (!patternsFile) return U_FILE_OPEN; // Parse input file - result = w.init(a.arguments().at(3)); + result = w.init(inputArg); if (result) return result; // Perform searches bool somethingFound = false; - while (!patternsFile.atEnd()) { - QByteArray line = patternsFile.readLine(); + while (!patternsFile.eof()) { + std::string line; + std::getline(patternsFile, line); // Use sharp symbol as commentary - if (line.count() == 0 || line[0] == '#') + if (line.size() == 0 || line[0] == '#') continue; // Split the read line - QList list = line.split(' '); - if (list.count() < 3) { - std::cout << line.constData() << "skipped, too few arguments" << std::endl << std::endl; + std::vector list; + std::string::size_type prev = 0, curr = 0; + while ((curr = line.find(' ', curr)) != std::string::npos) { + std::string substring( line.substr(prev, curr-prev) ); + list.push_back(UString(substring.c_str())); + prev = ++curr; + } + list.push_back(UString(line.substr(prev, curr-prev).c_str())); + + if (list.size() < 3) { + std::cout << line << std::endl << "skipped, too few arguments" << std::endl << std::endl; continue; } // Get search mode UINT8 mode; - if (list.at(0) == QString("header")) + if (list.at(0) == UString("header")) mode = SEARCH_MODE_HEADER; - else if (list.at(0) == QString("body")) + else if (list.at(0) == UString("body")) mode = SEARCH_MODE_BODY; - else if (list.at(0) == QString("all")) + else if (list.at(0) == UString("all")) mode = SEARCH_MODE_ALL; else { - std::cout << line.constData() << "skipped, invalid search mode" << std::endl << std::endl; + std::cout << line << std::endl << "skipped, invalid search mode" << std::endl << std::endl; continue; } // Get result type bool count; - if (list.at(1) == QString("list")) + if (list.at(1) == UString("list")) count = false; - else if (list.at(1) == QString("count")) + else if (list.at(1) == UString("count")) count = true; else { - std::cout << line.constData() << "skipped, invalid result type" << std::endl << std::endl; + std::cout << line << std::endl << "skipped, invalid result type" << std::endl << std::endl; continue; } // Go find the supplied pattern - QString found; + UString found; result = w.find(mode, count, list.at(2), found); if (result) { - std::cout << line.constData() << "skipped, find failed with error " << (UINT32)result << std::endl << std::endl; + std::cout << line << std::endl << "skipped, find failed with error " << (UINT32)result << std::endl << std::endl; continue; } if (found.isEmpty()) { // Nothing is found - std::cout << line.constData() << "nothing found" << std::endl << std::endl; + std::cout << line << std::endl << "nothing found" << std::endl << std::endl; } else { // Print result - std::cout << line.constData() << found.toStdString() << std::endl; + std::cout << line << std::endl << found.toLocal8Bit() << std::endl; somethingFound = true; } } @@ -147,11 +186,7 @@ int main(int argc, char *argv[]) return U_SUCCESS; } - else { - std::cout << "UEFIFind 0.10.6" << std::endl << std::endl << - "Usage: UEFIFind {header | body | all} {list | count} pattern imagefile" << std::endl << - " or UEFIFind file patternsfile imagefile" << std::endl; - return U_INVALID_PARAMETER; - } -} + print_usage(); + return U_INVALID_PARAMETER; +} diff --git a/UEFITool/CMakeLists.txt b/UEFITool/CMakeLists.txt new file mode 100644 index 0000000..363f5c1 --- /dev/null +++ b/UEFITool/CMakeLists.txt @@ -0,0 +1,146 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) + +PROJECT(UEFITool LANGUAGES C CXX) + +SET(CMAKE_CXX_STANDARD 11) +SET(CMAKE_CXX_STANDARD_REQUIRED ON) +SET(CMAKE_CXX_EXTENSIONS OFF) + +FIND_PACKAGE(Qt6 REQUIRED COMPONENTS Widgets) + +SET(PROJECT_FORMS + uefitool.ui + searchdialog.ui + hexviewdialog.ui + gotobasedialog.ui + gotoaddressdialog.ui + ) + +SET(PROJECT_HEADERS + uefitool.h + hexspinbox.h + searchdialog.h + hexviewdialog.h + gotobasedialog.h + gotoaddressdialog.h +) + +SET(PROJECT_SOURCES + icons/uefitool.icns + uefitool.rc + uefitool_main.cpp + uefitool.cpp + searchdialog.cpp + hexviewdialog.cpp + hexlineedit.cpp + ffsfinder.cpp + hexspinbox.cpp + ../common/fitparser.cpp + ../common/guiddatabase.cpp + ../common/nvram.cpp + ../common/nvramparser.cpp + ../common/meparser.cpp + ../common/ffsops.cpp + ../common/types.cpp + ../common/descriptor.cpp + ../common/ffs.cpp + ../common/peimage.cpp + ../common/utility.cpp + ../common/ffsbuilder.cpp + ../common/ffsparser.cpp + ../common/ffsreport.cpp + ../common/treeitem.cpp + ../common/treemodel.cpp + ../common/LZMA/LzmaCompress.c + ../common/LZMA/LzmaDecompress.c + ../common/LZMA/SDK/C/CpuArch.c + ../common/LZMA/SDK/C/Bra.c + ../common/LZMA/SDK/C/Bra86.c + ../common/LZMA/SDK/C/LzFind.c + ../common/LZMA/SDK/C/LzmaDec.c + ../common/LZMA/SDK/C/LzmaEnc.c + ../common/Tiano/EfiTianoDecompress.c + ../common/Tiano/EfiTianoCompress.c + ../common/Tiano/EfiTianoCompressLegacy.c + ../common/ustring.cpp + ../common/digest/sha1.c + ../common/digest/sha256.c + ../common/digest/sha512.c + ../common/digest/sm3.c + ../common/generated/ami_nvar.cpp + ../common/generated/apple_sysf.cpp + ../common/generated/dell_dvar.cpp + ../common/generated/edk2_vss.cpp + ../common/generated/edk2_vss2.cpp + ../common/generated/edk2_ftw.cpp + ../common/generated/insyde_fdc.cpp + ../common/generated/insyde_fdm.cpp + ../common/generated/ms_slic_marker.cpp + ../common/generated/ms_slic_pubkey.cpp + ../common/generated/phoenix_evsa.cpp + ../common/generated/phoenix_flm.cpp + ../common/generated/intel_acbp_v1.cpp + ../common/generated/intel_acbp_v2.cpp + ../common/generated/intel_keym_v1.cpp + ../common/generated/intel_keym_v2.cpp + ../common/generated/intel_acm.cpp + ../common/kaitai/kaitaistream.cpp + ../common/zlib/adler32.c + ../common/zlib/compress.c + ../common/zlib/crc32.c + ../common/zlib/deflate.c + ../common/zlib/gzclose.c + ../common/zlib/gzlib.c + ../common/zlib/gzread.c + ../common/zlib/gzwrite.c + ../common/zlib/inflate.c + ../common/zlib/infback.c + ../common/zlib/inftrees.c + ../common/zlib/inffast.c + ../common/zlib/trees.c + ../common/zlib/uncompr.c + ../common/zlib/zutil.c +) + +QT_ADD_RESOURCES(PROJECT_SOURCES + uefitool.qrc +) + +ADD_DEFINITIONS( + -DU_ENABLE_NVRAM_PARSING_SUPPORT + -DU_ENABLE_ME_PARSING_SUPPORT + -DU_ENABLE_FIT_PARSING_SUPPORT + -DU_ENABLE_GUID_DATABASE_SUPPORT +) + +SET_SOURCE_FILES_PROPERTIES(icons/uefitool.icns PROPERTIES MACOSX_PACKAGE_LOCATION "Resources") + +ADD_EXECUTABLE(UEFITool ${PROJECT_HEADERS} ${PROJECT_FORMS} ${PROJECT_SOURCES}) + +TARGET_INCLUDE_DIRECTORIES(UEFITool PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}") + +TARGET_LINK_LIBRARIES(UEFITool PRIVATE Qt6::Widgets) + +ADD_SUBDIRECTORY(QHexView) +TARGET_LINK_LIBRARIES(UEFITool PRIVATE QHexView) + +SET_TARGET_PROPERTIES(UEFITool PROPERTIES + WIN32_EXECUTABLE ON + MACOSX_BUNDLE ON + MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/Info.plist" + AUTOMOC ON + AUTOUIC ON +) + +IF(UNIX AND (NOT APPLE) AND (NOT CYGWIN)) + SET_TARGET_PROPERTIES(UEFITool PROPERTIES OUTPUT_NAME uefitool) + INSTALL(FILES icons/uefitool_16x16.png DESTINATION share/icons/hicolor/16x16/apps RENAME uefitool.png) + INSTALL(FILES icons/uefitool_32x32.png DESTINATION share/icons/hicolor/32x32/apps RENAME uefitool.png) + INSTALL(FILES icons/uefitool_64x64.png DESTINATION share/icons/hicolor/64x64/apps RENAME uefitool.png) + INSTALL(FILES icons/uefitool_128x128.png DESTINATION share/icons/hicolor/128x128/apps RENAME uefitool.png) + INSTALL(FILES icons/uefitool_256x256.png DESTINATION share/icons/hicolor/256x256/apps RENAME uefitool.png) + INSTALL(FILES icons/uefitool_512x512.png DESTINATION share/icons/hicolor/512x512/apps RENAME uefitool.png) + INSTALL(FILES uefitool.desktop DESTINATION share/applications) +ENDIF() + +INSTALL(TARGETS UEFITool BUNDLE DESTINATION "/Applications" ) diff --git a/UEFITool/Info.plist b/UEFITool/Info.plist new file mode 100644 index 0000000..b63e115 --- /dev/null +++ b/UEFITool/Info.plist @@ -0,0 +1,33 @@ + + + + + CFBundleDocumentTypes + + + CFBundleTypeExtensions + + * + + CFBundleTypeRole + Viewer + LSHandlerRank + None + + + CFBundleExecutable + UEFITool + CFBundleGetInfoString + UEFITool NE + CFBundleIconFile + uefitool + CFBundleIdentifier + me.coderush.UEFITool + CFBundlePackageType + APPL + CFBundleSignature + ???? + NSPrincipalClass + NSApplication + + diff --git a/UEFITool/QHexView/CMakeLists.txt b/UEFITool/QHexView/CMakeLists.txt new file mode 100644 index 0000000..8fbb2a8 --- /dev/null +++ b/UEFITool/QHexView/CMakeLists.txt @@ -0,0 +1,91 @@ +cmake_minimum_required(VERSION 3.13) + +project(QHexView) + +option(QHEXVIEW_BUILD_EXAMPLE "Build Example Application" OFF) +option(QHEXVIEW_USE_QT5 "Enable Qt5 build" OFF) +option(QHEXVIEW_ENABLE_DIALOGS "BuiltIn dialogs" OFF) + +if(QHEXVIEW_USE_QT5) + find_package(Qt5 REQUIRED COMPONENTS Widgets) +else() + find_package(Qt6 COMPONENTS Widgets) + + if(NOT Qt6_FOUND) + find_package(Qt5 REQUIRED COMPONENTS Widgets) + endif() +endif() + +add_library(${PROJECT_NAME} STATIC) + +set_target_properties(${PROJECT_NAME} + PROPERTIES + CXX_STANDARD_REQUIRED YES + CXX_STANDARD 11 + AUTOMOC ON +) + +target_link_libraries(${PROJECT_NAME} + PUBLIC + Qt::Widgets +) + +target_include_directories(${PROJECT_NAME} + PUBLIC + "${PROJECT_SOURCE_DIR}/include" +) + +target_sources(${PROJECT_NAME} + PRIVATE + include/QHexView/model/buffer/qdevicebuffer.h + include/QHexView/model/buffer/qhexbuffer.h + include/QHexView/model/buffer/qmappedfilebuffer.h + include/QHexView/model/buffer/qmemorybuffer.h + include/QHexView/model/buffer/qmemoryrefbuffer.h + include/QHexView/model/commands/hexcommand.h + include/QHexView/model/commands/insertcommand.h + include/QHexView/model/commands/removecommand.h + include/QHexView/model/commands/replacecommand.h + include/QHexView/model/commands/replacecommand.h + include/QHexView/model/qhexcursor.h + include/QHexView/model/qhexdelegate.h + include/QHexView/model/qhexdocument.h + include/QHexView/model/qhexmetadata.h + include/QHexView/model/qhexoptions.h + include/QHexView/model/qhexutils.h + include/QHexView/qhexview.h + + PRIVATE + src/model/commands/hexcommand.cpp + src/model/commands/insertcommand.cpp + src/model/commands/removecommand.cpp + src/model/commands/replacecommand.cpp + src/model/buffer/qdevicebuffer.cpp + src/model/buffer/qhexbuffer.cpp + src/model/buffer/qmemorybuffer.cpp + src/model/buffer/qmemoryrefbuffer.cpp + src/model/buffer/qmappedfilebuffer.cpp + src/model/qhexdelegate.cpp + src/model/qhexutils.cpp + src/model/qhexcursor.cpp + src/model/qhexmetadata.cpp + src/model/qhexdocument.cpp + src/qhexview.cpp +) + +if(QHEXVIEW_ENABLE_DIALOGS) + target_sources(${PROJECT_NAME} + PRIVATE + include/QHexView/dialogs/hexfinddialog.h + src/dialogs/hexfinddialog.cpp + ) + + target_compile_definitions(${PROJECT_NAME} + PUBLIC + QHEXVIEW_ENABLE_DIALOGS + ) +endif() + +if(QHEXVIEW_BUILD_EXAMPLE) + add_subdirectory(example) +endif() diff --git a/UEFITool/QHexView/LICENSE b/UEFITool/QHexView/LICENSE new file mode 100644 index 0000000..d48dcab --- /dev/null +++ b/UEFITool/QHexView/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2014 Dax89 + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/UEFITool/QHexView/include/QHexView/dialogs/hexfinddialog.h b/UEFITool/QHexView/include/QHexView/dialogs/hexfinddialog.h new file mode 100644 index 0000000..d041db9 --- /dev/null +++ b/UEFITool/QHexView/include/QHexView/dialogs/hexfinddialog.h @@ -0,0 +1,56 @@ +#pragma once + +#include +#include + +class QRegularExpressionValidator; +class QDoubleValidator; +class QIntValidator; +class QHexView; + +class HexFindDialog: public QDialog { + Q_OBJECT + +public: + enum class Type { Find, Replace }; + +public: + explicit HexFindDialog(HexFindDialog::Type type = Type::Find, + QHexView* parent = nullptr); + QHexView* hexView() const; + +private Q_SLOTS: + void updateFindOptions(int); + void validateActions(); + void replace(); + void find(); + +private: + bool prepareOptions(QString& q, QHexFindMode& mode, QHexFindDirection& fd); + bool validateIntRange(uint v) const; + void checkResult(const QString& q, qint64 offset, QHexFindDirection fd); + void prepareTextMode(QLayout* l); + void prepareHexMode(QLayout* l); + void prepareIntMode(QLayout* l); + void prepareFloatMode(QLayout* l); + +private: + QRegularExpressionValidator *m_hexvalidator, *m_hexpvalidator; + QDoubleValidator* m_dblvalidator; + QIntValidator* m_intvalidator; + int m_oldidxbits{-1}, m_oldidxendian{-1}; + unsigned int m_findoptions{0}; + qint64 m_startoffset{-1}; + Type m_type; + +private: + static const QString BUTTONBOX; + static const QString CBFINDMODE; + static const QString LEFIND; + static const QString LEREPLACE; + static const QString HLAYOUT; + static const QString GBOPTIONS; + static const QString RBALL; + static const QString RBFORWARD; + static const QString RBBACKWARD; +}; diff --git a/UEFITool/QHexView/include/QHexView/model/buffer/qdevicebuffer.h b/UEFITool/QHexView/include/QHexView/model/buffer/qdevicebuffer.h new file mode 100644 index 0000000..39fccef --- /dev/null +++ b/UEFITool/QHexView/include/QHexView/model/buffer/qdevicebuffer.h @@ -0,0 +1,24 @@ +#pragma once + +#include + +class QDeviceBuffer: public QHexBuffer { + Q_OBJECT + +public: + explicit QDeviceBuffer(QObject* parent = nullptr); + virtual ~QDeviceBuffer(); + uchar at(qint64 idx) override; + qint64 length() const override; + void insert(qint64 offset, const QByteArray& data) override; + void replace(qint64 offset, const QByteArray& data) override; + void remove(qint64 offset, int length) override; + QByteArray read(qint64 offset, int length) override; + bool read(QIODevice* device) override; + void write(QIODevice* device) override; + qint64 indexOf(const QByteArray& ba, qint64 from) override; + qint64 lastIndexOf(const QByteArray& ba, qint64 from) override; + +protected: + QIODevice* m_device{nullptr}; +}; diff --git a/UEFITool/QHexView/include/QHexView/model/buffer/qhexbuffer.h b/UEFITool/QHexView/include/QHexView/model/buffer/qhexbuffer.h new file mode 100644 index 0000000..0c6424f --- /dev/null +++ b/UEFITool/QHexView/include/QHexView/model/buffer/qhexbuffer.h @@ -0,0 +1,29 @@ +#pragma once + +#include +#include + +class QHexBuffer: public QObject { + Q_OBJECT + +public: + explicit QHexBuffer(QObject* parent = nullptr); + bool isEmpty() const; + +public: + virtual uchar at(qint64 idx); + virtual bool accept(qint64 idx) const; + virtual void replace(qint64 offset, const QByteArray& data); + virtual void read(char* data, int size); + virtual void read(const QByteArray& ba); + +public: + virtual qint64 length() const = 0; + virtual void insert(qint64 offset, const QByteArray& data) = 0; + virtual void remove(qint64 offset, int length) = 0; + virtual QByteArray read(qint64 offset, int length) = 0; + virtual bool read(QIODevice* iodevice) = 0; + virtual void write(QIODevice* iodevice) = 0; + virtual qint64 indexOf(const QByteArray& ba, qint64 from) = 0; + virtual qint64 lastIndexOf(const QByteArray& ba, qint64 from) = 0; +}; diff --git a/UEFITool/QHexView/include/QHexView/model/buffer/qmappedfilebuffer.h b/UEFITool/QHexView/include/QHexView/model/buffer/qmappedfilebuffer.h new file mode 100644 index 0000000..f4f9239 --- /dev/null +++ b/UEFITool/QHexView/include/QHexView/model/buffer/qmappedfilebuffer.h @@ -0,0 +1,20 @@ +#pragma once + +#include + +class QMappedFileBuffer: public QDeviceBuffer { +public: + explicit QMappedFileBuffer(QObject* parent = nullptr); + virtual ~QMappedFileBuffer(); + +public: + QByteArray read(qint64 offset, int length) override; + bool read(QIODevice* iodevice) override; + void write(QIODevice* iodevice) override; + +private: + void remap(); + +private: + uchar* m_mappeddata{nullptr}; +}; diff --git a/UEFITool/QHexView/include/QHexView/model/buffer/qmemorybuffer.h b/UEFITool/QHexView/include/QHexView/model/buffer/qmemorybuffer.h new file mode 100644 index 0000000..b8f4c5b --- /dev/null +++ b/UEFITool/QHexView/include/QHexView/model/buffer/qmemorybuffer.h @@ -0,0 +1,22 @@ +#pragma once + +#include + +class QMemoryBuffer: public QHexBuffer { + Q_OBJECT + +public: + explicit QMemoryBuffer(QObject* parent = nullptr); + uchar at(qint64 idx) override; + qint64 length() const override; + void insert(qint64 offset, const QByteArray& data) override; + void remove(qint64 offset, int length) override; + QByteArray read(qint64 offset, int length) override; + bool read(QIODevice* device) override; + void write(QIODevice* device) override; + qint64 indexOf(const QByteArray& ba, qint64 from) override; + qint64 lastIndexOf(const QByteArray& ba, qint64 from) override; + +private: + QByteArray m_buffer; +}; diff --git a/UEFITool/QHexView/include/QHexView/model/buffer/qmemoryrefbuffer.h b/UEFITool/QHexView/include/QHexView/model/buffer/qmemoryrefbuffer.h new file mode 100644 index 0000000..d1f29b5 --- /dev/null +++ b/UEFITool/QHexView/include/QHexView/model/buffer/qmemoryrefbuffer.h @@ -0,0 +1,12 @@ +#pragma once + +#include + +class QMemoryRefBuffer: public QDeviceBuffer { + Q_OBJECT + +public: + explicit QMemoryRefBuffer(QObject* parent = nullptr); + bool read(QIODevice* device) override; + void write(QIODevice* device) override; +}; diff --git a/UEFITool/QHexView/include/QHexView/model/commands/hexcommand.h b/UEFITool/QHexView/include/QHexView/model/commands/hexcommand.h new file mode 100644 index 0000000..16637f4 --- /dev/null +++ b/UEFITool/QHexView/include/QHexView/model/commands/hexcommand.h @@ -0,0 +1,19 @@ +#pragma once + +#include +#include + +class QHexDocument; + +class HexCommand: public QUndoCommand { +public: + HexCommand(QHexBuffer* buffer, QHexDocument* document, + QUndoCommand* parent = nullptr); + +protected: + QHexDocument* m_hexdocument; + QHexBuffer* m_buffer; + qint64 m_offset; + int m_length; + QByteArray m_data; +}; diff --git a/UEFITool/QHexView/include/QHexView/model/commands/insertcommand.h b/UEFITool/QHexView/include/QHexView/model/commands/insertcommand.h new file mode 100644 index 0000000..971a4d9 --- /dev/null +++ b/UEFITool/QHexView/include/QHexView/model/commands/insertcommand.h @@ -0,0 +1,11 @@ +#pragma once + +#include + +class InsertCommand: public HexCommand { +public: + InsertCommand(QHexBuffer* buffer, QHexDocument* document, qint64 offset, + const QByteArray& data, QUndoCommand* parent = nullptr); + void undo() override; + void redo() override; +}; diff --git a/UEFITool/QHexView/include/QHexView/model/commands/removecommand.h b/UEFITool/QHexView/include/QHexView/model/commands/removecommand.h new file mode 100644 index 0000000..a1bf13b --- /dev/null +++ b/UEFITool/QHexView/include/QHexView/model/commands/removecommand.h @@ -0,0 +1,11 @@ +#pragma once + +#include + +class RemoveCommand: public HexCommand { +public: + RemoveCommand(QHexBuffer* buffer, QHexDocument* document, qint64 offset, + int length, QUndoCommand* parent = nullptr); + void undo() override; + void redo() override; +}; diff --git a/UEFITool/QHexView/include/QHexView/model/commands/replacecommand.h b/UEFITool/QHexView/include/QHexView/model/commands/replacecommand.h new file mode 100644 index 0000000..13912d7 --- /dev/null +++ b/UEFITool/QHexView/include/QHexView/model/commands/replacecommand.h @@ -0,0 +1,14 @@ +#pragma once + +#include + +class ReplaceCommand: public HexCommand { +public: + ReplaceCommand(QHexBuffer* buffer, QHexDocument* document, qint64 offset, + const QByteArray& data, QUndoCommand* parent = nullptr); + void undo() override; + void redo() override; + +private: + QByteArray m_olddata; +}; diff --git a/UEFITool/QHexView/include/QHexView/model/qhexcursor.h b/UEFITool/QHexView/include/QHexView/model/qhexcursor.h new file mode 100644 index 0000000..3651398 --- /dev/null +++ b/UEFITool/QHexView/include/QHexView/model/qhexcursor.h @@ -0,0 +1,73 @@ +#pragma once + +#include +#include +#include + +class QHexView; + +class QHexCursor: public QObject { + Q_OBJECT + +public: + enum class Mode { Overwrite, Insert }; + +private: + explicit QHexCursor(const QHexOptions* options, QHexView* parent = nullptr); + +public: + QHexView* hexView() const; + Mode mode() const; + qint64 line() const; + qint64 column() const; + qint64 offset() const; + qint64 address() const; + quint64 lineAddress() const; + qint64 selectionStartOffset() const; + qint64 selectionEndOffset() const; + qint64 selectionLength() const; + QHexPosition position() const; + QHexPosition selectionStart() const; + QHexPosition selectionEnd() const; + QByteArray selectedBytes() const; + bool hasSelection() const; + bool isSelected(qint64 line, qint64 column) const; + void setMode(Mode m); + void move(qint64 offset); + void move(qint64 line, qint64 column); + void move(QHexPosition pos); + void select(qint64 offset); + void select(qint64 line, qint64 column); + void select(QHexPosition pos); + void selectSize(qint64 length); + qint64 replace(const QVariant& oldvalue, const QVariant& newvalue, + qint64 offset, QHexFindMode mode = QHexFindMode::Text, + unsigned int options = QHexFindOptions::None, + QHexFindDirection fd = QHexFindDirection::Forward) const; + qint64 find(const QVariant& value, qint64 offset, + QHexFindMode mode = QHexFindMode::Text, + unsigned int options = QHexFindOptions::None, + QHexFindDirection fd = QHexFindDirection::Forward) const; + qint64 positionToOffset(QHexPosition pos) const; + QHexPosition offsetToPosition(qint64 offset) const; + +public Q_SLOTS: + void cut(bool hex = false); + void copy(bool hex = false) const; + void paste(bool hex = false); + void selectAll(); + void removeSelection(); + void clearSelection(); + void switchMode(); + +Q_SIGNALS: + void positionChanged(); + void modeChanged(); + +private: + const QHexOptions* m_options; + Mode m_mode{Mode::Overwrite}; + QHexPosition m_position{}, m_selection{}; + + friend class QHexView; +}; diff --git a/UEFITool/QHexView/include/QHexView/model/qhexdelegate.h b/UEFITool/QHexView/include/QHexView/model/qhexdelegate.h new file mode 100644 index 0000000..c698589 --- /dev/null +++ b/UEFITool/QHexView/include/QHexView/model/qhexdelegate.h @@ -0,0 +1,30 @@ +#pragma once + +#include +#include +#include + +class QHexView; + +class QHexDelegate: public QObject { + Q_OBJECT + +public: + explicit QHexDelegate(QObject* parent = nullptr); + virtual ~QHexDelegate() = default; + virtual QString addressHeader(const QHexView* hexview) const; + virtual QString hexHeader(const QHexView* hexview) const; + virtual QString asciiHeader(const QHexView* hexview) const; + virtual void renderAddress(quint64 address, QTextCharFormat& cf, + const QHexView* hexview) const; + virtual void renderHeader(QTextBlockFormat& bf, + const QHexView* hexview) const; + virtual void renderHeaderPart(const QString& s, QHexArea area, + QTextCharFormat& cf, + const QHexView* hexview) const; + virtual bool render(quint64 offset, quint8 b, QTextCharFormat& outcf, + const QHexView* hexview) const; + virtual bool paintSeparator(QPainter* painter, QLineF line, + const QHexView* hexview) const; + virtual void paint(QPainter* painter, const QHexView* hexview) const; +}; diff --git a/UEFITool/QHexView/include/QHexView/model/qhexdocument.h b/UEFITool/QHexView/include/QHexView/model/qhexdocument.h new file mode 100644 index 0000000..30f9d99 --- /dev/null +++ b/UEFITool/QHexView/include/QHexView/model/qhexdocument.h @@ -0,0 +1,102 @@ +#pragma once + +#include +#include +#include + +class QHexCursor; + +class QHexDocument: public QObject { + Q_OBJECT + +public: + enum class ChangeReason { Insert, Remove, Replace }; + enum class FindDirection { Forward, Backward }; + Q_ENUM(ChangeReason); + Q_ENUM(FindDirection); + +private: + explicit QHexDocument(QHexBuffer* buffer, QObject* parent = nullptr); + bool accept(qint64 idx) const; + +public: + bool isEmpty() const; + bool isModified() const; + bool canUndo() const; + bool canRedo() const; + void setData(const QByteArray& ba); + void setData(QHexBuffer* buffer); + qint64 length() const; + qint64 indexOf(const QByteArray& ba, qint64 from = 0); + qint64 lastIndexOf(const QByteArray& ba, qint64 from = 0); + QByteArray read(qint64 offset, int len = 0) const; + uchar at(int offset) const; + +public Q_SLOTS: + void clearModified(); + void undo(); + void redo(); + void insert(qint64 offset, uchar b); + void replace(qint64 offset, uchar b); + void insert(qint64 offset, const QByteArray& data); + void replace(qint64 offset, const QByteArray& data); + void remove(qint64 offset, int len); + bool saveTo(QIODevice* device); + +public: + template + static QHexDocument* fromDevice(QIODevice* iodevice, + QObject* parent = nullptr); + template + static QHexDocument* fromMemory(char* data, int size, + QObject* parent = nullptr); + template + static QHexDocument* fromMemory(const QByteArray& ba, + QObject* parent = nullptr); + static QHexDocument* fromBuffer(QHexBuffer* buffer, + QObject* parent = nullptr); + static QHexDocument* fromLargeFile(QString filename, + QObject* parent = nullptr); + static QHexDocument* fromMappedFile(QString filename, + QObject* parent = nullptr); + static QHexDocument* fromFile(QString filename, QObject* parent = nullptr); + static QHexDocument* create(QObject* parent = nullptr); + +Q_SIGNALS: + void modifiedChanged(bool modified); + void canUndoChanged(bool canundo); + void canRedoChanged(bool canredo); + void dataChanged(const QByteArray& data, quint64 offset, + QHexDocument::ChangeReason reason); + void changed(); + void reset(); + +private: + QHexBuffer* m_buffer; + QUndoStack m_undostack; + + friend class QHexView; +}; + +template +QHexDocument* QHexDocument::fromDevice(QIODevice* iodevice, QObject* parent) { + QHexBuffer* hexbuffer = new T(parent); + if(Owned) + iodevice->setParent(hexbuffer); + return hexbuffer->read(iodevice) ? new QHexDocument(hexbuffer, parent) + : nullptr; +} + +template +QHexDocument* QHexDocument::fromMemory(char* data, int size, QObject* parent) { + QHexBuffer* hexbuffer = new T(); + hexbuffer->read(data, size); + return new QHexDocument(hexbuffer, parent); +} + +template +QHexDocument* QHexDocument::fromMemory(const QByteArray& ba, QObject* parent) { + QHexBuffer* hexbuffer = new T(); + hexbuffer->read(ba); + return new QHexDocument(hexbuffer, parent); +} diff --git a/UEFITool/QHexView/include/QHexView/model/qhexmetadata.h b/UEFITool/QHexView/include/QHexView/model/qhexmetadata.h new file mode 100644 index 0000000..f4a1517 --- /dev/null +++ b/UEFITool/QHexView/include/QHexView/model/qhexmetadata.h @@ -0,0 +1,92 @@ +#pragma once + +#include +#include +#include +#include +#include +#include + +struct QHexMetadataItem { + qint64 begin, end; + QColor foreground, background; + QString comment; +}; + +using QHexMetadataLine = QList; + +class QHexMetadata: public QObject { + Q_OBJECT + +private: + using ClearMetadataCallback = std::function; + +private: + explicit QHexMetadata(const QHexOptions* options, + QObject* parent = nullptr); + +public: + const QHexMetadataLine* find(qint64 line) const; + QString getComment(qint64 line, qint64 column) const; + void removeMetadata(qint64 line); + void removeBackground(qint64 line); + void removeForeground(qint64 line); + void removeComments(qint64 line); + void unhighlight(qint64 line); + void clear(); + +public: + inline void setMetadata(qint64 begin, qint64 end, const QColor& fgcolor, + const QColor& bgcolor, const QString& comment) { + this->setMetadata({begin, end, fgcolor, bgcolor, comment}); + } + + inline void setForeground(qint64 begin, qint64 end, const QColor& fgcolor) { + this->setMetadata(begin, end, fgcolor, QColor(), QString()); + } + + inline void setBackground(qint64 begin, qint64 end, const QColor& bgcolor) { + this->setMetadata(begin, end, QColor(), bgcolor, QString()); + } + + inline void setComment(qint64 begin, qint64 end, const QString& comment) { + this->setMetadata(begin, end, QColor(), QColor(), comment); + }; + + inline void setMetadataSize(qint64 begin, qint64 length, + const QColor& fgcolor, const QColor& bgcolor, + const QString& comment) { + this->setMetadata({begin, begin + length, fgcolor, bgcolor, comment}); + } + + inline void setForegroundSize(qint64 begin, qint64 length, + const QColor& fgcolor) { + this->setForeground(begin, begin + length, fgcolor); + } + + inline void setBackgroundSize(qint64 begin, qint64 length, + const QColor& bgcolor) { + this->setBackground(begin, begin + length, bgcolor); + } + + inline void setCommentSize(qint64 begin, qint64 length, + const QString& comment) { + this->setComment(begin, begin + length, comment); + }; + +private: + void copy(const QHexMetadata* metadata); + void clearMetadata(qint64 line, ClearMetadataCallback&& cb); + void setMetadata(const QHexMetadataItem& mi); + void invalidate(); + +Q_SIGNALS: + void changed(); + void cleared(); + +private: + QHash m_metadata; + const QHexOptions* m_options; + + friend class QHexView; +}; diff --git a/UEFITool/QHexView/include/QHexView/model/qhexoptions.h b/UEFITool/QHexView/include/QHexView/model/qhexoptions.h new file mode 100644 index 0000000..07a2a3a --- /dev/null +++ b/UEFITool/QHexView/include/QHexView/model/qhexoptions.h @@ -0,0 +1,56 @@ +#pragma once + +#include +#include +#include + +namespace QHexFlags { + +enum : unsigned int { + None = (1 << 0), + HSeparator = (1 << 1), + VSeparator = (1 << 2), + StyledHeader = (1 << 3), + StyledAddress = (1 << 4), + NoHeader = (1 << 5), + HighlightAddress = (1 << 6), + HighlightColumn = (1 << 7), + + Separators = HSeparator | VSeparator, + Styled = StyledHeader | StyledAddress, +}; + +} + +struct QHexColor { + QColor foreground; + QColor background; +}; + +struct QHexOptions { + // Appearance + QChar unprintablechar{'.'}; + QChar invalidchar{'?'}; + QString addresslabel{""}; + QString hexlabel; + QString asciilabel; + quint64 baseaddress{0}; + unsigned int flags{QHexFlags::None}; + unsigned int linelength{0x10}; + unsigned int addresswidth{0}; + unsigned int grouplength{1}; + int scrollsteps{1}; + + // Colors & Styles + QHash bytecolors; + QColor linealternatebackground; + QColor linebackground; + QColor headercolor; + QColor commentcolor; + QColor separatorcolor; + + // Misc + bool copybreak{true}; + + inline bool hasFlag(unsigned int flag) const { return flags & flag; } +}; diff --git a/UEFITool/QHexView/include/QHexView/model/qhexutils.h b/UEFITool/QHexView/include/QHexView/model/qhexutils.h new file mode 100644 index 0000000..b591479 --- /dev/null +++ b/UEFITool/QHexView/include/QHexView/model/qhexutils.h @@ -0,0 +1,66 @@ +#pragma once + +#include +#include +#include +#include + +struct QHexOptions; +class QHexView; + +namespace QHexFindOptions { + +enum : unsigned int { + None = (1 << 0), + CaseSensitive = (1 << 1), + Int8 = (1 << 2), + Int16 = (1 << 3), + Int32 = (1 << 4), + Int64 = (1 << 5), + Float = (1 << 6), + Double = (1 << 7), + + BigEndian = (1 << 11), +}; + +} + +enum class QHexFindMode { Text, Hex, Int, Float }; +enum class QHexFindDirection { All, Forward, Backward }; +enum class QHexArea { Header, Address, Hex, Ascii, Extra }; + +struct QHexPosition { + qint64 line; + qint64 column; + static inline QHexPosition invalid() { return {-1, -1}; } + inline bool isValid() const { return line >= 0 && column >= 0; } + inline bool operator==(const QHexPosition& rhs) const { + return (line == rhs.line) && (column == rhs.column); + } + inline bool operator!=(const QHexPosition& rhs) const { + return (line != rhs.line) || (column != rhs.column); + } +}; + +namespace QHexUtils { + +bool isHex(char ch); +QByteArray toHex(const QByteArray& ba, char sep); +QByteArray toHex(const QByteArray& ba); +qint64 positionToOffset(const QHexOptions* options, QHexPosition pos); +QHexPosition offsetToPosition(const QHexOptions* options, qint64 offset); +bool checkPattern(QString pattern); + +QPair find(const QHexView* hexview, QVariant value, + qint64 startoffset = 0, + QHexFindMode mode = QHexFindMode::Text, + unsigned int options = QHexFindOptions::None, + QHexFindDirection fd = QHexFindDirection::Forward); + +QPair +replace(const QHexView* hexview, QVariant oldvalue, QVariant newvalue, + qint64 startoffset = 0, QHexFindMode mode = QHexFindMode::Text, + unsigned int options = QHexFindOptions::None, + QHexFindDirection fd = QHexFindDirection::Forward); + +} // namespace QHexUtils diff --git a/UEFITool/QHexView/include/QHexView/qhexview.h b/UEFITool/QHexView/include/QHexView/qhexview.h new file mode 100644 index 0000000..0e3c8c8 --- /dev/null +++ b/UEFITool/QHexView/include/QHexView/qhexview.h @@ -0,0 +1,184 @@ +#pragma once + +#define QHEXVIEW_VERSION 5.0 + +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(QHEXVIEW_ENABLE_DIALOGS) +class HexFindDialog; +#endif + +class QHexView: public QAbstractScrollArea { + Q_OBJECT + +public: + enum class CopyMode { Visual, HexArraySquare, HexArrayCurly, HexArrayChar }; + Q_ENUM(CopyMode); + +public: + explicit QHexView(QWidget* parent = nullptr); + QRectF headerRect() const; + QRectF addressRect() const; + QRectF hexRect() const; + QRectF asciiRect() const; + QHexDocument* hexDocument() const; + QHexCursor* hexCursor() const; + const QHexMetadata* hexMetadata() const; + QHexOptions options() const; + QColor getReadableColor(QColor c) const; + QByteArray selectedBytes() const; + QByteArray getLine(qint64 line) const; + unsigned int addressWidth() const; + unsigned int lineLength() const; + bool isModified() const; + bool canUndo() const; + bool canRedo() const; + quint64 offset() const; + quint64 address() const; + QHexPosition positionFromOffset(quint64 offset) const; + QHexPosition positionFromAddress(quint64 address) const; + QHexPosition position() const; + QHexPosition selectionStart() const; + QHexPosition selectionEnd() const; + quint64 selectionStartOffset() const; + quint64 selectionEndOffset() const; + quint64 baseAddress() const; + quint64 lines() const; + qint64 replace(const QVariant& oldvalue, const QVariant& newvalue, + qint64 offset, QHexFindMode mode = QHexFindMode::Text, + unsigned int options = QHexFindOptions::None, + QHexFindDirection fd = QHexFindDirection::Forward) const; + qint64 find(const QVariant& value, qint64 offset, + QHexFindMode mode = QHexFindMode::Text, + unsigned int options = QHexFindOptions::None, + QHexFindDirection fd = QHexFindDirection::Forward) const; + void setOptions(const QHexOptions& options); + void setBaseAddress(quint64 baseaddress); + void setDelegate(QHexDelegate* rd); + void setDocument(QHexDocument* doc); + void setData(const QByteArray& ba); + void setData(QHexBuffer* buffer); + void setCursorMode(QHexCursor::Mode mode); + void setByteColor(quint8 b, QHexColor c); + void setByteForeground(quint8 b, QColor c); + void setByteBackground(quint8 b, QColor c); + void setMetadata(qint64 begin, qint64 end, const QColor& fgcolor, + const QColor& bgcolor, const QString& comment); + void setForeground(qint64 begin, qint64 end, const QColor& fgcolor); + void setBackground(qint64 begin, qint64 end, const QColor& bgcolor); + void setComment(qint64 begin, qint64 end, const QString& comment); + void setMetadataSize(qint64 begin, qint64 length, const QColor& fgcolor, + const QColor& bgcolor, const QString& comment); + void setForegroundSize(qint64 begin, qint64 length, const QColor& fgcolor); + void setBackgroundSize(qint64 begin, qint64 length, const QColor& bgcolor); + void setCommentSize(qint64 begin, qint64 length, const QString& comment); + void removeMetadata(qint64 line); + void removeBackground(qint64 line); + void removeForeground(qint64 line); + void removeComments(qint64 line); + void unhighlight(qint64 line); + void clearMetadata(); + +public Q_SLOTS: +#if defined(QHEXVIEW_ENABLE_DIALOGS) + void showFind(); + void showReplace(); +#endif + void undo(); + void redo(); + void cut(bool hex = false); + void copyAs(CopyMode mode = CopyMode::Visual) const; + void copy(bool hex = false) const; + void paste(bool hex = false); + void clearModified(); + void selectAll(); + void removeSelection(); + void switchMode(); + void setAddressWidth(unsigned int w); + void setLineLength(unsigned int l); + void setGroupLength(unsigned int l); + void setScrollSteps(int scrollsteps); + void setReadOnly(bool r); + void setAutoWidth(bool r); + +private: + void paint(QPainter* painter) const; + void checkOptions(); + void checkState(); + void checkAndUpdate(bool calccolumns = false); + void calcColumns(); + void ensureVisible(); + void drawSeparators(QPainter* p) const; + void drawHeader(QTextCursor& c) const; + void drawDocument(QTextCursor& c) const; + QTextCharFormat drawFormat(QTextCursor& c, quint8 b, const QString& s, + QHexArea area, qint64 line, qint64 column, + bool applyformat) const; + unsigned int calcAddressWidth() const; + int visibleLines(bool absolute = false) const; + qint64 getLastColumn(qint64 line) const; + qint64 lastLine() const; + qreal getNCellsWidth(int n) const; + qreal hexColumnWidth() const; + qreal hexColumnX() const; + qreal asciiColumnX() const; + qreal endColumnX() const; + qreal cellWidth() const; + qreal lineHeight() const; + qint64 positionFromLineCol(qint64 line, qint64 col) const; + QHexPosition positionFromPoint(QPoint pt) const; + QPoint absolutePoint(QPoint pt) const; + QHexArea areaFromPoint(QPoint pt) const; + void moveNext(bool select = false); + void movePrevious(bool select = false); + bool keyPressMove(QKeyEvent* e); + bool keyPressTextInput(QKeyEvent* e); + bool keyPressAction(QKeyEvent* e); + +protected: + bool event(QEvent* e) override; + void showEvent(QShowEvent* e) override; + void paintEvent(QPaintEvent*) override; + void resizeEvent(QResizeEvent* e) override; + void focusInEvent(QFocusEvent* e) override; + void focusOutEvent(QFocusEvent* e) override; + void mousePressEvent(QMouseEvent* e) override; + void mouseMoveEvent(QMouseEvent* e) override; + void wheelEvent(QWheelEvent* e) override; + void keyPressEvent(QKeyEvent* e) override; + +private: + static QString reduced(const QString& s, int maxlen); + static bool isColorLight(QColor c); + +Q_SIGNALS: + void dataChanged(const QByteArray& data, quint64 offset, + QHexDocument::ChangeReason reason); + void modifiedChanged(bool modified); + void positionChanged(); + void modeChanged(); + +private: + bool m_readonly{false}, m_writing{false}, m_autowidth{false}; + QHexArea m_currentarea{QHexArea::Ascii}; + QList m_hexcolumns; + QFontMetricsF m_fontmetrics; + QHexOptions m_options; + QHexCursor* m_hexcursor{nullptr}; + QHexDocument* m_hexdocument{nullptr}; + QHexMetadata* m_hexmetadata{nullptr}; + QHexDelegate* m_hexdelegate{nullptr}; +#if defined(QHEXVIEW_ENABLE_DIALOGS) + HexFindDialog *m_hexdlgfind{nullptr}, *m_hexdlgreplace{nullptr}; +#endif + + friend class QHexDelegate; + friend class QHexCursor; +}; diff --git a/UEFITool/QHexView/src/dialogs/hexfinddialog.cpp b/UEFITool/QHexView/src/dialogs/hexfinddialog.cpp new file mode 100644 index 0000000..ce42092 --- /dev/null +++ b/UEFITool/QHexView/src/dialogs/hexfinddialog.cpp @@ -0,0 +1,418 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +const QString HexFindDialog::BUTTONBOX = "qhexview_buttonbox"; +const QString HexFindDialog::CBFINDMODE = "qhexview_cbfindmode"; +const QString HexFindDialog::LEFIND = "qhexview_lefind"; +const QString HexFindDialog::LEREPLACE = "qhexview_lereplace"; +const QString HexFindDialog::HLAYOUT = "qhexview_hlayout"; +const QString HexFindDialog::GBOPTIONS = "qhexview_gboptions"; +const QString HexFindDialog::RBALL = "qhexview_rball"; +const QString HexFindDialog::RBFORWARD = "qhexview_rbforward"; +const QString HexFindDialog::RBBACKWARD = "qhexview_rbbackward"; + +HexFindDialog::HexFindDialog(Type type, QHexView* parent) + : QDialog{parent}, m_type{type} { + m_hexvalidator = new QRegularExpressionValidator( + QRegularExpression{"[0-9A-Fa-f ]+"}, this); + m_hexpvalidator = new QRegularExpressionValidator( + QRegularExpression{"[0-9A-Fa-f \\?]+"}, this); + m_dblvalidator = new QDoubleValidator(this); + m_intvalidator = new QIntValidator(this); + + this->setWindowTitle(type == Type::Replace ? tr("Replace...") + : tr("Find...")); + + auto* vlayout = new QVBoxLayout(this); + auto* gridlayout = new QGridLayout(); + + auto* cbfindmode = new QComboBox(this); + cbfindmode->setObjectName(HexFindDialog::CBFINDMODE); + cbfindmode->addItem("Text", static_cast(QHexFindMode::Text)); + cbfindmode->addItem("Hex", static_cast(QHexFindMode::Hex)); + cbfindmode->addItem("Int", static_cast(QHexFindMode::Int)); + cbfindmode->addItem("Float", static_cast(QHexFindMode::Float)); + + QLineEdit *lereplace = nullptr, *lefind = new QLineEdit(this); + lefind->setObjectName(HexFindDialog::LEFIND); + + gridlayout->addWidget(new QLabel(tr("Mode:"), this), 0, 0, Qt::AlignRight); + gridlayout->addWidget(cbfindmode, 0, 1); + gridlayout->addWidget(new QLabel(tr("Find:"), this), 1, 0, Qt::AlignRight); + gridlayout->addWidget(lefind, 1, 1); + + if(type == Type::Replace) { + lereplace = new QLineEdit(this); + lereplace->setObjectName(HexFindDialog::LEREPLACE); + + gridlayout->addWidget(new QLabel(tr("Replace:"), this), 2, 0, + Qt::AlignRight); + gridlayout->addWidget(lereplace, 2, 1); + } + + vlayout->addLayout(gridlayout); + + auto* gboptions = new QGroupBox(this); + gboptions->setObjectName(HexFindDialog::GBOPTIONS); + gboptions->setTitle(tr("Options")); + gboptions->setLayout(new QStackedLayout()); + + QGroupBox* gbdirection = new QGroupBox(this); + gbdirection->setTitle(tr("Find direction")); + auto* gbvlayout = new QVBoxLayout(gbdirection); + + auto* rball = new QRadioButton("All", gbdirection); + rball->setObjectName(HexFindDialog::RBALL); + auto* rbforward = new QRadioButton("Forward", gbdirection); + rbforward->setObjectName(HexFindDialog::RBFORWARD); + rbforward->setChecked(true); + auto* rbbackward = new QRadioButton("Backward", gbdirection); + rbbackward->setObjectName(HexFindDialog::RBBACKWARD); + + gbvlayout->addWidget(rball); + gbvlayout->addWidget(rbforward); + gbvlayout->addWidget(rbbackward); + gbvlayout->addSpacerItem( + new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding)); + + auto* hlayout = new QHBoxLayout(); + hlayout->setObjectName(HexFindDialog::HLAYOUT); + hlayout->addWidget(gboptions, 1); + hlayout->addWidget(gbdirection); + vlayout->addLayout(hlayout, 1); + + auto* buttonbox = new QDialogButtonBox(this); + buttonbox->setOrientation(Qt::Horizontal); + + if(type == Type::Replace) + buttonbox->setStandardButtons(QDialogButtonBox::Ok | + QDialogButtonBox::Apply | + QDialogButtonBox::Cancel); + else + buttonbox->setStandardButtons(QDialogButtonBox::Ok | + QDialogButtonBox::Cancel); + + buttonbox->setObjectName(HexFindDialog::BUTTONBOX); + buttonbox->button(QDialogButtonBox::Ok)->setEnabled(false); + buttonbox->button(QDialogButtonBox::Ok)->setText(tr("Find")); + + if(type == Type::Replace) { + buttonbox->button(QDialogButtonBox::Apply)->setEnabled(false); + buttonbox->button(QDialogButtonBox::Apply)->setText(tr("Replace")); + } + + vlayout->addWidget(buttonbox); + + connect(lefind, &QLineEdit::textChanged, this, + &HexFindDialog::validateActions); + connect(cbfindmode, QOverload::of(&QComboBox::currentIndexChanged), + this, &HexFindDialog::updateFindOptions); + connect(buttonbox, &QDialogButtonBox::accepted, this, &HexFindDialog::find); + connect(buttonbox, &QDialogButtonBox::rejected, this, &QDialog::reject); + connect(parent, &QHexView::positionChanged, this, + [this]() { m_startoffset = -1; }); + + if(lereplace) { + connect(buttonbox->button(QDialogButtonBox::Apply), + &QPushButton::clicked, this, &HexFindDialog::replace); + connect(lereplace, &QLineEdit::textChanged, this, + &HexFindDialog::validateActions); + } + + this->prepareTextMode(gboptions->layout()); + this->prepareHexMode(gboptions->layout()); + this->prepareIntMode(gboptions->layout()); + this->prepareFloatMode(gboptions->layout()); + this->updateFindOptions(-1); +} + +QHexView* HexFindDialog::hexView() const { + return qobject_cast(this->parentWidget()); +} + +void HexFindDialog::updateFindOptions(int) { + QGroupBox* gboptions = + this->findChild(HexFindDialog::GBOPTIONS); + + QLineEdit* lefind = this->findChild(HexFindDialog::LEFIND); + QLineEdit* lereplace = + this->findChild(HexFindDialog::LEREPLACE); + lefind->clear(); + if(lereplace) + lereplace->clear(); + + bool ok = false; + QHexFindMode mode = static_cast( + this->findChild(HexFindDialog::CBFINDMODE) + ->currentData() + .toInt(&ok)); + if(!ok) + return; + + m_findoptions = QHexFindOptions::None; + m_oldidxbits = m_oldidxendian = -1; + + auto* stack = qobject_cast(gboptions->layout()); + + switch(mode) { + case QHexFindMode::Text: { + lefind->setValidator(nullptr); + if(lereplace) + lereplace->setValidator(nullptr); + + stack->setCurrentIndex(0); + gboptions->setVisible(true); + break; + } + + case QHexFindMode::Hex: { + lefind->setValidator(m_hexpvalidator); + if(lereplace) + lereplace->setValidator(m_hexvalidator); + stack->setCurrentIndex(1); + gboptions->setVisible(false); + break; + } + + case QHexFindMode::Int: { + lefind->setValidator(m_intvalidator); + if(lereplace) + lereplace->setValidator(m_intvalidator); + + stack->setCurrentIndex(2); + gboptions->setVisible(true); + break; + } + + case QHexFindMode::Float: { + lefind->setValidator(m_dblvalidator); + if(lereplace) + lereplace->setValidator(m_dblvalidator); + + stack->setCurrentIndex(3); + gboptions->setVisible(true); + break; + } + } +} + +bool HexFindDialog::validateIntRange(uint v) const { + if(m_findoptions & QHexFindOptions::Int8) + return !(v > std::numeric_limits::max()); + if(m_findoptions & QHexFindOptions::Int16) + return !(v > std::numeric_limits::max()); + if(m_findoptions & QHexFindOptions::Int32) + return !(v > std::numeric_limits::max()); + return true; +} + +void HexFindDialog::checkResult(const QString& q, qint64 offset, + QHexFindDirection fd) { + if(offset == -1) { + QMessageBox::information(this, tr("Not found"), + tr("Cannot find '%1'").arg(q)); + return; + } + + if(fd == QHexFindDirection::Backward) + m_startoffset = this->hexView()->selectionStartOffset() - 1; + else + m_startoffset = this->hexView()->selectionEndOffset() + 1; +} + +void HexFindDialog::validateActions() { + auto mode = static_cast( + this->findChild(HexFindDialog::CBFINDMODE) + ->currentData() + .toUInt()); + auto* lefind = this->findChild(HexFindDialog::LEFIND); + auto* lereplace = this->findChild(HexFindDialog::LEREPLACE); + auto* buttonbox = + this->findChild(HexFindDialog::BUTTONBOX); + + bool findenable = false, replaceenable = false; + + switch(mode) { + case QHexFindMode::Hex: + findenable = QHexUtils::checkPattern(lefind->text()); + replaceenable = findenable; + break; + + case QHexFindMode::Float: { + lefind->text().toFloat(&findenable); + if(lereplace && findenable) + lereplace->text().toFloat(&replaceenable); + break; + } + + case QHexFindMode::Int: { + auto v = lefind->text().toUInt(&findenable); + if(findenable && !this->validateIntRange(v)) + findenable = false; + if(lereplace && findenable) + lereplace->text().toUInt(&replaceenable); + break; + } + + default: + findenable = !lefind->text().isEmpty(); + replaceenable = findenable; + break; + } + + if(lereplace) + buttonbox->button(QDialogButtonBox::Apply)->setEnabled(replaceenable); + buttonbox->button(QDialogButtonBox::Ok)->setEnabled(findenable); +} + +void HexFindDialog::replace() { + QString q1; + QHexFindMode mode; + QHexFindDirection fd; + + if(!this->prepareOptions(q1, mode, fd)) + return; + + QString q2 = this->findChild(HexFindDialog::LEREPLACE)->text(); + auto offset = this->hexView()->hexCursor()->replace( + q1, q2, m_startoffset > -1 ? m_startoffset : this->hexView()->offset(), + mode, m_findoptions, fd); + this->checkResult(q1, offset, fd); +} + +void HexFindDialog::find() { + QString q; + QHexFindMode mode; + QHexFindDirection fd; + + if(!this->prepareOptions(q, mode, fd)) + return; + + auto offset = this->hexView()->hexCursor()->find( + q, m_startoffset > -1 ? m_startoffset : this->hexView()->offset(), mode, + m_findoptions, fd); + this->checkResult(q, offset, fd); +} + +bool HexFindDialog::prepareOptions(QString& q, QHexFindMode& mode, + QHexFindDirection& fd) { + q = this->findChild(HexFindDialog::LEFIND)->text(); + mode = static_cast( + this->findChild(HexFindDialog::CBFINDMODE) + ->currentData() + .toUInt()); + + if(mode == QHexFindMode::Hex && !QHexUtils::checkPattern(q)) { + QMessageBox::warning(this, tr("Pattern Error"), + tr("Hex pattern '%1' is not valid").arg(q)); + return false; + } + + if(this->findChild(HexFindDialog::RBBACKWARD)->isChecked()) + fd = QHexFindDirection::Backward; + else if(this->findChild(HexFindDialog::RBFORWARD) + ->isChecked()) + fd = QHexFindDirection::Forward; + else + fd = QHexFindDirection::All; + return true; +} + +void HexFindDialog::prepareTextMode(QLayout* l) { + auto* cbcasesensitive = new QCheckBox("Case sensitive"); + + connect(cbcasesensitive, &QCheckBox::stateChanged, this, [this](int state) { + if(state == Qt::Checked) + m_findoptions |= QHexFindOptions::CaseSensitive; + else + m_findoptions &= ~QHexFindOptions::CaseSensitive; + }); + + auto* vlayout = new QVBoxLayout(new QWidget()); + vlayout->addWidget(cbcasesensitive); + l->addWidget(vlayout->parentWidget()); +} + +void HexFindDialog::prepareHexMode(QLayout* l) { l->addWidget(new QWidget()); } + +void HexFindDialog::prepareIntMode(QLayout* l) { + static const QList> INT_TYPES = { + qMakePair("(any)", 0), + qMakePair("8", QHexFindOptions::Int8), + qMakePair("16", QHexFindOptions::Int16), + qMakePair("32", QHexFindOptions::Int32), + qMakePair("64", QHexFindOptions::Int64)}; + + auto* cbbits = new QComboBox(); + for(const auto& it : INT_TYPES) + cbbits->addItem(it.first, it.second); + + connect(cbbits, QOverload::of(&QComboBox::currentIndexChanged), this, + [this, cbbits](int index) { + if(m_oldidxbits > -1) + m_findoptions &= ~cbbits->itemData(m_oldidxbits).toUInt(); + m_findoptions |= cbbits->itemData(index).toUInt(); + m_oldidxbits = index; + }); + + auto* cbendian = new QComboBox(); + cbendian->addItem("Little Endian", 0); + cbendian->addItem("Big Endian", QHexFindOptions::BigEndian); + + connect(cbendian, QOverload::of(&QComboBox::currentIndexChanged), this, + [this, cbendian](int index) { + if(m_oldidxendian > -1) + m_findoptions &= + ~cbendian->itemData(m_oldidxendian).toUInt(); + m_findoptions |= cbendian->itemData(index).toUInt(); + m_oldidxendian = index; + }); + + auto* vlayout = new QVBoxLayout(new QWidget()); + + QGridLayout* gl = new QGridLayout(); + gl->addWidget(new QLabel("Type:"), 0, 0, Qt::AlignRight); + gl->addWidget(cbbits, 0, 1); + gl->addWidget(new QLabel("Endian:"), 1, 0, Qt::AlignRight); + gl->addWidget(cbendian, 1, 1); + vlayout->addLayout(gl); + + l->addWidget(vlayout->parentWidget()); +} + +void HexFindDialog::prepareFloatMode(QLayout* l) { + static const QList> FLOAT_TYPES = { + qMakePair("float", QHexFindOptions::Float), + qMakePair("double", QHexFindOptions::Double)}; + + bool first = true; + auto* vlayout = new QVBoxLayout(new QWidget()); + + for(const auto& ft : FLOAT_TYPES) { + auto* rb = new QRadioButton(ft.first); + rb->setChecked(first); + vlayout->addWidget(rb); + first = false; + } + + l->addWidget(vlayout->parentWidget()); +} diff --git a/UEFITool/QHexView/src/model/buffer/qdevicebuffer.cpp b/UEFITool/QHexView/src/model/buffer/qdevicebuffer.cpp new file mode 100644 index 0000000..24413e4 --- /dev/null +++ b/UEFITool/QHexView/src/model/buffer/qdevicebuffer.cpp @@ -0,0 +1,118 @@ +#include +#include +#include + +QDeviceBuffer::QDeviceBuffer(QObject* parent): QHexBuffer{parent} {} + +QDeviceBuffer::~QDeviceBuffer() { + if(!m_device) + return; + + if(m_device->parent() == this) { + if(m_device->isOpen()) + m_device->close(); + m_device->deleteLater(); + } + + m_device = nullptr; +} + +uchar QDeviceBuffer::at(qint64 idx) { + m_device->seek(idx); + + char c = '\0'; + m_device->getChar(&c); + return static_cast(c); +} + +qint64 QDeviceBuffer::length() const { return m_device->size(); } + +void QDeviceBuffer::insert(qint64 offset, const QByteArray& data) { + Q_UNUSED(offset) + Q_UNUSED(data) + // Not implemented +} + +void QDeviceBuffer::replace(qint64 offset, const QByteArray& data) { + m_device->seek(offset); + m_device->write(data); +} + +void QDeviceBuffer::remove(qint64 offset, int length) { + Q_UNUSED(offset) + Q_UNUSED(length) + // Not implemented +} + +QByteArray QDeviceBuffer::read(qint64 offset, int length) { + m_device->seek(offset); + return m_device->read(length); +} + +bool QDeviceBuffer::read(QIODevice* device) { + m_device = device; + if(!m_device) + return false; + if(!m_device->isOpen()) + m_device->open(QIODevice::ReadWrite); + return m_device->isOpen(); +} + +void QDeviceBuffer::write(QIODevice* device) { + Q_UNUSED(device) + // Not implemented +} + +qint64 QDeviceBuffer::indexOf(const QByteArray& ba, qint64 from) { + const auto MAX = std::numeric_limits::max(); + qint64 idx = -1; + + if(from < m_device->size()) { + idx = from; + m_device->seek(from); + + while(idx < m_device->size()) { + QByteArray data = m_device->read(MAX); + int sidx = data.indexOf(ba); + + if(sidx >= 0) { + idx += sidx; + break; + } + + if(idx + data.size() >= m_device->size()) + return -1; + m_device->seek(m_device->pos() + data.size() - ba.size()); + } + } + + return idx; +} + +qint64 QDeviceBuffer::lastIndexOf(const QByteArray& ba, qint64 from) { + const auto MAX = std::numeric_limits::max(); + qint64 idx = -1; + + if(from >= 0 && ba.size() < MAX) { + qint64 currpos = from; + + while(currpos >= 0) { + qint64 readpos = (currpos < MAX) ? 0 : currpos - MAX; + m_device->seek(readpos); + + QByteArray data = m_device->read(currpos - readpos); + int lidx = data.lastIndexOf(ba, from); + + if(lidx >= 0) { + idx = readpos + lidx; + break; + } + + if(readpos <= 0) + break; + currpos = readpos + ba.size(); + } + } + + return idx; +} diff --git a/UEFITool/QHexView/src/model/buffer/qhexbuffer.cpp b/UEFITool/QHexView/src/model/buffer/qhexbuffer.cpp new file mode 100644 index 0000000..1d07b8a --- /dev/null +++ b/UEFITool/QHexView/src/model/buffer/qhexbuffer.cpp @@ -0,0 +1,36 @@ +#include +#include + +QHexBuffer::QHexBuffer(QObject* parent): QObject{parent} {} +uchar QHexBuffer::at(qint64 idx) { return this->read(idx, 1).at(0); } +bool QHexBuffer::isEmpty() const { return this->length() <= 0; } + +void QHexBuffer::replace(qint64 offset, const QByteArray& data) { + this->remove(offset, data.length()); + this->insert(offset, data); +} + +bool QHexBuffer::accept(qint64 idx) const { + Q_UNUSED(idx); + return true; +} + +void QHexBuffer::read(char* data, int size) { + QBuffer* buffer = new QBuffer(this); + buffer->setData(data, size); + + if(!buffer->isOpen()) + buffer->open(QBuffer::ReadWrite); + + this->read(buffer); +} + +void QHexBuffer::read(const QByteArray& ba) { + QBuffer* buffer = new QBuffer(this); + + buffer->setData(ba); + if(!buffer->isOpen()) + buffer->open(QBuffer::ReadWrite); + + this->read(buffer); +} diff --git a/UEFITool/QHexView/src/model/buffer/qmappedfilebuffer.cpp b/UEFITool/QHexView/src/model/buffer/qmappedfilebuffer.cpp new file mode 100644 index 0000000..a870d0a --- /dev/null +++ b/UEFITool/QHexView/src/model/buffer/qmappedfilebuffer.cpp @@ -0,0 +1,51 @@ +#include +#include + +QMappedFileBuffer::QMappedFileBuffer(QObject* parent): QDeviceBuffer{parent} {} + +QMappedFileBuffer::~QMappedFileBuffer() { + if((m_device && (m_device->parent() == this)) && m_mappeddata) { + QFile* f = qobject_cast(m_device); + f->unmap(m_mappeddata); + } + + m_mappeddata = nullptr; +} + +QByteArray QMappedFileBuffer::read(qint64 offset, int length) { + if(offset >= this->length()) + return {}; + + if(offset + length >= this->length()) + length = this->length() - offset; + + return QByteArray::fromRawData( + reinterpret_cast(m_mappeddata + offset), length); +} + +bool QMappedFileBuffer::read(QIODevice* iodevice) { + m_device = qobject_cast(iodevice); + if(!m_device || !QDeviceBuffer::read(iodevice)) + return false; + + this->remap(); + return m_mappeddata; +} + +void QMappedFileBuffer::write(QIODevice* iodevice) { + if(iodevice == m_device) + this->remap(); + else + iodevice->write(reinterpret_cast(m_mappeddata), + m_device->size()); +} + +void QMappedFileBuffer::remap() { + QFile* f = qobject_cast(m_device); + if(!f) + return; + + if(m_mappeddata) + f->unmap(m_mappeddata); + m_mappeddata = f->map(0, f->size()); +} diff --git a/UEFITool/QHexView/src/model/buffer/qmemorybuffer.cpp b/UEFITool/QHexView/src/model/buffer/qmemorybuffer.cpp new file mode 100644 index 0000000..220cebf --- /dev/null +++ b/UEFITool/QHexView/src/model/buffer/qmemorybuffer.cpp @@ -0,0 +1,39 @@ +#include +#include + +QMemoryBuffer::QMemoryBuffer(QObject* parent): QHexBuffer{parent} {} + +uchar QMemoryBuffer::at(qint64 idx) { + return static_cast(m_buffer.at(idx)); +} + +qint64 QMemoryBuffer::length() const { + return static_cast(m_buffer.length()); +} + +void QMemoryBuffer::insert(qint64 offset, const QByteArray& data) { + m_buffer.insert(static_cast(offset), data); +} + +void QMemoryBuffer::remove(qint64 offset, int length) { + m_buffer.remove(static_cast(offset), length); +} + +QByteArray QMemoryBuffer::read(qint64 offset, int length) { + return m_buffer.mid(static_cast(offset), length); +} + +bool QMemoryBuffer::read(QIODevice* device) { + m_buffer = device->readAll(); + return true; +} + +void QMemoryBuffer::write(QIODevice* device) { device->write(m_buffer); } + +qint64 QMemoryBuffer::indexOf(const QByteArray& ba, qint64 from) { + return m_buffer.indexOf(ba, static_cast(from)); +} + +qint64 QMemoryBuffer::lastIndexOf(const QByteArray& ba, qint64 from) { + return m_buffer.lastIndexOf(ba, static_cast(from)); +} diff --git a/UEFITool/QHexView/src/model/buffer/qmemoryrefbuffer.cpp b/UEFITool/QHexView/src/model/buffer/qmemoryrefbuffer.cpp new file mode 100644 index 0000000..2598b85 --- /dev/null +++ b/UEFITool/QHexView/src/model/buffer/qmemoryrefbuffer.cpp @@ -0,0 +1,26 @@ +#include +#include + +QMemoryRefBuffer::QMemoryRefBuffer(QObject* parent): QDeviceBuffer{parent} {} + +bool QMemoryRefBuffer::read(QIODevice* device) { + m_device = qobject_cast(device); + + if(m_device) { + m_device->setParent(this); + return QDeviceBuffer::read(device); + } + + return false; +} + +void QMemoryRefBuffer::write(QIODevice* device) { + if(!m_device || m_device == device) + return; + + static const int CHUNK_SIZE = 4096; + m_device->seek(0); + + while(!m_device->atEnd()) + device->write(m_device->read(CHUNK_SIZE)); +} diff --git a/UEFITool/QHexView/src/model/commands/hexcommand.cpp b/UEFITool/QHexView/src/model/commands/hexcommand.cpp new file mode 100644 index 0000000..ce27843 --- /dev/null +++ b/UEFITool/QHexView/src/model/commands/hexcommand.cpp @@ -0,0 +1,6 @@ +#include + +HexCommand::HexCommand(QHexBuffer* buffer, QHexDocument* document, + QUndoCommand* parent) + : QUndoCommand(parent), m_hexdocument(document), m_buffer(buffer), + m_offset(0), m_length(0) {} diff --git a/UEFITool/QHexView/src/model/commands/insertcommand.cpp b/UEFITool/QHexView/src/model/commands/insertcommand.cpp new file mode 100644 index 0000000..eaec5bc --- /dev/null +++ b/UEFITool/QHexView/src/model/commands/insertcommand.cpp @@ -0,0 +1,18 @@ +#include +#include + +InsertCommand::InsertCommand(QHexBuffer* buffer, QHexDocument* document, + qint64 offset, const QByteArray& data, + QUndoCommand* parent) + : HexCommand(buffer, document, parent) { + m_offset = offset; + m_data = data; +} + +void InsertCommand::undo() { + m_buffer->remove(m_offset, m_data.length()); + Q_EMIT m_hexdocument->dataChanged(m_data, m_offset, + QHexDocument::ChangeReason::Remove); +} + +void InsertCommand::redo() { m_buffer->insert(m_offset, m_data); } diff --git a/UEFITool/QHexView/src/model/commands/removecommand.cpp b/UEFITool/QHexView/src/model/commands/removecommand.cpp new file mode 100644 index 0000000..a71b37e --- /dev/null +++ b/UEFITool/QHexView/src/model/commands/removecommand.cpp @@ -0,0 +1,20 @@ +#include +#include + +RemoveCommand::RemoveCommand(QHexBuffer* buffer, QHexDocument* document, + qint64 offset, int length, QUndoCommand* parent) + : HexCommand(buffer, document, parent) { + m_offset = offset; + m_length = length; +} + +void RemoveCommand::undo() { + m_buffer->insert(m_offset, m_data); + Q_EMIT m_hexdocument->dataChanged(m_data, m_offset, + QHexDocument::ChangeReason::Insert); +} + +void RemoveCommand::redo() { + m_data = m_buffer->read(m_offset, m_length); // Backup data + m_buffer->remove(m_offset, m_length); +} diff --git a/UEFITool/QHexView/src/model/commands/replacecommand.cpp b/UEFITool/QHexView/src/model/commands/replacecommand.cpp new file mode 100644 index 0000000..6a193ea --- /dev/null +++ b/UEFITool/QHexView/src/model/commands/replacecommand.cpp @@ -0,0 +1,21 @@ +#include +#include + +ReplaceCommand::ReplaceCommand(QHexBuffer* buffer, QHexDocument* document, + qint64 offset, const QByteArray& data, + QUndoCommand* parent) + : HexCommand(buffer, document, parent) { + m_offset = offset; + m_data = data; +} + +void ReplaceCommand::undo() { + m_buffer->replace(m_offset, m_olddata); + Q_EMIT m_hexdocument->dataChanged(m_olddata, m_offset, + QHexDocument::ChangeReason::Replace); +} + +void ReplaceCommand::redo() { + m_olddata = m_buffer->read(m_offset, m_data.length()); + m_buffer->replace(m_offset, m_data); +} diff --git a/UEFITool/QHexView/src/model/qhexcursor.cpp b/UEFITool/QHexView/src/model/qhexcursor.cpp new file mode 100644 index 0000000..1b702cc --- /dev/null +++ b/UEFITool/QHexView/src/model/qhexcursor.cpp @@ -0,0 +1,182 @@ +#include +#include +#include + +/* + * https://stackoverflow.com/questions/10803043/inverse-column-row-major-order-transformation + * + * If the index is calculated as: + * offset = row + column*NUMROWS + * then the inverse would be: + * row = offset % NUMROWS + * column = offset / NUMROWS + * where % is modulus, and / is integer division. + */ + +QHexCursor::QHexCursor(const QHexOptions* options, QHexView* parent) + : QObject(parent), m_options(options) {} + +QHexView* QHexCursor::hexView() const { + return qobject_cast(this->parent()); +} + +QHexCursor::Mode QHexCursor::mode() const { return m_mode; } +qint64 QHexCursor::offset() const { return this->positionToOffset(m_position); } + +qint64 QHexCursor::address() const { + return m_options->baseaddress + this->offset(); +} + +quint64 QHexCursor::lineAddress() const { + return m_options->baseaddress + (m_position.line * m_options->linelength); +} + +qint64 QHexCursor::selectionStartOffset() const { + return this->positionToOffset(this->selectionStart()); +} + +qint64 QHexCursor::selectionEndOffset() const { + return this->positionToOffset(this->selectionEnd()); +} + +qint64 QHexCursor::line() const { return m_position.line; } +qint64 QHexCursor::column() const { return m_position.column; } + +QHexPosition QHexCursor::selectionStart() const { + if(m_position.line < m_selection.line) + return m_position; + + if(m_position.line == m_selection.line) { + if(m_position.column < m_selection.column) + return m_position; + } + + return m_selection; +} + +QHexPosition QHexCursor::selectionEnd() const { + if(m_position.line > m_selection.line) + return m_position; + + if(m_position.line == m_selection.line) { + if(m_position.column > m_selection.column) + return m_position; + } + + return m_selection; +} + +qint64 QHexCursor::selectionLength() const { + auto selstart = this->selectionStartOffset(), + selend = this->selectionEndOffset(); + return selstart == selend ? 0 : selend - selstart + 1; +} + +QHexPosition QHexCursor::position() const { return m_position; } + +QByteArray QHexCursor::selectedBytes() const { + return this->hexView()->selectedBytes(); +} + +bool QHexCursor::hasSelection() const { return m_position != m_selection; } + +bool QHexCursor::isSelected(qint64 line, qint64 column) const { + if(!this->hasSelection()) + return false; + + auto selstart = this->selectionStart(), selend = this->selectionEnd(); + if(line > selstart.line && line < selend.line) + return true; + if(line == selstart.line && line == selend.line) + return column >= selstart.column && column <= selend.column; + if(line == selstart.line) + return column >= selstart.column; + if(line == selend.line) + return column <= selend.column; + return false; +} + +void QHexCursor::setMode(Mode m) { + if(m_mode == m) + return; + m_mode = m; + Q_EMIT modeChanged(); +} + +void QHexCursor::switchMode() { + switch(m_mode) { + case Mode::Insert: this->setMode(Mode::Overwrite); break; + case Mode::Overwrite: this->setMode(Mode::Insert); break; + } +} + +void QHexCursor::move(qint64 offset) { + this->move(this->offsetToPosition(offset)); +} + +void QHexCursor::move(qint64 line, qint64 column) { + return this->move({line, column}); +} + +void QHexCursor::move(QHexPosition pos) { + if(pos.line >= 0) + m_selection.line = pos.line; + if(pos.column >= 0) + m_selection.column = pos.column; + this->select(pos); +} + +void QHexCursor::select(qint64 offset) { + this->select(this->offsetToPosition(offset)); +} + +void QHexCursor::select(qint64 line, qint64 column) { + this->select({line, column}); +} + +void QHexCursor::select(QHexPosition pos) { + if(pos.line >= 0) + m_position.line = pos.line; + if(pos.column >= 0) + m_position.column = pos.column; + Q_EMIT positionChanged(); +} + +void QHexCursor::selectSize(qint64 length) { + if(length > 0) + length--; + else if(length < 0) + length++; + if(length) + this->select(this->offset() + length); +} + +qint64 QHexCursor::replace(const QVariant& oldvalue, const QVariant& newvalue, + qint64 offset, QHexFindMode mode, + unsigned int options, QHexFindDirection fd) const { + return this->hexView()->replace(oldvalue, newvalue, offset, mode, options, + fd); +} +qint64 QHexCursor::find(const QVariant& value, qint64 offset, QHexFindMode mode, + unsigned int options, QHexFindDirection fd) const { + return this->hexView()->find(value, offset, mode, options, fd); +} + +void QHexCursor::cut(bool hex) { this->hexView()->cut(hex); } +void QHexCursor::copy(bool hex) const { this->hexView()->copy(hex); } +void QHexCursor::paste(bool hex) { this->hexView()->paste(hex); } +void QHexCursor::selectAll() { this->hexView()->selectAll(); } +void QHexCursor::removeSelection() { this->hexView()->removeSelection(); } + +void QHexCursor::clearSelection() { + m_position = m_selection; + Q_EMIT positionChanged(); +} + +qint64 QHexCursor::positionToOffset(QHexPosition pos) const { + return QHexUtils::positionToOffset(m_options, pos); +} + +QHexPosition QHexCursor::offsetToPosition(qint64 offset) const { + return QHexUtils::offsetToPosition(m_options, offset); +} diff --git a/UEFITool/QHexView/src/model/qhexdelegate.cpp b/UEFITool/QHexView/src/model/qhexdelegate.cpp new file mode 100644 index 0000000..fe2a1d0 --- /dev/null +++ b/UEFITool/QHexView/src/model/qhexdelegate.cpp @@ -0,0 +1,65 @@ +#include +#include + +QHexDelegate::QHexDelegate(QObject* parent): QObject{parent} {} + +QString QHexDelegate::addressHeader(const QHexView* hexview) const { + Q_UNUSED(hexview); + return QString(); +} + +QString QHexDelegate::hexHeader(const QHexView* hexview) const { + Q_UNUSED(hexview); + return QString(); +} + +QString QHexDelegate::asciiHeader(const QHexView* hexview) const { + Q_UNUSED(hexview); + return QString(); +} + +void QHexDelegate::renderAddress(quint64 address, QTextCharFormat& cf, + const QHexView* hexview) const { + Q_UNUSED(address); + Q_UNUSED(hexview); + Q_UNUSED(cf); + Q_UNUSED(hexview); +} + +void QHexDelegate::renderHeader(QTextBlockFormat& bf, + const QHexView* hexview) const { + Q_UNUSED(bf); + Q_UNUSED(hexview); +} + +void QHexDelegate::renderHeaderPart(const QString& s, QHexArea area, + QTextCharFormat& cf, + const QHexView* hexview) const { + Q_UNUSED(s); + Q_UNUSED(area); + Q_UNUSED(cf); + Q_UNUSED(hexview); +} + +bool QHexDelegate::render(quint64 offset, quint8 b, QTextCharFormat& outcf, + const QHexView* hexview) const { + Q_UNUSED(offset); + Q_UNUSED(b); + Q_UNUSED(outcf); + Q_UNUSED(hexview); + + return false; +} + +bool QHexDelegate::paintSeparator(QPainter* painter, QLineF line, + const QHexView* hexview) const { + Q_UNUSED(painter); + Q_UNUSED(line); + Q_UNUSED(hexview); + return false; +} + +void QHexDelegate::paint(QPainter* painter, const QHexView* hexview) const { + Q_UNUSED(hexview); + hexview->paint(painter); +} diff --git a/UEFITool/QHexView/src/model/qhexdocument.cpp b/UEFITool/QHexView/src/model/qhexdocument.cpp new file mode 100644 index 0000000..0933b6b --- /dev/null +++ b/UEFITool/QHexView/src/model/qhexdocument.cpp @@ -0,0 +1,142 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +QHexDocument::QHexDocument(QHexBuffer* buffer, QObject* parent) + : QObject(parent) { + m_buffer = buffer; + m_buffer->setParent(this); // Take Ownership + + connect(&m_undostack, &QUndoStack::canUndoChanged, this, + &QHexDocument::canUndoChanged); + connect(&m_undostack, &QUndoStack::canRedoChanged, this, + &QHexDocument::canRedoChanged); + connect(&m_undostack, &QUndoStack::cleanChanged, this, + [&](bool clean) { Q_EMIT modifiedChanged(!clean); }); +} + +qint64 QHexDocument::indexOf(const QByteArray& ba, qint64 from) { + return m_buffer->indexOf(ba, from); +} + +qint64 QHexDocument::lastIndexOf(const QByteArray& ba, qint64 from) { + return m_buffer->lastIndexOf(ba, from); +} + +bool QHexDocument::accept(qint64 idx) const { return m_buffer->accept(idx); } +bool QHexDocument::isEmpty() const { return m_buffer->isEmpty(); } +bool QHexDocument::isModified() const { return !m_undostack.isClean(); } +bool QHexDocument::canUndo() const { return m_undostack.canUndo(); } +bool QHexDocument::canRedo() const { return m_undostack.canRedo(); } + +void QHexDocument::setData(const QByteArray& ba) { + QHexBuffer* mb = new QMemoryBuffer(); + mb->read(ba); + this->setData(mb); +} + +void QHexDocument::setData(QHexBuffer* buffer) { + if(!buffer) + return; + + m_undostack.clear(); + buffer->setParent(this); + + auto* oldbuffer = m_buffer; + m_buffer = buffer; + if(oldbuffer) + oldbuffer->deleteLater(); + + Q_EMIT canUndoChanged(false); + Q_EMIT canRedoChanged(false); + Q_EMIT changed(); + Q_EMIT reset(); +} + +void QHexDocument::clearModified() { m_undostack.setClean(); } + +qint64 QHexDocument::length() const { + return m_buffer ? m_buffer->length() : 0; +} + +uchar QHexDocument::at(int offset) const { return m_buffer->at(offset); } + +QHexDocument* QHexDocument::fromFile(QString filename, QObject* parent) { + QFile f(filename); + f.open(QFile::ReadOnly); + return QHexDocument::fromMemory(f.readAll(), parent); +} + +void QHexDocument::undo() { + m_undostack.undo(); + Q_EMIT changed(); +} + +void QHexDocument::redo() { + m_undostack.redo(); + Q_EMIT changed(); +} + +void QHexDocument::insert(qint64 offset, uchar b) { + this->insert(offset, QByteArray(1, b)); +} + +void QHexDocument::replace(qint64 offset, uchar b) { + this->replace(offset, QByteArray(1, b)); +} + +void QHexDocument::insert(qint64 offset, const QByteArray& data) { + m_undostack.push(new InsertCommand(m_buffer, this, offset, data)); + + Q_EMIT changed(); + Q_EMIT dataChanged(data, offset, ChangeReason::Insert); +} + +void QHexDocument::replace(qint64 offset, const QByteArray& data) { + m_undostack.push(new ReplaceCommand(m_buffer, this, offset, data)); + Q_EMIT changed(); + Q_EMIT dataChanged(data, offset, ChangeReason::Replace); +} + +void QHexDocument::remove(qint64 offset, int len) { + QByteArray data = m_buffer->read(offset, len); + + m_undostack.push(new RemoveCommand(m_buffer, this, offset, len)); + Q_EMIT changed(); + Q_EMIT dataChanged(data, offset, ChangeReason::Remove); +} + +QByteArray QHexDocument::read(qint64 offset, int len) const { + return m_buffer->read(offset, len); +} + +bool QHexDocument::saveTo(QIODevice* device) { + if(!device->isWritable()) + return false; + m_buffer->write(device); + return true; +} + +QHexDocument* QHexDocument::fromBuffer(QHexBuffer* buffer, QObject* parent) { + return new QHexDocument(buffer, parent); +} + +QHexDocument* QHexDocument::fromLargeFile(QString filename, QObject* parent) { + return QHexDocument::fromDevice(new QFile(filename), parent); +} + +QHexDocument* QHexDocument::fromMappedFile(QString filename, QObject* parent) { + return QHexDocument::fromDevice(new QFile(filename), + parent); +} + +QHexDocument* QHexDocument::create(QObject* parent) { + return QHexDocument::fromMemory({}, parent); +} diff --git a/UEFITool/QHexView/src/model/qhexmetadata.cpp b/UEFITool/QHexView/src/model/qhexmetadata.cpp new file mode 100644 index 0000000..8fa4864 --- /dev/null +++ b/UEFITool/QHexView/src/model/qhexmetadata.cpp @@ -0,0 +1,158 @@ +#include +#include + +QHexMetadata::QHexMetadata(const QHexOptions* options, QObject* parent) + : QObject(parent), m_options(options) {} + +const QHexMetadataLine* QHexMetadata::find(qint64 line) const { + auto it = m_metadata.find(line); + return it != m_metadata.end() ? std::addressof(it.value()) : nullptr; +} + +QString QHexMetadata::getComment(qint64 line, qint64 column) const { + auto* metadataline = this->find(line); + if(!metadataline) + return QString(); + + auto offset = QHexUtils::positionToOffset(m_options, {line, column}); + QStringList comments; + + for(auto& mi : *metadataline) { + if((offset < mi.begin || offset > mi.end) || mi.comment.isEmpty()) + continue; + comments.push_back(mi.comment); + } + + return comments.join("\n"); +} + +void QHexMetadata::removeMetadata(qint64 line) { + auto it = m_metadata.find(line); + if(it == m_metadata.end()) + return; + + m_metadata.erase(it); + Q_EMIT changed(); +} + +void QHexMetadata::removeBackground(qint64 line) { + this->clearMetadata(line, [](QHexMetadataItem& mi) -> bool { + if(!mi.background.isValid()) + return false; + + if(mi.foreground.isValid() || !mi.comment.isEmpty()) { + mi.background = QColor(); + return false; + } + + return true; + }); +} + +void QHexMetadata::removeForeground(qint64 line) { + this->clearMetadata(line, [](QHexMetadataItem& mi) -> bool { + if(!mi.foreground.isValid()) + return false; + + if(mi.background.isValid() || !mi.comment.isEmpty()) { + mi.foreground = QColor(); + return false; + } + + return true; + }); +} + +void QHexMetadata::removeComments(qint64 line) { + this->clearMetadata(line, [](QHexMetadataItem& mi) -> bool { + if(mi.comment.isEmpty()) + return false; + + if(mi.foreground.isValid() || mi.background.isValid()) { + mi.comment.clear(); + return false; + } + + return true; + }); +} + +void QHexMetadata::unhighlight(qint64 line) { + this->clearMetadata(line, [](QHexMetadataItem& mi) -> bool { + if(!mi.foreground.isValid() && !mi.background.isValid()) + return false; + + if(!mi.comment.isEmpty()) { + mi.foreground = QColor(); + mi.background = QColor(); + return false; + } + + return true; + }); +} + +void QHexMetadata::clear() { + m_metadata.clear(); + Q_EMIT changed(); +} + +void QHexMetadata::copy(const QHexMetadata* metadata) { + m_metadata = metadata->m_metadata; +} + +void QHexMetadata::clearMetadata(qint64 line, ClearMetadataCallback&& cb) { + auto iit = m_metadata.find(line); + if(iit == m_metadata.end()) + return; + + auto oldsize = iit->size(); + + for(auto it = iit->begin(); it != iit->end();) { + if(cb(*it)) + it = iit->erase(it); + else + it++; + } + + if(iit->empty()) { + this->removeMetadata(line); + return; + } + + if(oldsize != iit->size()) + Q_EMIT changed(); +} + +void QHexMetadata::setMetadata(const QHexMetadataItem& mi) { + if(!m_options->linelength) + return; + + const qint64 firstline = mi.begin / m_options->linelength; + const qint64 lastline = mi.end / m_options->linelength; + bool notify = false; + + for(auto line = firstline; line <= lastline; line++) { + auto start = line == firstline ? mi.begin % m_options->linelength : 0; + auto length = line == lastline + ? (mi.end % m_options->linelength) - start + : m_options->linelength; + if(length <= 0) + continue; + + notify = true; + m_metadata[line].push_back(mi); + } + + if(notify) + Q_EMIT changed(); +} + +void QHexMetadata::invalidate() { + auto oldmetadata = m_metadata; + m_metadata.clear(); + + for(const QHexMetadataLine& line : oldmetadata) + for(const QHexMetadataItem& mi : line) + this->setMetadata(mi); +} diff --git a/UEFITool/QHexView/src/model/qhexutils.cpp b/UEFITool/QHexView/src/model/qhexutils.cpp new file mode 100644 index 0000000..13350ba --- /dev/null +++ b/UEFITool/QHexView/src/model/qhexutils.cpp @@ -0,0 +1,384 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) +#define QHEXVIEW_VARIANT_EQ(x, t) ((x).metaType().id() == QMetaType::Q##t) +#else +#define QHEXVIEW_VARIANT_EQ(x, t) ((x).type() == QVariant::t) +#endif + +#if defined(_WIN32) && _MSC_VER <= 1916 // v141_xp +#include +namespace std { +using ::tolower; +} +#else +#include +#endif + +namespace QHexUtils { + +Q_GLOBAL_STATIC_WITH_ARGS(QList, HEXMAP, + ({'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + 'a', 'b', 'c', 'd', 'e', 'f'})); + +bool isHex(char ch) { + return (ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'F') || + (ch >= 'a' && ch <= 'f'); +} + +namespace PatternUtils { + +Q_GLOBAL_STATIC_WITH_ARGS(QString, WILDCARD_BYTE, ("??")) + +bool check(QString& p, qint64& len) { + static QHash> + processed; // Cache processed patterns + + auto it = processed.find(p); + + if(it != processed.end()) { + p = it.value().first; + len = it.value().second; + return true; + } + + QString op = p; // Store unprocessed pattern + p = p.simplified().replace(" ", ""); + if(p.isEmpty() || (p.size() % 2)) + return false; + + int wccount = 0; + + for(auto i = 0; i < p.size() - 2; i += 2) { + const auto& hexb = p.mid(i, 2); + + if(hexb == *WILDCARD_BYTE) { + wccount++; + continue; + } + + if(!QHexUtils::isHex(hexb.at(0).toLatin1()) || + !QHexUtils::isHex(hexb.at(1).toLatin1())) + return false; + } + + if(wccount >= p.size()) + return false; + len = p.size() / 2; + processed[op] = qMakePair(p, len); // Cache processed pattern + return true; +} + +bool match(const QByteArray& data, const QString& pattern) { + for(qint64 i = 0, idx = 0; (i <= (pattern.size() - 2)); i += 2, idx++) { + if(idx >= data.size()) + return false; + +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + QStringView hexb = QStringView{pattern}.mid(i, 2); +#else + const QStringRef& hexb = pattern.midRef(i, 2); +#endif + + if(hexb == *WILDCARD_BYTE) + continue; + + bool ok = false; + auto b = static_cast(hexb.toUInt(&ok, 16)); + if(!ok || (b != data.at(idx))) + return false; + } + + return true; +} + +} // namespace PatternUtils + +namespace { + +unsigned int countBits(uint val) { + if(val <= std::numeric_limits::max()) + return QHexFindOptions::Int8; + if(val <= std::numeric_limits::max()) + return QHexFindOptions::Int16; + if(val <= std::numeric_limits::max()) + return QHexFindOptions::Int32; + + return QHexFindOptions::Int64; +} + +template +qint64 findIter(qint64 startoffset, QHexFindDirection fd, + const QHexView* hexview, Function&& f) { + QHexDocument* hexdocument = hexview->hexDocument(); + qint64 offset = -1; + + QHexFindDirection cfd = fd; + if(cfd == QHexFindDirection::All) + cfd = QHexFindDirection::Forward; + + qint64 i = startoffset; + + bool restartLoopOnce = true; + + while(offset == -1 && + (cfd == QHexFindDirection::Backward ? (i >= 0) + : (i < hexdocument->length()))) { + if(!f(i, offset)) + break; + + if(cfd == QHexFindDirection::Backward) + i--; + else + i++; + + if(fd == QHexFindDirection::All && i >= hexdocument->length() && + restartLoopOnce) { + i = 0; + restartLoopOnce = false; + } + } + + return offset; +} + +qint64 findDefault(const QByteArray& value, qint64 startoffset, + const QHexView* hexview, unsigned int options, + QHexFindDirection fd) { + QHexDocument* hexdocument = hexview->hexDocument(); + if(value.size() > hexdocument->length()) + return -1; + + return findIter( + startoffset, fd, hexview, + [options, value, hexdocument](qint64 idx, qint64& offset) -> bool { + for(auto i = 0; i < value.size(); i++) { + qint64 curroffset = idx + i; + + if(curroffset >= hexdocument->length()) { + offset = -1; + return false; + } + + uchar ch1 = hexdocument->at(curroffset); + uchar ch2 = value.at(i); + + if(!(options & QHexFindOptions::CaseSensitive)) { + ch1 = std::tolower(ch1); + ch2 = std::tolower(ch2); + } + + if(ch1 != ch2) + break; + if(i == value.size() - 1) + offset = idx; + } + + return true; + }); +} + +qint64 findWildcard(QString pattern, qint64 startoffset, + const QHexView* hexview, QHexFindDirection fd, + qint64& patternlen) { + QHexDocument* hexdocument = hexview->hexDocument(); + if(!PatternUtils::check(pattern, patternlen) || + (patternlen >= hexdocument->length())) + return -1; + + return findIter( + startoffset, fd, hexview, + [hexdocument, pattern, patternlen](qint64 idx, qint64& offset) -> bool { + if(PatternUtils::match(hexdocument->read(idx, patternlen), pattern)) + offset = idx; + return true; + }); +} + +QByteArray variantToByteArray(QVariant value, QHexFindMode mode, + unsigned int options) { + QByteArray v; + + switch(mode) { + case QHexFindMode::Text: + if(QHEXVIEW_VARIANT_EQ(value, String)) + v = value.toString().toUtf8(); + else if(QHEXVIEW_VARIANT_EQ(value, ByteArray)) + v = value.toByteArray(); + break; + + case QHexFindMode::Hex: { + if(QHEXVIEW_VARIANT_EQ(value, String)) { + qint64 len = 0; + auto s = value.toString(); + if(!PatternUtils::check(s, len)) + return {}; + + bool ok = true; + +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + for(auto i = 0; ok && i < s.size(); i += 2) + v.push_back(static_cast( + QStringView{s}.mid(i, 2).toUInt(&ok, 16))); +#else + for(auto i = 0; ok && i < s.size(); i += 2) + v.push_back( + static_cast(s.midRef(i, 2).toUInt(&ok, 16))); +#endif + + if(!ok) + return {}; + } + else if(QHEXVIEW_VARIANT_EQ(value, ByteArray)) + v = value.toByteArray(); + break; + } + + case QHexFindMode::Int: { + bool ok = false; + uint val = value.toUInt(&ok); + if(!ok) + return QByteArray{}; + + QDataStream ds(&v, QIODevice::WriteOnly); + + if(options & QHexFindOptions::BigEndian) { + if(options & QHexFindOptions::Int8) + ds << qToBigEndian(val); + else if(options & QHexFindOptions::Int16) + ds << qToBigEndian(val); + else if(options & QHexFindOptions::Int32) + ds << qToBigEndian(val); + else if(options & QHexFindOptions::Int64) + ds << qToBigEndian(val); + else + return variantToByteArray(value, mode, + options | countBits(val)); + } + else { + if(options & QHexFindOptions::Int8) + ds << static_cast(val); + else if(options & QHexFindOptions::Int16) + ds << static_cast(val); + else if(options & QHexFindOptions::Int32) + ds << static_cast(val); + else if(options & QHexFindOptions::Int64) + ds << static_cast(val); + else + return variantToByteArray(value, mode, + options | countBits(val)); + } + + break; + } + + case QHexFindMode::Float: { + bool ok = false; + QDataStream ds(&v, QIODevice::WriteOnly); + if(options & QHexFindOptions::Float) + ds << value.toFloat(&ok); + else if(options & QHexFindOptions::Double) + ds << value.toDouble(&ok); + if(!ok) + return {}; + } + + default: break; + } + + return v; +} + +} // namespace + +QByteArray toHex(const QByteArray& ba, char sep) { + if(ba.isEmpty()) { + return QByteArray(); + } + + QByteArray hex(sep ? (ba.size() * 3 - 1) : (ba.size() * 2), + Qt::Uninitialized); + + for(auto i = 0, o = 0; i < ba.size(); i++) { + if(sep && i) + hex[o++] = static_cast(sep); + hex[o++] = HEXMAP->at((ba.at(i) & 0xf0) >> 4); + hex[o++] = HEXMAP->at(ba.at(i) & 0x0f); + } + + return hex; +} + +QByteArray toHex(const QByteArray& ba) { return QHexUtils::toHex(ba, '\0'); } +qint64 positionToOffset(const QHexOptions* options, QHexPosition pos) { + return options->linelength * pos.line + pos.column; +} +QHexPosition offsetToPosition(const QHexOptions* options, qint64 offset) { + return {offset / options->linelength, offset % options->linelength}; +} + +QPair find(const QHexView* hexview, QVariant value, + qint64 startoffset, QHexFindMode mode, + unsigned int options, QHexFindDirection fd) { + qint64 offset = -1, size = 0; + if(startoffset == -1) + startoffset = static_cast(hexview->offset()); + + if(mode == QHexFindMode::Hex && QHEXVIEW_VARIANT_EQ(value, String)) { + offset = QHexUtils::findWildcard(value.toString(), startoffset, hexview, + fd, size); + } + else { + auto ba = variantToByteArray(value, mode, options); + + if(!ba.isEmpty()) { + offset = + QHexUtils::findDefault(ba, startoffset, hexview, options, fd); + size = ba.size(); + } + else + offset = -1; + } + + return {offset, offset > -1 ? size : 0}; +} + +bool checkPattern(QString pattern) { + qint64 len = 0; + return PatternUtils::check(pattern, len); +} + +QPair replace(const QHexView* hexview, QVariant oldvalue, + QVariant newvalue, qint64 startoffset, + QHexFindMode mode, unsigned int options, + QHexFindDirection fd) { + auto res = + QHexUtils::find(hexview, oldvalue, startoffset, mode, options, fd); + + if(res.first != -1 && res.second > 0) { + QHexDocument* hexdocument = hexview->hexDocument(); + auto ba = variantToByteArray(newvalue, mode, options); + + if(!ba.isEmpty()) { + hexdocument->remove(res.first, res.second); + hexdocument->insert(res.first, ba); + res.second = ba.size(); + } + else { + res.first = -1; + res.second = 0; + } + } + + return res; +} + +} // namespace QHexUtils diff --git a/UEFITool/QHexView/src/qhexview.cpp b/UEFITool/QHexView/src/qhexview.cpp new file mode 100644 index 0000000..4055317 --- /dev/null +++ b/UEFITool/QHexView/src/qhexview.cpp @@ -0,0 +1,1583 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(QHEXVIEW_ENABLE_DIALOGS) +#include +#endif + +#if defined(QHEXVIEW_DEBUG) +#include +#define qhexview_fmtprint(fmt, ...) qDebug("%s " fmt, __func__, __VA_ARGS__) +#else +#define qhexview_fmtprint(fmt, ...) +#endif + +QHexView::QHexView(QWidget* parent) + : QAbstractScrollArea(parent), m_fontmetrics(this->font()) { + QFont f = QFontDatabase::systemFont(QFontDatabase::FixedFont); + + if(f.styleHint() != QFont::TypeWriter) { + f.setFamily("Monospace"); // Force Monospaced font + f.setStyleHint(QFont::TypeWriter); + } + + this->setFont(f); + this->setMouseTracking(true); + this->setFocusPolicy(Qt::StrongFocus); + this->viewport()->setCursor(Qt::IBeamCursor); + + QPalette p = this->palette(); + p.setBrush(QPalette::Window, p.base()); + + connect(this->verticalScrollBar(), &QScrollBar::valueChanged, this, + [=](int) { this->viewport()->update(); }); + + m_hexmetadata = new QHexMetadata(&m_options, this); + connect(m_hexmetadata, &QHexMetadata::changed, this, + [=]() { this->viewport()->update(); }); + + m_hexcursor = new QHexCursor(&m_options, this); + this->setDocument( + QHexDocument::fromMemory(QByteArray(), this)); + this->checkState(); + + connect(m_hexcursor, &QHexCursor::positionChanged, this, [=]() { + m_writing = false; + this->ensureVisible(); + Q_EMIT positionChanged(); + }); + + connect(m_hexcursor, &QHexCursor::modeChanged, this, [=]() { + m_writing = false; + this->viewport()->update(); + Q_EMIT modeChanged(); + }); +} + +QRectF QHexView::headerRect() const { + if(m_options.hasFlag(QHexFlags::NoHeader)) + return QRectF(); + + return QRectF(0, 0, this->endColumnX(), this->lineHeight()); +} + +QRectF QHexView::addressRect() const { + qreal y = m_options.hasFlag(QHexFlags::NoHeader) ? 0 : this->lineHeight(); + + return QRectF(0, y, this->endColumnX(), this->height() - y); +} + +QRectF QHexView::hexRect() const { + qreal y = m_options.hasFlag(QHexFlags::NoHeader) ? 0 : this->lineHeight(); + + return QRectF(this->hexColumnX(), y, + this->asciiColumnX() - this->hexColumnX(), + this->height() - y); +} + +QRectF QHexView::asciiRect() const { + qreal y = m_options.hasFlag(QHexFlags::NoHeader) ? 0 : this->lineHeight(); + + return QRectF(this->asciiColumnX(), y, + this->endColumnX() - this->asciiColumnX(), + this->height() - y); +} + +QHexDocument* QHexView::hexDocument() const { return m_hexdocument; } +QHexCursor* QHexView::hexCursor() const { + return m_hexdocument ? m_hexcursor : nullptr; +} +const QHexMetadata* QHexView::hexMetadata() const { return m_hexmetadata; } +QHexOptions QHexView::options() const { return m_options; } + +void QHexView::setOptions(const QHexOptions& options) { + auto oldlinelength = m_options.linelength; + m_options = options; + + if(oldlinelength != m_options.linelength) + m_hexmetadata->invalidate(); + + this->checkAndUpdate(); +} + +void QHexView::setBaseAddress(quint64 baseaddress) { + if(m_options.baseaddress == baseaddress) + return; + + m_options.baseaddress = baseaddress; + this->checkAndUpdate(); +} + +void QHexView::setDelegate(QHexDelegate* rd) { + if(m_hexdelegate == rd) + return; + m_hexdelegate = rd; + this->checkAndUpdate(); +} + +void QHexView::setDocument(QHexDocument* doc) { + if(!doc) + doc = QHexDocument::fromMemory(QByteArray(), this); + if(!doc->parent()) + doc->setParent(this); + + m_writing = false; + m_hexmetadata->clear(); + m_hexcursor->move(0); + + if(m_hexdocument) { + disconnect(m_hexdocument, &QHexDocument::changed, this, nullptr); + disconnect(m_hexdocument, &QHexDocument::dataChanged, this, nullptr); + disconnect(m_hexdocument, &QHexDocument::reset, this, nullptr); + disconnect(m_hexdocument, &QHexDocument::modifiedChanged, this, + nullptr); + } + + m_hexdocument = doc; + + connect(m_hexdocument, &QHexDocument::reset, this, [=]() { + m_writing = false; + m_hexcursor->move(0); + this->checkAndUpdate(true); + }); + + connect(m_hexdocument, &QHexDocument::dataChanged, this, + &QHexView::dataChanged); + + connect(m_hexdocument, &QHexDocument::modifiedChanged, this, + &QHexView::modifiedChanged); + + connect(m_hexdocument, &QHexDocument::changed, this, + [=]() { this->checkAndUpdate(true); }); + + this->checkAndUpdate(true); +} + +void QHexView::setData(const QByteArray& ba) { m_hexdocument->setData(ba); } +void QHexView::setData(QHexBuffer* buffer) { m_hexdocument->setData(buffer); } + +void QHexView::setCursorMode(QHexCursor::Mode mode) { + m_hexcursor->setMode(mode); +} + +void QHexView::setByteColor(quint8 b, QHexColor c) { + m_options.bytecolors[b] = c; + this->checkAndUpdate(); +} + +void QHexView::setByteForeground(quint8 b, QColor c) { + m_options.bytecolors[b].foreground = c; + this->checkAndUpdate(); +} + +void QHexView::setByteBackground(quint8 b, QColor c) { + m_options.bytecolors[b].background = c; + this->checkAndUpdate(); +} + +void QHexView::setMetadata(qint64 begin, qint64 end, const QColor& fgcolor, + const QColor& bgcolor, const QString& comment) { + m_hexmetadata->setMetadata(begin, end, fgcolor, bgcolor, comment); +} +void QHexView::setForeground(qint64 begin, qint64 end, const QColor& fgcolor) { + m_hexmetadata->setForeground(begin, end, fgcolor); +} +void QHexView::setBackground(qint64 begin, qint64 end, const QColor& bgcolor) { + m_hexmetadata->setBackground(begin, end, bgcolor); +} +void QHexView::setComment(qint64 begin, qint64 end, const QString& comment) { + m_hexmetadata->setComment(begin, end, comment); +} +void QHexView::setMetadataSize(qint64 begin, qint64 length, + const QColor& fgcolor, const QColor& bgcolor, + const QString& comment) { + m_hexmetadata->setMetadataSize(begin, length, fgcolor, bgcolor, comment); +} +void QHexView::setForegroundSize(qint64 begin, qint64 length, + const QColor& fgcolor) { + m_hexmetadata->setForegroundSize(begin, length, fgcolor); +} +void QHexView::setBackgroundSize(qint64 begin, qint64 length, + const QColor& bgcolor) { + m_hexmetadata->setBackgroundSize(begin, length, bgcolor); +} +void QHexView::setCommentSize(qint64 begin, qint64 length, + const QString& comment) { + m_hexmetadata->setCommentSize(begin, length, comment); +} +void QHexView::removeMetadata(qint64 line) { + m_hexmetadata->removeMetadata(line); +} +void QHexView::removeBackground(qint64 line) { + m_hexmetadata->removeBackground(line); +} +void QHexView::removeForeground(qint64 line) { + m_hexmetadata->removeForeground(line); +} +void QHexView::removeComments(qint64 line) { + m_hexmetadata->removeComments(line); +} +void QHexView::unhighlight(qint64 line) { m_hexmetadata->unhighlight(line); } +void QHexView::clearMetadata() { m_hexmetadata->clear(); } + +#if defined(QHEXVIEW_ENABLE_DIALOGS) +void QHexView::showFind() { + if(!m_hexdlgfind) + m_hexdlgfind = new HexFindDialog(HexFindDialog::Type::Find, this); + m_hexdlgfind->show(); +} + +void QHexView::showReplace() { + if(!m_hexdlgreplace) + m_hexdlgreplace = new HexFindDialog(HexFindDialog::Type::Replace, this); + m_hexdlgreplace->show(); +} +#endif + +void QHexView::undo() { + if(m_hexdocument) + m_hexdocument->undo(); +} +void QHexView::redo() { + if(m_hexdocument) + m_hexdocument->redo(); +} + +void QHexView::cut(bool hex) { + this->copy(hex); + if(m_readonly) + return; + + if(m_hexcursor->hasSelection()) + this->removeSelection(); + else + m_hexdocument->remove(m_hexcursor->offset(), 1); +} + +void QHexView::copyAs(CopyMode mode) const { + QClipboard* c = qApp->clipboard(); + + QByteArray bytes = m_hexcursor->hasSelection() + ? m_hexcursor->selectedBytes() + : m_hexdocument->read(m_hexcursor->offset(), 1); + + switch(mode) { + case CopyMode::HexArrayCurly: + case CopyMode::HexArraySquare: { + QString hexchar; + int i = 0; + + for(char b : bytes) { + if(!hexchar.isEmpty()) { + hexchar += ", "; + if(m_options.copybreak && !(++i % m_options.linelength)) + hexchar += "\n"; + } + + hexchar += + "0x" + QString::number(static_cast(b), 16).toUpper(); + } + + c->setText( + QString(mode == CopyMode::HexArraySquare ? "[%1]" : "{%1}") + .arg(hexchar)); + break; + } + + case CopyMode::HexArrayChar: { + QString hexchar; + + for(char b : bytes) + hexchar += + "\\x" + QString::number(static_cast(b), 16).toUpper(); + + c->setText(QString("\"%1\"").arg(hexchar)); + break; + } + + default: { + QString hexchar; + + for(int i = 0; i < bytes.size(); i++) { + if(!(i % m_options.grouplength)) { + if(!hexchar.isEmpty()) { + hexchar += ", "; + if(m_options.copybreak && !(i % m_options.linelength)) + hexchar += "\n"; + } + + hexchar += "0x"; + } + + hexchar += QString("%1") + .arg(static_cast(bytes[i]), 2, 16, + QLatin1Char('0')) + .toUpper(); + } + + c->setText(hexchar); + break; + } + } +} + +void QHexView::copy(bool hex) const { + QClipboard* c = qApp->clipboard(); + + QByteArray bytes = m_hexcursor->hasSelection() + ? m_hexcursor->selectedBytes() + : m_hexdocument->read(m_hexcursor->offset(), 1); + + if(hex) + bytes = QHexUtils::toHex(bytes, ' ').toUpper(); + c->setText(bytes); +} + +void QHexView::paste(bool hex) { + if(m_readonly) + return; + + QClipboard* c = qApp->clipboard(); + QByteArray pastedata = c->text().toUtf8(); + if(pastedata.isEmpty()) + return; + + this->removeSelection(); + if(hex) + pastedata = QByteArray::fromHex(pastedata); + + if(m_hexcursor->mode() == QHexCursor::Mode::Insert) + m_hexdocument->insert(m_hexcursor->offset(), pastedata); + else + m_hexdocument->replace(m_hexcursor->offset(), pastedata); +} + +void QHexView::clearModified() { + if(m_hexdocument) + m_hexdocument->clearModified(); +} + +void QHexView::selectAll() { + m_hexcursor->move(0); + m_hexcursor->select(m_hexdocument->length()); +} + +void QHexView::removeSelection() { + if(!m_hexcursor->hasSelection()) + return; + if(!m_readonly) + m_hexdocument->remove(m_hexcursor->selectionStartOffset(), + m_hexcursor->selectionLength() - 1); + m_hexcursor->clearSelection(); +} + +void QHexView::switchMode() { m_hexcursor->switchMode(); } + +void QHexView::setAddressWidth(unsigned int w) { + if(w == m_options.addresswidth) + return; + m_options.addresswidth = w; + this->checkState(); +} + +void QHexView::setScrollSteps(int scrollsteps) { + m_options.scrollsteps = scrollsteps; +} + +void QHexView::setReadOnly(bool r) { m_readonly = r; } + +void QHexView::setAutoWidth(bool r) { + if(m_autowidth == r) + return; + m_autowidth = r; + this->checkState(); +} + +void QHexView::paint(QPainter* painter) const { + QTextDocument doc; + doc.setDocumentMargin(0); + doc.setUndoRedoEnabled(false); + doc.setDefaultFont(this->font()); + + QTextCursor c(&doc); + + this->drawHeader(c); + this->drawDocument(c); + + painter->translate(-this->horizontalScrollBar()->value(), 0); + doc.drawContents(painter); + this->drawSeparators(painter); +} + +void QHexView::checkOptions() { + if(m_options.grouplength > m_options.linelength) + m_options.grouplength = m_options.linelength; + + m_options.addresswidth = + qMax(m_options.addresswidth, this->calcAddressWidth()); + + // Round to nearest multiple of 2 + m_options.grouplength = + 1u << (static_cast(qFloor(m_options.grouplength / 2.0))); + + if(m_options.grouplength <= 1) + m_options.grouplength = 1; + + if(!m_options.headercolor.isValid()) + m_options.headercolor = + this->palette().color(QPalette::Normal, QPalette::Highlight); +} + +void QHexView::setLineLength(unsigned int l) { + if(l == m_options.linelength) + return; + m_options.linelength = l; + m_hexmetadata->invalidate(); + this->checkAndUpdate(true); +} + +void QHexView::setGroupLength(unsigned int l) { + if(l == m_options.grouplength) + return; + m_options.grouplength = l; + this->checkAndUpdate(true); +} + +void QHexView::checkState() { + if(!m_hexdocument) + return; + this->checkOptions(); + + int doclines = static_cast(this->lines()), + vislines = this->visibleLines(true); + qint64 vscrollmax = doclines - vislines + 1; // UEFITool: ensure the very last line is visible on macOS + if(doclines >= vislines) + vscrollmax++; + + this->verticalScrollBar()->setRange(0, qMax(0, vscrollmax)); + this->verticalScrollBar()->setPageStep(vislines - 1); + this->verticalScrollBar()->setSingleStep(m_options.scrollsteps); + + int vw = this->verticalScrollBar()->isVisible() + ? this->verticalScrollBar()->width() + : 0; + + static int oldmw = 0; + if(!oldmw) + oldmw = this->maximumWidth(); + this->setMaximumWidth(m_autowidth ? qCeil(this->endColumnX() + vw + 3) + : oldmw); + + this->horizontalScrollBar()->setRange( + 0, qMax(0, this->endColumnX() - this->width() + vw + 3)); + this->horizontalScrollBar()->setPageStep(this->width()); +} + +void QHexView::checkAndUpdate(bool calccolumns) { + this->checkState(); + if(calccolumns) + this->calcColumns(); + this->viewport()->update(); +} + +void QHexView::calcColumns() { + if(!m_hexdocument) + return; + + m_hexcolumns.clear(); + m_hexcolumns.reserve(m_options.linelength); + + auto x = this->hexColumnX(), cw = this->cellWidth() * 2; + + for(auto i = 0u; i < m_options.linelength; i++) { + for(auto j = 0u; j < m_options.grouplength; j++, x += cw) + m_hexcolumns.push_back(QRect(x, 0, cw, 0)); + + x += this->cellWidth(); + } +} + +void QHexView::ensureVisible() { + if(!m_hexdocument) + return; + + auto pos = m_hexcursor->position(); + auto vlines = this->visibleLines(); + + if(pos.line >= (this->verticalScrollBar()->value() + vlines)) + this->verticalScrollBar()->setValue(pos.line - vlines + 1); + else if(pos.line < this->verticalScrollBar()->value()) + this->verticalScrollBar()->setValue(pos.line); + else + this->viewport()->update(); +} + +void QHexView::drawSeparators(QPainter* p) const { + if(!m_options.hasFlag(QHexFlags::Separators)) + return; + + auto oldpen = p->pen(); + p->setPen(m_options.separatorcolor.isValid() + ? m_options.separatorcolor + : this->palette().color(QPalette::Dark)); + + if(m_options.hasFlag(QHexFlags::HSeparator)) { + QLineF l(0, m_fontmetrics.lineSpacing(), this->endColumnX(), + m_fontmetrics.lineSpacing()); + if(!m_hexdelegate || !m_hexdelegate->paintSeparator(p, l, this)) + p->drawLine(l); + } + + if(m_options.hasFlag(QHexFlags::VSeparator)) { + QLineF l1(this->hexColumnX(), 0, this->hexColumnX(), this->height()); + QLineF l2(this->asciiColumnX(), 0, this->asciiColumnX(), + this->height()); + + if(!m_hexdelegate || + (m_hexdelegate && !m_hexdelegate->paintSeparator(p, l1, this))) + p->drawLine(l1); + + if(!m_hexdelegate || + (m_hexdelegate && !m_hexdelegate->paintSeparator(p, l2, this))) + p->drawLine(l2); + } + + p->setPen(oldpen); +} + +void QHexView::drawHeader(QTextCursor& c) const { + if(m_options.hasFlag(QHexFlags::NoHeader)) + return; + + static const auto RESET_FORMAT = [](const QHexOptions& options, + QTextCharFormat& cf) { + cf = {}; + cf.setForeground(options.headercolor); + }; + + QString addresslabel; + if(m_hexdelegate) + addresslabel = m_hexdelegate->addressHeader(this); + if(addresslabel.isEmpty() && !m_options.addresslabel.isEmpty()) + addresslabel = m_options.addresslabel; + + QTextCharFormat cf; + RESET_FORMAT(m_options, cf); + if(m_hexdelegate) + m_hexdelegate->renderHeaderPart(addresslabel, QHexArea::Address, cf, + this); + c.insertText( + " " + QHexView::reduced(addresslabel, this->addressWidth()) + " ", cf); + + if(m_hexdelegate) + RESET_FORMAT(m_options, cf); + + QString hexlabel; + if(m_hexdelegate) + hexlabel = m_hexdelegate->hexHeader(this); + if(hexlabel.isEmpty()) + hexlabel = m_options.hexlabel; + + if(hexlabel.isNull()) { + c.insertText(" ", {}); + + for(auto i = 0u; i < m_options.linelength; i += m_options.grouplength) { + QString h = QString::number(i, 16) + .rightJustified(m_options.grouplength * 2, '0') + .toUpper(); + + if(m_hexdelegate) { + RESET_FORMAT(m_options, cf); + m_hexdelegate->renderHeaderPart(h, QHexArea::Hex, cf, this); + } + + if(m_hexcursor->column() == static_cast(i) && + m_options.hasFlag(QHexFlags::HighlightColumn)) { + cf.setBackground(this->palette().color(QPalette::Highlight)); + cf.setForeground( + this->palette().color(QPalette::HighlightedText)); + } + + c.insertText(h, cf); + c.insertText(" ", {}); + RESET_FORMAT(m_options, cf); + } + } + else { + if(m_hexdelegate) + m_hexdelegate->renderHeaderPart(hexlabel, QHexArea::Hex, cf, this); + c.insertText( + " " + + QHexView::reduced( + hexlabel, (this->hexColumnWidth() / this->cellWidth()) - 1) + + " "); + } + + if(m_hexdelegate) + RESET_FORMAT(m_options, cf); + + QString asciilabel; + if(m_hexdelegate) + asciilabel = m_hexdelegate->asciiHeader(this); + if(asciilabel.isEmpty()) + asciilabel = m_options.asciilabel; + + if(asciilabel.isNull()) { + c.insertText(" ", {}); + + for(unsigned int i = 0; i < m_options.linelength; i++) { + QString a = QString::number(i, 16).toUpper(); + + if(m_hexdelegate) { + RESET_FORMAT(m_options, cf); + m_hexdelegate->renderHeaderPart(a, QHexArea::Ascii, cf, this); + } + + if(m_hexcursor->column() == static_cast(i) && + m_options.hasFlag(QHexFlags::HighlightColumn)) { + cf.setBackground(this->palette().color(QPalette::Highlight)); + cf.setForeground( + this->palette().color(QPalette::HighlightedText)); + } + + c.insertText(a, cf); + RESET_FORMAT(m_options, cf); + } + + c.insertText(" ", {}); + } + else { + if(m_hexdelegate) + m_hexdelegate->renderHeaderPart(asciilabel, QHexArea::Ascii, cf, + this); + c.insertText(" " + + QHexView::reduced(asciilabel, ((this->endColumnX() - + this->asciiColumnX() - + this->cellWidth()) / + this->cellWidth()) - + 1) + + " "); + } + + QTextBlockFormat bf; + if(m_options.hasFlag(QHexFlags::StyledHeader)) + bf.setBackground(this->palette().color(QPalette::Window)); + if(m_hexdelegate) + m_hexdelegate->renderHeader(bf, this); + c.setBlockFormat(bf); + c.insertBlock(); +} + +void QHexView::drawDocument(QTextCursor& c) const { + if(!m_hexdocument) + return; + + qreal y = !m_options.hasFlag(QHexFlags::NoHeader) ? this->lineHeight() : 0; + quint64 line = static_cast(this->verticalScrollBar()->value()); + + QTextCharFormat addrformat; + addrformat.setForeground( + this->palette().color(QPalette::Normal, QPalette::Highlight)); + + for(qint64 l = 0; m_hexdocument->isEmpty() || + (line < this->lines() && l < this->visibleLines()); + l++, line++, y += this->lineHeight()) { + quint64 address = line * m_options.linelength + this->baseAddress(); + QString addrstr = QString::number(address, 16) + .rightJustified(this->addressWidth(), '0') + .toUpper(); + + // Address Part + QTextCharFormat acf; + acf.setForeground(m_options.headercolor); + + if(m_options.hasFlag(QHexFlags::StyledAddress)) + acf.setBackground(this->palette().color(QPalette::Window)); + + if(m_hexdelegate) + m_hexdelegate->renderAddress(address, acf, this); + + if(m_hexcursor->line() == static_cast(line) && + m_options.hasFlag(QHexFlags::HighlightAddress)) { + acf.setBackground(this->palette().color(QPalette::Highlight)); + acf.setForeground(this->palette().color(QPalette::HighlightedText)); + } + + c.insertText(" " + addrstr + " ", acf); + + QByteArray linebytes = this->getLine(line); + c.insertText(" ", {}); + + // Hex Part + for(unsigned int column = 0u; column < m_options.linelength;) { + QTextCharFormat cf; + + for(unsigned int byteidx = 0u; byteidx < m_options.grouplength; + byteidx++, column++) { + QString s; + quint8 b{}; + + if(m_hexdocument->accept( + this->positionFromLineCol(line, column))) { + s = linebytes.isEmpty() || + column >= static_cast(linebytes.size()) + ? " " + : QString(QHexUtils::toHex(linebytes.mid(column, 1)) + .toUpper()); + b = static_cast(column) < linebytes.size() + ? linebytes.at(column) + : 0x00; + } + else + s = QString(m_options.invalidchar).repeated(2); + + cf = this->drawFormat(c, b, s, QHexArea::Hex, line, column, + static_cast(column) < + linebytes.size()); + } + + c.insertText(" ", cf); + } + + c.insertText(" ", {}); + + // Ascii Part + for(unsigned int column = 0u; column < m_options.linelength; column++) { + QString s; + quint8 b{}; + + if(m_hexdocument->accept(this->positionFromLineCol(line, column))) { + s = linebytes.isEmpty() || + column >= static_cast(linebytes.size()) + ? QChar(' ') + : (QChar::isPrint(linebytes.at(column)) + ? QChar(linebytes.at(column)) + : m_options.unprintablechar); + + b = static_cast(column) < linebytes.size() + ? linebytes.at(column) + : 0x00; + } + else + s = m_options.invalidchar; + + this->drawFormat(c, b, s, QHexArea::Ascii, line, column, + static_cast(column) < linebytes.size()); + } + + QTextBlockFormat bf; + + if(m_options.linealternatebackground.isValid() && line % 2) + bf.setBackground(m_options.linealternatebackground); + else if(m_options.linebackground.isValid() && !(line % 2)) + bf.setBackground(m_options.linebackground); + + bf.setLineHeight(this->lineHeight(), QTextBlockFormat::FixedHeight); // UEFITool: added to fix an issue with Hi-DPI displays on Windows + c.setBlockFormat(bf); + c.insertBlock({}); + if(m_hexdocument->isEmpty()) + break; + } +} + +unsigned int QHexView::calcAddressWidth() const { + if(!m_hexdocument) + return 0; + + auto maxaddr = + static_cast(m_options.baseaddress + m_hexdocument->length()); + if(maxaddr <= std::numeric_limits::max()) + return 8; + return QString::number(maxaddr, 16).size(); +} + +int QHexView::visibleLines(bool absolute) const { + int vl = static_cast( + qCeil(this->viewport()->height() / this->lineHeight())); + if(!m_options.hasFlag(QHexFlags::NoHeader)) + vl--; + return absolute ? vl : qMin(this->lines(), vl); +} + +qint64 QHexView::getLastColumn(qint64 line) const { + return this->getLine(line).size() - 1; +} +qint64 QHexView::lastLine() const { return qMax(0, this->lines() - 1); } + +qreal QHexView::hexColumnWidth() const { + int l = 0; + + for(auto i = 0u; i < m_options.linelength; i += m_options.grouplength) + l += (2 * m_options.grouplength) + 1; + + return this->getNCellsWidth(l); +} + +unsigned int QHexView::addressWidth() const { + if(!m_hexdocument || m_options.addresswidth) + return m_options.addresswidth; + return this->calcAddressWidth(); +} + +unsigned int QHexView::lineLength() const { return m_options.linelength; } + +bool QHexView::isModified() const { + return m_hexdocument && m_hexdocument->isModified(); +} + +bool QHexView::canUndo() const { + return m_hexdocument && m_hexdocument->canUndo(); +} + +bool QHexView::canRedo() const { + return m_hexdocument && m_hexdocument->canRedo(); +} + +quint64 QHexView::offset() const { return m_hexcursor->offset(); } +quint64 QHexView::address() const { return m_hexcursor->address(); } + +QHexPosition QHexView::positionFromOffset(quint64 offset) const { + QHexPosition opt = QHexPosition::invalid(); + + if(offset < static_cast(m_hexdocument->length())) { + opt.line = offset / m_options.linelength; + opt.column = offset % m_options.linelength; + } + + return opt; +} + +QHexPosition QHexView::positionFromAddress(quint64 address) const { + return this->positionFromOffset(address - m_options.baseaddress); +} + +QHexPosition QHexView::position() const { return m_hexcursor->position(); } + +QHexPosition QHexView::selectionStart() const { + return m_hexcursor->selectionStart(); +} + +QHexPosition QHexView::selectionEnd() const { + return m_hexcursor->selectionEnd(); +} + +quint64 QHexView::selectionStartOffset() const { + return m_hexcursor->selectionStartOffset(); +} + +quint64 QHexView::selectionEndOffset() const { + return m_hexcursor->selectionEndOffset(); +} + +quint64 QHexView::baseAddress() const { return m_options.baseaddress; } + +quint64 QHexView::lines() const { + if(!m_hexdocument) + return 0; + + auto lines = static_cast(qCeil( + m_hexdocument->length() / static_cast(m_options.linelength))); + return !m_hexdocument->isEmpty() && !lines ? 1 : lines; +} + +qint64 QHexView::replace(const QVariant& oldvalue, const QVariant& newvalue, + qint64 offset, QHexFindMode mode, unsigned int options, + QHexFindDirection fd) const { + auto res = + QHexUtils::replace(this, oldvalue, newvalue, offset, mode, options, fd); + + if(res.first > -1) { + m_hexcursor->move(res.first); + m_hexcursor->selectSize(res.second); + } + + return res.first; +} + +qint64 QHexView::find(const QVariant& value, qint64 offset, QHexFindMode mode, + unsigned int options, QHexFindDirection fd) const { + auto res = QHexUtils::find(this, value, offset, mode, options, fd); + + if(res.first > -1) { + m_hexcursor->move(res.first); + m_hexcursor->selectSize(res.second); + } + + return res.first; +} + +qreal QHexView::hexColumnX() const { + return this->getNCellsWidth(this->addressWidth() + 2); +} +qreal QHexView::asciiColumnX() const { + return this->hexColumnX() + this->hexColumnWidth() + this->cellWidth(); +} +qreal QHexView::endColumnX() const { + return this->asciiColumnX() + + this->getNCellsWidth(m_options.linelength + 1) + this->cellWidth(); +} +qreal QHexView::getNCellsWidth(int n) const { return n * this->cellWidth(); } + +qreal QHexView::cellWidth() const { +#if QT_VERSION >= QT_VERSION_CHECK(5, 11, 0) + return m_fontmetrics.horizontalAdvance(" "); +#else + return m_fontmetrics.width(" "); +#endif +} + +qreal QHexView::lineHeight() const { return m_fontmetrics.height(); } + +qint64 QHexView::positionFromLineCol(qint64 line, qint64 col) const { + if(m_hexdocument) { + return qMin((line * m_options.linelength) + col, + m_hexdocument->length()); + } + + return 0; +} + +QHexPosition QHexView::positionFromPoint(QPoint pt) const { + QHexPosition pos = QHexPosition::invalid(); + auto abspt = this->absolutePoint(pt); + + switch(this->areaFromPoint(pt)) { + case QHexArea::Hex: { + pos.column = -1; + + for(qint64 i = 0; i < m_hexcolumns.size(); i++) { + if(m_hexcolumns.at(i).left() > abspt.x()) + break; + pos.column = i; + } + + break; + } + + case QHexArea::Ascii: + pos.column = qMax( + qFloor((abspt.x() - this->asciiColumnX()) / this->cellWidth()) - + 1, + 0); + break; + case QHexArea::Address: pos.column = 0; break; + case QHexArea::Header: return QHexPosition::invalid(); + default: break; + } + + pos.line = qMin(this->verticalScrollBar()->value() + + (abspt.y() / this->lineHeight()), + this->lines()); + if(!m_options.hasFlag(QHexFlags::NoHeader)) + pos.line = qMax(0, pos.line - 1); + + auto docline = this->getLine(pos.line); + pos.column = + qMin(pos.column, docline.isEmpty() ? 0 : docline.size()); + + qhexview_fmtprint("line: %lld, col: %lld", pos.line, pos.column); + return pos; +} + +QPoint QHexView::absolutePoint(QPoint pt) const { + return pt + QPoint(this->horizontalScrollBar()->value(), 0); +} + +QHexArea QHexView::areaFromPoint(QPoint pt) const { + pt = this->absolutePoint(pt); + qreal line = + this->verticalScrollBar()->value() + pt.y() / this->lineHeight(); + + if(!m_options.hasFlag(QHexFlags::NoHeader) && !qFloor(line)) + return QHexArea::Header; + if(pt.x() < this->hexColumnX()) + return QHexArea::Address; + if(pt.x() < this->asciiColumnX()) + return QHexArea::Hex; + if(pt.x() < this->endColumnX()) + return QHexArea::Ascii; + return QHexArea::Extra; +} + +QTextCharFormat QHexView::drawFormat(QTextCursor& c, quint8 b, const QString& s, + QHexArea area, qint64 line, qint64 column, + bool applyformat) const { + QTextCharFormat cf, selcf; + QHexPosition pos{line, column}; + + if(applyformat) { + auto offset = m_hexcursor->positionToOffset(pos); + bool hasdelegate = + m_hexdelegate && m_hexdelegate->render(offset, b, cf, this); + + if(!hasdelegate) { + auto it = m_options.bytecolors.find(b); + + if(it != m_options.bytecolors.end()) { + if(it->background.isValid()) + cf.setBackground(it->background); + if(it->foreground.isValid()) + cf.setForeground(it->foreground); + } + } + + const auto* metadataline = m_hexmetadata->find(line); + + if(metadataline) { + for(const auto& metadata : *metadataline) { + if(offset < metadata.begin || offset >= metadata.end) + continue; + + if(!hasdelegate) { + if(metadata.foreground.isValid()) + cf.setForeground(metadata.foreground); + + if(metadata.background.isValid()) { + cf.setBackground(metadata.background); + + if(!metadata.foreground.isValid()) + cf.setForeground( + this->getReadableColor(metadata.background)); + } + } + + if(!metadata.comment.isEmpty()) { + cf.setUnderlineColor( + m_options.commentcolor.isValid() + ? m_options.commentcolor + : this->palette().color(QPalette::WindowText)); + cf.setUnderlineStyle( + QTextCharFormat::UnderlineStyle::SingleUnderline); + } + + if(offset == metadata.begin) // Remove previous metadata's + // style, if needed + { + if(metadata.comment.isEmpty()) + selcf.setUnderlineStyle( + QTextCharFormat::UnderlineStyle::NoUnderline); + if(!metadata.foreground.isValid()) + selcf.setForeground(Qt::color1); + if(!metadata.background.isValid()) + selcf.setBackground(Qt::transparent); + } + + if(offset < metadata.end - 1 && + column < this->getLastColumn(line)) + selcf = cf; + } + } + + if(hasdelegate && column < this->getLastColumn(line)) + selcf = cf; + } + + if(this->hexCursor()->isSelected(line, column)) { + auto offset = this->hexCursor()->positionToOffset(pos); + auto selend = this->hexCursor()->selectionEndOffset(); + + cf.setBackground( + this->palette().color(QPalette::Normal, QPalette::Highlight)); + cf.setForeground( + this->palette().color(QPalette::Normal, QPalette::HighlightedText)); + if(offset < selend && column < this->getLastColumn(line)) + selcf = cf; + } + + if(this->hexCursor()->position() == pos) { + auto cursorbg = this->palette().color( + this->hasFocus() ? QPalette::Normal : QPalette::Disabled, + QPalette::WindowText); + auto cursorfg = this->palette().color( + this->hasFocus() ? QPalette::Normal : QPalette::Disabled, + QPalette::Base); + auto discursorbg = + this->palette().color(QPalette::Disabled, QPalette::WindowText); + auto discursorfg = + this->palette().color(QPalette::Disabled, QPalette::Base); + + switch(m_hexcursor->mode()) { + case QHexCursor::Mode::Insert: + cf.setUnderlineColor(m_currentarea == area ? cursorbg + : discursorbg); + cf.setUnderlineStyle( + QTextCharFormat::UnderlineStyle::SingleUnderline); + break; + + case QHexCursor::Mode::Overwrite: + cf.setBackground(m_currentarea == area ? cursorbg + : discursorbg); + cf.setForeground(m_currentarea == area ? cursorfg + : discursorfg); + break; + } + } + + c.insertText(s, cf); + return selcf; +} + +void QHexView::moveNext(bool select) { + auto line = this->hexCursor()->line(), column = this->hexCursor()->column(); + + if(column >= m_options.linelength - 1) { + line++; + column = 0; + } + else + column++; + + qint64 offset = + this->hexCursor()->mode() == QHexCursor::Mode::Insert ? 1 : 0; + if(select) + this->hexCursor()->select( + qMin(line, this->lines()), + qMin(column, this->getLastColumn(line) + offset)); + else + this->hexCursor()->move( + qMin(line, this->lines()), + qMin(column, this->getLastColumn(line) + offset)); +} + +void QHexView::movePrevious(bool select) { + auto line = this->hexCursor()->line(), column = this->hexCursor()->column(); + + if(column <= 0) { + if(!line) + return; + column = this->getLine(--line).size() - 1; + } + else + column--; + + if(select) + this->hexCursor()->select( + qMin(line, this->lines()), + qMin(column, this->getLastColumn(line))); + else + this->hexCursor()->move( + qMin(line, this->lines()), + qMin(column, this->getLastColumn(line))); +} + +bool QHexView::keyPressMove(QKeyEvent* e) { + if(e->matches(QKeySequence::MoveToNextChar) || + e->matches(QKeySequence::SelectNextChar)) + this->moveNext(e->matches(QKeySequence::SelectNextChar)); + else if(e->matches(QKeySequence::MoveToPreviousChar) || + e->matches(QKeySequence::SelectPreviousChar)) + this->movePrevious(e->matches(QKeySequence::SelectPreviousChar)); + else if(e->matches(QKeySequence::MoveToNextLine) || + e->matches(QKeySequence::SelectNextLine)) { + if(this->hexCursor()->line() == this->lastLine()) + return true; + auto nextline = this->hexCursor()->line() + 1; + if(e->matches(QKeySequence::MoveToNextLine)) + this->hexCursor()->move(nextline, this->hexCursor()->column()); + else + this->hexCursor()->select(nextline, this->hexCursor()->column()); + } + else if(e->matches(QKeySequence::MoveToPreviousLine) || + e->matches(QKeySequence::SelectPreviousLine)) { + if(!this->hexCursor()->line()) + return true; + auto prevline = this->hexCursor()->line() - 1; + if(e->matches(QKeySequence::MoveToPreviousLine)) + this->hexCursor()->move(prevline, this->hexCursor()->column()); + else + this->hexCursor()->select(prevline, this->hexCursor()->column()); + } + else if(e->matches(QKeySequence::MoveToNextPage) || + e->matches(QKeySequence::SelectNextPage)) { + if(this->lastLine() == this->hexCursor()->line()) + return true; + auto pageline = qMin(this->lastLine(), + this->hexCursor()->line() + this->visibleLines()); + if(e->matches(QKeySequence::MoveToNextPage)) + this->hexCursor()->move(pageline, this->hexCursor()->column()); + else + this->hexCursor()->select(pageline, this->hexCursor()->column()); + } + else if(e->matches(QKeySequence::MoveToPreviousPage) || + e->matches(QKeySequence::SelectPreviousPage)) { + if(!this->hexCursor()->line()) + return true; + auto pageline = + qMax(0, this->hexCursor()->line() - this->visibleLines()); + if(e->matches(QKeySequence::MoveToPreviousPage)) + this->hexCursor()->move(pageline, this->hexCursor()->column()); + else + this->hexCursor()->select(pageline, this->hexCursor()->column()); + } + else if(e->matches(QKeySequence::MoveToStartOfDocument) || + e->matches(QKeySequence::SelectStartOfDocument)) { + if(!this->hexCursor()->line()) + return true; + if(e->matches(QKeySequence::MoveToStartOfDocument)) + this->hexCursor()->move(0, 0); + else + this->hexCursor()->select(0, 0); + } + else if(e->matches(QKeySequence::MoveToEndOfDocument) || + e->matches(QKeySequence::SelectEndOfDocument)) { + if(this->lastLine() == this->hexCursor()->line()) + return true; + if(e->matches(QKeySequence::MoveToEndOfDocument)) + this->hexCursor()->move( + this->lastLine(), + this->getLastColumn(this->hexCursor()->line())); + else + this->hexCursor()->select(this->lastLine(), + this->getLastColumn(this->lastLine())); + } + else if(e->matches(QKeySequence::MoveToStartOfLine) || + e->matches(QKeySequence::SelectStartOfLine)) { + auto offset = + this->hexCursor()->positionToOffset({this->hexCursor()->line(), 0}); + if(e->matches(QKeySequence::MoveToStartOfLine)) + this->hexCursor()->move(offset); + else + this->hexCursor()->select(offset); + } + else if(e->matches(QKeySequence::SelectEndOfLine) || + e->matches(QKeySequence::MoveToEndOfLine)) { + auto offset = this->hexCursor()->positionToOffset( + {this->hexCursor()->line(), + this->getLastColumn(this->hexCursor()->line())}); + if(e->matches(QKeySequence::SelectEndOfLine)) + this->hexCursor()->select(offset); + else + this->hexCursor()->move(offset); + } + else + return false; + + return true; +} + +bool QHexView::keyPressTextInput(QKeyEvent* e) { + if(m_readonly || e->text().isEmpty() || + (e->modifiers() & Qt::ControlModifier)) + return false; + + bool atend = m_hexcursor->offset() >= m_hexdocument->length(); + if(atend && m_hexcursor->mode() == QHexCursor::Mode::Overwrite) + return false; + + char key = e->text().at(0).toLatin1(); + + switch(m_currentarea) { + case QHexArea::Hex: { + if(!QHexUtils::isHex(key)) + return false; + + bool ok = false; + auto val = static_cast(QString(key).toUInt(&ok, 16)); + if(!ok) + return false; + m_hexcursor->removeSelection(); + + quint8 ch = m_hexdocument->isEmpty() || + m_hexcursor->offset() >= m_hexdocument->length() + ? '\x00' + : m_hexdocument->at(m_hexcursor->offset()); + ch = m_writing ? (ch << 4) | val : val; + + if(!m_writing && (m_hexcursor->mode() == QHexCursor::Mode::Insert)) + m_hexdocument->insert(m_hexcursor->offset(), val); + else + m_hexdocument->replace(m_hexcursor->offset(), ch); + + m_writing = !m_writing; + if(!m_writing) + this->moveNext(); + + break; + } + + case QHexArea::Ascii: { + if(!QChar::isPrint(key)) + return false; + m_hexcursor->removeSelection(); + if(m_hexcursor->mode() == QHexCursor::Mode::Insert) + m_hexdocument->insert(m_hexcursor->offset(), key); + else + m_hexdocument->replace(m_hexcursor->offset(), key); + this->moveNext(); + break; + } + + default: return false; + } + + return true; +} + +bool QHexView::keyPressAction(QKeyEvent* e) { + if(e->modifiers() != Qt::NoModifier) { + if(e->matches(QKeySequence::SelectAll)) + this->selectAll(); + else if(!m_readonly && e->matches(QKeySequence::Undo)) + this->undo(); + else if(!m_readonly && e->matches(QKeySequence::Redo)) + this->redo(); + else if(!m_readonly && e->matches(QKeySequence::Cut)) + this->cut(m_currentarea != QHexArea::Ascii); + else if(e->matches(QKeySequence::Copy)) + this->copy(m_currentarea != QHexArea::Ascii); + else if(!m_readonly && e->matches(QKeySequence::Paste)) + this->paste(m_currentarea != QHexArea::Ascii); + else + return false; + + return true; + } + + if(m_readonly) + return false; + + switch(e->key()) { + case Qt::Key_Backspace: + case Qt::Key_Delete: { + if(!m_hexcursor->hasSelection()) { + auto offset = m_hexcursor->offset(); + if(offset <= 0) + return true; + + if(e->key() == Qt::Key_Backspace) + m_hexdocument->remove(offset - 1, 1); + else + m_hexdocument->remove(offset, 1); + } + else { + auto oldpos = m_hexcursor->selectionStart(); + m_hexcursor->removeSelection(); + m_hexcursor->move(oldpos); + } + + if(e->key() == Qt::Key_Backspace) + this->movePrevious(); + m_writing = false; + break; + } + + case Qt::Key_Insert: + m_writing = false; + m_hexcursor->switchMode(); + break; + + default: return false; + } + + return true; +} + +bool QHexView::event(QEvent* e) { + switch(e->type()) { + case QEvent::FontChange: + m_fontmetrics = QFontMetricsF(this->font()); + this->checkAndUpdate(true); + return true; + + case QEvent::ToolTip: { + if(m_hexdocument && (m_currentarea == QHexArea::Hex || + m_currentarea == QHexArea::Ascii)) { + auto* helpevent = static_cast(e); + auto pos = this->positionFromPoint(helpevent->pos()); + auto comment = m_hexmetadata->getComment(pos.line, pos.column); + if(!comment.isEmpty()) + QToolTip::showText(helpevent->globalPos(), comment); + return true; + } + + break; + } + + default: break; + } + + return QAbstractScrollArea::event(e); +} + +void QHexView::showEvent(QShowEvent* e) { + QAbstractScrollArea::showEvent(e); + this->checkAndUpdate(true); +} + +void QHexView::paintEvent(QPaintEvent*) { + if(!m_hexdocument) + return; + + QPainter painter(this->viewport()); + if(m_hexdelegate) + m_hexdelegate->paint(&painter, this); + else + this->paint(&painter); +} + +void QHexView::resizeEvent(QResizeEvent* e) { + this->checkState(); + QAbstractScrollArea::resizeEvent(e); +} + +void QHexView::focusInEvent(QFocusEvent* e) { + QAbstractScrollArea::focusInEvent(e); + if(m_hexdocument) + this->viewport()->update(); +} + +void QHexView::focusOutEvent(QFocusEvent* e) { + QAbstractScrollArea::focusOutEvent(e); + if(m_hexdocument) + this->viewport()->update(); +} + +void QHexView::mousePressEvent(QMouseEvent* e) { + QAbstractScrollArea::mousePressEvent(e); + if(!m_hexdocument || e->button() != Qt::LeftButton) + return; + + auto pos = this->positionFromPoint(e->pos()); + if(!pos.isValid()) + return; + + auto area = this->areaFromPoint(e->pos()); + qhexview_fmtprint("%d", static_cast(area)); + + switch(area) { + case QHexArea::Address: this->hexCursor()->move(pos.line, 0); break; + case QHexArea::Hex: + m_currentarea = area; + this->hexCursor()->move(pos); + break; + case QHexArea::Ascii: + m_currentarea = area; + this->hexCursor()->move(pos.line, pos.column); + break; + default: return; + } + + this->viewport()->update(); +} + +void QHexView::mouseMoveEvent(QMouseEvent* e) { + QAbstractScrollArea::mouseMoveEvent(e); + if(!this->hexCursor()) + return; + + e->accept(); + auto area = this->areaFromPoint(e->pos()); + + switch(area) { + case QHexArea::Header: + this->viewport()->setCursor(Qt::ArrowCursor); + return; + case QHexArea::Address: + this->viewport()->setCursor(Qt::ArrowCursor); + break; + default: this->viewport()->setCursor(Qt::IBeamCursor); break; + } + + if(e->buttons() == Qt::LeftButton) { + auto pos = this->positionFromPoint(e->pos()); + if(!pos.isValid()) + return; + if(area == QHexArea::Ascii || area == QHexArea::Hex) + m_currentarea = area; + this->hexCursor()->select(pos); + } +} + +void QHexView::wheelEvent(QWheelEvent* e) { + e->ignore(); + +#if defined(Q_OS_OSX) + // In macOS scrollbar invisibility should not prevent scrolling from working + if(!m_hexdocument) + return; +#else + if(!m_hexdocument || !this->verticalScrollBar()->isVisible()) + return; +#endif + + // https://doc.qt.io/qt-6/qwheelevent.html + // "Returns the relative amount that the wheel was rotated, in eighths of a + // degree." "Most mouse types work in steps of 15 degrees, in which case the + // delta value is a multiple of 120; i.e., 120 units * 1/8 = 15 degrees." + int const ydelta = e->angleDelta().y(); + if(0 != ydelta) { + int const ydeltaAbsolute = qAbs(ydelta); + int const numberOfLinesToMove = + (ydeltaAbsolute * m_options.scrollsteps + 119) / + 120; // always move at least 1 line + int const ydeltaSign = ydelta / ydeltaAbsolute; + + int const oldValue = this->verticalScrollBar()->value(); + int const newValue = oldValue - ydeltaSign * numberOfLinesToMove; + this->verticalScrollBar()->setValue(newValue); + } +} + +void QHexView::keyPressEvent(QKeyEvent* e) { + bool handled = false; + + if(this->hexCursor()) { + handled = this->keyPressMove(e); + if(!handled) + handled = this->keyPressAction(e); + if(!handled) + handled = this->keyPressTextInput(e); + } + + if(handled) + e->accept(); + else + QAbstractScrollArea::keyPressEvent(e); +} + +QString QHexView::reduced(const QString& s, int maxlen) { + if(s.length() <= maxlen) + return s.leftJustified(maxlen); + return s.mid(0, maxlen - 1) + "\u2026"; +} + +bool QHexView::isColorLight(QColor c) { + return std::sqrt(0.299 * std::pow(c.red(), 2) + + 0.587 * std::pow(c.green(), 2) + + 0.114 * std::pow(c.blue(), 2)) > 127.5; +} + +QColor QHexView::getReadableColor(QColor c) const { + QPalette palette = this->palette(); + return QHexView::isColorLight(c) + ? palette.color(QPalette::Normal, QPalette::WindowText) + : palette.color(QPalette::Normal, QPalette::HighlightedText); +} + +QByteArray QHexView::selectedBytes() const { + return m_hexcursor->hasSelection() + ? m_hexdocument->read(m_hexcursor->selectionStartOffset(), + m_hexcursor->selectionLength()) + : QByteArray{}; +} +QByteArray QHexView::getLine(qint64 line) const { + return m_hexdocument ? m_hexdocument->read(line * m_options.linelength, + m_options.linelength) + : QByteArray{}; +} diff --git a/UEFITool/ffsfinder.cpp b/UEFITool/ffsfinder.cpp index 20e6c8e..51a2f0e 100644 --- a/UEFITool/ffsfinder.cpp +++ b/UEFITool/ffsfinder.cpp @@ -1,64 +1,118 @@ -/* fssfinder.cpp +/* ffsfinder.cpp -Copyright (c) 2015, Nikolaj Schlej. All rights reserved. -This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -*/ + Copyright (c) 2015, Nikolaj Schlej. All rights reserved. + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + */ #include "ffsfinder.h" +#if QT_VERSION_MAJOR >= 6 +#include +#else +#include +#endif + +USTATUS FfsFinder::findHexPattern(const UByteArray & hexPattern, const UINT8 mode) { + const UModelIndex rootIndex = model->index(0, 0); + USTATUS ret = findHexPattern(rootIndex, hexPattern, mode); + if (ret != U_SUCCESS) + msg(UString("Hex pattern \"") + UString(hexPattern) + UString("\" could not be found"), rootIndex); + return ret; +} + USTATUS FfsFinder::findHexPattern(const UModelIndex & index, const UByteArray & hexPattern, const UINT8 mode) { if (!index.isValid()) return U_SUCCESS; - + if (hexPattern.isEmpty()) return U_INVALID_PARAMETER; - + // Check for "all substrings" pattern if (hexPattern.count('.') == hexPattern.length()) return U_SUCCESS; - + + USTATUS ret = U_ITEM_NOT_FOUND; bool hasChildren = (model->rowCount(index) > 0); for (int i = 0; i < model->rowCount(index); i++) { - findHexPattern(index.child(i, index.column()), hexPattern, mode); + if (U_SUCCESS == findHexPattern(index.model()->index(i, index.column(), index), hexPattern, mode)) + ret = U_SUCCESS; } - + UByteArray data; if (hasChildren) { - if (mode != SEARCH_MODE_BODY) + if (mode == SEARCH_MODE_HEADER) data = model->header(index); + else if (mode == SEARCH_MODE_ALL) + data = model->header(index) + model->body(index); } else { if (mode == SEARCH_MODE_HEADER) - data.append(model->header(index)); + data = model->header(index); else if (mode == SEARCH_MODE_BODY) - data.append(model->body(index)); + data = model->body(index); else - data.append(model->header(index)).append(model->body(index)); + data = model->header(index) + model->body(index); } - + UString hexBody = UString(data.toHex()); +#if QT_VERSION_MAJOR >= 6 + QRegularExpression regexp = QRegularExpression(UString(hexPattern)); + regexp.setPatternOptions(QRegularExpression::CaseInsensitiveOption); + QRegularExpressionMatch regexpmatch; + + INT32 offset = (INT32)hexBody.indexOf(regexp, 0, ®expmatch); +#else QRegExp regexp = QRegExp(UString(hexPattern), Qt::CaseInsensitive); + INT32 offset = regexp.indexIn(hexBody); +#endif while (offset >= 0) { if (offset % 2 == 0) { - msg(UString("Hex pattern \"") + UString(hexPattern) - + UString("\" found as \"") + hexBody.mid(offset, hexPattern.length()).toUpper() - + UString("\" in ") + model->name(index) - + usprintf(" at %s-offset %02Xh", mode == SEARCH_MODE_BODY ? "body" : "header", offset / 2), - index); + // For patterns that cross header|body boundary, skip patterns entirely located in body, since + // children search above has already found them. + if (!(hasChildren && mode == SEARCH_MODE_ALL && offset/2 >= model->header(index).size())) { + UModelIndex parentFileIndex = model->findParentOfType(index, Types::File); + UString name = model->name(index); + if (model->parent(index) == parentFileIndex) { + name = model->name(parentFileIndex) + UString("/") + name; + } + else if (parentFileIndex.isValid()) { + name = model->name(parentFileIndex) + UString("/.../") + name; + } + + msg(UString("Hex pattern \"") + UString(hexPattern) + + UString("\" found as \"") + hexBody.mid(offset, hexPattern.length()).toUpper() + + UString("\" in ") + name + + usprintf(" at %s-offset %02Xh", mode == SEARCH_MODE_BODY ? "body" : "header", offset / 2), + index); + ret = U_SUCCESS; + } } + +#if QT_VERSION_MAJOR >= 6 + offset = (INT32)hexBody.indexOf(regexp, (qsizetype)offset + 1, ®expmatch); +#else offset = regexp.indexIn(hexBody, offset + 1); +#endif } - return U_SUCCESS; + return ret; +} + +USTATUS FfsFinder::findGuidPattern(const UByteArray & guidPattern, const UINT8 mode) { + const UModelIndex rootIndex = model->index(0, 0); + USTATUS ret = findGuidPattern(rootIndex, guidPattern, mode); + if (ret != U_SUCCESS) + msg(UString("GUID pattern \"") + UString(guidPattern) + UString("\" could not be found"), rootIndex); + return ret; } USTATUS FfsFinder::findGuidPattern(const UModelIndex & index, const UByteArray & guidPattern, const UINT8 mode) @@ -69,9 +123,11 @@ USTATUS FfsFinder::findGuidPattern(const UModelIndex & index, const UByteArray & if (!index.isValid()) return U_SUCCESS; + USTATUS ret = U_ITEM_NOT_FOUND; bool hasChildren = (model->rowCount(index) > 0); for (int i = 0; i < model->rowCount(index); i++) { - findGuidPattern(index.child(i, index.column()), guidPattern, mode); + if (U_SUCCESS == findGuidPattern(index.model()->index(i, index.column(), index), guidPattern, mode)) + ret = U_SUCCESS; } UByteArray data; @@ -112,20 +168,53 @@ USTATUS FfsFinder::findGuidPattern(const UModelIndex & index, const UByteArray & if (hexPattern.count('.') == hexPattern.length()) return U_SUCCESS; +#if QT_VERSION_MAJOR >= 6 + QRegularExpression regexp((QString)UString(hexPattern)); + regexp.setPatternOptions(QRegularExpression::CaseInsensitiveOption); + QRegularExpressionMatch regexpmatch; + + INT32 offset = (INT32)hexBody.indexOf(regexp, 0, ®expmatch); +#else QRegExp regexp(UString(hexPattern), Qt::CaseInsensitive); + INT32 offset = regexp.indexIn(hexBody); +#endif while (offset >= 0) { if (offset % 2 == 0) { + UModelIndex parentFileIndex = model->findParentOfType(index, Types::File); + UString name = model->name(index); + if (model->parent(index) == parentFileIndex) { + name = model->name(parentFileIndex) + UString("/") + name; + } + else if (parentFileIndex.isValid()) { + name = model->name(parentFileIndex) + UString("/.../") + name; + } + msg(UString("GUID pattern \"") + UString(guidPattern) + UString("\" found as \"") + hexBody.mid(offset, hexPattern.length()).toUpper() - + UString("\" in ") + model->name(index) + + UString("\" in ") + name + usprintf(" at %s-offset %02Xh", mode == SEARCH_MODE_BODY ? "body" : "header", offset / 2), index); + ret = U_SUCCESS; } + +#if QT_VERSION_MAJOR >= 6 + offset = (INT32)hexBody.indexOf(regexp, (qsizetype)offset + 1, ®expmatch); +#else offset = regexp.indexIn(hexBody, offset + 1); +#endif } - return U_SUCCESS; + return ret; +} + +USTATUS FfsFinder::findTextPattern(const UString & pattern, const UINT8 mode, const bool unicode, const Qt::CaseSensitivity caseSensitive) { + const UModelIndex rootIndex = model->index(0, 0); + USTATUS ret = findTextPattern(rootIndex, pattern, mode, unicode, caseSensitive); + if (ret != U_SUCCESS) + msg((unicode ? UString("Unicode") : UString("ASCII")) + UString(" text \"") + + UString(pattern) + UString("\" could not be found"), rootIndex); + return ret; } USTATUS FfsFinder::findTextPattern(const UModelIndex & index, const UString & pattern, const UINT8 mode, const bool unicode, const Qt::CaseSensitivity caseSensitive) @@ -136,9 +225,11 @@ USTATUS FfsFinder::findTextPattern(const UModelIndex & index, const UString & pa if (!index.isValid()) return U_SUCCESS; + USTATUS ret = U_ITEM_NOT_FOUND; bool hasChildren = (model->rowCount(index) > 0); for (int i = 0; i < model->rowCount(index); i++) { - findTextPattern(index.child(i, index.column()), pattern, mode, unicode, caseSensitive); + if (U_SUCCESS == findTextPattern(index.model()->index(i, index.column(), index), pattern, mode, unicode, caseSensitive)) + ret = U_SUCCESS; } UByteArray body; @@ -155,20 +246,31 @@ USTATUS FfsFinder::findTextPattern(const UModelIndex & index, const UString & pa body.append(model->header(index)).append(model->body(index)); } - UString data; + UString data = UString::fromLatin1((const char*)body.constData(), body.length()); + + UString searchPattern; if (unicode) - data = UString::fromUtf16((const ushort*)body.constData(), body.length() / 2); + searchPattern = UString::fromLatin1((const char*)pattern.utf16(), pattern.length() * 2); else - data = UString::fromLatin1((const char*)body.constData(), body.length()); + searchPattern = pattern; int offset = -1; - while ((offset = data.indexOf(pattern, offset + 1, caseSensitive)) >= 0) { + while ((offset = (int)data.indexOf(searchPattern, (int)(offset + 1), caseSensitive)) >= 0) { + UModelIndex parentFileIndex = model->findParentOfType(index, Types::File); + UString name = model->name(index); + if (model->parent(index) == parentFileIndex) { + name = model->name(parentFileIndex) + UString("/") + name; + } + else if (parentFileIndex.isValid()) { + name = model->name(parentFileIndex) + UString("/.../") + name; + } msg((unicode ? UString("Unicode") : UString("ASCII")) + UString(" text \"") + UString(pattern) - + UString("\" found in ") + model->name(index) - + usprintf(" at %s-offset %02Xh", mode == SEARCH_MODE_BODY ? "body" : "header", (unicode ? offset * 2 : offset)), + + UString("\" found in ") + name + + usprintf(" at %s-offset %02Xh", mode == SEARCH_MODE_BODY ? "body" : "header", offset), index); + ret = U_SUCCESS; } - return U_SUCCESS; + return ret; } diff --git a/UEFITool/ffsfinder.h b/UEFITool/ffsfinder.h index b88866b..059f376 100644 --- a/UEFITool/ffsfinder.h +++ b/UEFITool/ffsfinder.h @@ -15,7 +15,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #define FFSFINDER_H #include -#include #include "../common/ubytearray.h" #include "../common/ustring.h" @@ -31,9 +30,9 @@ public: std::vector > getMessages() const { return messagesVector; } void clearMessages() { messagesVector.clear(); } - USTATUS findHexPattern(const UModelIndex & index, const UByteArray & hexPattern, const UINT8 mode); - USTATUS findGuidPattern(const UModelIndex & index, const UByteArray & guidPattern, const UINT8 mode); - USTATUS findTextPattern(const UModelIndex & index, const UString & pattern, const UINT8 mode, const bool unicode, const Qt::CaseSensitivity caseSensitive); + USTATUS findHexPattern(const UByteArray & hexPattern, const UINT8 mode); + USTATUS findGuidPattern(const UByteArray & guidPattern, const UINT8 mode); + USTATUS findTextPattern(const UString & pattern, const UINT8 mode, const bool unicode, const Qt::CaseSensitivity caseSensitive); private: const TreeModel* model; @@ -42,6 +41,10 @@ private: void msg(const UString & message, const UModelIndex &index = UModelIndex()) { messagesVector.push_back(std::pair(message, index)); } + + USTATUS findHexPattern(const UModelIndex & index, const UByteArray & hexPattern, const UINT8 mode); + USTATUS findGuidPattern(const UModelIndex & index, const UByteArray & guidPattern, const UINT8 mode); + USTATUS findTextPattern(const UModelIndex & index, const UString & pattern, const UINT8 mode, const bool unicode, const Qt::CaseSensitivity caseSensitive); }; #endif // FFSFINDER_H diff --git a/UEFITool/gotoaddressdialog.h b/UEFITool/gotoaddressdialog.h new file mode 100644 index 0000000..1d2948a --- /dev/null +++ b/UEFITool/gotoaddressdialog.h @@ -0,0 +1,36 @@ +/* gotoaddressdialog.h + + Copyright (c) 2018, Nikolaj Schlej. All rights reserved. + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + */ + +#ifndef GOTOADDRESSDIALOG_H +#define GOTOADDRESSDIALOG_H + +#include +#include +#include "ui_gotoaddressdialog.h" +class GoToAddressDialog : public QDialog +{ + Q_OBJECT + +public: + GoToAddressDialog(QWidget* parent = NULL) : + QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint), + ui(new Ui::GoToAddressDialog) { + ui->setupUi(this); + } + + ~GoToAddressDialog() { delete ui; } + + Ui::GoToAddressDialog* ui; +}; + +#endif // GOTOADDRESSDIALOG_H diff --git a/UEFITool/gotoaddressdialog.ui b/UEFITool/gotoaddressdialog.ui new file mode 100644 index 0000000..8531019 --- /dev/null +++ b/UEFITool/gotoaddressdialog.ui @@ -0,0 +1,133 @@ + + + GoToAddressDialog + + + + 0 + 0 + 270 + 86 + + + + Select item at address + + + false + + + + 5 + + + 5 + + + 5 + + + 5 + + + 5 + + + + + + + + + 5 + + + 5 + + + 5 + + + 5 + + + 5 + + + + + Select item at address: + + + + + + + + 0 + 0 + + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + HexSpinBox + QSpinBox +
hexspinbox.h
+
+
+ + buttonBox + + + + + buttonBox + accepted() + GoToAddressDialog + accept() + + + 182 + 185 + + + 157 + 194 + + + + + buttonBox + rejected() + GoToAddressDialog + reject() + + + 182 + 185 + + + 286 + 194 + + + + +
diff --git a/UEFITool/gotobasedialog.h b/UEFITool/gotobasedialog.h new file mode 100644 index 0000000..806eedf --- /dev/null +++ b/UEFITool/gotobasedialog.h @@ -0,0 +1,36 @@ +/* gotobasedialog.h + + Copyright (c) 2018, Nikolaj Schlej. All rights reserved. + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + */ + +#ifndef GOTOBASEDIALOG_H +#define GOTOBASEDIALOG_H + +#include +#include +#include "ui_gotobasedialog.h" +class GoToBaseDialog : public QDialog +{ + Q_OBJECT + +public: + GoToBaseDialog(QWidget* parent = NULL): + QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint), + ui(new Ui::GoToBaseDialog) { + ui->setupUi(this); + } + + ~GoToBaseDialog() {delete ui;} + + Ui::GoToBaseDialog* ui; +}; + +#endif // GOTOBASEDIALOG_H diff --git a/UEFITool/gotobasedialog.ui b/UEFITool/gotobasedialog.ui new file mode 100644 index 0000000..0572b1a --- /dev/null +++ b/UEFITool/gotobasedialog.ui @@ -0,0 +1,133 @@ + + + GoToBaseDialog + + + + 0 + 0 + 270 + 86 + + + + Select item at base + + + false + + + + 5 + + + 5 + + + 5 + + + 5 + + + 5 + + + + + + + + + 5 + + + 5 + + + 5 + + + 5 + + + 5 + + + + + Select item at base: + + + + + + + + 0 + 0 + + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + HexSpinBox + QSpinBox +
hexspinbox.h
+
+
+ + buttonBox + + + + + buttonBox + accepted() + GoToBaseDialog + accept() + + + 182 + 185 + + + 157 + 194 + + + + + buttonBox + rejected() + GoToBaseDialog + reject() + + + 182 + 185 + + + 286 + 194 + + + + +
diff --git a/UEFITool/guidlineedit.cpp b/UEFITool/guidlineedit.cpp deleted file mode 100644 index bf706f5..0000000 --- a/UEFITool/guidlineedit.cpp +++ /dev/null @@ -1,61 +0,0 @@ -/* guidlineedit.cpp - - Copyright (c) 2014, Nikolaj Schlej. All rights reserved. - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - */ - -#include "guidlineedit.h" - -GuidLineEdit::GuidLineEdit(QWidget * parent) - :QLineEdit(parent) -{ -} - -GuidLineEdit::GuidLineEdit(const QString & contents, QWidget * parent) - :QLineEdit(contents, parent) -{ -} - -GuidLineEdit::~GuidLineEdit() -{ -} - -void GuidLineEdit::keyPressEvent(QKeyEvent * event) -{ - if (event == QKeySequence::Delete || event->key() == Qt::Key_Backspace) - { - int pos = cursorPosition(); - if (event->key() == Qt::Key_Backspace && pos > 0) { - cursorBackward(false); - pos = cursorPosition(); - } - - QString txt = text(); - QString selected = selectedText(); - - if (!selected.isEmpty()) { - pos = QLineEdit::selectionStart(); - for (int i = pos; i < pos + selected.count(); i++) - if (txt[i] != QChar('-')) - txt[i] = QChar('.'); - } - else - txt[pos] = QChar('.'); - - setCursorPosition(0); - insert(txt); - setCursorPosition(pos); - - return; - } - - // Call original event handler - QLineEdit::keyPressEvent(event); -} \ No newline at end of file diff --git a/UEFITool/hexlineedit.cpp b/UEFITool/hexlineedit.cpp new file mode 100644 index 0000000..e646dde --- /dev/null +++ b/UEFITool/hexlineedit.cpp @@ -0,0 +1,86 @@ +/* hexlineedit.cpp + + Copyright (c) 2014, Nikolaj Schlej. All rights reserved. + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + */ + +#include "hexlineedit.h" + +#if QT_VERSION_MAJOR >= 6 +#include +#else +#include +#endif + +HexLineEdit::HexLineEdit(QWidget * parent) +:QLineEdit(parent) +{ + m_editAsGuid = false; +} + +HexLineEdit::HexLineEdit(const QString & contents, QWidget * parent) +:QLineEdit(contents, parent) +{ + m_editAsGuid = false; +} + +HexLineEdit::~HexLineEdit() +{ +} + +void HexLineEdit::keyPressEvent(QKeyEvent * event) +{ + QClipboard *clipboard; + QString originalText; + + if (m_editAsGuid && (event == QKeySequence::Delete || event->key() == Qt::Key_Backspace)) + { + int pos = cursorPosition(); + if (event->key() == Qt::Key_Backspace && pos > 0) { + cursorBackward(false); + pos = cursorPosition(); + } + + QString txt = text(); + QString selected = selectedText(); + + if (!selected.isEmpty()) { + pos = QLineEdit::selectionStart(); + for (int i = pos; i < pos + selected.length(); i++) + if (txt[i] != QChar('-')) + txt[i] = QChar('.'); + } + else { + txt[pos] = QChar('.'); + } + + setCursorPosition(0); + insert(txt); + setCursorPosition(pos); + + return; + } + + if (event == QKeySequence::Paste) + { + clipboard = QApplication::clipboard(); + originalText = clipboard->text(); + QString cleanedHex = QString(originalText).replace(QString("0x"), QString(""), Qt::CaseInsensitive); +#if QT_VERSION_MAJOR >= 6 + cleanedHex.remove(QRegularExpression("[^a-fA-F\\d]+")); +#else + cleanedHex.remove(QRegExp("[^a-fA-F\\d]+")); +#endif + clipboard->setText(cleanedHex); + } + + // Call original event handler + QLineEdit::keyPressEvent(event); +} diff --git a/UEFITool/guidlineedit.h b/UEFITool/hexlineedit.h similarity index 54% rename from UEFITool/guidlineedit.h rename to UEFITool/hexlineedit.h index e9a4bc4..d1dc672 100644 --- a/UEFITool/guidlineedit.h +++ b/UEFITool/hexlineedit.h @@ -1,4 +1,4 @@ -/* guidlineedit.h +/* hexlineedit.h Copyright (c) 2014, Nikolaj Schlej. All rights reserved. This program and the accompanying materials @@ -11,9 +11,11 @@ */ -#ifndef GUIDLINEEDIT_H -#define GUIDLINEEDIT_H +#ifndef HEXLINEEDIT_H +#define HEXLINEEDIT_H +#include +#include #include #include #include @@ -21,16 +23,29 @@ #include "../common/basetypes.h" -class GuidLineEdit : public QLineEdit +class HexLineEdit : public QLineEdit { + Q_OBJECT + Q_PROPERTY(bool editAsGuid READ editAsGuid WRITE setEditAsGuid) + public: - GuidLineEdit(QWidget * parent = 0); - GuidLineEdit(const QString & contents, QWidget * parent = 0); - ~GuidLineEdit(); + HexLineEdit(QWidget * parent = 0); + HexLineEdit(const QString & contents, QWidget * parent = 0); + ~HexLineEdit(); + + void setEditAsGuid(bool editAsGuid) + { + m_editAsGuid = editAsGuid; + } + bool editAsGuid() const + { return m_editAsGuid; } + +private: + bool m_editAsGuid; protected: void keyPressEvent(QKeyEvent * event); }; -#endif // GUIDLINEEDIT_H +#endif // HEXLINEEDIT_H diff --git a/UEFITool/hexspinbox.cpp b/UEFITool/hexspinbox.cpp new file mode 100644 index 0000000..738a7cc --- /dev/null +++ b/UEFITool/hexspinbox.cpp @@ -0,0 +1,41 @@ +/* hexspinbox.cpp + + Copyright (c) 2016, Nikolaj Schlej. All rights reserved. + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + */ + +#include "hexspinbox.h" +#include + +HexSpinBox::HexSpinBox(QWidget *parent) : +#if QT_VERSION_MAJOR >= 6 +QSpinBox(parent), validator(QRegularExpression("0x([0-9a-fA-F]){1,8}")) +#else +QSpinBox(parent), validator(QRegExp("0x([0-9a-fA-F]){1,8}")) +#endif +{ + this->setRange(INT_MIN, INT_MAX); + this->setPrefix("0x"); +} + +QValidator::State HexSpinBox::validate(QString &text, int &pos) const +{ + return validator.validate(text, pos); +} + +QString HexSpinBox::textFromValue(int val) const +{ + return QString::number((uint)val, 16).toUpper(); +} + +int HexSpinBox::valueFromText(const QString &text) const +{ + return (int)text.toUInt(NULL, 16); +} diff --git a/UEFITool/hexspinbox.h b/UEFITool/hexspinbox.h new file mode 100644 index 0000000..51a4180 --- /dev/null +++ b/UEFITool/hexspinbox.h @@ -0,0 +1,45 @@ +/* hexspinbox.h + + Copyright (c) 2016, Nikolaj Schlej. All rights reserved. + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + */ + +#ifndef HEXSPINBOX_H +#define HEXSPINBOX_H + +#include + +#if QT_VERSION_MAJOR >= 6 +#include +#else +#include +#endif + +class HexSpinBox : public QSpinBox +{ + Q_OBJECT + +public: + HexSpinBox(QWidget *parent = 0); + +protected: + QValidator::State validate(QString &text, int &pos) const; + int valueFromText(const QString &text) const; + QString textFromValue(int value) const; + +private: +#if QT_VERSION_MAJOR >= 6 + QRegularExpressionValidator validator; +#else + QRegExpValidator validator; +#endif +}; + +#endif // HEXSPINBOX_H diff --git a/UEFITool/hexviewdialog.cpp b/UEFITool/hexviewdialog.cpp index 60ac464..39b5559 100644 --- a/UEFITool/hexviewdialog.cpp +++ b/UEFITool/hexviewdialog.cpp @@ -1,15 +1,15 @@ /* hexviewdialog.cpp - - Copyright (c) 2016, Nikolaj Schlej. All rights reserved. - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - */ + + Copyright (c) 2016, Nikolaj Schlej. All rights reserved. + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + */ #include "hexviewdialog.h" @@ -20,9 +20,8 @@ hexView(NULL) { // Create UI ui->setupUi(this); - hexView = new QHexEdit(this); + hexView = new QHexView(this); hexView->setReadOnly(true); - hexView->setUpperCase(true); ui->layout->addWidget(hexView); } @@ -37,16 +36,33 @@ void HexViewDialog::setFont(const QFont &font) hexView->setFont(font); } -void HexViewDialog::setItem(const UModelIndex & index) +void HexViewDialog::setItem(const UModelIndex & index, HexViewType type) { const TreeModel * model = (const TreeModel*)index.model(); - - // Set dialog title UString itemName = model->name(index); UString itemText = model->text(index); - setWindowTitle(UString("Hex view: ") + (itemText.isEmpty() ? itemName : itemName + " | " + itemText)); - // Set hex data - QByteArray data = model->header(index) + model->body(index) + model->tail(index); - hexView->setData(data); -} \ No newline at end of file + // Set hex data and dialog title + QByteArray hexdata; + UString dialogTitle; + + switch (type) { + case fullHexView: + dialogTitle = UString("Hex view: "); + hexdata = model->header(index) + model->body(index) + model->tail(index); + break; + case bodyHexView: + dialogTitle = UString("Body hex view: "); + hexdata = model->body(index); + break; + case uncompressedHexView: + dialogTitle = UString("Uncompressed hex view: "); + hexdata = model->uncompressedData(index); + break; + } + + dialogTitle += itemText.isEmpty() ? itemName : itemName + " | " + itemText; + setWindowTitle(dialogTitle); + hexView->setData(hexdata); + hexView->setFont(QApplication::font()); +} diff --git a/UEFITool/hexviewdialog.h b/UEFITool/hexviewdialog.h index 0cd2fe9..18eaacc 100644 --- a/UEFITool/hexviewdialog.h +++ b/UEFITool/hexviewdialog.h @@ -15,8 +15,8 @@ #define HEXVIEWDIALOG_H #include +#include #include "../common/treemodel.h" -#include "../qhexedit2/qhexedit.h" #include "ui_hexviewdialog.h" class HexViewDialog : public QDialog @@ -24,15 +24,21 @@ class HexViewDialog : public QDialog Q_OBJECT public: + enum HexViewType { + fullHexView, + bodyHexView, + uncompressedHexView + }; + HexViewDialog(QWidget *parent = 0); ~HexViewDialog(); Ui::HexViewDialog* ui; - void setItem(const UModelIndex & index); + void setItem(const UModelIndex & index, HexViewType dataType); void setFont(const QFont &font); - + private: - QHexEdit * hexView; + QHexView * hexView; }; #endif // HEXVIEWDIALOG_H diff --git a/UEFITool/icons/uefitool.icns b/UEFITool/icons/uefitool.icns index a332b70..d99f0f8 100644 Binary files a/UEFITool/icons/uefitool.icns and b/UEFITool/icons/uefitool.icns differ diff --git a/UEFITool/messagelistitem.cpp b/UEFITool/messagelistitem.cpp deleted file mode 100644 index 46b3f6b..0000000 --- a/UEFITool/messagelistitem.cpp +++ /dev/null @@ -1,44 +0,0 @@ -/* messagelistitem.cpp - - Copyright (c) 2013, Nikolaj Schlej. All rights reserved. - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - */ - -#include "messagelistitem.h" - -MessageListItem::MessageListItem(QListWidget * parent, int type, const QModelIndex & index) - : QListWidgetItem(parent, type) -{ - itemIndex = index; -} - -MessageListItem::MessageListItem(const QString & text, QListWidget * parent, int type, const QModelIndex & index) - : QListWidgetItem(text, parent, type), itemIndex(index) -{ -} - -MessageListItem::MessageListItem(const QIcon & icon, const QString & text, QListWidget * parent, int type, const QModelIndex & index) - : QListWidgetItem(icon, text, parent, type), itemIndex(index) -{ -} - -MessageListItem::~MessageListItem() -{ -} - -QModelIndex MessageListItem::index() const -{ - return itemIndex; -} - -void MessageListItem::setIndex(QModelIndex & index) -{ - itemIndex = index; -} \ No newline at end of file diff --git a/UEFITool/messagelistitem.h b/UEFITool/messagelistitem.h deleted file mode 100644 index dd579f2..0000000 --- a/UEFITool/messagelistitem.h +++ /dev/null @@ -1,37 +0,0 @@ -/* messagelistitem.h - - Copyright (c) 2014, Nikolaj Schlej. All rights reserved. - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - */ - -#ifndef MESSAGELISTITEM_H -#define MESSAGELISTITEM_H - -#include -#include - -#include "../common/basetypes.h" - -class MessageListItem : public QListWidgetItem -{ -public: - MessageListItem(QListWidget * parent = 0, int type = Type, const QModelIndex & index = QModelIndex()); - MessageListItem(const QString & text, QListWidget * parent = 0, int type = Type, const QModelIndex & index = QModelIndex()); - MessageListItem(const QIcon & icon, const QString & text, QListWidget * parent = 0, int type = Type, const QModelIndex & index = QModelIndex()); - ~MessageListItem(); - - QModelIndex index() const; - void setIndex(QModelIndex & index); - -private: - QModelIndex itemIndex; -}; - -#endif // MESSAGELISTITEM_H diff --git a/UEFITool/searchdialog.cpp b/UEFITool/searchdialog.cpp index c9b716d..9b864fe 100644 --- a/UEFITool/searchdialog.cpp +++ b/UEFITool/searchdialog.cpp @@ -1,32 +1,37 @@ /* searchdialog.cpp - - Copyright (c) 2014, Nikolaj Schlej. All rights reserved. - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - */ + + Copyright (c) 2014, Nikolaj Schlej. All rights reserved. + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + */ #include "searchdialog.h" SearchDialog::SearchDialog(QWidget *parent) : -QDialog(parent), +QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint), ui(new Ui::SearchDialog), +#if QT_VERSION_MAJOR >= 6 +hexValidator(QRegularExpression("([0-9a-fA-F\\. ])*")), +guidValidator(QRegularExpression("[0-9a-fA-F\\.]{8}-[0-9a-fA-F\\.]{4}-[0-9a-fA-F\\.]{4}-[0-9a-fA-F\\.]{4}-[0-9a-fA-F\\.]{12}")) +#else hexValidator(QRegExp("([0-9a-fA-F\\. ])*")), guidValidator(QRegExp("[0-9a-fA-F\\.]{8}-[0-9a-fA-F\\.]{4}-[0-9a-fA-F\\.]{4}-[0-9a-fA-F\\.]{4}-[0-9a-fA-F\\.]{12}")) +#endif { // Create UI ui->setupUi(this); ui->hexEdit->setValidator(&hexValidator); ui->guidEdit->setValidator(&guidValidator); - + // Connect connect(ui->tabWidget, SIGNAL(currentChanged(int)), this, SLOT(setEditFocus(int))); - + // Set initial focus setEditFocus(ui->tabWidget->currentIndex()); } @@ -46,4 +51,4 @@ void SearchDialog::setEditFocus(int index) } else if (index == 2) // Text ui->textEdit->setFocus(); -} \ No newline at end of file +} diff --git a/UEFITool/searchdialog.h b/UEFITool/searchdialog.h index 56a673c..6698506 100644 --- a/UEFITool/searchdialog.h +++ b/UEFITool/searchdialog.h @@ -15,7 +15,13 @@ #define SEARCHDIALOG_H #include + +#if QT_VERSION_MAJOR >= 6 +#include +#else #include +#endif + #include "ui_searchdialog.h" class SearchDialog : public QDialog @@ -31,8 +37,13 @@ private slots: void setEditFocus(int index); private: +#if QT_VERSION_MAJOR >= 6 + QRegularExpressionValidator hexValidator; + QRegularExpressionValidator guidValidator; +#else QRegExpValidator hexValidator; QRegExpValidator guidValidator; +#endif }; #endif // SEARCHDIALOG_H diff --git a/UEFITool/searchdialog.ui b/UEFITool/searchdialog.ui index 510a46f..5f321d0 100644 --- a/UEFITool/searchdialog.ui +++ b/UEFITool/searchdialog.ui @@ -35,7 +35,10 @@ - + + + false + @@ -89,7 +92,10 @@ - + + + true + xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx @@ -241,9 +247,9 @@ - GuidLineEdit + HexLineEdit QLineEdit -
guidlineedit.h
+
hexlineedit.h
diff --git a/UEFITool/uefitool.cpp b/UEFITool/uefitool.cpp index 574312e..aa6ac32 100644 --- a/UEFITool/uefitool.cpp +++ b/UEFITool/uefitool.cpp @@ -1,42 +1,53 @@ /* uefitool.cpp + + Copyright (c) 2022, Nikolaj Schlej. All rights reserved. + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + */ - Copyright (c) 2016, Nikolaj Schlej. All rights reserved. - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - */ - +#include "../version.h" #include "uefitool.h" #include "ui_uefitool.h" +#if QT_VERSION_MAJOR >= 6 +#include +#endif + UEFITool::UEFITool(QWidget *parent) : QMainWindow(parent), -ui(new Ui::UEFITool), -version(tr("NE Alpha32")) +ui(new Ui::UEFITool), +version(tr(PROGRAM_VERSION)), +markingEnabled(true) { clipboard = QApplication::clipboard(); - + // Create UI ui->setupUi(this); searchDialog = new SearchDialog(this); hexViewDialog = new HexViewDialog(this); + goToAddressDialog = new GoToAddressDialog(this); + goToBaseDialog = new GoToBaseDialog(this); model = NULL; ffsParser = NULL; ffsFinder = NULL; ffsOps = NULL; ffsBuilder = NULL; - + ffsReport = NULL; + // Connect signals to slots connect(ui->actionOpenImageFile, SIGNAL(triggered()), this, SLOT(openImageFile())); connect(ui->actionOpenImageFileInNewWindow, SIGNAL(triggered()), this, SLOT(openImageFileInNewWindow())); connect(ui->actionSaveImageFile, SIGNAL(triggered()), this, SLOT(saveImageFile())); connect(ui->actionSearch, SIGNAL(triggered()), this, SLOT(search())); connect(ui->actionHexView, SIGNAL(triggered()), this, SLOT(hexView())); + connect(ui->actionBodyHexView, SIGNAL(triggered()), this, SLOT(bodyHexView())); + connect(ui->actionUncompressedHexView, SIGNAL(triggered()), this, SLOT(uncompressedHexView())); connect(ui->actionExtract, SIGNAL(triggered()), this, SLOT(extractAsIs())); connect(ui->actionExtractBody, SIGNAL(triggered()), this, SLOT(extractBody())); connect(ui->actionExtractBodyUncompressed, SIGNAL(triggered()), this, SLOT(extractBodyUncompressed())); @@ -54,34 +65,31 @@ version(tr("NE Alpha32")) connect(ui->actionAboutQt, SIGNAL(triggered()), this, SLOT(aboutQt())); connect(ui->actionQuit, SIGNAL(triggered()), this, SLOT(exit())); connect(ui->actionGoToData, SIGNAL(triggered()), this, SLOT(goToData())); + connect(ui->actionGoToBase, SIGNAL(triggered()), this, SLOT(goToBase())); + connect(ui->actionGoToAddress, SIGNAL(triggered()), this, SLOT(goToAddress())); + connect(ui->actionLoadGuidDatabase, SIGNAL(triggered()), this, SLOT(loadGuidDatabase())); + connect(ui->actionUnloadGuidDatabase, SIGNAL(triggered()), this, SLOT(unloadGuidDatabase())); + connect(ui->actionLoadDefaultGuidDatabase, SIGNAL(triggered()), this, SLOT(loadDefaultGuidDatabase())); + connect(ui->actionExportDiscoveredGuids, SIGNAL(triggered()), this, SLOT(exportDiscoveredGuids())); + connect(ui->actionGenerateReport, SIGNAL(triggered()), this, SLOT(generateReport())); + connect(ui->actionToggleBootGuardMarking, SIGNAL(toggled(bool)), this, SLOT(toggleBootGuardMarking(bool))); connect(QCoreApplication::instance(), SIGNAL(aboutToQuit()), this, SLOT(writeSettings())); - + // Enable Drag-and-Drop actions setAcceptDrops(true); - + + // Disable Builder tab, doesn't work right now + ui->messagesTabWidget->setTabEnabled(TAB_BUILDER, false); + // Set current directory currentDir = "."; - - // Set monospace font for some controls - QFont font("Courier New", 10); -#if defined Q_OS_OSX - font = QFont("Menlo", 10); -#elif defined Q_OS_WIN - font = QFont("Consolas", 9); -#endif - ui->infoEdit->setFont(font); - ui->parserMessagesListWidget->setFont(font); - ui->finderMessagesListWidget->setFont(font); - ui->builderMessagesListWidget->setFont(font); - ui->fitTableWidget->setFont(font); - ui->structureTreeView->setFont(font); - searchDialog->ui->guidEdit->setFont(font); - searchDialog->ui->hexEdit->setFont(font); - hexViewDialog->setFont(font); - + + // Load built-in GUID database + initGuidDatabase(":/guids.csv"); + // Initialize non-persistent data init(); - + // Read stored settings readSettings(); } @@ -92,6 +100,7 @@ UEFITool::~UEFITool() delete ffsOps; delete ffsFinder; delete ffsParser; + delete ffsReport; delete model; delete hexViewDialog; delete searchDialog; @@ -107,25 +116,30 @@ void UEFITool::init() ui->fitTableWidget->setRowCount(0); ui->fitTableWidget->setColumnCount(0); ui->infoEdit->clear(); - ui->messagesTabWidget->setTabEnabled(1, false); - + ui->securityEdit->clear(); + ui->messagesTabWidget->setTabEnabled(TAB_FIT, false); + ui->messagesTabWidget->setTabEnabled(TAB_SECURITY, false); + ui->messagesTabWidget->setTabEnabled(TAB_SEARCH, false); + ui->messagesTabWidget->setTabEnabled(TAB_BUILDER, false); + // Set window title setWindowTitle(tr("UEFITool %1").arg(version)); - + // Disable menus - ui->menuCapsuleActions->setDisabled(true); - ui->menuImageActions->setDisabled(true); - ui->menuRegionActions->setDisabled(true); - ui->menuPaddingActions->setDisabled(true); - ui->menuVolumeActions->setDisabled(true); - ui->menuFileActions->setDisabled(true); - ui->menuSectionActions->setDisabled(true); - ui->menuStoreActions->setDisabled(true); - ui->menuVariableActions->setDisabled(true); - - ui->actionMessagesCopy->setDisabled(true); - ui->actionMessagesCopyAll->setDisabled(true); - + ui->actionSearch->setEnabled(false); + ui->actionGoToBase->setEnabled(false); + ui->actionGoToAddress->setEnabled(false); + ui->menuCapsuleActions->setEnabled(false); + ui->menuImageActions->setEnabled(false); + ui->menuRegionActions->setEnabled(false); + ui->menuPaddingActions->setEnabled(false); + ui->menuVolumeActions->setEnabled(false); + ui->menuFileActions->setEnabled(false); + ui->menuSectionActions->setEnabled(false); + ui->menuStoreActions->setEnabled(false); + ui->menuEntryActions->setEnabled(false); + ui->menuMessageActions->setEnabled(false); + // Create new model ... delete model; model = new TreeModel(); @@ -133,30 +147,92 @@ void UEFITool::init() // ... and ffsParser delete ffsParser; ffsParser = new FfsParser(model); - - // Connect + + // Set proper marking state + model->setMarkingEnabled(markingEnabled); + ui->actionToggleBootGuardMarking->setChecked(markingEnabled); + + // Connect signals to slots connect(ui->structureTreeView->selectionModel(), SIGNAL(currentChanged(const QModelIndex &, const QModelIndex &)), - this, SLOT(populateUi(const QModelIndex &))); + this, SLOT(populateUi(const QModelIndex &))); + connect(ui->structureTreeView->selectionModel(), SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)), + this, SLOT(populateUi(const QItemSelection &))); connect(ui->parserMessagesListWidget, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(scrollTreeView(QListWidgetItem*))); connect(ui->parserMessagesListWidget, SIGNAL(itemEntered(QListWidgetItem*)), this, SLOT(enableMessagesCopyActions(QListWidgetItem*))); connect(ui->finderMessagesListWidget, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(scrollTreeView(QListWidgetItem*))); connect(ui->finderMessagesListWidget, SIGNAL(itemEntered(QListWidgetItem*)), this, SLOT(enableMessagesCopyActions(QListWidgetItem*))); connect(ui->builderMessagesListWidget, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(scrollTreeView(QListWidgetItem*))); connect(ui->builderMessagesListWidget, SIGNAL(itemEntered(QListWidgetItem*)), this, SLOT(enableMessagesCopyActions(QListWidgetItem*))); + connect(ui->fitTableWidget, SIGNAL(itemDoubleClicked(QTableWidgetItem*)), this, SLOT(scrollTreeView(QTableWidgetItem*))); + connect(ui->messagesTabWidget, SIGNAL(currentChanged(int)), this, SLOT(currentTabChanged(int))); + + // Allow enter/return pressing to scroll tree view + ui->parserMessagesListWidget->installEventFilter(this); + ui->finderMessagesListWidget->installEventFilter(this); + ui->builderMessagesListWidget->installEventFilter(this); + + // Detect and set UI light or dark mode +#if QT_VERSION_MAJOR >= 6 +#if QT_VERSION_MINOR < 5 +#if defined Q_OS_WIN + QSettings settings("HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize", QSettings::NativeFormat); + if (settings.value("AppsUseLightTheme", 1).toInt() == 0) { + model->setMarkingDarkMode(true); + QApplication::setStyle(QStyleFactory::create("Fusion")); + QApplication::setPalette(QApplication::style()->standardPalette()); + } +#else + const QPalette palette = QApplication::palette(); + const QColor& color = palette.color(QPalette::Active, QPalette::Base); + if (color.lightness() < 127) { // TreeView has dark background + model->setMarkingDarkMode(true); + } +#endif // defined Q_OS_WIN +#else // QT_VERSION_MINOR >= 5 + // Qt 6.5.0 added proper support for dark UI mode, including detection and notification on mode change + // It also supposed to work in all OSes, but still requires changing the default style on Windows from Vista to Fusion + auto styleHints = QGuiApplication::styleHints(); + model->setMarkingDarkMode(styleHints->colorScheme() == Qt::ColorScheme::Dark); + connect(styleHints, SIGNAL(colorSchemeChanged(Qt::ColorScheme)), this, SLOT(updateUiForNewColorScheme(Qt::ColorScheme))); + +#if defined Q_OS_WIN + QApplication::setStyle(QStyleFactory::create("Fusion")); + QApplication::setPalette(QApplication::style()->standardPalette()); +#endif +#endif // QT_VERSION_MINOR +#endif // QT_VERSION_MAJOR +} + +#if QT_VERSION_MAJOR >= 6 && QT_VERSION_MINOR >= 5 +void UEFITool::updateUiForNewColorScheme(Qt::ColorScheme scheme) +{ + model->setMarkingDarkMode(scheme == Qt::ColorScheme::Dark); + QApplication::setPalette(QApplication::style()->standardPalette()); +} +#endif + +void UEFITool::populateUi(const QItemSelection &selected) +{ + if (selected.isEmpty()) { + return; + } + + populateUi(selected.indexes().at(0)); } void UEFITool::populateUi(const QModelIndex ¤t) { // Check sanity - if (!current.isValid()) + if (!current.isValid()) { return; - + } + UINT8 type = model->type(current); UINT8 subtype = model->subtype(current); - + // Set info text ui->infoEdit->setPlainText(model->info(current)); - + // Enable menus ui->menuCapsuleActions->setEnabled(type == Types::Capsule); ui->menuImageActions->setEnabled(type == Types::Image); @@ -165,33 +241,57 @@ void UEFITool::populateUi(const QModelIndex ¤t) ui->menuVolumeActions->setEnabled(type == Types::Volume); ui->menuFileActions->setEnabled(type == Types::File); ui->menuSectionActions->setEnabled(type == Types::Section); - ui->menuVariableActions->setEnabled(type == Types::NvarEntry - || type == Types::VssEntry - || type == Types::FsysEntry - || type == Types::EvsaEntry - || type == Types::FlashMapEntry); - ui->menuStoreActions->setEnabled(type == Types::VssStore - || type == Types::FdcStore - || type == Types::FsysStore - || type == Types::EvsaStore - || type == Types::FtwStore - || type == Types::FlashMapStore - || type == Types::CmdbStore - || type == Types::Microcode - || type == Types::SlicData); + ui->menuEntryActions->setEnabled(type == Types::Microcode + || type == Types::SlicData + || type == Types::NvarEntry + || type == Types::VssEntry + || type == Types::SysFEntry + || type == Types::EvsaEntry + || type == Types::PhoenixFlashMapEntry + || type == Types::InsydeFlashDeviceMapEntry + || type == Types::DellDvarEntry + || type == Types::IfwiHeader + || type == Types::IfwiPartition + || type == Types::FptPartition + || type == Types::FptEntry + || type == Types::BpdtPartition + || type == Types::BpdtEntry + || type == Types::CpdPartition + || type == Types::CpdEntry + || type == Types::CpdExtension + || type == Types::CpdSpiEntry + || type == Types::StartupApDataEntry + ); + ui->menuStoreActions->setEnabled(type == Types::VssStore + || type == Types::Vss2Store + || type == Types::FdcStore + || type == Types::SysFStore + || type == Types::EvsaStore + || type == Types::FtwStore + || type == Types::PhoenixFlashMapStore + || type == Types::InsydeFlashDeviceMapStore + || type == Types::DellDvarStore + || type == Types::NvarGuidStore + || type == Types::CmdbStore + || type == Types::FptStore + || type == Types::BpdtStore + || type == Types::CpdStore + ); // Enable actions ui->actionHexView->setDisabled(model->hasEmptyHeader(current) && model->hasEmptyBody(current) && model->hasEmptyTail(current)); + ui->actionBodyHexView->setDisabled(model->hasEmptyBody(current)); + ui->actionUncompressedHexView->setDisabled(model->hasEmptyUncompressedData(current)); ui->actionExtract->setDisabled(model->hasEmptyHeader(current) && model->hasEmptyBody(current) && model->hasEmptyTail(current)); ui->actionGoToData->setEnabled(type == Types::NvarEntry && subtype == Subtypes::LinkNvarEntry); - + // Disable rebuild for now //ui->actionRebuild->setDisabled(type == Types::Region && subtype == Subtypes::DescriptorRegion); //ui->actionReplace->setDisabled(type == Types::Region && subtype == Subtypes::DescriptorRegion); - + //ui->actionRebuild->setEnabled(type == Types::Volume || type == Types::File || type == Types::Section); ui->actionExtractBody->setDisabled(model->hasEmptyBody(current)); - ui->actionExtractBodyUncompressed->setEnabled(enableExtractBodyUncompressed(current)); + ui->actionExtractBodyUncompressed->setDisabled(model->hasEmptyUncompressedData(current)); //ui->actionRemove->setEnabled(type == Types::Volume || type == Types::File || type == Types::Section); //ui->actionInsertInto->setEnabled((type == Types::Volume && subtype != Subtypes::UnknownVolume) || // (type == Types::File && subtype != EFI_FV_FILETYPE_ALL && subtype != EFI_FV_FILETYPE_RAW && subtype != EFI_FV_FILETYPE_PAD) || @@ -200,40 +300,15 @@ void UEFITool::populateUi(const QModelIndex ¤t) //ui->actionInsertAfter->setEnabled(type == Types::File || type == Types::Section); //ui->actionReplace->setEnabled((type == Types::Region && subtype != Subtypes::DescriptorRegion) || type == Types::Volume || type == Types::File || type == Types::Section); //ui->actionReplaceBody->setEnabled(type == Types::Volume || type == Types::File || type == Types::Section); - ui->actionMessagesCopy->setEnabled(false); -} - -bool UEFITool::enableExtractBodyUncompressed(const QModelIndex ¤t) -{ - if (current.isValid() && model->type(current) == Types::Section && - (model->subtype(current) == EFI_SECTION_COMPRESSION || model->subtype(current) == EFI_SECTION_GUID_DEFINED)) { - // Get parsing data - PARSING_DATA pdata = parsingDataFromUModelIndex(current); - - if (model->subtype(current) == EFI_SECTION_COMPRESSION && - pdata.section.compressed.algorithm != COMPRESSION_ALGORITHM_NONE && - pdata.section.compressed.algorithm != COMPRESSION_ALGORITHM_UNKNOWN && - pdata.section.compressed.algorithm != COMPRESSION_ALGORITHM_UNDECIDED) { //Compressed section - return true; - } - else if (model->subtype(current) == EFI_SECTION_GUID_DEFINED) { - QByteArray guid = QByteArray((const char*)&pdata.section.guidDefined.guid, sizeof(EFI_GUID)); - if (guid == EFI_GUIDED_SECTION_TIANO || guid == EFI_GUIDED_SECTION_LZMA) { - return true; - } - } - } - - return false; + + ui->menuMessageActions->setEnabled(false); } void UEFITool::search() { if (searchDialog->exec() != QDialog::Accepted) return; - - QModelIndex rootIndex = model->index(0, 0); - + int index = searchDialog->ui->tabWidget->currentIndex(); if (index == 0) { // Hex pattern searchDialog->ui->hexEdit->setFocus(); @@ -247,7 +322,7 @@ void UEFITool::search() mode = SEARCH_MODE_BODY; else mode = SEARCH_MODE_ALL; - ffsFinder->findHexPattern(rootIndex, pattern, mode); + ffsFinder->findHexPattern(pattern, mode); showFinderMessages(); } else if (index == 1) { // GUID @@ -263,7 +338,7 @@ void UEFITool::search() mode = SEARCH_MODE_BODY; else mode = SEARCH_MODE_ALL; - ffsFinder->findGuidPattern(rootIndex, pattern, mode); + ffsFinder->findGuidPattern(pattern, mode); showFinderMessages(); } else if (index == 2) { // Text string @@ -278,8 +353,8 @@ void UEFITool::search() mode = SEARCH_MODE_BODY; else mode = SEARCH_MODE_ALL; - ffsFinder->findTextPattern(rootIndex, pattern, mode, searchDialog->ui->textUnicodeCheckBox->isChecked(), - (Qt::CaseSensitivity) searchDialog->ui->textCaseSensitiveCheckBox->isChecked()); + ffsFinder->findTextPattern(pattern, mode, searchDialog->ui->textUnicodeCheckBox->isChecked(), + (Qt::CaseSensitivity) searchDialog->ui->textCaseSensitiveCheckBox->isChecked()); showFinderMessages(); } } @@ -289,32 +364,89 @@ void UEFITool::hexView() QModelIndex index = ui->structureTreeView->selectionModel()->currentIndex(); if (!index.isValid()) return; - - hexViewDialog->setItem(index); + + hexViewDialog->setItem(index, HexViewDialog::HexViewType::fullHexView); hexViewDialog->exec(); } +void UEFITool::bodyHexView() +{ + QModelIndex index = ui->structureTreeView->selectionModel()->currentIndex(); + if (!index.isValid()) + return; + + hexViewDialog->setItem(index, HexViewDialog::HexViewType::bodyHexView); + hexViewDialog->exec(); +} + +void UEFITool::uncompressedHexView() +{ + QModelIndex index = ui->structureTreeView->selectionModel()->currentIndex(); + if (!index.isValid()) + return; + + hexViewDialog->setItem(index, HexViewDialog::HexViewType::uncompressedHexView); + hexViewDialog->exec(); +} + +void UEFITool::goToBase() +{ + goToBaseDialog->ui->hexSpinBox->setFocus(); + goToBaseDialog->ui->hexSpinBox->selectAll(); + if (goToBaseDialog->exec() != QDialog::Accepted) + return; + + UINT32 offset = (UINT32)goToBaseDialog->ui->hexSpinBox->value(); + QModelIndex index = model->findByBase(offset); + if (index.isValid()) { + ui->structureTreeView->scrollTo(index, QAbstractItemView::PositionAtCenter); + ui->structureTreeView->selectionModel()->select(index, QItemSelectionModel::Select | QItemSelectionModel::Rows | QItemSelectionModel::Clear); + } +} + +void UEFITool::goToAddress() +{ + goToAddressDialog->ui->hexSpinBox->setFocus(); + goToAddressDialog->ui->hexSpinBox->selectAll(); + if (goToAddressDialog->exec() != QDialog::Accepted) + return; + + UINT32 address = (UINT32)goToAddressDialog->ui->hexSpinBox->value(); + QModelIndex index = model->findByBase(address - (UINT32)ffsParser->getAddressDiff()); + if (index.isValid()) { + ui->structureTreeView->scrollTo(index, QAbstractItemView::PositionAtCenter); + ui->structureTreeView->selectionModel()->select(index, QItemSelectionModel::Select | QItemSelectionModel::Rows | QItemSelectionModel::Clear); + } +} + void UEFITool::goToData() { QModelIndex index = ui->structureTreeView->selectionModel()->currentIndex(); if (!index.isValid() || model->type(index) != Types::NvarEntry || model->subtype(index) != Subtypes::LinkNvarEntry) return; - + // Get parent QModelIndex parent = model->parent(index); for (int i = index.row(); i < model->rowCount(parent); i++) { - PARSING_DATA pdata = parsingDataFromUModelIndex(index); - UINT32 lastVariableFlag = pdata.emptyByte ? 0xFFFFFF : 0; - if (pdata.nvar.next == lastVariableFlag) { + if (model->hasEmptyParsingData(index)) + continue; + + UByteArray rdata = model->parsingData(index); + const NVAR_ENTRY_PARSING_DATA* pdata = (const NVAR_ENTRY_PARSING_DATA*)rdata.constData(); + UINT32 offset = model->offset(index); + if (pdata->next == 0xFFFFFF) { ui->structureTreeView->scrollTo(index, QAbstractItemView::PositionAtCenter); ui->structureTreeView->selectionModel()->select(index, QItemSelectionModel::Select | QItemSelectionModel::Rows | QItemSelectionModel::Clear); } for (int j = i + 1; j < model->rowCount(parent); j++) { - QModelIndex currentIndex = parent.child(j, 0); - PARSING_DATA currentPdata = parsingDataFromUModelIndex(currentIndex); - if (currentPdata.offset == pdata.offset + pdata.nvar.next) { + QModelIndex currentIndex = parent.model()->index(j, 0, parent); + + if (model->hasEmptyParsingData(currentIndex)) + continue; + + if (model->offset(currentIndex) == offset + pdata->next) { index = currentIndex; break; } @@ -324,56 +456,7 @@ void UEFITool::goToData() void UEFITool::insert(const UINT8 mode) { - /*QModelIndex index = ui->structureTreeView->selectionModel()->currentIndex(); - if (!index.isValid()) - return; - - UINT8 type; - - if (mode == CREATE_MODE_BEFORE || mode == CREATE_MODE_AFTER) - type = model->type(index.parent()); - else - type = model->type(index); - - QString path; - switch (type) { - case Types::Volume: - path = QFileDialog::getOpenFileName(this, tr("Select FFS file to insert"), currentDir, "FFS files (*.ffs *.bin);;All files (*)"); - break; - case Types::File: - case Types::Section: - path = QFileDialog::getOpenFileName(this, tr("Select section file to insert"), currentDir, "Section files (*.sct *.bin);;All files (*)"); - break; - default: - return; - } - - if (path.trimmed().isEmpty()) - return; - - QFileInfo fileInfo = QFileInfo(path); - if (!fileInfo.exists()) { - ui->statusBar->showMessage(tr("Please select existing file")); - return; - } - - QFile inputFile; - inputFile.setFileName(path); - - if (!inputFile.open(QFile::ReadOnly)) { - QMessageBox::critical(this, tr("Insertion failed"), tr("Can't open output file for reading"), QMessageBox::Ok); - return; - } - - QByteArray buffer = inputFile.readAll(); - inputFile.close(); - - UINT8 result = ffsEngine->insert(index, buffer, mode); - if (result) { - QMessageBox::critical(this, tr("Insertion failed"), errorMessage(result), QMessageBox::Ok); - return; - } - ui->actionSaveImageFile->setEnabled(true);*/ + U_UNUSED_PARAMETER(mode); } void UEFITool::insertInto() @@ -403,95 +486,7 @@ void UEFITool::replaceBody() void UEFITool::replace(const UINT8 mode) { - QModelIndex index = ui->structureTreeView->selectionModel()->currentIndex(); - if (!index.isValid()) - return; - - QString path; - if (model->type(index) == Types::Region) { - if (mode == REPLACE_MODE_AS_IS) { - path = QFileDialog::getOpenFileName(this, tr("Select region file to replace %1").arg(model->name(index)), currentDir, "Region files (*.rgn *.bin);;All files (*)"); - } - else - return; - } - else if (model->type(index) == Types::Volume) { - if (mode == REPLACE_MODE_AS_IS) { - path = QFileDialog::getOpenFileName(this, tr("Select volume file to replace selected volume"), currentDir, "Volume files (*.vol *.bin);;All files (*)"); - } - else if (mode == REPLACE_MODE_BODY) { - path = QFileDialog::getOpenFileName(this, tr("Select volume body file to replace the body of selected volume"), currentDir, "Volume body files (*.vbd *.bin);;All files (*)"); - } - else - return; - } - else if (model->type(index) == Types::File) { - if (mode == REPLACE_MODE_AS_IS) { - path = QFileDialog::getOpenFileName(this, tr("Select FFS file to replace %1 file").arg(model->text(index).isEmpty() ? model->name(index) : model->text(index)), - currentDir, "FFS files (*.ffs *.bin);;All files (*)"); - } - else if (mode == REPLACE_MODE_BODY) { - if (model->subtype(index) == EFI_FV_FILETYPE_ALL || model->subtype(index) == EFI_FV_FILETYPE_RAW) - path = QFileDialog::getOpenFileName(this, tr("Select raw file to replace the body of %1 file").arg(model->text(index).isEmpty() ? model->name(index) : model->text(index)), - currentDir, "Raw files (*.raw *.bin);;All files (*)"); - else if (model->subtype(index) == EFI_FV_FILETYPE_PAD) // Pad file body can't be replaced - //!TODO: handle non-empty pad files - return; - else - path = QFileDialog::getOpenFileName(this, tr("Select FFS file body to replace the body of %1 file").arg(model->text(index).isEmpty() ? model->name(index) : model->text(index)), - currentDir, "FFS file body files (*.fbd *.bin);;All files (*)"); - } - else - return; - } - else if (model->type(index) == Types::Section) { - if (mode == REPLACE_MODE_AS_IS) { - path = QFileDialog::getOpenFileName(this, tr("Select section file to replace selected section"), currentDir, "Section files (*.sct *.bin);;All files (*)"); - } - else if (mode == REPLACE_MODE_BODY) { - if (model->subtype(index) == EFI_SECTION_COMPRESSION || model->subtype(index) == EFI_SECTION_GUID_DEFINED || model->subtype(index) == EFI_SECTION_DISPOSABLE) - path = QFileDialog::getOpenFileName(this, tr("Select FFS file body file to replace the body of selected section"), currentDir, "FFS file body files (*.fbd *.bin);;All files (*)"); - else if (model->subtype(index) == EFI_SECTION_FIRMWARE_VOLUME_IMAGE) - path = QFileDialog::getOpenFileName(this, tr("Select volume file to replace the body of selected section"), currentDir, "Volume files (*.vol *.bin);;All files (*)"); - else if (model->subtype(index) == EFI_SECTION_RAW) - path = QFileDialog::getOpenFileName(this, tr("Select raw file to replace the body of selected section"), currentDir, "Raw files (*.raw *.bin);;All files (*)"); - else if (model->subtype(index) == EFI_SECTION_PE32 || model->subtype(index) == EFI_SECTION_TE || model->subtype(index) == EFI_SECTION_PIC) - path = QFileDialog::getOpenFileName(this, tr("Select EFI executable file to replace the body of selected section"), currentDir, "EFI executable files (*.efi *.dxe *.pei *.bin);;All files (*)"); - else - path = QFileDialog::getOpenFileName(this, tr("Select file to replace the body of selected section"), currentDir, "Binary files (*.bin);;All files (*)"); - } - else - return; - } - else - return; - - if (path.trimmed().isEmpty()) - return; - - QFileInfo fileInfo = QFileInfo(path); - if (!fileInfo.exists()) { - ui->statusBar->showMessage(tr("Please select an existing file")); - return; - } - - QFile inputFile; - inputFile.setFileName(path); - - if (!inputFile.open(QFile::ReadOnly)) { - QMessageBox::critical(this, tr("Replacing failed"), tr("Can't open input file for reading"), QMessageBox::Ok); - return; - } - - QByteArray buffer = inputFile.readAll(); - inputFile.close(); - - UINT8 result = ffsOps->replace(index, buffer, mode); - if (result) { - QMessageBox::critical(this, tr("Replacing failed"), errorCodeToUString(result), QMessageBox::Ok); - return; - } - ui->actionSaveImageFile->setEnabled(true); + U_UNUSED_PARAMETER(mode); } void UEFITool::extractAsIs() @@ -514,95 +509,56 @@ void UEFITool::extract(const UINT8 mode) QModelIndex index = ui->structureTreeView->selectionModel()->currentIndex(); if (!index.isValid()) return; - + QByteArray extracted; QString name; - UINT8 result = ffsOps->extract(index, name, extracted, mode); + USTATUS result = ffsOps->extract(index, name, extracted, mode); if (result) { QMessageBox::critical(this, tr("Extraction failed"), errorCodeToUString(result), QMessageBox::Ok); return; } name = QDir::toNativeSeparators(currentDir + QDir::separator() + name); - + //ui->statusBar->showMessage(name); - + UINT8 type = model->type(index); UINT8 subtype = model->subtype(index); QString path; if (mode == EXTRACT_MODE_AS_IS) { switch (type) { - case Types::Capsule: path = QFileDialog::getSaveFileName(this, tr("Save capsule to file"), name + ".cap", "Capsule files (*.cap *.bin);;All files (*)"); break; - case Types::Image: path = QFileDialog::getSaveFileName(this, tr("Save image to file"), name + ".rom", "Image files (*.rom *.bin);;All files (*)"); break; - case Types::Region: path = QFileDialog::getSaveFileName(this, tr("Save region to file"), name + ".rgn", "Region files (*.rgn *.bin);;All files (*)"); break; - case Types::Padding: path = QFileDialog::getSaveFileName(this, tr("Save padding to file"), name + ".pad", "Padding files (*.pad *.bin);;All files (*)"); break; - case Types::Volume: path = QFileDialog::getSaveFileName(this, tr("Save volume to file"), name + ".vol", "Volume files (*.vol *.bin);;All files (*)"); break; - case Types::File: path = QFileDialog::getSaveFileName(this, tr("Save FFS file to file"), name + ".ffs", "FFS files (*.ffs *.bin);;All files (*)"); break; - case Types::Section: path = QFileDialog::getSaveFileName(this, tr("Save section to file"), name + ".sct", "Section files (*.sct *.bin);;All files (*)"); break; - case Types::NvarEntry: path = QFileDialog::getSaveFileName(this, tr("Save NVAR entry to file"), name + ".nvar", "NVAR entry files (*.nvar *.bin);;All files (*)"); break; - case Types::VssEntry: path = QFileDialog::getSaveFileName(this, tr("Save VSS entry to file"), name + ".vss", "VSS entry files (*.vss *.bin);;All files (*)"); break; - case Types::FsysEntry: path = QFileDialog::getSaveFileName(this, tr("Save Fsys entry to file"), name + ".fse", "Fsys entry files (*.fse *.bin);;All files (*)"); break; - case Types::EvsaEntry: path = QFileDialog::getSaveFileName(this, tr("Save EVSA entry to file"), name + ".evse", "EVSA entry files (*.evse *.bin);;All files (*)"); break; - case Types::FlashMapEntry: path = QFileDialog::getSaveFileName(this, tr("Save FlashMap entry to file"), name + ".fme", "FlashMap entry files (*.fme *.bin);;All files (*)"); break; - case Types::VssStore: path = QFileDialog::getSaveFileName(this, tr("Save VSS store to file"), name + ".vss", "VSS store files (*.vss *.bin);;All files (*)"); break; - case Types::FdcStore: path = QFileDialog::getSaveFileName(this, tr("Save FDC store to file"), name + ".fdc", "FDC store files (*.fdc *.bin);;All files (*)"); break; - case Types::FsysStore: path = QFileDialog::getSaveFileName(this, tr("Save Fsys store to file"), name + ".fsys", "Fsys store files (*.fsys *.bin);;All files (*)"); break; - case Types::EvsaStore: path = QFileDialog::getSaveFileName(this, tr("Save EVSA store to file"), name + ".evsa", "EVSA store files (*.evsa *.bin);;All files (*)"); break; - case Types::FtwStore: path = QFileDialog::getSaveFileName(this, tr("Save FTW store to file"), name + ".ftw", "FTW store files (*.ftw *.bin);;All files (*)"); break; - case Types::FlashMapStore: path = QFileDialog::getSaveFileName(this, tr("Save FlashMap store to file"), name + ".fmap", "FlashMap store files (*.fmap *.bin);;All files (*)"); break; - case Types::CmdbStore: path = QFileDialog::getSaveFileName(this, tr("Save CMDB store to file"), name + ".cmdb", "CMDB store files (*.cmdb *.bin);;All files (*)"); break; - case Types::Microcode: path = QFileDialog::getSaveFileName(this, tr("Save microcode binary to file"), name + ".ucd", "Microcode binary files (*.ucd *.bin);;All files (*)"); break; - case Types::SlicData: - if (subtype == Subtypes::PubkeySlicData) path = QFileDialog::getSaveFileName(this, tr("Save SLIC pubkey to file"), name + ".spk", "SLIC pubkey files (*.spk *.bin);;All files (*)"); - else path = QFileDialog::getSaveFileName(this, tr("Save SLIC marker to file"), name + ".smk", "SLIC marker files (*.smk *.bin);;All files (*)"); - break; - default: path = QFileDialog::getSaveFileName(this, tr("Save object to file"), name + ".bin", "Binary files (*.bin);;All files (*)"); + case Types::Capsule: path = QFileDialog::getSaveFileName(this, tr("Save capsule to file"), name + ".cap", tr("Capsule files (*.cap *.bin);;All files (*)")); break; + case Types::Image: path = QFileDialog::getSaveFileName(this, tr("Save image to file"), name + ".rom", tr("Image files (*.rom *.bin);;All files (*)")); break; + case Types::Region: path = QFileDialog::getSaveFileName(this, tr("Save region to file"), name + ".rgn", tr("Region files (*.rgn *.bin);;All files (*)")); break; + case Types::Padding: path = QFileDialog::getSaveFileName(this, tr("Save padding to file"), name + ".pad", tr("Padding files (*.pad *.bin);;All files (*)")); break; + case Types::Volume: path = QFileDialog::getSaveFileName(this, tr("Save volume to file"), name + ".vol", tr("Volume files (*.vol *.bin);;All files (*)")); break; + case Types::File: path = QFileDialog::getSaveFileName(this, tr("Save FFS file to file"), name + ".ffs", tr("FFS files (*.ffs *.bin);;All files (*)")); break; + case Types::Section: path = QFileDialog::getSaveFileName(this, tr("Save section to file"), name + ".sct", tr("Section files (*.sct *.bin);;All files (*)")); break; + default: path = QFileDialog::getSaveFileName(this, tr("Save object to file"), name + ".bin", tr("Binary files (*.bin);;All files (*)")); } } else if (mode == EXTRACT_MODE_BODY || mode == EXTRACT_MODE_BODY_UNCOMPRESSED) { switch (type) { - case Types::Capsule: path = QFileDialog::getSaveFileName(this, tr("Save capsule body to image file"), name + ".rom", "Image files (*.rom *.bin);;All files (*)"); break; - case Types::Volume: path = QFileDialog::getSaveFileName(this, tr("Save volume body to file"), name + ".vbd", "Volume body files (*.vbd *.bin);;All files (*)"); break; - case Types::File: - if (subtype == EFI_FV_FILETYPE_ALL - || subtype == EFI_FV_FILETYPE_RAW) path = QFileDialog::getSaveFileName(this, tr("Save FFS file body to raw file"), name + ".raw", "Raw files (*.raw *.bin);;All files (*)"); - else path = QFileDialog::getSaveFileName(this, tr("Save FFS file body to file"), name + ".fbd", "FFS file body files (*.fbd *.bin);;All files (*)"); - break; - case Types::Section: - if (subtype == EFI_SECTION_COMPRESSION - || subtype == EFI_SECTION_GUID_DEFINED - || subtype == EFI_SECTION_DISPOSABLE) path = QFileDialog::getSaveFileName(this, tr("Save encapsulation section body to FFS body file"), name + ".fbd", "FFS file body files (*.fbd *.bin);;All files (*)"); - else if (subtype == EFI_SECTION_FIRMWARE_VOLUME_IMAGE) path = QFileDialog::getSaveFileName(this, tr("Save section body to volume file"), name + ".vol", "Volume files (*.vol *.bin);;All files (*)"); - else if (subtype == EFI_SECTION_RAW) path = QFileDialog::getSaveFileName(this, tr("Save section body to raw file"), name + ".raw", "Raw files (*.raw *.bin);;All files (*)"); - else if (subtype == EFI_SECTION_PE32 - || subtype == EFI_SECTION_TE - || subtype == EFI_SECTION_PIC) path = QFileDialog::getSaveFileName(this, tr("Save section body to EFI executable file"), name + ".efi", "EFI executable files (*.efi *.bin);;All files (*)"); - else path = QFileDialog::getSaveFileName(this, tr("Save section body to file"), name + ".bin", "Binary files (*.bin);;All files (*)"); - break; - case Types::NvarEntry: - case Types::VssEntry: - case Types::EvsaEntry: - case Types::FlashMapEntry: - case Types::FsysEntry: path = QFileDialog::getSaveFileName(this, tr("Save entry body to file"), name + ".bin", "Binary files (*.bin);;All files (*)"); break; - case Types::VssStore: - case Types::FtwStore: - case Types::FdcStore: - case Types::FsysStore: - case Types::FlashMapStore: - case Types::CmdbStore: path = QFileDialog::getSaveFileName(this, tr("Save store body to file"), name + ".bin", "Binary files (*.bin);;All files (*)"); break; - case Types::Microcode: path = QFileDialog::getSaveFileName(this, tr("Save microcode body to file"), name + ".ucb", "Microcode body files (*.ucb *.bin);;All files (*)"); break; - case Types::SlicData: - if (subtype == Subtypes::PubkeySlicData) path = QFileDialog::getSaveFileName(this, tr("Save SLIC pubkey body to file"), name + ".spb", "SLIC pubkey body files (*.spb *.bin);;All files (*)"); - else path = QFileDialog::getSaveFileName(this, tr("Save SLIC marker body to file"), name + ".smb", "SLIC marker body files (*.smb *.bin);;All files (*)"); - break; - default: path = QFileDialog::getSaveFileName(this, tr("Save object to file"), name + ".bin", "Binary files (*.bin);;All files (*)"); + case Types::Capsule: path = QFileDialog::getSaveFileName(this, tr("Save capsule body to image file"), name + ".rom", tr("Image files (*.rom *.bin);;All files (*)")); break; + case Types::Volume: path = QFileDialog::getSaveFileName(this, tr("Save volume body to file"), name + ".vbd", tr("Volume body files (*.vbd *.bin);;All files (*)")); break; + case Types::File: path = QFileDialog::getSaveFileName(this, tr("Save FFS file body to file"), name + ".fbd", tr("FFS file body files (*.fbd *.bin);;All files (*)")); break; + case Types::Section: + if (subtype == EFI_SECTION_FIRMWARE_VOLUME_IMAGE) { + path = QFileDialog::getSaveFileName(this, tr("Save section body to volume file"), name + ".vol", tr("Volume files (*.vol *.bin);;All files (*)")); break; + } + else if (subtype == EFI_SECTION_PE32 + || subtype == EFI_SECTION_TE + || subtype == EFI_SECTION_PIC) { + path = QFileDialog::getSaveFileName(this, tr("Save section body to EFI executable file"), name + ".efi", tr("EFI executable files (*.efi *.bin);;All files (*)")); break; + } + default: path = QFileDialog::getSaveFileName(this, tr("Save object body to file"), name + ".bin", tr("Binary files (*.bin);;All files (*)")); } } - else path = QFileDialog::getSaveFileName(this, tr("Save object to file"), name + ".bin", "Binary files (*.bin);;All files (*)"); - + else path = QFileDialog::getSaveFileName(this, tr("Save object to file"), name + ".bin", tr("Binary files (*.bin);;All files (*)")); + if (path.trimmed().isEmpty()) return; - + QFile outputFile; outputFile.setFileName(path); if (!outputFile.open(QFile::WriteOnly)) { @@ -616,37 +572,36 @@ void UEFITool::extract(const UINT8 mode) void UEFITool::rebuild() { - UModelIndex index = ui->structureTreeView->selectionModel()->currentIndex(); - if (!index.isValid()) - return; - - if (U_SUCCESS == ffsOps->rebuild(index)) - ui->actionSaveImageFile->setEnabled(true); + } void UEFITool::remove() { - UModelIndex index = ui->structureTreeView->selectionModel()->currentIndex(); - if (!index.isValid()) - return; - - if (U_SUCCESS == ffsOps->remove(index)) - ui->actionSaveImageFile->setEnabled(true); + } void UEFITool::about() { - QMessageBox::about(this, tr("About UEFITool"), tr( - "Copyright (c) 2016, Nikolaj Schlej aka CodeRush.
" - "Program icon made by Alexander Zhidkov.
" - "The program uses QHexEdit2 library made by Simsys.
" - "Qt-less engine is using Bstrlib made by Paul Hsieh.

" - "The program is dedicated to RevoGirl. Rest in peace, young genius.

" - "The program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License.
" - "The full text of the license may be found at OpenSource.org.

" - "THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN \"AS IS\" BASIS, " - "WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, " - "EITHER EXPRESS OR IMPLIED.")); + QMessageBox::about(this, + tr("About UEFITool"), + tr("UEFITool %1.

" + "Copyright (c) 2013-2025, Nikolaj (CodeRush) Schlej, Vitaly (vit9696) Cheptsov, et al.

" + "Program icon made by Alexander Zhidkov.

" + "GUI uses QHexView made by Antonio Davide.
" + "Qt-less engine uses Bstrlib made by Paul Hsieh.
" + "Engine uses Tiano compression code made by TianoCore developers.
" + "Engine uses LZMA compression code made by Igor Pavlov.
" + "Engine uses zlib compression code made by Mark Adler.
" + "Engine uses LibTomCrypt hashing code made by LibTom developers.
" + "Engine uses KaitaiStruct runtime made by Kaitai team.

" + "The program is dedicated to RevoGirl. Rest in peace, young genius.

" + "The program and the accompanying materials are licensed and made available under the terms and conditions of the BSD-2-Clause License.
" + "The full text of the license may be found at OpenSource.org.

" + "THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN \"AS IS\" BASIS, " + "WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, " + "EITHER EXPRESS OR IMPLIED." + "").arg(version) + ); } void UEFITool::aboutQt() @@ -661,45 +616,18 @@ void UEFITool::exit() void UEFITool::saveImageFile() { - QString path = QFileDialog::getSaveFileName(this, tr("Save BIOS image file"), currentDir, "BIOS image files (*.rom *.bin *.cap *.scap *.bio *.fd *.wph *.dec);;All files (*)"); - - if (path.isEmpty()) - return; - - QByteArray reconstructed; - // Create ffsBuilder - delete ffsBuilder; - ffsBuilder = new FfsBuilder(model); - USTATUS result = ffsBuilder->build(model->index(0,0), reconstructed); - showBuilderMessages(); - if (result) { - QMessageBox::critical(this, tr("Image build failed"), errorCodeToUString(result), QMessageBox::Ok); - return; - } - - QFile outputFile; - outputFile.setFileName(path); - if (!outputFile.open(QFile::WriteOnly)) { - QMessageBox::critical(this, tr("Image build failed"), tr("Can't open output file for rewriting"), QMessageBox::Ok); - return; - } - - outputFile.resize(0); - outputFile.write(reconstructed); - outputFile.close(); - if (QMessageBox::Yes == QMessageBox::information(this, tr("Image build successful"), tr("Open the resulting file?"), QMessageBox::Yes, QMessageBox::No)) - openImageFile(path); + } void UEFITool::openImageFile() { - QString path = QFileDialog::getOpenFileName(this, tr("Open BIOS image file"), currentDir, "BIOS image files (*.rom *.bin *.cap *scap *.bio *.fd *.wph *.dec);;All files (*)"); + QString path = QFileDialog::getOpenFileName(this, tr("Open BIOS image file"), currentDir, tr("BIOS image files (*.rom *.bin *.cap *scap *.bio *.fd *.wph *.dec);;All files (*)")); openImageFile(path); } void UEFITool::openImageFileInNewWindow() { - QString path = QFileDialog::getOpenFileName(this, tr("Open BIOS image file in new window"), currentDir, "BIOS image files (*.rom *.bin *.cap *scap *.bio *.fd *.wph *.dec);;All files (*)"); + QString path = QFileDialog::getOpenFileName(this, tr("Open BIOS image file in new window"), currentDir, tr("BIOS image files (*.rom *.bin *.cap *scap *.bio *.fd *.wph *.dec);;All files (*)")); if (path.trimmed().isEmpty()) return; QProcess::startDetached(currentProgramPath, QStringList(path)); @@ -709,37 +637,46 @@ void UEFITool::openImageFile(QString path) { if (path.trimmed().isEmpty()) return; - + QFileInfo fileInfo = QFileInfo(path); - + if (!fileInfo.exists()) { ui->statusBar->showMessage(tr("Please select existing file")); return; } - + QFile inputFile; inputFile.setFileName(path); - + if (!inputFile.open(QFile::ReadOnly)) { QMessageBox::critical(this, tr("Image parsing failed"), tr("Can't open input file for reading"), QMessageBox::Ok); return; } - + QByteArray buffer = inputFile.readAll(); inputFile.close(); - + init(); setWindowTitle(tr("UEFITool %1 - %2").arg(version).arg(fileInfo.fileName())); - - UINT8 result = ffsParser->parse(buffer); + + // Parse the image + USTATUS result = ffsParser->parse(buffer); showParserMessages(); if (result) { QMessageBox::critical(this, tr("Image parsing failed"), errorCodeToUString(result), QMessageBox::Ok); return; } - else + else { ui->statusBar->showMessage(tr("Opened: %1").arg(fileInfo.fileName())); - + } + ffsParser->outputInfo(); + + // Enable or disable FIT tab + showFitTable(); + + // Enable or disable Security tab + showSecurityInfo(); + // Enable search ... delete ffsFinder; ffsFinder = new FfsFinder(model); @@ -747,22 +684,44 @@ void UEFITool::openImageFile(QString path) // ... and other operations delete ffsOps; ffsOps = new FfsOperations(model); - - // Enable or disable FIT tab - showFitTable(); - + // ... and reports + delete ffsReport; + ffsReport = new FfsReport(model); + + // Enable goToBase and goToAddress + ui->actionGoToBase->setEnabled(true); + if (ffsParser->getAddressDiff() <= 0xFFFFFFFFUL) + ui->actionGoToAddress->setEnabled(true); + + // Enable generateReport + ui->actionGenerateReport->setEnabled(true); + + // Enable saving GUIDs + ui->actionExportDiscoveredGuids->setEnabled(true); + // Set current directory currentDir = fileInfo.absolutePath(); + + // Set current path + currentPath = path; +} + +void UEFITool::enableMessagesCopyActions(QListWidgetItem* item) +{ + ui->menuMessageActions->setEnabled(item != NULL); + ui->actionMessagesCopy->setEnabled(item != NULL); + ui->actionMessagesCopyAll->setEnabled(item != NULL); + ui->actionMessagesClear->setEnabled(item != NULL); } void UEFITool::copyMessage() { clipboard->clear(); - if (ui->messagesTabWidget->currentIndex() == 0) // Parser tab - clipboard->setText(ui->parserMessagesListWidget->currentItem()->text()); - else if (ui->messagesTabWidget->currentIndex() == 2) // Search tab + if (ui->messagesTabWidget->currentIndex() == TAB_PARSER) // Parser tab + clipboard->setText(ui->parserMessagesListWidget->currentItem()->text()); + else if (ui->messagesTabWidget->currentIndex() == TAB_SEARCH) // Search tab clipboard->setText(ui->finderMessagesListWidget->currentItem()->text()); - else if (ui->messagesTabWidget->currentIndex() == 3) // Builder tab + else if (ui->messagesTabWidget->currentIndex() == TAB_BUILDER) // Builder tab clipboard->setText(ui->builderMessagesListWidget->currentItem()->text()); } @@ -770,46 +729,65 @@ void UEFITool::copyAllMessages() { QString text; clipboard->clear(); - if (ui->messagesTabWidget->currentIndex() == 0) { // Parser tab + if (ui->messagesTabWidget->currentIndex() == TAB_PARSER) { // Parser tab for (INT32 i = 0; i < ui->parserMessagesListWidget->count(); i++) text.append(ui->parserMessagesListWidget->item(i)->text()).append("\n"); clipboard->setText(text); } - else if (ui->messagesTabWidget->currentIndex() == 2) { // Search tab + else if (ui->messagesTabWidget->currentIndex() == TAB_SEARCH) { // Search tab for (INT32 i = 0; i < ui->finderMessagesListWidget->count(); i++) text.append(ui->finderMessagesListWidget->item(i)->text()).append("\n"); clipboard->setText(text); } - else if (ui->messagesTabWidget->currentIndex() == 3) { // Builder tab + else if (ui->messagesTabWidget->currentIndex() == TAB_BUILDER) { // Builder tab for (INT32 i = 0; i < ui->builderMessagesListWidget->count(); i++) text.append(ui->builderMessagesListWidget->item(i)->text()).append("\n"); clipboard->setText(text); } } -void UEFITool::enableMessagesCopyActions(QListWidgetItem* item) -{ - ui->actionMessagesCopy->setEnabled(item != NULL); - ui->actionMessagesCopyAll->setEnabled(item != NULL); -} - void UEFITool::clearMessages() { - if (ui->messagesTabWidget->currentIndex() == 0) { // Parser tab + if (ui->messagesTabWidget->currentIndex() == TAB_PARSER) { // Parser tab if (ffsParser) ffsParser->clearMessages(); ui->parserMessagesListWidget->clear(); } - else if (ui->messagesTabWidget->currentIndex() == 2) { // Search tab + else if (ui->messagesTabWidget->currentIndex() == TAB_SEARCH) { // Search tab if (ffsFinder) ffsFinder->clearMessages(); ui->finderMessagesListWidget->clear(); } - else if (ui->messagesTabWidget->currentIndex() == 3) { // Builder tab + else if (ui->messagesTabWidget->currentIndex() == TAB_BUILDER) { // Builder tab if (ffsBuilder) ffsBuilder->clearMessages(); ui->builderMessagesListWidget->clear(); } + ui->menuMessageActions->setEnabled(false); ui->actionMessagesCopy->setEnabled(false); ui->actionMessagesCopyAll->setEnabled(false); + ui->actionMessagesClear->setEnabled(false); +} + +void UEFITool::toggleBootGuardMarking(bool enabled) +{ + model->setMarkingEnabled(enabled); + markingEnabled = enabled; +} + +// Emit double click signal of QListWidget on enter/return key pressed +bool UEFITool::eventFilter(QObject* obj, QEvent* event) +{ + if (event->type() == QEvent::KeyPress) { + QKeyEvent* key = static_cast(event); + + if (key->key() == Qt::Key_Enter || key->key() == Qt::Key_Return) { + QListWidget* list = qobject_cast(obj); + + if (list != NULL && list->currentItem() != NULL) + emit list->itemDoubleClicked(list->currentItem()); + } + } + + return QObject::eventFilter(obj, event); } void UEFITool::dragEnterEvent(QDragEnterEvent* event) @@ -829,14 +807,16 @@ void UEFITool::showParserMessages() ui->parserMessagesListWidget->clear(); if (!ffsParser) return; - + std::vector > messages = ffsParser->getMessages(); - std::pair msg; - foreach (msg, messages) { - ui->parserMessagesListWidget->addItem(new MessageListItem(msg.first, NULL, 0, msg.second)); + + for (const auto &msg : messages) { + QListWidgetItem* item = new QListWidgetItem(msg.first, NULL, 0); + item->setData(Qt::UserRole, QByteArray((const char*)&msg.second, sizeof(msg.second))); + ui->parserMessagesListWidget->addItem(item); } - - ui->messagesTabWidget->setCurrentIndex(0); + + ui->messagesTabWidget->setCurrentIndex(TAB_PARSER); ui->parserMessagesListWidget->scrollToBottom(); } @@ -845,14 +825,17 @@ void UEFITool::showFinderMessages() ui->finderMessagesListWidget->clear(); if (!ffsParser) return; - + std::vector > messages = ffsFinder->getMessages(); - std::pair msg; - foreach (msg, messages) { - ui->finderMessagesListWidget->addItem(new MessageListItem(msg.first, NULL, 0, msg.second)); + + for (const auto &msg : messages) { + QListWidgetItem* item = new QListWidgetItem(msg.first, NULL, 0); + item->setData(Qt::UserRole, QByteArray((const char*)&msg.second, sizeof(msg.second)));; + ui->finderMessagesListWidget->addItem(item); } - - ui->messagesTabWidget->setCurrentIndex(2); + + ui->messagesTabWidget->setTabEnabled(TAB_SEARCH, true); + ui->messagesTabWidget->setCurrentIndex(TAB_SEARCH); ui->finderMessagesListWidget->scrollToBottom(); } @@ -861,75 +844,94 @@ void UEFITool::showBuilderMessages() ui->builderMessagesListWidget->clear(); if (!ffsBuilder) return; - + std::vector > messages = ffsBuilder->getMessages(); - std::pair msg; - foreach (msg, messages) { - ui->builderMessagesListWidget->addItem(new MessageListItem(msg.first, NULL, 0, msg.second)); + + for (const auto &msg : messages) { + QListWidgetItem* item = new QListWidgetItem(msg.first, NULL, 0); + item->setData(Qt::UserRole, QByteArray((const char*)&msg.second, sizeof(msg.second))); + ui->builderMessagesListWidget->addItem(item); } - - ui->messagesTabWidget->setCurrentIndex(3); + + ui->messagesTabWidget->setTabEnabled(TAB_BUILDER, true); + ui->messagesTabWidget->setCurrentIndex(TAB_BUILDER); ui->builderMessagesListWidget->scrollToBottom(); } void UEFITool::scrollTreeView(QListWidgetItem* item) { - MessageListItem* messageItem = static_cast(item); - QModelIndex index = messageItem->index(); - if (index.isValid()) { - ui->structureTreeView->scrollTo(index, QAbstractItemView::PositionAtCenter); - ui->structureTreeView->selectionModel()->select(index, QItemSelectionModel::Select | QItemSelectionModel::Rows | QItemSelectionModel::Clear); + QByteArray second = item->data(Qt::UserRole).toByteArray(); + QModelIndex *index = (QModelIndex *)second.data(); + if (index && index->isValid()) { + ui->structureTreeView->scrollTo(*index, QAbstractItemView::PositionAtCenter); + ui->structureTreeView->selectionModel()->select(*index, QItemSelectionModel::Select | QItemSelectionModel::Rows | QItemSelectionModel::Clear); + } +} + +void UEFITool::scrollTreeView(QTableWidgetItem* item) +{ + QByteArray second = item->data(Qt::UserRole).toByteArray(); + QModelIndex *index = (QModelIndex *)second.data(); + if (index && index->isValid()) { + ui->structureTreeView->scrollTo(*index, QAbstractItemView::PositionAtCenter); + ui->structureTreeView->selectionModel()->select(*index, QItemSelectionModel::Select | QItemSelectionModel::Rows | QItemSelectionModel::Clear); } } void UEFITool::contextMenuEvent(QContextMenuEvent* event) { - if (ui->parserMessagesListWidget->underMouse() || - ui->finderMessagesListWidget->underMouse() || - ui->builderMessagesListWidget->underMouse()) { - ui->menuMessages->exec(event->globalPos()); + // The checks involving underMouse do not work well enough on macOS, and result in right-click sometimes + // not showing any context menu at all. Most likely it is a bug in Qt, which does not affect other systems. + // For this reason we reimplement this manually. + if (ui->parserMessagesListWidget->rect().contains(ui->parserMessagesListWidget->mapFromGlobal(event->globalPos())) || + ui->finderMessagesListWidget->rect().contains(ui->finderMessagesListWidget->mapFromGlobal(event->globalPos())) || + ui->builderMessagesListWidget->rect().contains(ui->builderMessagesListWidget->mapFromGlobal(event->globalPos()))) { + ui->menuMessageActions->exec(event->globalPos()); return; } - - if (!ui->structureTreeView->underMouse()) + + + if (!ui->structureTreeView->rect().contains(ui->structureTreeView->mapFromGlobal(event->globalPos()))) return; - + QPoint pt = event->pos(); QModelIndex index = ui->structureTreeView->indexAt(ui->structureTreeView->viewport()->mapFrom(this, pt)); - if (!index.isValid()) + if (!index.isValid()) { return; - - switch (model->type(index)) - { - case Types::Capsule: ui->menuCapsuleActions->exec(event->globalPos()); break; - case Types::Image: ui->menuImageActions->exec(event->globalPos()); break; - case Types::Region: ui->menuRegionActions->exec(event->globalPos()); break; - case Types::Padding: ui->menuPaddingActions->exec(event->globalPos()); break; - case Types::Volume: ui->menuVolumeActions->exec(event->globalPos()); break; - case Types::File: ui->menuFileActions->exec(event->globalPos()); break; - case Types::Section: ui->menuSectionActions->exec(event->globalPos()); break; - case Types::NvarEntry: - case Types::VssEntry: - case Types::FsysEntry: - case Types::EvsaEntry: - case Types::FlashMapEntry: ui->menuVariableActions->exec(event->globalPos()); break; - case Types::VssStore: - case Types::FdcStore: - case Types::FsysStore: - case Types::EvsaStore: - case Types::FtwStore: - case Types::FlashMapStore: - case Types::CmdbStore: - case Types::Microcode: - case Types::SlicData: ui->menuStoreActions->exec(event->globalPos()); break; + } + + switch (model->type(index)) { + case Types::Capsule: ui->menuCapsuleActions->exec(event->globalPos()); break; + case Types::Image: ui->menuImageActions->exec(event->globalPos()); break; + case Types::Region: ui->menuRegionActions->exec(event->globalPos()); break; + case Types::Padding: ui->menuPaddingActions->exec(event->globalPos()); break; + case Types::Volume: ui->menuVolumeActions->exec(event->globalPos()); break; + case Types::File: ui->menuFileActions->exec(event->globalPos()); break; + case Types::Section: ui->menuSectionActions->exec(event->globalPos()); break; + case Types::VssStore: + case Types::Vss2Store: + case Types::FdcStore: + case Types::SysFStore: + case Types::EvsaStore: + case Types::FtwStore: + case Types::PhoenixFlashMapStore: + case Types::InsydeFlashDeviceMapStore: + case Types::DellDvarStore: + case Types::NvarGuidStore: + case Types::CmdbStore: + case Types::FptStore: + case Types::CpdStore: + case Types::BpdtStore: ui->menuStoreActions->exec(event->globalPos()); break; + case Types::FreeSpace: break; // No menu needed for FreeSpace item + default: ui->menuEntryActions->exec(event->globalPos()); break; } } void UEFITool::readSettings() { QSettings settings(this); - resize(settings.value("mainWindow/size", QSize(800, 600)).toSize()); - move(settings.value("mainWindow/position", QPoint(0, 0)).toPoint()); + restoreGeometry(settings.value("mainWindow/geometry").toByteArray()); + restoreState(settings.value("mainWindow/windowState").toByteArray()); QList horList, vertList; horList.append(settings.value("mainWindow/treeWidth", 600).toInt()); horList.append(settings.value("mainWindow/infoWidth", 180).toInt()); @@ -941,13 +943,32 @@ void UEFITool::readSettings() ui->structureTreeView->setColumnWidth(1, settings.value("tree/columnWidth1", ui->structureTreeView->columnWidth(1)).toInt()); ui->structureTreeView->setColumnWidth(2, settings.value("tree/columnWidth2", ui->structureTreeView->columnWidth(2)).toInt()); ui->structureTreeView->setColumnWidth(3, settings.value("tree/columnWidth3", ui->structureTreeView->columnWidth(3)).toInt()); + markingEnabled = settings.value("tree/markingEnabled", true).toBool(); + ui->actionToggleBootGuardMarking->setChecked(markingEnabled); + + // Set monospace font + QString fontName; + int fontSize; +#if defined Q_OS_MACOS + fontName = settings.value("mainWindow/fontName", QString("Menlo")).toString(); + fontSize = settings.value("mainWindow/fontSize", 10).toInt(); +#elif defined Q_OS_WIN + fontName = settings.value("mainWindow/fontName", QString("Consolas")).toString(); + fontSize = settings.value("mainWindow/fontSize", 9).toInt(); +#else + fontName = settings.value("mainWindow/fontName", QString("Courier New")).toString(); + fontSize = settings.value("mainWindow/fontSize", 10).toInt(); +#endif + currentFont = QFont(fontName, fontSize); + currentFont.setStyleHint(QFont::Monospace); + QApplication::setFont(currentFont); } void UEFITool::writeSettings() { QSettings settings(this); - settings.setValue("mainWindow/size", size()); - settings.setValue("mainWindow/position", pos()); + settings.setValue("mainWindow/geometry", saveGeometry()); + settings.setValue("mainWindow/windowState", saveState()); settings.setValue("mainWindow/treeWidth", ui->structureGroupBox->width()); settings.setValue("mainWindow/infoWidth", ui->infoGroupBox->width()); settings.setValue("mainWindow/treeHeight", ui->structureGroupBox->height()); @@ -956,38 +977,119 @@ void UEFITool::writeSettings() settings.setValue("tree/columnWidth1", ui->structureTreeView->columnWidth(1)); settings.setValue("tree/columnWidth2", ui->structureTreeView->columnWidth(2)); settings.setValue("tree/columnWidth3", ui->structureTreeView->columnWidth(3)); + settings.setValue("tree/markingEnabled", markingEnabled); + settings.setValue("mainWindow/fontName", currentFont.family()); + settings.setValue("mainWindow/fontSize", currentFont.pointSize()); } void UEFITool::showFitTable() { - std::vector > fitTable = ffsParser->getFitTable(); + std::vector, UModelIndex> > fitTable = ffsParser->getFitTable(); if (fitTable.empty()) { // Disable FIT tab - ui->messagesTabWidget->setTabEnabled(1, false); + ui->messagesTabWidget->setTabEnabled(TAB_FIT, false); return; } - + // Enable FIT tab - ui->messagesTabWidget->setTabEnabled(1, true); - + ui->messagesTabWidget->setTabEnabled(TAB_FIT, true); + // Set up the FIT table ui->fitTableWidget->clear(); - ui->fitTableWidget->setRowCount(fitTable.size()); - ui->fitTableWidget->setColumnCount(5); - ui->fitTableWidget->setHorizontalHeaderLabels(QStringList() << tr("Address") << tr("Size") << tr("Version") << tr("Checksum") << tr("Type")); + ui->fitTableWidget->setRowCount((int)fitTable.size()); + ui->fitTableWidget->setColumnCount(6); + ui->fitTableWidget->setHorizontalHeaderLabels(QStringList() << tr("Address") << tr("Size") << tr("Version") << tr("Checksum") << tr("Type") << tr("Information")); ui->fitTableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers); ui->fitTableWidget->setSelectionBehavior(QAbstractItemView::SelectRows); ui->fitTableWidget->setSelectionMode(QAbstractItemView::SingleSelection); ui->fitTableWidget->horizontalHeader()->setStretchLastSection(true); - + // Add all data to the table widget for (size_t i = 0; i < fitTable.size(); i++) { - for (UINT8 j = 0; j < 5; j++) { - ui->fitTableWidget->setItem(i, j, new QTableWidgetItem(fitTable[i][j])); + for (UINT8 j = 0; j < 6; j++) { + QTableWidgetItem* item = new QTableWidgetItem(fitTable[i].first[j]); + item->setData(Qt::UserRole, QByteArray((const char*)&fitTable[i].second, sizeof(fitTable[i].second))); + ui->fitTableWidget->setItem((int)i, j, item); } } - + ui->fitTableWidget->resizeColumnsToContents(); ui->fitTableWidget->resizeRowsToContents(); - ui->messagesTabWidget->setCurrentIndex(1); + ui->messagesTabWidget->setCurrentIndex(TAB_FIT); +} + +void UEFITool::showSecurityInfo() +{ + // Get security info + UString secInfo = ffsParser->getSecurityInfo(); + if (secInfo.isEmpty()) { + ui->messagesTabWidget->setTabEnabled(TAB_SECURITY, false); + return; + } + + ui->messagesTabWidget->setTabEnabled(TAB_SECURITY, true); + ui->securityEdit->setPlainText(secInfo); + ui->messagesTabWidget->setCurrentIndex(TAB_SECURITY); +} + +void UEFITool::currentTabChanged(int index) +{ + U_UNUSED_PARAMETER(index); + + ui->menuMessageActions->setEnabled(false); + ui->actionMessagesCopy->setEnabled(false); + ui->actionMessagesCopyAll->setEnabled(false); + ui->actionMessagesClear->setEnabled(false); +} + +void UEFITool::loadGuidDatabase() +{ + QString path = QFileDialog::getOpenFileName(this, tr("Select GUID database file to load"), currentDir, tr("Comma-separated values files (*.csv);;All files (*)")); + if (!path.isEmpty()) { + initGuidDatabase(path); + if (!currentPath.isEmpty() && QMessageBox::Yes == QMessageBox::information(this, tr("New GUID database loaded"), tr("Apply new GUID database on the opened file?\nUnsaved changes and tree position will be lost."), QMessageBox::Yes, QMessageBox::No)) + openImageFile(currentPath); + } +} + +void UEFITool::unloadGuidDatabase() +{ + initGuidDatabase(); + if (!currentPath.isEmpty() && QMessageBox::Yes == QMessageBox::information(this, tr("GUID database unloaded"), tr("Apply changes on the opened file?\nUnsaved changes and tree position will be lost."), QMessageBox::Yes, QMessageBox::No)) + openImageFile(currentPath); +} + +void UEFITool::loadDefaultGuidDatabase() +{ + initGuidDatabase(":/guids.csv"); + if (!currentPath.isEmpty() && QMessageBox::Yes == QMessageBox::information(this, tr("Default GUID database loaded"), tr("Apply default GUID database on the opened file?\nUnsaved changes and tree position will be lost."), QMessageBox::Yes, QMessageBox::No)) + openImageFile(currentPath); +} + +void UEFITool::exportDiscoveredGuids() +{ + GuidDatabase db = guidDatabaseFromTreeRecursive(model, model->index(0, 0)); + if (!db.empty()) { + QString path = QFileDialog::getSaveFileName(this, tr("Save parsed GUIDs to database"), currentPath + ".guids.csv", tr("Comma-separated values files (*.csv);;All files (*)")); + if (!path.isEmpty()) + guidDatabaseExportToFile(path, db); + } +} + +void UEFITool::generateReport() +{ + QString path = QFileDialog::getSaveFileName(this, tr("Save report to text file"), currentPath + ".report.txt", tr("Text files (*.txt);;All files (*)")); + if (!path.isEmpty()) { + std::vector report = ffsReport->generate(); + if (report.size()) { + QFile file; + file.setFileName(path); + if (file.open(QFile::Text | QFile::WriteOnly)) { + for (size_t i = 0; i < report.size(); i++) { + file.write(report[i].toLatin1().append('\n')); + } + file.close(); + } + } + } } diff --git a/UEFITool/uefitool.desktop b/UEFITool/uefitool.desktop old mode 100755 new mode 100644 index 1023100..f525b6a --- a/UEFITool/uefitool.desktop +++ b/UEFITool/uefitool.desktop @@ -3,9 +3,8 @@ Type=Application Version=1.0 Name=UEFITool Comment=UEFI firmware image viewer and editor -Path=/usr/bin Exec=uefitool Icon=uefitool Terminal=false Categories=Development;System;Utility;HardwareSettings;Electronics;Engineering; -Keywords=BIOS; +Keywords=BIOS;UEFI; diff --git a/UEFITool/uefitool.entitlements b/UEFITool/uefitool.entitlements new file mode 100644 index 0000000..6b54693 --- /dev/null +++ b/UEFITool/uefitool.entitlements @@ -0,0 +1,20 @@ + + + + + com.apple.security.app-sandbox + + com.apple.security.assets.movies.read-write + + com.apple.security.assets.music.read-write + + com.apple.security.assets.pictures.read-write + + com.apple.security.files.downloads.read-write + + com.apple.security.files.user-selected.read-write + + com.apple.security.print + + + diff --git a/UEFITool/uefitool.h b/UEFITool/uefitool.h index 6f6f40a..08ef908 100644 --- a/UEFITool/uefitool.h +++ b/UEFITool/uefitool.h @@ -22,15 +22,19 @@ #include #include #include +#include #include #include #include #include +#include #include #include #include #include +#include #include +#include #include #include @@ -40,10 +44,13 @@ #include "../common/ffsparser.h" #include "../common/ffsops.h" #include "../common/ffsbuilder.h" +#include "../common/ffsreport.h" +#include "../common/guiddatabase.h" #include "searchdialog.h" +#include "gotobasedialog.h" +#include "gotoaddressdialog.h" #include "hexviewdialog.h" -#include "messagelistitem.h" #include "ffsfinder.h" namespace Ui { @@ -63,18 +70,24 @@ public: private slots: void init(); + void populateUi(const QItemSelection &selected); void populateUi(const QModelIndex ¤t); - void scrollTreeView(QListWidgetItem* item); + void scrollTreeView(QListWidgetItem* item); // For messages + void scrollTreeView(QTableWidgetItem* item); // For FIT table entries void openImageFile(); void openImageFileInNewWindow(); void saveImageFile(); + void search(); + void goToBase(); + void goToAddress(); void hexView(); - + void bodyHexView(); + void uncompressedHexView(); void goToData(); - + void extract(const UINT8 mode); void extractAsIs(); void extractBody(); @@ -98,28 +111,47 @@ private slots: void enableMessagesCopyActions(QListWidgetItem* item); void clearMessages(); + void toggleBootGuardMarking(bool enabled); + void about(); void aboutQt(); void exit(); void writeSettings(); + void loadGuidDatabase(); + void unloadGuidDatabase(); + void loadDefaultGuidDatabase(); + void exportDiscoveredGuids(); + void generateReport(); + + void currentTabChanged(int index); + +#if QT_VERSION_MAJOR >= 6 && QT_VERSION_MINOR >= 5 + void updateUiForNewColorScheme(Qt::ColorScheme scheme); +#endif + private: Ui::UEFITool* ui; TreeModel* model; FfsParser* ffsParser; FfsFinder* ffsFinder; + FfsReport* ffsReport; FfsOperations* ffsOps; FfsBuilder* ffsBuilder; SearchDialog* searchDialog; HexViewDialog* hexViewDialog; + GoToBaseDialog* goToBaseDialog; + GoToAddressDialog* goToAddressDialog; QClipboard* clipboard; QString currentDir; + QString currentPath; QString currentProgramPath; + QFont currentFont; const QString version; + bool markingEnabled; - bool enableExtractBodyUncompressed(const QModelIndex ¤t); - + bool eventFilter(QObject* obj, QEvent* event); void dragEnterEvent(QDragEnterEvent* event); void dropEvent(QDropEvent* event); void contextMenuEvent(QContextMenuEvent* event); @@ -127,7 +159,16 @@ private: void showParserMessages(); void showFinderMessages(); void showFitTable(); + void showSecurityInfo(); void showBuilderMessages(); + + enum { + TAB_PARSER, + TAB_FIT, + TAB_SECURITY, + TAB_SEARCH, + TAB_BUILDER + }; }; #endif // UEFITOOL_H diff --git a/UEFITool/uefitool.pro b/UEFITool/uefitool.pro index 1e15a6e..0f396f1 100644 --- a/UEFITool/uefitool.pro +++ b/UEFITool/uefitool.pro @@ -1,30 +1,44 @@ -QT += core gui -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets +QT += core gui widgets TARGET = UEFITool TEMPLATE = app +CONFIG += c++11 + +DEFINES += "U_ENABLE_FIT_PARSING_SUPPORT" +DEFINES += "U_ENABLE_NVRAM_PARSING_SUPPORT" +DEFINES += "U_ENABLE_ME_PARSING_SUPPORT" +DEFINES += "U_ENABLE_GUID_DATABASE_SUPPORT" + HEADERS += uefitool.h \ searchdialog.h \ hexviewdialog.h \ - messagelistitem.h \ - guidlineedit.h \ + gotobasedialog.h \ + gotoaddressdialog.h \ + hexlineedit.h \ ffsfinder.h \ + hexspinbox.h \ + ../common/fitparser.h \ + ../common/guiddatabase.h \ ../common/nvram.h \ + ../common/nvramparser.h \ + ../common/meparser.h \ ../common/ffsops.h \ ../common/basetypes.h \ ../common/descriptor.h \ ../common/gbe.h \ ../common/me.h \ ../common/ffs.h \ - ../common/fit.h \ ../common/peimage.h \ ../common/types.h \ ../common/utility.h \ ../common/parsingdata.h \ ../common/ffsbuilder.h \ ../common/ffsparser.h \ + ../common/ffsreport.h \ ../common/treeitem.h \ + ../common/intel_fit.h \ + ../common/intel_microcode.h \ ../common/treemodel.h \ ../common/LZMA/LzmaCompress.h \ ../common/LZMA/LzmaDecompress.h \ @@ -32,18 +46,61 @@ HEADERS += uefitool.h \ ../common/Tiano/EfiTianoCompress.h \ ../common/ustring.h \ ../common/ubytearray.h \ - ../qhexedit2/qhexedit.h \ - ../qhexedit2/chunks.h \ - ../qhexedit2/commands.h + ../common/umemstream.h \ + ../common/digest/sha1.h \ + ../common/digest/sha2.h \ + ../common/digest/sm3.h \ + ../common/generated/ami_nvar.h \ + ../common/generated/apple_sysf.h \ + ../common/generated/dell_dvar.h \ + ../common/generated/edk2_vss.h \ + ../common/generated/edk2_vss2.h \ + ../common/generated/edk2_ftw.h \ + ../common/generated/insyde_fdc.h \ + ../common/generated/insyde_fdm.h \ + ../common/generated/ms_slic_marker.h \ + ../common/generated/ms_slic_pubkey.h \ + ../common/generated/phoenix_flm.h \ + ../common/generated/phoenix_evsa.h \ + ../common/generated/intel_acbp_v1.h \ + ../common/generated/intel_acbp_v2.h \ + ../common/generated/intel_keym_v1.h \ + ../common/generated/intel_keym_v2.h \ + ../common/generated/intel_acm.h \ + ../common/kaitai/kaitaistream.h \ + ../common/kaitai/kaitaistruct.h \ + ../common/kaitai/exceptions.h \ + ../common/zlib/zlib.h \ + ../common/zlib/crc32.h \ + ../version.h \ + QHexView/include/QHexView/model/buffer/qhexbuffer.h \ + QHexView/include/QHexView/model/buffer/qdevicebuffer.h \ + QHexView/include/QHexView/model/buffer/qmemorybuffer.h \ + QHexView/include/QHexView/model/buffer/qmappedfilebuffer.h \ + QHexView/include/QHexView/model/commands/hexcommand.h \ + QHexView/include/QHexView/model/commands/insertcommand.h \ + QHexView/include/QHexView/model/commands/removecommand.h \ + QHexView/include/QHexView/model/commands/replacecommand.h \ + QHexView/include/QHexView/model/qhexcursor.h \ + QHexView/include/QHexView/model/qhexdelegate.h \ + QHexView/include/QHexView/model/qhexdocument.h \ + QHexView/include/QHexView/model/qhexmetadata.h \ + QHexView/include/QHexView/model/qhexoptions.h \ + QHexView/include/QHexView/model/qhexutils.h \ + QHexView/include/QHexView/qhexview.h SOURCES += uefitool_main.cpp \ uefitool.cpp \ searchdialog.cpp \ hexviewdialog.cpp \ - messagelistitem.cpp \ - guidlineedit.cpp \ + hexlineedit.cpp \ ffsfinder.cpp \ + hexspinbox.cpp \ + ../common/fitparser.cpp \ + ../common/guiddatabase.cpp \ ../common/nvram.cpp \ + ../common/nvramparser.cpp \ + ../common/meparser.cpp \ ../common/ffsops.cpp \ ../common/types.cpp \ ../common/descriptor.cpp \ @@ -52,10 +109,14 @@ SOURCES += uefitool_main.cpp \ ../common/utility.cpp \ ../common/ffsbuilder.cpp \ ../common/ffsparser.cpp \ + ../common/ffsreport.cpp \ ../common/treeitem.cpp \ ../common/treemodel.cpp \ ../common/LZMA/LzmaCompress.c \ ../common/LZMA/LzmaDecompress.c \ + ../common/LZMA/SDK/C/CpuArch.c \ + ../common/LZMA/SDK/C/Bra.c \ + ../common/LZMA/SDK/C/Bra86.c \ ../common/LZMA/SDK/C/LzFind.c \ ../common/LZMA/SDK/C/LzmaDec.c \ ../common/LZMA/SDK/C/LzmaEnc.c \ @@ -63,15 +124,68 @@ SOURCES += uefitool_main.cpp \ ../common/Tiano/EfiTianoCompress.c \ ../common/Tiano/EfiTianoCompressLegacy.c \ ../common/ustring.cpp \ - ../qhexedit2/qhexedit.cpp \ - ../qhexedit2/chunks.cpp \ - ../qhexedit2/commands.cpp + ../common/digest/sha1.c \ + ../common/digest/sha256.c \ + ../common/digest/sha512.c \ + ../common/digest/sm3.c \ + ../common/generated/ami_nvar.cpp \ + ../common/generated/apple_sysf.cpp \ + ../common/generated/dell_dvar.cpp \ + ../common/generated/edk2_vss.cpp \ + ../common/generated/edk2_vss2.cpp \ + ../common/generated/edk2_ftw.cpp \ + ../common/generated/insyde_fdc.cpp \ + ../common/generated/insyde_fdm.cpp \ + ../common/generated/ms_slic_marker.cpp \ + ../common/generated/ms_slic_pubkey.cpp \ + ../common/generated/phoenix_flm.cpp \ + ../common/generated/phoenix_evsa.cpp \ + ../common/generated/intel_acbp_v1.cpp \ + ../common/generated/intel_acbp_v2.cpp \ + ../common/generated/intel_keym_v1.cpp \ + ../common/generated/intel_keym_v2.cpp \ + ../common/generated/intel_acm.cpp \ + ../common/kaitai/kaitaistream.cpp \ + ../common/zlib/adler32.c \ + ../common/zlib/compress.c \ + ../common/zlib/crc32.c \ + ../common/zlib/deflate.c \ + ../common/zlib/gzclose.c \ + ../common/zlib/gzlib.c \ + ../common/zlib/gzread.c \ + ../common/zlib/gzwrite.c \ + ../common/zlib/inflate.c \ + ../common/zlib/infback.c \ + ../common/zlib/inftrees.c \ + ../common/zlib/inffast.c \ + ../common/zlib/trees.c \ + ../common/zlib/uncompr.c \ + ../common/zlib/zutil.c \ + QHexView/src/model/buffer/qhexbuffer.cpp \ + QHexView/src/model/buffer/qdevicebuffer.cpp \ + QHexView/src/model/buffer/qmemorybuffer.cpp \ + QHexView/src/model/buffer/qmappedfilebuffer.cpp \ + QHexView/src/model/commands/hexcommand.cpp \ + QHexView/src/model/commands/insertcommand.cpp \ + QHexView/src/model/commands/removecommand.cpp \ + QHexView/src/model/commands/replacecommand.cpp \ + QHexView/src/model/qhexcursor.cpp \ + QHexView/src/model/qhexdelegate.cpp \ + QHexView/src/model/qhexdocument.cpp \ + QHexView/src/model/qhexmetadata.cpp \ + QHexView/src/model/qhexutils.cpp \ + QHexView/src/qhexview.cpp + +INCLUDEPATH += QHexView/include/ FORMS += uefitool.ui \ searchdialog.ui \ - hexviewdialog.ui + hexviewdialog.ui \ + gotobasedialog.ui \ + gotoaddressdialog.ui +RESOURCES += uefitool.qrc RC_FILE = uefitool.rc - ICON = icons/uefitool.icns - +QMAKE_BUNDLE_DATA += ICONFILE +QMAKE_INFO_PLIST = Info.plist diff --git a/UEFITool/uefitool.qrc b/UEFITool/uefitool.qrc new file mode 100644 index 0000000..9b463ae --- /dev/null +++ b/UEFITool/uefitool.qrc @@ -0,0 +1,5 @@ + + + ../common/guids.csv + + \ No newline at end of file diff --git a/UEFITool/uefitool.ui b/UEFITool/uefitool.ui index 886435e..51b6248 100644 --- a/UEFITool/uefitool.ui +++ b/UEFITool/uefitool.ui @@ -132,15 +132,15 @@ true - - false -
+ + true + 0 @@ -203,6 +203,44 @@ + + + true + + + Security + + + + 0 + + + 5 + + + 5 + + + 5 + + + 5 + + + + + false + + + false + + + true + + + + + Search @@ -273,7 +311,7 @@ 0 0 851 - 21 + 31 @@ -284,7 +322,12 @@ - + + + + + + @@ -300,15 +343,23 @@ &Action + + false + &Capsule + + + + false + &Image @@ -317,6 +368,9 @@ + + false + &Region @@ -329,6 +383,9 @@ + + false + &Padding @@ -337,10 +394,15 @@ + + false + &Volume + + @@ -353,10 +415,15 @@ + + false + &File + + @@ -373,10 +440,15 @@ + + false + &Section + + @@ -393,7 +465,10 @@ - + + + false + &Messages @@ -402,11 +477,16 @@ - + + + false + - Variable + &Entry + + @@ -424,10 +504,15 @@ + + false + S&tore + + @@ -441,6 +526,10 @@ + + + + @@ -448,13 +537,21 @@ - - - + + + + + + + + &View + + + @@ -609,6 +706,9 @@ About &Qt + + Shift+F1 + QAction::AboutQtRole @@ -617,6 +717,9 @@ &Quit + + Alt+X + QAction::QuitRole @@ -626,13 +729,16 @@ false - Sear&ch... + Searc&h... Ctrl+F + + false + Clea&r @@ -658,6 +764,9 @@ + + false + &Copy @@ -666,6 +775,9 @@ + + false + Copy &all @@ -700,7 +812,10 @@ false - Go to &data + Go &to data + + + Ctrl+T @@ -714,6 +829,113 @@ Ctrl+D + + + false + + + &Select item at base... + + + Ctrl+G + + + + + false + + + Body hex vie&w... + + + Ctrl+Shift+D + + + + + false + + + Un&compressed hex view... + + + Ctrl+Alt+D + + + + + Load &GUID database... + + + Ctrl+Alt+G + + + + + false + + + Select item at &address... + + + Ctrl+Shift+G + + + + + true + + + true + + + BootGuard &markings + + + Ctrl+Shift+B + + + + + false + + + Generate &report... + + + Generate report + + + Ctrl+Alt+R + + + + + &Unload GUID database + + + Ctrl+Alt+U + + + + + Load &default GUID database + + + Ctrl+Alt+D + + + + + false + + + &Export discovered GUIDs... + + + Ctrl+Alt+E + + diff --git a/UEFITool/uefitool_main.cpp b/UEFITool/uefitool_main.cpp index a9ac03a..a932a9b 100644 --- a/UEFITool/uefitool_main.cpp +++ b/UEFITool/uefitool_main.cpp @@ -1,32 +1,64 @@ /* uefitool_main.cpp - - Copyright (c) 2014, Nikolaj Schlej. All rights reserved. - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - */ + + Copyright (c) 2022, Nikolaj Schlej. All rights reserved. + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + */ #include #include #include "uefitool.h" +class UEFIToolApplication : public QApplication +{ + UEFITool* tool; + +public: + UEFIToolApplication(int &argc, char **argv) + : QApplication(argc, argv) + { + setOrganizationName("CodeRush"); + setOrganizationDomain("coderush.me"); + setApplicationName("UEFITool"); +#if QT_VERSION >= QT_VERSION_CHECK(5, 7, 0) + setDesktopFileName("uefitool"); +#endif + tool = new UEFITool(); + } + + virtual ~UEFIToolApplication() { + delete tool; + } + + virtual bool event(QEvent *event) + { + if (event->type() == QEvent::FileOpen) { + QFileOpenEvent *openEvent = static_cast(event); + tool->openImageFile(openEvent->file()); + } + + return QApplication::event(event); + } + + int startup() + { + tool->setProgramPath(arguments().at(0)); + if (arguments().length() > 1) + tool->openImageFile(arguments().at(1)); + tool->show(); + + return exec(); + } +}; + int main(int argc, char *argv[]) { - QApplication a(argc, argv); - a.setOrganizationName("CodeRush"); - a.setOrganizationDomain("coderush.me"); - a.setApplicationName("UEFITool"); - - UEFITool w; - w.setProgramPath(a.arguments().at(0)); - if (a.arguments().length() > 1) - w.openImageFile(a.arguments().at(1)); - w.show(); - - return a.exec(); -} \ No newline at end of file + UEFIToolApplication a(argc, argv); + return a.startup(); +} diff --git a/appstream/UEFITool.png b/appstream/UEFITool.png new file mode 100644 index 0000000..1490c49 Binary files /dev/null and b/appstream/UEFITool.png differ diff --git a/appstream/appdata.xml b/appstream/appdata.xml new file mode 100644 index 0000000..c67deaa --- /dev/null +++ b/appstream/appdata.xml @@ -0,0 +1,23 @@ + + + com.github.LongSoft.UEFITool + com.github.LongSoft.UEFITool.desktop + UEFITool + UEFI firmware image viewer and editor + +

UEFITool is a cross-platform open source application, that parses UEFI PI-compatible firmware image into a tree structure, verifies image integrity and provides a GUI to manipulate image elements.

+
+ + + https://github.com/LongSoft/UEFITool/raw/new_engine/appstream/UEFITool.png + + + + + + https://github.com/LongSoft/UEFITool + LongSoft + CC0-1.0 + BSD-2-Clause + +
diff --git a/bstrlib/README.md b/bstrlib/README.md deleted file mode 100644 index 367650b..0000000 --- a/bstrlib/README.md +++ /dev/null @@ -1,34 +0,0 @@ -The Better String Library - -The Better String Library is an abstraction of a string data type which is -superior to the C library char buffer string type, or C++'s std::string. -Among the features achieved are: - - - Substantial mitigation of buffer overflow/overrun problems and other - failures that result from erroneous usage of the common C string - library functions - - - Significantly simplified string manipulation - - - High performance interoperability with other source/libraries which - expect '\0' terminated char buffers - - - Improved overall performance of common string operations - - - Functional equivalency with other more modern languages - -The library is totally stand alone, portable (known to work with gcc/g++, -MSVC++, Intel C++, WATCOM C/C++, Turbo C, Borland C++, IBM's native CC -compiler on Windows, Linux and Mac OS X), high performance, easy to use and -is not part of some other collection of data structures. Even the file I/O -functions are totally abstracted (so that other stream-like mechanisms, like -sockets, can be used.) Nevertheless, it is adequate as a complete -replacement of the C string library for string manipulation in any C program. - -The library includes a robust C++ wrapper that uses overloaded operators, -rich constructors, exceptions, stream I/O and STL to make the CBString -struct a natural and powerful string abstraction with more functionality and -higher performance than std::string. - -Bstrlib is stable, well tested and suitable for any software production -environment. diff --git a/bstrlib/bsafe.c b/bstrlib/bsafe.c deleted file mode 100644 index dc32e90..0000000 --- a/bstrlib/bsafe.c +++ /dev/null @@ -1,82 +0,0 @@ -/* - * This source file is part of the bstring string library. This code was - * written by Paul Hsieh in 2002-2015, and is covered by the BSD open source - * license. Refer to the accompanying documentation for details on usage and - * license. - */ - -/* - * bsafe.c - * - * This is an optional module that can be used to help enforce a safety - * standard based on pervasive usage of bstrlib. This file is not necessarily - * portable, however, it has been tested to work correctly with Intel's C/C++ - * compiler, WATCOM C/C++ v11.x and Microsoft Visual C++. - */ - -#include -#include -#include "bsafe.h" - -static int bsafeShouldExit = 1; - -char * strcpy (char *dst, const char *src); -char * strcat (char *dst, const char *src); - -char * strcpy (char *dst, const char *src) { - (void) dst; - (void) src; - fprintf (stderr, "bsafe error: strcpy() is not safe, use bstrcpy instead.\n"); - if (bsafeShouldExit) exit (-1); - return NULL; -} - -char * strcat (char *dst, const char *src) { - (void) dst; - (void) src; - fprintf (stderr, "bsafe error: strcat() is not safe, use bstrcat instead.\n"); - if (bsafeShouldExit) exit (-1); - return NULL; -} - -#if !defined (__GNUC__) && (!defined(_MSC_VER) || (_MSC_VER <= 1310)) -char * (gets) (char * buf) { - (void) buf; - fprintf (stderr, "bsafe error: gets() is not safe, use bgets.\n"); - if (bsafeShouldExit) exit (-1); - return NULL; -} -#endif - -char * (strncpy) (char *dst, const char *src, size_t n) { - (void) dst; - (void) src; - (void) n; - fprintf (stderr, "bsafe error: strncpy() is not safe, use bmidstr instead.\n"); - if (bsafeShouldExit) exit (-1); - return NULL; -} - -char * (strncat) (char *dst, const char *src, size_t n) { - (void) dst; - (void) src; - (void) n; - fprintf (stderr, "bsafe error: strncat() is not safe, use bstrcat then btrunc\n\tor cstr2tbstr, btrunc then bstrcat instead.\n"); - if (bsafeShouldExit) exit (-1); - return NULL; -} - -char * (strtok) (char *s1, const char *s2) { - (void) s1; - (void) s2; - fprintf (stderr, "bsafe error: strtok() is not safe, use bsplit or bsplits instead.\n"); - if (bsafeShouldExit) exit (-1); - return NULL; -} - -char * (strdup) (const char *s) { - (void) s; - fprintf (stderr, "bsafe error: strdup() is not safe, use bstrcpy.\n"); - if (bsafeShouldExit) exit (-1); - return NULL; -} diff --git a/bstrlib/bsafe.h b/bstrlib/bsafe.h deleted file mode 100644 index 6ee49cf..0000000 --- a/bstrlib/bsafe.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * This source file is part of the bstring string library. This code was - * written by Paul Hsieh in 2002-2004, and is covered by the BSD open source - * license. Refer to the accompanying documentation for details on usage and - * license. - */ - -/* - * bsafe.h - * - * This is an optional module that can be used to help enforce a safety - * standard based on pervasive usage of bstrlib. This file is not necessarily - * portable, however, it has been tested to work correctly with Intel's C/C++ - * compiler, WATCOM C/C++ v11.x and Microsoft Visual C++. - */ - -#ifndef BSTRLIB_BSAFE_INCLUDE -#define BSTRLIB_BSAFE_INCLUDE - -#ifdef __cplusplus -extern "C" { -#endif - -#if !defined (__GNUC__) && (!defined(_MSC_VER) || (_MSC_VER <= 1310)) -/* This is caught in the linker, so its not necessary for gcc. */ -extern char * (gets) (char * buf); -#endif - -extern char * (strncpy) (char *dst, const char *src, size_t n); -extern char * (strncat) (char *dst, const char *src, size_t n); -extern char * (strtok) (char *s1, const char *s2); -extern char * (strdup) (const char *s); - -#undef strcpy -#undef strcat -#define strcpy(a,b) bsafe_strcpy(a,b) -#define strcat(a,b) bsafe_strcat(a,b) - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/bstrlib/bstest.c b/bstrlib/bstest.c deleted file mode 100644 index 773768d..0000000 --- a/bstrlib/bstest.c +++ /dev/null @@ -1,3689 +0,0 @@ -/* - * This source file is part of the bstring string library. This code was - * written by Paul Hsieh in 2002-2015, and is covered by the BSD open source - * license. Refer to the accompanying documentation for details on usage and - * license. - */ - -/* - * bstest.c - * - * This file is the C unit test for Bstrlib. - */ - -#include -#include -#include -#include -#include -#include "bstrlib.h" -#include "bstraux.h" - -static bstring dumpOut[16]; -static int rot = 0; - -static int incorrectBstring (const struct tagbstring * b) { - if (NULL == b) return 1; - if (NULL == b->data) return 1; - if (b->slen < 0) return 1; - if (b->mlen > 0 && b->slen > b->mlen) return 1; - if (b->data[b->slen] != '\0') return 1; - return 0; -} - -static char * dumpBstring (const struct tagbstring * b) { - rot = (rot + 1) % (unsigned)16; - if (dumpOut[rot] == NULL) { - dumpOut[rot] = bfromcstr (""); - if (dumpOut[rot] == NULL) return "FATAL INTERNAL ERROR"; - } - dumpOut[rot]->slen = 0; - if (b == NULL) { - bcatcstr (dumpOut[rot], "NULL"); - } else { - static char msg[256]; - sprintf (msg, "%p", (void *)b); - bcatcstr (dumpOut[rot], msg); - - if (b->slen < 0) { - sprintf (msg, ":[err:slen=%d<0]", b->slen); - bcatcstr (dumpOut[rot], msg); - } else { - if (b->mlen > 0 && b->mlen < b->slen) { - sprintf (msg, ":[err:mlen=%dmlen, b->slen); - bcatcstr (dumpOut[rot], msg); - } else { - if (b->mlen == -1) { - bcatcstr (dumpOut[rot], "[p]"); - } else if (b->mlen < 0) { - bcatcstr (dumpOut[rot], "[c]"); - } - bcatcstr (dumpOut[rot], ":"); - if (b->data == NULL) { - bcatcstr (dumpOut[rot], "[err:data=NULL]"); - } else { - bcatcstr (dumpOut[rot], "\""); - bcatcstr (dumpOut[rot], (const char *) b->data); - bcatcstr (dumpOut[rot], "\""); - } - } - } - } - return (char *) dumpOut[rot]->data; -} - -static char* dumpCstring (const char* s) { - rot = (rot + 1) % (unsigned)16; - if (dumpOut[rot] == NULL) { - dumpOut[rot] = bfromcstr (""); - if (dumpOut[rot] == NULL) return "FATAL INTERNAL ERROR"; - } - dumpOut[rot]->slen = 0; - if (s == NULL) { - bcatcstr (dumpOut[rot], "NULL"); - } else { - static char msg[64]; - int i; - - sprintf (msg, "cstr[%p] -> ", (void *)s); - bcatcstr (dumpOut[rot], msg); - - bcatStatic (dumpOut[rot], "\""); - for (i = 0; s[i]; i++) { - if (i > 1024) { - bcatStatic (dumpOut[rot], " ..."); - break; - } - bconchar (dumpOut[rot], s[i]); - } - bcatStatic (dumpOut[rot], "\""); - } - - return (char *) dumpOut[rot]->data; -} - -static int test0_0 (const char * s, const char * res) { -bstring b0 = bfromcstr (s); -int ret = 0; - - if (s == NULL) { - if (res != NULL) ret++; - printf (".\tbfromcstr (NULL) = %s\n", dumpBstring (b0)); - return ret; - } - - ret += (res == NULL) || ((int) strlen (res) != b0->slen) - || (0 != memcmp (res, b0->data, b0->slen)); - ret += b0->data[b0->slen] != '\0'; - - printf (".\tbfromcstr (\"%s\") = %s\n", s, dumpBstring (b0)); - bdestroy (b0); - return ret; -} - -static int test0_1 (const char * s, int len, const char * res) { -bstring b0 = bfromcstralloc (len, s); -int ret = 0; - - if (s == NULL) { - if (res != NULL) ret++; - printf (".\tbfromcstralloc (*, NULL) = %s\n", dumpBstring (b0)); - return ret; - } - - ret += (res == NULL) || ((int) strlen (res) != b0->slen) - || (0 != memcmp (res, b0->data, b0->slen)); - ret += b0->data[b0->slen] != '\0'; - ret += len > b0->mlen; - - printf (".\tbfromcstralloc (%d, \"%s\") = %s\n", len, s, dumpBstring (b0)); - bdestroy (b0); - return ret; -} - -#define EMPTY_STRING "" -#define SHORT_STRING "bogus" -#define EIGHT_CHAR_STRING "Waterloo" -#define LONG_STRING "This is a bogus but reasonably long string. Just long enough to cause some mallocing." - -static int test0_2 (char* s) { -int l = s?strlen(s):2; -int i, j, k; -int ret = 0; - - for (i = 0; i < l*2; i++) { - for (j = 0; j < l*2; j++) { - for (k = 0; k <= l; k++) { - char* t = s ? (s + k) : NULL; - bstring b = bfromcstrrangealloc (i, j, t); - if (NULL == b) { - if (i < j && t != NULL) { - printf ("[%d] i = %d, j = %d, l = %d, k = %d\n", __LINE__, i, j, l, k); - } - ret += (i < j && t != NULL); - continue; - } - if (NULL == t) { - printf ("[%d] i = %d, j = %d, l = %d, k = %d\n", __LINE__, i, j, l, k); - ret++; - bdestroy (b); - continue; - } - if (b->data == NULL) { - printf ("[%d] i = %d, j = %d, l = %d, k = %d\n", __LINE__, i, j, l, k); - ret++; - continue; - } - if (b->slen != l-k || b->data[l-k] != '\0' || b->mlen <= b->slen) { - printf ("[%d] i = %d, j = %d, l = %d, k = %d, b->slen = %d\n", __LINE__, i, j, l, k, b->slen); - ret++; - } else if (0 != memcmp (t, b->data, l-k+1)) { - printf ("[%d] \"%s\" != \"%s\"\n", b->data, t); - ret++; - } - bdestroy (b); - continue; - } - } - } - - printf (".\tbfromcstrrangealloc (*,*,%s) correct\n", dumpCstring(s)); - return ret; -} - -static int test0 (void) { -int ret = 0; - - printf ("TEST: bstring bfromcstr (const char * str);\n"); - - /* tests with NULL */ - ret += test0_0 (NULL, NULL); - - /* normal operation tests */ - ret += test0_0 (EMPTY_STRING, EMPTY_STRING); - ret += test0_0 (SHORT_STRING, SHORT_STRING); - ret += test0_0 (LONG_STRING, LONG_STRING); - printf ("\t# failures: %d\n", ret); - - printf ("TEST: bstring bfromcstralloc (int len, const char * str);\n"); - - /* tests with NULL */ - ret += test0_1 (NULL, 0, NULL); - ret += test0_1 (NULL, 30, NULL); - - /* normal operation tests */ - ret += test0_1 (EMPTY_STRING, 0, EMPTY_STRING); - ret += test0_1 (EMPTY_STRING, 30, EMPTY_STRING); - ret += test0_1 (SHORT_STRING, 0, SHORT_STRING); - ret += test0_1 (SHORT_STRING, 30, SHORT_STRING); - ret += test0_1 ( LONG_STRING, 0, LONG_STRING); - ret += test0_1 ( LONG_STRING, 30, LONG_STRING); - - printf ("TEST: bstring bfromcstrrangealloc (int minl, int maxl, const char * str);\n"); - - ret += test0_2 (NULL); - ret += test0_2 (EMPTY_STRING); - ret += test0_2 ( LONG_STRING); - - printf ("\t# failures: %d\n", ret); - - return ret; -} - -static int test1_0 (const void * blk, int len, const char * res) { -bstring b0 = blk2bstr (blk, len); -int ret = 0; - if (b0 == NULL) { - if (res != NULL) ret++; - printf (".\tblk2bstr (NULL, len=%d) = %s\n", len, dumpBstring (b0)); - } else { - ret += (res == NULL) || (len != b0->slen) - || (0 != memcmp (res, b0->data, len)); - ret += b0->data[b0->slen] != '\0'; - printf (".\tblk2bstr (blk=%p, len=%d) = %s\n", blk, len, dumpBstring (b0)); - } - - if (ret) { - printf ("\t\tfailure(%d) = %d (res = %p", __LINE__, ret, res); - if (res) printf (" = \"%s\"", res); - printf (")\n"); - } - bdestroy (b0); - return ret; -} - -static int test1 (void) { -int ret = 0; - - printf ("TEST: bstring blk2bstr (const void * blk, int len);\n"); - - /* tests with NULL */ - ret += test1_0 (NULL, 10, NULL); - ret += test1_0 (NULL, 0, NULL); - ret += test1_0 (NULL, -1, NULL); - - /* normal operation tests */ - ret += test1_0 (SHORT_STRING, sizeof (SHORT_STRING)-1, SHORT_STRING); - ret += test1_0 (LONG_STRING, sizeof (LONG_STRING)-1, LONG_STRING); - ret += test1_0 (LONG_STRING, 5, "This "); - ret += test1_0 (LONG_STRING, 0, ""); - ret += test1_0 (LONG_STRING, -1, NULL); - printf ("\t# failures: %d\n", ret); - return ret; -} - -static int test2_0 (const_bstring b, char z, const unsigned char * res) { -char * s = bstr2cstr (b, z); -int ret = 0; - if (s == NULL) { - if (res != NULL) ret++; - printf (".\tbstr2cstr (%s, %02X) = NULL\n", dumpBstring (b), z); - free(s); - return ret; - } - - if (res == NULL) ret++; - else { - if (z != '\0') if ((int) strlen (s) != b->slen) ret++; - if (!ret) { - ret += (0 != memcmp (res, b->data, b->slen)); - } - } - - printf (".\tbstr2cstr (%s, %02X) = \"%s\"\n", dumpBstring (b), z, s); - free (s); - return ret; -} - -struct tagbstring emptyBstring = bsStatic (""); -struct tagbstring shortBstring = bsStatic ("bogus"); -struct tagbstring longBstring = bsStatic ("This is a bogus but reasonably long string. Just long enough to cause some mallocing."); - -struct tagbstring badBstring1 = {8, 4, NULL}; -struct tagbstring badBstring2 = {2, -5, (unsigned char *) "bogus"}; -struct tagbstring badBstring3 = {2, 5, (unsigned char *) "bogus"}; - -struct tagbstring xxxxxBstring = bsStatic ("xxxxx"); - -static int test2 (void) { -int ret = 0; - - printf ("TEST: char * bstr2cstr (const_bstring s, char z);\n"); - - /* tests with NULL */ - ret += test2_0 (NULL, (char) '?', NULL); - - /* normal operation tests */ - ret += test2_0 (&emptyBstring, (char) '?', emptyBstring.data); - ret += test2_0 (&shortBstring, (char) '?', shortBstring.data); - ret += test2_0 (&longBstring, (char) '?', longBstring.data); - ret += test2_0 (&badBstring1, (char) '?', NULL); - ret += test2_0 (&badBstring2, (char) '?', NULL); - printf ("\t# failures: %d\n", ret); - return ret; -} - -static int test3_0 (const_bstring b) { -bstring b0 = bstrcpy (b); -int ret = 0; - printf (".\tbstrcpy (%s) = %s\n", dumpBstring (b), dumpBstring (b0)); - if (b0 == NULL) { - if (b != NULL && b->data != NULL && b->slen >= 0) ret++; - } else { - ret += (b == NULL) || (b->slen != b0->slen) - || (0 != memcmp (b->data, b0->data, b->slen)); - ret += b0->data[b0->slen] != '\0'; - } - bdestroy (b0); - return ret; -} - -static int test3 (void) { -int ret = 0; - - printf ("TEST: bstring bstrcpy (const_bstring b1);\n"); - - /* tests with NULL to make sure that there is NULL propogation */ - ret += test3_0 (NULL); - ret += test3_0 (&badBstring1); - ret += test3_0 (&badBstring2); - - /* normal operation tests */ - ret += test3_0 (&emptyBstring); - ret += test3_0 (&shortBstring); - ret += test3_0 (&longBstring); - printf ("\t# failures: %d\n", ret); - return ret; -} - -static int test4_0 (const_bstring b, int left, int len, const char * res) { -bstring b0 = bmidstr (b, left, len); -int ret = 0; - printf (".\tbmidstr (%s, %d, %d) = %s\n", dumpBstring (b), left, len, dumpBstring (b0)); - if (b0 == NULL) { - if (b != NULL && b->data != NULL && b->slen >= 0 && len >= 0) ret++; - } else { - ret += (b == NULL) || (res == NULL) || (b0->slen > len && len >= 0) - || (b0->slen != (int) strlen (res)) - || (b0->slen > 0 && 0 != memcmp (res, b0->data, b0->slen)); - ret += b0->data[b0->slen] != '\0'; - } - if (ret) { - printf ("(b == NULL) = %d\n", (b == NULL)); - printf ("(res == NULL) = %d\n", (res == NULL)); - printf ("(b0->slen > len && len >= 0) = %d\n", (b0->slen > len && len >= 0)); - if (res) printf ("(b0->slen != strlen (res)) = %d\n", (b0->slen != (int) strlen (res))); - printf ("(b0->slen > 0 && 0 != memcmp (res, b0->data, b0->slen) = %d\n", (b0->slen > 0 && 0 != memcmp (res, b0->data, b0->slen))); - - printf ("\t\tfailure(%d) = %d (res = %p", __LINE__, ret, res); - if (res) printf (" = \"%s\"", res); - printf (")\n"); - } - bdestroy (b0); - return ret; -} - -static int test4 (void) { -int ret = 0; - - printf ("TEST: bstring bmidstr (const_bstring b, int left, int len);\n"); - - /* tests with NULL to make sure that there is NULL propogation */ - ret += test4_0 (NULL, 0, 0, NULL); - ret += test4_0 (NULL, 0, 2, NULL); - ret += test4_0 (NULL, 0, -2, NULL); - ret += test4_0 (NULL, -5, 2, NULL); - ret += test4_0 (NULL, -5, -2, NULL); - ret += test4_0 (&badBstring1, 1, 3, NULL); - ret += test4_0 (&badBstring2, 1, 3, NULL); - - /* normal operation tests on all sorts of subranges */ - ret += test4_0 (&emptyBstring, 0, 0, ""); - ret += test4_0 (&emptyBstring, 0, -1, ""); - ret += test4_0 (&emptyBstring, 1, 3, ""); - ret += test4_0 (&shortBstring, 0, 0, ""); - ret += test4_0 (&shortBstring, 0, -1, ""); - ret += test4_0 (&shortBstring, 1, 3, "ogu"); - ret += test4_0 (&shortBstring, -1, 3, "bo"); - ret += test4_0 (&shortBstring, -1, 9, "bogus"); - ret += test4_0 (&shortBstring, 3, -1, ""); - ret += test4_0 (&shortBstring, 9, 3, ""); - printf ("\t# failures: %d\n", ret); - return ret; -} - -static int test5_0 (bstring b0, const_bstring b1, const char * res) { -bstring b2; -int rv, ret = 0; - - if (b0 != NULL && b0->data != NULL && b0->slen >= 0 && - b1 != NULL && b1->data != NULL && b1->slen >= 0 ) { - b2 = bstrcpy (b0); - bwriteprotect (*b2); - - printf (".\tbconcat (%s, ", dumpBstring (b2)); - - rv = bconcat (b2, b1); - ret += (rv == 0); - if (!biseq (b0, b2)) ret++; - - printf ("%s) = %s\n", dumpBstring (b1), dumpBstring (b2)); - - bwriteallow (*b2); - - printf (".\tbconcat (%s, ", dumpBstring (b2)); - - rv = bconcat (b2, b1); - - printf ("%s) = %s\n", dumpBstring (b1), dumpBstring (b2)); - - if (b1) ret += (b2->slen != b0->slen + b1->slen); - ret += ((0 != rv) && (b1 != NULL)) || ((0 == rv) && (b1 == NULL)); - ret += (res == NULL) || ((int) strlen (res) > b2->slen) - || (0 != memcmp (b2->data, res, b2->slen)); - ret += b2->data[b2->slen] != '\0'; - bdestroy (b2); - } else { - ret += (BSTR_ERR != (rv = bconcat (b0, b1))); - printf (".\tbconcat (%s, %s) = %d\n", dumpBstring (b0), dumpBstring (b1), rv); - } - - if (ret) { - printf ("\t\tfailure(%d) = %d (res = %p", __LINE__, ret, res); - if (res) printf (" = \"%s\"", res); - printf (")\n"); - } - return ret; -} - -static int test5_1 (void) { -bstring b, c; -struct tagbstring t; -int i, ret; - - printf ("TEST: bconcat aliasing\n"); - for (ret=i=0; i < longBstring.slen; i++) { - b = bstrcpy (&longBstring); - c = bstrcpy (&longBstring); - bmid2tbstr (t, b, i, longBstring.slen); - ret += 0 != bconcat (c, &t); - ret += 0 != bconcat (b, &t); - ret += !biseq (b, c); - bdestroy (b); - bdestroy (c); - } - - b = bfromcstr ("abcd"); - c = bfromcstr ("abcd"); - - for (ret=i=0; i < 100; i++) { - bmid2tbstr (t, b, 0, 3); - ret += 0 != bcatcstr (c, "abc"); - ret += 0 != bconcat (b, &t); - ret += !biseq (b, c); - } - - bdestroy (b); - bdestroy (c); - - if (ret) { - printf ("\t\talias failures(%d) = %d\n", __LINE__, ret); - } - - return ret; -} - -static int test5 (void) { -int ret = 0; - - printf ("TEST: int bconcat (bstring b0, const_bstring b1);\n"); - - /* tests with NULL */ - ret += test5_0 (NULL, NULL, NULL); - ret += test5_0 (NULL, &emptyBstring, NULL); - ret += test5_0 (&emptyBstring, NULL, ""); - ret += test5_0 (&emptyBstring, &badBstring1, NULL); - ret += test5_0 (&emptyBstring, &badBstring2, NULL); - ret += test5_0 (&badBstring1, &emptyBstring, NULL); - ret += test5_0 (&badBstring2, &emptyBstring, NULL); - - /* normal operation tests on all sorts of subranges */ - ret += test5_0 (&emptyBstring, &emptyBstring, ""); - ret += test5_0 (&emptyBstring, &shortBstring, "bogus"); - ret += test5_0 (&shortBstring, &emptyBstring, "bogus"); - ret += test5_0 (&shortBstring, &shortBstring, "bogusbogus"); - - ret += test5_1 (); - - printf ("\t# failures: %d\n", ret); - return ret; -} - -static int test6_0 (bstring b, char c, const char * res) { -bstring b0; -int rv, ret = 0; - - if (b != NULL && b->data != NULL && b->slen >= 0) { - b0 = bstrcpy (b); - bwriteprotect (*b0); - rv = bconchar (b0, c); - ret += (rv == 0); - if (!biseq (b0, b)) ret++; - - printf (".\tbconchar (%s, %c) = %s\n", dumpBstring (b), c, dumpBstring (b0)); - - bwriteallow (*b0); - rv = bconchar (b0, c); - ret += (0 != rv); - ret += (b0->slen != b->slen + 1); - ret += (res == NULL) || ((int) strlen (res) > b0->slen) - || (0 != memcmp (b0->data, res, b0->slen)); - ret += b0->data[b0->slen] != '\0'; - printf (".\tbconchar (%s, %c) = %s\n", dumpBstring (b), c, dumpBstring (b0)); - - bdestroy (b0); - } else { - ret += (BSTR_ERR != (rv = bconchar (b, c))); - printf (".\tbconchar (%s, %c) = %d\n", dumpBstring (b), c, rv); - } - - if (ret) { - printf ("\t\tfailure(%d) = %d (res = %p", __LINE__, ret, res); - if (res) printf (" = \"%s\"", res); - printf (")\n"); - } - return ret; -} - -static int test6 (void) { -int ret = 0; - - printf ("TEST: int bconchar (bstring b, char c);\n"); - - /* tests with NULL */ - ret += test6_0 (NULL, (char) 'x', NULL); - ret += test6_0 (&badBstring1, (char) 'x', NULL); - ret += test6_0 (&badBstring2, (char) 'x', NULL); - - /* normal operation tests on all sorts of subranges */ - ret += test6_0 (&emptyBstring, (char) 'x', "x"); - ret += test6_0 (&shortBstring, (char) 'x', "bogusx"); - printf ("\t# failures: %d\n", ret); - return ret; -} - -static int test7x8_0 (char * fnname, int (* fnptr) (const struct tagbstring *, const struct tagbstring *), const struct tagbstring * b0, const struct tagbstring * b1, int res) { -int rv, ret = 0; - - ret += (res != (rv = fnptr (b0, b1))); - printf (".\t%s (%s, %s) = %d\n", fnname, dumpBstring (b0), dumpBstring (b1), rv); - if (ret) { - printf ("\t\tfailure(%d) = %d (res = %d)\n", __LINE__, ret, res); - } - return ret; -} - -static int test7x8 (char * fnname, int (* fnptr) (const struct tagbstring *, const struct tagbstring *), - int retFail, int retLT, int retGT, int retEQ) { -int ret = 0; - - printf ("TEST: int %s (const_bstring b0, const_bstring b1);\n", fnname); - - /* tests with NULL */ - ret += test7x8_0 (fnname, fnptr, NULL, NULL, retFail); - ret += test7x8_0 (fnname, fnptr, &emptyBstring, NULL, retFail); - ret += test7x8_0 (fnname, fnptr, NULL, &emptyBstring, retFail); - ret += test7x8_0 (fnname, fnptr, &shortBstring, NULL, retFail); - ret += test7x8_0 (fnname, fnptr, NULL, &shortBstring, retFail); - ret += test7x8_0 (fnname, fnptr, &badBstring1, &badBstring1, retFail); - ret += test7x8_0 (fnname, fnptr, &badBstring2, &badBstring2, retFail); - ret += test7x8_0 (fnname, fnptr, &shortBstring, &badBstring2, retFail); - ret += test7x8_0 (fnname, fnptr, &badBstring2, &shortBstring, retFail); - - /* normal operation tests on all sorts of subranges */ - ret += test7x8_0 (fnname, fnptr, &emptyBstring, &emptyBstring, retEQ); - ret += test7x8_0 (fnname, fnptr, &shortBstring, &emptyBstring, retGT); - ret += test7x8_0 (fnname, fnptr, &emptyBstring, &shortBstring, retLT); - ret += test7x8_0 (fnname, fnptr, &shortBstring, &shortBstring, retEQ); - - { - bstring b = bstrcpy (&shortBstring); - b->data[1]++; - ret += test7x8_0 (fnname, fnptr, b, &shortBstring, retGT); - bdestroy (b); - } - - if (fnptr == biseq) { - ret += test7x8_0 (fnname, fnptr, &shortBstring, &longBstring, retGT); - ret += test7x8_0 (fnname, fnptr, &longBstring, &shortBstring, retLT); - } else { - ret += test7x8_0 (fnname, fnptr, &shortBstring, &longBstring, 'b'-'T'); - ret += test7x8_0 (fnname, fnptr, &longBstring, &shortBstring, 'T'-'b'); - } - - printf ("\t# failures: %d\n", ret); - return ret; -} - -#define test7() test7x8 ("biseq", biseq, -1, 0, 0, 1) -#define test8() test7x8 ("bstrcmp", bstrcmp, SHRT_MIN, -1, 1, 0) - -static int test47_0 (const struct tagbstring* b, const unsigned char* blk, int len, int res) { -int rv, ret = 0; - - ret += (res != (rv = biseqblk (b, blk, len))); - printf (".\tbiseqblk (%s, %s) = %d\n", dumpBstring (b), dumpCstring (blk), rv); - if (ret) { - printf ("\t\tfailure(%d) = %d (res = %d)\n", __LINE__, ret, res); - } - return ret; -} - -static int test47 (void) { -int ret = 0; - - printf ("TEST: int biseqblk (const_bstring b, const void * blk, int len);\n"); - - /* tests with NULL */ - ret += test47_0 (NULL, NULL, 0, -1); - ret += test47_0 (&emptyBstring, NULL, 0, -1); - ret += test47_0 (NULL, emptyBstring.data, 0, -1); - ret += test47_0 (&shortBstring, NULL, shortBstring.slen, -1); - ret += test47_0 (NULL, shortBstring.data, 0, -1); - ret += test47_0 (&badBstring1, badBstring1.data, badBstring1.slen, -1); - ret += test47_0 (&badBstring2, badBstring2.data, badBstring2.slen, -1); - ret += test47_0 (&shortBstring, badBstring2.data, badBstring2.slen, -1); - ret += test47_0 (&badBstring2, shortBstring.data, shortBstring.slen, -1); - - /* normal operation tests on all sorts of subranges */ - ret += test47_0 (&emptyBstring, emptyBstring.data, emptyBstring.slen, 1); - ret += test47_0 (&shortBstring, emptyBstring.data, emptyBstring.slen, 0); - ret += test47_0 (&emptyBstring, shortBstring.data, shortBstring.slen, 0); - ret += test47_0 (&shortBstring, shortBstring.data, shortBstring.slen, 1); - - { - bstring b = bstrcpy (&shortBstring); - b->data[1]++; - ret += test47_0 (b, shortBstring.data, shortBstring.slen, 0); - bdestroy (b); - } - ret += test47_0 (&shortBstring, longBstring.data, longBstring.slen, 0); - ret += test47_0 (&longBstring, shortBstring.data, shortBstring.slen, 0); - - printf ("\t# failures: %d\n", ret); - return ret; -} - -static int test9_0 (const_bstring b0, const_bstring b1, int n, int res) { -int rv, ret = 0; - - ret += (res != (rv = bstrncmp (b0, b1, n))); - printf (".\tbstrncmp (%s, %s, %d) = %d\n", dumpBstring (b0), dumpBstring (b1), n, rv); - if (ret) { - printf ("\t\tfailure(%d) = %d (res = %d)\n", __LINE__, ret, res); - } - return ret; -} - -static int test9 (void) { -int ret = 0; - - printf ("TEST: int bstrncmp (const_bstring b0, const_bstring b1, int n);\n"); - - /* tests with NULL */ - ret += test9_0 (NULL, NULL, 0, SHRT_MIN); - ret += test9_0 (NULL, NULL, -1, SHRT_MIN); - ret += test9_0 (NULL, NULL, 1, SHRT_MIN); - ret += test9_0 (&emptyBstring, NULL, 0, SHRT_MIN); - ret += test9_0 (NULL, &emptyBstring, 0, SHRT_MIN); - ret += test9_0 (&emptyBstring, NULL, 1, SHRT_MIN); - ret += test9_0 (NULL, &emptyBstring, 1, SHRT_MIN); - ret += test9_0 (&badBstring1, &badBstring1, 1, SHRT_MIN); - ret += test9_0 (&badBstring2, &badBstring2, 1, SHRT_MIN); - ret += test9_0 (&emptyBstring, &badBstring1, 1, SHRT_MIN); - ret += test9_0 (&emptyBstring, &badBstring2, 1, SHRT_MIN); - ret += test9_0 (&badBstring1, &emptyBstring, 1, SHRT_MIN); - ret += test9_0 (&badBstring2, &emptyBstring, 1, SHRT_MIN); - - /* normal operation tests on all sorts of subranges */ - ret += test9_0 (&emptyBstring, &emptyBstring, -1, 0); - ret += test9_0 (&emptyBstring, &emptyBstring, 0, 0); - ret += test9_0 (&emptyBstring, &emptyBstring, 1, 0); - ret += test9_0 (&shortBstring, &shortBstring, -1, 0); - ret += test9_0 (&shortBstring, &shortBstring, 0, 0); - ret += test9_0 (&shortBstring, &shortBstring, 1, 0); - ret += test9_0 (&shortBstring, &shortBstring, 9, 0); - printf ("\t# failures: %d\n", ret); - return ret; -} - -static int test10_0 (bstring b, int res, int nochange) { -struct tagbstring sb = bsStatic (""); -int rv, x, ret = 0; - - if (b) sb = *b; - printf (".\tbdestroy (%s) = ", dumpBstring (b)); - rv = bdestroy (b); - printf ("%d\n", rv); - - if (b != NULL) { - if (rv >= 0) - /* If the bdestroy was successful we have to assume - the contents were "changed" */ - x = 1; - else - x = memcmp (&sb, b, sizeof sb); - } else x = !nochange; - ret += (rv != res); - ret += (!nochange) == (!x); - if (ret) { - printf ("\t\tfailure(%d) res = %d nochange = %d, x = %d, sb.slen = %d, sb.mlen = %d, sb.data = %p\n", __LINE__, res, nochange, x, sb.slen, sb.mlen, sb.data); - } - return ret; -} - -static int test10 (void) { -bstring c = bstrcpy (&shortBstring); -bstring b = bstrcpy (&emptyBstring); -int ret = 0; - - printf ("TEST: int bdestroy (const_bstring b);\n"); - /* tests with NULL */ - ret += test10_0 (NULL, BSTR_ERR, 1); - - /* protected, constant and regular instantiations on empty or not */ - bwriteprotect (*b); - bwriteprotect (*c); - ret += test10_0 (b, BSTR_ERR, 1); - ret += test10_0 (c, BSTR_ERR, 1); - bwriteallow (*b); - bwriteallow (*c); - ret += test10_0 (b, BSTR_OK, 0); - ret += test10_0 (c, BSTR_OK, 0); - ret += test10_0 (&emptyBstring, BSTR_ERR, 1); - bwriteallow (emptyBstring); - ret += test10_0 (&emptyBstring, BSTR_ERR, 1); - ret += test10_0 (&shortBstring, BSTR_ERR, 1); - bwriteallow (emptyBstring); - ret += test10_0 (&shortBstring, BSTR_ERR, 1); - ret += test10_0 (&badBstring1, BSTR_ERR, 1); - ret += test10_0 (&badBstring2, BSTR_ERR, 1); - - printf ("\t# failures: %d\n", ret); - return ret; -} - -static int test11_0 (bstring s1, int pos, const_bstring s2, int res) { -int rv, ret = 0; - - printf (".\tbinstr (%s, %d, %s) = ", dumpBstring (s1), pos, dumpBstring (s2)); - rv = binstr (s1, pos, s2); - printf ("%d\n", rv); - ret += (rv != res); - if (ret) { - printf ("\t\tfailure(%d) res = %d\n", __LINE__, res); - } - return ret; -} - -static int test11_1 (bstring s1, int pos, const_bstring s2, int res) { -int rv, ret = 0; - - printf (".\tbinstrcaseless (%s, %d, %s) = ", dumpBstring (s1), pos, dumpBstring (s2)); - rv = binstrcaseless (s1, pos, s2); - printf ("%d\n", rv); - ret += (rv != res); - if (ret) { - printf ("\t\tfailure(%d) res = %d\n", __LINE__, res); - } - return ret; -} - -static int test11 (void) { -bstring b, c; -int ret = 0; - - printf ("TEST: int binstr (const_bstring s1, int pos, const_bstring s2);\n"); - ret += test11_0 (NULL, 0, NULL, BSTR_ERR); - ret += test11_0 (&emptyBstring, 0, NULL, BSTR_ERR); - ret += test11_0 (NULL, 0, &emptyBstring, BSTR_ERR); - ret += test11_0 (&emptyBstring, 0, &badBstring1, BSTR_ERR); - ret += test11_0 (&emptyBstring, 0, &badBstring2, BSTR_ERR); - ret += test11_0 (&badBstring1, 0, &emptyBstring, BSTR_ERR); - ret += test11_0 (&badBstring2, 0, &emptyBstring, BSTR_ERR); - ret += test11_0 (&badBstring1, 0, &badBstring2, BSTR_ERR); - ret += test11_0 (&badBstring2, 0, &badBstring1, BSTR_ERR); - - ret += test11_0 (&emptyBstring, 0, &emptyBstring, 0); - ret += test11_0 (&emptyBstring, 1, &emptyBstring, BSTR_ERR); - ret += test11_0 (&shortBstring, 1, &shortBstring, BSTR_ERR); - ret += test11_0 (&shortBstring, 5, &emptyBstring, 5); - ret += test11_0 (&shortBstring, -1, &shortBstring, BSTR_ERR); - ret += test11_0 (&shortBstring, 0, &shortBstring, 0); - ret += test11_0 (&shortBstring, 0, b = bstrcpy (&shortBstring), 0); - bdestroy (b); - ret += test11_0 (&shortBstring, 0, b = bfromcstr ("BOGUS"), BSTR_ERR); - bdestroy (b); - ret += test11_0 (&longBstring, 0, &shortBstring, 10); - ret += test11_0 (&longBstring, 20, &shortBstring, BSTR_ERR); - - ret += test11_0 (c = bfromcstr ("sssssssssap"), 0, b = bfromcstr ("sap"), 8); - bdestroy (c); - bdestroy (b); - ret += test11_0 (c = bfromcstr ("sssssssssap"), 3, b = bfromcstr ("sap"), 8); - bdestroy (c); - bdestroy (b); - ret += test11_0 (c = bfromcstr ("ssssssssssap"), 3, b = bfromcstr ("sap"), 9); - bdestroy (c); - bdestroy (b); - ret += test11_0 (c = bfromcstr ("sssssssssap"), 0, b = bfromcstr ("s"), 0); - bdestroy (c); - bdestroy (b); - ret += test11_0 (c = bfromcstr ("sssssssssap"), 3, b = bfromcstr ("s"), 3); - bdestroy (c); - bdestroy (b); - ret += test11_0 (c = bfromcstr ("sssssssssap"), 0, b = bfromcstr ("a"), 9); - bdestroy (c); - bdestroy (b); - ret += test11_0 (c = bfromcstr ("sssssssssap"), 5, b = bfromcstr ("a"), 9); - bdestroy (c); - bdestroy (b); - ret += test11_0 (c = bfromcstr ("sasasasasap"), 0, b = bfromcstr ("sap"), 8); - bdestroy (c); - bdestroy (b); - ret += test11_0 (c = bfromcstr ("ssasasasasap"), 0, b = bfromcstr ("sap"), 9); - bdestroy (c); - bdestroy (b); - - printf ("TEST: int binstrcaseless (const_bstring s1, int pos, const_bstring s2);\n"); - ret += test11_1 (NULL, 0, NULL, BSTR_ERR); - ret += test11_1 (&emptyBstring, 0, NULL, BSTR_ERR); - ret += test11_1 (NULL, 0, &emptyBstring, BSTR_ERR); - ret += test11_1 (&emptyBstring, 0, &badBstring1, BSTR_ERR); - ret += test11_1 (&emptyBstring, 0, &badBstring2, BSTR_ERR); - ret += test11_1 (&badBstring1, 0, &emptyBstring, BSTR_ERR); - ret += test11_1 (&badBstring2, 0, &emptyBstring, BSTR_ERR); - ret += test11_1 (&badBstring1, 0, &badBstring2, BSTR_ERR); - ret += test11_1 (&badBstring2, 0, &badBstring1, BSTR_ERR); - - ret += test11_1 (&emptyBstring, 0, &emptyBstring, 0); - ret += test11_1 (&emptyBstring, 1, &emptyBstring, BSTR_ERR); - ret += test11_1 (&shortBstring, 1, &shortBstring, BSTR_ERR); - ret += test11_1 (&shortBstring, 5, &emptyBstring, 5); - ret += test11_1 (&shortBstring, -1, &shortBstring, BSTR_ERR); - ret += test11_1 (&shortBstring, 0, &shortBstring, 0); - ret += test11_1 (&shortBstring, 0, b = bstrcpy (&shortBstring), 0); - bdestroy (b); - ret += test11_1 (&shortBstring, 0, b = bfromcstr ("BOGUS"), 0); - bdestroy (b); - ret += test11_1 (&longBstring, 0, &shortBstring, 10); - ret += test11_1 (&longBstring, 20, &shortBstring, BSTR_ERR); - - printf ("\t# failures: %d\n", ret); - return ret; -} - -static int test12_0 (bstring s1, int pos, const_bstring s2, int res) { -int rv, ret = 0; - - printf (".\tbinstrr (%s, %d, %s) = ", dumpBstring (s1), pos, dumpBstring (s2)); - rv = binstrr (s1, pos, s2); - printf ("%d\n", rv); - ret += (rv != res); - if (ret) { - printf ("\t\tfailure(%d) res = %d\n", __LINE__, res); - } - return ret; -} - -static int test12_1 (bstring s1, int pos, const_bstring s2, int res) { -int rv, ret = 0; - - printf (".\tbinstrrcaseless (%s, %d, %s) = ", dumpBstring (s1), pos, dumpBstring (s2)); - rv = binstrrcaseless (s1, pos, s2); - printf ("%d\n", rv); - ret += (rv != res); - if (ret) { - printf ("\t\tfailure(%d) res = %d\n", __LINE__, res); - } - return ret; -} - -static int test12 (void) { -bstring b; -int ret = 0; - - printf ("TEST: int binstrr (const_bstring s1, int pos, const_bstring s2);\n"); - ret += test12_0 (NULL, 0, NULL, BSTR_ERR); - ret += test12_0 (&emptyBstring, 0, NULL, BSTR_ERR); - ret += test12_0 (NULL, 0, &emptyBstring, BSTR_ERR); - ret += test12_0 (&emptyBstring, 0, &badBstring1, BSTR_ERR); - ret += test12_0 (&emptyBstring, 0, &badBstring2, BSTR_ERR); - ret += test12_0 (&badBstring1, 0, &emptyBstring, BSTR_ERR); - ret += test12_0 (&badBstring2, 0, &emptyBstring, BSTR_ERR); - ret += test12_0 (&badBstring1, 0, &badBstring2, BSTR_ERR); - ret += test12_0 (&badBstring2, 0, &badBstring1, BSTR_ERR); - - ret += test12_0 (&emptyBstring, 0, &emptyBstring, 0); - ret += test12_0 (&emptyBstring, 1, &emptyBstring, BSTR_ERR); - ret += test12_0 (&shortBstring, 1, &shortBstring, 0); - ret += test12_0 (&shortBstring, 5, &emptyBstring, 5); - ret += test12_0 (&shortBstring, -1, &shortBstring, BSTR_ERR); - ret += test12_0 (&shortBstring, 0, &shortBstring, 0); - ret += test12_0 (&shortBstring, 0, b = bstrcpy (&shortBstring), 0); - bdestroy (b); - ret += test12_0 (&shortBstring, 0, b = bfromcstr ("BOGUS"), BSTR_ERR); - bdestroy (b); - ret += test12_0 (&longBstring, 0, &shortBstring, BSTR_ERR); - ret += test12_0 (&longBstring, 20, &shortBstring, 10); - - printf ("TEST: int binstrrcaseless (const_bstring s1, int pos, const_bstring s2);\n"); - ret += test12_1 (NULL, 0, NULL, BSTR_ERR); - ret += test12_1 (&emptyBstring, 0, NULL, BSTR_ERR); - ret += test12_1 (NULL, 0, &emptyBstring, BSTR_ERR); - ret += test12_1 (&emptyBstring, 0, &badBstring1, BSTR_ERR); - ret += test12_1 (&emptyBstring, 0, &badBstring2, BSTR_ERR); - ret += test12_1 (&badBstring1, 0, &emptyBstring, BSTR_ERR); - ret += test12_1 (&badBstring2, 0, &emptyBstring, BSTR_ERR); - ret += test12_1 (&badBstring1, 0, &badBstring2, BSTR_ERR); - ret += test12_1 (&badBstring2, 0, &badBstring1, BSTR_ERR); - - ret += test12_1 (&emptyBstring, 0, &emptyBstring, 0); - ret += test12_1 (&emptyBstring, 1, &emptyBstring, BSTR_ERR); - ret += test12_1 (&shortBstring, 1, &shortBstring, 0); - ret += test12_1 (&shortBstring, 5, &emptyBstring, 5); - ret += test12_1 (&shortBstring, -1, &shortBstring, BSTR_ERR); - ret += test12_1 (&shortBstring, 0, &shortBstring, 0); - ret += test12_1 (&shortBstring, 0, b = bstrcpy (&shortBstring), 0); - bdestroy (b); - ret += test12_1 (&shortBstring, 0, b = bfromcstr ("BOGUS"), 0); - bdestroy (b); - ret += test12_1 (&longBstring, 0, &shortBstring, BSTR_ERR); - ret += test12_1 (&longBstring, 20, &shortBstring, 10); - - printf ("\t# failures: %d\n", ret); - return ret; -} - -static int test13_0 (bstring s1, int pos, const_bstring s2, int res) { -int rv, ret = 0; - - printf (".\tbinchr (%s, %d, %s) = ", dumpBstring (s1), pos, dumpBstring (s2)); - rv = binchr (s1, pos, s2); - printf ("%d\n", rv); - ret += (rv != res); - if (ret) { - printf ("\t\tfailure(%d) res = %d\n", __LINE__, res); - } - return ret; -} - -static int test13 (void) { -bstring b; -int ret = 0; -struct tagbstring multipleOs = bsStatic ("ooooo"); - - printf ("TEST: int binchr (const_bstring s1, int pos, const_bstring s2);\n"); - ret += test13_0 (NULL, 0, NULL, BSTR_ERR); - ret += test13_0 (&emptyBstring, 0, NULL, BSTR_ERR); - ret += test13_0 (NULL, 0, &emptyBstring, BSTR_ERR); - ret += test13_0 (&emptyBstring, 0, &badBstring1, BSTR_ERR); - ret += test13_0 (&emptyBstring, 0, &badBstring2, BSTR_ERR); - ret += test13_0 (&badBstring1, 0, &emptyBstring, BSTR_ERR); - ret += test13_0 (&badBstring2, 0, &emptyBstring, BSTR_ERR); - ret += test13_0 (&badBstring2, 0, &badBstring1, BSTR_ERR); - ret += test13_0 (&badBstring1, 0, &badBstring2, BSTR_ERR); - - ret += test13_0 (&emptyBstring, 0, &emptyBstring, BSTR_ERR); - ret += test13_0 (&shortBstring, 0, &emptyBstring, BSTR_ERR); - ret += test13_0 (&shortBstring, 0, &shortBstring, 0); - ret += test13_0 (&shortBstring, 0, &multipleOs, 1); - ret += test13_0 (&shortBstring, 0, b = bstrcpy (&shortBstring), 0); - bdestroy (b); - ret += test13_0 (&shortBstring, -1, &shortBstring, BSTR_ERR); - ret += test13_0 (&shortBstring, 10, &shortBstring, BSTR_ERR); - ret += test13_0 (&shortBstring, 1, &shortBstring, 1); - ret += test13_0 (&emptyBstring, 0, &shortBstring, BSTR_ERR); - ret += test13_0 (&xxxxxBstring, 0, &shortBstring, BSTR_ERR); - ret += test13_0 (&longBstring, 0, &shortBstring, 3); - ret += test13_0 (&longBstring, 10, &shortBstring, 10); - printf ("\t# failures: %d\n", ret); - return ret; -} - -static int test14_0 (bstring s1, int pos, const_bstring s2, int res) { -int rv, ret = 0; - - printf (".\tbinchrr (%s, %d, %s) = ", dumpBstring (s1), pos, dumpBstring (s2)); - rv = binchrr (s1, pos, s2); - printf ("%d\n", rv); - ret += (rv != res); - if (ret) { - printf ("\t\tfailure(%d) res = %d\n", __LINE__, res); - } - return ret; -} - -static int test14 (void) { -bstring b; -int ret = 0; - - printf ("TEST: int binchrr (const_bstring s1, int pos, const_bstring s2);\n"); - ret += test14_0 (NULL, 0, NULL, BSTR_ERR); - ret += test14_0 (&emptyBstring, 0, NULL, BSTR_ERR); - ret += test14_0 (NULL, 0, &emptyBstring, BSTR_ERR); - ret += test14_0 (&emptyBstring, 0, &emptyBstring, BSTR_ERR); - ret += test14_0 (&shortBstring, 0, &emptyBstring, BSTR_ERR); - ret += test14_0 (&emptyBstring, 0, &badBstring1, BSTR_ERR); - ret += test14_0 (&emptyBstring, 0, &badBstring2, BSTR_ERR); - ret += test14_0 (&badBstring1, 0, &emptyBstring, BSTR_ERR); - ret += test14_0 (&badBstring2, 0, &emptyBstring, BSTR_ERR); - ret += test14_0 (&badBstring2, 0, &badBstring1, BSTR_ERR); - ret += test14_0 (&badBstring1, 0, &badBstring2, BSTR_ERR); - - ret += test14_0 (&shortBstring, 0, &shortBstring, 0); - ret += test14_0 (&shortBstring, 0, b = bstrcpy (&shortBstring), 0); - bdestroy (b); - ret += test14_0 (&shortBstring, -1, &shortBstring, BSTR_ERR); - ret += test14_0 (&shortBstring, 5, &shortBstring, 4); - ret += test14_0 (&shortBstring, 4, &shortBstring, 4); - ret += test14_0 (&shortBstring, 1, &shortBstring, 1); - ret += test14_0 (&emptyBstring, 0, &shortBstring, BSTR_ERR); - ret += test14_0 (&xxxxxBstring, 4, &shortBstring, BSTR_ERR); - ret += test14_0 (&longBstring, 0, &shortBstring, BSTR_ERR); - ret += test14_0 (&longBstring, 10, &shortBstring, 10); - printf ("\t# failures: %d\n", ret); - return ret; -} - -static int test15_0 (bstring b0, int pos, const_bstring b1, unsigned char fill, char * res) { -bstring b2; -int rv, ret = 0, linenum = 0; - - if (b0 != NULL && b0->data != NULL && b0->slen >= 0 && - b1 != NULL && b1->data != NULL && b1->slen >= 0) { - b2 = bstrcpy (b0); - bwriteprotect (*b2); - - printf (".\tbsetstr (%s, ", dumpBstring (b2)); - - rv = bsetstr (b2, pos, b1, fill); - ret += (rv == 0); if (ret && 0 == linenum) linenum = __LINE__; - if (!biseq (b0, b2)) ret++; if (ret && 0 == linenum) linenum = __LINE__; - - printf ("%d, %s, %02X) = %s\n", pos, dumpBstring (b1), fill, dumpBstring (b2)); - - bwriteallow (*b2); - - printf (".\tbsetstr (%s, ", dumpBstring (b2)); - - rv = bsetstr (b2, pos, b1, fill); - if (b1) { - ret += (pos >= 0) && (b2->slen != b0->slen + b1->slen) && (b2->slen != pos + b1->slen); if (ret && 0 == linenum) linenum = __LINE__; - ret += (pos < 0) && (b2->slen != b0->slen); if (ret && 0 == linenum) linenum = __LINE__; - } - - ret += ((rv == 0) != (pos >= 0)); if (ret && 0 == linenum) linenum = __LINE__; - ret += (res == NULL); if (ret && 0 == linenum) linenum = __LINE__; - ret += ((int) strlen (res) > b2->slen); if (ret && 0 == linenum) linenum = __LINE__; - ret += (0 != memcmp (b2->data, res, b2->slen)); if (ret && 0 == linenum) linenum = __LINE__; - ret += b2->data[b2->slen] != '\0'; if (ret && 0 == linenum) linenum = __LINE__; - - printf ("%d, %s, %02X) = %s\n", pos, dumpBstring (b1), fill, dumpBstring (b2)); - - bdestroy (b2); - } else { - ret += (BSTR_ERR != (rv = bsetstr (b0, pos, b1, fill))); if (ret && 0 == linenum) linenum = __LINE__; - printf (".\tbsetstr (%s, %d, %s, %02X) = %d\n", dumpBstring (b0), pos, dumpBstring (b1), fill, rv); - } - - if (ret) { - printf ("\t\tfailure(%d) = %d (res = %p", linenum, ret, res); - if (res) printf (" = \"%s\"", res); - printf (")\n"); - } - return ret; -} - -static int test15 (void) { -int ret = 0; - printf ("TEST: int bsetstr (bstring b0, int pos, const_bstring b1, unsigned char fill);\n"); - /* tests with NULL */ - ret += test15_0 (NULL, 0, NULL, (unsigned char) '?', NULL); - ret += test15_0 (NULL, 0, &emptyBstring, (unsigned char) '?', NULL); - ret += test15_0 (&badBstring1, 0, NULL, (unsigned char) '?', NULL); - ret += test15_0 (&badBstring1, 0, &badBstring1, (unsigned char) '?', NULL); - ret += test15_0 (&emptyBstring, 0, &badBstring1, (unsigned char) '?', NULL); - ret += test15_0 (&badBstring1, 0, &emptyBstring, (unsigned char) '?', NULL); - ret += test15_0 (&badBstring2, 0, NULL, (unsigned char) '?', NULL); - ret += test15_0 (&badBstring2, 0, &badBstring2, (unsigned char) '?', NULL); - ret += test15_0 (&emptyBstring, 0, &badBstring2, (unsigned char) '?', NULL); - ret += test15_0 (&badBstring2, 0, &emptyBstring, (unsigned char) '?', NULL); - - /* normal operation tests */ - ret += test15_0 (&emptyBstring, 0, &emptyBstring, (unsigned char) '?', ""); - ret += test15_0 (&emptyBstring, 5, &emptyBstring, (unsigned char) '?', "?????"); - ret += test15_0 (&emptyBstring, 5, &shortBstring, (unsigned char) '?', "?????bogus"); - ret += test15_0 (&shortBstring, 0, &emptyBstring, (unsigned char) '?', "bogus"); - ret += test15_0 (&emptyBstring, 0, &shortBstring, (unsigned char) '?', "bogus"); - ret += test15_0 (&shortBstring, 0, &shortBstring, (unsigned char) '?', "bogus"); - ret += test15_0 (&shortBstring, -1, &shortBstring, (unsigned char) '?', "bogus"); - ret += test15_0 (&shortBstring, 2, &shortBstring, (unsigned char) '?', "bobogus"); - ret += test15_0 (&shortBstring, 6, &shortBstring, (unsigned char) '?', "bogus?bogus"); - ret += test15_0 (&shortBstring, 6, NULL, (unsigned char) '?', "bogus?"); - printf ("\t# failures: %d\n", ret); - return ret; -} - -static int test16_0 (bstring b0, int pos, const_bstring b1, unsigned char fill, char * res) { -bstring b2; -int rv, ret = 0; - - if (b0 != NULL && b0->data != NULL && b0->slen >= 0 && - b1 != NULL && b1->data != NULL && b1->slen >= 0) { - b2 = bstrcpy (b0); - bwriteprotect (*b2); - - printf (".\tbinsert (%s, ", dumpBstring (b2)); - - rv = binsert (b2, pos, b1, fill); - ret += (rv == 0); - if (!biseq (b0, b2)) ret++; - - printf ("%d, %s, %02X) = %s\n", pos, dumpBstring (b1), fill, dumpBstring (b2)); - - bwriteallow (*b2); - - printf (".\tbinsert (%s, ", dumpBstring (b2)); - - rv = binsert (b2, pos, b1, fill); - if (b1) { - ret += (pos >= 0) && (b2->slen != b0->slen + b1->slen) && (b2->slen != pos + b1->slen); - ret += (pos < 0) && (b2->slen != b0->slen); - ret += ((rv == 0) != (pos >= 0 && pos <= b2->slen)); - } - - ret += (res == NULL) || ((int) strlen (res) > b2->slen) - || (0 != memcmp (b2->data, res, b2->slen)); - ret += b2->data[b2->slen] != '\0'; - - printf ("%d, %s, %02X) = %s\n", pos, dumpBstring (b1), fill, dumpBstring (b2)); - - bdestroy (b2); - } else { - ret += (BSTR_ERR != (rv = binsert (b0, pos, b1, fill))); - printf (".\tbinsert (%s, %d, %s, %02X) = %d\n", dumpBstring (b0), pos, dumpBstring (b1), fill, rv); - } - - if (ret) { - printf ("\t\tfailure(%d) = %d (res = %p", __LINE__, ret, res); - if (res) printf (" = \"%s\"", res); - printf (")\n"); - } - return ret; -} - -static int test16_1 (void) { -bstring b0 = bfromStatic ("aaaaabbbbb"); -struct tagbstring b1; -int res, ret = 0; - - bmid2tbstr (b1, b0, 4, 4); - b0->slen = 6; - - printf (".\tbinsert (%s, 2, %s, '?') = ", dumpBstring (b0), dumpBstring (&b1)); - res = binsert (b0, 2, &b1, '?'); - printf ("%s (Alias test)\n", dumpBstring (b0)); - - ret += (res != 0); - ret += !biseqStatic(b0, "aaabbbaaab"); - - return ret; -} - -static int test16 (void) { -int ret = 0; - printf ("TEST: int binsert (bstring b0, int pos, const_bstring b1, unsigned char fill);\n"); - /* tests with NULL */ - ret += test16_0 (NULL, 0, NULL, (unsigned char) '?', NULL); - ret += test16_0 (NULL, 0, &emptyBstring, (unsigned char) '?', NULL); - ret += test16_0 (&badBstring1, 0, NULL, (unsigned char) '?', NULL); - ret += test16_0 (&badBstring1, 0, &badBstring1, (unsigned char) '?', NULL); - ret += test16_0 (&emptyBstring, 0, &badBstring1, (unsigned char) '?', NULL); - ret += test16_0 (&badBstring1, 0, &emptyBstring, (unsigned char) '?', NULL); - ret += test16_0 (&badBstring2, 0, NULL, (unsigned char) '?', NULL); - ret += test16_0 (&badBstring2, 0, &badBstring2, (unsigned char) '?', NULL); - ret += test16_0 (&emptyBstring, 0, &badBstring2, (unsigned char) '?', NULL); - ret += test16_0 (&badBstring2, 0, &emptyBstring, (unsigned char) '?', NULL); - - /* normal operation tests */ - ret += test16_0 (&emptyBstring, 0, &emptyBstring, (unsigned char) '?', ""); - ret += test16_0 (&emptyBstring, 5, &emptyBstring, (unsigned char) '?', "?????"); - ret += test16_0 (&emptyBstring, 5, &shortBstring, (unsigned char) '?', "?????bogus"); - ret += test16_0 (&shortBstring, 0, &emptyBstring, (unsigned char) '?', "bogus"); - ret += test16_0 (&emptyBstring, 0, &shortBstring, (unsigned char) '?', "bogus"); - ret += test16_0 (&shortBstring, 0, &shortBstring, (unsigned char) '?', "bogusbogus"); - ret += test16_0 (&shortBstring, -1, &shortBstring, (unsigned char) '?', "bogus"); - ret += test16_0 (&shortBstring, 2, &shortBstring, (unsigned char) '?', "bobogusgus"); - ret += test16_0 (&shortBstring, 6, &shortBstring, (unsigned char) '?', "bogus?bogus"); - ret += test16_0 (&shortBstring, 6, NULL, (unsigned char) '?', "bogus"); - - /* Alias testing */ - ret += test16_1 (); - - printf ("\t# failures: %d\n", ret); - return ret; -} - -static int test17_0 (bstring s1, int pos, int len, char * res) { -bstring b2; -int rv, ret = 0; - - if (s1 != NULL && s1->data != NULL && s1->slen >= 0) { - b2 = bstrcpy (s1); - bwriteprotect (*b2); - - printf (".\tbdelete (%s, ", dumpBstring (b2)); - - rv = bdelete (b2, pos, len); - ret += (rv == 0); - if (!biseq (s1, b2)) ret++; - - printf ("%d, %d) = %s\n", pos, len, dumpBstring (b2)); - - bwriteallow (*b2); - - printf (".\tbdelete (%s, ", dumpBstring (b2)); - - rv = bdelete (b2, pos, len); - ret += (len >= 0) != (rv == 0); - ret += (b2->slen > s1->slen) || (b2->slen < pos && s1->slen >= pos); - - ret += (res == NULL) || ((int) strlen (res) > b2->slen) - || (0 != memcmp (b2->data, res, b2->slen)); - ret += b2->data[b2->slen] != '\0'; - - printf ("%d, %d) = %s\n", pos, len, dumpBstring (b2)); - - bdestroy (b2); - } else { - ret += (BSTR_ERR != (rv = bdelete (s1, pos, len))); - printf (".\tbdelete (%s, %d, %d) = %d\n", dumpBstring (s1), pos, len, rv); - } - - if (ret) { - printf ("\t\tfailure(%d) = %d (res = %p", __LINE__, ret, res); - if (res) printf (" = \"%s\"", res); - printf (")\n"); - } - return ret; -} - -static int test17 (void) { -int ret = 0; - printf ("TEST: int bdelete (bstring s1, int pos, int len);\n"); - /* tests with NULL */ - ret += test17_0 (NULL, 0, 0, NULL); - ret += test17_0 (&badBstring1, 0, 0, NULL); - ret += test17_0 (&badBstring2, 0, 0, NULL); - - /* normal operation tests */ - ret += test17_0 (&emptyBstring, 0, 0, ""); - ret += test17_0 (&shortBstring, 1, 3, "bs"); - ret += test17_0 (&shortBstring, -1, 3, "gus"); - ret += test17_0 (&shortBstring, 1, -3, "bogus"); - ret += test17_0 (&shortBstring, 3, 9, "bog"); - ret += test17_0 (&shortBstring, 3, 1, "bogs"); - ret += test17_0 (&longBstring, 4, 300, "This"); - - printf ("\t# failures: %d\n", ret); - return ret; -} - -static int test18_0 (bstring b, int len, int res, int mlen) { -int ret = 0; -int rv; -int ol = 0; - - printf (".\tballoc (%s, %d) = ", dumpBstring (b), len); - if (b) ol = b->mlen; - rv = balloc (b, len); - printf ("%d\n", rv); - - if (b != NULL && b->data != NULL && b->slen >=0 && ol > b->mlen) { - printf ("\t\tfailure(%d) oldmlen = %d, newmlen %d\n", __LINE__, ol, b->mlen); - ret++; - } - - if (rv != res) { - printf ("\t\tfailure(%d) res = %d\n", __LINE__, res); - ret++; - } - if (b != NULL && (mlen > b->mlen || b->mlen == 0)) { - printf ("\t\tfailure(%d) b->mlen = %d mlen = %d\n", __LINE__, b->mlen, mlen); - ret++; - } - return ret; -} - -static int test18_1_int (bstring b, int len, int res, int mlen, int __line__) { -int ret = 0; -int rv; -int ol = 0; - - printf (".\tballocmin (%s, %d) = ", dumpBstring (b), len); - if (b) ol = b->mlen; - - rv = ballocmin (b, len); - printf ("[%d] %d\n", __LINE__, rv); - - if (b != NULL && b->data != NULL && b->mlen != mlen) { - printf ("\t\t[%d] failure(%d) oldmlen = %d, newmlen = %d, mlen = %d len = %d\n", __line__, __LINE__, ol, b->mlen, mlen, b->slen); - ret++; - } - - if (rv != res) { - printf ("\t\t[%d] failure(%d) res = %d\n", __line__, __LINE__, res); - ret++; - } - - return ret; -} - -#define test18_1(b, len, res, mlen) test18_1_int (b, len, res, mlen, __LINE__) - -static int test18 (void) { -int ret = 0, reto; -bstring b = bfromcstr ("test"); - - printf ("TEST: int balloc (bstring s, int len);\n"); - /* tests with NULL */ - ret += test18_0 (NULL, 2, BSTR_ERR, 0); - ret += test18_0 (&badBstring1, 2, BSTR_ERR, 0); - ret += test18_0 (&badBstring2, 2, BSTR_ERR, 0); - - /* normal operation tests */ - ret += test18_0 (b, 2, 0, b->mlen); - ret += test18_0 (b, -1, BSTR_ERR, b->mlen); - ret += test18_0 (b, 9, 0, 9); - ret += test18_0 (b, 2, 0, 9); - bwriteprotect (*b); - ret += test18_0 (b, 4, BSTR_ERR, b->mlen); - bwriteallow (*b); - ret += test18_0 (b, 2, 0, b->mlen); - ret += test18_0 (&emptyBstring, 9, BSTR_ERR, emptyBstring.mlen); - - bdestroy (b); - printf ("\t# failures: %d\n", ret); - - reto = ret; - ret = 0; - - b = bfromcstr ("test"); - - printf ("TEST: int ballocmin (bstring s, int len);\n"); - /* tests with NULL */ - ret += test18_1 (NULL, 2, BSTR_ERR, 0); - ret += test18_1 (&badBstring1, 2, BSTR_ERR, 0); - ret += test18_1 (&badBstring2, 2, BSTR_ERR, 2); - - /* normal operation tests */ - ret += test18_1 (b, 2, 0, b->slen + 1); - ret += test18_1 (b, -1, BSTR_ERR, b->mlen); - ret += test18_1 (b, 9, 0, 9); - ret += test18_1 (b, 2, 0, b->slen + 1); - ret += test18_1 (b, 9, 0, 9); - bwriteprotect (*b); - ret += test18_1 (b, 4, BSTR_ERR, -1); - bwriteallow (*b); - ret += test18_1 (b, 2, 0, b->slen + 1); - ret += test18_1 (&emptyBstring, 9, BSTR_ERR, emptyBstring.mlen); - - bdestroy (b); - printf ("\t# failures: %d\n", ret); - - return reto + ret; -} - -static int test19_0 (bstring b, int len, const char * res, int erv) { -int rv, ret = 0; -bstring b1; - - if (b != NULL && b->data != NULL && b->slen >= 0) { - b1 = bstrcpy (b); - bwriteprotect (*b1); - ret += bpattern (b1, len) != BSTR_ERR; - ret += !biseq (b1, b); - bwriteallow (*b1); - - printf (".\tbpattern (%s, %d) = ", dumpBstring (b1), len); - - rv = bpattern (b1, len); - - printf ("%s\n", dumpBstring (b1)); - - ret += (rv != erv); - ret += (res == NULL) || ((int) strlen (res) > b1->slen) - || (0 != memcmp (b1->data, res, b1->slen)); - ret += b1->data[b1->slen] != '\0'; - } else { - ret += BSTR_ERR != (rv = bpattern (b, len)); - printf (".\tbpattern (%s, %d) = %d\n", dumpBstring (b), len, rv); - } - - if (ret) { - printf ("\t\tfailure(%d) rv = %d erv = %d (res = %p", __LINE__, rv, erv, res); - if (res) printf (" = \"%s\"", res); - printf (")\n"); - } - return ret; -} - -static int test19 (void) { -int ret = 0; - - printf ("TEST: int bpattern (bstring b, int len);\n"); - /* tests with NULL */ - ret += test19_0 (NULL, 0, NULL, BSTR_ERR); - ret += test19_0 (NULL, 5, NULL, BSTR_ERR); - ret += test19_0 (NULL, -5, NULL, BSTR_ERR); - ret += test19_0 (&badBstring1, 5, NULL, BSTR_ERR); - ret += test19_0 (&badBstring2, 5, NULL, BSTR_ERR); - - /* normal operation tests */ - ret += test19_0 (&emptyBstring, 0, "", BSTR_ERR); - ret += test19_0 (&emptyBstring, 10, "", BSTR_ERR); - ret += test19_0 (&emptyBstring, -1, "", BSTR_ERR); - ret += test19_0 (&shortBstring, 0, "", 0); - ret += test19_0 (&shortBstring, 12, "bogusbogusbo", 0); - ret += test19_0 (&shortBstring, -1, "bogus", BSTR_ERR); - - printf ("\t# failures: %d\n", ret); - return ret; -} - -static int test20 (void) { -int ret = 0; - -#if !defined (BSTRLIB_NOVSNP) -int rv; -bstring b, c; - - printf ("TEST: bstring bformat (const char * fmt, ...);\n"); - /* tests with NULL */ - printf (".\tbformat (NULL, 1, 2) = "); - b = bformat (NULL, 1, 2); - printf ("%s\n", dumpBstring (b)); - ret += b != NULL; - - /* normal operation tests */ - printf (".\tbformat (\"%%d %%s\", 1, \"xy\") = "); - b = bformat ("%d %s", 1, "xy"); - printf ("%s\n", dumpBstring (b)); - ret += !biseq (c = bfromcstr ("1 xy"), b); - bdestroy (b); - - printf (".\tbformat (\"%%d %%s(%%s)\", 6, %s, %s) = ", dumpBstring (c), dumpBstring (&shortBstring)); - b = bformat ("%d %s(%s)", 6, c->data, shortBstring.data); - printf ("%s\n", dumpBstring (b)); - bdestroy (c); - ret += !biseq (c = bfromcstr ("6 1 xy(bogus)"), b); - bdestroy (c); - bdestroy (b); - - printf (".\tbformat (\"%%s%%s%%s%%s%%s%%s%%s%%s\", ...) ...\n"); - b = bformat ("%s%s%s%s%s%s%s%s", longBstring.data, longBstring.data - , longBstring.data, longBstring.data - , longBstring.data, longBstring.data - , longBstring.data, longBstring.data); - c = bstrcpy (&longBstring); - bconcat (c, c); - bconcat (c, c); - bconcat (c, c); - ret += !biseq (c, b); - bdestroy (c); - bdestroy (b); - - printf ("\t# failures: %d\n", ret); - - b = bfromcstr (""); - printf ("TEST: int bformata (bstring b, const char * fmt, ...);\n"); - /* tests with NULL */ - printf (".\tbformata (%s, NULL, 1, 2) = ", dumpBstring (b)); - rv = bformata (b, NULL, 1, 2); - printf ("%d\n", rv); - ret += rv != BSTR_ERR; - printf (".\tbformata (%s, \"%%d %%d\", 1, 2) = ", dumpBstring (&badBstring1)); - rv = bformata (&badBstring1, "%d %d", 1, 2); - printf ("%d\n", rv); - ret += rv != BSTR_ERR; - printf (".\tbformata (%s, \"%%d %%d\", 1, 2) = ", dumpBstring (b)); - rv = bformata (b, "%d %d", 1, 2); - printf ("%s\n", dumpBstring (b)); - ret += !biseq (c = bfromcstr ("1 2"), b); - bdestroy (c); - bdestroy (b); - - printf (".\tbformata (\"x\", \"%%s%%s%%s%%s%%s%%s%%s%%s\", ...) ...\n"); - rv = bformata (b = bfromcstr ("x"), "%s%s%s%s%s%s%s%s", - longBstring.data, longBstring.data, - longBstring.data, longBstring.data, - longBstring.data, longBstring.data, - longBstring.data, longBstring.data); - ret += rv == BSTR_ERR; - c = bstrcpy (&longBstring); - bconcat (c, c); - bconcat (c, c); - bconcat (c, c); - binsertch (c, 0, 1, (char) 'x'); - ret += !biseq (c, b); - bdestroy (c); - bdestroy (b); - - printf ("\t# failures: %d\n", ret); - - b = bfromcstr ("Initial"); - printf ("TEST: int bassignformat (bstring b, const char * fmt, ...);\n"); - /* tests with NULL */ - printf (".\tbassignformat (%s, NULL, 1, 2) = ", dumpBstring (b)); - rv = bassignformat (b, NULL, 1, 2); - printf ("%d\n", rv); - ret += rv != BSTR_ERR; - printf (".\tbassignformat (%s, \"%%d %%d\", 1, 2) = ", dumpBstring (&badBstring1)); - rv = bassignformat (&badBstring1, "%d %d", 1, 2); - printf ("%d\n", rv); - ret += rv != BSTR_ERR; - printf (".\tbassignformat (%s, \"%%d %%d\", 1, 2) = ", dumpBstring (b)); - rv = bassignformat (b, "%d %d", 1, 2); - printf ("%s\n", dumpBstring (b)); - ret += !biseq (c = bfromcstr ("1 2"), b); - bdestroy (c); - bdestroy (b); - - printf (".\tbassignformat (\"x\", \"%%s%%s%%s%%s%%s%%s%%s%%s\", ...) ...\n"); - rv = bassignformat (b = bfromcstr ("x"), "%s%s%s%s%s%s%s%s", - longBstring.data, longBstring.data, - longBstring.data, longBstring.data, - longBstring.data, longBstring.data, - longBstring.data, longBstring.data); - ret += rv == BSTR_ERR; - c = bstrcpy (&longBstring); - bconcat (c, c); - bconcat (c, c); - bconcat (c, c); - ret += !biseq (c, b); - bdestroy (c); - bdestroy (b); - - printf ("\t# failures: %d\n", ret); -#endif - - return ret; -} - -static int test21_0 (bstring b, char sc, int ns) { -struct bstrList * l; -int ret = 0; - - printf (".\tbsplit (%s, '%c') = ", dumpBstring (b), sc); - - if (b != NULL && b->data != NULL && b->slen >= 0) { - bstring c; - struct tagbstring t; - - blk2tbstr(t,&sc,1); - - printf ("{"); - - l = bsplit (b, sc); - - if (l) { - int i; - for (i=0; i < l->qty; i++) { - if (i != 0) printf (", "); - printf ("%s", dumpBstring (l->entry[i])); - } - printf (":<%d>", l->qty); - if (ns != l->qty) ret++; - } else { - printf ("NULL"); - ret ++; - } - - printf ("}\n"); - - c = bjoin (l, &t); - ret += !biseq (c, b); - ret += incorrectBstring (c); - bdestroy (c); - ret += 0 != bstrListDestroy (l); - } else { - l = bsplit (b, sc); - ret += (l != NULL); - printf ("%p\n", (void *) l); - } - - if (ret) { - printf ("\t\tfailure(%d) ns = %d\n", __LINE__, ns); - } - - return ret; -} - -static int test21_1 (bstring b, const_bstring sc, int ns) { -struct bstrList * l; -int ret = 0; - - printf (".\tbsplitstr (%s, %s) = ", dumpBstring (b), dumpBstring (sc)); - - if (b != NULL && b->data != NULL && b->slen >= 0) { - bstring c; - - printf ("{"); - - l = bsplitstr (b, sc); - - if (l) { - int i; - for (i=0; i < l->qty; i++) { - if (i != 0) printf (", "); - printf ("%s", dumpBstring (l->entry[i])); - } - printf (":<%d>", l->qty); - if (ns != l->qty) ret++; - } else { - printf ("NULL"); - ret ++; - } - - printf ("}\n"); - - c = bjoin (l, sc); - ret += !biseq (c, b); - ret += incorrectBstring (c); - bdestroy (c); - ret += 0 != bstrListDestroy (l); - } else { - l = bsplitstr (b, sc); - ret += (l != NULL); - printf ("%p\n", (void *) l); - } - - if (ret) { - printf ("\t\tfailure(%d) ns = %d\n", __LINE__, ns); - } - - return ret; -} - -static int test21 (void) { -struct tagbstring is = bsStatic ("is"); -struct tagbstring ng = bsStatic ("ng"); -struct tagbstring commas = bsStatic (",,,,"); -int ret = 0; - - printf ("TEST: struct bstrList * bsplit (const_bstring str, unsigned char splitChar);\n"); - /* tests with NULL */ - ret += test21_0 (NULL, (char) '?', 0); - ret += test21_0 (&badBstring1, (char) '?', 0); - ret += test21_0 (&badBstring2, (char) '?', 0); - - /* normal operation tests */ - ret += test21_0 (&emptyBstring, (char) '?', 1); - ret += test21_0 (&shortBstring, (char) 'o', 2); - ret += test21_0 (&shortBstring, (char) 's', 2); - ret += test21_0 (&shortBstring, (char) 'b', 2); - ret += test21_0 (&longBstring, (char) 'o', 9); - ret += test21_0 (&commas, (char) ',', 5); - - printf ("TEST: struct bstrList * bsplitstr (bstring str, const_bstring splitStr);\n"); - - ret += test21_1 (NULL, NULL, 0); - ret += test21_1 (&badBstring1, &emptyBstring, 0); - ret += test21_1 (&badBstring2, &emptyBstring, 0); - - /* normal operation tests */ - ret += test21_1 (&shortBstring, &emptyBstring, 5); - ret += test21_1 (&longBstring, &is, 3); - ret += test21_1 (&longBstring, &ng, 5); - - if (0 == ret) { - struct bstrList * l; - unsigned char c; - struct tagbstring t; - bstring b; - bstring list[3] = { &emptyBstring, &shortBstring, &longBstring }; - int i; - - blk2tbstr (t, &c, 1); - - for (i=0; i < 3; i++) { - c = (unsigned char) '\0'; - for (;;) { - b = bjoin (l = bsplit (list[i], c), &t); - if (!biseq (b, list[i])) { - printf ("\t\tfailure(%d) ", __LINE__); - printf ("join (bsplit (%s, x%02X), {x%02X}) = %s\n", dumpBstring (list[i]), c, c, dumpBstring (b)); - ret++; - } - bdestroy (b); - bstrListDestroy (l); - if (ret) break; - - b = bjoin (l = bsplitstr (list[i], &t), &t); - if (!biseq (b, list[i])) { - printf ("\t\tfailure(%d) ", __LINE__); - printf ("join (bsplitstr (%s, {x%02X}), {x%02X}) = %s\n", dumpBstring (list[i]), c, c, dumpBstring (b)); - ret++; - } - bdestroy (b); - bstrListDestroy (l); - if (ret) break; - - if (UCHAR_MAX == c) break; - c++; - } - if (ret) break; - } - - l = bsplit (&emptyBstring, 'x'); - bdestroy (l->entry[0]); - l->qty--; - b = bjoin (l, &longBstring); - ret += incorrectBstring (b); - bstrListDestroy (l); - if (b->slen) { - printf ("\t\tfailure(%d) ", __LINE__); - ret++; - } - bdestroy (b); - - } - - printf ("\t# failures: %d\n", ret); - return ret; -} - -static int test22_0 (const_bstring b, const_bstring sep, int ns, ...) { -va_list arglist; -struct bstrList * l; -int ret = 0; - - printf (".\tbsplits (%s, %s)", dumpBstring (b), dumpBstring (sep)); - if ( b != NULL && b->data != NULL && b->slen >= 0 && - sep != NULL && sep->data != NULL && sep->slen >= 0) { - printf (" {"); - - l = bsplits (b, sep); - - if (l) { - int i; - va_start (arglist, ns); - - for (i=0; i < l->qty; i++) { - char * res; - - res = va_arg (arglist, char *); - - if (i != 0) printf (", "); - printf ("%s", dumpBstring (l->entry[i])); - - ret += (res == NULL) || ((int) strlen (res) > l->entry[i]->slen) - || (0 != memcmp (l->entry[i]->data, res, l->entry[i]->slen)); - ret += l->entry[i]->data[l->entry[i]->slen] != '\0'; - } - - va_end (arglist); - - printf (":<%d>", l->qty); - if (ns != l->qty) ret++; - } else { - printf ("NULL"); - ret += (ns != 0); - } - - printf ("}\n"); - - ret += (0 != bstrListDestroy (l) && l != NULL); - } else { - l = bsplits (b, sep); - ret += (l != NULL); - printf (" = %p\n", (void *) l); - } - - if (ret) { - printf ("\t\tfailure(%d) ns = %d\n", __LINE__, ns); - } - - return ret; -} - -static int test22 (void) { -int ret = 0; -struct tagbstring o=bsStatic("o"); -struct tagbstring s=bsStatic("s"); -struct tagbstring b=bsStatic("b"); -struct tagbstring bs=bsStatic("bs"); -struct tagbstring uo=bsStatic("uo"); - - printf ("TEST: extern struct bstrList * bsplits (const_bstring str, const_bstring splitStr);\n"); - /* tests with NULL */ - ret += test22_0 (NULL, &o, 0); - ret += test22_0 (&o, NULL, 0); - - /* normal operation tests */ - ret += test22_0 (&emptyBstring, &o, 1, ""); - ret += test22_0 (&emptyBstring, &uo, 1, ""); - ret += test22_0 (&shortBstring, &emptyBstring, 1, "bogus"); - ret += test22_0 (&shortBstring, &o, 2, "b", "gus"); - ret += test22_0 (&shortBstring, &s, 2, "bogu", ""); - ret += test22_0 (&shortBstring, &b, 2, "" , "ogus"); - ret += test22_0 (&shortBstring, &bs, 3, "" , "ogu", ""); - ret += test22_0 (&longBstring, &o, 9, "This is a b", "gus but reas", "nably l", "ng string. Just l", "ng en", "ugh t", " cause s", "me mall", "cing."); - ret += test22_0 (&shortBstring, &uo, 3, "b", "g", "s"); - - if (0 == ret) { - struct bstrList * l; - unsigned char c; - struct tagbstring t; - bstring bb; - bstring list[3] = { &emptyBstring, &shortBstring, &longBstring }; - int i; - - blk2tbstr (t, &c, 1); - - for (i=0; i < 3; i++) { - c = (unsigned char) '\0'; - for (;;) { - bb = bjoin (l = bsplits (list[i], &t), &t); - if (!biseq (bb, list[i])) { - printf ("\t\tfailure(%d) ", __LINE__); - printf ("join (bsplits (%s, {x%02X}), {x%02X}) = %s\n", dumpBstring (list[i]), c, c, dumpBstring (bb)); - ret++; - } - bdestroy (bb); - bstrListDestroy (l); - if (ret) break; - if (UCHAR_MAX == c) break; - c++; - } - if (ret) break; - } - } - - printf ("\t# failures: %d\n", ret); - return ret; -} - -struct sbstr { - int ofs; - bstring b; -}; - -static size_t test23_aux_read (void *buff, size_t elsize, size_t nelem, void *parm) { -struct sbstr * sb = (struct sbstr *)parm; -int els, len; - - if (parm == NULL || elsize == 0 || nelem == 0) return 0; - len = (int) (nelem * elsize); if (len <= 0) return 0; - if (len + sb->ofs > sb->b->slen) len = sb->b->slen - sb->ofs; - els = (int) (len / elsize); - len = (int) (els * elsize); - if (len > 0) { - memcpy (buff, sb->b->data + sb->ofs, len); - sb->ofs += len; - } - return els; -} - -static int test23_aux_open (struct sbstr * sb, bstring b) { - if (!sb || b == NULL || b->data == NULL) return -__LINE__; - sb->ofs = 0; - sb->b = b; - return 0; -} - -static int test23_aux_splitcb (void * parm, int ofs, const struct tagbstring * entry) { -bstring b = (bstring) parm; - - ofs = ofs; - if (b->slen > 0) bconchar (b, (char) '|'); - bconcat (b, entry); - return 0; -} - -struct tagBss { - int first; - unsigned char sc; - bstring b; -}; - -static int test23_aux_splitcbx (void * parm, int ofs, const struct tagbstring * entry) { -struct tagBss * p = (struct tagBss *) parm; - - ofs = ofs; - if (!p->first) { - bconchar (p->b, (char) p->sc); - } else p->first = 0; - - bconcat (p->b, entry); - return 0; -} - -static int test23 (void) { -struct tagbstring space = bsStatic (" "); -struct sbstr sb; -struct bStream * bs; -bstring b; -int l, ret = 0; - - printf ("TEST: bstream integrated test\n"); - test23_aux_open (&sb, &longBstring); - ret += NULL != (bs = bsopen ((bNread) NULL, &sb)); - ret += NULL == (bs = bsopen ((bNread) test23_aux_read, &sb)); - ret += (bseof (bs) != 0); - ret += BSTR_ERR != bsbufflength (NULL, -1); - ret += BSTR_ERR != bsbufflength (NULL, 1); - ret += BSTR_ERR != bsbufflength (bs, -1); - printf (".\tbsbufflength (bs, 0) -> %d\n", bsbufflength (bs, 0)); - ret += BSTR_ERR == bsbufflength (bs, 1); - ret += BSTR_ERR != bspeek (NULL, bs); - ret += BSTR_ERR != bsreadln (NULL, bs, (char) '?'); - ret += BSTR_ERR != bsreadln (&emptyBstring, bs, (char) '?'); - ret += BSTR_ERR != bspeek (&emptyBstring, bs); - - ret += BSTR_ERR == bspeek (b = bfromcstr (""), bs); - - printf (".\tbspeek () -> %s\n", dumpBstring (b)); - ret += BSTR_ERR != bsreadln (b, NULL, (char) '?'); - b->slen = 0; - ret += BSTR_ERR == bsreadln (b, bs, (char) '?'); - ret += (bseof (bs) <= 0); - ret += biseq (b, &longBstring) < 0; - printf (".\tbsreadln ('?') -> %s\n", dumpBstring (b)); - ret += BSTR_ERR == bsunread (bs, b); - ret += (bseof (bs) != 0); - printf (".\tbsunread (%s)\n", dumpBstring (b)); - b->slen = 0; - ret += BSTR_ERR == bspeek (b, bs); - ret += biseq (b, &longBstring) < 0; - printf (".\tbspeek () -> %s\n", dumpBstring (b)); - b->slen = 0; - ret += BSTR_ERR == bsreadln (b, bs, (char) '?'); - ret += (bseof (bs) <= 0); - ret += biseq (b, &longBstring) < 0; - printf (".\tbsreadln ('?') -> %s\n", dumpBstring (b)); - ret += NULL == bsclose (bs); - sb.ofs = 0; - - ret += NULL == (bs = bsopen ((bNread) test23_aux_read, &sb)); - b->slen = 0; - ret += BSTR_ERR == bsreadln (b, bs, (char) '.'); - l = b->slen; - ret += (0 != bstrncmp (b, &longBstring, l)) || (longBstring.data[l-1] != '.'); - printf (".\tbsreadln ('.') -> %s\n", dumpBstring (b)); - ret += BSTR_ERR == bsunread (bs, b); - - printf (".\tbsunread (%s)\n", dumpBstring (b)); - b->slen = 0; - ret += BSTR_ERR == bspeek (b, bs); - ret += biseq (b, &longBstring) < 0; - printf (".\tbspeek () -> %s\n", dumpBstring (b)); - b->slen = 0; - ret += BSTR_ERR == bsreadln (b, bs, (char) '.'); - - ret += b->slen != l || (0 != bstrncmp (b, &longBstring, l)) || (longBstring.data[l-1] != '.'); - printf (".\tbsreadln ('.') -> %s\n", dumpBstring (b)); - ret += NULL == bsclose (bs); - - test23_aux_open (&sb, &longBstring); - ret += NULL == (bs = bsopen ((bNread) test23_aux_read, &sb)); - ret += (bseof (bs) != 0); - b->slen = 0; - l = bssplitscb (bs, &space, test23_aux_splitcb, b); - ret += (bseof (bs) <= 0); - ret += NULL == bsclose (bs); - printf (".\tbssplitscb (' ') -> %s\n", dumpBstring (b)); - - for (l=1; l < 4; l++) { - char * str; - for (str = (char *) longBstring.data; *str; str++) { - test23_aux_open (&sb, &longBstring); - ret += NULL == (bs = bsopen ((bNread) test23_aux_read, &sb)); - ret += bseof (bs) != 0; - ret += 0 > bsbufflength (bs, l); - b->slen = 0; - while (0 == bsreadlna (b, bs, *str)) ; - ret += 0 == biseq (b, &longBstring); - ret += bseof (bs) <= 0; - ret += NULL == bsclose (bs); - if (ret) break; - } - if (ret) break; - } - - bdestroy (b); - - if (0 == ret) { - unsigned char c; - struct tagbstring t; - bstring list[3] = { &emptyBstring, &shortBstring, &longBstring }; - int i; - - blk2tbstr (t, &c, 1); - - for (i=0; i < 3; i++) { - c = (unsigned char) '\0'; - for (;;) { - struct tagBss bss; - - bss.sc = c; - bss.b = bfromcstr (""); - bss.first = 1; - - test23_aux_open (&sb, list[i]); - bs = bsopen ((bNread) test23_aux_read, &sb); - bssplitscb (bs, &t, test23_aux_splitcbx, &bss); - bsclose (bs); - - if (!biseq (bss.b, list[i])) { - printf ("\t\tfailure(%d) ", __LINE__); - printf ("join (bssplitscb (%s, {x%02X}), {x%02X}) = %s\n", dumpBstring (list[i]), c, c, dumpBstring (bss.b)); - ret++; - } - bdestroy (bss.b); - if (ret) break; - if (UCHAR_MAX == c) break; - c++; - } - if (ret) break; - - for (;;) { - struct tagBss bss; - - bss.sc = c; - bss.b = bfromcstr (""); - bss.first = 1; - - test23_aux_open (&sb, list[i]); - bs = bsopen ((bNread) test23_aux_read, &sb); - bssplitstrcb (bs, &t, test23_aux_splitcbx, &bss); - bsclose (bs); - - if (!biseq (bss.b, list[i])) { - printf ("\t\tfailure(%d) ", __LINE__); - printf ("join (bssplitstrcb (%s, {x%02X}), {x%02X}) = %s\n", dumpBstring (list[i]), c, c, dumpBstring (bss.b)); - ret++; - } - bdestroy (bss.b); - if (ret) break; - if (UCHAR_MAX == c) break; - c++; - } - if (ret) break; - } - } - - printf ("\t# failures: %d\n", ret); - return ret; -} - -static int test24_0 (bstring s1, int pos, const_bstring s2, int res) { -int rv, ret = 0; - - printf (".\tbninchr (%s, %d, %s) = ", dumpBstring (s1), pos, dumpBstring (s2)); - rv = bninchr (s1, pos, s2); - printf ("%d\n", rv); - ret += (rv != res); - if (ret) { - printf ("\t\tfailure(%d) res = %d\n", __LINE__, res); - } - return ret; -} - -static int test24 (void) { -bstring b; -int ret = 0; - - printf ("TEST: int bninchr (const_bstring s1, int pos, const_bstring s2);\n"); - ret += test24_0 (NULL, 0, NULL, BSTR_ERR); - ret += test24_0 (&emptyBstring, 0, NULL, BSTR_ERR); - ret += test24_0 (NULL, 0, &emptyBstring, BSTR_ERR); - ret += test24_0 (&shortBstring, 3, &badBstring1, BSTR_ERR); - ret += test24_0 (&badBstring1, 3, &shortBstring, BSTR_ERR); - - ret += test24_0 (&emptyBstring, 0, &emptyBstring, BSTR_ERR); - ret += test24_0 (&shortBstring, 0, &emptyBstring, BSTR_ERR); - ret += test24_0 (&shortBstring, 0, &shortBstring, BSTR_ERR); - ret += test24_0 (&shortBstring, 1, &shortBstring, BSTR_ERR); - ret += test24_0 (&longBstring, 3, &shortBstring, 4); - ret += test24_0 (&longBstring, 3, b = bstrcpy (&shortBstring), 4); - bdestroy (b); - ret += test24_0 (&longBstring, -1, &shortBstring, BSTR_ERR); - ret += test24_0 (&longBstring, 1000, &shortBstring, BSTR_ERR); - ret += test24_0 (&xxxxxBstring, 0, &shortBstring, 0); - ret += test24_0 (&xxxxxBstring, 1, &shortBstring, 1); - ret += test24_0 (&emptyBstring, 0, &shortBstring, BSTR_ERR); - - ret += test24_0 (&longBstring, 0, &shortBstring, 0); - ret += test24_0 (&longBstring, 10, &shortBstring, 15); - printf ("\t# failures: %d\n", ret); - return ret; -} - -static int test25_0 (bstring s1, int pos, const_bstring s2, int res) { -int rv, ret = 0; - - printf (".\tbninchrr (%s, %d, %s) = ", dumpBstring (s1), pos, dumpBstring (s2)); - rv = bninchrr (s1, pos, s2); - printf ("%d\n", rv); - ret += (rv != res); - if (ret) { - printf ("\t\tfailure(%d) res = %d\n", __LINE__, res); - } - return ret; -} - -static int test25 (void) { -bstring b; -int ret = 0; - - printf ("TEST: int bninchrr (const_bstring s1, int pos, const_bstring s2);\n"); - ret += test25_0 (NULL, 0, NULL, BSTR_ERR); - ret += test25_0 (&emptyBstring, 0, NULL, BSTR_ERR); - ret += test25_0 (NULL, 0, &emptyBstring, BSTR_ERR); - ret += test25_0 (&emptyBstring, 0, &emptyBstring, BSTR_ERR); - ret += test25_0 (&shortBstring, 0, &emptyBstring, BSTR_ERR); - ret += test25_0 (&shortBstring, 0, &badBstring1, BSTR_ERR); - ret += test25_0 (&badBstring1, 0, &shortBstring, BSTR_ERR); - - ret += test25_0 (&shortBstring, 0, &shortBstring, BSTR_ERR); - ret += test25_0 (&shortBstring, 4, &shortBstring, BSTR_ERR); - ret += test25_0 (&longBstring, 10, &shortBstring, 9); - ret += test25_0 (&longBstring, 10, b = bstrcpy (&shortBstring), 9); - bdestroy (b); - ret += test25_0 (&xxxxxBstring, 4, &shortBstring, 4); - ret += test25_0 (&emptyBstring, 0, &shortBstring, BSTR_ERR); - - printf ("\t# failures: %d\n", ret); - return ret; -} - -static int test26_0 (bstring b0, int pos, int len, const_bstring b1, unsigned char fill, char * res) { -bstring b2; -int rv, ret = 0; - - if (b0 != NULL && b0->data != NULL && b0->slen >= 0 && - b1 != NULL && b1->data != NULL && b1->slen >= 0) { - b2 = bstrcpy (b0); - bwriteprotect (*b2); - - printf (".\tbreplace (%s, ", dumpBstring (b2)); - - rv = breplace (b2, pos, len, b1, fill); - ret += (rv == 0); - if (!biseq (b0, b2)) ret++; - - printf ("%d, %d, %s, %02X) = %s\n", pos, len, dumpBstring (b1), fill, dumpBstring (b2)); - - bwriteallow (*b2); - - printf (".\tbreplace (%s, ", dumpBstring (b2)); - - rv = breplace (b2, pos, len, b1, fill); - if (b1) { - ret += (pos < 0) && (b2->slen != b0->slen); - ret += ((rv == 0) != (pos >= 0 && pos <= b2->slen)); - } - - ret += (res == NULL) || ((int) strlen (res) > b2->slen) - || (0 != memcmp (b2->data, res, b2->slen)); - ret += b2->data[b2->slen] != '\0'; - - printf ("%d, %d, %s, %02X) = %s\n", pos, len, dumpBstring (b1), fill, dumpBstring (b2)); - - bdestroy (b2); - } else { - ret += (BSTR_ERR != (rv = breplace (b0, pos, len, b1, fill))); - printf (".\tbreplace (%s, %d, %d, %s, %02X) = %d\n", dumpBstring (b0), pos, len, dumpBstring (b1), fill, rv); - } - - if (ret) { - printf ("\t\tfailure(%d) = %d (res = %p", __LINE__, ret, res); - if (res) printf (" = \"%s\"", res); - printf (")\n"); - } - return ret; -} - -static int test26 (void) { -int ret = 0; - printf ("TEST: int breplace (bstring b0, int pos, int len, const_bstring b1, unsigned char fill);\n"); - /* tests with NULL */ - ret += test26_0 (NULL, 0, 0, NULL, (unsigned char) '?', NULL); - ret += test26_0 (NULL, 0, 0, &emptyBstring, (unsigned char) '?', NULL); - ret += test26_0 (&badBstring1, 1, 3, &shortBstring, (unsigned char) '?', NULL); - ret += test26_0 (&shortBstring, 1, 3, &badBstring1, (unsigned char) '?', NULL); - - /* normal operation tests */ - ret += test26_0 (&emptyBstring, 0, 0, &emptyBstring, (unsigned char) '?', ""); - ret += test26_0 (&emptyBstring, 5, 0, &emptyBstring, (unsigned char) '?', "?????"); - ret += test26_0 (&emptyBstring, 5, 0, &shortBstring, (unsigned char) '?', "?????bogus"); - ret += test26_0 (&shortBstring, 0, 0, &emptyBstring, (unsigned char) '?', "bogus"); - ret += test26_0 (&emptyBstring, 0, 0, &shortBstring, (unsigned char) '?', "bogus"); - ret += test26_0 (&shortBstring, 0, 0, &shortBstring, (unsigned char) '?', "bogusbogus"); - ret += test26_0 (&shortBstring, 1, 3, &shortBstring, (unsigned char) '?', "bboguss"); - ret += test26_0 (&shortBstring, 3, 8, &shortBstring, (unsigned char) '?', "bogbogus"); - ret += test26_0 (&shortBstring, -1, 0, &shortBstring, (unsigned char) '?', "bogus"); - ret += test26_0 (&shortBstring, 2, 0, &shortBstring, (unsigned char) '?', "bobogusgus"); - ret += test26_0 (&shortBstring, 6, 0, &shortBstring, (unsigned char) '?', "bogus?bogus"); - ret += test26_0 (&shortBstring, 6, 0, NULL, (unsigned char) '?', "bogus"); - printf ("\t# failures: %d\n", ret); - return ret; -} - -static int test27_0 (bstring b0, const_bstring b1, const char * res) { -bstring b2; -int rv, ret = 0; - - if (b0 != NULL && b0->data != NULL && b0->slen >= 0 && - b1 != NULL && b1->data != NULL && b1->slen >= 0) { - b2 = bstrcpy (b0); - bwriteprotect (*b2); - - printf (".\tbassign (%s, ", dumpBstring (b2)); - - rv = bassign (b2, b1); - ret += (rv == 0); - if (!biseq (b0, b2)) ret++; - - printf ("%s) = %s\n", dumpBstring (b1), dumpBstring (b2)); - - bwriteallow (*b2); - - printf (".\tbassign (%s, ", dumpBstring (b2)); - - rv = bassign (b2, b1); - - printf ("%s) = %s\n", dumpBstring (b1), dumpBstring (b2)); - - if (b1) ret += (b2->slen != b1->slen); - ret += ((0 != rv) && (b1 != NULL)) || ((0 == rv) && (b1 == NULL)); - ret += (res == NULL) || ((int) strlen (res) != b2->slen) - || (0 != memcmp (b2->data, res, b2->slen)); - ret += b2->data[b2->slen] != '\0'; - bdestroy (b2); - } else { - ret += (BSTR_ERR != (rv = bassign (b0, b1))); - printf (".\tbassign (%s, %s) = %d\n", dumpBstring (b0), dumpBstring (b1), rv); - } - - if (ret) { - printf ("\t\tfailure(%d) = %d (res = %p", __LINE__, ret, res); - if (res) printf (" = \"%s\"", res); - printf (")\n"); - } - return ret; -} - -static int test27 (void) { -int ret = 0; - - printf ("TEST: int bassign (bstring b0, const_bstring b1);\n"); - - /* tests with NULL */ - ret += test27_0 (NULL, NULL, NULL); - ret += test27_0 (NULL, &emptyBstring, NULL); - ret += test27_0 (&emptyBstring, NULL, ""); - ret += test27_0 (&badBstring1, &emptyBstring, NULL); - ret += test27_0 (&badBstring2, &emptyBstring, NULL); - ret += test27_0 (&emptyBstring, &badBstring1, NULL); - ret += test27_0 (&emptyBstring, &badBstring2, NULL); - - /* normal operation tests on all sorts of subranges */ - ret += test27_0 (&emptyBstring, &emptyBstring, ""); - ret += test27_0 (&emptyBstring, &shortBstring, "bogus"); - ret += test27_0 (&shortBstring, &emptyBstring, ""); - ret += test27_0 (&shortBstring, &shortBstring, "bogus"); - printf ("\t# failures: %d\n", ret); - return ret; -} - -static int test28_0 (bstring s1, int c, int res) { -int rv, ret = 0; - - printf (".\tbstrchr (%s, %d) = ", dumpBstring (s1), c); - rv = bstrchr (s1, c); - printf ("%d\n", rv); - ret += (rv != res); - if (ret) { - printf ("\t\tfailure(%d) res = %d\n", __LINE__, res); - } - return ret; -} - -static int test28_1 (bstring s1, int c, int res) { -int rv, ret = 0; - - printf (".\tbstrrchr (%s, %d) = ", dumpBstring (s1), c); - rv = bstrrchr (s1, c); - printf ("%d\n", rv); - ret += (rv != res); - if (ret) { - printf ("\t\tfailure(%d) res = %d rv = %d\n", __LINE__, res, rv); - } - return ret; -} - -static int test28_2 (bstring s1, int c, int pos, int res) { -int rv, ret = 0; - - printf (".\tbstrchrp (%s, %d, %d) = ", dumpBstring (s1), c, pos); - rv = bstrchrp (s1, c, pos); - printf ("%d\n", rv); - ret += (rv != res); - if (ret) { - printf ("\t\tfailure(%d) res = %d\n", __LINE__, res); - } - return ret; -} - -static int test28_3 (bstring s1, int c, int pos, int res) { -int rv, ret = 0; - - printf (".\tbstrrchrp (%s, %d, %d) = ", dumpBstring (s1), c, pos); - rv = bstrrchrp (s1, c, pos); - printf ("%d\n", rv); - ret += (rv != res); - if (ret) { - printf ("\t\tfailure(%d) res = %d rv = %d\n", __LINE__, res, rv); - } - return ret; -} - -static int test28 (void) { -int ret = 0; - - printf ("TEST: int bstrchr (const_bstring s1, int c);\n"); - ret += test28_0 (NULL, 0, BSTR_ERR); - ret += test28_0 (&badBstring1, 'b', BSTR_ERR); - ret += test28_0 (&badBstring2, 's', BSTR_ERR); - - ret += test28_0 (&emptyBstring, 0, BSTR_ERR); - ret += test28_0 (&shortBstring, 0, BSTR_ERR); - ret += test28_0 (&shortBstring, 'b', 0); - ret += test28_0 (&shortBstring, 's', 4); - ret += test28_0 (&shortBstring, 'q', BSTR_ERR); - ret += test28_0 (&xxxxxBstring, 0, BSTR_ERR); - ret += test28_0 (&xxxxxBstring, 'b', BSTR_ERR); - ret += test28_0 (&longBstring, 'i', 2); - - printf ("TEST: int bstrrchr (const_bstring s1, int c);\n"); - ret += test28_1 (NULL, 0, BSTR_ERR); - ret += test28_1 (&badBstring1, 'b', BSTR_ERR); - ret += test28_1 (&badBstring2, 's', BSTR_ERR); - - ret += test28_1 (&emptyBstring, 0, BSTR_ERR); - ret += test28_1 (&shortBstring, 0, BSTR_ERR); - ret += test28_1 (&shortBstring, 'b', 0); - ret += test28_1 (&shortBstring, 's', 4); - ret += test28_1 (&shortBstring, 'q', BSTR_ERR); - ret += test28_1 (&xxxxxBstring, 0, BSTR_ERR); - ret += test28_1 (&xxxxxBstring, 'b', BSTR_ERR); - ret += test28_1 (&longBstring, 'i', 82); - - printf ("TEST: int bstrchrp (const_bstring s1, int c, int pos);\n"); - ret += test28_2 (NULL, 0, 0, BSTR_ERR); - ret += test28_2 (&badBstring1, 'b', 0, BSTR_ERR); - ret += test28_2 (&badBstring2, 's', 0, BSTR_ERR); - ret += test28_2 (&shortBstring, 'b', -1, BSTR_ERR); - ret += test28_2 (&shortBstring, 'b', shortBstring.slen, BSTR_ERR); - - ret += test28_2 (&emptyBstring, 0, 0, BSTR_ERR); - ret += test28_2 (&shortBstring, 0, 0, BSTR_ERR); - ret += test28_2 (&shortBstring, 'b', 0, 0); - ret += test28_2 (&shortBstring, 'b', 1, BSTR_ERR); - ret += test28_2 (&shortBstring, 's', 0, 4); - ret += test28_2 (&shortBstring, 'q', 0, BSTR_ERR); - - printf ("TEST: int bstrrchrp (const_bstring s1, int c, int pos);\n"); - ret += test28_3 (NULL, 0, 0, BSTR_ERR); - ret += test28_3 (&badBstring1, 'b', 0, BSTR_ERR); - ret += test28_3 (&badBstring2, 's', 0, BSTR_ERR); - ret += test28_3 (&shortBstring, 'b', -1, BSTR_ERR); - ret += test28_3 (&shortBstring, 'b', shortBstring.slen, BSTR_ERR); - - ret += test28_3 (&emptyBstring, 0, 0, BSTR_ERR); - ret += test28_3 (&shortBstring, 0, 0, BSTR_ERR); - ret += test28_3 (&shortBstring, 'b', 0, 0); - ret += test28_3 (&shortBstring, 'b', shortBstring.slen - 1, 0); - ret += test28_3 (&shortBstring, 's', shortBstring.slen - 1, 4); - ret += test28_3 (&shortBstring, 's', 0, BSTR_ERR); - - printf ("\t# failures: %d\n", ret); - return ret; -} - -static int test29_0 (bstring b0, char * s, const char * res) { -bstring b2; -int rv, ret = 0; - - if (b0 != NULL && b0->data != NULL && b0->slen >= 0) { - b2 = bstrcpy (b0); - bwriteprotect (*b2); - - printf (".\tbcatcstr (%s, ", dumpBstring (b2)); - - rv = bcatcstr (b2, s); - ret += (rv == 0); - if (!biseq (b0, b2)) ret++; - - printf ("%p) = %s\n", s, dumpBstring (b2)); - - bwriteallow (*b2); - - printf (".\tbcatcstr (%s, ", dumpBstring (b2)); - - rv = bcatcstr (b2, s); - - printf ("%p) = %s\n", s, dumpBstring (b2)); - - if (s) ret += (b2->slen != b0->slen + (int) strlen (s)); - ret += ((0 != rv) && (s != NULL)) || ((0 == rv) && (s == NULL)); - ret += (res == NULL) || ((int) strlen (res) != b2->slen) - || (0 != memcmp (b2->data, res, b2->slen)); - ret += b2->data[b2->slen] != '\0'; - bdestroy (b2); - } else { - ret += (BSTR_ERR != (rv = bcatcstr (b0, s))); - printf (".\tbcatcstr (%s, %p) = %d\n", dumpBstring (b0), s, rv); - } - - if (ret) { - printf ("\t\tfailure(%d) = %d (res = %p", __LINE__, ret, res); - if (res) printf (" = \"%s\"", res); - printf (")\n"); - } - return ret; -} - -static int test29 (void) { -int ret = 0; - - printf ("TEST: int bcatcstr (bstring b0, const char * s);\n"); - - /* tests with NULL */ - ret += test29_0 (NULL, NULL, NULL); - ret += test29_0 (NULL, "", NULL); - ret += test29_0 (&emptyBstring, NULL, ""); - ret += test29_0 (&badBstring1, "bogus", NULL); - ret += test29_0 (&badBstring2, "bogus", NULL); - - /* normal operation tests on all sorts of subranges */ - ret += test29_0 (&emptyBstring, "", ""); - ret += test29_0 (&emptyBstring, "bogus", "bogus"); - ret += test29_0 (&shortBstring, "", "bogus"); - ret += test29_0 (&shortBstring, "bogus", "bogusbogus"); - printf ("\t# failures: %d\n", ret); - return ret; -} - -static int test30_0 (bstring b0, const unsigned char * s, int len, const char * res) { -bstring b2; -int rv, ret = 0; - - if (b0 != NULL && b0->data != NULL && b0->slen >= 0) { - b2 = bstrcpy (b0); - bwriteprotect (*b2); - - printf (".\tbcatblk (%s, ", dumpBstring (b2)); - - rv = bcatblk (b2, s, len); - ret += (rv == 0); - if (!biseq (b0, b2)) ret++; - - printf ("%p) = %s\n", s, dumpBstring (b2)); - - bwriteallow (*b2); - - printf (".\tbcatblk (%s, ", dumpBstring (b2)); - - rv = bcatblk (b2, s, len); - - printf ("%p) = %s\n", s, dumpBstring (b2)); - - if (s) { - if (len >= 0) ret += (b2->slen != b0->slen + len); - else ret += (b2->slen != b0->slen); - } - ret += ((0 != rv) && (s != NULL && len >= 0)) || ((0 == rv) && (s == NULL || len < 0)); - ret += (res == NULL) || ((int) strlen (res) != b2->slen) - || (0 != memcmp (b2->data, res, b2->slen)); - ret += b2->data[b2->slen] != '\0'; - bdestroy (b2); - } else { - ret += (BSTR_ERR != (rv = bcatblk (b0, s, len))); - printf (".\tbcatblk (%s, %p, %d) = %d\n", dumpBstring (b0), s, len, rv); - } - - if (ret) { - printf ("\t\tfailure(%d) = %d (res = %p", __LINE__, ret, res); - if (res) printf (" = \"%s\"", res); - printf (")\n"); - } - return ret; -} - -static int test30 (void) { -int ret = 0; - - printf ("TEST: int bcatblk (bstring b0, const char * s);\n"); - - /* tests with NULL */ - ret += test30_0 (NULL, NULL, 0, NULL); - ret += test30_0 (NULL, (unsigned char *) "", 0, NULL); - ret += test30_0 (&emptyBstring, NULL, 0, ""); - ret += test30_0 (&emptyBstring, NULL, -1, ""); - ret += test30_0 (&badBstring1, NULL, 0, NULL); - ret += test30_0 (&badBstring2, NULL, 0, NULL); - - /* normal operation tests on all sorts of subranges */ - ret += test30_0 (&emptyBstring, (unsigned char *) "", -1, ""); - ret += test30_0 (&emptyBstring, (unsigned char *) "", 0, ""); - ret += test30_0 (&emptyBstring, (unsigned char *) "bogus", 5, "bogus"); - ret += test30_0 (&shortBstring, (unsigned char *) "", 0, "bogus"); - ret += test30_0 (&shortBstring, (unsigned char *) "bogus", 5, "bogusbogus"); - ret += test30_0 (&shortBstring, (unsigned char *) "bogus", -1, "bogus"); - printf ("\t# failures: %d\n", ret); - return ret; -} - -static int test31_0 (bstring b0, const_bstring find, const_bstring replace, int pos, char * res) { -bstring b2; -int rv, ret = 0; - - if (b0 != NULL && b0->data != NULL && b0->slen >= 0 && - find != NULL && find->data != NULL && find->slen >= 0 && - replace != NULL && replace->data != NULL && replace->slen >= 0) { - b2 = bstrcpy (b0); - bwriteprotect (*b2); - - printf (".\tbfindreplace (%s, %s, %s, %d) = ", dumpBstring (b2), dumpBstring (find), dumpBstring (replace), pos); - - rv = bfindreplace (b2, find, replace, pos); - ret += (rv == 0); - if (!biseq (b0, b2)) ret++; - - printf ("%d\n", rv); - - bwriteallow (*b2); - - printf (".\tbfindreplace (%s, %s, %s, %d)", dumpBstring (b2), dumpBstring (find), dumpBstring (replace), pos); - - rv = bfindreplace (b2, find, replace, pos); - - ret += (res == NULL) || ((int) strlen (res) > b2->slen) - || (0 != memcmp (b2->data, res, b2->slen)); - ret += b2->data[b2->slen] != '\0'; - - printf (" -> %s\n", dumpBstring (b2)); - - bdestroy (b2); - } else { - ret += (BSTR_ERR != (rv = bfindreplace (b0, find, replace, pos))); - printf (".\tbfindreplace (%s, %s, %s, %d) = %d\n", dumpBstring (b0), dumpBstring (find), dumpBstring (replace), pos, rv); - } - - if (ret) { - printf ("\t\tfailure(%d) = %d (res = %p", __LINE__, ret, res); - if (res) printf (" = \"%s\"", res); - printf (")\n"); - } - return ret; -} - -static int test31_1 (bstring b0, const_bstring find, const_bstring replace, int pos, char * res) { -bstring b2; -int rv, ret = 0; - - if (b0 != NULL && b0->data != NULL && b0->slen >= 0 && - find != NULL && find->data != NULL && find->slen >= 0 && - replace != NULL && replace->data != NULL && replace->slen >= 0) { - b2 = bstrcpy (b0); - bwriteprotect (*b2); - - printf (".\tbfindreplacecaseless (%s, %s, %s, %d) = ", dumpBstring (b2), dumpBstring (find), dumpBstring (replace), pos); - - rv = bfindreplacecaseless (b2, find, replace, pos); - ret += (rv == 0); - if (!biseq (b0, b2)) ret++; - - printf ("%d\n", rv); - - bwriteallow (*b2); - - printf (".\tbfindreplacecaseless (%s, %s, %s, %d)", dumpBstring (b2), dumpBstring (find), dumpBstring (replace), pos); - - rv = bfindreplacecaseless (b2, find, replace, pos); - - ret += (res == NULL) || ((int) strlen (res) > b2->slen) - || (0 != memcmp (b2->data, res, b2->slen)); - ret += b2->data[b2->slen] != '\0'; - - printf (" -> %s\n", dumpBstring (b2)); - - bdestroy (b2); - } else { - ret += (BSTR_ERR != (rv = bfindreplacecaseless (b0, find, replace, pos))); - printf (".\tbfindreplacecaseless (%s, %s, %s, %d) = %d\n", dumpBstring (b0), dumpBstring (find), dumpBstring (replace), pos, rv); - } - - if (ret) { - printf ("\t\tfailure(%d) = %d (res = %p", __LINE__, ret, res); - if (res) printf (" = \"%s\"", res); - printf (")\n"); - } - return ret; -} - -#define LOTS_OF_S "ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss" - -static int test31 (void) { -int ret = 0; -struct tagbstring t0 = bsStatic ("funny"); -struct tagbstring t1 = bsStatic ("weird"); -struct tagbstring t2 = bsStatic ("s"); -struct tagbstring t3 = bsStatic ("long"); -struct tagbstring t4 = bsStatic ("big"); -struct tagbstring t5 = bsStatic ("ss"); -struct tagbstring t6 = bsStatic ("sstsst"); -struct tagbstring t7 = bsStatic ("xx" LOTS_OF_S "xx"); -struct tagbstring t8 = bsStatic ("S"); -struct tagbstring t9 = bsStatic ("LONG"); - - printf ("TEST: int bfindreplace (bstring b, const_bstring f, const_bstring r, int pos);\n"); - /* tests with NULL */ - ret += test31_0 (NULL, NULL, NULL, 0, NULL); - ret += test31_0 (&shortBstring, NULL, &t1, 0, (char *) shortBstring.data); - ret += test31_0 (&shortBstring, &t2, NULL, 0, (char *) shortBstring.data); - ret += test31_0 (&badBstring1, &t2, &t1, 0, NULL); - ret += test31_0 (&badBstring2, &t2, &t1, 0, NULL); - - /* normal operation tests */ - ret += test31_0 (&longBstring, &shortBstring, &t0, 0, "This is a funny but reasonably long string. Just long enough to cause some mallocing."); - ret += test31_0 (&longBstring, &t2, &t1, 0, "Thiweird iweird a boguweird but reaweirdonably long weirdtring. Juweirdt long enough to cauweirde weirdome mallocing."); - ret += test31_0 (&shortBstring, &t2, &t1, 0, "boguweird"); - ret += test31_0 (&shortBstring, &t8, &t1, 0, "bogus"); - ret += test31_0 (&longBstring, &t2, &t1, 27, "This is a bogus but reasonably long weirdtring. Juweirdt long enough to cauweirde weirdome mallocing."); - ret += test31_0 (&longBstring, &t3, &t4, 0, "This is a bogus but reasonably big string. Just big enough to cause some mallocing."); - ret += test31_0 (&longBstring, &t9, &t4, 0, "This is a bogus but reasonably long string. Just long enough to cause some mallocing."); - ret += test31_0 (&t6, &t2, &t5, 0, "sssstsssst"); - ret += test31_0 (&t7, &t2, &t5, 0, "xx" LOTS_OF_S LOTS_OF_S "xx"); - - printf ("TEST: int bfindreplacecaseless (bstring b, const_bstring f, const_bstring r, int pos);\n"); - /* tests with NULL */ - ret += test31_1 (NULL, NULL, NULL, 0, NULL); - ret += test31_1 (&shortBstring, NULL, &t1, 0, (char *) shortBstring.data); - ret += test31_1 (&shortBstring, &t2, NULL, 0, (char *) shortBstring.data); - ret += test31_1 (&badBstring1, &t2, &t1, 0, NULL); - ret += test31_1 (&badBstring2, &t2, &t1, 0, NULL); - - /* normal operation tests */ - ret += test31_1 (&longBstring, &shortBstring, &t0, 0, "This is a funny but reasonably long string. Just long enough to cause some mallocing."); - ret += test31_1 (&longBstring, &t2, &t1, 0, "Thiweird iweird a boguweird but reaweirdonably long weirdtring. Juweirdt long enough to cauweirde weirdome mallocing."); - ret += test31_1 (&shortBstring, &t2, &t1, 0, "boguweird"); - ret += test31_1 (&shortBstring, &t8, &t1, 0, "boguweird"); - ret += test31_1 (&longBstring, &t2, &t1, 27, "This is a bogus but reasonably long weirdtring. Juweirdt long enough to cauweirde weirdome mallocing."); - ret += test31_1 (&longBstring, &t3, &t4, 0, "This is a bogus but reasonably big string. Just big enough to cause some mallocing."); - ret += test31_1 (&longBstring, &t9, &t4, 0, "This is a bogus but reasonably big string. Just big enough to cause some mallocing."); - ret += test31_1 (&t6, &t2, &t5, 0, "sssstsssst"); - ret += test31_1 (&t6, &t8, &t5, 0, "sssstsssst"); - ret += test31_1 (&t7, &t2, &t5, 0, "xx" LOTS_OF_S LOTS_OF_S "xx"); - - printf ("\t# failures: %d\n", ret); - return ret; -} - -static int test32_0 (const_bstring b, const char * s, int res) { -int rv, ret = 0; - - ret += (res != (rv = biseqcstr (b, s))); - printf (".\tbiseqcstr (%s, %p:<%s>) = %d\n", dumpBstring (b), s, (s ? s : NULL), rv); - if (ret) { - printf ("\t\tfailure(%d) = %d (res = %d)\n", __LINE__, ret, res); - } - return ret; -} - -static int test32_1 (const_bstring b, const char * s, int res) { -int rv, ret = 0; - - ret += (res != (rv = biseqcstrcaseless (b, s))); - printf (".\tbiseqcstrcaseless (%s, %p:<%s>) = %d\n", dumpBstring (b), s, (s ? s : NULL), rv); - if (ret) { - printf ("\t\tfailure(%d) = %d (res = %d)\n", __LINE__, ret, res); - } - return ret; -} - - -static int test32 (void) { -int ret = 0; - - printf ("TEST: int biseqcstr (const_bstring b, const char * s);\n"); - - /* tests with NULL */ - ret += test32_0 (NULL, NULL, BSTR_ERR); - ret += test32_0 (&emptyBstring, NULL, BSTR_ERR); - ret += test32_0 (NULL, "", BSTR_ERR); - ret += test32_0 (&badBstring1, "", BSTR_ERR); - ret += test32_0 (&badBstring2, "bogus", BSTR_ERR); - - /* normal operation tests on all sorts of subranges */ - ret += test32_0 (&emptyBstring, "", 1); - ret += test32_0 (&shortBstring, "bogus", 1); - ret += test32_0 (&emptyBstring, "bogus", 0); - ret += test32_0 (&shortBstring, "", 0); - - { - bstring b = bstrcpy (&shortBstring); - b->data[1]++; - ret += test32_0 (b, (char *) shortBstring.data, 0); - bdestroy (b); - } - - printf ("TEST: int biseqcstrcaseless (const_bstring b, const char * s);\n"); - - /* tests with NULL */ - ret += test32_1 (NULL, NULL, BSTR_ERR); - ret += test32_1 (&emptyBstring, NULL, BSTR_ERR); - ret += test32_1 (NULL, "", BSTR_ERR); - ret += test32_1 (&badBstring1, "", BSTR_ERR); - ret += test32_1 (&badBstring2, "bogus", BSTR_ERR); - - /* normal operation tests on all sorts of subranges */ - ret += test32_1 (&emptyBstring, "", 1); - ret += test32_1 (&shortBstring, "bogus", 1); - ret += test32_1 (&shortBstring, "BOGUS", 1); - ret += test32_1 (&emptyBstring, "bogus", 0); - ret += test32_1 (&shortBstring, "", 0); - - { - bstring b = bstrcpy (&shortBstring); - b->data[1]++; - ret += test32_1 (b, (char *) shortBstring.data, 0); - bdestroy (b); - } - - if (ret) printf ("\t# failures: %d\n", ret); - return ret; -} - -static int test33_0 (bstring b0, const char * res) { -bstring b2; -int rv, ret = 0; - - if (b0 != NULL && b0->data != NULL && b0->slen >= 0) { - b2 = bstrcpy (b0); - bwriteprotect (*b2); - - printf (".\tbtoupper (%s)", dumpBstring (b2)); - - rv = btoupper (b2); - ret += (rv == 0); - if (!biseq (b0, b2)) ret++; - - printf (" = %s\n", dumpBstring (b2)); - - bwriteallow (*b2); - - printf (".\tbtoupper (%s)", dumpBstring (b2)); - - rv = btoupper (b2); - - printf (" = %s\n", dumpBstring (b2)); - - ret += (b2->slen != b0->slen); - ret += (0 != rv); - ret += (res == NULL) || ((int) strlen (res) != b2->slen) - || (0 != memcmp (b2->data, res, b2->slen)); - ret += b2->data[b2->slen] != '\0'; - bdestroy (b2); - } else { - ret += (BSTR_ERR != (rv = btoupper (b0))); - printf (".\tbtoupper (%s) = %d\n", dumpBstring (b0), rv); - } - - if (ret) { - printf ("\t\tfailure(%d) = %d (res = %p", __LINE__, ret, res); - if (res) printf (" = \"%s\"", res); - printf (")\n"); - } - return ret; -} - -static int test33 (void) { -int ret = 0; - - printf ("TEST: int btoupper (bstring b);\n"); - - /* tests with NULL */ - ret += test33_0 (NULL, NULL); - ret += test33_0 (&badBstring1, NULL); - ret += test33_0 (&badBstring2, NULL); - - /* normal operation tests on all sorts of subranges */ - ret += test33_0 (&emptyBstring, ""); - ret += test33_0 (&shortBstring, "BOGUS"); - ret += test33_0 (&longBstring, "THIS IS A BOGUS BUT REASONABLY LONG STRING. JUST LONG ENOUGH TO CAUSE SOME MALLOCING."); - - if (ret) printf ("\t# failures: %d\n", ret); - return ret; -} - -static int test34_0 (bstring b0, const char * res) { -bstring b2; -int rv, ret = 0; - - if (b0 != NULL && b0->data != NULL && b0->slen >= 0) { - b2 = bstrcpy (b0); - bwriteprotect (*b2); - - printf (".\tbtolower (%s)", dumpBstring (b2)); - - rv = btolower (b2); - ret += (rv == 0); - if (!biseq (b0, b2)) ret++; - - printf (" = %s\n", dumpBstring (b2)); - - bwriteallow (*b2); - - printf (".\tbtolower (%s)", dumpBstring (b2)); - - rv = btolower (b2); - - printf (" = %s\n", dumpBstring (b2)); - - ret += (b2->slen != b0->slen); - ret += (0 != rv); - ret += (res == NULL) || ((int) strlen (res) != b2->slen) - || (0 != memcmp (b2->data, res, b2->slen)); - ret += b2->data[b2->slen] != '\0'; - bdestroy (b2); - } else { - ret += (BSTR_ERR != (rv = btolower (b0))); - printf (".\tbtolower (%s) = %d\n", dumpBstring (b0), rv); - } - - if (ret) { - printf ("\t\tfailure(%d) = %d (res = %p", __LINE__, ret, res); - if (res) printf (" = \"%s\"", res); - printf (")\n"); - } - return ret; -} - -static int test34 (void) { -int ret = 0; - - printf ("TEST: int btolower (bstring b);\n"); - - /* tests with NULL */ - ret += test34_0 (NULL, NULL); - ret += test34_0 (&badBstring1, NULL); - ret += test34_0 (&badBstring2, NULL); - - /* normal operation tests on all sorts of subranges */ - ret += test34_0 (&emptyBstring, ""); - ret += test34_0 (&shortBstring, "bogus"); - ret += test34_0 (&longBstring, "this is a bogus but reasonably long string. just long enough to cause some mallocing."); - - if (ret) printf ("\t# failures: %d\n", ret); - return ret; -} - -static int test35_0 (const_bstring b0, const_bstring b1, int res) { -int rv, ret = 0; - - ret += (res != (rv = bstricmp (b0, b1))); - printf (".\tbstricmp (%s, %s) = %d\n", dumpBstring (b0), dumpBstring (b1), rv); - if (ret) { - printf ("\t\tfailure(%d) = %d (res = %d)\n", __LINE__, ret, res); - } - return ret; -} - -static int test35 (void) { -int ret = 0; -struct tagbstring t0 = bsStatic ("bOgUs"); -struct tagbstring t1 = bsStatic ("bOgUR"); -struct tagbstring t2 = bsStatic ("bOgUt"); - - printf ("TEST: int bstricmp (const_bstring b0, const_bstring b1);\n"); - - /* tests with NULL */ - ret += test35_0 (NULL, NULL, SHRT_MIN); - ret += test35_0 (&emptyBstring, NULL, SHRT_MIN); - ret += test35_0 (NULL, &emptyBstring, SHRT_MIN); - ret += test35_0 (&emptyBstring, &badBstring1, SHRT_MIN); - ret += test35_0 (&badBstring1, &emptyBstring, SHRT_MIN); - ret += test35_0 (&shortBstring, &badBstring2, SHRT_MIN); - ret += test35_0 (&badBstring2, &shortBstring, SHRT_MIN); - - /* normal operation tests on all sorts of subranges */ - ret += test35_0 (&emptyBstring, &emptyBstring, 0); - ret += test35_0 (&shortBstring, &t0, 0); - ret += test35_0 (&shortBstring, &t1, tolower (shortBstring.data[4]) - tolower (t1.data[4])); - ret += test35_0 (&shortBstring, &t2, tolower (shortBstring.data[4]) - tolower (t2.data[4])); - - t0.slen++; - ret += test35_0 (&shortBstring, &t0, -(UCHAR_MAX+1)); - ret += test35_0 (&t0, &shortBstring, (UCHAR_MAX+1)); - - if (ret) printf ("\t# failures: %d\n", ret); - return ret; -} - -static int test36_0 (const_bstring b0, const_bstring b1, int n, int res) { -int rv, ret = 0; - - ret += (res != (rv = bstrnicmp (b0, b1, n))); - printf (".\tbstrnicmp (%s, %s, %d) = %d\n", dumpBstring (b0), dumpBstring (b1), n, rv); - if (ret) { - printf ("\t\tfailure(%d) = %d (res = %d)\n", __LINE__, ret, res); - } - return ret; -} - -static int test36 (void) { -int ret = 0; -struct tagbstring t0 = bsStatic ("bOgUs"); -struct tagbstring t1 = bsStatic ("bOgUR"); -struct tagbstring t2 = bsStatic ("bOgUt"); - - printf ("TEST: int bstrnicmp (const_bstring b0, const_bstring b1);\n"); - - /* tests with NULL */ - ret += test36_0 (NULL, NULL, 0, SHRT_MIN); - ret += test36_0 (&emptyBstring, NULL, 0, SHRT_MIN); - ret += test36_0 (NULL, &emptyBstring, 0, SHRT_MIN); - ret += test36_0 (&emptyBstring, &badBstring1, 0, SHRT_MIN); - ret += test36_0 (&badBstring1, &emptyBstring, 0, SHRT_MIN); - ret += test36_0 (&shortBstring, &badBstring2, 5, SHRT_MIN); - ret += test36_0 (&badBstring2, &shortBstring, 5, SHRT_MIN); - - /* normal operation tests on all sorts of subranges */ - ret += test36_0 (&emptyBstring, &emptyBstring, 0, 0); - ret += test36_0 (&shortBstring, &t0, 0, 0); - ret += test36_0 (&shortBstring, &t0, 5, 0); - ret += test36_0 (&shortBstring, &t0, 4, 0); - ret += test36_0 (&shortBstring, &t0, 6, 0); - ret += test36_0 (&shortBstring, &t1, 5, shortBstring.data[4] - t1.data[4]); - ret += test36_0 (&shortBstring, &t1, 4, 0); - ret += test36_0 (&shortBstring, &t1, 6, shortBstring.data[4] - t1.data[4]); - ret += test36_0 (&shortBstring, &t2, 5, shortBstring.data[4] - t2.data[4]); - ret += test36_0 (&shortBstring, &t2, 4, 0); - ret += test36_0 (&shortBstring, &t2, 6, shortBstring.data[4] - t2.data[4]); - - t0.slen++; - ret += test36_0 (&shortBstring, &t0, 5, 0); - ret += test36_0 (&shortBstring, &t0, 6, -(UCHAR_MAX+1)); - ret += test36_0 (&t0, &shortBstring, 6, (UCHAR_MAX+1)); - - if (ret) printf ("\t# failures: %d\n", ret); - return ret; -} - -static int test37_0 (const_bstring b0, const_bstring b1, int res) { -int rv, ret = 0; - - ret += (res != (rv = biseqcaseless (b0, b1))); - printf (".\tbiseqcaseless (%s, %s) = %d\n", dumpBstring (b0), dumpBstring (b1), rv); - if (ret) { - printf ("\t\tfailure(%d) = %d (res = %d)\n", __LINE__, ret, res); - } - return ret; -} - -static int test37 (void) { -int ret = 0; -struct tagbstring t0 = bsStatic ("bOgUs"); -struct tagbstring t1 = bsStatic ("bOgUR"); -struct tagbstring t2 = bsStatic ("bOgUt"); - - printf ("TEST: int biseqcaseless (const_bstring b0, const_bstring b1);\n"); - - /* tests with NULL */ - ret += test37_0 (NULL, NULL, BSTR_ERR); - ret += test37_0 (&emptyBstring, NULL, BSTR_ERR); - ret += test37_0 (NULL, &emptyBstring, BSTR_ERR); - ret += test37_0 (&emptyBstring, &badBstring1, BSTR_ERR); - ret += test37_0 (&badBstring1, &emptyBstring, BSTR_ERR); - ret += test37_0 (&shortBstring, &badBstring2, BSTR_ERR); - ret += test37_0 (&badBstring2, &shortBstring, BSTR_ERR); - - /* normal operation tests on all sorts of subranges */ - ret += test37_0 (&emptyBstring, &emptyBstring, 1); - ret += test37_0 (&shortBstring, &t0, 1); - ret += test37_0 (&shortBstring, &t1, 0); - ret += test37_0 (&shortBstring, &t2, 0); - - if (ret) printf ("\t# failures: %d\n", ret); - return ret; -} - -static int test48_0 (const_bstring b, const unsigned char * blk, int len, int res) { -int rv, ret = 0; - - ret += (res != (rv = biseqcaselessblk (b, blk, len))); - printf (".\tbiseqcaselessblk (%s, %s, %d) = %d\n", dumpBstring (b), dumpCstring (blk), len, rv); - if (ret) { - printf ("\t\tfailure(%d) = %d (res = %d)\n", __LINE__, ret, res); - } - return ret; -} - -static int test48 (void) { -int ret = 0; -struct tagbstring t0 = bsStatic ("bOgUs"); -struct tagbstring t1 = bsStatic ("bOgUR"); -struct tagbstring t2 = bsStatic ("bOgUt"); - - printf ("TEST: int biseqcaselessblk (const_bstring b, const void * blk, int len);\n"); - - /* tests with NULL */ - ret += test48_0 (NULL, NULL, 0, BSTR_ERR); - ret += test48_0 (&emptyBstring, NULL, 0, BSTR_ERR); - ret += test48_0 (NULL, emptyBstring.data, 0, BSTR_ERR); - ret += test48_0 (&emptyBstring, badBstring1.data, emptyBstring.slen, BSTR_ERR); - ret += test48_0 (&badBstring1, emptyBstring.data, badBstring1.slen, BSTR_ERR); - ret += test48_0 (&shortBstring, badBstring2.data, badBstring2.slen, BSTR_ERR); - ret += test48_0 (&badBstring2, shortBstring.data, badBstring2.slen, BSTR_ERR); - - /* normal operation tests on all sorts of subranges */ - ret += test48_0 (&emptyBstring, emptyBstring.data, emptyBstring.slen, 1); - ret += test48_0 (&shortBstring, t0.data, t0.slen, 1); - ret += test48_0 (&shortBstring, t1.data, t1.slen, 0); - ret += test48_0 (&shortBstring, t2.data, t2.slen, 0); - - if (ret) printf ("\t# failures: %d\n", ret); - return ret; -} - -struct emuFile { - int ofs; - bstring contents; -}; - -static int test38_aux_bNgetc (struct emuFile * f) { -int v = EOF; - if (NULL != f && EOF != (v = bchare (f->contents, f->ofs, EOF))) f->ofs++; - return v; -} - -static size_t test38_aux_bNread (void *buff, size_t elsize, size_t nelem, struct emuFile * f) { -char * b = (char *) buff; -int v; -size_t i, j, c = 0; - - if (NULL == f || NULL == b) return c; - for (i=0; i < nelem; i++) for (j=0; j < elsize; j++) { - v = test38_aux_bNgetc (f); - if (EOF == v) { - *b = (char) '\0'; - return c; - } else { - *b = (char) v; - b++; - c++; - } - } - - return c; -} - -static int test38_aux_bNopen (struct emuFile * f, bstring b) { - if (NULL == f || NULL == b) return -__LINE__; - f->ofs = 0; - f->contents = b; - return 0; -} - -static int test38 (void) { -struct emuFile f; -bstring b0, b1, b2, b3; -int ret = 0; - - printf ("TEST: bgets/breads test\n"); - - test38_aux_bNopen (&f, &shortBstring); - - /* Creation/reads */ - - b0 = bgets ((bNgetc) test38_aux_bNgetc, &f, (char) 'b'); - b1 = bread ((bNread) test38_aux_bNread, &f); - b2 = bgets ((bNgetc) test38_aux_bNgetc, &f, (char) '\0'); - b3 = bread ((bNread) test38_aux_bNread, &f); - - ret += 1 != biseqcstr (b0, "b"); - ret += 1 != biseqcstr (b1, "ogus"); - ret += NULL != b2; - ret += 1 != biseqcstr (b3, ""); - - /* Bogus accumulations */ - - f.ofs = 0; - - ret += 0 <= bgetsa (NULL, (bNgetc) test38_aux_bNgetc, &f, (char) 'o'); - ret += 0 <= breada (NULL, (bNread) test38_aux_bNread, &f); - ret += 0 <= bgetsa (&shortBstring, (bNgetc) test38_aux_bNgetc, &f, (char) 'o'); - ret += 0 <= breada (&shortBstring, (bNread) test38_aux_bNread, &f); - - /* Normal accumulations */ - - ret += 0 > bgetsa (b0, (bNgetc) test38_aux_bNgetc, &f, (char) 'o'); - ret += 0 > breada (b1, (bNread) test38_aux_bNread, &f); - - ret += 1 != biseqcstr (b0, "bbo"); - ret += 1 != biseqcstr (b1, "ogusgus"); - - /* Attempt to append past end should do nothing */ - - ret += 0 > bgetsa (b0, (bNgetc) test38_aux_bNgetc, &f, (char) 'o'); - ret += 0 > breada (b1, (bNread) test38_aux_bNread, &f); - - ret += 1 != biseqcstr (b0, "bbo"); - ret += 1 != biseqcstr (b1, "ogusgus"); - - bdestroy (b0); - bdestroy (b1); - bdestroy (b2); - bdestroy (b3); - - if (ret) printf ("\t# failures: %d\n", ret); - return ret; -} - -static int test39_0 (const_bstring b, const_bstring lt, const_bstring rt, const_bstring t) { -bstring r; -int ret = 0; - - ret += 0 <= bltrimws (NULL); - ret += 0 <= brtrimws (NULL); - ret += 0 <= btrimws (NULL); - - r = bstrcpy (b); - bwriteprotect (*r); - ret += 0 <= bltrimws (r); - ret += 0 <= brtrimws (r); - ret += 0 <= btrimws (r); - bwriteallow(*r); - ret += 0 != bltrimws (r); - printf (".\tbltrim (%s) = %s\n", dumpBstring (b), dumpBstring (r)); - ret += !biseq (r, lt); - bdestroy (r); - - r = bstrcpy (b); - ret += 0 != brtrimws (r); - printf (".\tbrtrim (%s) = %s\n", dumpBstring (b), dumpBstring (r)); - ret += !biseq (r, rt); - bdestroy (r); - - r = bstrcpy (b); - ret += 0 != btrimws (r); - printf (".\tbtrim (%s) = %s\n", dumpBstring (b), dumpBstring (r)); - ret += !biseq (r, t); - bdestroy (r); - - return ret; -} - -static int test39 (void) { -int ret = 0; -struct tagbstring t0 = bsStatic (" bogus string "); -struct tagbstring t1 = bsStatic ("bogus string "); -struct tagbstring t2 = bsStatic (" bogus string"); -struct tagbstring t3 = bsStatic ("bogus string"); -struct tagbstring t4 = bsStatic (" "); -struct tagbstring t5 = bsStatic (""); - - printf ("TEST: trim functions\n"); - - ret += test39_0 (&t0, &t1, &t2, &t3); - ret += test39_0 (&t1, &t1, &t3, &t3); - ret += test39_0 (&t2, &t3, &t2, &t3); - ret += test39_0 (&t3, &t3, &t3, &t3); - ret += test39_0 (&t4, &t5, &t5, &t5); - ret += test39_0 (&t5, &t5, &t5, &t5); - - if (ret) printf ("\t# failures: %d\n", ret); - return ret; -} - -static int test40_0 (bstring b0, const_bstring b1, int left, int len, const char * res) { -bstring b2; -int rv, ret = 0; - - if (b0 != NULL && b0->data != NULL && b0->slen >= 0 && - b1 != NULL && b1->data != NULL && b1->slen >= 0) { - b2 = bstrcpy (b0); - bwriteprotect (*b2); - - printf (".\tbassignmidstr (%s, ", dumpBstring (b2)); - - rv = bassignmidstr (b2, b1, left, len); - ret += (rv == 0); - if (!biseq (b0, b2)) ret++; - - printf ("%s, %d, %d) = %s\n", dumpBstring (b1), left, len, dumpBstring (b2)); - - bwriteallow (*b2); - - printf (".\tbassignmidstr (%s, ", dumpBstring (b2)); - - rv = bassignmidstr (b2, b1, left, len); - - printf ("%s, %d, %d) = %s\n", dumpBstring (b1), left, len, dumpBstring (b2)); - - if (b1) ret += (b2->slen > len) | (b2->slen < 0); - ret += ((0 != rv) && (b1 != NULL)) || ((0 == rv) && (b1 == NULL)); - ret += (res == NULL) || ((int) strlen (res) != b2->slen) - || (0 != memcmp (b2->data, res, b2->slen)); - ret += b2->data[b2->slen] != '\0'; - bdestroy (b2); - } else { - ret += (BSTR_ERR != (rv = bassignmidstr (b0, b1, left, len))); - printf (".\tbassignmidstr (%s, %s, %d, %d) = %d\n", dumpBstring (b0), dumpBstring (b1), left, len, rv); - } - - if (ret) { - printf ("\t\tfailure(%d) = %d (res = %p", __LINE__, ret, res); - if (res) printf (" = \"%s\"", res); - printf (")\n"); - } - return ret; -} - -static int test40 (void) { -int ret = 0; - - printf ("TEST: int bassignmidstr (bstring b0, const_bstring b1, int left, int len);\n"); - - /* tests with NULL */ - ret += test40_0 (NULL, NULL, 0, 1, NULL); - ret += test40_0 (NULL, &emptyBstring, 0, 1, NULL); - ret += test40_0 (&emptyBstring, NULL, 0, 1, ""); - ret += test40_0 (&badBstring1, &emptyBstring, 0, 1, NULL); - ret += test40_0 (&badBstring2, &emptyBstring, 0, 1, NULL); - ret += test40_0 (&emptyBstring, &badBstring1, 0, 1, NULL); - ret += test40_0 (&emptyBstring, &badBstring2, 0, 1, NULL); - - /* normal operation tests on all sorts of subranges */ - ret += test40_0 (&emptyBstring, &emptyBstring, 0, 1, ""); - ret += test40_0 (&emptyBstring, &shortBstring, 1, 3, "ogu"); - ret += test40_0 (&shortBstring, &emptyBstring, 0, 1, ""); - ret += test40_0 (&shortBstring, &shortBstring, 1, 3, "ogu"); - ret += test40_0 (&shortBstring, &shortBstring, -1, 4, "bog"); - ret += test40_0 (&shortBstring, &shortBstring, 1, 9, "ogus"); - ret += test40_0 (&shortBstring, &shortBstring, 9, 1, ""); - - printf ("\t# failures: %d\n", ret); - return ret; -} - -static int test41_0 (bstring b1, int left, int len, const char * res) { -struct tagbstring t; -bstring b2, b3; -int ret = 0; - - if (b1 != NULL && b1->data != NULL && b1->slen >= 0) { - b2 = bfromcstr (""); - - bassignmidstr (b2, b1, left, len); - - bmid2tbstr (t, b1, left, len); - b3 = bstrcpy (&t); - - printf (".\tbmid2tbstr (%s, %d, %d) = %s\n", dumpBstring (b1), left, len, dumpBstring (b3)); - - ret += !biseq (&t, b2); - - bdestroy (b2); - bdestroy (b3); - } else { - bmid2tbstr (t, b1, left, len); - b3 = bstrcpy (&t); - ret += t.slen != 0; - - printf (".\tbmid2tbstr (%s, %d, %d) = %s\n", dumpBstring (b1), left, len, dumpBstring (b3)); - bdestroy (b3); - } - - if (ret) { - printf ("\t\tfailure(%d) = %d (res = %p", __LINE__, ret, res); - if (res) printf (" = \"%s\"", res); - printf (")\n"); - } - return ret; -} - -static int test41 (void) { -int ret = 0; - - printf ("TEST: int bmid2tbstr (struct tagbstring &t, const_bstring b1, int left, int len);\n"); - - /* tests with NULL */ - ret += test41_0 (NULL, 0, 1, NULL); - ret += test41_0 (&emptyBstring, 0, 1, NULL); - ret += test41_0 (NULL, 0, 1, ""); - ret += test41_0 (&emptyBstring, 0, 1, NULL); - ret += test41_0 (&emptyBstring, 0, 1, NULL); - ret += test41_0 (&badBstring1, 0, 1, NULL); - ret += test41_0 (&badBstring2, 0, 1, NULL); - - /* normal operation tests on all sorts of subranges */ - ret += test41_0 (&emptyBstring, 0, 1, ""); - ret += test41_0 (&shortBstring, 1, 3, "ogu"); - ret += test41_0 (&emptyBstring, 0, 1, ""); - ret += test41_0 (&shortBstring, 1, 3, "ogu"); - ret += test41_0 (&shortBstring, -1, 4, "bog"); - ret += test41_0 (&shortBstring, 1, 9, "ogus"); - ret += test41_0 (&shortBstring, 9, 1, ""); - - printf ("\t# failures: %d\n", ret); - return ret; -} - -static int test42_0 (const_bstring bi, int len, const char * res) { -bstring b; -int rv, ret = 0; - - rv = btrunc (b = bstrcpy (bi), len); - ret += (len >= 0) ? (rv < 0) : (rv >= 0); - if (res) ret += (0 == biseqcstr (b, res)); - printf (".\tbtrunc (%s, %d) = %s\n", dumpBstring (bi), len, dumpBstring (b)); - bdestroy (b); - return ret; -} - -static int test42 (void) { -int ret = 0; - - printf ("TEST: int btrunc (bstring b, int n);\n"); - - /* tests with NULL */ - ret += 0 <= btrunc (NULL, 2); - ret += 0 <= btrunc (NULL, 0); - ret += 0 <= btrunc (NULL, -1); - - /* write protected */ - ret += 0 <= btrunc (&shortBstring, 2); - ret += 0 <= btrunc (&shortBstring, 0); - ret += 0 <= btrunc (&shortBstring, -1); - - ret += test42_0 (&emptyBstring, 10, ""); - ret += test42_0 (&emptyBstring, 0, ""); - ret += test42_0 (&emptyBstring, -1, NULL); - - ret += test42_0 (&shortBstring, 10, "bogus"); - ret += test42_0 (&shortBstring, 3, "bog"); - ret += test42_0 (&shortBstring, 0, ""); - ret += test42_0 (&shortBstring, -1, NULL); - - printf ("\t# failures: %d\n", ret); - return ret; -} - -static int test43 (void) { -static struct tagbstring ts0 = bsStatic (""); -static struct tagbstring ts1 = bsStatic (" "); -static struct tagbstring ts2 = bsStatic (" abc"); -static struct tagbstring ts3 = bsStatic ("abc "); -static struct tagbstring ts4 = bsStatic (" abc "); -static struct tagbstring ts5 = bsStatic ("abc"); -bstring tstrs[6] = { &ts0, &ts1, &ts2, &ts3, &ts4, &ts5 }; -int ret = 0; -int i; - - printf ("TEST: int btfromblk*trim (struct tagbstring t, void * s, int l);\n"); - - for (i=0; i < 6; i++) { - struct tagbstring t; - bstring b; - - btfromblkltrimws (t, tstrs[i]->data, tstrs[i]->slen); - bltrimws (b = bstrcpy (tstrs[i])); - if (!biseq (b, &t)) { - ret++; - bassign (b, &t); - printf ("btfromblkltrimws failure: <%s> -> <%s>\n", tstrs[i]->data, b->data); - } - printf (".\tbtfromblkltrimws (\"%s\", \"%s\", %d)\n", (char *) bdatae (b, NULL), tstrs[i]->data, tstrs[i]->slen); - bdestroy (b); - - btfromblkrtrimws (t, tstrs[i]->data, tstrs[i]->slen); - brtrimws (b = bstrcpy (tstrs[i])); - if (!biseq (b, &t)) { - ret++; - bassign (b, &t); - printf ("btfromblkrtrimws failure: <%s> -> <%s>\n", tstrs[i]->data, b->data); - } - printf (".\tbtfromblkrtrimws (\"%s\", \"%s\", %d)\n", (char *) bdatae (b, NULL), tstrs[i]->data, tstrs[i]->slen); - bdestroy (b); - - btfromblktrimws (t, tstrs[i]->data, tstrs[i]->slen); - btrimws (b = bstrcpy (tstrs[i])); - if (!biseq (b, &t)) { - ret++; - bassign (b, &t); - printf ("btfromblktrimws failure: <%s> -> <%s>\n", tstrs[i]->data, b->data); - } - printf (".\tbtfromblktrimws (\"%s\", \"%s\", %d)\n", (char *) bdatae (b, NULL), tstrs[i]->data, tstrs[i]->slen); - bdestroy (b); - } - - printf ("\t# failures: %d\n", ret); - return ret; -} - -static int test44_0 (const char * str) { -int ret = 0, v; -bstring b; - if (NULL == str) { - ret += 0 <= bassigncstr (NULL, "test"); - printf (".\tbassigncstr (b = %s, NULL)", dumpBstring (b = bfromcstr (""))); - ret += 0 <= (v = bassigncstr (b, NULL)); - printf (" = %d; b -> %s\n", v, dumpBstring (b)); - ret += 0 <= bassigncstr (&shortBstring, NULL); - bdestroy (b); - return ret; - } - - ret += 0 <= bassigncstr (NULL, str); - printf (".\tbassigncstr (b = %s, \"%s\")", dumpBstring (b = bfromcstr ("")), str); - ret += 0 > (v = bassigncstr (b, str)); - printf (" = %d; b -> %s\n", v, dumpBstring (b)); - ret += 0 != strcmp (bdatae (b, ""), str); - ret += ((size_t) b->slen) != strlen (str); - ret += 0 > bassigncstr (b, "xxxxx"); - bwriteprotect(*b) - printf (".\tbassigncstr (b = %s, \"%s\")", dumpBstring (b), str); - ret += 0 <= (v = bassigncstr (b, str)); - printf (" = %d; b -> %s\n", v, dumpBstring (b)); - ret += 0 != strcmp (bdatae (b, ""), "xxxxx"); - ret += ((size_t) b->slen) != strlen ("xxxxx"); - bwriteallow(*b) - ret += 0 <= bassigncstr (&shortBstring, str); - bdestroy (b); - printf (".\tbassigncstr (a = %s, \"%s\")", dumpBstring (&shortBstring), str); - ret += 0 <= (v = bassigncstr (&shortBstring, str)); - printf (" = %d; a -> %s\n", v, dumpBstring (&shortBstring)); - return ret; -} - -static int test44 (void) { -int ret = 0; - - printf ("TEST: int bassigncstr (bstring a, char * str);\n"); - - /* tests with NULL */ - ret += test44_0 (NULL); - - ret += test44_0 (EMPTY_STRING); - ret += test44_0 (SHORT_STRING); - ret += test44_0 (LONG_STRING); - - printf ("\t# failures: %d\n", ret); - return ret; -} - -static int test45_0 (const char * str) { -int ret = 0, v, len; -bstring b; - if (NULL == str) { - ret += 0 <= bassignblk (NULL, "test", 4); - printf (".\tbassignblk (b = %s, NULL, 1)", dumpBstring (b = bfromcstr (""))); - ret += 0 <= (v = bassignblk (b, NULL, 1)); - printf (" = %d; b -> %s\n", v, dumpBstring (b)); - ret += 0 <= bassignblk (&shortBstring, NULL, 1); - bdestroy (b); - return ret; - } - - len = (int) strlen (str); - ret += 0 <= bassignblk (NULL, str, len); - printf (".\tbassignblk (b = %s, \"%s\", %d)", dumpBstring (b = bfromcstr ("")), str, len); - ret += 0 > (v = bassignblk (b, str, len)); - printf (" = %d; b -> %s\n", v, dumpBstring (b)); - ret += 0 != strcmp (bdatae (b, ""), str); - ret += b->slen != len; - ret += 0 > bassigncstr (b, "xxxxx"); - bwriteprotect(*b) - printf (".\tbassignblk (b = %s, \"%s\", %d)", dumpBstring (b), str, len); - ret += 0 <= (v = bassignblk (b, str, len)); - printf (" = %d; b -> %s\n", v, dumpBstring (b)); - ret += 0 != strcmp (bdatae (b, ""), "xxxxx"); - ret += ((size_t) b->slen) != strlen ("xxxxx"); - bwriteallow(*b) - ret += 0 <= bassignblk (&shortBstring, str, len); - bdestroy (b); - printf (".\tbassignblk (a = %s, \"%s\", %d)", dumpBstring (&shortBstring), str, len); - ret += 0 <= (v = bassignblk (&shortBstring, str, len)); - printf (" = %d; a -> %s\n", v, dumpBstring (&shortBstring)); - return ret; -} - -static int test45 (void) { -int ret = 0; - - printf ("TEST: int bassignblk (bstring a, const void * s, int len);\n"); - - /* tests with NULL */ - ret += test45_0 (NULL); - - ret += test45_0 (EMPTY_STRING); - ret += test45_0 (SHORT_STRING); - ret += test45_0 (LONG_STRING); - - printf ("\t# failures: %d\n", ret); - return ret; -} - -static int test46_0 (const_bstring r, bstring b, int count, const char * fmt, ...) { -int ret; -va_list arglist; - - printf (".\tbvcformata (%s, %d, \"%s\", ...) -> ", dumpBstring (b), count, fmt); - va_start (arglist, fmt); - ret = bvcformata (b, count, fmt, arglist); - va_end (arglist); - printf ("%d, %s (%s)\n", ret, dumpBstring (b), dumpBstring (r)); - if (ret < 0) return (NULL != r); - ret += 1 != biseq (r, b); - if (0 != ret) printf ("\t->failed\n"); - return ret; -} - -static int test46_1 (bstring b, const char * fmt, const_bstring r, ...) { -int ret; - - printf (".\tbvformata (&, %s, \"%s\", ...) -> ", dumpBstring (b), fmt); - bvformata (ret, b, fmt, r); - printf ("%d, %s (%s)\n", ret, dumpBstring (b), dumpBstring (r)); - if (ret < 0) return (NULL != r); - ret += 1 != biseq (r, b); - if (0 != ret) printf ("\t->failed\n"); - return ret; -} - -static int test46 (void) { -bstring b, b2; -int ret = 0; - - printf ("TEST: int bvcformata (bstring b, int count, const char * fmt, va_list arg);\n"); - - ret += test46_0 (NULL, NULL, 8, "[%d]", 15); - ret += test46_0 (NULL, &shortBstring, 8, "[%d]", 15); - ret += test46_0 (NULL, &badBstring1, 8, "[%d]", 15); - ret += test46_0 (NULL, &badBstring2, 8, "[%d]", 15); - ret += test46_0 (NULL, &badBstring3, 8, "[%d]", 15); - - b = bfromcstr (""); - ret += test46_0 (&shortBstring, b, shortBstring.slen, "%s", (char *) shortBstring.data); - b->slen = 0; - ret += test46_0 (&shortBstring, b, shortBstring.slen + 1, "%s", (char *) shortBstring.data); - b->slen = 0; - ret += test46_0 (NULL, b, shortBstring.slen-1, "%s", (char *) shortBstring.data); - - printf ("TEST: bvformata (int &ret, bstring b, const char * fmt, lastarg);\n"); - - ret += test46_1 (NULL, "[%d]", NULL, 15); - ret += test46_1 (&shortBstring, "[%d]", NULL, 15); - ret += test46_1 (&badBstring1, "[%d]", NULL, 15); - ret += test46_1 (&badBstring2, "[%d]", NULL, 15); - ret += test46_1 (&badBstring3, "[%d]", NULL, 15); - - b->slen = 0; - ret += test46_1 (b, "%s", &shortBstring, (char *) shortBstring.data); - - b->slen = 0; - ret += test46_1 (b, "%s", &longBstring, (char *) longBstring.data); - - b->slen = 0; - b2 = bfromcstr (EIGHT_CHAR_STRING); - bconcat (b2, b2); - bconcat (b2, b2); - bconcat (b2, b2); - ret += test46_1 (b, "%s%s%s%s%s%s%s%s", b2, - EIGHT_CHAR_STRING, EIGHT_CHAR_STRING, EIGHT_CHAR_STRING, EIGHT_CHAR_STRING, - EIGHT_CHAR_STRING, EIGHT_CHAR_STRING, EIGHT_CHAR_STRING, EIGHT_CHAR_STRING); - bdestroy (b2); - - bdestroy (b); - printf ("\t# failures: %d\n", ret); - return ret; -} - -int main (int argc, char * argv[]) { -int ret = 0; - - argc = argc; - argv = argv; - - printf ("Direct case testing of bstring core functions\n"); - - ret += test0 (); - ret += test1 (); - ret += test2 (); - ret += test3 (); - ret += test4 (); - ret += test5 (); - ret += test6 (); - ret += test7 (); - ret += test8 (); - ret += test9 (); - ret += test10 (); - ret += test11 (); - ret += test12 (); - ret += test13 (); - ret += test14 (); - ret += test15 (); - ret += test16 (); - ret += test17 (); - ret += test18 (); - ret += test19 (); - ret += test20 (); - ret += test21 (); - ret += test22 (); - ret += test23 (); - ret += test24 (); - ret += test25 (); - ret += test26 (); - ret += test27 (); - ret += test28 (); - ret += test29 (); - ret += test30 (); - ret += test31 (); - ret += test32 (); - ret += test33 (); - ret += test34 (); - ret += test35 (); - ret += test36 (); - ret += test37 (); - ret += test38 (); - ret += test39 (); - ret += test40 (); - ret += test41 (); - ret += test42 (); - ret += test43 (); - ret += test44 (); - ret += test45 (); - ret += test46 (); - ret += test47 (); - ret += test48 (); - - printf ("# test failures: %d\n", ret); - - return 0; -} diff --git a/bstrlib/bstraux.c b/bstrlib/bstraux.c deleted file mode 100644 index ac97836..0000000 --- a/bstrlib/bstraux.c +++ /dev/null @@ -1,1161 +0,0 @@ - -/* - * This source file is part of the bstring string library. This code was - * written by Paul Hsieh in 2002-2015, and is covered by the BSD open source - * license and the GPL. Refer to the accompanying documentation for details - * on usage and license. - */ - -/* - * bstraux.c - * - * This file is not necessarily part of the core bstring library itself, but - * is just an auxilliary module which includes miscellaneous or trivial - * functions. - */ - -#if defined (_MSC_VER) -# define _CRT_SECURE_NO_WARNINGS -#endif - -#include -#include -#include -#include -#include -#include "bstrlib.h" -#include "bstraux.h" - -#ifndef UNUSED -#define UNUSED(x) (void)(x) -#endif - -/* bstring bTail (bstring b, int n) - * - * Return with a string of the last n characters of b. - */ -bstring bTail (bstring b, int n) { - if (b == NULL || n < 0 || (b->mlen < b->slen && b->mlen > 0)) return NULL; - if (n >= b->slen) return bstrcpy (b); - return bmidstr (b, b->slen - n, n); -} - -/* bstring bHead (bstring b, int n) - * - * Return with a string of the first n characters of b. - */ -bstring bHead (bstring b, int n) { - if (b == NULL || n < 0 || (b->mlen < b->slen && b->mlen > 0)) return NULL; - if (n >= b->slen) return bstrcpy (b); - return bmidstr (b, 0, n); -} - -/* int bFill (bstring a, char c, int len) - * - * Fill a given bstring with the character in parameter c, for a length n. - */ -int bFill (bstring b, char c, int len) { - if (b == NULL || len < 0 || (b->mlen < b->slen && b->mlen > 0)) return -__LINE__; - b->slen = 0; - return bsetstr (b, len, NULL, c); -} - -/* int bReplicate (bstring b, int n) - * - * Replicate the contents of b end to end n times and replace it in b. - */ -int bReplicate (bstring b, int n) { - return bpattern (b, n * b->slen); -} - -/* int bReverse (bstring b) - * - * Reverse the contents of b in place. - */ -int bReverse (bstring b) { -int i, n, m; -unsigned char t; - - if (b == NULL || b->slen < 0 || b->mlen < b->slen) return -__LINE__; - n = b->slen; - if (2 <= n) { - m = ((unsigned)n) >> 1; - n--; - for (i=0; i < m; i++) { - t = b->data[n - i]; - b->data[n - i] = b->data[i]; - b->data[i] = t; - } - } - return 0; -} - -/* int bInsertChrs (bstring b, int pos, int len, unsigned char c, unsigned char fill) - * - * Insert a repeated sequence of a given character into the string at - * position pos for a length len. - */ -int bInsertChrs (bstring b, int pos, int len, unsigned char c, unsigned char fill) { - if (b == NULL || b->slen < 0 || b->mlen < b->slen || pos < 0 || len <= 0) return -__LINE__; - - if (pos > b->slen - && 0 > bsetstr (b, pos, NULL, fill)) return -__LINE__; - - if (0 > balloc (b, b->slen + len)) return -__LINE__; - if (pos < b->slen) memmove (b->data + pos + len, b->data + pos, b->slen - pos); - memset (b->data + pos, c, len); - b->slen += len; - b->data[b->slen] = (unsigned char) '\0'; - return BSTR_OK; -} - -/* int bJustifyLeft (bstring b, int space) - * - * Left justify a string. - */ -int bJustifyLeft (bstring b, int space) { -int j, i, s, t; -unsigned char c = (unsigned char) space; - - if (b == NULL || b->slen < 0 || b->mlen < b->slen) return -__LINE__; - if (space != (int) c) return BSTR_OK; - - for (s=j=i=0; i < b->slen; i++) { - t = s; - s = c != (b->data[j] = b->data[i]); - j += (t|s); - } - if (j > 0 && b->data[j-1] == c) j--; - - b->data[j] = (unsigned char) '\0'; - b->slen = j; - return BSTR_OK; -} - -/* int bJustifyRight (bstring b, int width, int space) - * - * Right justify a string to within a given width. - */ -int bJustifyRight (bstring b, int width, int space) { -int ret; - if (width <= 0) return -__LINE__; - if (0 > (ret = bJustifyLeft (b, space))) return ret; - if (b->slen <= width) - return bInsertChrs (b, 0, width - b->slen, (unsigned char) space, (unsigned char) space); - return BSTR_OK; -} - -/* int bJustifyCenter (bstring b, int width, int space) - * - * Center a string's non-white space characters to within a given width by - * inserting whitespaces at the beginning. - */ -int bJustifyCenter (bstring b, int width, int space) { -int ret; - if (width <= 0) return -__LINE__; - if (0 > (ret = bJustifyLeft (b, space))) return ret; - if (b->slen <= width) - return bInsertChrs (b, 0, (width - b->slen + 1) >> 1, (unsigned char) space, (unsigned char) space); - return BSTR_OK; -} - -/* int bJustifyMargin (bstring b, int width, int space) - * - * Stretch a string to flush against left and right margins by evenly - * distributing additional white space between words. If the line is too - * long to be margin justified, it is left justified. - */ -int bJustifyMargin (bstring b, int width, int space) { -struct bstrList * sl; -int i, l, c; - - if (b == NULL || b->slen < 0 || b->mlen == 0 || b->mlen < b->slen) return -__LINE__; - if (NULL == (sl = bsplit (b, (unsigned char) space))) return -__LINE__; - for (l=c=i=0; i < sl->qty; i++) { - if (sl->entry[i]->slen > 0) { - c ++; - l += sl->entry[i]->slen; - } - } - - if (l + c >= width || c < 2) { - bstrListDestroy (sl); - return bJustifyLeft (b, space); - } - - b->slen = 0; - for (i=0; i < sl->qty; i++) { - if (sl->entry[i]->slen > 0) { - if (b->slen > 0) { - int s = (width - l + (c / 2)) / c; - bInsertChrs (b, b->slen, s, (unsigned char) space, (unsigned char) space); - l += s; - } - bconcat (b, sl->entry[i]); - c--; - if (c <= 0) break; - } - } - - bstrListDestroy (sl); - return BSTR_OK; -} - -static size_t readNothing (void *buff, size_t elsize, size_t nelem, void *parm) { - UNUSED(buff); - UNUSED(elsize); - UNUSED(nelem); - UNUSED(parm); - return 0; /* Immediately indicate EOF. */ -} - -/* struct bStream * bsFromBstr (const_bstring b); - * - * Create a bStream whose contents are a copy of the bstring passed in. - * This allows the use of all the bStream APIs with bstrings. - */ -struct bStream * bsFromBstr (const_bstring b) { -struct bStream * s = bsopen ((bNread) readNothing, NULL); - bsunread (s, b); /* Push the bstring data into the empty bStream. */ - return s; -} - -static size_t readRef (void *buff, size_t elsize, size_t nelem, void *parm) { -struct tagbstring * t = (struct tagbstring *) parm; -size_t tsz = elsize * nelem; - - if (tsz > (size_t) t->slen) tsz = (size_t) t->slen; - if (tsz > 0) { - memcpy (buff, t->data, tsz); - t->slen -= (int) tsz; - t->data += tsz; - return tsz / elsize; - } - return 0; -} - -/* The "by reference" version of the above function. This function puts - * a number of restrictions on the call site (the passed in struct - * tagbstring *will* be modified by this function, and the source data - * must remain alive and constant for the lifetime of the bStream). - * Hence it is not presented as an extern. - */ -static struct bStream * bsFromBstrRef (struct tagbstring * t) { - if (!t) return NULL; - return bsopen ((bNread) readRef, t); -} - -/* char * bStr2NetStr (const_bstring b) - * - * Convert a bstring to a netstring. See - * http://cr.yp.to/proto/netstrings.txt for a description of netstrings. - * Note: 1) The value returned should be freed with a call to bcstrfree() at - * the point when it will no longer be referenced to avoid a memory - * leak. - * 2) If the returned value is non-NULL, then it also '\0' terminated - * in the character position one past the "," terminator. - */ -char * bStr2NetStr (const_bstring b) { -char strnum[sizeof (b->slen) * 3 + 1]; -bstring s; -unsigned char * buff; - - if (b == NULL || b->data == NULL || b->slen < 0) return NULL; - sprintf (strnum, "%d:", b->slen); - if (NULL == (s = bfromcstr (strnum)) - || bconcat (s, b) == BSTR_ERR || bconchar (s, (char) ',') == BSTR_ERR) { - bdestroy (s); - return NULL; - } - buff = s->data; - bcstrfree ((char *) s); - return (char *) buff; -} - -/* bstring bNetStr2Bstr (const char * buf) - * - * Convert a netstring to a bstring. See - * http://cr.yp.to/proto/netstrings.txt for a description of netstrings. - * Note that the terminating "," *must* be present, however a following '\0' - * is *not* required. - */ -bstring bNetStr2Bstr (const char * buff) { -int i, x; -bstring b; - if (buff == NULL) return NULL; - x = 0; - for (i=0; buff[i] != ':'; i++) { - unsigned int v = buff[i] - '0'; - if (v > 9 || x > ((INT_MAX - (signed int)v) / 10)) return NULL; - x = (x * 10) + v; - } - - /* This thing has to be properly terminated */ - if (buff[i + 1 + x] != ',') return NULL; - - if (NULL == (b = bfromcstr (""))) return NULL; - if (balloc (b, x + 1) != BSTR_OK) { - bdestroy (b); - return NULL; - } - memcpy (b->data, buff + i + 1, x); - b->data[x] = (unsigned char) '\0'; - b->slen = x; - return b; -} - -static char b64ETable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - -/* bstring bBase64Encode (const_bstring b) - * - * Generate a base64 encoding. See: RFC1341 - */ -bstring bBase64Encode (const_bstring b) { -int i, c0, c1, c2, c3; -bstring out; - - if (b == NULL || b->slen < 0 || b->data == NULL) return NULL; - - out = bfromcstr (""); - for (i=0; i + 2 < b->slen; i += 3) { - if (i && ((i % 57) == 0)) { - if (bconchar (out, (char) '\015') < 0 || bconchar (out, (char) '\012') < 0) { - bdestroy (out); - return NULL; - } - } - c0 = b->data[i] >> 2; - c1 = ((b->data[i] << 4) | - (b->data[i+1] >> 4)) & 0x3F; - c2 = ((b->data[i+1] << 2) | - (b->data[i+2] >> 6)) & 0x3F; - c3 = b->data[i+2] & 0x3F; - if (bconchar (out, b64ETable[c0]) < 0 || - bconchar (out, b64ETable[c1]) < 0 || - bconchar (out, b64ETable[c2]) < 0 || - bconchar (out, b64ETable[c3]) < 0) { - bdestroy (out); - return NULL; - } - } - - if (i && ((i % 57) == 0)) { - if (bconchar (out, (char) '\015') < 0 || bconchar (out, (char) '\012') < 0) { - bdestroy (out); - return NULL; - } - } - - switch (i + 2 - b->slen) { - case 0: c0 = b->data[i] >> 2; - c1 = ((b->data[i] << 4) | - (b->data[i+1] >> 4)) & 0x3F; - c2 = (b->data[i+1] << 2) & 0x3F; - if (bconchar (out, b64ETable[c0]) < 0 || - bconchar (out, b64ETable[c1]) < 0 || - bconchar (out, b64ETable[c2]) < 0 || - bconchar (out, (char) '=') < 0) { - bdestroy (out); - return NULL; - } - break; - case 1: c0 = b->data[i] >> 2; - c1 = (b->data[i] << 4) & 0x3F; - if (bconchar (out, b64ETable[c0]) < 0 || - bconchar (out, b64ETable[c1]) < 0 || - bconchar (out, (char) '=') < 0 || - bconchar (out, (char) '=') < 0) { - bdestroy (out); - return NULL; - } - break; - case 2: break; - } - - return out; -} - -#define B64_PAD (-2) -#define B64_ERR (-1) - -static int base64DecodeSymbol (unsigned char alpha) { - if ((alpha >= 'A') && (alpha <= 'Z')) return (int)(alpha - 'A'); - else if ((alpha >= 'a') && (alpha <= 'z')) - return 26 + (int)(alpha - 'a'); - else if ((alpha >= '0') && (alpha <= '9')) - return 52 + (int)(alpha - '0'); - else if (alpha == '+') return 62; - else if (alpha == '/') return 63; - else if (alpha == '=') return B64_PAD; - else return B64_ERR; -} - -/* bstring bBase64DecodeEx (const_bstring b, int * boolTruncError) - * - * Decode a base64 block of data. All MIME headers are assumed to have been - * removed. See: RFC1341 - */ -bstring bBase64DecodeEx (const_bstring b, int * boolTruncError) { -int i, v; -unsigned char c0, c1, c2; -bstring out; - - if (b == NULL || b->slen < 0 || b->data == NULL) return NULL; - if (boolTruncError) *boolTruncError = 0; - out = bfromcstr (""); - i = 0; - for (;;) { - do { - if (i >= b->slen) return out; - if (b->data[i] == '=') { /* Bad "too early" truncation */ - if (boolTruncError) { - *boolTruncError = 1; - return out; - } - bdestroy (out); - return NULL; - } - v = base64DecodeSymbol (b->data[i]); - i++; - } while (v < 0); - c0 = (unsigned char) (v << 2); - do { - if (i >= b->slen || b->data[i] == '=') { /* Bad "too early" truncation */ - if (boolTruncError) { - *boolTruncError = 1; - return out; - } - bdestroy (out); - return NULL; - } - v = base64DecodeSymbol (b->data[i]); - i++; - } while (v < 0); - c0 |= (unsigned char) (v >> 4); - c1 = (unsigned char) (v << 4); - do { - if (i >= b->slen) { - if (boolTruncError) { - *boolTruncError = 1; - return out; - } - bdestroy (out); - return NULL; - } - if (b->data[i] == '=') { - i++; - if (i >= b->slen || b->data[i] != '=' || bconchar (out, c0) < 0) { - if (boolTruncError) { - *boolTruncError = 1; - return out; - } - bdestroy (out); /* Missing "=" at the end. */ - return NULL; - } - return out; - } - v = base64DecodeSymbol (b->data[i]); - i++; - } while (v < 0); - c1 |= (unsigned char) (v >> 2); - c2 = (unsigned char) (v << 6); - do { - if (i >= b->slen) { - if (boolTruncError) { - *boolTruncError = 1; - return out; - } - bdestroy (out); - return NULL; - } - if (b->data[i] == '=') { - if (bconchar (out, c0) < 0 || bconchar (out, c1) < 0) { - if (boolTruncError) { - *boolTruncError = 1; - return out; - } - bdestroy (out); - return NULL; - } - if (boolTruncError) *boolTruncError = 0; - return out; - } - v = base64DecodeSymbol (b->data[i]); - i++; - } while (v < 0); - c2 |= (unsigned char) (v); - if (bconchar (out, c0) < 0 || - bconchar (out, c1) < 0 || - bconchar (out, c2) < 0) { - if (boolTruncError) { - *boolTruncError = -1; - return out; - } - bdestroy (out); - return NULL; - } - } -} - -#define UU_DECODE_BYTE(b) (((b) == (signed int)'`') ? 0 : (b) - (signed int)' ') - -struct bUuInOut { - bstring src, dst; - int * badlines; -}; - -#define UU_MAX_LINELEN 45 - -static int bUuDecLine (void * parm, int ofs, int len) { -struct bUuInOut * io = (struct bUuInOut *) parm; -bstring s = io->src; -bstring t = io->dst; -int i, llen, otlen, ret, c0, c1, c2, c3, d0, d1, d2, d3; - - if (len == 0) return 0; - llen = UU_DECODE_BYTE (s->data[ofs]); - ret = 0; - - otlen = t->slen; - - if (((unsigned) llen) > UU_MAX_LINELEN) { ret = -__LINE__; - goto bl; - } - - llen += t->slen; - - for (i=1; i < s->slen && t->slen < llen;i += 4) { - unsigned char outoctet[3]; - c0 = UU_DECODE_BYTE (d0 = (int) bchare (s, i+ofs+0, ' ' - 1)); - c1 = UU_DECODE_BYTE (d1 = (int) bchare (s, i+ofs+1, ' ' - 1)); - c2 = UU_DECODE_BYTE (d2 = (int) bchare (s, i+ofs+2, ' ' - 1)); - c3 = UU_DECODE_BYTE (d3 = (int) bchare (s, i+ofs+3, ' ' - 1)); - - if (((unsigned) (c0|c1) >= 0x40)) { if (!ret) ret = -__LINE__; - if (d0 > 0x60 || (d0 < (' ' - 1) && !isspace (d0)) || - d1 > 0x60 || (d1 < (' ' - 1) && !isspace (d1))) { - t->slen = otlen; - goto bl; - } - c0 = c1 = 0; - } - outoctet[0] = (unsigned char) ((c0 << 2) | ((unsigned) c1 >> 4)); - if (t->slen+1 >= llen) { - if (0 > bconchar (t, (char) outoctet[0])) return -__LINE__; - break; - } - if ((unsigned) c2 >= 0x40) { if (!ret) ret = -__LINE__; - if (d2 > 0x60 || (d2 < (' ' - 1) && !isspace (d2))) { - t->slen = otlen; - goto bl; - } - c2 = 0; - } - outoctet[1] = (unsigned char) ((c1 << 4) | ((unsigned) c2 >> 2)); - if (t->slen+2 >= llen) { - if (0 > bcatblk (t, outoctet, 2)) return -__LINE__; - break; - } - if ((unsigned) c3 >= 0x40) { if (!ret) ret = -__LINE__; - if (d3 > 0x60 || (d3 < (' ' - 1) && !isspace (d3))) { - t->slen = otlen; - goto bl; - } - c3 = 0; - } - outoctet[2] = (unsigned char) ((c2 << 6) | ((unsigned) c3)); - if (0 > bcatblk (t, outoctet, 3)) return -__LINE__; - } - if (t->slen < llen) { if (0 == ret) ret = -__LINE__; - t->slen = otlen; - } - bl:; - if (ret && io->badlines) { - (*io->badlines)++; - return 0; - } - return ret; -} - -/* bstring bUuDecodeEx (const_bstring src, int * badlines) - * - * Performs a UUDecode of a block of data. If there are errors in the - * decoding, they are counted up and returned in "badlines", if badlines is - * not NULL. It is assumed that the "begin" and "end" lines have already - * been stripped off. The potential security problem of writing the - * filename in the begin line is something that is beyond the scope of a - * portable library. - */ - -#ifdef _MSC_VER -#pragma warning(disable:4204) -#endif - -bstring bUuDecodeEx (const_bstring src, int * badlines) { -struct tagbstring t; -struct bStream * s; -struct bStream * d; -bstring b; - - if (!src) return NULL; - t = *src; /* Short lifetime alias to header of src */ - s = bsFromBstrRef (&t); /* t is undefined after this */ - if (!s) return NULL; - d = bsUuDecode (s, badlines); - b = bfromcstralloc (256, ""); - if (NULL == b || 0 > bsread (b, d, INT_MAX)) { - bdestroy (b); - b = NULL; - } - bsclose (d); - bsclose (s); - return b; -} - -struct bsUuCtx { - struct bUuInOut io; - struct bStream * sInp; -}; - -static size_t bsUuDecodePart (void *buff, size_t elsize, size_t nelem, void *parm) { -static struct tagbstring eol = bsStatic ("\r\n"); -struct bsUuCtx * luuCtx = (struct bsUuCtx *) parm; -size_t tsz; -int l, lret; - - if (NULL == buff || NULL == parm) return 0; - tsz = elsize * nelem; - - CheckInternalBuffer:; - /* If internal buffer has sufficient data, just output it */ - if (((size_t) luuCtx->io.dst->slen) > tsz) { - memcpy (buff, luuCtx->io.dst->data, tsz); - bdelete (luuCtx->io.dst, 0, (int) tsz); - return nelem; - } - - DecodeMore:; - if (0 <= (l = binchr (luuCtx->io.src, 0, &eol))) { - int ol = 0; - struct tagbstring t; - bstring s = luuCtx->io.src; - luuCtx->io.src = &t; - - do { - if (l > ol) { - bmid2tbstr (t, s, ol, l - ol); - lret = bUuDecLine (&luuCtx->io, 0, t.slen); - if (0 > lret) { - luuCtx->io.src = s; - goto Done; - } - } - ol = l + 1; - if (((size_t) luuCtx->io.dst->slen) > tsz) break; - l = binchr (s, ol, &eol); - } while (BSTR_ERR != l); - bdelete (s, 0, ol); - luuCtx->io.src = s; - goto CheckInternalBuffer; - } - - if (BSTR_ERR != bsreada (luuCtx->io.src, luuCtx->sInp, bsbufflength (luuCtx->sInp, BSTR_BS_BUFF_LENGTH_GET))) { - goto DecodeMore; - } - - bUuDecLine (&luuCtx->io, 0, luuCtx->io.src->slen); - - Done:; - /* Output any lingering data that has been translated */ - if (((size_t) luuCtx->io.dst->slen) > 0) { - if (((size_t) luuCtx->io.dst->slen) > tsz) goto CheckInternalBuffer; - memcpy (buff, luuCtx->io.dst->data, luuCtx->io.dst->slen); - tsz = luuCtx->io.dst->slen / elsize; - luuCtx->io.dst->slen = 0; - if (tsz > 0) return tsz; - } - - /* Deallocate once EOF becomes triggered */ - bdestroy (luuCtx->io.dst); - bdestroy (luuCtx->io.src); - free (luuCtx); - return 0; -} - -/* bStream * bsUuDecode (struct bStream * sInp, int * badlines) - * - * Creates a bStream which performs the UUDecode of an an input stream. If - * there are errors in the decoding, they are counted up and returned in - * "badlines", if badlines is not NULL. It is assumed that the "begin" and - * "end" lines have already been stripped off. The potential security - * problem of writing the filename in the begin line is something that is - * beyond the scope of a portable library. - */ - -struct bStream * bsUuDecode (struct bStream * sInp, int * badlines) { -struct bsUuCtx * luuCtx = (struct bsUuCtx *) malloc (sizeof (struct bsUuCtx)); -struct bStream * sOut; - - if (NULL == luuCtx) return NULL; - - luuCtx->io.src = bfromcstr (""); - luuCtx->io.dst = bfromcstr (""); - if (NULL == luuCtx->io.dst || NULL == luuCtx->io.src) { - CleanUpFailureToAllocate:; - bdestroy (luuCtx->io.dst); - bdestroy (luuCtx->io.src); - free (luuCtx); - return NULL; - } - luuCtx->io.badlines = badlines; - if (badlines) *badlines = 0; - - luuCtx->sInp = sInp; - - sOut = bsopen ((bNread) bsUuDecodePart, luuCtx); - if (NULL == sOut) goto CleanUpFailureToAllocate; - return sOut; -} - -#define UU_ENCODE_BYTE(b) (char) (((b) == 0) ? '`' : ((b) + ' ')) - -/* bstring bUuEncode (const_bstring src) - * - * Performs a UUEncode of a block of data. The "begin" and "end" lines are - * not appended. - */ -bstring bUuEncode (const_bstring src) { -bstring out; -int i, j, jm; -unsigned int c0, c1, c2; - if (src == NULL || src->slen < 0 || src->data == NULL) return NULL; - if ((out = bfromcstr ("")) == NULL) return NULL; - for (i=0; i < src->slen; i += UU_MAX_LINELEN) { - if ((jm = i + UU_MAX_LINELEN) > src->slen) jm = src->slen; - if (bconchar (out, UU_ENCODE_BYTE (jm - i)) < 0) { - bstrFree (out); - break; - } - for (j = i; j < jm; j += 3) { - c0 = (unsigned int) bchar (src, j ); - c1 = (unsigned int) bchar (src, j + 1); - c2 = (unsigned int) bchar (src, j + 2); - if (bconchar (out, UU_ENCODE_BYTE ( (c0 & 0xFC) >> 2)) < 0 || - bconchar (out, UU_ENCODE_BYTE (((c0 & 0x03) << 4) | ((c1 & 0xF0) >> 4))) < 0 || - bconchar (out, UU_ENCODE_BYTE (((c1 & 0x0F) << 2) | ((c2 & 0xC0) >> 6))) < 0 || - bconchar (out, UU_ENCODE_BYTE ( (c2 & 0x3F))) < 0) { - bstrFree (out); - goto End; - } - } - if (bconchar (out, (char) '\r') < 0 || bconchar (out, (char) '\n') < 0) { - bstrFree (out); - break; - } - } - End:; - return out; -} - -/* bstring bYEncode (const_bstring src) - * - * Performs a YEncode of a block of data. No header or tail info is - * appended. See: http://www.yenc.org/whatis.htm and - * http://www.yenc.org/yenc-draft.1.3.txt - */ -bstring bYEncode (const_bstring src) { -int i; -bstring out; -unsigned char c; - - if (src == NULL || src->slen < 0 || src->data == NULL) return NULL; - if ((out = bfromcstr ("")) == NULL) return NULL; - for (i=0; i < src->slen; i++) { - c = (unsigned char)(src->data[i] + 42); - if (c == '=' || c == '\0' || c == '\r' || c == '\n') { - if (0 > bconchar (out, (char) '=')) { - bdestroy (out); - return NULL; - } - c += (unsigned char) 64; - } - if (0 > bconchar (out, c)) { - bdestroy (out); - return NULL; - } - } - return out; -} - -/* bstring bYDecode (const_bstring src) - * - * Performs a YDecode of a block of data. See: - * http://www.yenc.org/whatis.htm and http://www.yenc.org/yenc-draft.1.3.txt - */ -#define MAX_OB_LEN (64) - -bstring bYDecode (const_bstring src) { -int i; -bstring out; -unsigned char c; -unsigned char octetbuff[MAX_OB_LEN]; -int obl; - - if (src == NULL || src->slen < 0 || src->data == NULL) return NULL; - if ((out = bfromcstr ("")) == NULL) return NULL; - - obl = 0; - - for (i=0; i < src->slen; i++) { - if ('=' == (c = src->data[i])) { /* The = escape mode */ - i++; - if (i >= src->slen) { - bdestroy (out); - return NULL; - } - c = (unsigned char) (src->data[i] - 64); - } else { - if ('\0' == c) { - bdestroy (out); - return NULL; - } - - /* Extraneous CR/LFs are to be ignored. */ - if (c == '\r' || c == '\n') continue; - } - - octetbuff[obl] = (unsigned char) ((int) c - 42); - obl++; - - if (obl >= MAX_OB_LEN) { - if (0 > bcatblk (out, octetbuff, obl)) { - bdestroy (out); - return NULL; - } - obl = 0; - } - } - - if (0 > bcatblk (out, octetbuff, obl)) { - bdestroy (out); - out = NULL; - } - return out; -} - -/* int bSGMLEncode (bstring b) - * - * Change the string into a version that is quotable in SGML (HTML, XML). - */ -int bSGMLEncode (bstring b) { -static struct tagbstring fr[4][2] = { - { bsStatic("&"), bsStatic("&") }, - { bsStatic("\""), bsStatic(""") }, - { bsStatic("<"), bsStatic("<") }, - { bsStatic(">"), bsStatic(">") } }; -int i; - for (i = 0; i < 4; i++) { - int ret = bfindreplace (b, &fr[i][0], &fr[i][1], 0); - if (0 > ret) return ret; - } - return 0; -} - -/* bstring bStrfTime (const char * fmt, const struct tm * timeptr) - * - * Takes a format string that is compatible with strftime and a struct tm - * pointer, formats the time according to the format string and outputs - * the bstring as a result. Note that if there is an early generation of a - * '\0' character, the bstring will be truncated to this end point. - */ -bstring bStrfTime (const char * fmt, const struct tm * timeptr) { -#if defined (__TURBOC__) && !defined (__BORLANDC__) -static struct tagbstring ns = bsStatic ("bStrfTime Not supported"); - fmt = fmt; - timeptr = timeptr; - return &ns; -#else -bstring buff; -int n; -size_t r; - - if (fmt == NULL) return NULL; - - /* Since the length is not determinable beforehand, a search is - performed using the truncating "strftime" call on increasing - potential sizes for the output result. */ - - if ((n = (int) (2*strlen (fmt))) < 16) n = 16; - buff = bfromcstralloc (n+2, ""); - - for (;;) { - if (BSTR_OK != balloc (buff, n + 2)) { - bdestroy (buff); - return NULL; - } - - r = strftime ((char *) buff->data, n + 1, fmt, timeptr); - - if (r > 0) { - buff->slen = (int) r; - break; - } - - n += n; - } - - return buff; -#endif -} - -/* int bSetCstrChar (bstring a, int pos, char c) - * - * Sets the character at position pos to the character c in the bstring a. - * If the character c is NUL ('\0') then the string is truncated at this - * point. Note: this does not enable any other '\0' character in the bstring - * as terminator indicator for the string. pos must be in the position - * between 0 and b->slen inclusive, otherwise BSTR_ERR will be returned. - */ -int bSetCstrChar (bstring b, int pos, char c) { - if (NULL == b || b->mlen <= 0 || b->slen < 0 || b->mlen < b->slen) - return BSTR_ERR; - if (pos < 0 || pos > b->slen) return BSTR_ERR; - - if (pos == b->slen) { - if ('\0' != c) return bconchar (b, c); - return 0; - } - - b->data[pos] = (unsigned char) c; - if ('\0' == c) b->slen = pos; - - return 0; -} - -/* int bSetChar (bstring b, int pos, char c) - * - * Sets the character at position pos to the character c in the bstring a. - * The string is not truncated if the character c is NUL ('\0'). pos must - * be in the position between 0 and b->slen inclusive, otherwise BSTR_ERR - * will be returned. - */ -int bSetChar (bstring b, int pos, char c) { - if (NULL == b || b->mlen <= 0 || b->slen < 0 || b->mlen < b->slen) - return BSTR_ERR; - if (pos < 0 || pos > b->slen) return BSTR_ERR; - - if (pos == b->slen) { - return bconchar (b, c); - } - - b->data[pos] = (unsigned char) c; - return 0; -} - -#define INIT_SECURE_INPUT_LENGTH (256) - -/* bstring bSecureInput (int maxlen, int termchar, - * bNgetc vgetchar, void * vgcCtx) - * - * Read input from an abstracted input interface, for a length of at most - * maxlen characters. If maxlen <= 0, then there is no length limit put - * on the input. The result is terminated early if vgetchar() return EOF - * or the user specified value termchar. - * - */ -bstring bSecureInput (int maxlen, int termchar, bNgetc vgetchar, void * vgcCtx) { -int i, m, c; -bstring b, t; - - if (!vgetchar) return NULL; - - b = bfromcstralloc (INIT_SECURE_INPUT_LENGTH, ""); - if ((c = UCHAR_MAX + 1) == termchar) c++; - - for (i=0; ; i++) { - if (termchar == c || (maxlen > 0 && i >= maxlen)) break; - c = vgetchar (vgcCtx); - if (EOF == c) break; - - if (i+1 >= b->mlen) { - - /* Double size, and deal with numeric overflows */ - - if (b->mlen <= INT_MAX / 2) m = b->mlen << 1; - else if (b->mlen <= INT_MAX - 1024) m = b->mlen + 1024; - else if (b->mlen <= INT_MAX - 16) m = b->mlen + 16; - else if (b->mlen <= INT_MAX - 1) m = b->mlen + 1; - else { - bSecureDestroy (b); /* Cleanse partial buffer */ - return NULL; - } - - t = bfromcstrrangealloc (b->mlen + 1, m, ""); - if (t) memcpy (t->data, b->data, i); - bSecureDestroy (b); /* Cleanse previous buffer */ - b = t; - if (!b) return b; - } - - b->data[i] = (unsigned char) c; - } - - b->slen = i; - b->data[i] = (unsigned char) '\0'; - return b; -} - -#define BWS_BUFF_SZ (1024) - -struct bwriteStream { - bstring buff; /* Buffer for underwrites */ - void * parm; /* The stream handle for core stream */ - bNwrite writeFn; /* fwrite work-a-like fnptr for core stream */ - int isEOF; /* track stream's EOF state */ - int minBuffSz; -}; - -/* struct bwriteStream * bwsOpen (bNwrite writeFn, void * parm) - * - * Wrap a given open stream (described by a fwrite work-a-like function - * pointer and stream handle) into an open bwriteStream suitable for write - * streaming functions. - */ -struct bwriteStream * bwsOpen (bNwrite writeFn, void * parm) { -struct bwriteStream * ws; - - if (NULL == writeFn) return NULL; - ws = (struct bwriteStream *) malloc (sizeof (struct bwriteStream)); - if (ws) { - if (NULL == (ws->buff = bfromcstr (""))) { - free (ws); - ws = NULL; - } else { - ws->parm = parm; - ws->writeFn = writeFn; - ws->isEOF = 0; - ws->minBuffSz = BWS_BUFF_SZ; - } - } - return ws; -} - -#define internal_bwswriteout(ws,b) { \ - if ((b)->slen > 0) { \ - if (1 != (ws->writeFn ((b)->data, (b)->slen, 1, ws->parm))) { \ - ws->isEOF = 1; \ - return BSTR_ERR; \ - } \ - } \ -} - -/* int bwsWriteFlush (struct bwriteStream * ws) - * - * Force any pending data to be written to the core stream. - */ -int bwsWriteFlush (struct bwriteStream * ws) { - if (NULL == ws || ws->isEOF || 0 >= ws->minBuffSz || - NULL == ws->writeFn || NULL == ws->buff) return BSTR_ERR; - internal_bwswriteout (ws, ws->buff); - ws->buff->slen = 0; - return 0; -} - -/* int bwsWriteBstr (struct bwriteStream * ws, const_bstring b) - * - * Send a bstring to a bwriteStream. If the stream is at EOF BSTR_ERR is - * returned. Note that there is no deterministic way to determine the exact - * cut off point where the core stream stopped accepting data. - */ -int bwsWriteBstr (struct bwriteStream * ws, const_bstring b) { -struct tagbstring t; -int l; - - if (NULL == ws || NULL == b || NULL == ws->buff || - ws->isEOF || 0 >= ws->minBuffSz || NULL == ws->writeFn) - return BSTR_ERR; - - /* Buffer prepacking optimization */ - if (b->slen > 0 && ws->buff->mlen - ws->buff->slen > b->slen) { - static struct tagbstring empty = bsStatic (""); - if (0 > bconcat (ws->buff, b)) return BSTR_ERR; - return bwsWriteBstr (ws, &empty); - } - - if (0 > (l = ws->minBuffSz - ws->buff->slen)) { - internal_bwswriteout (ws, ws->buff); - ws->buff->slen = 0; - l = ws->minBuffSz; - } - - if (b->slen < l) return bconcat (ws->buff, b); - - if (0 > bcatblk (ws->buff, b->data, l)) return BSTR_ERR; - internal_bwswriteout (ws, ws->buff); - ws->buff->slen = 0; - - bmid2tbstr (t, (bstring) b, l, b->slen); - - if (t.slen >= ws->minBuffSz) { - internal_bwswriteout (ws, &t); - return 0; - } - - return bassign (ws->buff, &t); -} - -/* int bwsWriteBlk (struct bwriteStream * ws, void * blk, int len) - * - * Send a block of data a bwriteStream. If the stream is at EOF BSTR_ERR is - * returned. - */ -int bwsWriteBlk (struct bwriteStream * ws, void * blk, int len) { -struct tagbstring t; - if (NULL == blk || len < 0) return BSTR_ERR; - blk2tbstr (t, blk, len); - return bwsWriteBstr (ws, &t); -} - -/* int bwsIsEOF (const struct bwriteStream * ws) - * - * Returns 0 if the stream is currently writable, 1 if the core stream has - * responded by not accepting the previous attempted write. - */ -int bwsIsEOF (const struct bwriteStream * ws) { - if (NULL == ws || NULL == ws->buff || 0 > ws->minBuffSz || - NULL == ws->writeFn) return BSTR_ERR; - return ws->isEOF; -} - -/* int bwsBuffLength (struct bwriteStream * ws, int sz) - * - * Set the length of the buffer used by the bwsStream. If sz is zero, the - * length is not set. This function returns with the previous length. - */ -int bwsBuffLength (struct bwriteStream * ws, int sz) { -int oldSz; - if (ws == NULL || sz < 0) return BSTR_ERR; - oldSz = ws->minBuffSz; - if (sz > 0) ws->minBuffSz = sz; - return oldSz; -} - -/* void * bwsClose (struct bwriteStream * s) - * - * Close the bwriteStream, and return the handle to the stream that was - * originally used to open the given stream. Note that even if the stream - * is at EOF it still needs to be closed with a call to bwsClose. - */ -void * bwsClose (struct bwriteStream * ws) { -void * parm; - if (NULL == ws || NULL == ws->buff || 0 >= ws->minBuffSz || - NULL == ws->writeFn) return NULL; - bwsWriteFlush (ws); - parm = ws->parm; - ws->parm = NULL; - ws->minBuffSz = -1; - ws->writeFn = NULL; - bstrFree (ws->buff); - free (ws); - return parm; -} diff --git a/bstrlib/bstraux.h b/bstrlib/bstraux.h deleted file mode 100644 index 9f30e3c..0000000 --- a/bstrlib/bstraux.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * This source file is part of the bstring string library. This code was - * written by Paul Hsieh in 2002-2015, and is covered by the BSD open source - * license and the GPL. Refer to the accompanying documentation for details - * on usage and license. - */ - -/* - * bstraux.h - * - * This file is not a necessary part of the core bstring library itself, but - * is just an auxilliary module which includes miscellaneous or trivial - * functions. - */ - -#ifndef BSTRAUX_INCLUDE -#define BSTRAUX_INCLUDE - -#include -#include "bstrlib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* Safety mechanisms */ -#define bstrDeclare(b) bstring (b) = NULL; -#define bstrFree(b) {if ((b) != NULL && (b)->slen >= 0 && (b)->mlen >= (b)->slen) { bdestroy (b); (b) = NULL; }} - -/* Backward compatibilty with previous versions of Bstrlib */ -#if !defined(BSTRLIB_REDUCE_NAMESPACE_POLLUTION) -#define bAssign(a,b) ((bassign)((a), (b))) -#define bSubs(b,pos,len,a,c) ((breplace)((b),(pos),(len),(a),(unsigned char)(c))) -#define bStrchr(b,c) ((bstrchr)((b), (c))) -#define bStrchrFast(b,c) ((bstrchr)((b), (c))) -#define bCatCstr(b,s) ((bcatcstr)((b), (s))) -#define bCatBlk(b,s,len) ((bcatblk)((b),(s),(len))) -#define bCatStatic(b,s) bcatStatic(b,s) -#define bTrunc(b,n) ((btrunc)((b), (n))) -#define bReplaceAll(b,find,repl,pos) ((bfindreplace)((b),(find),(repl),(pos))) -#define bUppercase(b) ((btoupper)(b)) -#define bLowercase(b) ((btolower)(b)) -#define bCaselessCmp(a,b) ((bstricmp)((a), (b))) -#define bCaselessNCmp(a,b,n) ((bstrnicmp)((a), (b), (n))) -#define bBase64Decode(b) (bBase64DecodeEx ((b), NULL)) -#define bUuDecode(b) (bUuDecodeEx ((b), NULL)) -#endif - -/* Unusual functions */ -extern struct bStream * bsFromBstr (const_bstring b); -extern bstring bTail (bstring b, int n); -extern bstring bHead (bstring b, int n); -extern int bSetCstrChar (bstring a, int pos, char c); -extern int bSetChar (bstring b, int pos, char c); -extern int bFill (bstring a, char c, int len); -extern int bReplicate (bstring b, int n); -extern int bReverse (bstring b); -extern int bInsertChrs (bstring b, int pos, int len, unsigned char c, unsigned char fill); -extern bstring bStrfTime (const char * fmt, const struct tm * timeptr); -#define bAscTime(t) (bStrfTime ("%c\n", (t))) -#define bCTime(t) ((t) ? bAscTime (localtime (t)) : NULL) - -/* Spacing formatting */ -extern int bJustifyLeft (bstring b, int space); -extern int bJustifyRight (bstring b, int width, int space); -extern int bJustifyMargin (bstring b, int width, int space); -extern int bJustifyCenter (bstring b, int width, int space); - -/* Esoteric standards specific functions */ -extern char * bStr2NetStr (const_bstring b); -extern bstring bNetStr2Bstr (const char * buf); -extern bstring bBase64Encode (const_bstring b); -extern bstring bBase64DecodeEx (const_bstring b, int * boolTruncError); -extern struct bStream * bsUuDecode (struct bStream * sInp, int * badlines); -extern bstring bUuDecodeEx (const_bstring src, int * badlines); -extern bstring bUuEncode (const_bstring src); -extern bstring bYEncode (const_bstring src); -extern bstring bYDecode (const_bstring src); -extern int bSGMLEncode (bstring b); - -/* Writable stream */ -typedef int (* bNwrite) (const void * buf, size_t elsize, size_t nelem, void * parm); - -struct bwriteStream * bwsOpen (bNwrite writeFn, void * parm); -int bwsWriteBstr (struct bwriteStream * stream, const_bstring b); -int bwsWriteBlk (struct bwriteStream * stream, void * blk, int len); -int bwsWriteFlush (struct bwriteStream * stream); -int bwsIsEOF (const struct bwriteStream * stream); -int bwsBuffLength (struct bwriteStream * stream, int sz); -void * bwsClose (struct bwriteStream * stream); - -/* Security functions */ -#define bSecureDestroy(b) { \ -bstring bstr__tmp = (b); \ - if (bstr__tmp && bstr__tmp->mlen > 0 && bstr__tmp->data) { \ - (void) memset (bstr__tmp->data, 0, (size_t) bstr__tmp->mlen); \ - bdestroy (bstr__tmp); \ - } \ -} -#define bSecureWriteProtect(t) { \ - if ((t).mlen >= 0) { \ - if ((t).mlen > (t).slen)) { \ - (void) memset ((t).data + (t).slen, 0, (size_t) (t).mlen - (t).slen); \ - } \ - (t).mlen = -1; \ - } \ -} -extern bstring bSecureInput (int maxlen, int termchar, - bNgetc vgetchar, void * vgcCtx); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/bstrlib/bstrlib.txt b/bstrlib/bstrlib.txt deleted file mode 100644 index 9d2231b..0000000 --- a/bstrlib/bstrlib.txt +++ /dev/null @@ -1,3512 +0,0 @@ -Better String library ---------------------- - -by Paul Hsieh - -The bstring library is an attempt to provide improved string processing -functionality to the C and C++ language. At the heart of the bstring library -(Bstrlib for short) is the management of "bstring"s which are a significant -improvement over '\0' terminated char buffers. - -=============================================================================== - -Motivation ----------- - -The standard C string library has serious problems: - - 1) Its use of '\0' to denote the end of the string means knowing a - string's length is O(n) when it could be O(1). - 2) It imposes an interpretation for the character value '\0'. - 3) gets() always exposes the application to a buffer overflow. - 4) strtok() modifies the string its parsing and thus may not be usable in - programs which are re-entrant or multithreaded. - 5) fgets has the unusual semantic of ignoring '\0's that occur before - '\n's are consumed. - 6) There is no memory management, and actions performed such as strcpy, - strcat and sprintf are common places for buffer overflows. - 7) strncpy() doesn't '\0' terminate the destination in some cases. - 8) Passing NULL to C library string functions causes an undefined NULL - pointer access. - 9) Parameter aliasing (overlapping, or self-referencing parameters) - within most C library functions has undefined behavior. - 10) Many C library string function calls take integer parameters with - restricted legal ranges. Parameters passed outside these ranges are - not typically detected and cause undefined behavior. - -So the desire is to create an alternative string library that does not suffer -from the above problems and adds in the following functionality: - - 1) Incorporate string functionality seen from other languages. - a) MID$() - from BASIC - b) split()/join() - from Python - c) string/char x n - from Perl - 2) Implement analogs to functions that combine stream IO and char buffers - without creating a dependency on stream IO functionality. - 3) Implement the basic text editor-style functions insert, delete, find, - and replace. - 4) Implement reference based sub-string access (as a generalization of - pointer arithmetic.) - 5) Implement runtime write protection for strings. - -There is also a desire to avoid "API-bloat". So functionality that can be -implemented trivially in other functionality is omitted. So there is no -left$() or right$() or reverse() or anything like that as part of the core -functionality. - -Explaining Bstrings -------------------- - -A bstring is basically a header which wraps a pointer to a char buffer. Lets -start with the declaration of a struct tagbstring: - - struct tagbstring { - int mlen; - int slen; - unsigned char * data; - }; - -This definition is considered exposed, not opaque (though it is neither -necessary nor recommended that low level maintenance of bstrings be performed -whenever the abstract interfaces are sufficient). The mlen field (usually) -describes a lower bound for the memory allocated for the data field. The -slen field describes the exact length for the bstring. The data field is a -single contiguous buffer of unsigned chars. Note that the existence of a '\0' -character in the unsigned char buffer pointed to by the data field does not -necessarily denote the end of the bstring. - -To be a well formed modifiable bstring the mlen field must be at least the -length of the slen field, and slen must be non-negative. Furthermore, the -data field must point to a valid buffer in which access to the first mlen -characters has been acquired. So the minimal check for correctness is: - - (slen >= 0 && mlen >= slen && data != NULL) - -bstrings returned by bstring functions can be assumed to be either NULL or -satisfy the above property. (When bstrings are only readable, the mlen >= -slen restriction is not required; this is discussed later in this section.) -A bstring itself is just a pointer to a struct tagbstring: - - typedef struct tagbstring * bstring; - -Note that use of the prefix "tag" in struct tagbstring is required to work -around the inconsistency between C and C++'s struct namespace usage. This -definition is also considered exposed. - -Bstrlib basically manages bstrings allocated as a header and an associated -data-buffer. Since the implementation is exposed, they can also be -constructed manually. Functions which mutate bstrings assume that the header -and data buffer have been malloced; the bstring library may perform free() or -realloc() on both the header and data buffer of any bstring parameter. -Functions which return bstring's create new bstrings. The string memory is -freed by a bdestroy() call (or using the bstrFree macro). - -The following related typedef is also provided: - - typedef const struct tagbstring * const_bstring; - -which is also considered exposed. These are directly bstring compatible (no -casting required) but are just used for parameters which are meant to be -non-mutable. So in general, bstring parameters which are read as input but -not meant to be modified will be declared as const_bstring, and bstring -parameters which may be modified will be declared as bstring. This convention -is recommended for user written functions as well. - -Since bstrings maintain interoperability with C library char-buffer style -strings, all functions which modify, update or create bstrings also append a -'\0' character into the position slen + 1. This trailing '\0' character is -not required for bstrings input to the bstring functions; this is provided -solely as a convenience for interoperability with standard C char-buffer -functionality. - -Analogs for the ANSI C string library functions have been created when they -are necessary, but have also been left out when they are not. In particular -there are no functions analogous to fwrite, or puts just for the purposes of -bstring. The ->data member of any string is exposed, and therefore can be -used just as easily as char buffers for C functions which read strings. - -For those that wish to hand construct bstrings, the following should be kept -in mind: - - 1) While bstrlib can accept constructed bstrings without terminating - '\0' characters, the rest of the C language string library will not - function properly on such non-terminated strings. This is obvious - but must be kept in mind. - 2) If it is intended that a constructed bstring be written to by the - bstring library functions then the data portion should be allocated - by the malloc function and the slen and mlen fields should be entered - properly. The struct tagbstring header is not reallocated, and only - freed by bdestroy. - 3) Writing arbitrary '\0' characters at various places in the string - will not modify its length as perceived by the bstring library - functions. In fact, '\0' is a legitimate non-terminating character - for a bstring to contain. - 4) For read only parameters, bstring functions do not check the mlen. - I.e., the minimal correctness requirements are reduced to: - - (slen >= 0 && data != NULL) - -Better pointer arithmetic -------------------------- - -One built-in feature of '\0' terminated char * strings, is that its very easy -and fast to obtain a reference to the tail of any string using pointer -arithmetic. Bstrlib does one better by providing a way to get a reference to -any substring of a bstring (or any other length delimited block of memory.) -So rather than just having pointer arithmetic, with bstrlib one essentially -has segment arithmetic. This is achieved using the macro blk2tbstr() which -builds a reference to a block of memory and the macro bmid2tbstr() which -builds a reference to a segment of a bstring. Bstrlib also includes -functions for direct consumption of memory blocks into bstrings, namely -bcatblk () and blk2bstr (). - -One scenario where this can be extremely useful is when string contains many -substrings which one would like to pass as read-only reference parameters to -some string consuming function without the need to allocate entire new -containers for the string data. More concretely, imagine parsing a command -line string whose parameters are space delimited. This can only be done for -tails of the string with '\0' terminated char * strings. - -Improved NULL semantics and error handling ------------------------------------------- - -Unless otherwise noted, if a NULL pointer is passed as a bstring or any other -detectably illegal parameter, the called function will return with an error -indicator (either NULL or BSTR_ERR) rather than simply performing a NULL -pointer access, or having undefined behavior. - -To illustrate the value of this, consider the following example: - - strcpy (p = malloc (13 * sizeof (char)), "Hello,"); - strcat (p, " World"); - -This is not correct because malloc may return NULL (due to an out of memory -condition), and the behaviour of strcpy is undefined if either of its -parameters are NULL. However: - - bstrcat (p = bfromcstr ("Hello,"), q = bfromcstr (" World")); - bdestroy (q); - -is well defined, because if either p or q are assigned NULL (indicating a -failure to allocate memory) both bstrcat and bdestroy will recognize it and -perform no detrimental action. - -Note that it is not necessary to check any of the members of a returned -bstring for internal correctness (in particular the data member does not need -to be checked against NULL when the header is non-NULL), since this is -assured by the bstring library itself. - -bStreams --------- - -In addition to the bgets and bread functions, bstrlib can abstract streams -with a high performance read only stream called a bStream. In general, the -idea is to open a core stream (with something like fopen) then pass its -handle as well as a bNread function pointer (like fread) to the bsopen -function which will return a handle to an open bStream. Then the functions -bsread, bsreadln or bsreadlns can be called to read portions of the stream. -Finally, the bsclose function is called to close the bStream -- it will -return a handle to the original (core) stream. So bStreams, essentially, -wrap other streams. - -The bStreams have two main advantages over the bgets and bread (as well as -fgets/ungetc) paradigms: - -1) Improved functionality via the bunread function which allows a stream to - unread characters, giving the bStream stack-like functionality if so - desired. -2) A very high performance bsreadln function. The C library function fgets() - (and the bgets function) can typically be written as a loop on top of - fgetc(), thus paying all of the overhead costs of calling fgetc on a per - character basis. bsreadln will read blocks at a time, thus amortizing the - overhead of fread calls over many characters at once. - -However, clearly bStreams are suboptimal or unusable for certain kinds of -streams (stdin) or certain usage patterns (a few spotty, or non-sequential -reads from a slow stream.) For those situations, using bgets will be more -appropriate. - -The semantics of bStreams allows practical construction of layerable data -streams. What this means is that by writing a bNread compatible function on -top of a bStream, one can construct a new bStream on top of it. This can be -useful for writing multi-pass parsers that don't actually read the entire -input more than once and don't require the use of intermediate storage. - -Aliasing --------- - -Aliasing occurs when a function is given two parameters which point to data -structures which overlap in the memory they occupy. While this does not -disturb read only functions, for many libraries this can make functions that -write to these memory locations malfunction. This is a common problem of the -C standard library and especially the string functions in the C standard -library. - -The C standard string library is entirely char by char oriented (as is -bstring) which makes conforming implementations alias safe for some -scenarios. However no actual detection of aliasing is typically performed, -so it is easy to find cases where the aliasing will cause anomolous or -undesirable behaviour (consider: strcat (p, p).) The C99 standard includes -the "restrict" pointer modifier which allows the compiler to document and -assume a no-alias condition on usage. However, only the most trivial cases -can be caught (if at all) by the compiler at compile time, and thus there is -no actual enforcement of non-aliasing. - -Bstrlib, by contrast, permits aliasing and is completely aliasing safe, in -the C99 sense of aliasing. That is to say, under the assumption that -pointers of incompatible types from distinct objects can never alias, bstrlib -is completely aliasing safe. (In practice this means that the data buffer -portion of any bstring and header of any bstring are assumed to never alias.) -With the exception of the reference building macros, the library behaves as -if all read-only parameters are first copied and replaced by temporary -non-aliased parameters before any writing to any output bstring is performed -(though actual copying is extremely rarely ever done.) - -Besides being a useful safety feature, bstring searching/comparison -functions can improve to O(1) execution when aliasing is detected. - -Note that aliasing detection and handling code in Bstrlib is generally -extremely cheap. There is almost never any appreciable performance penalty -for using aliased parameters. - -Reenterancy ------------ - -Nearly every function in Bstrlib is a leaf function, and is completely -reenterable with the exception of writing to common bstrings. The split -functions which use a callback mechanism requires only that the source string -not be destroyed by the callback function unless the callback function returns -with an error status (note that Bstrlib functions which return an error do -not modify the string in any way.) The string can in fact be modified by the -callback and the behaviour is deterministic. See the documentation of the -various split functions for more details. - -Undefined scenarios -------------------- - -One of the basic important premises for Bstrlib is to not to increase the -propogation of undefined situations from parameters that are otherwise legal -in of themselves. In particular, except for extremely marginal cases, usages -of bstrings that use the bstring library functions alone cannot lead to any -undefined action. But due to C/C++ language and library limitations, there -is no way to define a non-trivial library that is completely without -undefined operations. All such possible undefined operations are described -below: - -1) bstrings or struct tagbstrings that are not explicitely initialized cannot - be passed as a parameter to any bstring function. -2) The members of the NULL bstring cannot be accessed directly. (Though all - APIs and macros detect the NULL bstring.) -3) A bstring whose data member has not been obtained from a malloc or - compatible call and which is write accessible passed as a writable - parameter will lead to undefined results. (i.e., do not writeAllow any - constructed bstrings unless the data portion has been obtained from the - heap.) -4) If the headers of two strings alias but are not identical (which can only - happen via a defective manual construction), then passing them to a - bstring function in which one is writable is not defined. -5) If the mlen member is larger than the actual accessible length of the data - member for a writable bstring, or if the slen member is larger than the - readable length of the data member for a readable bstring, then the - corresponding bstring operations are undefined. -6) Any bstring definition whose header or accessible data portion has been - assigned to inaccessible or otherwise illegal memory clearly cannot be - acted upon by the bstring library in any way. -7) Destroying the source of an incremental split from within the callback - and not returning with a negative value (indicating that it should abort) - will lead to undefined behaviour. (Though *modifying* or adjusting the - state of the source data, even if those modification fail within the - bstrlib API, has well defined behavior.) -8) Modifying a bstring which is write protected by direct access has - undefined behavior. - -While this may seem like a long list, with the exception of invalid uses of -the writeAllow macro, and source destruction during an iterative split -without an accompanying abort, no usage of the bstring API alone can cause -any undefined scenario to occurr. I.e., the policy of restricting usage of -bstrings to the bstring API can significantly reduce the risk of runtime -errors (in practice it should eliminate them) related to string manipulation -due to undefined action. - -C++ wrapper ------------ - -A C++ wrapper has been created to enable bstring functionality for C++ in the -most natural (for C++ programers) way possible. The mandate for the C++ -wrapper is different from the base C bstring library. Since the C++ language -has far more abstracting capabilities, the CBString structure is considered -fully abstracted -- i.e., hand generated CBStrings are not supported (though -conversion from a struct tagbstring is allowed) and all detectable errors are -manifest as thrown exceptions. - -- The C++ class definitions are all under the namespace Bstrlib. bstrwrap.h - enables this namespace (with a using namespace Bstrlib; directive at the - end) unless the macro BSTRLIB_DONT_ASSUME_NAMESPACE has been defined before - it is included. - -- Erroneous accesses results in an exception being thrown. The exception - parameter is of type "struct CBStringException" which is derived from - std::exception if STL is used. A verbose description of the error message - can be obtained from the what() method. - -- CBString is a C++ structure derived from a struct tagbstring. An address - of a CBString cast to a bstring must not be passed to bdestroy. The bstring - C API has been made C++ safe and can be used directly in a C++ project. - -- It includes constructors which can take a char, '\0' terminated char - buffer, tagbstring, (char, repeat-value), a length delimited buffer or a - CBStringList to initialize it. - -- Concatenation is performed with the + and += operators. Comparisons are - done with the ==, !=, <, >, <= and >= operators. Note that == and != use - the biseq call, while <, >, <= and >= use bstrcmp. - -- CBString's can be directly cast to const character buffers. - -- CBString's can be directly cast to double, float, int or unsigned int so - long as the CBString are decimal representations of those types (otherwise - an exception will be thrown). Converting the other way should be done with - the format(a) method(s). - -- CBString contains the length, character and [] accessor methods. The - character and [] accessors are aliases of each other. If the bounds for - the string are exceeded, an exception is thrown. To avoid the overhead for - this check, first cast the CBString to a (const char *) and use [] to - dereference the array as normal. Note that the character and [] accessor - methods allows both reading and writing of individual characters. - -- The methods: format, formata, find, reversefind, findcaseless, - reversefindcaseless, midstr, insert, insertchrs, replace, findreplace, - findreplacecaseless, remove, findchr, nfindchr, alloc, toupper, tolower, - gets, read are analogous to the functions that can be found in the C API. - -- The caselessEqual and caselessCmp methods are analogous to biseqcaseless - and bstricmp functions respectively. - -- Note that just like the bformat function, the format and formata methods do - not automatically cast CBStrings into char * strings for "%s"-type - substitutions: - - CBString w("world"); - CBString h("Hello"); - CBString hw; - - /* The casts are necessary */ - hw.format ("%s, %s", (const char *)h, (const char *)w); - -- The methods trunc and repeat have been added instead of using pattern. - -- ltrim, rtrim and trim methods have been added. These remove characters - from a given character string set (defaulting to the whitespace characters) - from either the left, right or both ends of the CBString, respectively. - -- The method setsubstr is also analogous in functionality to bsetstr, except - that it cannot be passed NULL. Instead the method fill and the fill-style - constructor have been supplied to enable this functionality. - -- The writeprotect(), writeallow() and iswriteprotected() methods are - analogous to the bwriteprotect(), bwriteallow() and biswriteprotected() - macros in the C API. Write protection semantics in CBString are stronger - than with the C API in that indexed character assignment is checked for - write protection. However, unlike with the C API, a write protected - CBString can be destroyed by the destructor. - -- CBStream is a C++ structure which wraps a struct bStream (its not derived - from it, since destruction is slightly different). It is constructed by - passing in a bNread function pointer and a stream parameter cast to void *. - This structure includes methods for detecting eof, setting the buffer - length, reading the whole stream or reading entries line by line or block - by block, an unread function, and a peek function. - -- If STL is available, the CBStringList structure is derived from a vector of - CBString with various split methods. The split method has been overloaded - to accept either a character or CBString as the second parameter (when the - split parameter is a CBString any character in that CBString is used as a - seperator). The splitstr method takes a CBString as a substring seperator. - Joins can be performed via a CBString constructor which takes a - CBStringList as a parameter, or just using the CBString::join() method. - -- If there is proper support for std::iostreams, then the >> and << operators - and the getline() function have been added (with semantics the same as - those for std::string). - -Multithreading --------------- - -A mutable bstring is kind of analogous to a small (two entry) linked list -allocated by malloc, with all aliasing completely under programmer control. -I.e., manipulation of one bstring will never affect any other distinct -bstring unless explicitely constructed to do so by the programmer via hand -construction or via building a reference. Bstrlib also does not use any -static or global storage, so there are no hidden unremovable race conditions. -Bstrings are also clearly not inherently thread local. So just like -char *'s, bstrings can be passed around from thread to thread and shared and -so on, so long as modifications to a bstring correspond to some kind of -exclusive access lock as should be expected (or if the bstring is read-only, -which can be enforced by bstring write protection) for any sort of shared -object in a multithreaded environment. - -Bsafe module ------------- - -For convenience, a bsafe module has been included. The idea is that if this -module is included, inadvertant usage of the most dangerous C functions will -be overridden and lead to an immediate run time abort. Of course, it should -be emphasized that usage of this module is completely optional. The -intention is essentially to provide an option for creating project safety -rules which can be enforced mechanically rather than socially. This is -useful for larger, or open development projects where its more difficult to -enforce social rules or "coding conventions". - -Problems not solved -------------------- - -Bstrlib is written for the C and C++ languages, which have inherent weaknesses -that cannot be easily solved: - -1. Memory leaks: Forgetting to call bdestroy on a bstring that is about to be - unreferenced, just as forgetting to call free on a heap buffer that is - about to be dereferenced. Though bstrlib itself is leak free. -2. Read before write usage: In C, declaring an auto bstring does not - automatically fill it with legal/valid contents. This problem has been - somewhat mitigated in C++. (The bstrDeclare and bstrFree macros from - bstraux can be used to help mitigate this problem.) - -Other problems not addressed: - -3. Built-in mutex usage to automatically avoid all bstring internal race - conditions in multitasking environments: The problem with trying to - implement such things at this low a level is that it is typically more - efficient to use locks in higher level primitives. There is also no - platform independent way to implement locks or mutexes. - -Note that except for spotty support of wide characters, the default C -standard library does not address any of these problems either. - -Configurable compilation options --------------------------------- - -The Better String Library is not an application, it is a library. To compile -it, you need to compile bstrlib.c to an object file that is linked to your -application. A Makefile might contain entries such as the following to -accomplish this: - -BSTRDIR = $(CDIR)/bstrlib -INCLUDES = -I$(BSTRDIR) -BSTROBJS = $(ODIR)/bstrlib.o -DEFINES = -CFLAGS = -O3 -Wall -pedantic -ansi -s $(DEFINES) - -application: $(ODIR)/main.o $(BSTROBJS) - echo Linking: $@ - $(CC) $< $(BSTROBJS) -o $@ - -$(ODIR)/%.o : $(BSTRDIR)/%.c - echo Compiling: $< - $(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@ - -$(ODIR)/%.o : %.c - echo Compiling: $< - $(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@ - -You can configure bstrlib using with the standard macro defines passed to -the compiler. All configuration options are meant solely for the purpose of -compiler compatibility. Configuration options are not meant to change the -semantics or capabilities of the library, except where it is unavoidable. - -Since some C++ compilers don't include the Standard Template Library and some -have the options of disabling exception handling, a number of macros can be -used to conditionally compile support for each of this: - -BSTRLIB_CAN_USE_STL - - - defining this will enable the used of the Standard Template Library. - Defining BSTRLIB_CAN_USE_STL overrides the BSTRLIB_CANNOT_USE_STL macro. - -BSTRLIB_CANNOT_USE_STL - - - defining this will disable the use of the Standard Template Library. - Defining BSTRLIB_CAN_USE_STL overrides the BSTRLIB_CANNOT_USE_STL macro. - -BSTRLIB_CAN_USE_IOSTREAM - - - defining this will enable the used of streams from class std. Defining - BSTRLIB_CAN_USE_IOSTREAM overrides the BSTRLIB_CANNOT_USE_IOSTREAM macro. - -BSTRLIB_CANNOT_USE_IOSTREAM - - - defining this will disable the use of streams from class std. Defining - BSTRLIB_CAN_USE_IOSTREAM overrides the BSTRLIB_CANNOT_USE_IOSTREAM macro. - -BSTRLIB_THROWS_EXCEPTIONS - - - defining this will enable the exception handling within bstring. - Defining BSTRLIB_THROWS_EXCEPTIONS overrides the - BSTRLIB_DOESNT_THROWS_EXCEPTIONS macro. - -BSTRLIB_DOESNT_THROW_EXCEPTIONS - - - defining this will disable the exception handling within bstring. - Defining BSTRLIB_THROWS_EXCEPTIONS overrides the - BSTRLIB_DOESNT_THROW_EXCEPTIONS macro. - -Note that these macros must be defined consistently throughout all modules -that use CBStrings including bstrwrap.cpp. - -Some older C compilers do not support functions such as vsnprintf. This is -handled by the following macro variables: - -BSTRLIB_NOVSNP - - - defining this indicates that the compiler does not support vsnprintf. - This will cause bformat and bformata to not be declared. Note that - for some compilers, such as Turbo C, this is set automatically. - Defining BSTRLIB_NOVSNP overrides the BSTRLIB_VSNP_OK macro. - -BSTRLIB_VSNP_OK - - - defining this will disable the autodetection of compilers that do not - vsnprintf. - Defining BSTRLIB_NOVSNP overrides the BSTRLIB_VSNP_OK macro. - -Semantic compilation options ----------------------------- - -Bstrlib comes with very few compilation options for changing the semantics of -of the library. These are described below. - -BSTRLIB_DONT_ASSUME_NAMESPACE - - - Defining this before including bstrwrap.h will disable the automatic - enabling of the Bstrlib namespace for the C++ declarations. - -BSTRLIB_DONT_USE_VIRTUAL_DESTRUCTOR - - - Defining this will make the CBString destructor non-virtual. - -BSTRLIB_MEMORY_DEBUG - - - Defining this will cause the bstrlib modules bstrlib.c and bstrwrap.cpp - to invoke a #include "memdbg.h". memdbg.h has to be supplied by the user. - -Note that these macros must be defined consistently throughout all modules -that use bstrings or CBStrings including bstrlib.c, bstraux.c and -bstrwrap.cpp. - -=============================================================================== - -Files ------ - -Core C files (required for C and C++): -bstrlib.c - C implementaion of bstring functions. -bstrlib.h - C header file for bstring functions. - -Core C++ files (required for C++): -bstrwrap.cpp - C++ implementation of CBString. -bstrwrap.h - C++ header file for CBString. - -Base Unicode support: -utf8util.c - C implemention of generic utf8 parsing functions. -utf8util.h - C head file for generic utf8 parsing functions. -buniutil.c - C implemention utf8 bstring packing and unpacking functions. -buniutil.c - C header file for utf8 bstring functions. - -Extra utility functions: -bstraux.c - C example that implements trivial additional functions. -bstraux.h - C header for bstraux.c - -Miscellaneous: -bstest.c - C unit/regression test for bstrlib.c -test.cpp - C++ unit/regression test for bstrwrap.cpp -bsafe.c - C runtime stubs to abort usage of unsafe C functions. -bsafe.h - C header file for bsafe.c functions. - -C modules need only include bstrlib.h and compile/link bstrlib.c to use the -basic bstring library. C++ projects need to additionally include bstrwrap.h -and compile/link bstrwrap.cpp. For both, there may be a need to make choices -about feature configuration as described in the "Configurable compilation -options" in the section above. - -Other files that are included in this archive are: - -license.txt - The BSD license for Bstrlib -gpl.txt - The GPL version 2 -security.txt - A security statement useful for auditting Bstrlib -porting.txt - A guide to porting Bstrlib -bstrlib.txt - This file - -=============================================================================== - -The functions -------------- - - extern bstring bfromcstr (const char * str); - - Take a standard C library style '\0' terminated char buffer and generate - a bstring with the same contents as the char buffer. If an error occurs - NULL is returned. - - So for example: - - bstring b = bfromcstr ("Hello"); - if (!b) { - fprintf (stderr, "Out of memory"); - } else { - puts ((char *) b->data); - } - - .......................................................................... - - extern bstring bfromcstralloc (int mlen, const char * str); - - Create a bstring which contains the contents of the '\0' terminated - char * buffer str. The memory buffer backing the bstring is at least - mlen characters in length. The buffer is also at least size required - to hold the string with the '\0' terminator. If an error occurs NULL - is returned. - - So for example: - - bstring b = bfromcstralloc (64, someCstr); - if (b) b->data[63] = 'x'; - - The idea is that this will set the 64th character of b to 'x' if it is at - least 64 characters long otherwise do nothing. And we know this is well - defined so long as b was successfully created, since it will have been - allocated with at least 64 characters. - - .......................................................................... - - extern bstring bfromcstrrangealloc (int minl, int maxl, const char* str); - - Create a bstring which contains the contents of the '\0' terminated - char * buffer str. The memory buffer backing the string is at least - minl characters in length, but an attempt is made to allocate up to - maxl characters. The buffer is also at least size required to hold - the string with the '\0' terminator. If an error occurs NULL is - returned. - - So for example: - - bstring b = bfromcstrrangealloc (0, 128, "Hello."); - if (b) b->data[5] = '!'; - - The idea is that this will set the 6th character of b to '!' if it was - allocated otherwise do nothing. And we know this is well defined so - long as b was successfully created, since it will have been allocated - with at least 7 (strlen("Hello.")) characters. - - .......................................................................... - - extern bstring blk2bstr (const void * blk, int len); - - Create a bstring whose contents are described by the contiguous buffer - pointing to by blk with a length of len bytes. Note that this function - creates a copy of the data in blk, rather than simply referencing it. - Compare with the blk2tbstr macro. If an error occurs NULL is returned. - - .......................................................................... - - extern char * bstr2cstr (const_bstring s, char z); - - Create a '\0' terminated char buffer which contains the contents of the - bstring s, except that any contained '\0' characters are converted to the - character in z. This returned value should be freed with bcstrfree(), by - the caller. If an error occurs NULL is returned. - - .......................................................................... - - extern int bcstrfree (char * s); - - Frees a C-string generated by bstr2cstr (). This is normally unnecessary - since it just wraps a call to free (), however, if malloc () and free () - have been redefined as a macros within the bstrlib module (via macros in - the memdbg.h backdoor) with some difference in behaviour from the std - library functions, then this allows a correct way of freeing the memory - that allows higher level code to be independent from these macro - redefinitions. - - .......................................................................... - - extern bstring bstrcpy (const_bstring b1); - - Make a copy of the passed in bstring. The copied bstring is returned if - there is no error, otherwise NULL is returned. - - .......................................................................... - - extern int bassign (bstring a, const_bstring b); - - Overwrite the bstring a with the contents of bstring b. Note that the - bstring a must be a well defined and writable bstring. If an error - occurs BSTR_ERR is returned and a is not overwritten. - - .......................................................................... - - int bassigncstr (bstring a, const char * str); - - Overwrite the string a with the contents of char * string str. Note that - the bstring a must be a well defined and writable bstring. If an error - occurs BSTR_ERR is returned and a may be partially overwritten. - - .......................................................................... - - int bassignblk (bstring a, const void * s, int len); - - Overwrite the string a with the contents of the block (s, len). Note that - the bstring a must be a well defined and writable bstring. If an error - occurs BSTR_ERR is returned and a is not overwritten. - - .......................................................................... - - extern int bassignmidstr (bstring a, const_bstring b, int left, int len); - - Overwrite the bstring a with the middle of contents of bstring b - starting from position left and running for a length len. left and - len are clamped to the ends of b as with the function bmidstr. Note that - the bstring a must be a well defined and writable bstring. If an error - occurs BSTR_ERR is returned and a is not overwritten. - - .......................................................................... - - extern bstring bmidstr (const_bstring b, int left, int len); - - Create a bstring which is the substring of b starting from position left - and running for a length len (clamped by the end of the bstring b.) If - there was no error, the value of this constructed bstring is returned - otherwise NULL is returned. - - .......................................................................... - - extern int bdelete (bstring s1, int pos, int len); - - Removes characters from pos to pos+len-1 and shifts the tail of the - bstring starting from pos+len to pos. len must be positive for this call - to have any effect. The section of the bstring described by (pos, len) - is clamped to boundaries of the bstring b. The value BSTR_OK is returned - if the operation is successful, otherwise BSTR_ERR is returned. - - .......................................................................... - - extern int bconcat (bstring b0, const_bstring b1); - - Concatenate the bstring b1 to the end of bstring b0. The value BSTR_OK - is returned if the operation is successful, otherwise BSTR_ERR is - returned. - - .......................................................................... - - extern int bconchar (bstring b, char c); - - Concatenate the character c to the end of bstring b. The value BSTR_OK - is returned if the operation is successful, otherwise BSTR_ERR is - returned. - - .......................................................................... - - extern int bcatcstr (bstring b, const char * s); - - Concatenate the char * string s to the end of bstring b. The value - BSTR_OK is returned if the operation is successful, otherwise BSTR_ERR is - returned. - - .......................................................................... - - extern int bcatblk (bstring b, const void * s, int len); - - Concatenate a fixed length buffer (s, len) to the end of bstring b. The - value BSTR_OK is returned if the operation is successful, otherwise - BSTR_ERR is returned. - - .......................................................................... - - extern int biseq (const_bstring b0, const_bstring b1); - - Compare the bstring b0 and b1 for equality. If the bstrings differ, 0 - is returned, if the bstrings are the same, 1 is returned, if there is an - error, -1 is returned. If the length of the bstrings are different, this - function has O(1) complexity. Contained '\0' characters are not treated - as a termination character. - - Note that the semantics of biseq are not completely compatible with - bstrcmp because of its different treatment of the '\0' character. - - .......................................................................... - - extern int bisstemeqblk (const_bstring b, const void * blk, int len); - - Compare beginning of bstring b0 with a block of memory of length len for - equality. If the beginning of b0 differs from the memory block (or if b0 - is too short), 0 is returned, if the bstrings are the same, 1 is returned, - if there is an error, -1 is returned. - - .......................................................................... - - extern int biseqcaseless (const_bstring b0, const_bstring b1); - - Compare two bstrings for equality without differentiating between case. - If the bstrings differ other than in case, 0 is returned, if the bstrings - are the same, 1 is returned, if there is an error, -1 is returned. If - the length of the bstrings are different, this function is O(1). '\0' - termination characters are not treated in any special way. - - .......................................................................... - - extern int biseqcaselessblk (const_bstring b, const void * blk, int len); - - Compare content of b and the array of bytes in blk for length len for - equality without differentiating between character case. If the content - differs other than in case, 0 is returned, if, ignoring case, the content - is the same, 1 is returned, if there is an error, -1 is returned. If the - length of the strings are different, this function is O(1). '\0' - termination characters are not treated in any special way. - - .......................................................................... - - extern int bisstemeqcaselessblk (const_bstring b0, const void * blk, int len); - - Compare beginning of bstring b0 with a block of memory of length len - without differentiating between case for equality. If the beginning of b0 - differs from the memory block other than in case (or if b0 is too short), - 0 is returned, if the bstrings are the same, 1 is returned, if there is an - error, -1 is returned. - - .......................................................................... - - int biseqblk (const_bstring b, const void * blk, int len) - - Compare the string b with the character block blk of length len. If the - content differs, 0 is returned, if the content is the same, 1 is returned, - if there is an error, -1 is returned. If the length of the strings are - different, this function is O(1). '\0' characters are not treated in - any special way. - - .......................................................................... - - extern int biseqcstr (const_bstring b, const char *s); - - Compare the bstring b and char * bstring s. The C string s must be '\0' - terminated at exactly the length of the bstring b, and the contents - between the two must be identical with the bstring b with no '\0' - characters for the two contents to be considered equal. This is - equivalent to the condition that their current contents will be always be - equal when comparing them in the same format after converting one or the - other. If they are equal 1 is returned, if they are unequal 0 is - returned and if there is a detectable error BSTR_ERR is returned. - - .......................................................................... - - extern int biseqcstrcaseless (const_bstring b, const char *s); - - Compare the bstring b and char * string s. The C string s must be '\0' - terminated at exactly the length of the bstring b, and the contents - between the two must be identical except for case with the bstring b with - no '\0' characters for the two contents to be considered equal. This is - equivalent to the condition that their current contents will be always be - equal ignoring case when comparing them in the same format after - converting one or the other. If they are equal, except for case, 1 is - returned, if they are unequal regardless of case 0 is returned and if - there is a detectable error BSTR_ERR is returned. - - .......................................................................... - - extern int bstrcmp (const_bstring b0, const_bstring b1); - - Compare the bstrings b0 and b1 for ordering. If there is an error, - SHRT_MIN is returned, otherwise a value less than or greater than zero, - indicating that the bstring pointed to by b0 is lexicographically less - than or greater than the bstring pointed to by b1 is returned. If the - bstring lengths are unequal but the characters up until the length of the - shorter are equal then a value less than, or greater than zero, - indicating that the bstring pointed to by b0 is shorter or longer than the - bstring pointed to by b1 is returned. 0 is returned if and only if the - two bstrings are the same. If the length of the bstrings are different, - this function is O(n). Like its standard C library counter part, the - comparison does not proceed past any '\0' termination characters - encountered. - - The seemingly odd error return value, merely provides slightly more - granularity than the undefined situation given in the C library function - strcmp. The function otherwise behaves very much like strcmp(). - - Note that the semantics of bstrcmp are not completely compatible with - biseq because of its different treatment of the '\0' termination - character. - - .......................................................................... - - extern int bstrncmp (const_bstring b0, const_bstring b1, int n); - - Compare the bstrings b0 and b1 for ordering for at most n characters. If - there is an error, SHRT_MIN is returned, otherwise a value is returned as - if b0 and b1 were first truncated to at most n characters then bstrcmp - was called with these new bstrings are paremeters. If the length of the - bstrings are different, this function is O(n). Like its standard C - library counter part, the comparison does not proceed past any '\0' - termination characters encountered. - - The seemingly odd error return value, merely provides slightly more - granularity than the undefined situation given in the C library function - strncmp. The function otherwise behaves very much like strncmp(). - - .......................................................................... - - extern int bstricmp (const_bstring b0, const_bstring b1); - - Compare two bstrings without differentiating between case. The return - value is the difference of the values of the characters where the two - bstrings first differ, otherwise 0 is returned indicating that the - bstrings are equal. If the lengths are different, then a difference from - 0 is given, but if the first extra character is '\0', then it is taken to - be the value UCHAR_MAX+1. - - .......................................................................... - - extern int bstrnicmp (const_bstring b0, const_bstring b1, int n); - - Compare two bstrings without differentiating between case for at most n - characters. If the position where the two bstrings first differ is - before the nth position, the return value is the difference of the values - of the characters, otherwise 0 is returned. If the lengths are different - and less than n characters, then a difference from 0 is given, but if the - first extra character is '\0', then it is taken to be the value - UCHAR_MAX+1. - - .......................................................................... - - extern int bdestroy (bstring b); - - Deallocate the bstring passed. Passing NULL in as a parameter will have - no effect. Note that both the header and the data portion of the bstring - will be freed. No other bstring function which modifies one of its - parameters will free or reallocate the header. Because of this, in - general, bdestroy cannot be called on any declared struct tagbstring even - if it is not write protected. A bstring which is write protected cannot - be destroyed via the bdestroy call. Any attempt to do so will result in - no action taken, and BSTR_ERR will be returned. - - Note to C++ users: Passing in a CBString cast to a bstring will lead to - undefined behavior (free will be called on the header, rather than the - CBString destructor.) Instead just use the ordinary C++ language - facilities to dealloc a CBString. - - .......................................................................... - - extern int binstr (const_bstring s1, int pos, const_bstring s2); - - Search for the bstring s2 in s1 starting at position pos and looking in a - forward (increasing) direction. If it is found then it returns with the - first position after pos where it is found, otherwise it returns BSTR_ERR. - The algorithm used is brute force; O(m*n). - - .......................................................................... - - extern int binstrr (const_bstring s1, int pos, const_bstring s2); - - Search for the bstring s2 in s1 starting at position pos and looking in a - backward (decreasing) direction. If it is found then it returns with the - first position after pos where it is found, otherwise return BSTR_ERR. - Note that the current position at pos is tested as well -- so to be - disjoint from a previous forward search it is recommended that the - position be backed up (decremented) by one position. The algorithm used - is brute force; O(m*n). - - .......................................................................... - - extern int binstrcaseless (const_bstring s1, int pos, const_bstring s2); - - Search for the bstring s2 in s1 starting at position pos and looking in a - forward (increasing) direction but without regard to case. If it is - found then it returns with the first position after pos where it is - found, otherwise it returns BSTR_ERR. The algorithm used is brute force; - O(m*n). - - .......................................................................... - - extern int binstrrcaseless (const_bstring s1, int pos, const_bstring s2); - - Search for the bstring s2 in s1 starting at position pos and looking in a - backward (decreasing) direction but without regard to case. If it is - found then it returns with the first position after pos where it is - found, otherwise return BSTR_ERR. Note that the current position at pos - is tested as well -- so to be disjoint from a previous forward search it - is recommended that the position be backed up (decremented) by one - position. The algorithm used is brute force; O(m*n). - - .......................................................................... - - extern int binchr (const_bstring b0, int pos, const_bstring b1); - - Search for the first position in b0 starting from pos or after, in which - one of the characters in b1 is found. This function has an execution - time of O(b0->slen + b1->slen). If such a position does not exist in b0, - then BSTR_ERR is returned. - - .......................................................................... - - extern int binchrr (const_bstring b0, int pos, const_bstring b1); - - Search for the last position in b0 no greater than pos, in which one of - the characters in b1 is found. This function has an execution time - of O(b0->slen + b1->slen). If such a position does not exist in b0, - then BSTR_ERR is returned. - - .......................................................................... - - extern int bninchr (const_bstring b0, int pos, const_bstring b1); - - Search for the first position in b0 starting from pos or after, in which - none of the characters in b1 is found and return it. This function has - an execution time of O(b0->slen + b1->slen). If such a position does - not exist in b0, then BSTR_ERR is returned. - - .......................................................................... - - extern int bninchrr (const_bstring b0, int pos, const_bstring b1); - - Search for the last position in b0 no greater than pos, in which none of - the characters in b1 is found and return it. This function has an - execution time of O(b0->slen + b1->slen). If such a position does not - exist in b0, then BSTR_ERR is returned. - - .......................................................................... - - extern int bstrchr (const_bstring b, int c); - - Search for the character c in the bstring b forwards from the start of - the bstring. Returns the position of the found character or BSTR_ERR if - it is not found. - - NOTE: This has been implemented as a macro on top of bstrchrp (). - - .......................................................................... - - extern int bstrrchr (const_bstring b, int c); - - Search for the character c in the bstring b backwards from the end of the - bstring. Returns the position of the found character or BSTR_ERR if it is - not found. - - NOTE: This has been implemented as a macro on top of bstrrchrp (). - - .......................................................................... - - extern int bstrchrp (const_bstring b, int c, int pos); - - Search for the character c in b forwards from the position pos - (inclusive). Returns the position of the found character or BSTR_ERR if - it is not found. - - .......................................................................... - - extern int bstrrchrp (const_bstring b, int c, int pos); - - Search for the character c in b backwards from the position pos in bstring - (inclusive). Returns the position of the found character or BSTR_ERR if - it is not found. - - .......................................................................... - - extern int bsetstr (bstring b0, int pos, const_bstring b1, unsigned char fill); - - Overwrite the bstring b0 starting at position pos with the bstring b1. If - the position pos is past the end of b0, then the character "fill" is - appended as necessary to make up the gap between the end of b0 and pos. - If b1 is NULL, it behaves as if it were a 0-length bstring. The value - BSTR_OK is returned if the operation is successful, otherwise BSTR_ERR is - returned. - - .......................................................................... - - extern int binsert (bstring s1, int pos, const_bstring s2, unsigned char fill); - - Inserts the bstring s2 into s1 at position pos. If the position pos is - past the end of s1, then the character "fill" is appended as necessary to - make up the gap between the end of s1 and pos. The value BSTR_OK is - returned if the operation is successful, otherwise BSTR_ERR is returned. - - .......................................................................... - - int binsertblk (bstring b, int pos, const void * blk, int len, - unsigned char fill) - - Inserts the block of characters at blk with length len into b at position - pos. If the position pos is past the end of b, then the character "fill" - is appended as necessary to make up the gap between the end of b1 and pos. - Unlike bsetstr, binsert does not allow b2 to be NULL. - - .......................................................................... - - extern int binsertch (bstring s1, int pos, int len, unsigned char fill); - - Inserts the character fill repeatedly into s1 at position pos for a - length len. If the position pos is past the end of s1, then the - character "fill" is appended as necessary to make up the gap between the - end of s1 and the position pos + len (exclusive). The value BSTR_OK is - returned if the operation is successful, otherwise BSTR_ERR is returned. - - .......................................................................... - - extern int breplace (bstring b1, int pos, int len, const_bstring b2, - unsigned char fill); - - Replace a section of a bstring from pos for a length len with the bstring - b2. If the position pos is past the end of b1 then the character "fill" - is appended as necessary to make up the gap between the end of b1 and - pos. - - .......................................................................... - - extern int bfindreplace (bstring b, const_bstring find, - const_bstring replace, int position); - - Replace all occurrences of the find substring with a replace bstring - after a given position in the bstring b. The find bstring must have a - length > 0 otherwise BSTR_ERR is returned. This function does not - perform recursive per character replacement; that is to say successive - searches resume at the position after the last replace. - - So for example: - - bfindreplace (a0 = bfromcstr("aabaAb"), a1 = bfromcstr("a"), - a2 = bfromcstr("aa"), 0); - - Should result in changing a0 to "aaaabaaAb". - - This function performs exactly (b->slen - position) bstring comparisons, - and data movement is bounded above by character volume equivalent to size - of the output bstring. - - .......................................................................... - - extern int bfindreplacecaseless (bstring b, const_bstring find, - const_bstring replace, int position); - - Replace all occurrences of the find substring, ignoring case, with a - replace bstring after a given position in the bstring b. The find bstring - must have a length > 0 otherwise BSTR_ERR is returned. This function - does not perform recursive per character replacement; that is to say - successive searches resume at the position after the last replace. - - So for example: - - bfindreplacecaseless (a0 = bfromcstr("AAbaAb"), a1 = bfromcstr("a"), - a2 = bfromcstr("aa"), 0); - - Should result in changing a0 to "aaaabaaaab". - - This function performs exactly (b->slen - position) bstring comparisons, - and data movement is bounded above by character volume equivalent to size - of the output bstring. - - .......................................................................... - - extern int balloc (bstring b, int length); - - Increase the allocated memory backing the data buffer for the bstring b - to a length of at least length. If the memory backing the bstring b is - already large enough, not action is performed. This has no effect on the - bstring b that is visible to the bstring API. Usually this function will - only be used when a minimum buffer size is required coupled with a direct - access to the ->data member of the bstring structure. - - Be warned that like any other bstring function, the bstring must be well - defined upon entry to this function. I.e., doing something like: - - b->slen *= 2; /* ?? Most likely incorrect */ - balloc (b, b->slen); - - is invalid, and should be implemented as: - - int t; - if (BSTR_OK == balloc (b, t = (b->slen * 2))) b->slen = t; - - This function will return with BSTR_ERR if b is not detected as a valid - bstring or length is not greater than 0, otherwise BSTR_OK is returned. - - .......................................................................... - - extern int ballocmin (bstring b, int length); - - Change the amount of memory backing the bstring b to at least length. - This operation will never truncate the bstring data including the - extra terminating '\0' and thus will not decrease the length to less than - b->slen + 1. Note that repeated use of this function may cause - performance problems (realloc may be called on the bstring more than - the O(log(INT_MAX)) times). This function will return with BSTR_ERR if b - is not detected as a valid bstring or length is not greater than 0, - otherwise BSTR_OK is returned. - - So for example: - - if (BSTR_OK == ballocmin (b, 64)) b->data[63] = 'x'; - - The idea is that this will set the 64th character of b to 'x' if it is at - least 64 characters long otherwise do nothing. And we know this is well - defined so long as the ballocmin call was successfully, since it will - ensure that b has been allocated with at least 64 characters. - - .......................................................................... - - int btrunc (bstring b, int n); - - Truncate the bstring to at most n characters. This function will return - with BSTR_ERR if b is not detected as a valid bstring or n is less than - 0, otherwise BSTR_OK is returned. - - .......................................................................... - - extern int bpattern (bstring b, int len); - - Replicate the starting bstring, b, end to end repeatedly until it - surpasses len characters, then chop the result to exactly len characters. - This function operates in-place. This function will return with BSTR_ERR - if b is NULL or of length 0, otherwise BSTR_OK is returned. - - .......................................................................... - - extern int btoupper (bstring b); - - Convert contents of bstring to upper case. This function will return with - BSTR_ERR if b is NULL or of length 0, otherwise BSTR_OK is returned. - - .......................................................................... - - extern int btolower (bstring b); - - Convert contents of bstring to lower case. This function will return with - BSTR_ERR if b is NULL or of length 0, otherwise BSTR_OK is returned. - - .......................................................................... - - extern int bltrimws (bstring b); - - Delete whitespace contiguous from the left end of the bstring. This - function will return with BSTR_ERR if b is NULL or of length 0, otherwise - BSTR_OK is returned. - - .......................................................................... - - extern int brtrimws (bstring b); - - Delete whitespace contiguous from the right end of the bstring. This - function will return with BSTR_ERR if b is NULL or of length 0, otherwise - BSTR_OK is returned. - - .......................................................................... - - extern int btrimws (bstring b); - - Delete whitespace contiguous from both ends of the bstring. This function - will return with BSTR_ERR if b is NULL or of length 0, otherwise BSTR_OK - is returned. - - .......................................................................... - - extern struct bstrList* bstrListCreate (void); - - Create an empty struct bstrList. The struct bstrList output structure is - declared as follows: - - struct bstrList { - int qty, mlen; - bstring * entry; - }; - - The entry field actually is an array with qty number entries. The mlen - record counts the maximum number of bstring's for which there is memory - in the entry record. - - The Bstrlib API does *NOT* include a comprehensive set of functions for - full management of struct bstrList in an abstracted way. The reason for - this is because aliasing semantics of the list are best left to the user - of this function, and performance varies wildly depending on the - assumptions made. For a complete list of bstring data type it is - recommended that the C++ public std::vector be used, since its - semantics are usage are more standard. - - .......................................................................... - - extern int bstrListDestroy (struct bstrList * sl); - - Destroy a struct bstrList structure that was returned by the bsplit - function. Note that this will destroy each bstring in the ->entry array - as well. See bstrListCreate() above for structure of struct bstrList. - - .......................................................................... - - extern int bstrListAlloc (struct bstrList * sl, int msz); - - Ensure that there is memory for at least msz number of entries for the - list. - - .......................................................................... - - extern int bstrListAllocMin (struct bstrList * sl, int msz); - - Try to allocate the minimum amount of memory for the list to include at - least msz entries or sl->qty whichever is greater. - - .......................................................................... - - extern struct bstrList * bsplit (bstring str, unsigned char splitChar); - - Create an array of sequential substrings from str divided by the - character splitChar. Successive occurrences of the splitChar will be - divided by empty bstring entries, following the semantics from the Python - programming language. To reclaim the memory from this output structure, - bstrListDestroy () should be called. See bstrListCreate() above for - structure of struct bstrList. - - .......................................................................... - - extern struct bstrList * bsplits (bstring str, const_bstring splitStr); - - Create an array of sequential substrings from str divided by any - character contained in splitStr. An empty splitStr causes a single entry - bstrList containing a copy of str to be returned. See bstrListCreate() - above for structure of struct bstrList. - - .......................................................................... - - extern struct bstrList * bsplitstr (bstring str, const_bstring splitStr); - - Create an array of sequential substrings from str divided by the entire - substring splitStr. An empty splitStr causes a single entry bstrList - containing a copy of str to be returned. See bstrListCreate() above for - structure of struct bstrList. - - .......................................................................... - - extern bstring bjoin (const struct bstrList * bl, const_bstring sep); - - Join the entries of a bstrList into one bstring by sequentially - concatenating them with the sep bstring in between. If sep is NULL, it - is treated as if it were the empty bstring. Note that: - - bjoin (l = bsplit (b, s->data[0]), s); - - should result in a copy of b, if s->slen is 1. If there is an error NULL - is returned, otherwise a bstring with the correct result is returned. - See bstrListCreate() above for structure of struct bstrList. - - .......................................................................... - - bstring bjoinblk (const struct bstrList * bl, void * blk, int len); - - Join the entries of a bstrList into one bstring by sequentially - concatenating them with the content from blk for length len in between. - If there is an error NULL is returned, otherwise a bstring with the - correct result is returned. - - .......................................................................... - - extern int bsplitcb (const_bstring str, unsigned char splitChar, int pos, - int (* cb) (void * parm, int ofs, int len), void * parm); - - Iterate the set of disjoint sequential substrings over str starting at - position pos divided by the character splitChar. The parm passed to - bsplitcb is passed on to cb. If the function cb returns a value < 0, - then further iterating is halted and this value is returned by bsplitcb. - - Note: Non-destructive modification of str from within the cb function - while performing this split is not undefined. bsplitcb behaves in - sequential lock step with calls to cb. I.e., after returning from a cb - that return a non-negative integer, bsplitcb continues from the position - 1 character after the last detected split character and it will halt - immediately if the length of str falls below this point. However, if the - cb function destroys str, then it *must* return with a negative value, - otherwise bsplitcb will continue in an undefined manner. - - This function is provided as an incremental alternative to bsplit that is - abortable and which does not impose additional memory allocation. - - .......................................................................... - - extern int bsplitscb (const_bstring str, const_bstring splitStr, int pos, - int (* cb) (void * parm, int ofs, int len), void * parm); - - Iterate the set of disjoint sequential substrings over str starting at - position pos divided by any of the characters in splitStr. An empty - splitStr causes the whole str to be iterated once. The parm passed to - bsplitcb is passed on to cb. If the function cb returns a value < 0, - then further iterating is halted and this value is returned by bsplitcb. - - Note: Non-destructive modification of str from within the cb function - while performing this split is not undefined. bsplitscb behaves in - sequential lock step with calls to cb. I.e., after returning from a cb - that return a non-negative integer, bsplitscb continues from the position - 1 character after the last detected split character and it will halt - immediately if the length of str falls below this point. However, if the - cb function destroys str, then it *must* return with a negative value, - otherwise bsplitscb will continue in an undefined manner. - - This function is provided as an incremental alternative to bsplits that - is abortable and which does not impose additional memory allocation. - - .......................................................................... - - extern int bsplitstrcb (const_bstring str, const_bstring splitStr, int pos, - int (* cb) (void * parm, int ofs, int len), void * parm); - - Iterate the set of disjoint sequential substrings over str starting at - position pos divided by the entire substring splitStr. An empty splitStr - causes each character of str to be iterated. The parm passed to bsplitcb - is passed on to cb. If the function cb returns a value < 0, then further - iterating is halted and this value is returned by bsplitcb. - - Note: Non-destructive modification of str from within the cb function - while performing this split is not undefined. bsplitstrcb behaves in - sequential lock step with calls to cb. I.e., after returning from a cb - that return a non-negative integer, bsplitstrcb continues from the position - 1 character after the last detected split character and it will halt - immediately if the length of str falls below this point. However, if the - cb function destroys str, then it *must* return with a negative value, - otherwise bsplitscb will continue in an undefined manner. - - This function is provided as an incremental alternative to bsplitstr that - is abortable and which does not impose additional memory allocation. - - .......................................................................... - - extern bstring bformat (const char * fmt, ...); - - Takes the same parameters as printf (), but rather than outputting - results to stdio, it forms a bstring which contains what would have been - output. Note that if there is an early generation of a '\0' character, - the bstring will be truncated to this end point. - - Note that %s format tokens correspond to '\0' terminated char * buffers, - not bstrings. To print a bstring, first dereference data element of the - the bstring: - - /* b1->data needs to be '\0' terminated, so tagbstrings generated - by blk2tbstr () might not be suitable. */ - b0 = bformat ("Hello, %s", b1->data); - - Note that if the BSTRLIB_NOVSNP macro has been set when bstrlib has been - compiled the bformat function is not present. - - .......................................................................... - - extern int bformata (bstring b, const char * fmt, ...); - - In addition to the initial output buffer b, bformata takes the same - parameters as printf (), but rather than outputting results to stdio, it - appends the results to the initial bstring parameter. Note that if - there is an early generation of a '\0' character, the bstring will be - truncated to this end point. - - Note that %s format tokens correspond to '\0' terminated char * buffers, - not bstrings. To print a bstring, first dereference data element of the - the bstring: - - /* b1->data needs to be '\0' terminated, so tagbstrings generated - by blk2tbstr () might not be suitable. */ - bformata (b0 = bfromcstr ("Hello"), ", %s", b1->data); - - Note that if the BSTRLIB_NOVSNP macro has been set when bstrlib has been - compiled the bformata function is not present. - - .......................................................................... - - extern int bassignformat (bstring b, const char * fmt, ...); - - After the first parameter, it takes the same parameters as printf (), but - rather than outputting results to stdio, it outputs the results to - the bstring parameter b. Note that if there is an early generation of a - '\0' character, the bstring will be truncated to this end point. - - Note that %s format tokens correspond to '\0' terminated char * buffers, - not bstrings. To print a bstring, first dereference data element of the - the bstring: - - /* b1->data needs to be '\0' terminated, so tagbstrings generated - by blk2tbstr () might not be suitable. */ - bassignformat (b0 = bfromcstr ("Hello"), ", %s", b1->data); - - Note that if the BSTRLIB_NOVSNP macro has been set when bstrlib has been - compiled the bassignformat function is not present. - - .......................................................................... - - extern int bvcformata (bstring b, int count, const char * fmt, va_list arglist); - - The bvcformata function formats data under control of the format control - string fmt and attempts to append the result to b. The fmt parameter is - the same as that of the printf function. The variable argument list is - replaced with arglist, which has been initialized by the va_start macro. - The size of the output is upper bounded by count. If the required output - exceeds count, the string b is not augmented with any contents and a value - below BSTR_ERR is returned. If a value below -count is returned then it - is recommended that the negative of this value be used as an update to the - count in a subsequent pass. On other errors, such as running out of - memory, parameter errors or numeric wrap around BSTR_ERR is returned. - BSTR_OK is returned when the output is successfully generated and - appended to b. - - Note: There is no sanity checking of arglist, and this function is - destructive of the contents of b from the b->slen point onward. If there - is an early generation of a '\0' character, the bstring will be truncated - to this end point. - - Although this function is part of the external API for Bstrlib, the - interface and semantics (length limitations, and unusual return codes) - are fairly atypical. The real purpose for this function is to provide an - engine for the bvformata macro. - - Note that if the BSTRLIB_NOVSNP macro has been set when bstrlib has been - compiled the bvcformata function is not present. - - .......................................................................... - - extern bstring bread (bNread readPtr, void * parm); - typedef size_t (* bNread) (void *buff, size_t elsize, size_t nelem, - void *parm); - - Read an entire stream into a bstring, verbatum. The readPtr function - pointer is compatible with fread sematics, except that it need not obtain - the stream data from a file. The intention is that parm would contain - the stream data context/state required (similar to the role of the FILE* - I/O stream parameter of fread.) - - Abstracting the block read function allows for block devices other than - file streams to be read if desired. Note that there is an ANSI - compatibility issue if "fread" is used directly; see the ANSI issues - section below. - - .......................................................................... - - extern int breada (bstring b, bNread readPtr, void * parm); - - Read an entire stream and append it to a bstring, verbatum. Behaves - like bread, except that it appends it results to the bstring b. - BSTR_ERR is returned on error, otherwise 0 is returned. - - .......................................................................... - - extern bstring bgets (bNgetc getcPtr, void * parm, char terminator); - typedef int (* bNgetc) (void * parm); - - Read a bstring from a stream. As many bytes as is necessary are read - until the terminator is consumed or no more characters are available from - the stream. If read from the stream, the terminator character will be - appended to the end of the returned bstring. The getcPtr function must - have the same semantics as the fgetc C library function (i.e., returning - an integer whose value is negative when there are no more characters - available, otherwise the value of the next available unsigned character - from the stream.) The intention is that parm would contain the stream - data context/state required (similar to the role of the FILE* I/O stream - parameter of fgets.) If no characters are read, or there is some other - detectable error, NULL is returned. - - bgets will never call the getcPtr function more often than necessary to - construct its output (including a single call, if required, to determine - that the stream contains no more characters.) - - Abstracting the character stream function and terminator character allows - for different stream devices and string formats other than '\n' - terminated lines in a file if desired (consider \032 terminated email - messages, in a UNIX mailbox for example.) - - For files, this function can be used analogously as fgets as follows: - - fp = fopen ( ... ); - if (fp) b = bgets ((bNgetc) fgetc, fp, '\n'); - - (Note that only one terminator character can be used, and that '\0' is - not assumed to terminate the stream in addition to the terminator - character. This is consistent with the semantics of fgets.) - - .......................................................................... - - extern int bgetsa (bstring b, bNgetc getcPtr, void * parm, char terminator); - - Read from a stream and concatenate to a bstring. Behaves like bgets, - except that it appends it results to the bstring b. The value 1 is - returned if no characters are read before a negative result is returned - from getcPtr. Otherwise BSTR_ERR is returned on error, and 0 is returned - in other normal cases. - - .......................................................................... - - extern int bassigngets (bstring b, bNgetc getcPtr, void * parm, char terminator); - - Read from a stream and concatenate to a bstring. Behaves like bgets, - except that it assigns the results to the bstring b. The value 1 is - returned if no characters are read before a negative result is returned - from getcPtr. Otherwise BSTR_ERR is returned on error, and 0 is returned - in other normal cases. - - .......................................................................... - - extern struct bStream * bsopen (bNread readPtr, void * parm); - - Wrap a given open stream (described by a fread compatible function - pointer and stream handle) into an open bStream suitable for the bstring - library streaming functions. - - .......................................................................... - - extern void * bsclose (struct bStream * s); - - Close the bStream, and return the handle to the stream that was - originally used to open the given stream. If s is NULL or detectably - invalid, NULL will be returned. - - .......................................................................... - - extern int bsbufflength (struct bStream * s, int sz); - - Set the length of the buffer used by the bStream. If sz is the macro - BSTR_BS_BUFF_LENGTH_GET (which is 0), the length is not set. If s is - NULL or sz is negative, the function will return with BSTR_ERR, otherwise - this function returns with the previous length. - - .......................................................................... - - extern int bsreadln (bstring r, struct bStream * s, char terminator); - - Read a bstring terminated by the terminator character or the end of the - stream from the bStream (s) and return it into the parameter r. The - matched terminator, if found, appears at the end of the line read. If - the stream has been exhausted of all available data, before any can be - read, BSTR_ERR is returned. This function may read additional characters - into the stream buffer from the core stream that are not returned, but - will be retained for subsequent read operations. When reading from high - speed streams, this function can perform significantly faster than bgets. - - .......................................................................... - - extern int bsreadlna (bstring r, struct bStream * s, char terminator); - - Read a bstring terminated by the terminator character or the end of the - stream from the bStream (s) and concatenate it to the parameter r. The - matched terminator, if found, appears at the end of the line read. If - the stream has been exhausted of all available data, before any can be - read, BSTR_ERR is returned. This function may read additional characters - into the stream buffer from the core stream that are not returned, but - will be retained for subsequent read operations. When reading from high - speed streams, this function can perform significantly faster than bgets. - - .......................................................................... - - extern int bsreadlns (bstring r, struct bStream * s, bstring terminators); - - Read a bstring terminated by any character in the terminators bstring or - the end of the stream from the bStream (s) and return it into the - parameter r. This function may read additional characters from the core - stream that are not returned, but will be retained for subsequent read - operations. - - .......................................................................... - - extern int bsreadlnsa (bstring r, struct bStream * s, bstring terminators); - - Read a bstring terminated by any character in the terminators bstring or - the end of the stream from the bStream (s) and concatenate it to the - parameter r. If the stream has been exhausted of all available data, - before any can be read, BSTR_ERR is returned. This function may read - additional characters from the core stream that are not returned, but - will be retained for subsequent read operations. - - .......................................................................... - - extern int bsread (bstring r, struct bStream * s, int n); - - Read a bstring of length n (or, if it is fewer, as many bytes as is - remaining) from the bStream. This function will read the minimum - required number of additional characters from the core stream. When the - stream is at the end of the file BSTR_ERR is returned, otherwise BSTR_OK - is returned. - - .......................................................................... - - extern int bsreada (bstring r, struct bStream * s, int n); - - Read a bstring of length n (or, if it is fewer, as many bytes as is - remaining) from the bStream and concatenate it to the parameter r. This - function will read the minimum required number of additional characters - from the core stream. When the stream is at the end of the file BSTR_ERR - is returned, otherwise BSTR_OK is returned. - - .......................................................................... - - extern int bsunread (struct bStream * s, const_bstring b); - - Insert a bstring into the bStream at the current position. These - characters will be read prior to those that actually come from the core - stream. - - .......................................................................... - - extern int bspeek (bstring r, const struct bStream * s); - - Return the number of currently buffered characters from the bStream that - will be read prior to reads from the core stream, and append it to the - the parameter r. - - .......................................................................... - - extern int bssplitscb (struct bStream * s, const_bstring splitStr, - int (* cb) (void * parm, int ofs, const_bstring entry), void * parm); - - Iterate the set of disjoint sequential substrings over the stream s - divided by any character from the bstring splitStr. The parm passed to - bssplitscb is passed on to cb. If the function cb returns a value < 0, - then further iterating is halted and this return value is returned by - bssplitscb. - - Note: At the point of calling the cb function, the bStream pointer is - pointed exactly at the position right after having read the split - character. The cb function can act on the stream by causing the bStream - pointer to move, and bssplitscb will continue by starting the next split - at the position of the pointer after the return from cb. - - However, if the cb causes the bStream s to be destroyed then the cb must - return with a negative value, otherwise bssplitscb will continue in an - undefined manner. - - This function is provided as way to incrementally parse through a file - or other generic stream that in total size may otherwise exceed the - practical or desired memory available. As with the other split callback - based functions this is abortable and does not impose additional memory - allocation. - - .......................................................................... - - extern int bssplitstrcb (struct bStream * s, const_bstring splitStr, - int (* cb) (void * parm, int ofs, const_bstring entry), void * parm); - - Iterate the set of disjoint sequential substrings over the stream s - divided by the entire substring splitStr. The parm passed to - bssplitstrcb is passed on to cb. If the function cb returns a - value < 0, then further iterating is halted and this return value is - returned by bssplitstrcb. - - Note: At the point of calling the cb function, the bStream pointer is - pointed exactly at the position right after having read the split - character. The cb function can act on the stream by causing the bStream - pointer to move, and bssplitstrcb will continue by starting the next - split at the position of the pointer after the return from cb. - - However, if the cb causes the bStream s to be destroyed then the cb must - return with a negative value, otherwise bssplitscb will continue in an - undefined manner. - - This function is provided as way to incrementally parse through a file - or other generic stream that in total size may otherwise exceed the - practical or desired memory available. As with the other split callback - based functions this is abortable and does not impose additional memory - allocation. - - .......................................................................... - - extern int bseof (const struct bStream * s); - - Return the defacto "EOF" (end of file) state of a stream (1 if the - bStream is in an EOF state, 0 if not, and BSTR_ERR if stream is closed or - detectably erroneous.) When the readPtr callback returns a value <= 0 - the stream reaches its "EOF" state. Note that bunread with non-empty - content will essentially turn off this state, and the stream will not be - in its "EOF" state so long as its possible to read more data out of it. - - Also note that the semantics of bseof() are slightly different from - something like feof(). I.e., reaching the end of the stream does not - necessarily guarantee that bseof() will return with a value indicating - that this has happened. bseof() will only return indicating that it has - reached the "EOF" and an attempt has been made to read past the end of - the bStream. - -The macros ----------- - - The macros described below are shown in a prototype form indicating their - intended usage. Note that the parameters passed to these macros will be - referenced multiple times. As with all macros, programmer care is - required to guard against unintended side effects. - - int blengthe (const_bstring b, int err); - - Returns the length of the bstring. If the bstring is NULL err is - returned. - - .......................................................................... - - int blength (const_bstring b); - - Returns the length of the bstring. If the bstring is NULL, the length - returned is 0. - - .......................................................................... - - int bchare (const_bstring b, int p, int c); - - Returns the p'th character of the bstring b. If the position p refers to - a position that does not exist in the bstring or the bstring is NULL, - then c is returned. - - .......................................................................... - - char bchar (const_bstring b, int p); - - Returns the p'th character of the bstring b. If the position p refers to - a position that does not exist in the bstring or the bstring is NULL, - then '\0' is returned. - - .......................................................................... - - char * bdatae (bstring b, char * err); - - Returns the char * data portion of the bstring b. If b is NULL, err is - returned. - - .......................................................................... - - char * bdata (bstring b); - - Returns the char * data portion of the bstring b. If b is NULL, NULL is - returned. - - .......................................................................... - - char * bdataofse (bstring b, int ofs, char * err); - - Returns the char * data portion of the bstring b offset by ofs. If b is - NULL, err is returned. - - .......................................................................... - - char * bdataofs (bstring b, int ofs); - - Returns the char * data portion of the bstring b offset by ofs. If b is - NULL, NULL is returned. - - .......................................................................... - - struct tagbstring var = bsStatic ("..."); - - The bsStatic macro allows for static declarations of literal string - constants as struct tagbstring structures. The resulting tagbstring does - not need to be freed or destroyed. Note that this macro is only well - defined for string literal arguments. For more general string pointers, - use the btfromcstr macro. - - The resulting struct tagbstring is permanently write protected. Attempts - to write to this struct tagbstring from any bstrlib function will lead to - BSTR_ERR being returned. Invoking the bwriteallow macro onto this struct - tagbstring has no effect. - - .......................................................................... - - <- bsStaticBlkParms ("...") - - The bsStaticBlkParms macro emits a pair of comma seperated parameters - corresponding to the block parameters for the block functions in Bstrlib - (i.e., blk2bstr, bcatblk, blk2tbstr, bisstemeqblk, bisstemeqcaselessblk.) - Note that this macro is only well defined for string literal arguments. - - Examples: - - bstring b = blk2bstr (bsStaticBlkParms ("Fast init. ")); - bcatblk (b, bsStaticBlkParms ("No frills fast concatenation.")); - - These are faster than using bfromcstr() and bcatcstr() respectively - because the length of the inline string is known as a compile time - constant. Also note that seperate struct tagbstring declarations for - holding the output of a bsStatic() macro are not required. - - .......................................................................... - - void btfromcstr (struct tagbstring& t, const char * s); - - Fill in the tagbstring t with the '\0' terminated char buffer s. This - action is purely reference oriented; no memory management is done. The - data member is just assigned s, and slen is assigned the strlen of s. - The s parameter is accessed exactly once in this macro. - - The resulting struct tagbstring is initially write protected. Attempts - to write to this struct tagbstring in a write protected state from any - bstrlib function will lead to BSTR_ERR being returned. Invoke the - bwriteallow on this struct tagbstring to make it writeable (though this - requires that s be obtained from a function compatible with malloc.) - - .......................................................................... - - void btfromblk (struct tagbstring& t, void * s, int len); - - Fill in the tagbstring t with the data buffer s with length len. This - action is purely reference oriented; no memory management is done. The - data member of t is just assigned s, and slen is assigned len. Note that - the buffer is not appended with a '\0' character. The s and len - parameters are accessed exactly once each in this macro. - - The resulting struct tagbstring is initially write protected. Attempts - to write to this struct tagbstring in a write protected state from any - bstrlib function will lead to BSTR_ERR being returned. Invoke the - bwriteallow on this struct tagbstring to make it writeable (though this - requires that s be obtained from a function compatible with malloc.) - - .......................................................................... - - void btfromblkltrimws (struct tagbstring& t, void * s, int len); - - Fill in the tagbstring t with the data buffer s with length len after it - has been left trimmed. This action is purely reference oriented; no - memory management is done. The data member of t is just assigned to a - pointer inside the buffer s. Note that the buffer is not appended with a - '\0' character. The s and len parameters are accessed exactly once each - in this macro. - - The resulting struct tagbstring is permanently write protected. Attempts - to write to this struct tagbstring from any bstrlib function will lead to - BSTR_ERR being returned. Invoking the bwriteallow macro onto this struct - tagbstring has no effect. - - .......................................................................... - - void btfromblkrtrimws (struct tagbstring& t, void * s, int len); - - Fill in the tagbstring t with the data buffer s with length len after it - has been right trimmed. This action is purely reference oriented; no - memory management is done. The data member of t is just assigned to a - pointer inside the buffer s. Note that the buffer is not appended with a - '\0' character. The s and len parameters are accessed exactly once each - in this macro. - - The resulting struct tagbstring is permanently write protected. Attempts - to write to this struct tagbstring from any bstrlib function will lead to - BSTR_ERR being returned. Invoking the bwriteallow macro onto this struct - tagbstring has no effect. - - .......................................................................... - - void btfromblktrimws (struct tagbstring& t, void * s, int len); - - Fill in the tagbstring t with the data buffer s with length len after it - has been left and right trimmed. This action is purely reference - oriented; no memory management is done. The data member of t is just - assigned to a pointer inside the buffer s. Note that the buffer is not - appended with a '\0' character. The s and len parameters are accessed - exactly once each in this macro. - - The resulting struct tagbstring is permanently write protected. Attempts - to write to this struct tagbstring from any bstrlib function will lead to - BSTR_ERR being returned. Invoking the bwriteallow macro onto this struct - tagbstring has no effect. - - .......................................................................... - - void bmid2tbstr (struct tagbstring& t, bstring b, int pos, int len); - - Fill the tagbstring t with the substring from b, starting from position - pos with a length len. The segment is clamped by the boundaries of - the bstring b. This action is purely reference oriented; no memory - management is done. Note that the buffer is not appended with a '\0' - character. Note that the t parameter to this macro may be accessed - multiple times. Note that the contents of t will become undefined - if the contents of b change or are destroyed. - - The resulting struct tagbstring is permanently write protected. Attempts - to write to this struct tagbstring in a write protected state from any - bstrlib function will lead to BSTR_ERR being returned. Invoking the - bwriteallow macro on this struct tagbstring will have no effect. - - .......................................................................... - - bstring bfromStatic("..."); - - Allocate a bstring with the contents of a string literal. Returns - NULL if an error has occurred (ran out of memory). The string literal - parameter is enforced as literal at compile time. - - .......................................................................... - - int bcatStatic (bstring b, "..."); - - Append a string literal to bstring b. Returns 0 if successful, or - BSTR_ERR if some error has occurred. The string literal parameter is - enforced as literal at compile time. - - .......................................................................... - - int binsertStatic (bstring s1, int pos, " ... ", char fill); - - Inserts the string literal into s1 at position pos. If the position pos - is past the end of s1, then the character "fill" is appended as necessary - to make up the gap between the end of s1 and pos. The value BSTR_OK is - returned if the operation is successful, otherwise BSTR_ERR is returned. - - .......................................................................... - - int bassignStatic (bstring b, " ... "); - - Assign the contents of a string literal to the bstring b. The string - literal parameter is enforced as literal at compile time. - - .......................................................................... - - int biseqStatic (const_bstring b, " ... "); - - Compare the string b with the string literal. If the content differs, 0 - is returned, if the content is the same, 1 is returned, if there is an - error, -1 is returned. If the length of the strings are different, this - function is O(1). '\0' characters are not treated in any special way. - - .......................................................................... - - int biseqcaselessStatic (const_bstring b, " ... "); - - Compare content of b and the string literal for equality without - differentiating between character case. If the content differs other - than in case, 0 is returned, if, ignoring case, the content is the same, - 1 is returned, if there is an error, -1 is returned. If the length of - the strings are different, this function is O(1). '\0' characters are - not treated in any special way. - - .......................................................................... - - int bisstemeqStatic (bstring b, " ... "); - - Compare beginning of bstring b with a string literal for equality. If - the beginning of b differs from the memory block (or if b is too short), - 0 is returned, if the bstrings are the same, 1 is returned, if there is - an error, -1 is returned. The string literal parameter is enforced as - literal at compile time. - - .......................................................................... - - int bisstemeqcaselessStatic (bstring b, " ... "); - - Compare beginning of bstring b with a string literal without - differentiating between case for equality. If the beginning of b differs - from the memory block other than in case (or if b is too short), 0 is - returned, if the bstrings are the same, 1 is returned, if there is an - error, -1 is returned. The string literal parameter is enforced as - literal at compile time. - - .......................................................................... - - bstring bjoinStatic (const struct bstrList * bl, " ... "); - - Join the entries of a bstrList into one bstring by sequentially - concatenating them with the string literal in between. If there is an - error NULL is returned, otherwise a bstring with the correct result is - returned. See bstrListCreate() above for structure of struct bstrList. - - .......................................................................... - - void bvformata (int& ret, bstring b, const char * format, lastarg); - - Append the bstring b with printf like formatting with the format control - string, and the arguments taken from the ... list of arguments after - lastarg passed to the containing function. If the containing function - does not have ... parameters or lastarg is not the last named parameter - before the ... then the results are undefined. If successful, the - results are appended to b and BSTR_OK is assigned to ret. Otherwise - BSTR_ERR is assigned to ret. - - Example: - - void dbgerror (FILE * fp, const char * fmt, ...) { - int ret; - bstring b; - bvformata (ret, b = bfromcstr ("DBG: "), fmt, fmt); - if (BSTR_OK == ret) fputs ((char *) bdata (b), fp); - bdestroy (b); - } - - Note that if the BSTRLIB_NOVSNP macro was set when bstrlib had been - compiled the bvformata macro will not link properly. If the - BSTRLIB_NOVSNP macro has been set, the bvformata macro will not be - available. - - .......................................................................... - - void bwriteprotect (struct tagbstring& t); - - Disallow bstring from being written to via the bstrlib API. Attempts to - write to the resulting tagbstring from any bstrlib function will lead to - BSTR_ERR being returned. - - Note: bstrings which are write protected cannot be destroyed via bdestroy. - - Note to C++ users: Setting a CBString as write protected will not prevent - it from being destroyed by the destructor. - - .......................................................................... - - void bwriteallow (struct tagbstring& t); - - Allow bstring to be written to via the bstrlib API. Note that such an - action makes the bstring both writable and destroyable. If the bstring is - not legitimately writable (as is the case for struct tagbstrings - initialized with a bsStatic value), the results of this are undefined. - - Note that invoking the bwriteallow macro may increase the number of - reallocs by one more than necessary for every call to bwriteallow - interleaved with any bstring API which writes to this bstring. - - .......................................................................... - - int biswriteprotected (struct tagbstring& t); - - Returns 1 if the bstring is write protected, otherwise 0 is returned. - -=============================================================================== - -Unicode functions ------------------ - - The two modules utf8util.c and buniutil.c implement basic functions for - parsing and collecting Unicode data in the UTF8 format. Unicode is - described by a sequence of "code points" which are values between 0 and - 1114111 inclusive mapped to symbol content corresponding to nearly all - the standardized scripts of the world. - - The semantics of Unicode code points is varied and complicated. The - base support of the better string library does not attempt to perform - any interpretation of these code points. The better string library - solely provides support for iterating through unicode code points, - appending and extracting code points to and from bstrings, and parsing - UTF8 and UTF16 from raw data. - - The types cpUcs4 and cpUcs2 respectively are defined as 4 byte and 2 byte - encoding formats corresponding to UCS4 and UCS2 respectively. To test - if a raw code point is valid, the macro isLegalUnicodeCodePoint() has - been defined. The utf8 iterator is defined by struct utf8Iterator. To - test if the iterator has more code points to walk through the macro - utf8IteratorNoMore() has been defined. - - To use these functions compile and link utf8util.c and buniutil.c - - .......................................................................... - - extern void utf8IteratorInit (struct utf8Iterator* iter, - unsigned char* data, int slen); - - Initialize a unicode utf8 iterator to traverse an array of utf8 encoded - code points pointed to by data, with length slen from the start. The - iterator iter is only valid for as long as the array it is pointed to - is valid and not modified. - - .......................................................................... - - extern void utf8IteratorUninit (struct utf8Iterator* iter); - - Invalidate utf8 iterator. After calling this the iterator iter, should - yield false when passed to the utf8IteratorNoMore() macro. - - .......................................................................... - - extern cpUcs4 utf8IteratorGetNextCodePoint (struct utf8Iterator* iter, - cpUcs4 errCh); - - Parse code point the iterator is pointing at and advance the iterator to - the next code point. If the iterator was pointing at a valid code point - the code point is returned, otherwise, errCh will be returned. - - .......................................................................... - - extern cpUcs4 utf8IteratorGetCurrCodePoint (struct utf8Iterator* iter, - cpUcs4 errCh); - - Parse code point the iterator is pointing at. If the iterator was - pointing at a valid code point the code point is returned, otherwise, - errCh will be returned. - - .......................................................................... - - extern int utf8ScanBackwardsForCodePoint (unsigned char* msg, int len, - int pos, cpUcs4* out); - - From the position "pos" in the array msg of length len, search for the - last position before or at pos where from which a valid Unicode code - point can be parsed. If such an offset is found it is returned otherwise - a negative value is returned. The code point parsed is put into *out if - it is not NULL. - - .......................................................................... - - extern int buIsUTF8Content (const_bstring bu); - - Scan a bstring and determine if it is made entirely of unicode code - valid points. If it is, 1 is returned, otherwise 0 is returned. - - .......................................................................... - - extern int buAppendBlkUcs4 (bstring b, const cpUcs4* bu, int len, - cpUcs4 errCh); - - Append the code points passed in the UCS4 format (raw numbers) in the - array bu of length len. Any unparsable characters are replaced by errCh. - If errCh is not a valid Unicode code point, then parsing errors will cause - BSTR_ERR to be returned. - - .......................................................................... - - extern int buGetBlkUTF16 (cpUcs2* ucs2, int len, cpUcs4 errCh, - const_bstring bu, int pos); - - Convert a string of UTF8 codepoints (bu), skipping the first pos, into a - sequence of UTF16 encoded code points. Returns the number of UCS2 16-bit - words written to the output. No more than len words are written to the - target array ucs2. If any code point in bu is unparsable, it will be - translated to errCh. - - .......................................................................... - - extern int buAppendBlkUTF16 (bstring bu, const cpUcs2* utf16, int len, - cpUcs2* bom, cpUcs4 errCh); - - Append an array of UCS2 code points (utf16) to UTF8 codepoints (bu). Any - invalid code point is replaced by errCh. If errCh is itself not a - valid code point, then this translation will halt upon the first error - and return BSTR_ERR. Otherwise BSTR_OK is returned. If a byte order mark - has been previously read, it may be passed in as bom, otherwise if *bom is - set to 0, it will be filled in with the BOM as read from the first - character if it is a BOM. - -=============================================================================== - -The bstest module ------------------ - -The bstest module is just a unit test for the bstrlib module. For correct -implementations of bstrlib, it should execute with 0 failures being reported. -This test should be utilized if modifications/customizations to bstrlib have -been performed. It tests each core bstrlib function with bstrings of every -mode (read-only, NULL, static and mutable) and ensures that the expected -semantics are observed (including results that should indicate an error). It -also tests for aliasing support. Passing bstest is a necessary but not a -sufficient condition for ensuring the correctness of the bstrlib module. - - -The test module ---------------- - -The test module is just a unit test for the bstrwrap module. For correct -implementations of bstrwrap, it should execute with 0 failures being -reported. This test should be utilized if modifications/customizations to -bstrwrap have been performed. It tests each core bstrwrap function with -CBStrings write protected or not and ensures that the expected semantics are -observed (including expected exceptions.) Note that exceptions cannot be -disabled to run this test. Passing test is a necessary but not a sufficient -condition for ensuring the correctness of the bstrwrap module. - -=============================================================================== - -Using Bstring and CBString as an alternative to the C library -------------------------------------------------------------- - -First let us give a table of C library functions and the alternative bstring -functions and CBString methods that should be used instead of them. - -C-library Bstring alternative CBString alternative ---------- ------------------- -------------------- -gets bgets ::gets -strcpy bassign = operator -strncpy bassignmidstr ::midstr -strcat bconcat += operator -strncat bconcat + btrunc += operator + ::trunc -strtok bsplit, bsplits ::split -sprintf b(assign)format ::format -snprintf b(assign)format + btrunc ::format + ::trunc -vsprintf bvformata bvformata - -vsnprintf bvformata + btrunc bvformata + btrunc -vfprintf bvformata + fputs use bvformata + fputs -strcmp biseq, bstrcmp comparison operators. -strncmp bstrncmp, memcmp bstrncmp, memcmp -strlen ->slen, blength ::length -strdup bstrcpy constructor -strset bpattern ::fill -strstr binstr ::find -strpbrk binchr ::findchr -stricmp bstricmp cast & use bstricmp -strlwr btolower cast & use btolower -strupr btoupper cast & use btoupper -strrev bReverse (aux module) cast & use bReverse -strchr bstrchr cast & use bstrchr -strspnp use strspn use strspn -ungetc bsunread bsunread - -The top 9 C functions listed here are troublesome in that they impose memory -management in the calling function. The Bstring and CBstring interfaces have -built-in memory management, so there is far less code with far less potential -for buffer overrun problems. strtok can only be reliably called as a "leaf" -calculation, since it (quite bizarrely) maintains hidden internal state. And -gets is well known to be broken no matter what. The Bstrlib alternatives do -not suffer from those sorts of problems. - -The substitute for strncat can be performed with higher performance by using -the blk2tbstr macro to create a presized second operand for bconcat. - -C-library Bstring alternative CBString alternative ---------- ------------------- -------------------- -strspn strspn acceptable strspn acceptable -strcspn strcspn acceptable strcspn acceptable -strnset strnset acceptable strnset acceptable -printf printf acceptable printf acceptable -puts puts acceptable puts acceptable -fprintf fprintf acceptable fprintf acceptable -fputs fputs acceptable fputs acceptable -memcmp memcmp acceptable memcmp acceptable - -Remember that Bstring (and CBstring) functions will automatically append the -'\0' character to the character data buffer. So by simply accessing the data -buffer directly, ordinary C string library functions can be called directly -on them. Note that bstrcmp is not the same as memcmp in exactly the same way -that strcmp is not the same as memcmp. - -C-library Bstring alternative CBString alternative ---------- ------------------- -------------------- -fread balloc + fread ::alloc + fread -fgets balloc + fgets ::alloc + fgets - -These are odd ones because of the exact sizing of the buffer required. The -Bstring and CBString alternatives requires that the buffers are forced to -hold at least the prescribed length, then just use fread or fgets directly. -However, typically the automatic memory management of Bstring and CBstring -will make the typical use of fgets and fread to read specifically sized -strings unnecessary. - -Implementation Choices ----------------------- - -Overhead: -......... - -The bstring library has more overhead versus straight char buffers for most -functions. This overhead is essentially just the memory management and -string header allocation. This overhead usually only shows up for small -string manipulations. The performance loss has to be considered in -light of the following: - -1) What would be the performance loss of trying to write this management - code in one's own application? -2) Since the bstring library source code is given, a sufficiently powerful - modern inlining globally optimizing compiler can remove function call - overhead. - -Since the data type is exposed, a developer can replace any unsatisfactory -function with their own inline implementation. And that is besides the main -point of what the better string library is mainly meant to provide. Any -overhead lost has to be compared against the value of the safe abstraction -for coupling memory management and string functionality. - -Performance of the C interface: -............................... - -The algorithms used have performance advantages versus the analogous C -library functions. For example: - -1. bfromcstr/blk2str/bstrcpy versus strcpy/strdup. By using memmove instead - of strcpy, the break condition of the copy loop is based on an independent - counter (that should be allocated in a register) rather than having to - check the results of the load. Modern out-of-order executing CPUs can - parallelize the final branch mis-predict penality with the loading of the - source string. Some CPUs will also tend to have better built-in hardware - support for counted memory moves than load-compare-store. (This is a - minor, but non-zero gain.) -2. biseq versus strcmp. If the strings are unequal in length, bsiseq will - return in O(1) time. If the strings are aliased, or have aliased data - buffers, biseq will return in O(1) time. strcmp will always be O(k), - where k is the length of the common prefix or the whole string if they are - identical. -3. ->slen versus strlen. ->slen is obviously always O(1), while strlen is - always O(n) where n is the length of the string. -4. bconcat versus strcat. Both rely on precomputing the length of the - destination string argument, which will favor the bstring library. On - iterated concatenations the performance difference can be enormous. -5. bsreadln versus fgets. The bsreadln function reads large blocks at a time - from the given stream, then parses out lines from the buffers directly. - Some C libraries will implement fgets as a loop over single fgetc calls. - Testing indicates that the bsreadln approach can be several times faster - for fast stream devices (such as a file that has been entirely cached.) -6. bsplits/bsplitscb versus strspn. Accelerators for the set of match - characters are generated only once. -7. binstr versus strstr. The binstr implementation unrolls the loops to - help reduce loop overhead. This will matter if the target string is - long and source string is not found very early in the target string. - With strstr, while it is possible to unroll the source contents, it is - not possible to do so with the destination contents in a way that is - effective because every destination character must be tested against - '\0' before proceeding to the next character. -8. bReverse versus strrev. The C function must find the end of the string - first before swaping character pairs. -9. bstrrchr versus no comparable C function. Its not hard to write some C - code to search for a character from the end going backwards. But there - is no way to do this without computing the length of the string with - strlen. - -Practical testing indicates that in general Bstrlib is never signifcantly -slower than the C library for common operations, while very often having a -performance advantage that ranges from significant to massive. Even for -functions like b(n)inchr versus str(c)spn() (where, in theory, there is no -advantage for the Bstrlib architecture) the performance of Bstrlib is vastly -superior to most tested C library implementations. - -Some of Bstrlib's extra functionality also lead to inevitable performance -advantages over typical C solutions. For example, using the blk2tbstr macro, -one can (in O(1) time) generate an internal substring by reference while not -disturbing the original string. If disturbing the original string is not an -option, typically, a comparable char * solution would have to make a copy of -the substring to provide similar functionality. Another example is reverse -character set scanning -- the str(c)spn functions only scan in a forward -direction which can complicate some parsing algorithms. - -Where high performance char * based algorithms are available, Bstrlib can -still leverage them by accessing the ->data field on bstrings. So -realistically Bstrlib can never be significantly slower than any standard -'\0' terminated char * based solutions. - -Performance of the C++ interface: -................................. - -The C++ interface has been designed with an emphasis on abstraction and safety -first. However, since it is substantially a wrapper for the C bstring -functions, for longer strings the performance comments described in the -"Performance of the C interface" section above still apply. Note that the -(CBString *) type can be directly cast to a (bstring) type, and passed as -parameters to the C functions (though a CBString must never be passed to -bdestroy.) - -Probably the most controversial choice is performing full bounds checking on -the [] operator. This decision was made because 1) the fast alternative of -not bounds checking is still available by first casting the CBString to a -(const char *) buffer or to a (struct tagbstring) then derefencing .data and -2) because the lack of bounds checking is seen as one of the main weaknesses -of C/C++ versus other languages. This check being done on every access leads -to individual character extraction being actually slower than other languages -in this one respect (other language's compilers will normally dedicate more -resources on hoisting or removing bounds checking as necessary) but otherwise -bring C++ up to the level of other languages in terms of functionality. - -It is common for other C++ libraries to leverage the abstractions provided by -C++ to use reference counting and "copy on write" policies. While these -techniques can speed up some scenarios, they impose a problem with respect to -thread safety. bstrings and CBStrings can be properly protected with -"per-object" mutexes, meaning that two bstrlib calls can be made and execute -simultaneously, so long as the bstrings and CBstrings are distinct. With a -reference count and alias before copy on write policy, global mutexes are -required that prevent multiple calls to the strings library to execute -simultaneously regardless of whether or not the strings represent the same -string. - -One interesting trade off in CBString is that the default constructor is not -trivial. I.e., it always prepares a ready to use memory buffer. The purpose -is to ensure that there is a uniform internal composition for any functioning -CBString that is compatible with bstrings. It also means that the other -methods in the class are not forced to perform "late initialization" checks. -In the end it means that construction of CBStrings are slower than other -comparable C++ string classes. Initial testing, however, indicates that -CBString outperforms std::string and MFC's CString, for example, in all other -operations. So to work around this weakness it is recommended that CBString -declarations be pushed outside of inner loops. - -Practical testing indicates that with the exception of the caveats given -above (constructors and safe index character manipulations) the C++ API for -Bstrlib generally outperforms popular standard C++ string classes. Amongst -the standard libraries and compilers, the quality of concatenation operations -varies wildly and very little care has gone into search functions. Bstrlib -dominates those performance benchmarks. - -Memory management: -.................. - -The bstring functions which write and modify bstrings will automatically -reallocate the backing memory for the char buffer whenever it is required to -grow. The algorithm for resizing chosen is to snap up to sizes that are a -power of two which are sufficient to hold the intended new size. Memory -reallocation is not performed when the required size of the buffer is -decreased. This behavior can be relied on, and is necessary to make the -behaviour of balloc deterministic. This trades off additional memory usage -for decreasing the frequency for required reallocations: - -1. For any bstring whose size never exceeds n, its buffer is not ever - reallocated more than log_2(n) times for its lifetime. -2. For any bstring whose size never exceeds n, its buffer is never more than - 2*(n+1) in length. (The extra characters beyond 2*n are to allow for the - implicit '\0' which is always added by the bstring modifying functions.) - -Decreasing the buffer size when the string decreases in size would violate 1) -above and in real world case lead to pathological heap thrashing. Similarly, -allocating more tightly than "least power of 2 greater than necessary" would -lead to a violation of 1) and have the same potential for heap thrashing. - -Property 2) needs emphasizing. Although the memory allocated is always a -power of 2, for a bstring that grows linearly in size, its buffer memory also -grows linearly, not exponentially. The reason is that the amount of extra -space increases with each reallocation, which decreases the frequency of -future reallocations. - -Obviously, given that bstring writing functions may reallocate the data -buffer backing the target bstring, one should not attempt to cache the data -buffer address and use it after such bstring functions have been called. -This includes making reference struct tagbstrings which alias to a writable -bstring. - -balloc or bfromcstralloc can be used to preallocate the minimum amount of -space used for a given bstring. This will reduce even further the number of -times the data portion is reallocated. If the length of the string is never -more than one less than the memory length then there will be no further -reallocations. - -Note that invoking the bwriteallow macro may increase the number of reallocs -by one more than necessary for every call to bwriteallow interleaved with any -bstring API which writes to this bstring. - -The library does not use any mechanism for automatic clean up for the C API. -Thus explicit clean up via calls to bdestroy() are required to avoid memory -leaks. - -Constant and static tagbstrings: -................................ - -A struct tagbstring can be write protected from any bstrlib function using -the bwriteprotect macro. A write protected struct tagbstring can then be -reset to being writable via the bwriteallow macro. There is, of course, no -protection from attempts to directly access the bstring members. Modifying a -bstring which is write protected by direct access has undefined behavior. - -static struct tagbstrings can be declared via the bsStatic macro. They are -considered permanently unwritable. Such struct tagbstrings's are declared -such that attempts to write to it are not well defined. Invoking either -bwriteallow or bwriteprotect on static struct tagbstrings has no effect. - -struct tagbstring's initialized via btfromcstr or blk2tbstr are protected by -default but can be made writeable via the bwriteallow macro. If bwriteallow -is called on such struct tagbstring's, it is the programmer's responsibility -to ensure that: - -1) the buffer supplied was allocated from the heap. -2) bdestroy is not called on this tagbstring (unless the header itself has - also been allocated from the heap.) -3) free is called on the buffer to reclaim its memory. - -bwriteallow and bwriteprotect can be invoked on ordinary bstrings (they have -to be dereferenced with the (*) operator to get the levels of indirection -correct) to give them write protection. - -Buffer declaration: -................... - -The memory buffer is actually declared "unsigned char *" instead of "char *". -The reason for this is to trigger compiler warnings whenever uncasted char -buffers are assigned to the data portion of a bstring. This will draw more -diligent programmers into taking a second look at the code where they -have carelessly left off the typically required cast. (Research from -AT&T/Lucent indicates that additional programmer eyeballs is one of the most -effective mechanisms at ferreting out bugs.) - -Function pointers: -.................. - -The bgets, bread and bStream functions use function pointers to obtain -strings from data streams. The function pointer declarations have been -specifically chosen to be compatible with the fgetc and fread functions. -While this may seem to be a convoluted way of implementing fgets and fread -style functionality, it has been specifically designed this way to ensure -that there is no dependency on a single narrowly defined set of device -interfaces, such as just stream I/O. In the embedded world, its quite -possible to have environments where such interfaces may not exist in the -standard C library form. Furthermore, the generalization that this opens up -allows for more sophisticated uses for these functions (performing an fgets -like function on a socket, for example.) By using function pointers, it also -allows such abstract stream interfaces to be created using the bstring library -itself while not creating a circular dependency. - -Use of int's for sizes: -....................... - -This is just a recognition that 16bit platforms with requirements for strings -that are larger than 64K and 32bit+ platforms with requirements for strings -that are larger than 4GB are pretty marginal. The main focus is for 32bit -platforms, and emerging 64bit platforms with reasonable < 4GB string -requirements. Using ints allows for negative values which has meaning -internally to bstrlib. - -Semantic consideration: -....................... - -Certain care needs to be taken when copying and aliasing bstrings. A bstring -is essentially a pointer type which points to a multipart abstract data -structure. Thus usage, and lifetime of bstrings have semantics that follow -these considerations. For example: - - bstring a, b; - struct tagbstring t; - - a = bfromcstr("Hello"); /* Create new bstring and copy "Hello" into it. */ - b = a; /* Alias b to the contents of a. */ - t = *a; /* Create a current instance pseudo-alias of a. */ - bconcat (a, b); /* Double a and b, t is now undefined. */ - bdestroy (a); /* Destroy the contents of both a and b. */ - -Variables of type bstring are really just references that point to real -bstring objects. The equal operator (=) creates aliases, and the asterisk -dereference operator (*) creates a kind of alias to the current instance (which -is generally not useful for any purpose.) Using bstrcpy() is the correct way -of creating duplicate instances. The ampersand operator (&) is useful for -creating aliases to struct tagbstrings (remembering that constructed struct -tagbstrings are not writable by default.) - -CBStrings use complete copy semantics for the equal operator (=), and thus do -not have these sorts of issues. - -Debugging: -.......... - -Bstrings have a simple, exposed definition and construction, and the library -itself is open source. So most debugging is going to be fairly straight- -forward. But the memory for bstrings come from the heap, which can often be -corrupted indirectly, and it might not be obvious what has happened even from -direct examination of the contents in a debugger or a core dump. There are -some tools such as Purify, Insure++ and Electric Fence which can help solve -such problems, however another common approach is to directly instrument the -calls to malloc, realloc, calloc, free, memcpy, memmove and/or other calls -by overriding them with macro definitions. - -Although the user could hack on the Bstrlib sources directly as necessary to -perform such an instrumentation, Bstrlib comes with a built-in mechanism for -doing this. By defining the macro BSTRLIB_MEMORY_DEBUG and providing an -include file named memdbg.h this will force the core Bstrlib modules to -attempt to include this file. In such a file, macros could be defined which -overrides Bstrlib's useage of the C standard library. - -Rather than calling malloc, realloc, free, memcpy or memmove directly, Bstrlib -emits the macros bstr__alloc, bstr__realloc, bstr__free, bstr__memcpy and -bstr__memmove in their place respectively. By default these macros are simply -assigned to be equivalent to their corresponding C standard library function -call. However, if they are given earlier macro definitions (via the back -door include file) they will not be given their default definition. In this -way Bstrlib's interface to the standard library can be changed but without -having to directly redefine or link standard library symbols (both of which -are not strictly ANSI C compliant.) - -An example definition might include: - - #define bstr__alloc(sz) X_malloc ((sz), __LINE__, __FILE__) - -which might help contextualize heap entries in a debugging environment. - -The NULL parameter and sanity checking of bstrings is part of the Bstrlib -API, and thus Bstrlib itself does not present any different modes which would -correspond to "Debug" or "Release" modes. Bstrlib always contains mechanisms -which one might think of as debugging features, but retains the performance -and small memory footprint one would normally associate with release mode -code. - -Integration Microsoft's Visual Studio debugger: -............................................... - -Microsoft's Visual Studio debugger has a capability of customizable mouse -float over data type descriptions. This is accomplished by editting the -AUTOEXP.DAT file to include the following: - - ; new for CBString - tagbstring =slen= mlen= - Bstrlib::CBStringList =count= - -In Visual C++ 6.0 this file is located in the directory: - - C:\Program Files\Microsoft Visual Studio\Common\MSDev98\Bin - -and in Visual Studio .NET 2003 its located here: - - C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\Packages\Debugger - -This will improve the ability of debugging with Bstrlib under Visual Studio. - -Security --------- - -Bstrlib does not come with explicit security features outside of its fairly -comprehensive error detection, coupled with its strict semantic support. -That is to say that certain common security problems, such as buffer overrun, -constant overwrite, arbitrary truncation etc, are far less likely to happen -inadvertently. Where it does help, Bstrlib maximizes its advantage by -providing developers a simple adoption path that lets them leave less secure -string mechanisms behind. The library will not leave developers wanting, so -they will be less likely to add new code using a less secure string library -to add functionality that might be missing from Bstrlib. - -That said there are a number of security ideas not addressed by Bstrlib: - -1. Race condition exploitation (i.e., verifying a string's contents, then -raising the privilege level and execute it as a shell command as two -non-atomic steps) is well beyond the scope of what Bstrlib can provide. It -should be noted that MFC's built-in string mutex actually does not solve this -problem either -- it just removes immediate data corruption as a possible -outcome of such exploit attempts (it can be argued that this is worse, since -it will leave no trace of the exploitation). In general race conditions have -to be dealt with by careful design and implementation; it cannot be assisted -by a string library. - -2. Any kind of access control or security attributes to prevent usage in -dangerous interfaces such as system(). Perl includes a "trust" attribute -which can be endowed upon strings that are intended to be passed to such -dangerous interfaces. However, Perl's solution reflects its own limitations --- notably that it is not a strongly typed language. In the example code for -Bstrlib, there is a module called taint.cpp. It demonstrates how to write a -simple wrapper class for managing "untainted" or trusted strings using the -type system to prevent questionable mixing of ordinary untrusted strings with -untainted ones then passing them to dangerous interfaces. In this way the -security correctness of the code reduces to auditing the direct usages of -dangerous interfaces or promotions of tainted strings to untainted ones. - -3. Encryption of string contents is way beyond the scope of Bstrlib. -Maintaining encrypted string contents in the futile hopes of thwarting things -like using system-level debuggers to examine sensitive string data is likely -to be a wasted effort (imagine a debugger that runs at a higher level than a -virtual processor where the application runs). For more standard encryption -usages, since the bstring contents are simply binary blocks of data, this -should pose no problem for usage with other standard encryption libraries. - -Compatibility -------------- - -The Better String Library is known to compile and function correctly with the -following compilers: - - - Microsoft Visual C++ - - Watcom C/C++ - - Intel's C/C++ compiler (Windows) - - The GNU C/C++ compiler (cygwin and Linux on PPC64) - - Borland C - - Turbo C - -Setting of configuration options should be unnecessary for these compilers -(unless exceptions are being disabled or STLport has been added to WATCOM -C/C++). Bstrlib has been developed with an emphasis on portability. As such -porting it to other compilers should be straight forward. This package -includes a porting guide (called porting.txt) which explains what issues may -exist for porting Bstrlib to different compilers and environments. - -ANSI issues ------------ - -1. The function pointer types bNgetc and bNread have prototypes which are very -similar to, but not exactly the same as fgetc and fread respectively. -Basically the FILE * parameter is replaced by void *. The purpose of this -was to allow one to create other functions with fgetc and fread like -semantics without being tied to ANSI C's file streaming mechanism. I.e., one -could very easily adapt it to sockets, or simply reading a block of memory, -or procedurally generated strings (for fractal generation, for example.) - -The problem is that invoking the functions (bNgetc)fgetc and (bNread)fread is -not technically legal in ANSI C. The reason being that the compiler is only -able to coerce the function pointers themselves into the target type, however -are unable to perform any cast (implicit or otherwise) on the parameters -passed once invoked. I.e., if internally void * and FILE * need some kind of -mechanical coercion, the compiler will not properly perform this conversion -and thus lead to undefined behavior. - -Apparently a platform from Data General called "Eclipse" and another from -Tandem called "NonStop" have a different representation for pointers to bytes -and pointers to words, for example, where coercion via casting is necessary. -(Actual confirmation of the existence of such machines is hard to come by, so -it is prudent to be skeptical about this information.) However, this is not -an issue for any known contemporary platforms. One may conclude that such -platforms are effectively apocryphal even if they do exist. - -To correctly work around this problem to the satisfaction of the ANSI -limitations, one needs to create wrapper functions for fgets and/or -fread with the prototypes of bNgetc and/or bNread respectively which performs -no other action other than to explicitely cast the void * parameter to a -FILE *, and simply pass the remaining parameters straight to the function -pointer call. - -The wrappers themselves are trivial: - - size_t freadWrap (void * buff, size_t esz, size_t eqty, void * parm) { - return fread (buff, esz, eqty, (FILE *) parm); - } - - int fgetcWrap (void * parm) { - return fgetc ((FILE *) parm); - } - -These have not been supplied in bstrlib or bstraux to prevent unnecessary -linking with file I/O functions. - -2. vsnprintf is not available on all compilers. Because of this, the bformat -and bformata functions (and format and formata methods) are not guaranteed to -work properly. For those compilers that don't have vsnprintf, the -BSTRLIB_NOVSNP macro should be set before compiling bstrlib, and the format -functions/method will be disabled. - -The more recent ANSI C standards have specified the required inclusion of a -vsnprintf function. - -3. The bstrlib function names are not unique in the first 6 characters. This -is only an issue for older C compiler environments which do not store more -than 6 characters for function names. - -4. The bsafe module defines macros and function names which are part of the -C library. This simply overrides the definition as expected on all platforms -tested, however it is not sanctioned by the ANSI standard. This module is -clearly optional and should be omitted on platforms which disallow its -undefined semantics. - -In practice the real issue is that some compilers in some modes of operation -can/will inline these standard library functions on a module by module basis -as they appear in each. The linker will thus have no opportunity to override -the implementation of these functions for those cases. This can lead to -inconsistent behaviour of the bsafe module on different platforms and -compilers. - -=============================================================================== - -Comparison with Microsoft's CString class ------------------------------------------ - -Although developed independently, CBStrings have very similar functionality to -Microsoft's CString class. However, the bstring library has significant -advantages over CString: - -1. Bstrlib is a C-library as well as a C++ library (using the C++ wrapper). - - - Thus it is compatible with more programming environments and - available to a wider population of programmers. - -2. The internal structure of a bstring is considered exposed. - - - A single contiguous block of data can be cut into read-only pieces by - simply creating headers, without allocating additional memory to create - reference copies of each of these sub-strings. - - In this way, using bstrings in a totally abstracted way becomes a choice - rather than an imposition. Further this choice can be made differently - at different layers of applications that use it. - -3. Static declaration support precludes the need for constructor - invocation. - - - Allows for static declarations of constant strings that has no - additional constructor overhead. - -4. Bstrlib is not attached to another library. - - - Bstrlib is designed to be easily plugged into any other library - collection, without dependencies on other libraries or paradigms (such - as "MFC".) - -The bstring library also comes with a few additional functions that are not -available in the CString class: - - - bsetstr - - bsplit - - bread - - breplace (this is different from CString::Replace()) - - Writable indexed characters (for example a[i]='x') - -Interestingly, although Microsoft did implement mid$(), left$() and right$() -functional analogues (these are functions from GWBASIC) they seem to have -forgotten that mid$() could be also used to write into the middle of a string. -This functionality exists in Bstrlib with the bsetstr() and breplace() -functions. - -Among the disadvantages of Bstrlib is that there is no special support for -localization or wide characters. Such things are considered beyond the scope -of what bstrings are trying to deliver. CString essentially supports the -older UCS-2 version of Unicode via widechar_t as an application-wide compile -time switch. - -CString's also use built-in mechanisms for ensuring thread safety under all -situations. While this makes writing thread safe code that much easier, this -built-in safety feature has a price -- the inner loops of each CString method -runs in its own critical section (grabbing and releasing a light weight mutex -on every operation.) The usual way to decrease the impact of a critical -section performance penalty is to amortize more operations per critical -section. But since the implementation of CStrings is fixed as a one critical -section per-operation cost, there is no way to leverage this common -performance enhancing idea. - -The search facilities in Bstrlib are comparable to those in MFC's CString -class, though it is missing locale specific collation. But because Bstrlib -is interoperable with C's char buffers, it will allow programmers to write -their own string searching mechanism (such as Boyer-Moore), or be able to -choose from a variety of available existing string searching libraries (such -as those for regular expressions) without difficulty. - -Microsoft used a very non-ANSI conforming trick in its implementation to -allow printf() to use the "%s" specifier to output a CString correctly. This -can be convenient, but it is inherently not portable. CBString requires an -explicit cast, while bstring requires the data member to be dereferenced. -Microsoft's own documentation recommends casting, instead of relying on this -feature. - -Comparison with C++'s std::string ---------------------------------- - -This is the C++ language's standard STL based string class. - -1. There is no C implementation. -2. The [] operator is not bounds checked. -3. Missing a lot of useful functions like printf-like formatting. -4. Some sub-standard std::string implementations (SGI) are necessarily unsafe - to use with multithreading. -5. Limited by STL's std::iostream which in turn is limited by ifstream which - can only take input from files. (Compare to CBStream's API which can take - abstracted input.) -6. Extremely uneven performance across implementations. - -Comparison with ISO C TR 24731 proposal ---------------------------------------- - -Following the ISO C99 standard, Microsoft has proposed a group of C library -extensions which are supposedly "safer and more secure". This proposal is -expected to be adopted by the ISO C standard which follows C99. - -The proposal reveals itself to be very similar to Microsoft's "StrSafe" -library. The functions are basically the same as other standard C library -string functions except that destination parameters are paired with an -additional length parameter of type rsize_t. rsize_t is the same as size_t, -however, the range is checked to make sure its between 1 and RSIZE_MAX. Like -Bstrlib, the functions perform a "parameter check". Unlike Bstrlib, when a -parameter check fails, rather than simply outputing accumulatable error -statuses, they call a user settable global error function handler, and upon -return of control performs no (additional) detrimental action. The proposal -covers basic string functions as well as a few non-reenterable functions -(asctime, ctime, and strtok). - -1. Still based solely on char * buffers (and therefore strlen() and strcat() - is still O(n), and there are no faster streq() comparison functions.) -2. No growable string semantics. -3. Requires manual buffer length synchronization in the source code. -4. No attempt to enhance functionality of the C library. -5. Introduces a new error scenario (strings exceeding RSIZE_MAX length). - -The hope is that by exposing the buffer length requirements there will be -fewer buffer overrun errors. However, the error modes are really just -transformed, rather than removed. The real problem of buffer overflows is -that they all happen as a result of erroneous programming. So forcing -programmers to manually deal with buffer limits, will make them more aware of -the problem but doesn't remove the possibility of erroneous programming. So -a programmer that erroneously mixes up the rsize_t parameters is no better off -from a programmer that introduces potential buffer overflows through other -more typical lapses. So at best this may reduce the rate of erroneous -programming, rather than making any attempt at removing failure modes. - -The error handler can discriminate between types of failures, but does not -take into account any callsite context. So the problem is that the error is -going to be manifest in a piece of code, but there is no pointer to that -code. It would seem that passing in the call site __FILE__, __LINE__ as -parameters would be very useful, but the API clearly doesn't support such a -thing (it would increase code bloat even more than the extra length -parameter does, and would require macro tricks to implement). - -The Bstrlib C API takes the position that error handling needs to be done at -the callsite, and just tries to make it as painless as possible. Furthermore, -error modes are removed by supporting auto-growing strings and aliasing. For -capturing errors in more central code fragments, Bstrlib's C++ API uses -exception handling extensively, which is superior to the leaf-only error -handler approach. - -Comparison with Managed String Library CERT proposal ----------------------------------------------------- - -The main webpage for the managed string library: -http://www.cert.org/secure-coding/managedstring.html - -Robert Seacord at CERT has proposed a C string library that he calls the -"Managed String Library" for C. Like Bstrlib, it introduces a new type -which is called a managed string. The structure of a managed string -(string_m) is like a struct tagbstring but missing the length field. This -internal structure is considered opaque. The length is, like the C standard -library, always computed on the fly by searching for a terminating NUL on -every operation that requires it. So it suffers from every performance -problem that the C standard library suffers from. Interoperating with C -string APIs (like printf, fopen, or anything else that takes a string -parameter) requires copying to additionally allocating buffers that have to -be manually freed -- this makes this library probably slower and more -cumbersome than any other string library in existence. - -The library gives a fully populated error status as the return value of every -string function. The hope is to be able to diagnose all problems -specifically from the return code alone. Comparing this to Bstrlib, which -aways returns one consistent error message, might make it seem that Bstrlib -would be harder to debug; but this is not true. With Bstrlib, if an error -occurs there is always enough information from just knowing there was an error -and examining the parameters to deduce exactly what kind of error has -happened. The managed string library thus gives up nested function calls -while achieving little benefit, while Bstrlib does not. - -One interesting feature that "managed strings" has is the idea of data -sanitization via character set whitelisting. That is to say, a globally -definable filter that makes any attempt to put invalid characters into strings -lead to an error and not modify the string. The author gives the following -example: - - // create valid char set - if (retValue = strcreate_m(&str1, "abc") ) { - fprintf( - stderr, - "Error %d from strcreate_m.\n", - retValue - ); - } - if (retValue = setcharset(str1)) { - fprintf( - stderr, - "Error %d from setcharset().\n", - retValue - ); - } - if (retValue = strcreate_m(&str1, "aabbccabc")) { - fprintf( - stderr, - "Error %d from strcreate_m.\n", - retValue - ); - } - // create string with invalid char set - if (retValue = strcreate_m(&str1, "abbccdabc")) { - fprintf( - stderr, - "Error %d from strcreate_m.\n", - retValue - ); - } - -Which we can compare with a more Bstrlib way of doing things: - - bstring bCreateWithFilter (const char * cstr, const_bstring filter) { - bstring b = bfromcstr (cstr); - if (BSTR_ERR != bninchr (b, filter) && NULL != b) { - fprintf (stderr, "Filter violation.\n"); - bdestroy (b); - b = NULL; - } - return b; - } - - struct tagbstring charFilter = bsStatic ("abc"); - bstring str1 = bCreateWithFilter ("aabbccabc", &charFilter); - bstring str2 = bCreateWithFilter ("aabbccdabc", &charFilter); - -The first thing we should notice is that with the Bstrlib approach you can -have different filters for different strings if necessary. Furthermore, -selecting a charset filter in the Managed String Library is uni-contextual. -That is to say, there can only be one such filter active for the entire -program, which means its usage is not well defined for intermediate library -usage (a library that uses it will interfere with user code that uses it, and -vice versa.) It is also likely to be poorly defined in multi-threading -environments. - -There is also a question as to whether the data sanitization filter is checked -on every operation, or just on creation operations. Since the charset can be -set arbitrarily at run time, it might be set *after* some managed strings have -been created. This would seem to imply that all functions should run this -additional check every time if there is an attempt to enforce this. This -would make things tremendously slow. On the other hand, if it is assumed that -only creates and other operations that take char *'s as input need be checked -because the charset was only supposed to be called once at and before any -other managed string was created, then one can see that its easy to cover -Bstrlib with equivalent functionality via a few wrapper calls such as the -example given above. - -And finally we have to question the value of sanitation in the first place. -For example, for httpd servers, there is generally a requirement that the -URLs parsed have some form that avoids undesirable translation to local file -system filenames or resources. The problem is that the way URLs can be -encoded, it must be completely parsed and translated to know if it is using -certain invalid character combinations. That is to say, merely filtering -each character one at a time is not necessarily the right way to ensure that -a string has safe contents. - -In the article that describes this proposal, it is claimed that it fairly -closely approximates the existing C API semantics. On this point we should -compare this "closeness" with Bstrlib: - - Bstrlib Managed String Library - ------- ---------------------- - -Pointer arithmetic Segment arithmetic N/A - -Use in C Std lib ->data, or bdata{e} getstr_m(x,*) ... free(x) - -String literals bsStatic, bsStaticBlk strcreate_m() - -Transparency Complete None - -Its pretty clear that the semantic mapping from C strings to Bstrlib is fairly -straightforward, and that in general semantic capabilities are the same or -superior in Bstrlib. On the other hand the Managed String Library is either -missing semantics or changes things fairly significantly. - -Comparison with Annexia's c2lib library ---------------------------------------- - -This library is available at: -http://www.annexia.org/freeware/c2lib - -1. Still based solely on char * buffers (and therefore strlen() and strcat() - is still O(n), and there are no faster streq() comparison functions.) - Their suggestion that alternatives which wrap the string data type (such as - bstring does) imposes a difficulty in interoperating with the C langauge's - ordinary C string library is not founded. -2. Introduction of memory (and vector?) abstractions imposes a learning - curve, and some kind of memory usage policy that is outside of the strings - themselves (and therefore must be maintained by the developer.) -3. The API is massive, and filled with all sorts of trivial (pjoin) and - controvertial (pmatch -- regular expression are not sufficiently - standardized, and there is a very large difference in performance between - compiled and non-compiled, REs) functions. Bstrlib takes a decidely - minimal approach -- none of the functionality in c2lib is difficult or - challenging to implement on top of Bstrlib (except the regex stuff, which - is going to be difficult, and controvertial no matter what.) -4. Understanding why c2lib is the way it is pretty much requires a working - knowledge of Perl. bstrlib requires only knowledge of the C string library - while providing just a very select few worthwhile extras. -5. It is attached to a lot of cruft like a matrix math library (that doesn't - include any functions for getting the determinant, eigenvectors, - eigenvalues, the matrix inverse, test for singularity, test for - orthogonality, a grahm schmit orthogonlization, LU decomposition ... I - mean why bother?) - -Convincing a development house to use c2lib is likely quite difficult. It -introduces too much, while not being part of any kind of standards body. The -code must therefore be trusted, or maintained by those that use it. While -bstring offers nothing more on this front, since its so much smaller, covers -far less in terms of scope, and will typically improve string performance, -the barrier to usage should be much smaller. - -Comparison with stralloc/qmail ------------------------------- - -More information about this library can be found here: -http://www.canonical.org/~kragen/stralloc.html or here: -http://cr.yp.to/lib/stralloc.html - -1. Library is very very minimal. A little too minimal. -2. Untargetted source parameters are not declared const. -3. Slightly different expected emphasis (like _cats function which takes an - ordinary C string char buffer as a parameter.) Its clear that the - remainder of the C string library is still required to perform more - useful string operations. - -The struct declaration for their string header is essentially the same as that -for bstring. But its clear that this was a quickly written hack whose goals -are clearly a subset of what Bstrlib supplies. For anyone who is served by -stralloc, Bstrlib is complete substitute that just adds more functionality. - -stralloc actually uses the interesting policy that a NULL data pointer -indicates an empty string. In this way, non-static empty strings can be -declared without construction. This advantage is minimal, since static empty -bstrings can be declared inline without construction, and if the string needs -to be written to it should be constructed from an empty string (or its first -initializer) in any event. - -wxString class --------------- - -This is the string class used in the wxWindows project. A description of -wxString can be found here: -http://www.wxwindows.org/manuals/2.4.2/wx368.htm#wxstring - -This C++ library is similar to CBString. However, it is littered with -trivial functions (IsAscii, UpperCase, RemoveLast etc.) - -1. There is no C implementation. -2. The memory management strategy is to allocate a bounded fixed amount of - additional space on each resize, meaning that it does not have the - log_2(n) property that Bstrlib has (it will thrash very easily, cause - massive fragmentation in common heap implementations, and can easily be a - common source of performance problems). -3. The library uses a "copy on write" strategy, meaning that it has to deal - with multithreading problems. - -Vstr ----- - -This is a highly orthogonal C string library with an emphasis on -networking/realtime programming. It can be found here: -http://www.and.org/vstr/ - -1. The convoluted internal structure does not contain a '\0' char * compatible - buffer, so interoperability with the C library a non-starter. -2. The API and implementation is very large (owing to its orthogonality) and - can lead to difficulty in understanding its exact functionality. -3. An obvious dependency on gnu tools (confusing make configure step) -4. Uses a reference counting system, meaning that it is not likely to be - thread safe. - -The implementation has an extreme emphasis on performance for nontrivial -actions (adds, inserts and deletes are all constant or roughly O(#operations) -time) following the "zero copy" principle. This trades off performance of -trivial functions (character access, char buffer access/coersion, alias -detection) which becomes significantly slower, as well as incremental -accumulative costs for its searching/parsing functions. Whether or not Vstr -wins any particular performance benchmark will depend a lot on the benchmark, -but it should handily win on some, while losing dreadfully on others. - -The learning curve for Vstr is very steep, and it doesn't come with any -obvious way to build for Windows or other platforms without gnu tools. At -least one mechanism (the iterator) introduces a new undefined scenario -(writing to a Vstr while iterating through it.) Vstr has a very large -footprint, and is very ambitious in its total functionality. Vstr has no C++ -API. - -Vstr usage requires context initialization via vstr_init() which must be run -in a thread-local context. Given the totally reference based architecture -this means that sharing Vstrings across threads is not well defined, or at -least not safe from race conditions. This API is clearly geared to the older -standard of fork() style multitasking in UNIX, and is not safely transportable -to modern shared memory multithreading available in Linux and Windows. There -is no portable external solution making the library thread safe (since it -requires a mutex around each Vstr context -- not each string.) - -In the documentation for this library, a big deal is made of its self hosted -s(n)printf-like function. This is an issue for older compilers that don't -include vsnprintf(), but also an issue because Vstr has a slow conversion to -'\0' terminated char * mechanism. That is to say, using "%s" to format data -that originates from Vstr would be slow without some sort of native function -to do so. Bstrlib sidesteps the issue by relying on what snprintf-like -functionality does exist and having a high performance conversion to a char * -compatible string so that "%s" can be used directly. - -Str Library ------------ - -This is a fairly extensive string library, that includes full unicode support -and targetted at the goal of out performing MFC and STL. The architecture, -similarly to MFC's CStrings, is a copy on write reference counting mechanism. - -http://www.utilitycode.com/str/default.aspx - -1. Commercial. -2. C++ only. - -This library, like Vstr, uses a ref counting system. There is only so deeply -I can analyze it, since I don't have a license for it. However, performance -improvements over MFC's and STL, doesn't seem like a sufficient reason to -move your source base to it. For example, in the future, Microsoft may -improve the performance CString. - -It should be pointed out that performance testing of Bstrlib has indicated -that its relative performance advantage versus MFC's CString and STL's -std::string is at least as high as that for the Str library. - -libmib astrings ---------------- - -A handful of functional extensions to the C library that add dynamic string -functionality. -http://www.mibsoftware.com/libmib/astring/ - -This package basically references strings through char ** pointers and assumes -they are pointing to the top of an allocated heap entry (or NULL, in which -case memory will be newly allocated from the heap.) So its still up to user -to mix and match the older C string functions with these functions whenever -pointer arithmetic is used (i.e., there is no leveraging of the type system -to assert semantic differences between references and base strings as Bstrlib -does since no new types are introduced.) Unlike Bstrlib, exact string length -meta data is not stored, thus requiring a strlen() call on *every* string -writing operation. The library is very small, covering only a handful of C's -functions. - -While this is better than nothing, it is clearly slower than even the -standard C library, less safe and less functional than Bstrlib. - -To explain the advantage of using libmib, their website shows an example of -how dangerous C code: - - char buf[256]; - char *pszExtraPath = ";/usr/local/bin"; - - strcpy(buf,getenv("PATH")); /* oops! could overrun! */ - strcat(buf,pszExtraPath); /* Could overrun as well! */ - - printf("Checking...%s\n",buf); /* Some printfs overrun too! */ - -is avoided using libmib: - - char *pasz = 0; /* Must initialize to 0 */ - char *paszOut = 0; - char *pszExtraPath = ";/usr/local/bin"; - - if (!astrcpy(&pasz,getenv("PATH"))) /* malloc error */ exit(-1); - if (!astrcat(&pasz,pszExtraPath)) /* malloc error */ exit(-1); - - /* Finally, a "limitless" printf! we can use */ - asprintf(&paszOut,"Checking...%s\n",pasz);fputs(paszOut,stdout); - - astrfree(&pasz); /* Can use free(pasz) also. */ - astrfree(&paszOut); - -However, compare this to Bstrlib: - - bstring b, out; - - bcatcstr (b = bfromcstr (getenv ("PATH")), ";/usr/local/bin"); - out = bformat ("Checking...%s\n", bdatae (b, "")); - /* if (out && b) */ fputs (bdatae (out, ""), stdout); - bdestroy (b); - bdestroy (out); - -Besides being shorter, we can see that error handling can be deferred right -to the very end. Also, unlike the above two versions, if getenv() returns -with NULL, the Bstrlib version will not exhibit undefined behavior. -Initialization starts with the relevant content rather than an extra -autoinitialization step. - -libclc ------- - -An attempt to add to the standard C library with a number of common useful -functions, including additional string functions. -http://libclc.sourceforge.net/ - -1. Uses standard char * buffer, and adopts C 99's usage of "restrict" to pass - the responsibility to guard against aliasing to the programmer. -2. Adds no safety or memory management whatsoever. -3. Most of the supplied string functions are completely trivial. - -The goals of libclc and Bstrlib are clearly quite different. - -fireString ----------- - -http://firestuff.org/ - -1. Uses standard char * buffer, and adopts C 99's usage of "restrict" to pass - the responsibility to guard against aliasing to the programmer. -2. Mixes char * and length wrapped buffers (estr) functions, doubling the API - size, with safety limited to only half of the functions. - -Firestring was originally just a wrapper of char * functionality with extra -length parameters. However, it has been augmented with the inclusion of the -estr type which has similar functionality to stralloc. But firestring does -not nearly cover the functional scope of Bstrlib. - -Safe C String Library ---------------------- - -A library written for the purpose of increasing safety and power to C's string -handling capabilities. -http://www.zork.org/safestr/safestr.html - -1. While the safestr_* functions are safe in of themselves, interoperating - with char * string has dangerous unsafe modes of operation. -2. The architecture of safestr's causes the base pointer to change. Thus, - its not practical/safe to store a safestr in multiple locations if any - single instance can be manipulated. -3. Dependent on an additional error handling library. -4. Uses reference counting, meaning that it is either not thread safe or - slow and not portable. - -I think the idea of reallocating (and hence potentially changing) the base -pointer is a serious design flaw that is fatal to this architecture. True -safety is obtained by having automatic handling of all common scenarios -without creating implicit constraints on the user. - -Because of its automatic temporary clean up system, it cannot use "const" -semantics on input arguments. Interesting anomolies such as: - - safestr_t s, t; - s = safestr_replace (t = SAFESTR_TEMP ("This is a test"), - SAFESTR_TEMP (" "), SAFESTR_TEMP (".")); - /* t is now undefined. */ - -are possible. If one defines a function which takes a safestr_t as a -parameter, then the function would not know whether or not the safestr_t is -defined after it passes it to a safestr library function. The author -recommended method for working around this problem is to examine the -attributes of the safestr_t within the function which is to modify any of -its parameters and play games with its reference count. I think, therefore, -that the whole SAFESTR_TEMP idea is also fatally broken. - -The library implements immutability, optional non-resizability, and a "trust" -flag. This trust flag is interesting, and suggests that applying any -arbitrary sequence of safestr_* function calls on any set of trusted strings -will result in a trusted string. It seems to me, however, that if one wanted -to implement a trusted string semantic, one might do so by actually creating -a different *type* and only implement the subset of string functions that are -deemed safe (i.e., user input would be excluded, for example.) This, in -essence, would allow the compiler to enforce trust propogation at compile -time rather than run time. Non-resizability is also interesting, however, -it seems marginal (i.e., to want a string that cannot be resized, yet can be -modified and yet where a fixed sized buffer is undesirable.) - -Libsrt ------- - -This is a length based string library based on a slightly different strategy. -The string contents are appended to the end of the header directly so strings -only require a single allocation. However, whenever a reallocation occurs, -the header is replicated and the base pointer for the string is changed. -That means references to the string are only valid so long as they are not -resized after any such reference is cached. The internal structure maintains -a lot some state used to accelerate unicode manipulation. This makes -sustainable usage of the library essentially opaque. This also creates a -bottleneck for whatever extensions to the library one desires (write all -extensions on top of the base library, put in a request to the author, or -dedicate an expert to learn the internals of the library). The library is -committed to Unicode representation of its string data, and therefore cannot -be used as a generic buffer library. - -=============================================================================== - -Examples --------- - - Dumping a line numbered file: - - FILE * fp; - int i, ret; - struct bstrList * lines; - struct tagbstring prefix = bsStatic ("-> "); - - if (NULL != (fp = fopen ("bstrlib.txt", "rb"))) { - bstring b = bread ((bNread) fread, fp); - fclose (fp); - if (NULL != (lines = bsplit (b, '\n'))) { - for (i=0; i < lines->qty; i++) { - binsert (lines->entry[i], 0, &prefix, '?'); - printf ("%04d: %s\n", i, bdatae (lines->entry[i], "NULL")); - } - bstrListDestroy (lines); - } - bdestroy (b); - } - -For numerous other examples, see bstraux.c, bstraux.h and the example archive. - -=============================================================================== - -License -------- - -The Better String Library is available under either the BSD license (see the -accompanying license.txt) or the Gnu Public License version 2 (see the -accompanying gpl.txt) at the option of the user. - -=============================================================================== - -Acknowledgements ----------------- - -The following individuals have made significant contributions to the design -and testing of the Better String Library: - -Bjorn Augestad -Clint Olsen -Darryl Bleau -Fabian Cenedese -Graham Wideman -Ignacio Burgueno -International Business Machines Corporation -Ira Mica -John Kortink -Manuel Woelker -Marcel van Kervinck -Michael Hsieh -Richard A. Smith -Simon Ekstrom -Wayne Scott -Zed A. Shaw - -=============================================================================== diff --git a/bstrlib/buniutil.c b/bstrlib/buniutil.c deleted file mode 100644 index f8d38e5..0000000 --- a/bstrlib/buniutil.c +++ /dev/null @@ -1,274 +0,0 @@ -/* - * This source file is part of the bstring string library. This code was - * written by Paul Hsieh in 2002-2015, and is covered by the BSD open source - * license and the GPL. Refer to the accompanying documentation for details - * on usage and license. - */ - -/* - * buniutil.c - * - * This file is not necessarily part of the core bstring library itself, but - * is just an implementation of basic utf8 processing for bstrlib. Note that - * this module is dependent upon bstrlib.c and utf8util.c - */ - -#include "bstrlib.h" -#include "buniutil.h" - -#define UNICODE__CODE_POINT__REPLACEMENT_CHARACTER (0xFFFDL) - -/* int buIsUTF8Content (const_bstring bu) - * - * Scan string and return 1 if its entire contents is entirely UTF8 code - * points. Otherwise return 0. - */ -int buIsUTF8Content (const_bstring bu) { -struct utf8Iterator iter; - - if (NULL == bdata (bu)) return 0; - for (utf8IteratorInit (&iter, bu->data, bu->slen); - iter.next < iter.slen;) { - if (0 >= utf8IteratorGetNextCodePoint (&iter, -1)) return 0; - } - return 1; -} - -/* int buGetBlkUTF16 (cpUcs2* ucs2, int len, cpUcs4 errCh, const_bstring bu, - * int pos) - * - * Convert a string of UTF8 codepoints (bu) skipping the first pos, into a - * sequence of UTF16 encoded code points. Returns the number of UCS2 16-bit - * words written to the output. No more than len words are written to the - * target array ucs2. If any code point in bu is unparsable, it will be - * translated to errCh. - */ -int buGetBlkUTF16 (/* @out */ cpUcs2* ucs2, int len, cpUcs4 errCh, const_bstring bu, int pos) { -struct tagbstring t; -struct utf8Iterator iter; -cpUcs4 ucs4; -int i, j; - - if (!isLegalUnicodeCodePoint (errCh)) errCh = UNICODE__CODE_POINT__REPLACEMENT_CHARACTER; - if (NULL == ucs2 || 0 >= len || NULL == bdata (bu) || 0 > pos) return BSTR_ERR; - - for (j=0, i=0; j < bu->slen; j++) { - if (0x80 != (0xC0 & bu->data[j])) { - if (i >= pos) break; - i++; - } - } - - t.mlen = -1; - t.data = bu->data + j; - t.slen = bu->slen - j; - - utf8IteratorInit (&iter, t.data, t.slen); - - ucs4 = BSTR_ERR; - for (i=0; 0 < len && iter.next < iter.slen && - 0 <= (ucs4 = utf8IteratorGetNextCodePoint (&iter, errCh)); i++) { - if (ucs4 < 0x10000) { - *ucs2++ = (cpUcs2) ucs4; - len--; - } else { - if (len < 2) { - *ucs2++ = UNICODE__CODE_POINT__REPLACEMENT_CHARACTER; - len--; - } else { - long y = ucs4 - 0x10000; - ucs2[0] = (cpUcs2) (0xD800 | (y >> 10)); - ucs2[1] = (cpUcs2) (0xDC00 | (y & 0x03FF)); - len -= 2; - ucs2 += 2; - i++; - } - } - } - while (0 < len) { - *ucs2++ = 0; - len--; - } - - utf8IteratorUninit (&iter); - if (0 > ucs4) return BSTR_ERR; - return i; -} - -/* - -Unicode UTF-8 -------- ----- -U-00000000 - U-0000007F: 0xxxxxxx -U-00000080 - U-000007FF: 110xxxxx 10xxxxxx -U-00000800 - U-0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx -U-00010000 - U-001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx - -U-00200000 - U-03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx -U-04000000 - U-7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx - -UTF-32: U-000000 - U-10FFFF - -*/ - -/* int buAppendBlkUcs4 (bstring b, const cpUcs4* bu, int len, cpUcs4 errCh) - * - * Convert an array of UCS4 code points (bu) to UTF8 codepoints b. Any - * invalid code point is replaced by errCh. If errCh is itself not a - * valid code point, then this translation will halt upon the first error - * and return BSTR_ERR. Otherwise BSTR_OK is returned. - */ -int buAppendBlkUcs4 (bstring b, const cpUcs4* bu, int len, cpUcs4 errCh) { -int i, oldSlen; - - if (NULL == bu || NULL == b || 0 > len || 0 > (oldSlen = blengthe (b, -1))) return BSTR_ERR; - if (!isLegalUnicodeCodePoint (errCh)) errCh = ~0; - - for (i=0; i < len; i++) { - unsigned char c[6]; - cpUcs4 v = bu[i]; - - if (!isLegalUnicodeCodePoint (v)) { - if (~0 == errCh) { - b->slen = oldSlen; - return BSTR_ERR; - } - v = errCh; - } - - if (v < 0x80) { - if (BSTR_OK != bconchar (b, (char) v)) { - b->slen = oldSlen; - return BSTR_ERR; - } - } else if (v < 0x800) { - c[0] = (unsigned char) ( (v >> 6) + 0xc0); - c[1] = (unsigned char) (( v & 0x3f) + 0x80); - if (BSTR_OK != bcatblk (b, c, 2)) { - b->slen = oldSlen; - return BSTR_ERR; - } - } else if (v < 0x10000) { - c[0] = (unsigned char) ( (v >> 12) + 0xe0); - c[1] = (unsigned char) (((v >> 6) & 0x3f) + 0x80); - c[2] = (unsigned char) (( v & 0x3f) + 0x80); - if (BSTR_OK != bcatblk (b, c, 3)) { - b->slen = oldSlen; - return BSTR_ERR; - } - } else -#if 0 - if (v < 0x200000) -#endif - { - c[0] = (unsigned char) ( (v >> 18) + 0xf0); - c[1] = (unsigned char) (((v >> 12) & 0x3f) + 0x80); - c[2] = (unsigned char) (((v >> 6) & 0x3f) + 0x80); - c[3] = (unsigned char) (( v & 0x3f) + 0x80); - if (BSTR_OK != bcatblk (b, c, 4)) { - b->slen = oldSlen; - return BSTR_ERR; - } - } -#if 0 - else if (v < 0x4000000) { - c[0] = (unsigned char) ( (v >> 24) + 0xf8); - c[1] = (unsigned char) (((v >> 18) & 0x3f) + 0x80); - c[2] = (unsigned char) (((v >> 12) & 0x3f) + 0x80); - c[3] = (unsigned char) (((v >> 6) & 0x3f) + 0x80); - c[4] = (unsigned char) (( v & 0x3f) + 0x80); - if (BSTR_OK != bcatblk (b, c, 5)) { - b->slen = oldSlen; - return BSTR_ERR; - } - } else { - c[0] = (unsigned char) ( (v >> 30) + 0xfc); - c[1] = (unsigned char) (((v >> 24) & 0x3f) + 0x80); - c[2] = (unsigned char) (((v >> 18) & 0x3f) + 0x80); - c[3] = (unsigned char) (((v >> 12) & 0x3f) + 0x80); - c[4] = (unsigned char) (((v >> 6) & 0x3f) + 0x80); - c[5] = (unsigned char) (( v & 0x3f) + 0x80); - if (BSTR_OK != bcatblk (b, c, 6)) { - b->slen = oldSlen; - return BSTR_ERR; - } - } -#endif - } - return BSTR_OK; -} - -#define endSwap(cs,mode) ((mode) ? ((((cs) & 0xFF) << 8) | (((cs) >> 8) & 0xFF)) : (cs)) -#define TEMP_UCS4_BUFFER_SIZE (64) - -/* int buAppendBlkUTF16 (bstring bu, const cpUcs2* utf16, int len, - * cpUcs2* bom, cpUcs4 errCh) - * - * Append an array of UCS2 code points (utf16) to UTF8 codepoints (bu). Any - * invalid code point is replaced by errCh. If errCh is itself not a - * valid code point, then this translation will halt upon the first error - * and return BSTR_ERR. Otherwise BSTR_OK is returned. If a byte order mark - * has been previously read, it may be passed in as bom, otherwise if *bom is - * set to 0, it will be filled in with the BOM as read from the first - * character if it is a BOM. - */ -int buAppendBlkUTF16 (bstring bu, const cpUcs2* utf16, int len, cpUcs2* bom, cpUcs4 errCh) { -cpUcs4 buff[TEMP_UCS4_BUFFER_SIZE]; -int cc, i, sm, oldSlen; - - if (NULL == bdata(bu) || NULL == utf16 || len < 0) return BSTR_ERR; - if (!isLegalUnicodeCodePoint (errCh)) errCh = ~0; - if (len == 0) return BSTR_OK; - - oldSlen = bu->slen; - i = 0; - - /* Check for BOM character and select endianess. Also remove the - BOM from the stream, since there is no need for it in a UTF-8 encoding. */ - if (bom && (cpUcs2) 0xFFFE == *bom) { - sm = 8; - } else if (bom && (cpUcs2) 0xFEFF == *bom) { - sm = 0; - } else if (utf16[i] == (cpUcs2) 0xFFFE) { - if (bom) *bom = utf16[i]; - sm = 8; - i++; - } else if (utf16[i] == (cpUcs2) 0xFEFF) { - if (bom) *bom = utf16[i]; - sm = 0; - i++; - } else { - sm = 0; /* Assume local endianness. */ - } - - cc = 0; - for (;i < len; i++) { - cpUcs4 c, v; - v = endSwap (utf16[i], sm); - - if ((v | 0x7FF) == 0xDFFF) { /* Deal with surrogate pairs */ - if (v >= 0xDC00 || i >= len) { - ErrMode:; - if (~0 == errCh) { - ErrReturn:; - bu->slen = oldSlen; - return BSTR_ERR; - } - v = errCh; - } else { - i++; - if ((c = endSwap (utf16[i], sm) - 0xDC00) > 0x3FF) goto ErrMode; - v = ((v - 0xD800) << 10) + c + 0x10000; - } - } - buff[cc] = v; - cc++; - if (cc >= TEMP_UCS4_BUFFER_SIZE) { - if (0 > buAppendBlkUcs4 (bu, buff, cc, errCh)) goto ErrReturn; - cc = 0; - } - } - if (cc > 0 && 0 > buAppendBlkUcs4 (bu, buff, cc, errCh)) goto ErrReturn; - - return BSTR_OK; -} diff --git a/bstrlib/buniutil.h b/bstrlib/buniutil.h deleted file mode 100644 index 1017212..0000000 --- a/bstrlib/buniutil.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * This source file is part of the bstring string library. This code was - * written by Paul Hsieh in 2002-2015, and is covered by the BSD open source - * license and the GPL. Refer to the accompanying documentation for details - * on usage and license. - */ - -/* - * buniutil.h - * - * This file is the interface for the buniutil basic "Unicode for bstrings" - * functions. Note that there are dependencies on bstrlib.h and utf8util.h . - */ - -#ifndef BSTRLIB_UNICODE_UTILITIES -#define BSTRLIB_UNICODE_UTILITIES - -#include "utf8util.h" -#include "bstrlib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -extern int buIsUTF8Content (const_bstring bu); -extern int buAppendBlkUcs4 (bstring b, const cpUcs4* bu, int len, cpUcs4 errCh); - -/* For those unfortunate enough to be stuck supporting UTF16. */ -extern int buGetBlkUTF16 (/* @out */ cpUcs2* ucs2, int len, cpUcs4 errCh, const_bstring bu, int pos); -extern int buAppendBlkUTF16 (bstring bu, const cpUcs2* utf16, int len, cpUcs2* bom, cpUcs4 errCh); - -#ifdef __cplusplus -} -#endif - -#endif /* BSTRLIB_UNICODE_UTILITIES */ - diff --git a/bstrlib/gpl.txt b/bstrlib/gpl.txt deleted file mode 100644 index d511905..0000000 --- a/bstrlib/gpl.txt +++ /dev/null @@ -1,339 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Lesser General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. diff --git a/bstrlib/porting.txt b/bstrlib/porting.txt deleted file mode 100644 index 11d8d13..0000000 --- a/bstrlib/porting.txt +++ /dev/null @@ -1,172 +0,0 @@ -Better String library Porting Guide ------------------------------------ - -by Paul Hsieh - -The bstring library is an attempt to provide improved string processing -functionality to the C and C++ language. At the heart of the bstring library -is the management of "bstring"s which are a significant improvement over '\0' -terminated char buffers. See the accompanying documenation file bstrlib.txt -for more information. - -=============================================================================== - -Identifying the Compiler ------------------------- - -Bstrlib has been tested on the following compilers: - - Microsoft Visual C++ - Watcom C/C++ (32 bit flat) - Intel's C/C++ compiler (on Windows) - The GNU C/C++ compiler (on Windows/Linux on x86 and PPC64) - Borland C++ - Turbo C - -There are slight differences in these compilers which requires slight -differences in the implementation of Bstrlib. These are accomodated in the -same sources using #ifdef/#if defined() on compiler specific macros. To -port Bstrlib to a new compiler not listed above, it is recommended that the -same strategy be followed. If you are unaware of the compiler specific -identifying preprocessor macro for your compiler you might find it here: - -http://predef.sourceforge.net/precomp.html - -Note that Intel C/C++ on Windows sets the Microsoft identifier: _MSC_VER. - -16-bit vs. 32-bit vs. 64-bit Systems ------------------------------------- - -Bstrlib has been architected to deal with strings of length between 0 and -INT_MAX (inclusive). Since the values of int are never higher than size_t -there will be no issue here. Note that on most 64-bit systems int is 32-bit. - -Dependency on The C-Library ---------------------------- - -Bstrlib uses the functions memcpy, memmove, malloc, realloc, free and -vsnprintf. Many free standing C compiler implementations that have a mode in -which the C library is not available will typically not include these -functions which will make porting Bstrlib to it onerous. Bstrlib is not -designed for such bare bones compiler environments. This usually includes -compilers that target ROM environments. - -Porting Issues --------------- - -Bstrlib has been written completely in ANSI/ISO C and ISO C++, however, there -are still a few porting issues. These are described below. - -1. The vsnprintf () function. - -Unfortunately, the earlier ANSI/ISO C standards did not include this function. -If the compiler of interest does not support this function then the -BSTRLIB_NOVSNP should be defined via something like: - - #if !defined (BSTRLIB_VSNP_OK) && !defined (BSTRLIB_NOVSNP) - # if defined (__TURBOC__) || defined (__COMPILERVENDORSPECIFICMACRO__) - # define BSTRLIB_NOVSNP - # endif - #endif - -which appears at the top of bstrlib.h. Note that the bformat(a) functions -will not be declared or implemented if the BSTRLIB_NOVSNP macro is set. If -the compiler has renamed vsnprintf() to some other named function, then -search for the definition of the exvsnprintf macro in bstrlib.c file and be -sure its defined appropriately: - - #if defined (__COMPILERVENDORSPECIFICMACRO__) - # define exvsnprintf(r,b,n,f,a) {r=__compiler_specific_vsnprintf(b,n,f,a);} - #else - # define exvsnprintf(r,b,n,f,a) {r=vsnprintf(b,n,f,a);} - #endif - -Take notice of the return value being captured in the variable r. It is -assumed that r exceeds n if and only if the underlying vsnprintf function has -determined what the true maximal output length would be for output if the -buffer were large enough to hold it. Non-modern implementations must output a -lesser number (the macro can and should be modified to ensure this). - -2. Weak C++ compiler. - -C++ is a much more complicated language to implement than C. This has lead -to varying quality of compiler implementations. The weaknesses isolated in -the initial ports are inclusion of the Standard Template Library, -std::iostream and exception handling. By default it is assumed that the C++ -compiler supports all of these things correctly. If your compiler does not -support one or more of these define the corresponding macro: - - BSTRLIB_CANNOT_USE_STL - BSTRLIB_CANNOT_USE_IOSTREAM - BSTRLIB_DOESNT_THROW_EXCEPTIONS - -The compiler specific detected macro should be defined at the top of -bstrwrap.h in the Configuration defines section. Note that these disabling -macros can be overrided with the associated enabling macro if a subsequent -version of the compiler gains support. (For example, its possible to rig -up STLport to provide STL support for WATCOM C/C++, so -DBSTRLIB_CAN_USE_STL -can be passed in as a compiler option.) - -3. The bsafe module, and reserved words. - -The bsafe module is in gross violation of the ANSI/ISO C standard in the -sense that it redefines what could be implemented as reserved words on a -given compiler. The typical problem is that a compiler may inline some of the -functions and thus not be properly overridden by the definitions in the bsafe -module. It is also possible that a compiler may prohibit the redefinitions in -the bsafe module. Compiler specific action will be required to deal with -these situations. - -Platform Specific Files ------------------------ - -The makefiles for the examples are basically setup of for particular -environments for each platform. In general these makefiles are not portable -and should be constructed as necessary from scratch for each platform. - -Testing a port --------------- - -To test that a port compiles correctly do the following: - -1. Build a sample project that includes the bstrlib, bstraux, bstrwrap, and - bsafe modules. -2. Compile bstest against the bstrlib module. -3. Run bstest and ensure that 0 errors are reported. -4. Compile test against the bstrlib and bstrwrap modules. -5. Run test and ensure that 0 errors are reported. -6. Compile each of the examples (except for the "re" example, which may be - complicated and is not a real test of bstrlib and except for the mfcbench - example which is Windows specific.) -7. Run each of the examples. - -The builds must have 0 errors, and should have the absolute minimum number of -warnings (in most cases can be reduced to 0.) The result of execution should -be essentially identical on each platform. - -Performance ------------ - -Different CPU and compilers have different capabilities in terms of -performance. It is possible for Bstrlib to assume performance -characteristics that a platform doesn't have (since it was primarily -developed on just one platform). The goal of Bstrlib is to provide very good -performance on all platforms regardless of this but without resorting to -extreme measures (such as using assembly language, or non-portable intrinsics -or library extensions.) - -There are two performance benchmarks that can be found in the example/ -directory. They are: cbench.c and cppbench.cpp. These are variations and -expansions of a benchmark for another string library. They don't cover all -string functionality, but do include the most basic functions which will be -common in most string manipulation kernels. - -............................................................................... - -Feedback --------- - -In all cases, you may email issues found to the primary author of Bstrlib at -the email address: websnarf@users.sourceforge.net - -=============================================================================== diff --git a/bstrlib/security.txt b/bstrlib/security.txt deleted file mode 100644 index d3f5c90..0000000 --- a/bstrlib/security.txt +++ /dev/null @@ -1,217 +0,0 @@ -Better String library Security Statement ----------------------------------------- - -by Paul Hsieh - -=============================================================================== - -Introduction ------------- - -The Better String library (hereafter referred to as Bstrlib) is an attempt to -provide improved string processing functionality to the C and C++ languages. -At the heart of the Bstrlib is the management of "bstring"s which are a -significant improvement over '\0' terminated char buffers. See the -accompanying documenation file bstrlib.txt for more information. - -DISCLAIMER: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND -CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT -NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -Like any software, there is always a possibility of failure due to a flawed -implementation. Nevertheless a good faith effort has been made to minimize -such flaws in Bstrlib. Use of Bstrlib by itself will not make an application -secure or free from implementation failures, however, it is the author's -conviction that use of Bstrlib can greatly facilitate the creation of -software meeting the highest possible standards of security. - -Part of the reason why this document has been created, is for the purpose of -security auditing, or the creation of further "Statements on Security" for -software that is created that uses Bstrlib. An auditor may check the claims -below against Bstrlib, and use this as a basis for analysis of software which -uses Bstrlib. - -=============================================================================== - -Statement on Security ---------------------- - -This is a document intended to give consumers of the Better String Library -who are interested in security an idea of where the Better String Library -stands on various security issues. Any deviation observed in the actual -library itself from the descriptions below should be considered an -implementation error, not a design flaw. - -This statement is not an analytical proof of correctness or an outline of one -but rather an assertion similar to a scientific claim or hypothesis. By use, -testing and open independent examination (otherwise known as scientific -falsifiability), the credibility of the claims made below can rise to the -level of an established theory. - -Common security issues: -....................... - -1. Buffer Overflows - -The Bstrlib API allows the programmer a way to deal with strings without -having to deal with the buffers containing them. Ordinary usage of the -Bstrlib API itself makes buffer overflows impossible. - -Furthermore, the Bstrlib API has a superset of basic string functionality as -compared to the C library's char * functions, C++'s std::string class and -Microsoft's MFC based CString class. It also has abstracted mechanisms for -dealing with IO. This is important as it gives developers a way of migrating -all their code from a functionality point of view. - -2. Memory size overflow/wrap around attack - -By design, Bstrlib is impervious to memory size overflow attacks. The -reason is that it detects length overflows and leads to a result error before -the operation attempts to proceed. Attempted conversions of char* strings -which may have lengths greater than INT_MAX are detected and the conversion -is aborted. If the memory to hold the string exceeds the available memory -for it, again, the result is aborted without changing the prior state of the -strings. - -3. Constant string protection - -Bstrlib implements runtime enforced constant and read-only string semantics. -I.e., bstrings which are declared as constant via the bsStatic() macro cannot -be modified or deallocated directly through the Bstrlib API, and this cannot -be subverted by casting or other type coercion. This is independent of the -use of the const_bstring data type. - -The Bstrlib C API uses the type const_bstring to specify bstring parameters -whose contents do not change. Although the C language cannot enforce this, -this is nevertheless guaranteed by the implementation of the Bstrlib library -of C functions. The C++ API enforces the const attribute on CBString types -correctly. - -4. Aliased bstring support - -Bstrlib detects and supports aliased parameter management throughout the API. -The kind of aliasing that is allowed is the one where pointers of the same -basic type may be pointing to overlapping objects (this is the assumption the -ANSI C99 specification makes.) Each function behaves as if all read-only -parameters were copied to temporaries which are used in their stead before -the function is enacted (it rarely actually does this). No function in the -Bstrlib uses the "restrict" parameter attribute from the ANSI C99 -specification. - -5. Information leaking - -In bstraux.h, using the semantically equivalent macros bSecureDestroy() and -bSecureWriteProtect() in place of bdestroy() and bwriteprotect() respectively -will ensure that stale data does not linger in the heap's free space after -strings have been released back to memory. Created bstrings or CBStrings -are not linked to anything external to themselves, and thus cannot expose -deterministic data leaking. If a bstring is resized, the preimage may exist -as a copy that is released to the heap. Thus for sensitive data, the bstring -should be sufficiently presized before manipulated so that it is not resized. -bSecureInput() has been supplied in bstraux.c, which can be used to obtain -input securely without any risk of leaving any part of the input image in the -heap except for the allocated bstring that is returned. - -6. Memory leaking - -Bstrlib can be built using memdbg.h enabled via the BSTRLIB_MEMORY_DEBUG -macro. User generated definitions for malloc, realloc and free can then be -supplied which can implement special strategies for memory corruption -detection or memory leaking. Otherwise, bstrlib does not do anything out of -the ordinary to attempt to deal with the standard problem of memory leaking -(i.e., losing references to allocated memory) when programming in the C and -C++ languages. However, it does not compound the problem any more than exists -either, as it doesn't have any intrinsic inescapable leaks in it. Bstrlib -does not preclude the use of automatic garbage collection mechanisms such as -the Boehm garbage collector. - -7. Encryption - -Bstrlib does not present any built-in encryption mechanism. However, it -supports full binary contents in its data buffers, so any standard block -based encryption mechanism can make direct use of bstrings/CBStrings for -buffer management. - -8. Double freeing - -Freeing a pointer that is already free is an extremely rare, but nevertheless -a potentially ruthlessly corrupting operation (its possible to cause Win 98 to -reboot, by calling free mulitiple times on already freed data using the WATCOM -CRT.) Bstrlib invalidates the bstring header data before freeing, so that in -many cases a double free will be detected and an error will be reported -(though this behaviour is not guaranteed and should not be relied on). - -Using bstrFree pervasively (instead of bdestroy) can lead to somewhat -improved invalid free avoidance (it is completely safe whenever bstring -instances are only stored in unique variables). For example: - - struct tagbstring hw = bsStatic ("Hello, world"); - bstring cpHw = bstrcpy (&hw); - - #ifdef NOT_QUITE_AS_SAFE - bdestroy (cpHw); /* Never fail */ - bdestroy (cpHw); /* Error sometimes detected at runtime */ - bdestroy (&hw); /* Error detected at run time */ - #else - bstrFree (cpHw); /* Never fail */ - bstrFree (cpHw); /* Will do nothing */ - bstrFree (&hw); /* Will lead to a compile time error */ - #endif - -9. Resource based denial of service - -bSecureInput() has been supplied in bstraux.c. It has an optional upper limit -for input length. But unlike fgets(), it is also easily determined if the -buffer has been truncated early. In this way, a program can set an upper -limit on input sizes while still allowing for implementing context specific -truncation semantics (i.e., does the program consume but dump the extra -input, or does it consume it in later inputs?) - -10. Mixing char *'s and bstrings - -The bstring and char * representations are not identical. So there is a risk -when converting back and forth that data may lost. Essentially bstrings can -contain '\0' as a valid non-terminating character, while char * strings -cannot and in fact must use the character as a terminator. The risk of data -loss is very low, since: - - A) the simple method of only using bstrings in a char * semantically - compatible way is both easy to achieve and pervasively supported. - B) obtaining '\0' content in a string is either deliberate or indicative - of another, likely more serious problem in the code. - C) the library comes with various functions which deal with this issue - (namely: bfromcstr(), bstr2cstr (), and bSetCstrChar ()) - -Marginal security issues: -......................... - -11. 8-bit versus 9-bit portability - -Bstrlib uses CHAR_BIT and other limits.h constants to the maximum extent -possible to avoid portability problems. However, Bstrlib has not been tested -on any system that does not represent char as 8-bits. So whether or not it -works on 9-bit systems is an open question. It is recommended that Bstrlib be -carefully auditted by anyone using a system in which CHAR_BIT is not 8. - -12. EBCDIC/ASCII/UTF-8 data representation attacks. - -Bstrlib uses ctype.h functions to ensure that it remains portable to non- -ASCII systems. It also checks range to make sure it is well defined even for -data that ANSI does not define for the ctype functions. - -Obscure issues: -............... - -13. Data attributes - -There is no support for a Perl-like "taint" attribute, although this is a -fairly straightforward exercise using C++'s type system. - diff --git a/bstrlib/test.cpp b/bstrlib/test.cpp deleted file mode 100644 index 9503342..0000000 --- a/bstrlib/test.cpp +++ /dev/null @@ -1,1725 +0,0 @@ -// -// This source file is part of the bstring string library. This code was -// written by Paul Hsieh in 2002-2015, and is covered by the BSD open source -// license. Refer to the accompanying documentation for details on usage and -// license. -// - -// -// test.cpp -// -// This file is the C++ unit test for Bstrlib -// - -#if defined (_MSC_VER) -# define _CRT_SECURE_NO_WARNINGS -#endif - -#include -#include -#include "bstrlib.h" -#include "bstrwrap.h" - -// Exceptions must be turned on in the compiler to successfully run -// this test. The compiler must also support STL. - -#define dumpOutQty (32) -static bstring dumpOut[dumpOutQty]; -static unsigned int rot = 0; - -const char * dumpBstring (const bstring b) { - rot = (rot + 1) % (unsigned) dumpOutQty; - if (dumpOut[rot] == NULL) { - dumpOut[rot] = bfromcstr (""); - if (dumpOut[rot] == NULL) return "FATAL INTERNAL ERROR"; - } - dumpOut[rot]->slen = 0; - if (b == NULL) { - bcatcstr (dumpOut[rot], "NULL"); - } else { - char msg[32]; - sprintf (msg, "%p", (void *)b); - bcatcstr (dumpOut[rot], msg); - - if (b->slen < 0) { - sprintf (msg, ":[err:slen=%d<0]", b->slen); - bcatcstr (dumpOut[rot], msg); - } else { - if (b->mlen > 0 && b->mlen < b->slen) { - sprintf (msg, ":[err:mlen=%dmlen, b->slen); - bcatcstr (dumpOut[rot], msg); - } else { - if (b->mlen == -1) { - bcatcstr (dumpOut[rot], "[p]"); - } else if (b->mlen < 0) { - bcatcstr (dumpOut[rot], "[c]"); - } - bcatcstr (dumpOut[rot], ":"); - if (b->data == NULL) { - bcatcstr (dumpOut[rot], "[err:data=NULL]"); - } else { - bcatcstr (dumpOut[rot], "\""); - bcatcstr (dumpOut[rot], (const char *) b->data); - bcatcstr (dumpOut[rot], "\""); - } - } - } - } - return (const char *) dumpOut[rot]->data; -} - -int test0 (void) { -int ret = 0; - - printf ("TEST: CBString constructor\n"); - - try { - printf ("\tCBString c;\n"); - CBString c0; - ret += (0 != c0.length()); - ret += '\0' != ((const char *)c0)[c0.length()]; - - printf ("\tCBString c(\"test\");\n"); - CBString c1 ("test"); - ret += (c1 != "test"); - ret += '\0' != ((const char *)c1)[c1.length()]; - - printf ("\tCBString c(25, \"test\");\n"); - CBString c8 (25, "test"); - ret += (c8 != "test"); - ret += c8.mlen < 25; - ret += '\0' != ((const char *)c8)[c8.length()]; - - printf ("\tCBString c('t');\n"); - CBString c2 ('t'); - ret += (c2 != "t"); - ret += '\0' != ((const char *)c2)[c2.length()]; - - printf ("\tCBString c('\\0');\n"); - CBString c3 ('\0'); - ret += (1 != c3.length()) || ('\0' != c3[0]); - ret += '\0' != ((const char *)c3)[c3.length()]; - - printf ("\tCBString c(bstr[\"test\"]);\n"); - struct tagbstring t = bsStatic ("test"); - CBString c4 (t); - ret += (c4 != t.data); - ret += '\0' != ((const char *)c4)[c4.length()]; - - printf ("\tCBString c(CBstr[\"test\"]);\n"); - CBString c5 (c1); - ret += (c1 != c5); - ret += '\0' != ((const char *)c5)[c5.length()]; - - printf ("\tCBString c('x',5);\n"); - CBString c6 ('x',5); - ret += (c6 != "xxxxx"); - ret += '\0' != ((const char *)c6)[c6.length()]; - - printf ("\tCBString c(\"123456\",4);\n"); - CBString c7 ((void *)"123456",4); - ret += (c7 != "1234"); - ret += '\0' != ((const char *)c7)[c7.length()]; - } - - catch (struct CBStringException err) { - printf ("Exception thrown [%d]: %s\n", __LINE__, err.what()); - ret ++; - } - - printf ("\t# failures: %d\n", ret); - return ret; -} - -#define EXCEPTION_EXPECTED(line) \ - try { \ - line; \ - ret++; \ - printf ("\tException was expected\n"); \ - } \ - catch (struct CBStringException) { } - -int test1 (void) { -int ret = 0; - - printf ("TEST: CBString = operator\n"); - - try { - CBString c0; - struct tagbstring t = bsStatic ("test"); - - ret += c0.iswriteprotected(); - c0.writeprotect (); - ret += 1 != c0.iswriteprotected(); - EXCEPTION_EXPECTED (c0 = 'x'); - EXCEPTION_EXPECTED (c0 = (unsigned char) 'x'); - EXCEPTION_EXPECTED (c0 = "test"); - EXCEPTION_EXPECTED (c0 = CBString ("test")); - EXCEPTION_EXPECTED (c0 = t); - } - catch (struct CBStringException err) { - printf ("Exception thrown [%d]: %s\n", __LINE__, err.what()); - ret ++; - } - - try { - CBString c0, c1; - struct tagbstring t = bsStatic ("test"); - - printf ("\tc = 'x';\n"); - c0 = 'x'; - ret += (c0 != "x"); - ret += '\0' != ((const char *)c0)[c0.length()]; - printf ("\tc = (unsigned char)'x';\n"); - c0 = (unsigned char) 'x'; - ret += (c0 != "x"); - ret += '\0' != ((const char *)c0)[c0.length()]; - printf ("\tc = \"test\";\n"); - c0 = "test"; - ret += (c0 != "test"); - ret += '\0' != ((const char *)c0)[c0.length()]; - printf ("\tc = CBStr[\"test\"];\n"); - c1 = c0; - ret += (c0 != c1); - ret += '\0' != ((const char *)c1)[c1.length()]; - printf ("\tc = tbstr[\"test\"];\n"); - c0 = t; - ret += (c0 != "test"); - ret += '\0' != ((const char *)c0)[c0.length()]; - } - - catch (struct CBStringException err) { - printf ("Exception thrown [%d]: %s\n", __LINE__, err.what()); - ret ++; - } - - printf ("\t# failures: %d\n", ret); - return ret; -} - -int test2 (void) { -int ret = 0; - - printf ("TEST: CBString += operator\n"); - - try { - CBString c0; - struct tagbstring t = bsStatic ("test"); - - c0.writeprotect (); - EXCEPTION_EXPECTED (c0 += 'x'); - EXCEPTION_EXPECTED (c0 += (unsigned char) 'x'); - EXCEPTION_EXPECTED (c0 += "test"); - EXCEPTION_EXPECTED (c0 += CBString ("test")); - EXCEPTION_EXPECTED (c0 += t); - } - catch (struct CBStringException err) { - printf ("Exception thrown [%d]: %s\n", __LINE__, err.what()); - ret ++; - } - - try { - CBString c0; - struct tagbstring t = bsStatic ("extra"); - - c0 = "test"; - printf ("\tc += 'x';\n"); - c0 += 'x'; - ret += (c0 != "testx"); - ret += '\0' != ((const char *)c0)[c0.length()]; - printf ("\tc += (unsigned char)'x';\n"); - c0 += (unsigned char) 'y'; - ret += (c0 != "testxy"); - ret += '\0' != ((const char *)c0)[c0.length()]; - printf ("\tc += \"test\";\n"); - c0 += "test"; - ret += (c0 != "testxytest"); - ret += '\0' != ((const char *)c0)[c0.length()]; - printf ("\tc += CBStr[\"test\"];\n"); - c0 += CBString (c0); - ret += (c0 != "testxytesttestxytest"); - ret += '\0' != ((const char *)c0)[c0.length()]; - printf ("\tc += tbstr[\"test\"];\n"); - c0 += t; - ret += (c0 != "testxytesttestxytestextra"); - ret += '\0' != ((const char *)c0)[c0.length()]; - } - - catch (struct CBStringException err) { - printf ("Exception thrown [%d]: %s\n", __LINE__, err.what()); - ret ++; - } - - printf ("\t# failures: %d\n", ret); - return ret; -} - -int test3 (void) { -int ret = 0; - - try { - CBString c0, c1; - struct tagbstring t = bsStatic ("extra"); - - printf ("TEST: CBString + operator\n"); - - c1 = "test"; - printf ("\tc + 'x';\n"); - c0 = c1 + 'x'; - ret += (c0 != "testx"); - ret += '\0' != ((const char *)c0)[c0.length()]; - printf ("\tc + (unsigned char)'x';\n"); - c0 = c1 + (unsigned char) 'y'; - ret += (c0 != "testy"); - ret += '\0' != ((const char *)c0)[c0.length()]; - printf ("\tc + \"test\";\n"); - c0 = c1 + (const char *) "stuff"; - ret += (c0 != "teststuff"); - ret += '\0' != ((const char *)c0)[c0.length()]; - printf ("\tc + (unsigned char *) \"test\";\n"); - c0 = c1 + (const unsigned char *) "stuff"; - ret += (c0 != "teststuff"); - ret += '\0' != ((const char *)c0)[c0.length()]; - printf ("\tc + CBStr[\"test\"];\n"); - c0 = c1 + CBString ("other"); - ret += (c0 != "testother"); - ret += '\0' != ((const char *)c0)[c0.length()]; - printf ("\tc + tbstr[\"test\"];\n"); - c0 = c1 + t; - ret += (c0 != "testextra"); - ret += '\0' != ((const char *)c0)[c0.length()]; - - printf ("TEST: + CBString operator\n"); - - printf ("\t'x' + c;\n"); - c0 = 'x' + c1; - ret += (c0 != "xtest"); - ret += '\0' != ((const char *)c0)[c0.length()]; - printf ("\t(unsigned char)'y' + c;\n"); - c0 = (unsigned char) 'y' + c1; - ret += (c0 != "ytest"); - ret += '\0' != ((const char *)c0)[c0.length()]; - printf ("\t\"test\" + c;\n"); - c0 = (const char *) "stuff" + c1; - ret += (c0 != "stufftest"); - ret += '\0' != ((const char *)c0)[c0.length()]; - printf ("\t(unsigned char *) \"test\" + c;\n"); - c0 = (const unsigned char *) "stuff" + c1; - ret += (c0 != "stufftest"); - ret += '\0' != ((const char *)c0)[c0.length()]; - printf ("\ttbstr[\"extra\"] + c;\n"); - c0 = t + c1; - ret += (c0 != "extratest"); - ret += '\0' != ((const char *)c0)[c0.length()]; - } - - catch (struct CBStringException err) { - printf ("Exception thrown [%d]: %s\n", __LINE__, err.what()); - ret ++; - } - - printf ("\t# failures: %d\n", ret); - return ret; -} - -int test4 (void) { -int ret = 0; - - try { - printf ("TEST: CBString == operator\n"); - - CBString c0, c1, c2; - - c0 = c1 = "test"; - c2 = "other"; - - printf ("\tc == d;\n"); - ret += !(c0 == c1); - ret += (c0 == c2); - - printf ("\tc == \"test\";\n"); - ret += !(c0 == "test"); - ret += (c2 == "test"); - - printf ("\tc == (unsigned char *) \"test\";\n"); - ret += !(c0 == (unsigned char *) "test"); - ret += (c2 == (unsigned char *) "test"); - } - - catch (struct CBStringException err) { - printf ("Exception thrown [%d]: %s\n", __LINE__, err.what()); - ret ++; - } - - printf ("\t# failures: %d\n", ret); - return ret; -} - -int test5 (void) { -int ret = 0; - - try { - printf ("TEST: CBString != operator\n"); - - CBString c0, c1, c2; - - c0 = c1 = "test"; - c2 = "other"; - - printf ("\tc != d;\n"); - ret += (c0 != c1); - ret += !(c0 != c2); - - printf ("\tc != \"test\";\n"); - ret += (c0 != "test"); - ret += !(c2 != "test"); - - printf ("\tc != (unsigned char *) \"test\";\n"); - ret += (c0 != (unsigned char *) "test"); - ret += !(c2 != (unsigned char *) "test"); - } - - catch (struct CBStringException err) { - printf ("Exception thrown [%d]: %s\n", __LINE__, err.what()); - ret ++; - } - - printf ("\t# failures: %d\n", ret); - return ret; -} - -int test6 (void) { -int ret = 0; - - try { - printf ("TEST: CBString <, <= operators\n"); - - CBString c0, c1, c2; - - c0 = c1 = "test"; - c2 = "other"; - - printf ("\tc < d;\n"); - ret += (c0 < c1); - ret += (c0 < c2); - ret += (c1 < c0); - ret += !(c2 < c0); - - printf ("\tc <= d;\n"); - ret += !(c0 <= c1); - ret += (c0 <= c2); - ret += !(c1 <= c0); - ret += !(c2 <= c0); - - printf ("\tc < \"test\";\n"); - ret += (c0 < "test"); - ret += (c1 < "test"); - ret += !(c2 < "test"); - ret += (c0 < "other"); - ret += (c1 < "other"); - ret += (c2 < "other"); - - printf ("\tc <= \"test\";\n"); - ret += !(c0 <= "test"); - ret += !(c1 <= "test"); - ret += !(c2 <= "test"); - ret += (c0 <= "other"); - ret += (c1 <= "other"); - ret += !(c2 <= "other"); - - printf ("\tc < (unsigned char *) \"test\";\n"); - ret += (c0 < (const char *) "test"); - ret += (c1 < (const char *) "test"); - ret += !(c2 < (const char *) "test"); - ret += (c0 < (const char *) "other"); - ret += (c1 < (const char *) "other"); - ret += (c2 < (const char *) "other"); - - printf ("\tc <= (unsigned char *) \"test\";\n"); - ret += !(c0 <= (const char *) "test"); - ret += !(c1 <= (const char *) "test"); - ret += !(c2 <= (const char *) "test"); - ret += (c0 <= (const char *) "other"); - ret += (c1 <= (const char *) "other"); - ret += !(c2 <= (const char *) "other"); - } - - catch (struct CBStringException err) { - printf ("Exception thrown [%d]: %s\n", __LINE__, err.what()); - ret ++; - } - - printf ("\t# failures: %d\n", ret); - return ret; -} - -int test7 (void) { -int ret = 0; - - try { - printf ("TEST: CBString >, >= operators\n"); - - CBString c0, c1, c2; - - c0 = c1 = "test"; - c2 = "other"; - - printf ("\tc >= d;\n"); - ret += !(c0 >= c1); - ret += !(c0 >= c2); - ret += !(c1 >= c0); - ret += (c2 >= c0); - - printf ("\tc > d;\n"); - ret += (c0 > c1); - ret += !(c0 > c2); - ret += (c1 > c0); - ret += (c2 > c0); - - printf ("\tc >= \"test\";\n"); - ret += !(c0 >= "test"); - ret += !(c1 >= "test"); - ret += (c2 >= "test"); - ret += !(c0 >= "other"); - ret += !(c1 >= "other"); - ret += !(c2 >= "other"); - - printf ("\tc > \"test\";\n"); - ret += (c0 > "test"); - ret += (c1 > "test"); - ret += (c2 > "test"); - ret += !(c0 > "other"); - ret += !(c1 > "other"); - ret += (c2 > "other"); - - printf ("\tc >= (unsigned char *) \"test\";\n"); - ret += !(c0 >= (const char *) "test"); - ret += !(c1 >= (const char *) "test"); - ret += (c2 >= (const char *) "test"); - ret += !(c0 >= (const char *) "other"); - ret += !(c1 >= (const char *) "other"); - ret += !(c2 >= (const char *) "other"); - - printf ("\tc > (unsigned char *) \"test\";\n"); - ret += (c0 > (const char *) "test"); - ret += (c1 > (const char *) "test"); - ret += (c2 > (const char *) "test"); - ret += !(c0 > (const char *) "other"); - ret += !(c1 > (const char *) "other"); - ret += (c2 > (const char *) "other"); - } - - catch (struct CBStringException err) { - printf ("Exception thrown [%d]: %s\n", __LINE__, err.what()); - ret ++; - } - - printf ("\t# failures: %d\n", ret); - return ret; -} - -int test8 (void) { -int ret = 0; - - try { - printf ("TEST: (const char *) CBString operator\n"); - - CBString c0 ("test"), c1 ("other"); - - printf ("\t(const char *) CBString\n"); - ret += 0 != memcmp ((const char *) c0, "test", 5); - ret += 0 != memcmp ((const char *) c1, "other", 6); - - printf ("\t(const unsigned char *) CBString\n"); - ret += 0 != memcmp ((const unsigned char *) c0, "test", 5); - ret += 0 != memcmp ((const unsigned char *) c1, "other", 6); - } - - catch (struct CBStringException err) { - printf ("Exception thrown [%d]: %s\n", __LINE__, err.what()); - ret ++; - } - - printf ("\t# failures: %d\n", ret); - return ret; -} - -int test9 (void) { -int ret = 0; - - try { - printf ("TEST: (double), (float), (int) CBString operators\n"); - CBString c0 ("1.2e3"), c1("100"), c2("100.55"); - printf ("\t(double) \"%s\"\n", (const char *) c0); - ret += 1.2e3 != (double) c0; - printf ("\t(float) \"%s\"\n", (const char *) c0); - ret += 1.2e3 != (float) c0; - printf ("\t(int) \"%s\"\n", (const char *) c1); - ret += 100 != (float) c1; - printf ("\t(int) \"%s\"\n", (const char *) c2); - ret += 100 != (int) c2; - printf ("\t(unsigned int) \"%s\"\n", (const char *) c2); - ret += 100 != (unsigned int) c2; - } - catch (struct CBStringException err) { - printf ("Exception thrown [%d]: %s\n", __LINE__, err.what()); - ret ++; - } - - try { - CBString c0 ("xxxxx"); - printf ("\t(double) \"%s\"\n", (const char *) c0); - ret += -1.2e3 != (double) c0; - } - catch (struct CBStringException err) { - printf ("\tException (%s) correctly thrown\n", err.what()); - } - - try { - CBString c0 ("xxxxx"); - printf ("\t(float) \"%s\"\n", (const char *) c0); - ret += -1.2e3 != (float) c0; - } - catch (struct CBStringException err) { - printf ("\tException (%s) correctly thrown\n", err.what()); - } - - try { - CBString c0 ("xxxxx"); - printf ("\t(int) \"%s\"\n", (const char *) c0); - ret += -100 != (int) c0; - } - catch (struct CBStringException err) { - printf ("\tException (%s) correctly thrown\n", err.what()); - } - - try { - CBString c0 ("xxxxx"); - printf ("\t(unsigned int) \"%s\"\n", (const char *) c0); - ret += 1000 != (unsigned int) c0; - } - catch (struct CBStringException err) { - printf ("\tException (%s) correctly thrown\n", err.what()); - } - - printf ("\t# failures: %d\n", ret); - return ret; -} - -int test10 (void) { -int ret = 0; - - try { - printf ("TEST: length() method\n"); - CBString c0, c1("Test"); - - printf ("\t\"%s\".length();\n", (const char *) c0); - ret += 0 != c0.length(); - printf ("\t\"%s\".length();\n", (const char *) c1); - ret += 4 != c1.length(); - } - - catch (struct CBStringException err) { - printf ("Exception thrown [%d]: %s\n", __LINE__, err.what()); - ret ++; - } - - printf ("\t# failures: %d\n", ret); - return ret; -} - -int test11 (void) { -int ret = 0; - - printf ("TEST: character() method, [] operator\n"); - - try { - CBString c0("test"); - c0.writeprotect (); - ret += c0[0] != 't'; - ret += (1 + c0[0]) != 'u'; - ret += ((unsigned char) c0[0] + 1) != 'u'; - ret += c0.character(0) != 't'; - EXCEPTION_EXPECTED (c0[0] = 'x'); - EXCEPTION_EXPECTED (c0.character(0) = 'x'); - } - catch (struct CBStringException err) { - printf ("Exception thrown [%d]: %s\n", __LINE__, err.what()); - ret ++; - } - - try { - CBString c0("Test"); - - printf ("\t\"%s\".character ();\n", (const char *) c0); - ret += 's' != c0.character (2); - c0.character (2) = 'x'; - ret += c0 != "Text"; - - printf ("\t\"%s\"[];\n", (const char *) c0); - ret += 'T' != c0[0]; - c0[0] = 't'; - ret += c0 != "text"; - } - catch (struct CBStringException err) { - printf ("Exception thrown [%d]: %s\n", __LINE__, err.what()); - ret ++; - } - - try { - CBString c0; - printf ("\t\"%s\".character ();\n", (const char *) c0); - ret += '?' != c0.character (0); - } - catch (struct CBStringException err) { - printf ("\tException (%s) correctly thrown\n", err.what()); - } - - try { - CBString c0; - printf ("\t\"%s\"[];\n", (const char *) c0); - ret += '?' != c0[0]; - } - catch (struct CBStringException err) { - printf ("\tException (%s) correctly thrown\n", err.what()); - } - - printf ("\t# failures: %d\n", ret); - return ret; -} - -int test12 (void) { -int ret = 0; - -#ifndef BSTRLIB_NOVSNP - printf ("TEST: format(), formata() methods\n"); - - try { - CBString c0; - - c0.writeprotect (); - EXCEPTION_EXPECTED (c0.format ("%s(%d)", "extra", 4)); - EXCEPTION_EXPECTED (c0.formata ("%s(%d)", "extra", 4)); - } - catch (struct CBStringException err) { - printf ("Exception thrown [%d]: %s\n", __LINE__, err.what()); - ret ++; - } - - try { - CBString c0, c1("Test"), c2, c3; - - printf ("\tc.format (...);\n"); - c0.format ("%s(%d)", "extra", 4); - ret += c0 != "extra(4)"; - - c2 = c0 + c0 + c0 + c0; - c2 += c2; - c2.insert (0, "x"); - c3.format ("x%s%s%s%s%s%s%s%s", (const char *) c0, (const char *) c0 - , (const char *) c0, (const char *) c0 - , (const char *) c0, (const char *) c0 - , (const char *) c0, (const char *) c0); - ret += c2 != c3; - - printf ("\t\"%s\".formata (...);\n", (const char *) c1); - c1.formata ("%s(%d)", "extra", 4); - ret += c1 != "Testextra(4)"; - - c2 = c0 + c0 + c0 + c0; - c2 += c2; - c2.insert (0, "x"); - c3 = "x"; - c3.formata ("%s%s%s%s%s%s%s%s", (const char *) c0, (const char *) c0 - , (const char *) c0, (const char *) c0 - , (const char *) c0, (const char *) c0 - , (const char *) c0, (const char *) c0); - ret += c2 != c3; - } - catch (struct CBStringException err) { - printf ("Exception thrown [%d]: %s\n", __LINE__, err.what()); - ret ++; - } - - printf ("\t# failures: %d\n", ret); -#endif - return ret; -} - -int test13 (void) { -int ret = 0; - - try { - printf ("TEST: find() method\n"); - CBString c0, c1("Test"); - - printf ("\t\"%s\".find (CBString());\n", (const char *) c0); - ret += -1 != c0.find (CBString("x")); - ret += 1 != c1.find (CBString("e")); - - printf ("\t\"%s\".find (char *);\n", (const char *) c0); - ret += -1 != c0.find ("x"); - ret += 1 != c1.find ("e"); - - ret += 8 != CBString ("sssssssssap").find ("sap"); - ret += 9 != CBString ("sssssssssap").find ("ap"); - ret += 9 != CBString ("sssssssssap").find ("ap", 3); - ret += 9 != CBString ("sssssssssap").find ("a"); - ret += 9 != CBString ("sssssssssap").find ("a", 3); - ret += -1 != CBString ("sssssssssap").find ("x"); - ret += -1 != CBString ("sssssssssap").find ("x", 3); - ret += -1 != CBString ("sssssssssap").find ("ax"); - ret += -1 != CBString ("sssssssssap").find ("ax", 3); - ret += -1 != CBString ("sssssssssap").find ("sax"); - ret += -1 != CBString ("sssssssssap").find ("sax", 1); - ret += 8 != CBString ("sssssssssap").find ("sap", 3); - ret += 9 != CBString ("ssssssssssap").find ("sap", 3); - ret += 0 != CBString ("sssssssssap").find ("s"); - ret += 3 != CBString ("sssssssssap").find ("s", 3); - ret += 9 != CBString ("sssssssssap").find ("a"); - ret += 9 != CBString ("sssssssssap").find ("a", 5); - ret += 8 != CBString ("sasasasasap").find ("sap"); - ret += 9 != CBString ("ssasasasasap").find ("sap"); - - printf ("\t\"%s\".find (char);\n", (const char *) c0); - ret += -1 != c0.find ('x'); - ret += 1 != c1.find ('e'); - - printf ("TEST: reversefind () method\n"); - printf ("\t\"%s\".reversefind (CBString());\n", (const char *) c0); - ret += -1 != c0.reversefind (CBString("x"), c0.length()); - ret += 1 != c1.reversefind (CBString("e"), c1.length()); - - printf ("\t\"%s\".reversefind (char *);\n", (const char *) c0); - ret += -1 != c0.reversefind ("x", c0.length()); - ret += 1 != c1.reversefind ("e", c1.length()); - - printf ("\t\"%s\".reversefind (char);\n", (const char *) c0); - ret += -1 != c0.reversefind ('x', c0.length()); - ret += 1 != c1.reversefind ('e', c1.length()); - - } - catch (struct CBStringException err) { - printf ("Exception thrown [%d]: %s\n", __LINE__, err.what()); - ret ++; - } - - printf ("\t# failures: %d\n", ret); - return ret; -} - -int test14 (void) { -int ret = 0; - - try { - printf ("TEST: findchr(), reversefindchr() methods\n"); - CBString c0, c1("Test"); - - printf ("\t\"%s\".findchr (CBString(\"abcdef\"));\n", (const char *) c0); - ret += -1 != c0.findchr (CBString ("abcdef")); - printf ("\t\"%s\".findchr (CBString(\"abcdef\"));\n", (const char *) c1); - ret += 1 != c1.findchr (CBString ("abcdef")); - printf ("\t\"%s\".findchr (\"abcdef\");\n", (const char *) c0); - ret += -1 != c0.findchr ("abcdef"); - printf ("\t\"%s\".findchr (\"abcdef\");\n", (const char *) c1); - ret += 1 != c1.findchr ("abcdef"); - - printf ("\t\"%s\".reversefindchr (CBString(\"abcdef\"));\n", (const char *) c0); - ret += -1 != c0.reversefindchr (CBString ("abcdef"), c0.length()); - printf ("\t\"%s\".reversefindchr (CBString(\"abcdef\"));\n", (const char *) c1); - ret += 1 != c1.reversefindchr (CBString ("abcdef"), c1.length()); - printf ("\t\"%s\".reversefindchr (\"abcdef\");\n", (const char *) c0); - ret += -1 != c0.reversefindchr ("abcdef", c0.length()); - printf ("\t\"%s\".reversefindchr (\"abcdef\");\n", (const char *) c1); - ret += 1 != c1.reversefindchr ("abcdef", c1.length()); - - } - catch (struct CBStringException err) { - printf ("Exception thrown [%d]: %s\n", __LINE__, err.what()); - ret ++; - } - - printf ("\t# failures: %d\n", ret); - return ret; -} - -int test15 (void) { -int ret = 0; - - try { - printf ("TEST: nfindchr(), nreversefindchr() methods\n"); - CBString c0, c1("Test"); - - printf ("\t\"%s\".nfindchr (CBString(\"abcdef\"));\n", (const char *) c0); - ret += -1 != c0.nfindchr (CBString ("abcdef")); - printf ("\t\"%s\".nfindchr (CBString(\"abcdef\"));\n", (const char *) c1); - ret += 0 != c1.nfindchr (CBString ("abcdef")); - printf ("\t\"%s\".nfindchr (\"abcdef\");\n", (const char *) c0); - ret += -1 != c0.nfindchr ("abcdef"); - printf ("\t\"%s\".nfindchr (\"abcdef\");\n", (const char *) c1); - ret += 0 != c1.nfindchr ("abcdef"); - - printf ("\t\"%s\".nreversefindchr (CBString(\"abcdef\"));\n", (const char *) c0); - ret += -1 != c0.nreversefindchr (CBString ("abcdef"), c0.length()); - printf ("\t\"%s\".nreversefindchr (CBString(\"abcdef\"));\n", (const char *) c1); - ret += 3 != c1.nreversefindchr (CBString ("abcdef"), c1.length()); - printf ("\t\"%s\".nreversefindchr (\"abcdef\");\n", (const char *) c0); - ret += -1 != c0.nreversefindchr ("abcdef", c0.length()); - printf ("\t\"%s\".nreversefindchr (\"abcdef\");\n", (const char *) c1); - ret += 3 != c1.nreversefindchr ("abcdef", c1.length()); - - } - catch (struct CBStringException err) { - printf ("Exception thrown [%d]: %s\n", __LINE__, err.what()); - ret ++; - } - - printf ("\t# failures: %d\n", ret); - return ret; -} - -int test16 (void) { -int ret = 0; - - printf ("TEST: midstr() method\n"); - - try { - CBString c0, c1("bogus"), c2; - - printf ("\t\"%s\".midstr (1,3)\n", (const char *) c0); - ret += (c2 = c0.midstr (1,3)) != ""; - ret += '\0' != ((const char *)c2)[c2.length ()]; - - printf ("\t\"%s\".midstr (1,3)\n", (const char *) c1); - ret += (c2 = c1.midstr (1,3)) != "ogu"; - ret += '\0' != ((const char *)c2)[c2.length ()]; - } - - catch (struct CBStringException err) { - printf ("Exception thrown [%d]: %s\n", __LINE__, err.what()); - ret ++; - } - - printf ("\t# failures: %d\n", ret); - return ret; -} - -int test17 (void) { -int ret = 0; - - printf ("TEST: fill() method\n"); - - try { - CBString c0; - - c0.writeprotect (); - EXCEPTION_EXPECTED (c0.fill (5, 'x')); - } - catch (struct CBStringException err) { - printf ("Exception thrown [%d]: %s\n", __LINE__, err.what()); - ret ++; - } - - try { - CBString c0, c1("Test-test"); - - printf ("\t\"%s\".fill(5,'x')\n", (const char *) c0); - c0.fill (5, 'x'); - ret += c0 != "xxxxx"; - - printf ("\t\"%s\".fill(5,'x')\n", (const char *) c1); - c1.fill (5, 'x'); - ret += c1 != "xxxxx"; - } - catch (struct CBStringException err) { - printf ("Exception thrown [%d]: %s\n", __LINE__, err.what()); - ret ++; - } - - printf ("\t# failures: %d\n", ret); - return ret; -} - -int test18 (void) { -int ret = 0; - - printf ("TEST: alloc() method\n"); - - try { - CBString c0; - - c0.writeprotect (); - EXCEPTION_EXPECTED (c0.alloc (5)); - } - catch (struct CBStringException err) { - printf ("Exception thrown [%d]: %s\n", __LINE__, err.what()); - ret ++; - } - - try { - CBString c0, c1("Test-test"); - - printf ("\t\"%s\".alloc(5)\n", (const char *) c0); - c0.alloc (5); - ret += c0 != ""; - - printf ("\t\"%s\".alloc(5)\n", (const char *) c1); - c1.alloc (5); - ret += c1 != "Test-test"; - } - catch (struct CBStringException err) { - printf ("Exception thrown [%d]: %s\n", __LINE__, err.what()); - ret ++; - } - - try { - CBString c0; - - printf ("\t\"%s\".alloc(0)\n", (const char *) c0); - c0.alloc (0); - ret += c0 != "Error"; - } - catch (struct CBStringException err) { - printf ("\tException (%s) properly thrown\n", err.what()); - } - - try { - CBString c0; - - printf ("\t\"%s\".alloc(-1)\n", (const char *) c0); - c0.alloc (-1); - ret += c0 != "Error"; - } - catch (struct CBStringException err) { - printf ("\tException (%s) properly thrown\n", err.what()); - } - - printf ("\t# failures: %d\n", ret); - return ret; -} - -int test19 (void) { -int ret = 0; - - printf ("TEST: setsubstr() method\n"); - - try { - CBString c0("Test-test"); - - c0.writeprotect (); - EXCEPTION_EXPECTED (c0.setsubstr (4, "extra")); - } - catch (struct CBStringException err) { - printf ("Exception thrown [%d]: %s\n", __LINE__, err.what()); - ret ++; - } - - try { - CBString c0, c1("Test-test"); - - printf ("\t\"%s\".setsubstr (4,\"extra\")\n", (const char *) c0); - c0.setsubstr (4, "extra"); - ret += c0 != " extra"; - printf ("\t\"%s\".setsubstr (4,\"extra\")\n", (const char *) c1); - c1.setsubstr (4, "extra"); - ret += c1 != "Testextra"; - - } - catch (struct CBStringException err) { - printf ("Exception thrown [%d]: %s\n", __LINE__, err.what()); - ret ++; - } - - try { - CBString c0; - - printf ("\t\"%s\".setsubstr(-1,\"extra\")\n", (const char *) c0); - c0.setsubstr (-1, "extra"); - ret ++; - } - catch (struct CBStringException err) { - printf ("\tException (%s) properly thrown\n", err.what()); - } - - printf ("\t# failures: %d\n", ret); - return ret; -} - -int test20 (void) { -int ret = 0; - - printf ("TEST: insert() method\n"); - - try { - CBString c0("Test-test"); - - c0.writeprotect (); - EXCEPTION_EXPECTED (c0.insert (4, "extra")); - } - catch (struct CBStringException err) { - printf ("Exception thrown [%d]: %s\n", __LINE__, err.what()); - ret ++; - } - - try { - CBString c0, c1("Test-test"); - - printf ("\t\"%s\".insert (4,\"extra\")\n", (const char *) c0); - c0.insert (4, "extra"); - ret += c0 != " extra"; - printf ("\t\"%s\".insert (4,\"extra\")\n", (const char *) c1); - c1.insert (4, "extra"); - ret += c1 != "Testextra-test"; - - } - catch (struct CBStringException err) { - printf ("Exception thrown [%d]: %s\n", __LINE__, err.what()); - ret ++; - } - - try { - CBString c0; - - printf ("\t\"%s\".insert(-1,\"extra\")\n", (const char *) c0); - c0.insert (-1, "extra"); - ret ++; - } - catch (struct CBStringException err) { - printf ("\tException (%s) properly thrown\n", err.what()); - } - - printf ("\t# failures: %d\n", ret); - return ret; -} - -int test21 (void) { -int ret = 0; - - printf ("TEST: insertchrs() method\n"); - - try { - CBString c0("Test-test"); - - c0.writeprotect (); - EXCEPTION_EXPECTED (c0.insertchrs (4, 2, 'x')); - } - catch (struct CBStringException err) { - printf ("Exception thrown [%d]: %s\n", __LINE__, err.what()); - ret ++; - } - - try { - CBString c0, c1("Test-test"); - - printf ("\t\"%s\".insertchrs (4,2,'x')\n", (const char *) c0); - c0.insertchrs (4, 2, 'x'); - ret += c0 != "xxxxxx"; - printf ("\t\"%s\".insertchrs (4,2,'x')\n", (const char *) c1); - c1.insertchrs (4, 2, 'x'); - ret += c1 != "Testxx-test"; - } - catch (struct CBStringException err) { - printf ("Exception thrown [%d]: %s\n", __LINE__, err.what()); - ret ++; - } - - try { - CBString c0; - - printf ("\t\"%s\".insertchrs (-1,2,'x')\n", (const char *) c0); - c0.insertchrs (-1, 2, 'x'); - ret ++; - } - catch (struct CBStringException err) { - printf ("\tException (%s) properly thrown\n", err.what()); - } - - printf ("\t# failures: %d\n", ret); - return ret; -} - -int test22 (void) { -int ret = 0; - - printf ("TEST: replace() method\n"); - - try { - CBString c0("Test-test"); - - c0.writeprotect (); - EXCEPTION_EXPECTED (c0.replace (4, 2, "beef")); - } - catch (struct CBStringException err) { - printf ("Exception thrown [%d]: %s\n", __LINE__, err.what()); - ret ++; - } - - try { - CBString c0, c1("Test-test"); - - printf ("\t\"%s\".replace (4,2,\"beef\")\n", (const char *) c0); - c0.replace (4, 2, CBString ("beef")); - ret += c0 != " beef"; - c0 = ""; - c0.replace (4, 2, "beef"); - ret += c0 != " beef"; - - printf ("\t\"%s\".replace (4,2,\"beef\")\n", (const char *) c1); - c1.replace (4, 2, CBString ("beef")); - ret += c1 != "Testbeefest"; - c1 = "Test-test"; - c1.replace (4, 2, "beef"); - ret += c1 != "Testbeefest"; - } - catch (struct CBStringException err) { - printf ("Exception thrown [%d]: %s\n", __LINE__, err.what()); - ret ++; - } - - printf ("\t# failures: %d\n", ret); - return ret; -} - -int test23 (void) { -int ret = 0; - - printf ("TEST: findreplace() method\n"); - - try { - CBString c0, c1("Test-test"); - - printf ("\t\"%s\".findreplace (\"est\",\"beef\")\n", (const char *) c0); - c0.findreplace ("est", "beef"); - ret += c0 != ""; - c0 = ""; - c0.findreplace (CBString ("est"), CBString ("beef")); - ret += c0 != ""; - - printf ("\t\"%s\".findreplace (\"est\",\"beef\")\n", (const char *) c1); - c1.findreplace ("est", "beef"); - ret += c1 != "Tbeef-tbeef"; - c1 = "Test-test"; - c1.findreplace (CBString ("est"), CBString ("beef")); - ret += c1 != "Tbeef-tbeef"; - - } - catch (struct CBStringException err) { - printf ("Exception thrown [%d]: %s\n", __LINE__, err.what()); - ret ++; - } - - try { - CBString c0, c1("TeSt-tEsT"); - - printf ("\t\"%s\".findreplacecaseless (\"est\",\"beef\")\n", (const char *) c0); - c0.findreplacecaseless ("est", "beef"); - ret += c0 != ""; - c0 = ""; - c0.findreplacecaseless (CBString ("est"), CBString ("beef")); - ret += c0 != ""; - - printf ("\t\"%s\".findreplacecaseless (\"est\",\"beef\")\n", (const char *) c1); - c1.findreplacecaseless ("est", "beef"); - ret += c1 != "Tbeef-tbeef"; - c1 = "Test-test"; - c1.findreplacecaseless (CBString ("est"), CBString ("beef")); - ret += c1 != "Tbeef-tbeef"; - - } - catch (struct CBStringException err) { - printf ("Exception thrown [%d]: %s\n", __LINE__, err.what()); - ret ++; - } - - printf ("\t# failures: %d\n", ret); - return ret; -} - -int test24 (void) { -int ret = 0; - - printf ("TEST: remove() method\n"); - - try { - CBString c0, c1("Test-test"); - - printf ("\t\"%s\".remove (4,2)\n", (const char *) c0); - c0.remove (4, 2); - ret += c0 != ""; - - printf ("\t\"%s\".remove (4,2)\n", (const char *) c1); - c1.remove (4, 2); - ret += c1 != "Testest"; - } - catch (struct CBStringException err) { - printf ("Exception thrown [%d]: %s\n", __LINE__, err.what()); - ret ++; - } - - printf ("\t# failures: %d\n", ret); - return ret; -} - -int test25 (void) { -int ret = 0; - - printf ("TEST: trunc() method\n"); - - try { - CBString c0, c1("Test-test"); - - printf ("\t\"%s\".trunc (4)\n", (const char *) c0); - c0.trunc (4); - ret += c0 != ""; - - printf ("\t\"%s\".trunc (4)\n", (const char *) c1); - c1.trunc (4); - ret += c1 != "Test"; - } - catch (struct CBStringException err) { - printf ("Exception thrown [%d]: %s\n", __LINE__, err.what()); - ret ++; - } - - printf ("\t# failures: %d\n", ret); - return ret; -} - -int test26 (void) { -int ret = 0; - - printf ("TEST: repeat() method\n"); - - try { - CBString c0, c1("Test"); - - printf ("\t\"%s\".repeat (4)\n", (const char *) c0); - c0.repeat (4); - ret += c0 != ""; - - printf ("\t\"%s\".repeat (4)\n", (const char *) c1); - c1.repeat (4); - ret += c1 != "TestTestTestTest"; - c1 = "Test"; - c1.repeat (4); - ret += c1 != "TestTestTestTest"; - } - catch (struct CBStringException err) { - printf ("Exception thrown [%d]: %s\n", __LINE__, err.what()); - ret ++; - } - - printf ("\t# failures: %d\n", ret); - return ret; -} - -int test27 (void) { -int ret = 0; - - printf ("TEST: ltrim(), rtrim() methods\n"); - - try { - CBString c0, c1(" Test "), c2(" "); - - printf ("\t\"%s\".ltrim ()\n", (const char *) c0); - c0.ltrim (); - ret += c0 != ""; - c0 = ""; - c0.rtrim (); - ret += c0 != ""; - - printf ("\t\"%s\".ltrim ()\n", (const char *) c1); - c1.ltrim (); - ret += c1 != "Test "; - c1 = " Test "; - c1.rtrim (); - ret += c1 != " Test"; - - printf ("\t\"%s\".ltrim ()\n", (const char *) c2); - c2.ltrim (); - ret += c2 != ""; - c2 = " "; - c2.rtrim (); - ret += c2 != ""; - } - catch (struct CBStringException err) { - printf ("Exception thrown [%d]: %s\n", __LINE__, err.what()); - ret ++; - } - - printf ("\t# failures: %d\n", ret); - return ret; -} - -#if !defined(BSTRLIB_CANNOT_USE_STL) - -int test28 (void) { -int ret = 0; - - printf ("TEST: split(), join() mechanisms\n"); - - try { - CBString c0, c1("a b c d e f"); - struct CBStringList s; - s.split (c1, ' '); - - c0.writeprotect (); - EXCEPTION_EXPECTED (c0.join (s)); - } - catch (struct CBStringException err) { - printf ("Exception thrown [%d]: %s\n", __LINE__, err.what()); - ret ++; - } - - try { - CBString c0, c1("a b c d e f"); - struct CBStringList s; - - printf ("\t\"%s\".split (' ')\n", (const char *) c1); - - s.split (c1, ' '); - CBString c2(s), c3(s, ','); - - printf ("\tc.join (<...>)\n"); - - ret += c2 != "abcdef"; - ret += c3 != "a,b,c,d,e,f"; - c0.join (s); - ret += c0 != "abcdef"; - c0.join (s, ','); - ret += c0 != "a,b,c,d,e,f"; - - CBString strPepe = "valor1@valor2@valor3@@@valor6"; - for (unsigned char c = (unsigned char) '\0';;c++) { - CBStringList sl; - CBString x; - - sl.split (strPepe, c); - x.join (sl, c); - if (x != strPepe) { - printf ("\tfailure[%d] split/join mismatch\n\t\t%s\n\t\t%s\n", __LINE__, (const char *) strPepe, (const char *) x); - ret++; - break; - } - if (UCHAR_MAX == c) break; - } - - { - CBStringList sl; - CBString x; - - sl.splitstr (strPepe, CBString ("or")); - x.join (sl, CBString ("or")); - if (x != strPepe) { - printf ("\tfailure[%d] splitstr/join mismatch\n\t\t%s\n\t\t%s\n", __LINE__, (const char *) strPepe, (const char *) x); - ret++; - } - } - - { - CBStringList sl; - CBString x; - - sl.splitstr (strPepe, CBString ("6")); - x.join (sl, CBString ("6")); - if (x != strPepe) { - printf ("\tfailure[%d] splitstr/join mismatch\n\t\t%s\n\t\t%s\n", __LINE__, (const char *) strPepe, (const char *) x); - ret++; - } - } - - { - CBStringList sl; - CBString x; - - sl.splitstr (strPepe, CBString ("val")); - x.join (sl, CBString ("val")); - if (x != strPepe) { - printf ("\tfailure[%d] splitstr/join mismatch\n\t\t%s\n\t\t%s\n", __LINE__, (const char *) strPepe, (const char *) x); - ret++; - } - } - - { - CBStringList sl; - CBString x; - - sl.splitstr (strPepe, CBString ("@@")); - x.join (sl, CBString ("@@")); - if (x != strPepe) { - printf ("\tfailure[%d] splitstr/join mismatch\n\t\t%s\n\t\t%s\n", __LINE__, (const char *) strPepe, (const char *) x); - ret++; - } - } - - } - catch (struct CBStringException err) { - printf ("Exception thrown [%d]: %s\n", __LINE__, err.what()); - ret ++; - } - - printf ("\t# failures: %d\n", ret); - return ret; -} - -#endif - -int test29 (void) { -int ret = 0; - - printf ("TEST: caselessEqual(), caselessCmp() mechanisms\n"); - - try { - CBString c0("Test"), c1("test"), c2("testy"); - - printf ("\t\"%s\".caselessEqual (\"%s\")\n", (const char *) c0, (const char *) c1); - ret += 1 != c0.caselessEqual (c1); - ret += 1 != c1.caselessEqual (c0); - printf ("\t\"%s\".caselessEqual (\"%s\")\n", (const char *) c0, (const char *) c2); - ret += 0 != c0.caselessEqual (c2); - ret += 0 != c2.caselessEqual (c0); - - printf ("\t\"%s\".caselessCmp (\"%s\")\n", (const char *) c0, (const char *) c1); - ret += 0 != c0.caselessCmp (c1); - ret += 0 != c1.caselessCmp (c0); - printf ("\t\"%s\".caselessCmp (\"%s\")\n", (const char *) c0, (const char *) c2); - ret += 0 == c0.caselessCmp (c2); - ret += 0 == c2.caselessCmp (c0); - } - catch (struct CBStringException err) { - printf ("Exception thrown [%d]: %s\n", __LINE__, err.what()); - ret ++; - } - - printf ("\t# failures: %d\n", ret); - return ret; -} - -int test30 (void) { -int ret = 0; - - printf ("TEST: toupper(), tolower() mechanisms\n"); - - try { - CBString c0("Test-test"); - - c0.writeprotect (); - EXCEPTION_EXPECTED (c0.toupper()); - EXCEPTION_EXPECTED (c0.tolower()); - } - catch (struct CBStringException err) { - printf ("Exception thrown [%d]: %s\n", __LINE__, err.what()); - ret ++; - } - - try { - CBString c0; - - c0 = "Test"; - printf ("\t\"%s\".toupper ()\n", (const char *) c0); - c0.toupper(); - ret += c0 != "TEST"; - - c0 = "Test"; - printf ("\t\"%s\".tolower ()\n", (const char *) c0); - c0.tolower (); - ret += c0 != "test"; - } - catch (struct CBStringException err) { - printf ("Exception thrown [%d]: %s\n", __LINE__, err.what()); - ret ++; - } - - printf ("\t# failures: %d\n", ret); - return ret; -} - -static size_t test31_aux (void *buff, size_t elsize, size_t nelem, void *parm) { - buff = buff; - elsize = elsize; - nelem = nelem; - parm = parm; - return 0; -} - -int test31 (void) { -CBString c; -int ret = 0; - - printf ("TEST: CBStream test\n"); - - CBStream s((bNread) test31_aux, NULL); - s << CBString("Test"); - - ret += ((c = s.read ()) != CBString ("Test")); - ret += !s.eof(); - - printf ("\t\"%s\" through CBStream.read()\n", (const char *) c); - - s << CBString("Test"); - - c.trunc (0); - ret += ((s >> c) != CBString ("Test")); - ret += !s.eof(); - - printf ("\t\"%s\" through CBStream.>>\n", (const char *) c); - - return ret; -} - -/* int bMultiConcatNeedNULLAsLastArgument (bstring dst, ...) - * - * Concatenate a sequence of exactly n char * arguments to dst. - */ -int bMultiConcatNeedNULLAsLastArgument (bstring dst, ...) { -va_list arglist; -int ret = 0; - va_start (arglist, dst); - do { - bstring parm = va_arg (arglist, bstring); - if (NULL == parm) break; - if (NULL == parm->data || parm->slen > parm->mlen || - parm->mlen < 0 || parm->slen < 0) { - ret = BSTR_ERR; - break; - } - ret = bconcat (dst, parm); - } while (0 <= ret); - va_end (arglist); - return ret; -} - -/* int bMultiCatCstrNeedNULLAsLastArgument (bstring dst, ...) - * - * Concatenate a sequence of exactly n char * arguments to dst. - */ -int bMultiCatCstrNeedNULLAsLastArgument (bstring dst, ...) { -va_list arglist; -int ret = 0; - va_start (arglist, dst); - do { - char* parm = va_arg (arglist, char *); - if (NULL == parm) break; - ret = bcatcstr (dst, parm); - } while (0 <= ret); - va_end (arglist); - return ret; -} - -/* - * The following macros are only available on more recent compilers that - * support variable length macro arguments and __VA_ARGS__. These can also - * be dangerous because there is no compiler time type checking on the - * arguments. - */ - - -#define bMultiConcat(dst,...) bMultiConcatNeedNULLAsLastArgument((dst),##__VA_ARGS__,NULL) -#define bMultiCatCstr(dst,...) bMultiCatCstrNeedNULLAsLastArgument((dst),##__VA_ARGS__,NULL) - -#define bGlue3_aux(a,b,c) a ## b ## c -#define bGlue3(a,b,c) bGlue3_aux(a,b,c) - -#if defined(_MSC_VER) -#define _bDeclTbstrIdx(t,n,...) \ - static unsigned char bGlue3(_btmpuc_,t,n)[] = {__VA_ARGS__, '\0'}; \ - struct tagbstring t = { -32, sizeof(bGlue3(_btmpuc_,t,n))-1, bGlue3(_btmpuc_,t,n)} -#define bDeclTbstr(t,...) _bDeclTbstrIdx(t,__COUNTER__,__VA_ARGS__) -#else -#define bDeclTbstr(t,...) \ - static unsigned char bGlue3(_btmpuc_,t,__LINE__)[] = {__VA_ARGS__, '\0'}; \ - struct tagbstring t = { -__LINE__, sizeof(bGlue3(_btmpuc_,t,__LINE__))-1, bGlue3(_btmpuc_,t,__LINE__)} -#endif - -static int test32(void) { -bstring b1 = bfromStatic ("a"); -bstring b2 = bfromStatic ("e"); -bstring b3 = bfromStatic ("i"); -bstring b4 = bfromStatic (""); -int ret = 0; - - printf ("TEST: bMultiCatCstr, bMultiConcat\n"); - - bMultiCatCstr(b1, "b", "c", "d"); - bMultiCatCstr(b2, "f", "g", "h"); - bMultiCatCstr(b3, "j", "k", "l"); - bMultiConcat(b4, b1, b2, b3); - - ret += 1 != biseqStatic (b1, "abcd"); - ret += 1 != biseqStatic (b2, "efgh"); - ret += 1 != biseqStatic (b3, "ijkl"); - ret += 1 != biseqStatic (b4, "abcdefghijkl"); - - bdestroy (b1); - bdestroy (b2); - bdestroy (b3); - bdestroy (b4); - - printf ("\t# failures: %d\n", ret); - return ret; -} - -static int test33(void) { - bDeclTbstr (t1, 'H','e','l','l','o'); - bDeclTbstr (t2, 32,'w','o','r','l','d'); - bstring b = bfromStatic("["); - int ret; - - printf ("TEST: bDeclTbstr\n"); - - bconcat (b, &t1); - bconcat (b, &t2); - bcatStatic (b, "]"); - ret = 1 != biseqStatic (b, "[Hello world]"); - bdestroy (b); - - printf ("\t# failures: %d\n", ret); - return ret; -} - -int main () { -int ret = 0; - - printf ("Direct case testing of CPP core functions\n"); - - ret += test0 (); - ret += test1 (); - ret += test2 (); - ret += test3 (); - ret += test4 (); - ret += test5 (); - ret += test6 (); - ret += test7 (); - ret += test8 (); - ret += test9 (); - ret += test10 (); - ret += test11 (); - ret += test12 (); - ret += test13 (); - ret += test14 (); - ret += test15 (); - ret += test16 (); - ret += test17 (); - ret += test18 (); - ret += test19 (); - ret += test20 (); - ret += test21 (); - ret += test22 (); - ret += test23 (); - ret += test24 (); - ret += test25 (); - ret += test26 (); - ret += test27 (); -#if !defined(BSTRLIB_CANNOT_USE_STL) - ret += test28 (); -#endif - ret += test29 (); - ret += test30 (); - ret += test31 (); - ret += test32 (); - ret += test33 (); - - printf ("# test failures: %d\n", ret); - - return 0; -} diff --git a/bstrlib/testaux.c b/bstrlib/testaux.c deleted file mode 100644 index 99a05df..0000000 --- a/bstrlib/testaux.c +++ /dev/null @@ -1,423 +0,0 @@ -/* - * This source file is part of the bstring string library. This code was - * written by Paul Hsieh in 2002-2015, and is covered by the BSD open source - * license. Refer to the accompanying documentation for details on usage and - * license. - */ - -/* - * testaux.c - * - * This file is the C unit test for the bstraux module of Bstrlib. - */ - -#include -#include "bstrlib.h" -#include "bstraux.h" - -static int tWrite (const void * buf, size_t elsize, size_t nelem, void * parm) { -bstring b = (bstring) parm; -size_t i; - - if (NULL == b || NULL == buf || 0 == elsize || 0 == nelem) - return -__LINE__; - - for (i=0; i < nelem; i++) { - if (0 > bcatblk (b, buf, elsize)) break; - buf = (const void *) (elsize + (const char *) buf); - } - return (int) i; -} - -int test0 (void) { -struct bwriteStream * ws; -bstring s; -int ret = 0; - - printf ("TEST: struct bwriteStream functions.\n"); - - ws = bwsOpen ((bNwrite) tWrite, (s = bfromcstr (""))); - bwsBuffLength (ws, 8); - ret += 8 != bwsBuffLength (ws, 0); - bwsWriteBlk (ws, bsStaticBlkParms ("Hello ")); - ret += 0 == biseqcstr (s, ""); - bwsWriteBlk (ws, bsStaticBlkParms ("World\n")); - ret += 0 == biseqcstr (s, "Hello Wo"); - ret += s != bwsClose (ws); - ret += 0 == biseqcstr (s, "Hello World\n"); - - printf ("\t# failures: %d\n", ret); - - return ret; -} - -int test1 (void) { -struct tagbstring t = bsStatic ("Hello world"); -bstring b, c, d; -int ret = 0; - - printf ("TEST: bTail and bHead functions.\n"); - b = bTail (&t, 5); - c = bHead (&t, 5); - ret += 0 >= biseqcstr (b, "world"); - ret += 0 >= biseqcstr (c, "Hello"); - bdestroy (b); - bdestroy (c); - - b = bTail (&t, 0); - c = bHead (&t, 0); - ret += 0 >= biseqcstr (b, ""); - ret += 0 >= biseqcstr (c, ""); - bdestroy (b); - bdestroy (c); - - d = bstrcpy (&t); - b = bTail (d, 5); - c = bHead (d, 5); - ret += 0 >= biseqcstr (b, "world"); - ret += 0 >= biseqcstr (c, "Hello"); - bdestroy (b); - bdestroy (c); - bdestroy (d); - - printf ("\t# failures: %d\n", ret); - - return ret; -} - -int test2 (void) { -struct tagbstring t = bsStatic ("Hello world"); -bstring b; -int ret = 0, reto; - - printf ("TEST: bSetChar function.\n"); - ret += 0 <= bSetChar (&t, 4, ','); - ret += 0 > bSetChar (b = bstrcpy (&t), 4, ','); - ret += 0 >= biseqcstr (b, "Hell, world"); - ret += 0 <= bSetChar (b, -1, 'x'); - b->slen = 2; - ret += 0 > bSetChar (b, 1, 'i'); - ret += 0 >= biseqcstr (b, "Hi"); - ret += 0 > bSetChar (b, 2, 's'); - ret += 0 >= biseqcstr (b, "His"); - ret += 0 > bSetChar (b, 1, '\0'); - ret += blength (b) != 3; - ret += bchare (b, 0, '?') != 'H'; - ret += bchare (b, 1, '?') != '\0'; - ret += bchare (b, 2, '?') != 's'; - bdestroy (b); - - printf ("\t# failures: %d\n", ret); - - reto = ret; - ret = 0; - - printf ("TEST: bSetCstrChar function.\n"); - ret += 0 <= bSetCstrChar (&t, 4, ','); - ret += 0 > bSetCstrChar (b = bstrcpy (&t), 4, ','); - ret += 0 >= biseqcstr (b, "Hell, world"); - ret += 0 <= bSetCstrChar (b, -1, 'x'); - b->slen = 2; - ret += 0 > bSetCstrChar (b, 1, 'i'); - ret += 0 >= biseqcstr (b, "Hi"); - ret += 0 > bSetCstrChar (b, 2, 's'); - ret += 0 >= biseqcstr (b, "His"); - ret += 0 > bSetCstrChar (b, 1, '\0'); - ret += blength (b) != 1; - ret += bchare (b, 0, '?') != 'H'; - bdestroy (b); - - printf ("\t# failures: %d\n", ret); - - return reto + ret; -} - -int test3 (void) { -struct tagbstring t = bsStatic ("Hello world"); -bstring b; -int ret = 0; - - printf ("TEST: bFill function.\n"); - ret += 0 <= bFill (&t, 'x', 7); - ret += 0 > bFill (b = bstrcpy (&t), 'x', 7); - ret += 0 >= biseqcstr (b, "xxxxxxx"); - ret += 0 <= bFill (b, 'x', -1); - ret += 0 > bFill (b, 'x', 0); - ret += 0 >= biseqcstr (b, ""); - bdestroy (b); - - printf ("\t# failures: %d\n", ret); - - return ret; -} - -int test4 (void) { -struct tagbstring t = bsStatic ("foo"); -bstring b; -int ret = 0; - - printf ("TEST: bReplicate function.\n"); - ret += 0 <= bReplicate (&t, 4); - ret += 0 <= bReplicate (b = bstrcpy (&t), -1); - ret += 0 > bReplicate (b, 4); - ret += 0 >= biseqcstr (b, "foofoofoofoo"); - ret += 0 > bReplicate (b, 0); - ret += 0 >= biseqcstr (b, ""); - bdestroy (b); - - printf ("\t# failures: %d\n", ret); - - return ret; -} - -int test5 (void) { -struct tagbstring t = bsStatic ("Hello world"); -bstring b; -int ret = 0; - - printf ("TEST: bReverse function.\n"); - ret += 0 <= bReverse (&t); - ret += 0 > bReverse (b = bstrcpy (&t)); - ret += 0 >= biseqcstr (b, "dlrow olleH"); - b->slen = 0; - ret += 0 > bReverse (b); - ret += 0 >= biseqcstr (b, ""); - bdestroy (b); - - printf ("\t# failures: %d\n", ret); - - return ret; -} - -int test6 (void) { -struct tagbstring t = bsStatic ("Hello world"); -bstring b; -int ret = 0; - - printf ("TEST: bInsertChrs function.\n"); - ret += 0 <= bInsertChrs (&t, 6, 4, 'x', '?'); - ret += 0 > bInsertChrs (b = bstrcpy (&t), 6, 4, 'x', '?'); - ret += 0 >= biseqcstr (b, "Hello xxxxworld"); - bdestroy (b); - - printf ("\t# failures: %d\n", ret); - - return ret; -} - -int test7 (void) { -struct tagbstring t = bsStatic (" i am "); -bstring b; -int ret = 0; - - printf ("TEST: bJustify functions.\n"); - ret += 0 <= bJustifyLeft (&t, ' '); - ret += 0 <= bJustifyRight (&t, 8, ' '); - ret += 0 <= bJustifyMargin (&t, 8, ' '); - ret += 0 <= bJustifyCenter (&t, 8, ' '); - ret += 0 > bJustifyLeft (b = bstrcpy (&t), ' '); - ret += 0 >= biseqcstr (b, "i am"); - ret += 0 > bJustifyRight (b, 8, ' '); - ret += 0 >= biseqcstr (b, " i am"); - ret += 0 > bJustifyMargin (b, 8, ' '); - ret += 0 >= biseqcstr (b, "i am"); - ret += 0 > bJustifyCenter (b, 8, ' '); - ret += 0 >= biseqcstr (b, " i am"); - bdestroy (b); - - printf ("\t# failures: %d\n", ret); - - return ret; -} - -int test8 (void) { -struct tagbstring t = bsStatic ("Hello world"); -bstring b; -char * c; -int ret = 0; - - printf ("TEST: NetStr functions.\n"); - c = bStr2NetStr (&t); - ret += 0 != strcmp (c, "11:Hello world,"); - b = bNetStr2Bstr (c); - ret += 0 >= biseq (b, &t); - bdestroy (b); - bcstrfree (c); - - printf ("\t# failures: %d\n", ret); - - return ret; -} - -int test9 (void) { -struct tagbstring t = bsStatic ("Hello world"); -bstring b, c; -int err, ret = 0; - - printf ("TEST: Base 64 codec.\n"); - - b = bBase64Encode (&t); - ret += 0 >= biseqcstr (b, "SGVsbG8gd29ybGQ="); - c = bBase64DecodeEx (b, &err); - ret += 0 != err; - ret += 0 >= biseq (c, &t); - bdestroy (b); - bdestroy (c); - - printf ("\t# failures: %d\n", ret); - - return ret; -} - -int test10 (void) { -struct tagbstring t = bsStatic ("Hello world"); -bstring b, c; -int err, ret = 0; - - printf ("TEST: UU codec.\n"); - - b = bUuEncode (&t); - ret += 0 >= biseqcstr (b, "+2&5L;&\\@=V]R;&0`\r\n"); - c = bUuDecodeEx (b, &err); - ret += 0 != err; - ret += 0 >= biseq (c, &t); - bdestroy (b); - bdestroy (c); - - printf ("\t# failures: %d\n", ret); - - return ret; -} - -int test11 (void) { -struct tagbstring t = bsStatic ("Hello world"); -unsigned char Ytstr[] = {0x72, 0x8f, 0x96, 0x96, 0x99, 0x4a, 0xa1, 0x99, 0x9c, 0x96, 0x8e}; -bstring b, c; -int ret = 0; - - printf ("TEST: Y codec.\n"); - - b = bYEncode (&t); - ret += 11 != b->slen; - ret += 0 >= bisstemeqblk (b, Ytstr, 11); - c = bYDecode (b); - ret += 0 >= biseq (c, &t); - bdestroy (b); - bdestroy (c); - - printf ("\t# failures: %d\n", ret); - - return ret; -} - -int test12 (void) { -struct tagbstring t = bsStatic ("Hello world"); -struct bStream * s; -bstring b; -int ret = 0; - - printf ("TEST: bsFromBstr.\n"); - - ret = bsread (b = bfromcstr (""), s = bsFromBstr (&t), 6); - ret += 1 != biseqcstr (b, "Hello "); - if (b) b->slen = 0; - ret = bsread (b, s, 6); - ret += 1 != biseqcstr (b, "world"); - - bdestroy (b); - bsclose (s); - - printf ("\t# failures: %d\n", ret); - - return ret; -} - -struct vfgetc { - int ofs; - bstring base; -}; - -static int test13_fgetc (void * ctx) { -struct vfgetc * vctx = (struct vfgetc *) ctx; -int c; - - if (NULL == vctx || NULL == vctx->base) return EOF; - if (vctx->ofs >= blength (vctx->base)) return EOF; - c = bchare (vctx->base, vctx->ofs, EOF); - vctx->ofs++; - return c; -} - -int test13 (void) { -struct tagbstring t0 = bsStatic ("Random String, long enough to cause to reallocing"); -struct vfgetc vctx; -bstring b; -int ret = 0; -int i; - - printf ("TEST: bSecureInput, bSecureDestroy.\n"); - - for (i=0; i < 1000; i++) { - unsigned char * h; - - vctx.ofs = 0; - vctx.base = &t0; - - b = bSecureInput (INT_MAX, '\n', (bNgetc) test13_fgetc, &vctx); - ret += 1 != biseq (b, &t0); - h = b->data; - bSecureDestroy (b); - - /* WARNING! Technically undefined code follows (h has been freed): */ - ret += (0 == memcmp (h, t0.data, t0.slen)); - - if (ret) break; - } - - printf ("\t# failures: %d\n", ret); - - return ret; -} - -int test14_aux(bstring b, const char* chkVal) { -int ret = 0; - ret += 0 != bSGMLEncode (b); - ret += 1 != biseqcstr (b, chkVal); - return ret; -} - -int test14 (void) { -bstring b; -int ret = 0; - - printf ("TEST: bSGMLEncode.\n"); - ret += test14_aux (b = bfromStatic ("<\"Hello, you, me, & world\">"), "<"Hello, you, me, & world">"); - printf ("\t# failures: %d\n", ret); - return ret; -} - -int main () { -int ret = 0; - - printf ("Direct case testing of bstraux functions\n"); - - ret += test0 (); - ret += test1 (); - ret += test2 (); - ret += test3 (); - ret += test4 (); - ret += test5 (); - ret += test6 (); - ret += test7 (); - ret += test8 (); - ret += test9 (); - ret += test10 (); - ret += test11 (); - ret += test12 (); - ret += test13 (); - ret += test14 (); - - printf ("# test failures: %d\n", ret); - - return 0; -} diff --git a/bstrlib/utf8util.c b/bstrlib/utf8util.c deleted file mode 100644 index b74606f..0000000 --- a/bstrlib/utf8util.c +++ /dev/null @@ -1,249 +0,0 @@ -/* - * This source file is part of the bstring string library. This code was - * written by Paul Hsieh in 2002-2015, and is covered by the BSD open source - * license and the GPL. Refer to the accompanying documentation for details - * on usage and license. - */ - -/* - * utf8util.c - * - * This file is not necessarily part of the core bstring library itself, but - * is just an generic module for implementing utf8 utility functions. - */ - -#include "utf8util.h" - -#ifndef NULL -#ifdef __cplusplus -#define NULL 0 -#else -#define NULL ((void *)0) -#endif -#endif - -/* Surrogate range is wrong, there is a maximum, the BOM alias is illegal and 0xFFFF is illegal */ -#define isLegalUnicodeCodePoint(v) ((((v) < 0xD800L) || ((v) > 0xDFFFL)) && (((unsigned long)(v)) <= 0x0010FFFFL) && (((v)|0x1F0001) != 0x1FFFFFL)) - -void utf8IteratorInit (struct utf8Iterator* iter, unsigned char* data, int slen) { - if (iter) { - iter->data = data; - iter->slen = (iter->data && slen >= 0) ? slen : -1; - iter->start = -1; - iter->next = (iter->slen >= 0) ? 0 : -1; - iter->error = (iter->slen >= 0) ? 0 : 1; - } -} - -void utf8IteratorUninit (struct utf8Iterator* iter) { - if (iter) { - iter->data = NULL; - iter->slen = -1; - iter->start = iter->next = -1; - } -} - -int utf8ScanBackwardsForCodePoint (unsigned char* msg, int len, int pos, cpUcs4* out) { - cpUcs4 v1, v2, v3, v4, x; - int ret; - if (NULL == msg || len < 0 || (unsigned) pos >= (unsigned) len) { - return -__LINE__; - } - if (!out) out = &x; - ret = 0; - if (msg[pos] < 0x80) { - *out = msg[pos]; - return 0; - } else if (msg[pos] < 0xC0) { - if (0 == pos) return -__LINE__; - ret = -__LINE__; - if (msg[pos-1] >= 0xC1 && msg[pos-1] < 0xF8) { - pos--; - ret = 1; - } else { - if (1 == pos) return -__LINE__; - if ((msg[pos-1] | 0x3F) != 0xBF) return -__LINE__; - if (msg[pos-2] >= 0xE0 && msg[pos-2] < 0xF8) { - pos -= 2; - ret = 2; - } else { - if (2 == pos) return -__LINE__; - if ((msg[pos-2] | 0x3F) != 0xBF) return -__LINE__; - if ((msg[pos-3]|0x07) == 0xF7) { - pos -= 3; - ret = 3; - } else return -__LINE__; - } - } - } - if (msg[pos] < 0xE0) { - if (pos + 1 >= len) return -__LINE__; - v1 = msg[pos] & ~0xE0; - v2 = msg[pos+1] & ~0xC0; - v1 = (v1 << 6) + v2; - if (v1 < 0x80) return -__LINE__; - *out = v1; - return ret; - } - if (msg[pos] < 0xF0) { - if (pos + 2 >= len) return -__LINE__; - v1 = msg[pos] & ~0xF0; - v2 = msg[pos+1] & ~0xC0; - v3 = msg[pos+2] & ~0xC0; - v1 = (v1 << 12) + (v2 << 6) + v3; - if (v1 < 0x800) return -__LINE__; - if (!isLegalUnicodeCodePoint(v1)) return -__LINE__; - *out = v1; - return ret; - } - - if (msg[pos] >= 0xF8) return -__LINE__; - - if (pos + 3 >= len) return -__LINE__; - v1 = msg[pos] & ~0xF8; - v2 = msg[pos+1] & ~0xC0; - v3 = msg[pos+2] & ~0xC0; - v4 = msg[pos+3] & ~0xC0; - v1 = (v1 << 18) + (v2 << 12) + (v3 << 6) + v4; - if (v1 < 0x10000) return -__LINE__; - if (!isLegalUnicodeCodePoint(v1)) return -__LINE__; - *out = v1; - return ret; -} - -/* -Code point UTF-8 ----------- ----- -U-00000000 - U-0000007F: 0xxxxxxx -U-00000080 - U-000007FF: 110xxxxx 10xxxxxx -U-00000800 - U-0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx -U-00010000 - U-001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx - -U-00200000 - U-03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx -U-04000000 - U-7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx -*/ - -/* - * Returns next read code point for iterator. - * - * iter->data + iter->start points at the characters just read. - * - * iter->data + iter->next points at the characters that will be read next. - * - * iter->error is boolean indicating whether or not last read contained an error. - */ -cpUcs4 utf8IteratorGetNextCodePoint (struct utf8Iterator* iter, cpUcs4 errCh) { - unsigned char * chrs; - unsigned char c, d, e; - long v; - int i, ofs; - - if (NULL == iter || iter->next < 0) return errCh; - if (iter->next >= iter->slen) { - iter->start = iter->slen; - return errCh; - } - if (NULL == iter->data || iter->next < 0 || utf8IteratorNoMore(iter)) return errCh; - chrs = iter->data + iter->next; - - iter->error = 0; - c = chrs[0]; - ofs = 0; - - if (c < 0xC0 || c > 0xFD) { - if (c >= 0x80) goto ErrMode; - v = c; - ofs = 1; - } else if (c < 0xE0) { - if (iter->next >= iter->slen + 1) goto ErrMode; - v = (c << 6u) - (0x0C0 << 6u); - c = (unsigned char) ((unsigned) chrs[1] - 0x080); - v += c; - if (c >= 0x40 || v < 0x80) goto ErrMode; - ofs = 2; - } else if (c < 0xF0) { - if (iter->next >= iter->slen + 2) goto ErrMode; - v = (c << 12) - (0x0E0 << 12u); - c = (unsigned char) ((unsigned) chrs[1] - 0x080); - d = (unsigned char) ((unsigned) chrs[2] - 0x080); - v += (c << 6u) + d; - if ((c|d) >= 0x40 || v < 0x800 || !isLegalUnicodeCodePoint (v)) goto ErrMode; - ofs = 3; - } else if (c < 0xF8) { - if (iter->next >= iter->slen + 3) goto ErrMode; - v = (c << 18) - (0x0F0 << 18u); - c = (unsigned char) ((unsigned) chrs[1] - 0x080); - d = (unsigned char) ((unsigned) chrs[2] - 0x080); - e = (unsigned char) ((unsigned) chrs[3] - 0x080); - v += (c << 12u) + (d << 6u) + e; - if ((c|d|e) >= 0x40 || v < 0x10000 || !isLegalUnicodeCodePoint (v)) goto ErrMode; - ofs = 4; - } else { /* 5 and 6 byte encodings are invalid */ - ErrMode:; - iter->error = 1; - v = errCh; - for (i = iter->next+1; i < iter->slen; i++) if ((iter->data[i] & 0xC0) != 0x80) break; - ofs = i - iter->next; - } - - iter->start = iter->next; - iter->next += ofs; - return v; -} - -/* - * Returns next read code point for iterator. - * - * iter->data + iter->start points at the characters to be read. - * - * iter->data + iter->next points at the characters that will be read next. - * - * iter->error is boolean indicating whether or not last read contained an error. - */ -cpUcs4 utf8IteratorGetCurrCodePoint (struct utf8Iterator* iter, cpUcs4 errCh) { - unsigned char * chrs; - unsigned char c, d, e; - long v; - - if (NULL == iter || iter->next < 0) return errCh; - if (iter->next >= iter->slen) { - iter->start = iter->slen; - return errCh; - } - if (NULL == iter->data || iter->next < 0 || utf8IteratorNoMore(iter)) return errCh; - chrs = iter->data + iter->next; - - iter->error = 0; - c = chrs[0]; - - if (c < 0xC0 || c > 0xFD) { - if (c >= 0x80) goto ErrMode; - v = c; - } else if (c < 0xE0) { - if (iter->next >= iter->slen + 1) goto ErrMode; - v = (c << 6u) - (0x0C0 << 6u); - c = (unsigned char) ((unsigned) chrs[1] - 0x080); - v += c; - if (c >= 0x40 || v < 0x80) goto ErrMode; - } else if (c < 0xF0) { - if (iter->next >= iter->slen + 2) goto ErrMode; - v = (c << 12lu) - (0x0E0 << 12u); - c = (unsigned char) ((unsigned) chrs[1] - 0x080); - d = (unsigned char) ((unsigned) chrs[2] - 0x080); - v += (c << 6u) + d; - if ((c|d) >= 0x40 || v < 0x800 || !isLegalUnicodeCodePoint (v)) goto ErrMode; - } else if (c < 0xF8) { - if (iter->next >= iter->slen + 3) goto ErrMode; - v = (c << 18lu) - (0x0F0 << 18u); - c = (unsigned char) ((unsigned) chrs[1] - 0x080); - d = (unsigned char) ((unsigned) chrs[2] - 0x080); - e = (unsigned char) ((unsigned) chrs[3] - 0x080); - v += (c << 12lu) + (d << 6u) + e; - if ((c|d|e) >= 0x40 || v < 0x10000 || !isLegalUnicodeCodePoint (v)) goto ErrMode; - } else { /* 5 and 6 byte encodings are invalid */ - ErrMode:; - iter->error = 1; - v = errCh; - } - return v; -} diff --git a/bstrlib/utf8util.h b/bstrlib/utf8util.h deleted file mode 100644 index 5e615f7..0000000 --- a/bstrlib/utf8util.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * This source file is part of the bstring string library. This code was - * written by Paul Hsieh in 2002-2015, and is covered by the BSD open source - * license and the GPL. Refer to the accompanying documentation for details - * on usage and license. - */ - -/* - * utf8util.h - * - * This file defines the interface to the utf8 utility functions. - */ - -#ifndef UTF8_UNICODE_UTILITIES -#define UTF8_UNICODE_UTILITIES - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#if INT_MAX >= 0x7fffffffUL -typedef int cpUcs4; -#elif LONG_MAX >= 0x7fffffffUL -typedef long cpUcs4; -#else -#error This compiler is not supported -#endif - -#if UINT_MAX == 0xFFFF -typedef unsigned int cpUcs2; -#elif USHRT_MAX == 0xFFFF -typedef unsigned short cpUcs2; -#elif UCHAR_MAX == 0xFFFF -typedef unsigned char cpUcs2; -#else -#error This compiler is not supported -#endif - -#define isLegalUnicodeCodePoint(v) ((((v) < 0xD800L) || ((v) > 0xDFFFL)) && (((unsigned long)(v)) <= 0x0010FFFFL) && (((v)|0x1F0001) != 0x1FFFFFL)) - -struct utf8Iterator { - unsigned char* data; - int slen; - int start, next; - int error; -}; - -#define utf8IteratorNoMore(it) (!(it) || (it)->next >= (it)->slen) - -extern void utf8IteratorInit (struct utf8Iterator* iter, unsigned char* data, int slen); -extern void utf8IteratorUninit (struct utf8Iterator* iter); -extern cpUcs4 utf8IteratorGetNextCodePoint (struct utf8Iterator* iter, cpUcs4 errCh); -extern cpUcs4 utf8IteratorGetCurrCodePoint (struct utf8Iterator* iter, cpUcs4 errCh); -extern int utf8ScanBackwardsForCodePoint (unsigned char* msg, int len, int pos, cpUcs4* out); - -#ifdef __cplusplus -} -#endif - -#endif /* UTF8_UNICODE_UTILITIES */ diff --git a/common/LZMA/LzmaCompress.c b/common/LZMA/LzmaCompress.c index 8ae345c..dc97fa5 100644 --- a/common/LZMA/LzmaCompress.c +++ b/common/LZMA/LzmaCompress.c @@ -19,13 +19,13 @@ WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #define LZMA_HEADER_SIZE (LZMA_PROPS_SIZE + 8) -static void * AllocForLzma(void *p, size_t size) { (void)p; return malloc(size); } -static void FreeForLzma(void *p, void *address) { (void)p; free(address); } +static void * AllocForLzma(ISzAllocPtr p, size_t size) { (void)p; return malloc(size); } +static void FreeForLzma(ISzAllocPtr p, void *address) { (void)p; free(address); } static ISzAlloc SzAllocForLzma = { &AllocForLzma, &FreeForLzma }; -SRes OnProgress(void *p, UInt64 inSize, UInt64 outSize) +SRes OnProgress(const ICompressProgress *p, UInt64 inSize, UInt64 outSize) { - (void)p; (void) inSize; (void) outSize; + (void)p; (void)inSize; (void)outSize; return SZ_OK; } @@ -34,9 +34,9 @@ static ICompressProgress g_ProgressCallback = { &OnProgress }; STATIC UINT64 EFIAPI -RShiftU64( -UINT64 Operand, -UINT32 Count +RShiftU64 ( + UINT64 Operand, + UINT32 Count ) { return Operand >> Count; @@ -44,8 +44,8 @@ UINT32 Count VOID SetEncodedSizeOfBuf( -UINT64 EncodedSize, -UINT8 *EncodedData + UINT64 EncodedSize, + UINT8* EncodedData ) { INT32 Index; @@ -58,13 +58,14 @@ UINT8 *EncodedData } } -INT32 +USTATUS EFIAPI -LzmaCompress( -CONST UINT8 *Source, -UINT32 SourceSize, -UINT8 *Destination, -UINT32 *DestinationSize +LzmaCompress ( + CONST UINT8 *Source, + UINT32 SourceSize, + UINT8 *Destination, + UINT32 *DestinationSize, + UINT32 DictionarySize ) { SRes LzmaResult; @@ -72,14 +73,14 @@ UINT32 *DestinationSize SizeT propsSize = LZMA_PROPS_SIZE; SizeT destLen = SourceSize + SourceSize / 3 + 128; - if (*DestinationSize < destLen) + if (*DestinationSize < (UINT32)destLen) { - *DestinationSize = destLen; + *DestinationSize = (UINT32)destLen; return EFI_BUFFER_TOO_SMALL; } LzmaEncProps_Init(&props); - props.dictSize = LZMA_DICTIONARY_SIZE; + props.dictSize = DictionarySize; props.level = 9; props.fb = 273; @@ -87,7 +88,7 @@ UINT32 *DestinationSize (Byte*)((UINT8*)Destination + LZMA_HEADER_SIZE), &destLen, Source, - SourceSize, + (SizeT)SourceSize, &props, (UINT8*)Destination, &propsSize, @@ -96,9 +97,9 @@ UINT32 *DestinationSize &SzAllocForLzma, &SzAllocForLzma); - *DestinationSize = destLen + LZMA_HEADER_SIZE; + *DestinationSize = (UINT32)(destLen + LZMA_HEADER_SIZE); - SetEncodedSizeOfBuf((UINT64)SourceSize, Destination); + SetEncodedSizeOfBuf(SourceSize, Destination); if (LzmaResult == SZ_OK) { return EFI_SUCCESS; diff --git a/common/LZMA/LzmaCompress.h b/common/LZMA/LzmaCompress.h index eeadb5c..6036523 100644 --- a/common/LZMA/LzmaCompress.h +++ b/common/LZMA/LzmaCompress.h @@ -14,23 +14,24 @@ #ifndef LZMACOMPRESS_H #define LZMACOMPRESS_H -#include "SDK/C/Types.h" +#include "SDK/C/7zTypes.h" #include "../basetypes.h" #ifdef __cplusplus extern "C" { #endif -#define LZMA_DICTIONARY_SIZE 0x800000 +#define DEFAULT_LZMA_DICTIONARY_SIZE 0x800000 #define _LZMA_SIZE_OPT - INT32 + USTATUS EFIAPI - LzmaCompress( - const UINT8 *Source, - UINT32 SourceSize, - UINT8 *Destination, - UINT32 *DestinationSize + LzmaCompress ( + const UINT8 *Source, + UINT32 SourceSize, + UINT8 *Destination, + UINT32 *DestinationSize, + UINT32 DictionarySize ); #ifdef __cplusplus diff --git a/common/LZMA/LzmaDecompress.c b/common/LZMA/LzmaDecompress.c index 1bac9d7..913ec97 100644 --- a/common/LZMA/LzmaDecompress.c +++ b/common/LZMA/LzmaDecompress.c @@ -12,23 +12,23 @@ WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. */ #include "LzmaDecompress.h" -#include "SDK/C/Types.h" +#include "SDK/C/7zTypes.h" #include "SDK/C/7zVersion.h" #include UINT64 EFIAPI -LShiftU64( -UINT64 Operand, -UINT32 Count -) +LShiftU64 ( + UINT64 Operand, + UINT32 Count + ) { return Operand << Count; } -static void * AllocForLzma(void *p, size_t size) { (void)p; return malloc(size); } -static void FreeForLzma(void *p, void *address) { (void)p; free(address); } +static void * AllocForLzma(ISzAllocPtr p, size_t size) { (void)p; return malloc(size); } +static void FreeForLzma(ISzAllocPtr p, void *address) { (void)p; free(address); } static ISzAlloc SzAllocForLzma = { &AllocForLzma, &FreeForLzma }; /* @@ -39,12 +39,12 @@ Get the size of the uncompressed buffer by parsing EncodeData header. @return The size of the uncompressed buffer. */ UINT64 -GetDecodedSizeOfBuf( -UINT8 *EncodedData -) +GetDecodedSizeOfBuf ( + UINT8 *EncodedData + ) { UINT64 DecodedSize; - INT32 Index; + INT32 Index; // Parse header DecodedSize = 0; @@ -85,22 +85,27 @@ DestinationSize and the size of the scratch buffer was returned ScratchSize. */ -INT32 +USTATUS EFIAPI -LzmaGetInfo( -CONST VOID *Source, -UINT32 SourceSize, -UINT32 *DestinationSize -) +LzmaGetInfo ( + CONST VOID *Source, + UINT32 SourceSize, + UINT32 *DestinationSize + ) { - UInt64 DecodedSize; + UINT64 DecodedSize; + ASSERT(SourceSize >= LZMA_HEADER_SIZE); + (void)SourceSize; - ASSERT(SourceSize >= LZMA_HEADER_SIZE); (void)SourceSize; - DecodedSize = GetDecodedSizeOfBuf((UINT8*)Source); - *DestinationSize = (UINT32)DecodedSize; - return U_SUCCESS; + if (DecodedSize <= UINT32_MAX) { + *DestinationSize = (UINT32)DecodedSize; + return U_SUCCESS; + } + else { + return U_INVALID_PARAMETER; + } } /* @@ -122,13 +127,13 @@ the uncompressed buffer is returned Destination. The source buffer specified by Source is corrupted (not a valid compressed format). */ -INT32 +USTATUS EFIAPI -LzmaDecompress( -CONST VOID *Source, -UINT32 SourceSize, -VOID *Destination -) +LzmaDecompress ( + CONST VOID *Source, + UINT32 SourceSize, + VOID *Destination + ) { SRes LzmaResult; ELzmaStatus Status; diff --git a/common/LZMA/LzmaDecompress.h b/common/LZMA/LzmaDecompress.h index fe89b86..1b9d8cf 100644 --- a/common/LZMA/LzmaDecompress.h +++ b/common/LZMA/LzmaDecompress.h @@ -16,6 +16,7 @@ #include "../basetypes.h" #include "SDK/C/LzmaDec.h" +#include "SDK/C/Bra.h" #ifdef __cplusplus extern "C" { @@ -23,13 +24,6 @@ extern "C" { #define LZMA_HEADER_SIZE (LZMA_PROPS_SIZE + 8) - UINT64 - EFIAPI - LShiftU64( - UINT64 Operand, - UINT32 Count - ); - /* Given a Lzma compressed source buffer, this function retrieves the size of the uncompressed buffer and the size of the scratch buffer required @@ -57,12 +51,12 @@ extern "C" { buffer was returned ScratchSize. */ - INT32 + USTATUS EFIAPI - LzmaGetInfo( - const VOID *Source, - UINT32 SourceSize, - UINT32 *DestinationSize + LzmaGetInfo ( + CONST VOID *Source, + UINT32 SourceSize, + UINT32 *DestinationSize ); /* @@ -84,12 +78,12 @@ extern "C" { The source buffer specified by Source is corrupted (not a valid compressed format). */ - INT32 + USTATUS EFIAPI - LzmaDecompress( - const VOID *Source, - UINT32 SourceSize, - VOID *Destination + LzmaDecompress ( + CONST VOID *Source, + UINT32 SourceSize, + VOID *Destination ); #ifdef __cplusplus diff --git a/common/LZMA/SDK/C/7zTypes.h b/common/LZMA/SDK/C/7zTypes.h new file mode 100644 index 0000000..5b77420 --- /dev/null +++ b/common/LZMA/SDK/C/7zTypes.h @@ -0,0 +1,597 @@ +/* 7zTypes.h -- Basic types +2024-01-24 : Igor Pavlov : Public domain */ + +#ifndef ZIP7_7Z_TYPES_H +#define ZIP7_7Z_TYPES_H + +#ifdef _WIN32 +/* #include */ +#else +#include +#endif + +#include + +#ifndef EXTERN_C_BEGIN +#ifdef __cplusplus +#define EXTERN_C_BEGIN extern "C" { +#define EXTERN_C_END } +#else +#define EXTERN_C_BEGIN +#define EXTERN_C_END +#endif +#endif + +EXTERN_C_BEGIN + +#define SZ_OK 0 + +#define SZ_ERROR_DATA 1 +#define SZ_ERROR_MEM 2 +#define SZ_ERROR_CRC 3 +#define SZ_ERROR_UNSUPPORTED 4 +#define SZ_ERROR_PARAM 5 +#define SZ_ERROR_INPUT_EOF 6 +#define SZ_ERROR_OUTPUT_EOF 7 +#define SZ_ERROR_READ 8 +#define SZ_ERROR_WRITE 9 +#define SZ_ERROR_PROGRESS 10 +#define SZ_ERROR_FAIL 11 +#define SZ_ERROR_THREAD 12 + +#define SZ_ERROR_ARCHIVE 16 +#define SZ_ERROR_NO_ARCHIVE 17 + +typedef int SRes; + + +#ifdef _MSC_VER + #if _MSC_VER > 1200 + #define MY_ALIGN(n) __declspec(align(n)) + #else + #define MY_ALIGN(n) + #endif +#else + /* + // C11/C++11: + #include + #define MY_ALIGN(n) alignas(n) + */ + #define MY_ALIGN(n) __attribute__ ((aligned(n))) +#endif + + +#ifdef _WIN32 + +/* typedef DWORD WRes; */ +typedef unsigned WRes; +#define MY_SRes_HRESULT_FROM_WRes(x) HRESULT_FROM_WIN32(x) + +// #define MY_HRES_ERROR_INTERNAL_ERROR MY_SRes_HRESULT_FROM_WRes(ERROR_INTERNAL_ERROR) + +#else // _WIN32 + +// #define ENV_HAVE_LSTAT +typedef int WRes; + +// (FACILITY_ERRNO = 0x800) is 7zip's FACILITY constant to represent (errno) errors in HRESULT +#define MY_FACILITY_ERRNO 0x800 +#define MY_FACILITY_WIN32 7 +#define MY_FACILITY_WRes MY_FACILITY_ERRNO + +#define MY_HRESULT_FROM_errno_CONST_ERROR(x) ((HRESULT)( \ + ( (HRESULT)(x) & 0x0000FFFF) \ + | (MY_FACILITY_WRes << 16) \ + | (HRESULT)0x80000000 )) + +#define MY_SRes_HRESULT_FROM_WRes(x) \ + ((HRESULT)(x) <= 0 ? ((HRESULT)(x)) : MY_HRESULT_FROM_errno_CONST_ERROR(x)) + +// we call macro HRESULT_FROM_WIN32 for system errors (WRes) that are (errno) +#define HRESULT_FROM_WIN32(x) MY_SRes_HRESULT_FROM_WRes(x) + +/* +#define ERROR_FILE_NOT_FOUND 2L +#define ERROR_ACCESS_DENIED 5L +#define ERROR_NO_MORE_FILES 18L +#define ERROR_LOCK_VIOLATION 33L +#define ERROR_FILE_EXISTS 80L +#define ERROR_DISK_FULL 112L +#define ERROR_NEGATIVE_SEEK 131L +#define ERROR_ALREADY_EXISTS 183L +#define ERROR_DIRECTORY 267L +#define ERROR_TOO_MANY_POSTS 298L + +#define ERROR_INTERNAL_ERROR 1359L +#define ERROR_INVALID_REPARSE_DATA 4392L +#define ERROR_REPARSE_TAG_INVALID 4393L +#define ERROR_REPARSE_TAG_MISMATCH 4394L +*/ + +// we use errno equivalents for some WIN32 errors: + +#define ERROR_INVALID_PARAMETER EINVAL +#define ERROR_INVALID_FUNCTION EINVAL +#define ERROR_ALREADY_EXISTS EEXIST +#define ERROR_FILE_EXISTS EEXIST +#define ERROR_PATH_NOT_FOUND ENOENT +#define ERROR_FILE_NOT_FOUND ENOENT +#define ERROR_DISK_FULL ENOSPC +// #define ERROR_INVALID_HANDLE EBADF + +// we use FACILITY_WIN32 for errors that has no errno equivalent +// Too many posts were made to a semaphore. +#define ERROR_TOO_MANY_POSTS ((HRESULT)0x8007012AL) +#define ERROR_INVALID_REPARSE_DATA ((HRESULT)0x80071128L) +#define ERROR_REPARSE_TAG_INVALID ((HRESULT)0x80071129L) + +// if (MY_FACILITY_WRes != FACILITY_WIN32), +// we use FACILITY_WIN32 for COM errors: +#define E_OUTOFMEMORY ((HRESULT)0x8007000EL) +#define E_INVALIDARG ((HRESULT)0x80070057L) +#define MY_E_ERROR_NEGATIVE_SEEK ((HRESULT)0x80070083L) + +/* +// we can use FACILITY_ERRNO for some COM errors, that have errno equivalents: +#define E_OUTOFMEMORY MY_HRESULT_FROM_errno_CONST_ERROR(ENOMEM) +#define E_INVALIDARG MY_HRESULT_FROM_errno_CONST_ERROR(EINVAL) +#define MY_E_ERROR_NEGATIVE_SEEK MY_HRESULT_FROM_errno_CONST_ERROR(EINVAL) +*/ + +#define TEXT(quote) quote + +#define FILE_ATTRIBUTE_READONLY 0x0001 +#define FILE_ATTRIBUTE_HIDDEN 0x0002 +#define FILE_ATTRIBUTE_SYSTEM 0x0004 +#define FILE_ATTRIBUTE_DIRECTORY 0x0010 +#define FILE_ATTRIBUTE_ARCHIVE 0x0020 +#define FILE_ATTRIBUTE_DEVICE 0x0040 +#define FILE_ATTRIBUTE_NORMAL 0x0080 +#define FILE_ATTRIBUTE_TEMPORARY 0x0100 +#define FILE_ATTRIBUTE_SPARSE_FILE 0x0200 +#define FILE_ATTRIBUTE_REPARSE_POINT 0x0400 +#define FILE_ATTRIBUTE_COMPRESSED 0x0800 +#define FILE_ATTRIBUTE_OFFLINE 0x1000 +#define FILE_ATTRIBUTE_NOT_CONTENT_INDEXED 0x2000 +#define FILE_ATTRIBUTE_ENCRYPTED 0x4000 + +#define FILE_ATTRIBUTE_UNIX_EXTENSION 0x8000 /* trick for Unix */ + +#endif + + +#ifndef RINOK +#define RINOK(x) { const int _result_ = (x); if (_result_ != 0) return _result_; } +#endif + +#ifndef RINOK_WRes +#define RINOK_WRes(x) { const WRes _result_ = (x); if (_result_ != 0) return _result_; } +#endif + +typedef unsigned char Byte; +typedef short Int16; +typedef unsigned short UInt16; + +#ifdef Z7_DECL_Int32_AS_long +typedef long Int32; +typedef unsigned long UInt32; +#else +typedef int Int32; +typedef unsigned int UInt32; +#endif + + +#ifndef _WIN32 + +typedef int INT; +typedef Int32 INT32; +typedef unsigned int UINT; +typedef UInt32 UINT32; +typedef INT32 LONG; // LONG, ULONG and DWORD must be 32-bit for _WIN32 compatibility +typedef UINT32 ULONG; + +#undef DWORD +typedef UINT32 DWORD; + +#define VOID void + +#define HRESULT LONG + +typedef void *LPVOID; +// typedef void VOID; +// typedef ULONG_PTR DWORD_PTR, *PDWORD_PTR; +// gcc / clang on Unix : sizeof(long==sizeof(void*) in 32 or 64 bits) +typedef long INT_PTR; +typedef unsigned long UINT_PTR; +typedef long LONG_PTR; +typedef unsigned long DWORD_PTR; + +typedef size_t SIZE_T; + +#endif // _WIN32 + + +#define MY_HRES_ERROR_INTERNAL_ERROR ((HRESULT)0x8007054FL) + + +#ifdef Z7_DECL_Int64_AS_long + +typedef long Int64; +typedef unsigned long UInt64; + +#else + +#if (defined(_MSC_VER) || defined(__BORLANDC__)) && !defined(__clang__) +typedef __int64 Int64; +typedef unsigned __int64 UInt64; +#else +#if defined(__clang__) || defined(__GNUC__) +#include +typedef int64_t Int64; +typedef uint64_t UInt64; +#else +typedef long long int Int64; +typedef unsigned long long int UInt64; +// #define UINT64_CONST(n) n ## ULL +#endif +#endif + +#endif + +#define UINT64_CONST(n) n + + +#ifdef Z7_DECL_SizeT_AS_unsigned_int +typedef unsigned int SizeT; +#else +typedef size_t SizeT; +#endif + +/* +#if (defined(_MSC_VER) && _MSC_VER <= 1200) +typedef size_t MY_uintptr_t; +#else +#include +typedef uintptr_t MY_uintptr_t; +#endif +*/ + +typedef int BoolInt; +/* typedef BoolInt Bool; */ +#define True 1 +#define False 0 + + +#ifdef _WIN32 +#define Z7_STDCALL __stdcall +#else +#define Z7_STDCALL +#endif + +#ifdef _MSC_VER + +#if _MSC_VER >= 1300 +#define Z7_NO_INLINE __declspec(noinline) +#else +#define Z7_NO_INLINE +#endif + +#define Z7_FORCE_INLINE __forceinline + +#define Z7_CDECL __cdecl +#define Z7_FASTCALL __fastcall + +#else // _MSC_VER + +#if (defined(__GNUC__) && (__GNUC__ >= 4)) \ + || (defined(__clang__) && (__clang_major__ >= 4)) \ + || defined(__INTEL_COMPILER) \ + || defined(__xlC__) +#define Z7_NO_INLINE __attribute__((noinline)) +#define Z7_FORCE_INLINE __attribute__((always_inline)) inline +#else +#define Z7_NO_INLINE +#define Z7_FORCE_INLINE +#endif + +#define Z7_CDECL + +#if defined(_M_IX86) \ + || defined(__i386__) +// #define Z7_FASTCALL __attribute__((fastcall)) +// #define Z7_FASTCALL __attribute__((cdecl)) +#define Z7_FASTCALL +#elif defined(MY_CPU_AMD64) +// #define Z7_FASTCALL __attribute__((ms_abi)) +#define Z7_FASTCALL +#else +#define Z7_FASTCALL +#endif + +#endif // _MSC_VER + + +/* The following interfaces use first parameter as pointer to structure */ + +// #define Z7_C_IFACE_CONST_QUAL +#define Z7_C_IFACE_CONST_QUAL const + +#define Z7_C_IFACE_DECL(a) \ + struct a ## _; \ + typedef Z7_C_IFACE_CONST_QUAL struct a ## _ * a ## Ptr; \ + typedef struct a ## _ a; \ + struct a ## _ + + +Z7_C_IFACE_DECL (IByteIn) +{ + Byte (*Read)(IByteInPtr p); /* reads one byte, returns 0 in case of EOF or error */ +}; +#define IByteIn_Read(p) (p)->Read(p) + + +Z7_C_IFACE_DECL (IByteOut) +{ + void (*Write)(IByteOutPtr p, Byte b); +}; +#define IByteOut_Write(p, b) (p)->Write(p, b) + + +Z7_C_IFACE_DECL (ISeqInStream) +{ + SRes (*Read)(ISeqInStreamPtr p, void *buf, size_t *size); + /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. + (output(*size) < input(*size)) is allowed */ +}; +#define ISeqInStream_Read(p, buf, size) (p)->Read(p, buf, size) + +/* try to read as much as avail in stream and limited by (*processedSize) */ +SRes SeqInStream_ReadMax(ISeqInStreamPtr stream, void *buf, size_t *processedSize); +/* it can return SZ_ERROR_INPUT_EOF */ +// SRes SeqInStream_Read(ISeqInStreamPtr stream, void *buf, size_t size); +// SRes SeqInStream_Read2(ISeqInStreamPtr stream, void *buf, size_t size, SRes errorType); +SRes SeqInStream_ReadByte(ISeqInStreamPtr stream, Byte *buf); + + +Z7_C_IFACE_DECL (ISeqOutStream) +{ + size_t (*Write)(ISeqOutStreamPtr p, const void *buf, size_t size); + /* Returns: result - the number of actually written bytes. + (result < size) means error */ +}; +#define ISeqOutStream_Write(p, buf, size) (p)->Write(p, buf, size) + +typedef enum +{ + SZ_SEEK_SET = 0, + SZ_SEEK_CUR = 1, + SZ_SEEK_END = 2 +} ESzSeek; + + +Z7_C_IFACE_DECL (ISeekInStream) +{ + SRes (*Read)(ISeekInStreamPtr p, void *buf, size_t *size); /* same as ISeqInStream::Read */ + SRes (*Seek)(ISeekInStreamPtr p, Int64 *pos, ESzSeek origin); +}; +#define ISeekInStream_Read(p, buf, size) (p)->Read(p, buf, size) +#define ISeekInStream_Seek(p, pos, origin) (p)->Seek(p, pos, origin) + + +Z7_C_IFACE_DECL (ILookInStream) +{ + SRes (*Look)(ILookInStreamPtr p, const void **buf, size_t *size); + /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. + (output(*size) > input(*size)) is not allowed + (output(*size) < input(*size)) is allowed */ + SRes (*Skip)(ILookInStreamPtr p, size_t offset); + /* offset must be <= output(*size) of Look */ + SRes (*Read)(ILookInStreamPtr p, void *buf, size_t *size); + /* reads directly (without buffer). It's same as ISeqInStream::Read */ + SRes (*Seek)(ILookInStreamPtr p, Int64 *pos, ESzSeek origin); +}; + +#define ILookInStream_Look(p, buf, size) (p)->Look(p, buf, size) +#define ILookInStream_Skip(p, offset) (p)->Skip(p, offset) +#define ILookInStream_Read(p, buf, size) (p)->Read(p, buf, size) +#define ILookInStream_Seek(p, pos, origin) (p)->Seek(p, pos, origin) + + +SRes LookInStream_LookRead(ILookInStreamPtr stream, void *buf, size_t *size); +SRes LookInStream_SeekTo(ILookInStreamPtr stream, UInt64 offset); + +/* reads via ILookInStream::Read */ +SRes LookInStream_Read2(ILookInStreamPtr stream, void *buf, size_t size, SRes errorType); +SRes LookInStream_Read(ILookInStreamPtr stream, void *buf, size_t size); + + +typedef struct +{ + ILookInStream vt; + ISeekInStreamPtr realStream; + + size_t pos; + size_t size; /* it's data size */ + + /* the following variables must be set outside */ + Byte *buf; + size_t bufSize; +} CLookToRead2; + +void LookToRead2_CreateVTable(CLookToRead2 *p, int lookahead); + +#define LookToRead2_INIT(p) { (p)->pos = (p)->size = 0; } + + +typedef struct +{ + ISeqInStream vt; + ILookInStreamPtr realStream; +} CSecToLook; + +void SecToLook_CreateVTable(CSecToLook *p); + + + +typedef struct +{ + ISeqInStream vt; + ILookInStreamPtr realStream; +} CSecToRead; + +void SecToRead_CreateVTable(CSecToRead *p); + + +Z7_C_IFACE_DECL (ICompressProgress) +{ + SRes (*Progress)(ICompressProgressPtr p, UInt64 inSize, UInt64 outSize); + /* Returns: result. (result != SZ_OK) means break. + Value (UInt64)(Int64)-1 for size means unknown value. */ +}; + +#define ICompressProgress_Progress(p, inSize, outSize) (p)->Progress(p, inSize, outSize) + + + +typedef struct ISzAlloc ISzAlloc; +typedef const ISzAlloc * ISzAllocPtr; + +struct ISzAlloc +{ + void *(*Alloc)(ISzAllocPtr p, size_t size); + void (*Free)(ISzAllocPtr p, void *address); /* address can be 0 */ +}; + +#define ISzAlloc_Alloc(p, size) (p)->Alloc(p, size) +#define ISzAlloc_Free(p, a) (p)->Free(p, a) + +/* deprecated */ +#define IAlloc_Alloc(p, size) ISzAlloc_Alloc(p, size) +#define IAlloc_Free(p, a) ISzAlloc_Free(p, a) + + + + + +#ifndef MY_offsetof + #ifdef offsetof + #define MY_offsetof(type, m) offsetof(type, m) + /* + #define MY_offsetof(type, m) FIELD_OFFSET(type, m) + */ + #else + #define MY_offsetof(type, m) ((size_t)&(((type *)0)->m)) + #endif +#endif + + + +#ifndef Z7_container_of + +/* +#define Z7_container_of(ptr, type, m) container_of(ptr, type, m) +#define Z7_container_of(ptr, type, m) CONTAINING_RECORD(ptr, type, m) +#define Z7_container_of(ptr, type, m) ((type *)((char *)(ptr) - offsetof(type, m))) +#define Z7_container_of(ptr, type, m) (&((type *)0)->m == (ptr), ((type *)(((char *)(ptr)) - MY_offsetof(type, m)))) +*/ + +/* + GCC shows warning: "perhaps the 'offsetof' macro was used incorrectly" + GCC 3.4.4 : classes with constructor + GCC 4.8.1 : classes with non-public variable members" +*/ + +#define Z7_container_of(ptr, type, m) \ + ((type *)(void *)((char *)(void *) \ + (1 ? (ptr) : &((type *)NULL)->m) - MY_offsetof(type, m))) + +#define Z7_container_of_CONST(ptr, type, m) \ + ((const type *)(const void *)((const char *)(const void *) \ + (1 ? (ptr) : &((type *)NULL)->m) - MY_offsetof(type, m))) + +/* +#define Z7_container_of_NON_CONST_FROM_CONST(ptr, type, m) \ + ((type *)(void *)(const void *)((const char *)(const void *) \ + (1 ? (ptr) : &((type *)NULL)->m) - MY_offsetof(type, m))) +*/ + +#endif + +#define Z7_CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m) ((type *)(void *)(ptr)) + +// #define Z7_CONTAINER_FROM_VTBL(ptr, type, m) Z7_CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m) +#define Z7_CONTAINER_FROM_VTBL(ptr, type, m) Z7_container_of(ptr, type, m) +// #define Z7_CONTAINER_FROM_VTBL(ptr, type, m) Z7_container_of_NON_CONST_FROM_CONST(ptr, type, m) + +#define Z7_CONTAINER_FROM_VTBL_CONST(ptr, type, m) Z7_container_of_CONST(ptr, type, m) + +#define Z7_CONTAINER_FROM_VTBL_CLS(ptr, type, m) Z7_CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m) +/* +#define Z7_CONTAINER_FROM_VTBL_CLS(ptr, type, m) Z7_CONTAINER_FROM_VTBL(ptr, type, m) +*/ +#if defined (__clang__) || defined(__GNUC__) +#define Z7_DIAGNOSTIC_IGNORE_BEGIN_CAST_QUAL \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wcast-qual\"") +#define Z7_DIAGNOSTIC_IGNORE_END_CAST_QUAL \ + _Pragma("GCC diagnostic pop") +#else +#define Z7_DIAGNOSTIC_IGNORE_BEGIN_CAST_QUAL +#define Z7_DIAGNOSTIC_IGNORE_END_CAST_QUAL +#endif + +#define Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR(ptr, type, m, p) \ + Z7_DIAGNOSTIC_IGNORE_BEGIN_CAST_QUAL \ + type *p = Z7_CONTAINER_FROM_VTBL(ptr, type, m); \ + Z7_DIAGNOSTIC_IGNORE_END_CAST_QUAL + +#define Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(type) \ + Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR(pp, type, vt, p) + + +// #define ZIP7_DECLARE_HANDLE(name) typedef void *name; +#define Z7_DECLARE_HANDLE(name) struct name##_dummy{int unused;}; typedef struct name##_dummy *name; + + +#define Z7_memset_0_ARRAY(a) memset((a), 0, sizeof(a)) + +#ifndef Z7_ARRAY_SIZE +#define Z7_ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) +#endif + + +#ifdef _WIN32 + +#define CHAR_PATH_SEPARATOR '\\' +#define WCHAR_PATH_SEPARATOR L'\\' +#define STRING_PATH_SEPARATOR "\\" +#define WSTRING_PATH_SEPARATOR L"\\" + +#else + +#define CHAR_PATH_SEPARATOR '/' +#define WCHAR_PATH_SEPARATOR L'/' +#define STRING_PATH_SEPARATOR "/" +#define WSTRING_PATH_SEPARATOR L"/" + +#endif + +#define k_PropVar_TimePrec_0 0 +#define k_PropVar_TimePrec_Unix 1 +#define k_PropVar_TimePrec_DOS 2 +#define k_PropVar_TimePrec_HighPrec 3 +#define k_PropVar_TimePrec_Base 16 +#define k_PropVar_TimePrec_100ns (k_PropVar_TimePrec_Base + 7) +#define k_PropVar_TimePrec_1ns (k_PropVar_TimePrec_Base + 9) + +EXTERN_C_END + +#endif + +/* +#ifndef Z7_ST +#ifdef _7ZIP_ST +#define Z7_ST +#endif +#endif +*/ diff --git a/common/LZMA/SDK/C/7zVersion.h b/common/LZMA/SDK/C/7zVersion.h index 9d99c5d..e82ba0b 100644 --- a/common/LZMA/SDK/C/7zVersion.h +++ b/common/LZMA/SDK/C/7zVersion.h @@ -1,7 +1,27 @@ -#define MY_VER_MAJOR 9 -#define MY_VER_MINOR 20 +#define MY_VER_MAJOR 24 +#define MY_VER_MINOR 9 #define MY_VER_BUILD 0 -#define MY_VERSION "9.20" -#define MY_DATE "2010-11-18" -#define MY_COPYRIGHT ": Igor Pavlov : Public domain" -#define MY_VERSION_COPYRIGHT_DATE MY_VERSION " " MY_COPYRIGHT " : " MY_DATE +#define MY_VERSION_NUMBERS "24.09" +#define MY_VERSION MY_VERSION_NUMBERS + +#ifdef MY_CPU_NAME + #define MY_VERSION_CPU MY_VERSION " (" MY_CPU_NAME ")" +#else + #define MY_VERSION_CPU MY_VERSION +#endif + +#define MY_DATE "2024-11-29" +#undef MY_COPYRIGHT +#undef MY_VERSION_COPYRIGHT_DATE +#define MY_AUTHOR_NAME "Igor Pavlov" +#define MY_COPYRIGHT_PD "Igor Pavlov : Public domain" +#define MY_COPYRIGHT_CR "Copyright (c) 1999-2024 Igor Pavlov" + +#ifdef USE_COPYRIGHT_CR + #define MY_COPYRIGHT MY_COPYRIGHT_CR +#else + #define MY_COPYRIGHT MY_COPYRIGHT_PD +#endif + +#define MY_COPYRIGHT_DATE MY_COPYRIGHT " : " MY_DATE +#define MY_VERSION_COPYRIGHT_DATE MY_VERSION_CPU " : " MY_COPYRIGHT " : " MY_DATE diff --git a/common/LZMA/SDK/C/7zWindows.h b/common/LZMA/SDK/C/7zWindows.h new file mode 100644 index 0000000..42c6db8 --- /dev/null +++ b/common/LZMA/SDK/C/7zWindows.h @@ -0,0 +1,101 @@ +/* 7zWindows.h -- StdAfx +2023-04-02 : Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_7Z_WINDOWS_H +#define ZIP7_INC_7Z_WINDOWS_H + +#ifdef _WIN32 + +#if defined(__clang__) +# pragma clang diagnostic push +#endif + +#if defined(_MSC_VER) + +#pragma warning(push) +#pragma warning(disable : 4668) // '_WIN32_WINNT' is not defined as a preprocessor macro, replacing with '0' for '#if/#elif' + +#if _MSC_VER == 1900 +// for old kit10 versions +// #pragma warning(disable : 4255) // winuser.h(13979): warning C4255: 'GetThreadDpiAwarenessContext': +#endif +// win10 Windows Kit: +#endif // _MSC_VER + +#if defined(_MSC_VER) && _MSC_VER <= 1200 && !defined(_WIN64) +// for msvc6 without sdk2003 +#define RPC_NO_WINDOWS_H +#endif + +#if defined(__MINGW32__) || defined(__MINGW64__) +// #if defined(__GNUC__) && !defined(__clang__) +#include +#else +#include +#endif +// #include +// #include + +// but if precompiled with clang-cl then we need +// #include +#if defined(_MSC_VER) +#pragma warning(pop) +#endif + +#if defined(__clang__) +# pragma clang diagnostic pop +#endif + +#if defined(_MSC_VER) && _MSC_VER <= 1200 && !defined(_WIN64) +#ifndef _W64 + +typedef long LONG_PTR, *PLONG_PTR; +typedef unsigned long ULONG_PTR, *PULONG_PTR; +typedef ULONG_PTR DWORD_PTR, *PDWORD_PTR; + +#define Z7_OLD_WIN_SDK +#endif // _W64 +#endif // _MSC_VER == 1200 + +#ifdef Z7_OLD_WIN_SDK + +#ifndef INVALID_FILE_ATTRIBUTES +#define INVALID_FILE_ATTRIBUTES ((DWORD)-1) +#endif +#ifndef INVALID_SET_FILE_POINTER +#define INVALID_SET_FILE_POINTER ((DWORD)-1) +#endif +#ifndef FILE_SPECIAL_ACCESS +#define FILE_SPECIAL_ACCESS (FILE_ANY_ACCESS) +#endif + +// ShlObj.h: +// #define BIF_NEWDIALOGSTYLE 0x0040 + +#pragma warning(disable : 4201) +// #pragma warning(disable : 4115) + +#undef VARIANT_TRUE +#define VARIANT_TRUE ((VARIANT_BOOL)-1) +#endif + +#endif // Z7_OLD_WIN_SDK + +#ifdef UNDER_CE +#undef VARIANT_TRUE +#define VARIANT_TRUE ((VARIANT_BOOL)-1) +#endif + + +#if defined(_MSC_VER) +#if _MSC_VER >= 1400 && _MSC_VER <= 1600 + // BaseTsd.h(148) : 'HandleToULong' : unreferenced inline function has been removed + // string.h + // #pragma warning(disable : 4514) +#endif +#endif + + +/* #include "7zTypes.h" */ + +#endif diff --git a/common/LZMA/SDK/C/Bra.c b/common/LZMA/SDK/C/Bra.c new file mode 100644 index 0000000..e61edf8 --- /dev/null +++ b/common/LZMA/SDK/C/Bra.c @@ -0,0 +1,709 @@ +/* Bra.c -- Branch converters for RISC code +2024-01-20 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include "Bra.h" +#include "RotateDefs.h" +#include "CpuArch.h" + +#if defined(MY_CPU_SIZEOF_POINTER) \ + && ( MY_CPU_SIZEOF_POINTER == 4 \ + || MY_CPU_SIZEOF_POINTER == 8) + #define BR_CONV_USE_OPT_PC_PTR +#endif + +#ifdef BR_CONV_USE_OPT_PC_PTR +#define BR_PC_INIT pc -= (UInt32)(SizeT)p; +#define BR_PC_GET (pc + (UInt32)(SizeT)p) +#else +#define BR_PC_INIT pc += (UInt32)size; +#define BR_PC_GET (pc - (UInt32)(SizeT)(lim - p)) +// #define BR_PC_INIT +// #define BR_PC_GET (pc + (UInt32)(SizeT)(p - data)) +#endif + +#define BR_CONVERT_VAL(v, c) if (encoding) v += c; else v -= c; +// #define BR_CONVERT_VAL(v, c) if (!encoding) c = (UInt32)0 - c; v += c; + +#define Z7_BRANCH_CONV(name) z7_ ## name + +#define Z7_BRANCH_FUNC_MAIN(name) \ +static \ +Z7_FORCE_INLINE \ +Z7_ATTRIB_NO_VECTOR \ +Byte *Z7_BRANCH_CONV(name)(Byte *p, SizeT size, UInt32 pc, int encoding) + +#define Z7_BRANCH_FUNC_IMP(name, m, encoding) \ +Z7_NO_INLINE \ +Z7_ATTRIB_NO_VECTOR \ +Byte *m(name)(Byte *data, SizeT size, UInt32 pc) \ + { return Z7_BRANCH_CONV(name)(data, size, pc, encoding); } \ + +#ifdef Z7_EXTRACT_ONLY +#define Z7_BRANCH_FUNCS_IMP(name) \ + Z7_BRANCH_FUNC_IMP(name, Z7_BRANCH_CONV_DEC_2, 0) +#else +#define Z7_BRANCH_FUNCS_IMP(name) \ + Z7_BRANCH_FUNC_IMP(name, Z7_BRANCH_CONV_DEC_2, 0) \ + Z7_BRANCH_FUNC_IMP(name, Z7_BRANCH_CONV_ENC_2, 1) +#endif + +#if defined(__clang__) +#define BR_EXTERNAL_FOR +#define BR_NEXT_ITERATION continue; +#else +#define BR_EXTERNAL_FOR for (;;) +#define BR_NEXT_ITERATION break; +#endif + +#if defined(__clang__) && (__clang_major__ >= 8) \ + || defined(__GNUC__) && (__GNUC__ >= 1000) \ + // GCC is not good for __builtin_expect() here + /* || defined(_MSC_VER) && (_MSC_VER >= 1920) */ + // #define Z7_unlikely [[unlikely]] + // #define Z7_LIKELY(x) (__builtin_expect((x), 1)) + #define Z7_UNLIKELY(x) (__builtin_expect((x), 0)) + // #define Z7_likely [[likely]] +#else + // #define Z7_LIKELY(x) (x) + #define Z7_UNLIKELY(x) (x) + // #define Z7_likely +#endif + + +Z7_BRANCH_FUNC_MAIN(BranchConv_ARM64) +{ + // Byte *p = data; + const Byte *lim; + const UInt32 flag = (UInt32)1 << (24 - 4); + const UInt32 mask = ((UInt32)1 << 24) - (flag << 1); + size &= ~(SizeT)3; + // if (size == 0) return p; + lim = p + size; + BR_PC_INIT + pc -= 4; // because (p) will point to next instruction + + BR_EXTERNAL_FOR + { + // Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + for (;;) + { + UInt32 v; + if Z7_UNLIKELY(p == lim) + return p; + v = GetUi32a(p); + p += 4; + if Z7_UNLIKELY(((v - 0x94000000) & 0xfc000000) == 0) + { + UInt32 c = BR_PC_GET >> 2; + BR_CONVERT_VAL(v, c) + v &= 0x03ffffff; + v |= 0x94000000; + SetUi32a(p - 4, v) + BR_NEXT_ITERATION + } + // v = rotlFixed(v, 8); v += (flag << 8) - 0x90; if Z7_UNLIKELY((v & ((mask << 8) + 0x9f)) == 0) + v -= 0x90000000; if Z7_UNLIKELY((v & 0x9f000000) == 0) + { + UInt32 z, c; + // v = rotrFixed(v, 8); + v += flag; if Z7_UNLIKELY(v & mask) continue; + z = (v & 0xffffffe0) | (v >> 26); + c = (BR_PC_GET >> (12 - 3)) & ~(UInt32)7; + BR_CONVERT_VAL(z, c) + v &= 0x1f; + v |= 0x90000000; + v |= z << 26; + v |= 0x00ffffe0 & ((z & (((flag << 1) - 1))) - flag); + SetUi32a(p - 4, v) + } + } + } +} +Z7_BRANCH_FUNCS_IMP(BranchConv_ARM64) + + +Z7_BRANCH_FUNC_MAIN(BranchConv_ARM) +{ + // Byte *p = data; + const Byte *lim; + size &= ~(SizeT)3; + lim = p + size; + BR_PC_INIT + /* in ARM: branch offset is relative to the +2 instructions from current instruction. + (p) will point to next instruction */ + pc += 8 - 4; + + for (;;) + { + for (;;) + { + if Z7_UNLIKELY(p >= lim) { return p; } p += 4; if Z7_UNLIKELY(p[-1] == 0xeb) break; + if Z7_UNLIKELY(p >= lim) { return p; } p += 4; if Z7_UNLIKELY(p[-1] == 0xeb) break; + } + { + UInt32 v = GetUi32a(p - 4); + UInt32 c = BR_PC_GET >> 2; + BR_CONVERT_VAL(v, c) + v &= 0x00ffffff; + v |= 0xeb000000; + SetUi32a(p - 4, v) + } + } +} +Z7_BRANCH_FUNCS_IMP(BranchConv_ARM) + + +Z7_BRANCH_FUNC_MAIN(BranchConv_PPC) +{ + // Byte *p = data; + const Byte *lim; + size &= ~(SizeT)3; + lim = p + size; + BR_PC_INIT + pc -= 4; // because (p) will point to next instruction + + for (;;) + { + UInt32 v; + for (;;) + { + if Z7_UNLIKELY(p == lim) + return p; + // v = GetBe32a(p); + v = *(UInt32 *)(void *)p; + p += 4; + // if ((v & 0xfc000003) == 0x48000001) break; + // if ((p[-4] & 0xFC) == 0x48 && (p[-1] & 3) == 1) break; + if Z7_UNLIKELY( + ((v - Z7_CONV_BE_TO_NATIVE_CONST32(0x48000001)) + & Z7_CONV_BE_TO_NATIVE_CONST32(0xfc000003)) == 0) break; + } + { + v = Z7_CONV_NATIVE_TO_BE_32(v); + { + UInt32 c = BR_PC_GET; + BR_CONVERT_VAL(v, c) + } + v &= 0x03ffffff; + v |= 0x48000000; + SetBe32a(p - 4, v) + } + } +} +Z7_BRANCH_FUNCS_IMP(BranchConv_PPC) + + +#ifdef Z7_CPU_FAST_ROTATE_SUPPORTED +#define BR_SPARC_USE_ROTATE +#endif + +Z7_BRANCH_FUNC_MAIN(BranchConv_SPARC) +{ + // Byte *p = data; + const Byte *lim; + const UInt32 flag = (UInt32)1 << 22; + size &= ~(SizeT)3; + lim = p + size; + BR_PC_INIT + pc -= 4; // because (p) will point to next instruction + for (;;) + { + UInt32 v; + for (;;) + { + if Z7_UNLIKELY(p == lim) + return p; + /* // the code without GetBe32a(): + { const UInt32 v = GetUi16a(p) & 0xc0ff; p += 4; if (v == 0x40 || v == 0xc07f) break; } + */ + v = GetBe32a(p); + p += 4; + #ifdef BR_SPARC_USE_ROTATE + v = rotlFixed(v, 2); + v += (flag << 2) - 1; + if Z7_UNLIKELY((v & (3 - (flag << 3))) == 0) + #else + v += (UInt32)5 << 29; + v ^= (UInt32)7 << 29; + v += flag; + if Z7_UNLIKELY((v & (0 - (flag << 1))) == 0) + #endif + break; + } + { + // UInt32 v = GetBe32a(p - 4); + #ifndef BR_SPARC_USE_ROTATE + v <<= 2; + #endif + { + UInt32 c = BR_PC_GET; + BR_CONVERT_VAL(v, c) + } + v &= (flag << 3) - 1; + #ifdef BR_SPARC_USE_ROTATE + v -= (flag << 2) - 1; + v = rotrFixed(v, 2); + #else + v -= (flag << 2); + v >>= 2; + v |= (UInt32)1 << 30; + #endif + SetBe32a(p - 4, v) + } + } +} +Z7_BRANCH_FUNCS_IMP(BranchConv_SPARC) + + +Z7_BRANCH_FUNC_MAIN(BranchConv_ARMT) +{ + // Byte *p = data; + Byte *lim; + size &= ~(SizeT)1; + // if (size == 0) return p; + if (size <= 2) return p; + size -= 2; + lim = p + size; + BR_PC_INIT + /* in ARM: branch offset is relative to the +2 instructions from current instruction. + (p) will point to the +2 instructions from current instruction */ + // pc += 4 - 4; + // if (encoding) pc -= 0xf800 << 1; else pc += 0xf800 << 1; + // #define ARMT_TAIL_PROC { goto armt_tail; } + #define ARMT_TAIL_PROC { return p; } + + do + { + /* in MSVC 32-bit x86 compilers: + UInt32 version : it loads value from memory with movzx + Byte version : it loads value to 8-bit register (AL/CL) + movzx version is slightly faster in some cpus + */ + unsigned b1; + // Byte / unsigned + b1 = p[1]; + // optimized version to reduce one (p >= lim) check: + // unsigned a1 = p[1]; b1 = p[3]; p += 2; if Z7_LIKELY((b1 & (a1 ^ 8)) < 0xf8) + for (;;) + { + unsigned b3; // Byte / UInt32 + /* (Byte)(b3) normalization can use low byte computations in MSVC. + It gives smaller code, and no loss of speed in some compilers/cpus. + But new MSVC 32-bit x86 compilers use more slow load + from memory to low byte register in that case. + So we try to use full 32-bit computations for faster code. + */ + // if (p >= lim) { ARMT_TAIL_PROC } b3 = b1 + 8; b1 = p[3]; p += 2; if ((b3 & b1) >= 0xf8) break; + if Z7_UNLIKELY(p >= lim) { ARMT_TAIL_PROC } b3 = p[3]; p += 2; if Z7_UNLIKELY((b3 & (b1 ^ 8)) >= 0xf8) break; + if Z7_UNLIKELY(p >= lim) { ARMT_TAIL_PROC } b1 = p[3]; p += 2; if Z7_UNLIKELY((b1 & (b3 ^ 8)) >= 0xf8) break; + } + { + /* we can adjust pc for (0xf800) to rid of (& 0x7FF) operation. + But gcc/clang for arm64 can use bfi instruction for full code here */ + UInt32 v = + ((UInt32)GetUi16a(p - 2) << 11) | + ((UInt32)GetUi16a(p) & 0x7FF); + /* + UInt32 v = + ((UInt32)p[1 - 2] << 19) + + (((UInt32)p[1] & 0x7) << 8) + + (((UInt32)p[-2] << 11)) + + (p[0]); + */ + p += 2; + { + UInt32 c = BR_PC_GET >> 1; + BR_CONVERT_VAL(v, c) + } + SetUi16a(p - 4, (UInt16)(((v >> 11) & 0x7ff) | 0xf000)) + SetUi16a(p - 2, (UInt16)(v | 0xf800)) + /* + p[-4] = (Byte)(v >> 11); + p[-3] = (Byte)(0xf0 | ((v >> 19) & 0x7)); + p[-2] = (Byte)v; + p[-1] = (Byte)(0xf8 | (v >> 8)); + */ + } + } + while (p < lim); + return p; + // armt_tail: + // if ((Byte)((lim[1] & 0xf8)) != 0xf0) { lim += 2; } return lim; + // return (Byte *)(lim + ((Byte)((lim[1] ^ 0xf0) & 0xf8) == 0 ? 0 : 2)); + // return (Byte *)(lim + (((lim[1] ^ ~0xfu) & ~7u) == 0 ? 0 : 2)); + // return (Byte *)(lim + 2 - (((((unsigned)lim[1] ^ 8) + 8) >> 7) & 2)); +} +Z7_BRANCH_FUNCS_IMP(BranchConv_ARMT) + + +// #define BR_IA64_NO_INLINE + +Z7_BRANCH_FUNC_MAIN(BranchConv_IA64) +{ + // Byte *p = data; + const Byte *lim; + size &= ~(SizeT)15; + lim = p + size; + pc -= 1 << 4; + pc >>= 4 - 1; + // pc -= 1 << 1; + + for (;;) + { + unsigned m; + for (;;) + { + if Z7_UNLIKELY(p == lim) + return p; + m = (unsigned)((UInt32)0x334b0000 >> (*p & 0x1e)); + p += 16; + pc += 1 << 1; + if (m &= 3) + break; + } + { + p += (ptrdiff_t)m * 5 - 20; // negative value is expected here. + do + { + const UInt32 t = + #if defined(MY_CPU_X86_OR_AMD64) + // we use 32-bit load here to reduce code size on x86: + GetUi32(p); + #else + GetUi16(p); + #endif + UInt32 z = GetUi32(p + 1) >> m; + p += 5; + if (((t >> m) & (0x70 << 1)) == 0 + && ((z - (0x5000000 << 1)) & (0xf000000 << 1)) == 0) + { + UInt32 v = (UInt32)((0x8fffff << 1) | 1) & z; + z ^= v; + #ifdef BR_IA64_NO_INLINE + v |= (v & ((UInt32)1 << (23 + 1))) >> 3; + { + UInt32 c = pc; + BR_CONVERT_VAL(v, c) + } + v &= (0x1fffff << 1) | 1; + #else + { + if (encoding) + { + // pc &= ~(0xc00000 << 1); // we just need to clear at least 2 bits + pc &= (0x1fffff << 1) | 1; + v += pc; + } + else + { + // pc |= 0xc00000 << 1; // we need to set at least 2 bits + pc |= ~(UInt32)((0x1fffff << 1) | 1); + v -= pc; + } + } + v &= ~(UInt32)(0x600000 << 1); + #endif + v += (0x700000 << 1); + v &= (0x8fffff << 1) | 1; + z |= v; + z <<= m; + SetUi32(p + 1 - 5, z) + } + m++; + } + while (m &= 3); // while (m < 4); + } + } +} +Z7_BRANCH_FUNCS_IMP(BranchConv_IA64) + + +#define BR_CONVERT_VAL_ENC(v) v += BR_PC_GET; +#define BR_CONVERT_VAL_DEC(v) v -= BR_PC_GET; + +#if 1 && defined(MY_CPU_LE_UNALIGN) + #define RISCV_USE_UNALIGNED_LOAD +#endif + +#ifdef RISCV_USE_UNALIGNED_LOAD + #define RISCV_GET_UI32(p) GetUi32(p) + #define RISCV_SET_UI32(p, v) { SetUi32(p, v) } +#else + #define RISCV_GET_UI32(p) \ + ((UInt32)GetUi16a(p) + \ + ((UInt32)GetUi16a((p) + 2) << 16)) + #define RISCV_SET_UI32(p, v) { \ + SetUi16a(p, (UInt16)(v)) \ + SetUi16a((p) + 2, (UInt16)(v >> 16)) } +#endif + +#if 1 && defined(MY_CPU_LE) + #define RISCV_USE_16BIT_LOAD +#endif + +#ifdef RISCV_USE_16BIT_LOAD + #define RISCV_LOAD_VAL(p) GetUi16a(p) +#else + #define RISCV_LOAD_VAL(p) (*(p)) +#endif + +#define RISCV_INSTR_SIZE 2 +#define RISCV_STEP_1 (4 + RISCV_INSTR_SIZE) +#define RISCV_STEP_2 4 +#define RISCV_REG_VAL (2 << 7) +#define RISCV_CMD_VAL 3 +#if 1 + // for code size optimization: + #define RISCV_DELTA_7F 0x7f +#else + #define RISCV_DELTA_7F 0 +#endif + +#define RISCV_CHECK_1(v, b) \ + (((((b) - RISCV_CMD_VAL) ^ ((v) << 8)) & (0xf8000 + RISCV_CMD_VAL)) == 0) + +#if 1 + #define RISCV_CHECK_2(v, r) \ + ((((v) - ((RISCV_CMD_VAL << 12) | RISCV_REG_VAL | 8)) \ + << 18) \ + < ((r) & 0x1d)) +#else + // this branch gives larger code, because + // compilers generate larger code for big constants. + #define RISCV_CHECK_2(v, r) \ + ((((v) - ((RISCV_CMD_VAL << 12) | RISCV_REG_VAL)) \ + & ((RISCV_CMD_VAL << 12) | RISCV_REG_VAL)) \ + < ((r) & 0x1d)) +#endif + + +#define RISCV_SCAN_LOOP \ + Byte *lim; \ + size &= ~(SizeT)(RISCV_INSTR_SIZE - 1); \ + if (size <= 6) return p; \ + size -= 6; \ + lim = p + size; \ + BR_PC_INIT \ + for (;;) \ + { \ + UInt32 a, v; \ + /* Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE */ \ + for (;;) \ + { \ + if Z7_UNLIKELY(p >= lim) { return p; } \ + a = (RISCV_LOAD_VAL(p) ^ 0x10u) + 1; \ + if ((a & 0x77) == 0) break; \ + a = (RISCV_LOAD_VAL(p + RISCV_INSTR_SIZE) ^ 0x10u) + 1; \ + p += RISCV_INSTR_SIZE * 2; \ + if ((a & 0x77) == 0) \ + { \ + p -= RISCV_INSTR_SIZE; \ + if Z7_UNLIKELY(p >= lim) { return p; } \ + break; \ + } \ + } +// (xx6f ^ 10) + 1 = xx7f + 1 = xx80 : JAL +// (xxef ^ 10) + 1 = xxff + 1 = xx00 + 100 : JAL +// (xx17 ^ 10) + 1 = xx07 + 1 = xx08 : AUIPC +// (xx97 ^ 10) + 1 = xx87 + 1 = xx88 : AUIPC + +Byte * Z7_BRANCH_CONV_ENC(RISCV)(Byte *p, SizeT size, UInt32 pc) +{ + RISCV_SCAN_LOOP + v = a; + a = RISCV_GET_UI32(p); +#ifndef RISCV_USE_16BIT_LOAD + v += (UInt32)p[1] << 8; +#endif + + if ((v & 8) == 0) // JAL + { + if ((v - (0x100 /* - RISCV_DELTA_7F */)) & 0xd80) + { + p += RISCV_INSTR_SIZE; + continue; + } + { + v = ((a & 1u << 31) >> 11) + | ((a & 0x3ff << 21) >> 20) + | ((a & 1 << 20) >> 9) + | (a & 0xff << 12); + BR_CONVERT_VAL_ENC(v) + // ((v & 1) == 0) + // v: bits [1 : 20] contain offset bits +#if 0 && defined(RISCV_USE_UNALIGNED_LOAD) + a &= 0xfff; + a |= ((UInt32)(v << 23)) + | ((UInt32)(v << 7) & ((UInt32)0xff << 16)) + | ((UInt32)(v >> 5) & ((UInt32)0xf0 << 8)); + RISCV_SET_UI32(p, a) +#else // aligned +#if 0 + SetUi16a(p, (UInt16)(((v >> 5) & 0xf000) | (a & 0xfff))) +#else + p[1] = (Byte)(((v >> 13) & 0xf0) | ((a >> 8) & 0xf)); +#endif + +#if 1 && defined(Z7_CPU_FAST_BSWAP_SUPPORTED) && defined(MY_CPU_LE) + v <<= 15; + v = Z7_BSWAP32(v); + SetUi16a(p + 2, (UInt16)v) +#else + p[2] = (Byte)(v >> 9); + p[3] = (Byte)(v >> 1); +#endif +#endif // aligned + } + p += 4; + continue; + } // JAL + + { + // AUIPC + if (v & 0xe80) // (not x0) and (not x2) + { + const UInt32 b = RISCV_GET_UI32(p + 4); + if (RISCV_CHECK_1(v, b)) + { + { + const UInt32 temp = (b << 12) | (0x17 + RISCV_REG_VAL); + RISCV_SET_UI32(p, temp) + } + a &= 0xfffff000; + { +#if 1 + const int t = -1 >> 1; + if (t != -1) + a += (b >> 20) - ((b >> 19) & 0x1000); // arithmetic right shift emulation + else +#endif + a += (UInt32)((Int32)b >> 20); // arithmetic right shift (sign-extension). + } + BR_CONVERT_VAL_ENC(a) +#if 1 && defined(Z7_CPU_FAST_BSWAP_SUPPORTED) && defined(MY_CPU_LE) + a = Z7_BSWAP32(a); + RISCV_SET_UI32(p + 4, a) +#else + SetBe32(p + 4, a) +#endif + p += 8; + } + else + p += RISCV_STEP_1; + } + else + { + UInt32 r = a >> 27; + if (RISCV_CHECK_2(v, r)) + { + v = RISCV_GET_UI32(p + 4); + r = (r << 7) + 0x17 + (v & 0xfffff000); + a = (a >> 12) | (v << 20); + RISCV_SET_UI32(p, r) + RISCV_SET_UI32(p + 4, a) + p += 8; + } + else + p += RISCV_STEP_2; + } + } + } // for +} + + +Byte * Z7_BRANCH_CONV_DEC(RISCV)(Byte *p, SizeT size, UInt32 pc) +{ + RISCV_SCAN_LOOP +#ifdef RISCV_USE_16BIT_LOAD + if ((a & 8) == 0) + { +#else + v = a; + a += (UInt32)p[1] << 8; + if ((v & 8) == 0) + { +#endif + // JAL + a -= 0x100 - RISCV_DELTA_7F; + if (a & 0xd80) + { + p += RISCV_INSTR_SIZE; + continue; + } + { + const UInt32 a_old = (a + (0xef - RISCV_DELTA_7F)) & 0xfff; +#if 0 // unaligned + a = GetUi32(p); + v = (UInt32)(a >> 23) & ((UInt32)0xff << 1) + | (UInt32)(a >> 7) & ((UInt32)0xff << 9) +#elif 1 && defined(Z7_CPU_FAST_BSWAP_SUPPORTED) && defined(MY_CPU_LE) + v = GetUi16a(p + 2); + v = Z7_BSWAP32(v) >> 15 +#else + v = (UInt32)p[3] << 1 + | (UInt32)p[2] << 9 +#endif + | (UInt32)((a & 0xf000) << 5); + BR_CONVERT_VAL_DEC(v) + a = a_old + | (v << 11 & 1u << 31) + | (v << 20 & 0x3ff << 21) + | (v << 9 & 1 << 20) + | (v & 0xff << 12); + RISCV_SET_UI32(p, a) + } + p += 4; + continue; + } // JAL + + { + // AUIPC + v = a; +#if 1 && defined(RISCV_USE_UNALIGNED_LOAD) + a = GetUi32(p); +#else + a |= (UInt32)GetUi16a(p + 2) << 16; +#endif + if ((v & 0xe80) == 0) // x0/x2 + { + const UInt32 r = a >> 27; + if (RISCV_CHECK_2(v, r)) + { + UInt32 b; +#if 1 && defined(Z7_CPU_FAST_BSWAP_SUPPORTED) && defined(MY_CPU_LE) + b = RISCV_GET_UI32(p + 4); + b = Z7_BSWAP32(b); +#else + b = GetBe32(p + 4); +#endif + v = a >> 12; + BR_CONVERT_VAL_DEC(b) + a = (r << 7) + 0x17; + a += (b + 0x800) & 0xfffff000; + v |= b << 20; + RISCV_SET_UI32(p, a) + RISCV_SET_UI32(p + 4, v) + p += 8; + } + else + p += RISCV_STEP_2; + } + else + { + const UInt32 b = RISCV_GET_UI32(p + 4); + if (!RISCV_CHECK_1(v, b)) + p += RISCV_STEP_1; + else + { + v = (a & 0xfffff000) | (b >> 20); + a = (b << 12) | (0x17 + RISCV_REG_VAL); + RISCV_SET_UI32(p, a) + RISCV_SET_UI32(p + 4, v) + p += 8; + } + } + } + } // for +} diff --git a/common/LZMA/SDK/C/Bra.h b/common/LZMA/SDK/C/Bra.h index 5748c1c..b47112c 100644 --- a/common/LZMA/SDK/C/Bra.h +++ b/common/LZMA/SDK/C/Bra.h @@ -1,68 +1,105 @@ /* Bra.h -- Branch converters for executables -2009-02-07 : Igor Pavlov : Public domain */ +2024-01-20 : Igor Pavlov : Public domain */ -#ifndef __BRA_H -#define __BRA_H +#ifndef ZIP7_INC_BRA_H +#define ZIP7_INC_BRA_H -#include "Types.h" +#include "7zTypes.h" -#ifdef __cplusplus -extern "C" { -#endif +EXTERN_C_BEGIN + +/* #define PPC BAD_PPC_11 // for debug */ + +#define Z7_BRANCH_CONV_DEC_2(name) z7_ ## name ## _Dec +#define Z7_BRANCH_CONV_ENC_2(name) z7_ ## name ## _Enc +#define Z7_BRANCH_CONV_DEC(name) Z7_BRANCH_CONV_DEC_2(BranchConv_ ## name) +#define Z7_BRANCH_CONV_ENC(name) Z7_BRANCH_CONV_ENC_2(BranchConv_ ## name) +#define Z7_BRANCH_CONV_ST_DEC(name) z7_BranchConvSt_ ## name ## _Dec +#define Z7_BRANCH_CONV_ST_ENC(name) z7_BranchConvSt_ ## name ## _Enc + +#define Z7_BRANCH_CONV_DECL(name) Byte * name(Byte *data, SizeT size, UInt32 pc) +#define Z7_BRANCH_CONV_ST_DECL(name) Byte * name(Byte *data, SizeT size, UInt32 pc, UInt32 *state) + +typedef Z7_BRANCH_CONV_DECL( (*z7_Func_BranchConv)); +typedef Z7_BRANCH_CONV_ST_DECL((*z7_Func_BranchConvSt)); + +#define Z7_BRANCH_CONV_ST_X86_STATE_INIT_VAL 0 +Z7_BRANCH_CONV_ST_DECL (Z7_BRANCH_CONV_ST_DEC(X86)); +Z7_BRANCH_CONV_ST_DECL (Z7_BRANCH_CONV_ST_ENC(X86)); + +#define Z7_BRANCH_FUNCS_DECL(name) \ +Z7_BRANCH_CONV_DECL (Z7_BRANCH_CONV_DEC_2(name)); \ +Z7_BRANCH_CONV_DECL (Z7_BRANCH_CONV_ENC_2(name)); + +Z7_BRANCH_FUNCS_DECL (BranchConv_ARM64) +Z7_BRANCH_FUNCS_DECL (BranchConv_ARM) +Z7_BRANCH_FUNCS_DECL (BranchConv_ARMT) +Z7_BRANCH_FUNCS_DECL (BranchConv_PPC) +Z7_BRANCH_FUNCS_DECL (BranchConv_SPARC) +Z7_BRANCH_FUNCS_DECL (BranchConv_IA64) +Z7_BRANCH_FUNCS_DECL (BranchConv_RISCV) /* -These functions convert relative addresses to absolute addresses -in CALL instructions to increase the compression ratio. - - In: - data - data buffer - size - size of data - ip - current virtual Instruction Pinter (IP) value - state - state variable for x86 converter - encoding - 0 (for decoding), 1 (for encoding) - - Out: - state - state variable for x86 converter +These functions convert data that contain CPU instructions. +Each such function converts relative addresses to absolute addresses in some +branch instructions: CALL (in all converters) and JUMP (X86 converter only). +Such conversion allows to increase compression ratio, if we compress that data. - Returns: - The number of processed bytes. If you call these functions with multiple calls, - you must start next call with first byte after block of processed bytes. +There are 2 types of converters: + Byte * Conv_RISC (Byte *data, SizeT size, UInt32 pc); + Byte * ConvSt_X86(Byte *data, SizeT size, UInt32 pc, UInt32 *state); +Each Converter supports 2 versions: one for encoding +and one for decoding (_Enc/_Dec postfixes in function name). + +In params: + data : data buffer + size : size of data + pc : current virtual Program Counter (Instruction Pointer) value +In/Out param: + state : pointer to state variable (for X86 converter only) + +Return: + The pointer to position in (data) buffer after last byte that was processed. + If the caller calls converter again, it must call it starting with that position. + But the caller is allowed to move data in buffer. So pointer to + current processed position also will be changed for next call. + Also the caller must increase internal (pc) value for next call. +Each converter has some characteristics: Endian, Alignment, LookAhead. Type Endian Alignment LookAhead - x86 little 1 4 + X86 little 1 4 ARMT little 2 2 + RISCV little 2 6 ARM little 4 0 + ARM64 little 4 0 PPC big 4 0 SPARC big 4 0 IA64 little 16 0 - size must be >= Alignment + LookAhead, if it's not last block. - If (size < Alignment + LookAhead), converter returns 0. + (data) must be aligned for (Alignment). + processed size can be calculated as: + SizeT processed = Conv(data, size, pc) - data; + if (processed == 0) + it means that converter needs more data for processing. + If (size < Alignment + LookAhead) + then (processed == 0) is allowed. - Example: - - UInt32 ip = 0; - for () - { - ; size must be >= Alignment + LookAhead, if it's not last block - SizeT processed = Convert(data, size, ip, 1); - data += processed; - size -= processed; - ip += processed; - } +Example code for conversion in loop: + UInt32 pc = 0; + size = 0; + for (;;) + { + size += Load_more_input_data(data + size); + SizeT processed = Conv(data, size, pc) - data; + if (processed == 0 && no_more_input_data_after_size) + break; // we stop convert loop + data += processed; + size -= processed; + pc += processed; + } */ -#define x86_Convert_Init(state) { state = 0; } -SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding); -SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); -SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); -SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); -SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); -SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); - -#ifdef __cplusplus -} -#endif +EXTERN_C_END #endif diff --git a/common/LZMA/SDK/C/Bra86.c b/common/LZMA/SDK/C/Bra86.c index 1ee0e70..d81f392 100644 --- a/common/LZMA/SDK/C/Bra86.c +++ b/common/LZMA/SDK/C/Bra86.c @@ -1,85 +1,187 @@ -/* Bra86.c -- Converter for x86 code (BCJ) -2008-10-04 : Igor Pavlov : Public domain */ +/* Bra86.c -- Branch converter for X86 code (BCJ) +2023-04-02 : Igor Pavlov : Public domain */ + +#include "Precomp.h" #include "Bra.h" +#include "CpuArch.h" -#define Test86MSByte(b) ((b) == 0 || (b) == 0xFF) -const Byte kMaskToAllowedStatus[8] = {1, 1, 1, 0, 1, 0, 0, 0}; -const Byte kMaskToBitNumber[8] = {0, 1, 2, 2, 3, 3, 3, 3}; +#if defined(MY_CPU_SIZEOF_POINTER) \ + && ( MY_CPU_SIZEOF_POINTER == 4 \ + || MY_CPU_SIZEOF_POINTER == 8) + #define BR_CONV_USE_OPT_PC_PTR +#endif -SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding) +#ifdef BR_CONV_USE_OPT_PC_PTR +#define BR_PC_INIT pc -= (UInt32)(SizeT)p; // (MY_uintptr_t) +#define BR_PC_GET (pc + (UInt32)(SizeT)p) +#else +#define BR_PC_INIT pc += (UInt32)size; +#define BR_PC_GET (pc - (UInt32)(SizeT)(lim - p)) +// #define BR_PC_INIT +// #define BR_PC_GET (pc + (UInt32)(SizeT)(p - data)) +#endif + +#define BR_CONVERT_VAL(v, c) if (encoding) v += c; else v -= c; +// #define BR_CONVERT_VAL(v, c) if (!encoding) c = (UInt32)0 - c; v += c; + +#define Z7_BRANCH_CONV_ST(name) z7_BranchConvSt_ ## name + +#define BR86_NEED_CONV_FOR_MS_BYTE(b) ((((b) + 1) & 0xfe) == 0) + +#ifdef MY_CPU_LE_UNALIGN + #define BR86_PREPARE_BCJ_SCAN const UInt32 v = GetUi32(p) ^ 0xe8e8e8e8; + #define BR86_IS_BCJ_BYTE(n) ((v & ((UInt32)0xfe << (n) * 8)) == 0) +#else + #define BR86_PREPARE_BCJ_SCAN + // bad for MSVC X86 (partial write to byte reg): + #define BR86_IS_BCJ_BYTE(n) ((p[n - 4] & 0xfe) == 0xe8) + // bad for old MSVC (partial write to byte reg): + // #define BR86_IS_BCJ_BYTE(n) (((*p ^ 0xe8) & 0xfe) == 0) +#endif + +static +Z7_FORCE_INLINE +Z7_ATTRIB_NO_VECTOR +Byte *Z7_BRANCH_CONV_ST(X86)(Byte *p, SizeT size, UInt32 pc, UInt32 *state, int encoding) { - SizeT bufferPos = 0, prevPosT; - UInt32 prevMask = *state & 0x7; if (size < 5) - return 0; - ip += 5; - prevPosT = (SizeT)0 - 1; + return p; + { + // Byte *p = data; + const Byte *lim = p + size - 4; + unsigned mask = (unsigned)*state; // & 7; +#ifdef BR_CONV_USE_OPT_PC_PTR + /* if BR_CONV_USE_OPT_PC_PTR is defined: we need to adjust (pc) for (+4), + because call/jump offset is relative to the next instruction. + if BR_CONV_USE_OPT_PC_PTR is not defined : we don't need to adjust (pc) for (+4), + because BR_PC_GET uses (pc - (lim - p)), and lim was adjusted for (-4) before. + */ + pc += 4; +#endif + BR_PC_INIT + goto start; - for (;;) + for (;; mask |= 4) { - Byte *p = data + bufferPos; - Byte *limit = data + size - 4; - for (; p < limit; p++) - if ((*p & 0xFE) == 0xE8) - break; - bufferPos = (SizeT)(p - data); - if (p >= limit) - break; - prevPosT = bufferPos - prevPosT; - if (prevPosT > 3) - prevMask = 0; - else + // cont: mask |= 4; + start: + if (p >= lim) + goto fin; { - prevMask = (prevMask << ((int)prevPosT - 1)) & 0x7; - if (prevMask != 0) - { - Byte b = p[4 - kMaskToBitNumber[prevMask]]; - if (!kMaskToAllowedStatus[prevMask] || Test86MSByte(b)) - { - prevPosT = bufferPos; - prevMask = ((prevMask << 1) & 0x7) | 1; - bufferPos++; - continue; - } - } + BR86_PREPARE_BCJ_SCAN + p += 4; + if (BR86_IS_BCJ_BYTE(0)) { goto m0; } mask >>= 1; + if (BR86_IS_BCJ_BYTE(1)) { goto m1; } mask >>= 1; + if (BR86_IS_BCJ_BYTE(2)) { goto m2; } mask = 0; + if (BR86_IS_BCJ_BYTE(3)) { goto a3; } } - prevPosT = bufferPos; + goto main_loop; - if (Test86MSByte(p[4])) + m0: p--; + m1: p--; + m2: p--; + if (mask == 0) + goto a3; + if (p > lim) + goto fin_p; + + // if (((0x17u >> mask) & 1) == 0) + if (mask > 4 || mask == 3) { - UInt32 src = ((UInt32)p[4] << 24) | ((UInt32)p[3] << 16) | ((UInt32)p[2] << 8) | ((UInt32)p[1]); - UInt32 dest; - for (;;) - { - Byte b; - int index; - if (encoding) - dest = (ip + (UInt32)bufferPos) + src; - else - dest = src - (ip + (UInt32)bufferPos); - if (prevMask == 0) - break; - index = kMaskToBitNumber[prevMask] * 8; - b = (Byte)(dest >> (24 - index)); - if (!Test86MSByte(b)) - break; - src = dest ^ ((1 << (32 - index)) - 1); - } - p[4] = (Byte)(~(((dest >> 24) & 1) - 1)); - p[3] = (Byte)(dest >> 16); - p[2] = (Byte)(dest >> 8); - p[1] = (Byte)dest; - bufferPos += 5; + mask >>= 1; + continue; // goto cont; } - else + mask >>= 1; + if (BR86_NEED_CONV_FOR_MS_BYTE(p[mask])) + continue; // goto cont; + // if (!BR86_NEED_CONV_FOR_MS_BYTE(p[3])) continue; // goto cont; { - prevMask = ((prevMask << 1) & 0x7) | 1; - bufferPos++; + UInt32 v = GetUi32(p); + UInt32 c; + v += (1 << 24); if (v & 0xfe000000) continue; // goto cont; + c = BR_PC_GET; + BR_CONVERT_VAL(v, c) + { + mask <<= 3; + if (BR86_NEED_CONV_FOR_MS_BYTE(v >> mask)) + { + v ^= (((UInt32)0x100 << mask) - 1); + #ifdef MY_CPU_X86 + // for X86 : we can recalculate (c) to reduce register pressure + c = BR_PC_GET; + #endif + BR_CONVERT_VAL(v, c) + } + mask = 0; + } + // v = (v & ((1 << 24) - 1)) - (v & (1 << 24)); + v &= (1 << 25) - 1; v -= (1 << 24); + SetUi32(p, v) + p += 4; + goto main_loop; + } + + main_loop: + if (p >= lim) + goto fin; + for (;;) + { + BR86_PREPARE_BCJ_SCAN + p += 4; + if (BR86_IS_BCJ_BYTE(0)) { goto a0; } + if (BR86_IS_BCJ_BYTE(1)) { goto a1; } + if (BR86_IS_BCJ_BYTE(2)) { goto a2; } + if (BR86_IS_BCJ_BYTE(3)) { goto a3; } + if (p >= lim) + goto fin; + } + + a0: p--; + a1: p--; + a2: p--; + a3: + if (p > lim) + goto fin_p; + // if (!BR86_NEED_CONV_FOR_MS_BYTE(p[3])) continue; // goto cont; + { + UInt32 v = GetUi32(p); + UInt32 c; + v += (1 << 24); if (v & 0xfe000000) continue; // goto cont; + c = BR_PC_GET; + BR_CONVERT_VAL(v, c) + // v = (v & ((1 << 24) - 1)) - (v & (1 << 24)); + v &= (1 << 25) - 1; v -= (1 << 24); + SetUi32(p, v) + p += 4; + goto main_loop; } } - prevPosT = bufferPos - prevPosT; - *state = ((prevPosT > 3) ? 0 : ((prevMask << ((int)prevPosT - 1)) & 0x7)); - return bufferPos; + +fin_p: + p--; +fin: + // the following processing for tail is optional and can be commented + /* + lim += 4; + for (; p < lim; p++, mask >>= 1) + if ((*p & 0xfe) == 0xe8) + break; + */ + *state = (UInt32)mask; + return p; + } } + + +#define Z7_BRANCH_CONV_ST_FUNC_IMP(name, m, encoding) \ +Z7_NO_INLINE \ +Z7_ATTRIB_NO_VECTOR \ +Byte *m(name)(Byte *data, SizeT size, UInt32 pc, UInt32 *state) \ + { return Z7_BRANCH_CONV_ST(name)(data, size, pc, state, encoding); } + +Z7_BRANCH_CONV_ST_FUNC_IMP(X86, Z7_BRANCH_CONV_ST_DEC, 0) +#ifndef Z7_EXTRACT_ONLY +Z7_BRANCH_CONV_ST_FUNC_IMP(X86, Z7_BRANCH_CONV_ST_ENC, 1) +#endif diff --git a/common/LZMA/SDK/C/Compiler.h b/common/LZMA/SDK/C/Compiler.h new file mode 100644 index 0000000..2a9c2b7 --- /dev/null +++ b/common/LZMA/SDK/C/Compiler.h @@ -0,0 +1,236 @@ +/* Compiler.h : Compiler specific defines and pragmas +2024-01-22 : Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_COMPILER_H +#define ZIP7_INC_COMPILER_H + +#if defined(__clang__) +# define Z7_CLANG_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) +#endif +#if defined(__clang__) && defined(__apple_build_version__) +# define Z7_APPLE_CLANG_VERSION Z7_CLANG_VERSION +#elif defined(__clang__) +# define Z7_LLVM_CLANG_VERSION Z7_CLANG_VERSION +#elif defined(__GNUC__) +# define Z7_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) +#endif + +#ifdef _MSC_VER +#if !defined(__clang__) && !defined(__GNUC__) +#define Z7_MSC_VER_ORIGINAL _MSC_VER +#endif +#endif + +#if defined(__MINGW32__) || defined(__MINGW64__) +#define Z7_MINGW +#endif + +#if defined(__LCC__) && (defined(__MCST__) || defined(__e2k__)) +#define Z7_MCST_LCC +#define Z7_MCST_LCC_VERSION (__LCC__ * 100 + __LCC_MINOR__) +#endif + +/* +#if defined(__AVX2__) \ + || defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION >= 40900) \ + || defined(Z7_APPLE_CLANG_VERSION) && (Z7_APPLE_CLANG_VERSION >= 40600) \ + || defined(Z7_LLVM_CLANG_VERSION) && (Z7_LLVM_CLANG_VERSION >= 30100) \ + || defined(Z7_MSC_VER_ORIGINAL) && (Z7_MSC_VER_ORIGINAL >= 1800) \ + || defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1400) + #define Z7_COMPILER_AVX2_SUPPORTED + #endif +#endif +*/ + +// #pragma GCC diagnostic ignored "-Wunknown-pragmas" + +#ifdef __clang__ +// padding size of '' with 4 bytes to alignment boundary +#pragma GCC diagnostic ignored "-Wpadded" + +#if defined(Z7_LLVM_CLANG_VERSION) && (__clang_major__ == 13) \ + && defined(__FreeBSD__) +// freebsd: +#pragma GCC diagnostic ignored "-Wexcess-padding" +#endif + +#if __clang_major__ >= 16 +#pragma GCC diagnostic ignored "-Wunsafe-buffer-usage" +#endif + +#if __clang_major__ == 13 +#if defined(__SIZEOF_POINTER__) && (__SIZEOF_POINTER__ == 16) +// cheri +#pragma GCC diagnostic ignored "-Wcapability-to-integer-cast" +#endif +#endif + +#if __clang_major__ == 13 + // for + #pragma GCC diagnostic ignored "-Wreserved-identifier" +#endif + +#endif // __clang__ + +#if defined(_WIN32) && defined(__clang__) && __clang_major__ >= 16 +// #pragma GCC diagnostic ignored "-Wcast-function-type-strict" +#define Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION \ + _Pragma("GCC diagnostic ignored \"-Wcast-function-type-strict\"") +#else +#define Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION +#endif + +typedef void (*Z7_void_Function)(void); +#if defined(__clang__) || defined(__GNUC__) +#define Z7_CAST_FUNC_C (Z7_void_Function) +#elif defined(_MSC_VER) && _MSC_VER > 1920 +#define Z7_CAST_FUNC_C (void *) +// #pragma warning(disable : 4191) // 'type cast': unsafe conversion from 'FARPROC' to 'void (__cdecl *)()' +#else +#define Z7_CAST_FUNC_C +#endif +/* +#if (defined(__GNUC__) && (__GNUC__ >= 8)) || defined(__clang__) + // #pragma GCC diagnostic ignored "-Wcast-function-type" +#endif +*/ +#ifdef __GNUC__ +#if defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION >= 40000) && (Z7_GCC_VERSION < 70000) +#pragma GCC diagnostic ignored "-Wstrict-aliasing" +#endif +#endif + + +#ifdef _MSC_VER + + #ifdef UNDER_CE + #define RPC_NO_WINDOWS_H + /* #pragma warning(disable : 4115) // '_RPC_ASYNC_STATE' : named type definition in parentheses */ + #pragma warning(disable : 4201) // nonstandard extension used : nameless struct/union + #pragma warning(disable : 4214) // nonstandard extension used : bit field types other than int + #endif + +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif + +// == 1200 : -O1 : for __forceinline +// >= 1900 : -O1 : for printf +#pragma warning(disable : 4710) // function not inlined + +#if _MSC_VER < 1900 +// winnt.h: 'Int64ShllMod32' +#pragma warning(disable : 4514) // unreferenced inline function has been removed +#endif + +#if _MSC_VER < 1300 +// #pragma warning(disable : 4702) // unreachable code +// Bra.c : -O1: +#pragma warning(disable : 4714) // function marked as __forceinline not inlined +#endif + +/* +#if _MSC_VER > 1400 && _MSC_VER <= 1900 +// strcat: This function or variable may be unsafe +// sysinfoapi.h: kit10: GetVersion was declared deprecated +#pragma warning(disable : 4996) +#endif +*/ + +#if _MSC_VER > 1200 +// -Wall warnings + +#pragma warning(disable : 4711) // function selected for automatic inline expansion +#pragma warning(disable : 4820) // '2' bytes padding added after data member + +#if _MSC_VER >= 1400 && _MSC_VER < 1920 +// 1400: string.h: _DBG_MEMCPY_INLINE_ +// 1600 - 191x : smmintrin.h __cplusplus' +// is not defined as a preprocessor macro, replacing with '0' for '#if/#elif' +#pragma warning(disable : 4668) + +// 1400 - 1600 : WinDef.h : 'FARPROC' : +// 1900 - 191x : immintrin.h: _readfsbase_u32 +// no function prototype given : converting '()' to '(void)' +#pragma warning(disable : 4255) +#endif + +#if _MSC_VER >= 1914 +// Compiler will insert Spectre mitigation for memory load if /Qspectre switch specified +#pragma warning(disable : 5045) +#endif + +#endif // _MSC_VER > 1200 +#endif // _MSC_VER + + +#if defined(__clang__) && (__clang_major__ >= 4) + #define Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE \ + _Pragma("clang loop unroll(disable)") \ + _Pragma("clang loop vectorize(disable)") + #define Z7_ATTRIB_NO_VECTORIZE +#elif defined(__GNUC__) && (__GNUC__ >= 5) \ + && (!defined(Z7_MCST_LCC_VERSION) || (Z7_MCST_LCC_VERSION >= 12610)) + #define Z7_ATTRIB_NO_VECTORIZE __attribute__((optimize("no-tree-vectorize"))) + // __attribute__((optimize("no-unroll-loops"))); + #define Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE +#elif defined(_MSC_VER) && (_MSC_VER >= 1920) + #define Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE \ + _Pragma("loop( no_vector )") + #define Z7_ATTRIB_NO_VECTORIZE +#else + #define Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + #define Z7_ATTRIB_NO_VECTORIZE +#endif + +#if defined(MY_CPU_X86_OR_AMD64) && ( \ + defined(__clang__) && (__clang_major__ >= 4) \ + || defined(__GNUC__) && (__GNUC__ >= 5)) + #define Z7_ATTRIB_NO_SSE __attribute__((__target__("no-sse"))) +#else + #define Z7_ATTRIB_NO_SSE +#endif + +#define Z7_ATTRIB_NO_VECTOR \ + Z7_ATTRIB_NO_VECTORIZE \ + Z7_ATTRIB_NO_SSE + + +#if defined(__clang__) && (__clang_major__ >= 8) \ + || defined(__GNUC__) && (__GNUC__ >= 1000) \ + /* || defined(_MSC_VER) && (_MSC_VER >= 1920) */ + // GCC is not good for __builtin_expect() + #define Z7_LIKELY(x) (__builtin_expect((x), 1)) + #define Z7_UNLIKELY(x) (__builtin_expect((x), 0)) + // #define Z7_unlikely [[unlikely]] + // #define Z7_likely [[likely]] +#else + #define Z7_LIKELY(x) (x) + #define Z7_UNLIKELY(x) (x) + // #define Z7_likely +#endif + + +#if (defined(Z7_CLANG_VERSION) && (Z7_CLANG_VERSION >= 30600)) + +#if (Z7_CLANG_VERSION < 130000) +#define Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wreserved-id-macro\"") +#else +#define Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wreserved-macro-identifier\"") +#endif + +#define Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER \ + _Pragma("GCC diagnostic pop") +#else +#define Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER +#define Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER +#endif + +#define UNUSED_VAR(x) (void)x; +/* #define UNUSED_VAR(x) x=x; */ + +#endif diff --git a/common/LZMA/SDK/C/CpuArch.c b/common/LZMA/SDK/C/CpuArch.c new file mode 100644 index 0000000..6e02551 --- /dev/null +++ b/common/LZMA/SDK/C/CpuArch.c @@ -0,0 +1,970 @@ +/* CpuArch.c -- CPU specific code +Igor Pavlov : Public domain */ + +#include "Precomp.h" + +// #include + +#include "CpuArch.h" + +#ifdef MY_CPU_X86_OR_AMD64 + +#undef NEED_CHECK_FOR_CPUID +#if !defined(MY_CPU_AMD64) +#define NEED_CHECK_FOR_CPUID +#endif + +/* + cpuid instruction supports (subFunction) parameter in ECX, + that is used only with some specific (function) parameter values. + most functions use only (subFunction==0). +*/ +/* + __cpuid(): MSVC and GCC/CLANG use same function/macro name + but parameters are different. + We use MSVC __cpuid() parameters style for our z7_x86_cpuid() function. +*/ + +#if defined(__GNUC__) /* && (__GNUC__ >= 10) */ \ + || defined(__clang__) /* && (__clang_major__ >= 10) */ + +/* there was some CLANG/GCC compilers that have issues with + rbx(ebx) handling in asm blocks in -fPIC mode (__PIC__ is defined). + compiler's contains the macro __cpuid() that is similar to our code. + The history of __cpuid() changes in CLANG/GCC: + GCC: + 2007: it preserved ebx for (__PIC__ && __i386__) + 2013: it preserved rbx and ebx for __PIC__ + 2014: it doesn't preserves rbx and ebx anymore + we suppose that (__GNUC__ >= 5) fixed that __PIC__ ebx/rbx problem. + CLANG: + 2014+: it preserves rbx, but only for 64-bit code. No __PIC__ check. + Why CLANG cares about 64-bit mode only, and doesn't care about ebx (in 32-bit)? + Do we need __PIC__ test for CLANG or we must care about rbx even if + __PIC__ is not defined? +*/ + +#define ASM_LN "\n" + +#if defined(MY_CPU_AMD64) && defined(__PIC__) \ + && ((defined (__GNUC__) && (__GNUC__ < 5)) || defined(__clang__)) + + /* "=&r" selects free register. It can select even rbx, if that register is free. + "=&D" for (RDI) also works, but the code can be larger with "=&D" + "2"(subFun) : 2 is (zero-based) index in the output constraint list "=c" (ECX). */ + +#define x86_cpuid_MACRO_2(p, func, subFunc) { \ + __asm__ __volatile__ ( \ + ASM_LN "mov %%rbx, %q1" \ + ASM_LN "cpuid" \ + ASM_LN "xchg %%rbx, %q1" \ + : "=a" ((p)[0]), "=&r" ((p)[1]), "=c" ((p)[2]), "=d" ((p)[3]) : "0" (func), "2"(subFunc)); } + +#elif defined(MY_CPU_X86) && defined(__PIC__) \ + && ((defined (__GNUC__) && (__GNUC__ < 5)) || defined(__clang__)) + +#define x86_cpuid_MACRO_2(p, func, subFunc) { \ + __asm__ __volatile__ ( \ + ASM_LN "mov %%ebx, %k1" \ + ASM_LN "cpuid" \ + ASM_LN "xchg %%ebx, %k1" \ + : "=a" ((p)[0]), "=&r" ((p)[1]), "=c" ((p)[2]), "=d" ((p)[3]) : "0" (func), "2"(subFunc)); } + +#else + +#define x86_cpuid_MACRO_2(p, func, subFunc) { \ + __asm__ __volatile__ ( \ + ASM_LN "cpuid" \ + : "=a" ((p)[0]), "=b" ((p)[1]), "=c" ((p)[2]), "=d" ((p)[3]) : "0" (func), "2"(subFunc)); } + +#endif + +#define x86_cpuid_MACRO(p, func) x86_cpuid_MACRO_2(p, func, 0) + +void Z7_FASTCALL z7_x86_cpuid(UInt32 p[4], UInt32 func) +{ + x86_cpuid_MACRO(p, func) +} + +static +void Z7_FASTCALL z7_x86_cpuid_subFunc(UInt32 p[4], UInt32 func, UInt32 subFunc) +{ + x86_cpuid_MACRO_2(p, func, subFunc) +} + + +Z7_NO_INLINE +UInt32 Z7_FASTCALL z7_x86_cpuid_GetMaxFunc(void) +{ + #if defined(NEED_CHECK_FOR_CPUID) + #define EFALGS_CPUID_BIT 21 + UInt32 a; + __asm__ __volatile__ ( + ASM_LN "pushf" + ASM_LN "pushf" + ASM_LN "pop %0" + // ASM_LN "movl %0, %1" + // ASM_LN "xorl $0x200000, %0" + ASM_LN "btc %1, %0" + ASM_LN "push %0" + ASM_LN "popf" + ASM_LN "pushf" + ASM_LN "pop %0" + ASM_LN "xorl (%%esp), %0" + + ASM_LN "popf" + ASM_LN + : "=&r" (a) // "=a" + : "i" (EFALGS_CPUID_BIT) + ); + if ((a & (1 << EFALGS_CPUID_BIT)) == 0) + return 0; + #endif + { + UInt32 p[4]; + x86_cpuid_MACRO(p, 0) + return p[0]; + } +} + +#undef ASM_LN + +#elif !defined(_MSC_VER) + +/* +// for gcc/clang and other: we can try to use __cpuid macro: +#include +void Z7_FASTCALL z7_x86_cpuid(UInt32 p[4], UInt32 func) +{ + __cpuid(func, p[0], p[1], p[2], p[3]); +} +UInt32 Z7_FASTCALL z7_x86_cpuid_GetMaxFunc(void) +{ + return (UInt32)__get_cpuid_max(0, NULL); +} +*/ +// for unsupported cpuid: +void Z7_FASTCALL z7_x86_cpuid(UInt32 p[4], UInt32 func) +{ + UNUSED_VAR(func) + p[0] = p[1] = p[2] = p[3] = 0; +} +UInt32 Z7_FASTCALL z7_x86_cpuid_GetMaxFunc(void) +{ + return 0; +} + +#else // _MSC_VER + +#if !defined(MY_CPU_AMD64) + +UInt32 __declspec(naked) Z7_FASTCALL z7_x86_cpuid_GetMaxFunc(void) +{ + #if defined(NEED_CHECK_FOR_CPUID) + #define EFALGS_CPUID_BIT 21 + __asm pushfd + __asm pushfd + /* + __asm pop eax + // __asm mov edx, eax + __asm btc eax, EFALGS_CPUID_BIT + __asm push eax + */ + __asm btc dword ptr [esp], EFALGS_CPUID_BIT + __asm popfd + __asm pushfd + __asm pop eax + // __asm xor eax, edx + __asm xor eax, [esp] + // __asm push edx + __asm popfd + __asm and eax, (1 shl EFALGS_CPUID_BIT) + __asm jz end_func + #endif + __asm push ebx + __asm xor eax, eax // func + __asm xor ecx, ecx // subFunction (optional) for (func == 0) + __asm cpuid + __asm pop ebx + #if defined(NEED_CHECK_FOR_CPUID) + end_func: + #endif + __asm ret 0 +} + +void __declspec(naked) Z7_FASTCALL z7_x86_cpuid(UInt32 p[4], UInt32 func) +{ + UNUSED_VAR(p) + UNUSED_VAR(func) + __asm push ebx + __asm push edi + __asm mov edi, ecx // p + __asm mov eax, edx // func + __asm xor ecx, ecx // subfunction (optional) for (func == 0) + __asm cpuid + __asm mov [edi ], eax + __asm mov [edi + 4], ebx + __asm mov [edi + 8], ecx + __asm mov [edi + 12], edx + __asm pop edi + __asm pop ebx + __asm ret 0 +} + +static +void __declspec(naked) Z7_FASTCALL z7_x86_cpuid_subFunc(UInt32 p[4], UInt32 func, UInt32 subFunc) +{ + UNUSED_VAR(p) + UNUSED_VAR(func) + UNUSED_VAR(subFunc) + __asm push ebx + __asm push edi + __asm mov edi, ecx // p + __asm mov eax, edx // func + __asm mov ecx, [esp + 12] // subFunc + __asm cpuid + __asm mov [edi ], eax + __asm mov [edi + 4], ebx + __asm mov [edi + 8], ecx + __asm mov [edi + 12], edx + __asm pop edi + __asm pop ebx + __asm ret 4 +} + +#else // MY_CPU_AMD64 + + #if _MSC_VER >= 1600 + #include + #define MY_cpuidex __cpuidex + +static +void Z7_FASTCALL z7_x86_cpuid_subFunc(UInt32 p[4], UInt32 func, UInt32 subFunc) +{ + __cpuidex((int *)p, func, subFunc); +} + + #else +/* + __cpuid (func == (0 or 7)) requires subfunction number in ECX. + MSDN: The __cpuid intrinsic clears the ECX register before calling the cpuid instruction. + __cpuid() in new MSVC clears ECX. + __cpuid() in old MSVC (14.00) x64 doesn't clear ECX + We still can use __cpuid for low (func) values that don't require ECX, + but __cpuid() in old MSVC will be incorrect for some func values: (func == 7). + So here we use the hack for old MSVC to send (subFunction) in ECX register to cpuid instruction, + where ECX value is first parameter for FASTCALL / NO_INLINE func. + So the caller of MY_cpuidex_HACK() sets ECX as subFunction, and + old MSVC for __cpuid() doesn't change ECX and cpuid instruction gets (subFunction) value. + +DON'T remove Z7_NO_INLINE and Z7_FASTCALL for MY_cpuidex_HACK(): !!! +*/ +static +Z7_NO_INLINE void Z7_FASTCALL MY_cpuidex_HACK(Int32 subFunction, Int32 func, Int32 *CPUInfo) +{ + UNUSED_VAR(subFunction) + __cpuid(CPUInfo, func); +} + #define MY_cpuidex(info, func, func2) MY_cpuidex_HACK(func2, func, info) + #pragma message("======== MY_cpuidex_HACK WAS USED ========") +static +void Z7_FASTCALL z7_x86_cpuid_subFunc(UInt32 p[4], UInt32 func, UInt32 subFunc) +{ + MY_cpuidex_HACK(subFunc, func, (Int32 *)p); +} + #endif // _MSC_VER >= 1600 + +#if !defined(MY_CPU_AMD64) +/* inlining for __cpuid() in MSVC x86 (32-bit) produces big ineffective code, + so we disable inlining here */ +Z7_NO_INLINE +#endif +void Z7_FASTCALL z7_x86_cpuid(UInt32 p[4], UInt32 func) +{ + MY_cpuidex((Int32 *)p, (Int32)func, 0); +} + +Z7_NO_INLINE +UInt32 Z7_FASTCALL z7_x86_cpuid_GetMaxFunc(void) +{ + Int32 a[4]; + MY_cpuidex(a, 0, 0); + return a[0]; +} + +#endif // MY_CPU_AMD64 +#endif // _MSC_VER + +#if defined(NEED_CHECK_FOR_CPUID) +#define CHECK_CPUID_IS_SUPPORTED { if (z7_x86_cpuid_GetMaxFunc() == 0) return 0; } +#else +#define CHECK_CPUID_IS_SUPPORTED +#endif +#undef NEED_CHECK_FOR_CPUID + + +static +BoolInt x86cpuid_Func_1(UInt32 *p) +{ + CHECK_CPUID_IS_SUPPORTED + z7_x86_cpuid(p, 1); + return True; +} + +/* +static const UInt32 kVendors[][1] = +{ + { 0x756E6547 }, // , 0x49656E69, 0x6C65746E }, + { 0x68747541 }, // , 0x69746E65, 0x444D4163 }, + { 0x746E6543 } // , 0x48727561, 0x736C7561 } +}; +*/ + +/* +typedef struct +{ + UInt32 maxFunc; + UInt32 vendor[3]; + UInt32 ver; + UInt32 b; + UInt32 c; + UInt32 d; +} Cx86cpuid; + +enum +{ + CPU_FIRM_INTEL, + CPU_FIRM_AMD, + CPU_FIRM_VIA +}; +int x86cpuid_GetFirm(const Cx86cpuid *p); +#define x86cpuid_ver_GetFamily(ver) (((ver >> 16) & 0xff0) | ((ver >> 8) & 0xf)) +#define x86cpuid_ver_GetModel(ver) (((ver >> 12) & 0xf0) | ((ver >> 4) & 0xf)) +#define x86cpuid_ver_GetStepping(ver) (ver & 0xf) + +int x86cpuid_GetFirm(const Cx86cpuid *p) +{ + unsigned i; + for (i = 0; i < sizeof(kVendors) / sizeof(kVendors[0]); i++) + { + const UInt32 *v = kVendors[i]; + if (v[0] == p->vendor[0] + // && v[1] == p->vendor[1] + // && v[2] == p->vendor[2] + ) + return (int)i; + } + return -1; +} + +BoolInt CPU_Is_InOrder() +{ + Cx86cpuid p; + UInt32 family, model; + if (!x86cpuid_CheckAndRead(&p)) + return True; + + family = x86cpuid_ver_GetFamily(p.ver); + model = x86cpuid_ver_GetModel(p.ver); + + switch (x86cpuid_GetFirm(&p)) + { + case CPU_FIRM_INTEL: return (family < 6 || (family == 6 && ( + // In-Order Atom CPU + model == 0x1C // 45 nm, N4xx, D4xx, N5xx, D5xx, 230, 330 + || model == 0x26 // 45 nm, Z6xx + || model == 0x27 // 32 nm, Z2460 + || model == 0x35 // 32 nm, Z2760 + || model == 0x36 // 32 nm, N2xxx, D2xxx + ))); + case CPU_FIRM_AMD: return (family < 5 || (family == 5 && (model < 6 || model == 0xA))); + case CPU_FIRM_VIA: return (family < 6 || (family == 6 && model < 0xF)); + } + return False; // v23 : unknown processors are not In-Order +} +*/ + +#ifdef _WIN32 +#include "7zWindows.h" +#endif + +#if !defined(MY_CPU_AMD64) && defined(_WIN32) + +/* for legacy SSE ia32: there is no user-space cpu instruction to check + that OS supports SSE register storing/restoring on context switches. + So we need some OS-specific function to check that it's safe to use SSE registers. +*/ + +Z7_FORCE_INLINE +static BoolInt CPU_Sys_Is_SSE_Supported(void) +{ +#ifdef _MSC_VER + #pragma warning(push) + #pragma warning(disable : 4996) // `GetVersion': was declared deprecated +#endif + /* low byte is major version of Windows + We suppose that any Windows version since + Windows2000 (major == 5) supports SSE registers */ + return (Byte)GetVersion() >= 5; +#if defined(_MSC_VER) + #pragma warning(pop) +#endif +} +#define CHECK_SYS_SSE_SUPPORT if (!CPU_Sys_Is_SSE_Supported()) return False; +#else +#define CHECK_SYS_SSE_SUPPORT +#endif + + +#if !defined(MY_CPU_AMD64) + +BoolInt CPU_IsSupported_CMOV(void) +{ + UInt32 a[4]; + if (!x86cpuid_Func_1(&a[0])) + return 0; + return (BoolInt)(a[3] >> 15) & 1; +} + +BoolInt CPU_IsSupported_SSE(void) +{ + UInt32 a[4]; + CHECK_SYS_SSE_SUPPORT + if (!x86cpuid_Func_1(&a[0])) + return 0; + return (BoolInt)(a[3] >> 25) & 1; +} + +BoolInt CPU_IsSupported_SSE2(void) +{ + UInt32 a[4]; + CHECK_SYS_SSE_SUPPORT + if (!x86cpuid_Func_1(&a[0])) + return 0; + return (BoolInt)(a[3] >> 26) & 1; +} + +#endif + + +static UInt32 x86cpuid_Func_1_ECX(void) +{ + UInt32 a[4]; + CHECK_SYS_SSE_SUPPORT + if (!x86cpuid_Func_1(&a[0])) + return 0; + return a[2]; +} + +BoolInt CPU_IsSupported_AES(void) +{ + return (BoolInt)(x86cpuid_Func_1_ECX() >> 25) & 1; +} + +BoolInt CPU_IsSupported_SSSE3(void) +{ + return (BoolInt)(x86cpuid_Func_1_ECX() >> 9) & 1; +} + +BoolInt CPU_IsSupported_SSE41(void) +{ + return (BoolInt)(x86cpuid_Func_1_ECX() >> 19) & 1; +} + +BoolInt CPU_IsSupported_SHA(void) +{ + CHECK_SYS_SSE_SUPPORT + + if (z7_x86_cpuid_GetMaxFunc() < 7) + return False; + { + UInt32 d[4]; + z7_x86_cpuid(d, 7); + return (BoolInt)(d[1] >> 29) & 1; + } +} + + +BoolInt CPU_IsSupported_SHA512(void) +{ + if (!CPU_IsSupported_AVX2()) return False; // maybe CPU_IsSupported_AVX() is enough here + + if (z7_x86_cpuid_GetMaxFunc() < 7) + return False; + { + UInt32 d[4]; + z7_x86_cpuid_subFunc(d, 7, 0); + if (d[0] < 1) // d[0] - is max supported subleaf value + return False; + z7_x86_cpuid_subFunc(d, 7, 1); + return (BoolInt)(d[0]) & 1; + } +} + +/* +MSVC: _xgetbv() intrinsic is available since VS2010SP1. + MSVC also defines (_XCR_XFEATURE_ENABLED_MASK) macro in + that we can use or check. + For any 32-bit x86 we can use asm code in MSVC, + but MSVC asm code is huge after compilation. + So _xgetbv() is better + +ICC: _xgetbv() intrinsic is available (in what version of ICC?) + ICC defines (__GNUC___) and it supports gnu assembler + also ICC supports MASM style code with -use-msasm switch. + but ICC doesn't support __attribute__((__target__)) + +GCC/CLANG 9: + _xgetbv() is macro that works via __builtin_ia32_xgetbv() + and we need __attribute__((__target__("xsave")). + But with __target__("xsave") the function will be not + inlined to function that has no __target__("xsave") attribute. + If we want _xgetbv() call inlining, then we should use asm version + instead of calling _xgetbv(). + Note:intrinsic is broke before GCC 8.2: + https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85684 +*/ + +#if defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1100) \ + || defined(_MSC_VER) && (_MSC_VER >= 1600) && (_MSC_FULL_VER >= 160040219) \ + || defined(__GNUC__) && (__GNUC__ >= 9) \ + || defined(__clang__) && (__clang_major__ >= 9) +// we define ATTRIB_XGETBV, if we want to use predefined _xgetbv() from compiler +#if defined(__INTEL_COMPILER) +#define ATTRIB_XGETBV +#elif defined(__GNUC__) || defined(__clang__) +// we don't define ATTRIB_XGETBV here, because asm version is better for inlining. +// #define ATTRIB_XGETBV __attribute__((__target__("xsave"))) +#else +#define ATTRIB_XGETBV +#endif +#endif + +#if defined(ATTRIB_XGETBV) +#include +#endif + + +// XFEATURE_ENABLED_MASK/XCR0 +#define MY_XCR_XFEATURE_ENABLED_MASK 0 + +#if defined(ATTRIB_XGETBV) +ATTRIB_XGETBV +#endif +static UInt64 x86_xgetbv_0(UInt32 num) +{ +#if defined(ATTRIB_XGETBV) + { + return + #if (defined(_MSC_VER)) + _xgetbv(num); + #else + __builtin_ia32_xgetbv( + #if !defined(__clang__) + (int) + #endif + num); + #endif + } + +#elif defined(__GNUC__) || defined(__clang__) || defined(__SUNPRO_CC) + + UInt32 a, d; + #if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) + __asm__ + ( + "xgetbv" + : "=a"(a), "=d"(d) : "c"(num) : "cc" + ); + #else // is old gcc + __asm__ + ( + ".byte 0x0f, 0x01, 0xd0" "\n\t" + : "=a"(a), "=d"(d) : "c"(num) : "cc" + ); + #endif + return ((UInt64)d << 32) | a; + // return a; + +#elif defined(_MSC_VER) && !defined(MY_CPU_AMD64) + + UInt32 a, d; + __asm { + push eax + push edx + push ecx + mov ecx, num; + // xor ecx, ecx // = MY_XCR_XFEATURE_ENABLED_MASK + _emit 0x0f + _emit 0x01 + _emit 0xd0 + mov a, eax + mov d, edx + pop ecx + pop edx + pop eax + } + return ((UInt64)d << 32) | a; + // return a; + +#else // it's unknown compiler + // #error "Need xgetbv function" + UNUSED_VAR(num) + // for MSVC-X64 we could call external function from external file. + /* Actually we had checked OSXSAVE/AVX in cpuid before. + So it's expected that OS supports at least AVX and below. */ + // if (num != MY_XCR_XFEATURE_ENABLED_MASK) return 0; // if not XCR0 + return + // (1 << 0) | // x87 + (1 << 1) // SSE + | (1 << 2); // AVX + +#endif +} + +#ifdef _WIN32 +/* + Windows versions do not know about new ISA extensions that + can be introduced. But we still can use new extensions, + even if Windows doesn't report about supporting them, + But we can use new extensions, only if Windows knows about new ISA extension + that changes the number or size of registers: SSE, AVX/XSAVE, AVX512 + So it's enough to check + MY_PF_AVX_INSTRUCTIONS_AVAILABLE + instead of + MY_PF_AVX2_INSTRUCTIONS_AVAILABLE +*/ +#define MY_PF_XSAVE_ENABLED 17 +// #define MY_PF_SSSE3_INSTRUCTIONS_AVAILABLE 36 +// #define MY_PF_SSE4_1_INSTRUCTIONS_AVAILABLE 37 +// #define MY_PF_SSE4_2_INSTRUCTIONS_AVAILABLE 38 +// #define MY_PF_AVX_INSTRUCTIONS_AVAILABLE 39 +// #define MY_PF_AVX2_INSTRUCTIONS_AVAILABLE 40 +// #define MY_PF_AVX512F_INSTRUCTIONS_AVAILABLE 41 +#endif + +BoolInt CPU_IsSupported_AVX(void) +{ + #ifdef _WIN32 + if (!IsProcessorFeaturePresent(MY_PF_XSAVE_ENABLED)) + return False; + /* PF_AVX_INSTRUCTIONS_AVAILABLE probably is supported starting from + some latest Win10 revisions. But we need AVX in older Windows also. + So we don't use the following check: */ + /* + if (!IsProcessorFeaturePresent(MY_PF_AVX_INSTRUCTIONS_AVAILABLE)) + return False; + */ + #endif + + /* + OS must use new special XSAVE/XRSTOR instructions to save + AVX registers when it required for context switching. + At OS statring: + OS sets CR4.OSXSAVE flag to signal the processor that OS supports the XSAVE extensions. + Also OS sets bitmask in XCR0 register that defines what + registers will be processed by XSAVE instruction: + XCR0.SSE[bit 0] - x87 registers and state + XCR0.SSE[bit 1] - SSE registers and state + XCR0.AVX[bit 2] - AVX registers and state + CR4.OSXSAVE is reflected to CPUID.1:ECX.OSXSAVE[bit 27]. + So we can read that bit in user-space. + XCR0 is available for reading in user-space by new XGETBV instruction. + */ + { + const UInt32 c = x86cpuid_Func_1_ECX(); + if (0 == (1 + & (c >> 28) // AVX instructions are supported by hardware + & (c >> 27))) // OSXSAVE bit: XSAVE and related instructions are enabled by OS. + return False; + } + + /* also we can check + CPUID.1:ECX.XSAVE [bit 26] : that shows that + XSAVE, XRESTOR, XSETBV, XGETBV instructions are supported by hardware. + But that check is redundant, because if OSXSAVE bit is set, then XSAVE is also set */ + + /* If OS have enabled XSAVE extension instructions (OSXSAVE == 1), + in most cases we expect that OS also will support storing/restoring + for AVX and SSE states at least. + But to be ensure for that we call user-space instruction + XGETBV(0) to get XCR0 value that contains bitmask that defines + what exact states(registers) OS have enabled for storing/restoring. + */ + + { + const UInt32 bm = (UInt32)x86_xgetbv_0(MY_XCR_XFEATURE_ENABLED_MASK); + // printf("\n=== XGetBV=0x%x\n", bm); + return 1 + & (BoolInt)(bm >> 1) // SSE state is supported (set by OS) for storing/restoring + & (BoolInt)(bm >> 2); // AVX state is supported (set by OS) for storing/restoring + } + // since Win7SP1: we can use GetEnabledXStateFeatures(); +} + + +BoolInt CPU_IsSupported_AVX2(void) +{ + if (!CPU_IsSupported_AVX()) + return False; + if (z7_x86_cpuid_GetMaxFunc() < 7) + return False; + { + UInt32 d[4]; + z7_x86_cpuid(d, 7); + // printf("\ncpuid(7): ebx=%8x ecx=%8x\n", d[1], d[2]); + return 1 + & (BoolInt)(d[1] >> 5); // avx2 + } +} + +#if 0 +BoolInt CPU_IsSupported_AVX512F_AVX512VL(void) +{ + if (!CPU_IsSupported_AVX()) + return False; + if (z7_x86_cpuid_GetMaxFunc() < 7) + return False; + { + UInt32 d[4]; + BoolInt v; + z7_x86_cpuid(d, 7); + // printf("\ncpuid(7): ebx=%8x ecx=%8x\n", d[1], d[2]); + v = 1 + & (BoolInt)(d[1] >> 16) // avx512f + & (BoolInt)(d[1] >> 31); // avx512vl + if (!v) + return False; + } + { + const UInt32 bm = (UInt32)x86_xgetbv_0(MY_XCR_XFEATURE_ENABLED_MASK); + // printf("\n=== XGetBV=0x%x\n", bm); + return 1 + & (BoolInt)(bm >> 5) // OPMASK + & (BoolInt)(bm >> 6) // ZMM upper 256-bit + & (BoolInt)(bm >> 7); // ZMM16 ... ZMM31 + } +} +#endif + +BoolInt CPU_IsSupported_VAES_AVX2(void) +{ + if (!CPU_IsSupported_AVX()) + return False; + if (z7_x86_cpuid_GetMaxFunc() < 7) + return False; + { + UInt32 d[4]; + z7_x86_cpuid(d, 7); + // printf("\ncpuid(7): ebx=%8x ecx=%8x\n", d[1], d[2]); + return 1 + & (BoolInt)(d[1] >> 5) // avx2 + // & (d[1] >> 31) // avx512vl + & (BoolInt)(d[2] >> 9); // vaes // VEX-256/EVEX + } +} + +BoolInt CPU_IsSupported_PageGB(void) +{ + CHECK_CPUID_IS_SUPPORTED + { + UInt32 d[4]; + z7_x86_cpuid(d, 0x80000000); + if (d[0] < 0x80000001) + return False; + z7_x86_cpuid(d, 0x80000001); + return (BoolInt)(d[3] >> 26) & 1; + } +} + + +#elif defined(MY_CPU_ARM_OR_ARM64) + +#ifdef _WIN32 + +#include "7zWindows.h" + +BoolInt CPU_IsSupported_CRC32(void) { return IsProcessorFeaturePresent(PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE) ? 1 : 0; } +BoolInt CPU_IsSupported_CRYPTO(void) { return IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE) ? 1 : 0; } +BoolInt CPU_IsSupported_NEON(void) { return IsProcessorFeaturePresent(PF_ARM_NEON_INSTRUCTIONS_AVAILABLE) ? 1 : 0; } + +#else + +#if defined(__APPLE__) + +/* +#include +#include +static void Print_sysctlbyname(const char *name) +{ + size_t bufSize = 256; + char buf[256]; + int res = sysctlbyname(name, &buf, &bufSize, NULL, 0); + { + int i; + printf("\nres = %d : %s : '%s' : bufSize = %d, numeric", res, name, buf, (unsigned)bufSize); + for (i = 0; i < 20; i++) + printf(" %2x", (unsigned)(Byte)buf[i]); + + } +} +*/ +/* + Print_sysctlbyname("hw.pagesize"); + Print_sysctlbyname("machdep.cpu.brand_string"); +*/ + +static BoolInt z7_sysctlbyname_Get_BoolInt(const char *name) +{ + UInt32 val = 0; + if (z7_sysctlbyname_Get_UInt32(name, &val) == 0 && val == 1) + return 1; + return 0; +} + +BoolInt CPU_IsSupported_CRC32(void) +{ + return z7_sysctlbyname_Get_BoolInt("hw.optional.armv8_crc32"); +} + +BoolInt CPU_IsSupported_NEON(void) +{ + return z7_sysctlbyname_Get_BoolInt("hw.optional.neon"); +} + +BoolInt CPU_IsSupported_SHA512(void) +{ + return z7_sysctlbyname_Get_BoolInt("hw.optional.armv8_2_sha512"); +} + +/* +BoolInt CPU_IsSupported_SHA3(void) +{ + return z7_sysctlbyname_Get_BoolInt("hw.optional.armv8_2_sha3"); +} +*/ + +#ifdef MY_CPU_ARM64 +#define APPLE_CRYPTO_SUPPORT_VAL 1 +#else +#define APPLE_CRYPTO_SUPPORT_VAL 0 +#endif + +BoolInt CPU_IsSupported_SHA1(void) { return APPLE_CRYPTO_SUPPORT_VAL; } +BoolInt CPU_IsSupported_SHA2(void) { return APPLE_CRYPTO_SUPPORT_VAL; } +BoolInt CPU_IsSupported_AES (void) { return APPLE_CRYPTO_SUPPORT_VAL; } + + +#else // __APPLE__ + +#if defined(__GLIBC__) && (__GLIBC__ * 100 + __GLIBC_MINOR__ >= 216) + #define Z7_GETAUXV_AVAILABLE +#else +// #pragma message("=== is not NEW GLIBC === ") + #if defined __has_include + #if __has_include () +// #pragma message("=== sys/auxv.h is avail=== ") + #define Z7_GETAUXV_AVAILABLE + #endif + #endif +#endif + +#ifdef Z7_GETAUXV_AVAILABLE +// #pragma message("=== Z7_GETAUXV_AVAILABLE === ") +#include +#define USE_HWCAP +#endif + +#ifdef USE_HWCAP + +#if defined(__FreeBSD__) +static unsigned long MY_getauxval(int aux) +{ + unsigned long val; + if (elf_aux_info(aux, &val, sizeof(val))) + return 0; + return val; +} +#else +#define MY_getauxval getauxval + #if defined __has_include + #if __has_include () +#include + #endif + #endif +#endif + + #define MY_HWCAP_CHECK_FUNC_2(name1, name2) \ + BoolInt CPU_IsSupported_ ## name1(void) { return (MY_getauxval(AT_HWCAP) & (HWCAP_ ## name2)); } + +#ifdef MY_CPU_ARM64 + #define MY_HWCAP_CHECK_FUNC(name) \ + MY_HWCAP_CHECK_FUNC_2(name, name) +#if 1 || defined(__ARM_NEON) + BoolInt CPU_IsSupported_NEON(void) { return True; } +#else + MY_HWCAP_CHECK_FUNC_2(NEON, ASIMD) +#endif +// MY_HWCAP_CHECK_FUNC (ASIMD) +#elif defined(MY_CPU_ARM) + #define MY_HWCAP_CHECK_FUNC(name) \ + BoolInt CPU_IsSupported_ ## name(void) { return (MY_getauxval(AT_HWCAP2) & (HWCAP2_ ## name)); } + MY_HWCAP_CHECK_FUNC_2(NEON, NEON) +#endif + +#else // USE_HWCAP + + #define MY_HWCAP_CHECK_FUNC(name) \ + BoolInt CPU_IsSupported_ ## name(void) { return 0; } +#if defined(__ARM_NEON) + BoolInt CPU_IsSupported_NEON(void) { return True; } +#else + MY_HWCAP_CHECK_FUNC(NEON) +#endif + +#endif // USE_HWCAP + +MY_HWCAP_CHECK_FUNC (CRC32) +MY_HWCAP_CHECK_FUNC (SHA1) +MY_HWCAP_CHECK_FUNC (SHA2) +MY_HWCAP_CHECK_FUNC (AES) +#ifdef MY_CPU_ARM64 +// supports HWCAP_SHA512 and HWCAP_SHA3 since 2017. +// we define them here, if they are not defined +#ifndef HWCAP_SHA3 +// #define HWCAP_SHA3 (1 << 17) +#endif +#ifndef HWCAP_SHA512 +// #pragma message("=== HWCAP_SHA512 define === ") +#define HWCAP_SHA512 (1 << 21) +#endif +MY_HWCAP_CHECK_FUNC (SHA512) +// MY_HWCAP_CHECK_FUNC (SHA3) +#endif + +#endif // __APPLE__ +#endif // _WIN32 + +#endif // MY_CPU_ARM_OR_ARM64 + + + +#ifdef __APPLE__ + +#include + +int z7_sysctlbyname_Get(const char *name, void *buf, size_t *bufSize) +{ + return sysctlbyname(name, buf, bufSize, NULL, 0); +} + +int z7_sysctlbyname_Get_UInt32(const char *name, UInt32 *val) +{ + size_t bufSize = sizeof(*val); + const int res = z7_sysctlbyname_Get(name, val, &bufSize); + if (res == 0 && bufSize != sizeof(*val)) + return EFAULT; + return res; +} + +#endif diff --git a/common/LZMA/SDK/C/CpuArch.h b/common/LZMA/SDK/C/CpuArch.h index 01930c7..a6297ea 100644 --- a/common/LZMA/SDK/C/CpuArch.h +++ b/common/LZMA/SDK/C/CpuArch.h @@ -1,77 +1,481 @@ /* CpuArch.h -- CPU specific code -2010-10-26: Igor Pavlov : Public domain */ +Igor Pavlov : Public domain */ -#ifndef __CPU_ARCH_H -#define __CPU_ARCH_H +#ifndef ZIP7_INC_CPU_ARCH_H +#define ZIP7_INC_CPU_ARCH_H -#include "Types.h" +#include "7zTypes.h" EXTERN_C_BEGIN /* MY_CPU_LE means that CPU is LITTLE ENDIAN. -If MY_CPU_LE is not defined, we don't know about that property of platform (it can be LITTLE ENDIAN). +MY_CPU_BE means that CPU is BIG ENDIAN. +If MY_CPU_LE and MY_CPU_BE are not defined, we don't know about ENDIANNESS of platform. MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned memory accesses. -If MY_CPU_LE_UNALIGN is not defined, we don't know about these properties of platform. + +MY_CPU_64BIT means that processor can work with 64-bit registers. + MY_CPU_64BIT can be used to select fast code branch + MY_CPU_64BIT doesn't mean that (sizeof(void *) == 8) */ -#if defined(_M_X64) || defined(_M_AMD64) || defined(__x86_64__) -#define MY_CPU_AMD64 +#if !defined(_M_ARM64EC) +#if defined(_M_X64) \ + || defined(_M_AMD64) \ + || defined(__x86_64__) \ + || defined(__AMD64__) \ + || defined(__amd64__) + #define MY_CPU_AMD64 + #ifdef __ILP32__ + #define MY_CPU_NAME "x32" + #define MY_CPU_SIZEOF_POINTER 4 + #else + #define MY_CPU_NAME "x64" + #define MY_CPU_SIZEOF_POINTER 8 + #endif + #define MY_CPU_64BIT +#endif #endif -#if defined(MY_CPU_AMD64) || defined(_M_IA64) -#define MY_CPU_64BIT + +#if defined(_M_IX86) \ + || defined(__i386__) + #define MY_CPU_X86 + #define MY_CPU_NAME "x86" + /* #define MY_CPU_32BIT */ + #define MY_CPU_SIZEOF_POINTER 4 #endif -#if defined(_M_IX86) || defined(__i386__) -#define MY_CPU_X86 + +#if defined(_M_ARM64) \ + || defined(_M_ARM64EC) \ + || defined(__AARCH64EL__) \ + || defined(__AARCH64EB__) \ + || defined(__aarch64__) + #define MY_CPU_ARM64 +#if defined(__ILP32__) \ + || defined(__SIZEOF_POINTER__) && (__SIZEOF_POINTER__ == 4) + #define MY_CPU_NAME "arm64-32" + #define MY_CPU_SIZEOF_POINTER 4 +#elif defined(__SIZEOF_POINTER__) && (__SIZEOF_POINTER__ == 16) + #define MY_CPU_NAME "arm64-128" + #define MY_CPU_SIZEOF_POINTER 16 +#else +#if defined(_M_ARM64EC) + #define MY_CPU_NAME "arm64ec" +#else + #define MY_CPU_NAME "arm64" #endif + #define MY_CPU_SIZEOF_POINTER 8 +#endif + #define MY_CPU_64BIT +#endif + + +#if defined(_M_ARM) \ + || defined(_M_ARM_NT) \ + || defined(_M_ARMT) \ + || defined(__arm__) \ + || defined(__thumb__) \ + || defined(__ARMEL__) \ + || defined(__ARMEB__) \ + || defined(__THUMBEL__) \ + || defined(__THUMBEB__) + #define MY_CPU_ARM + + #if defined(__thumb__) || defined(__THUMBEL__) || defined(_M_ARMT) + #define MY_CPU_ARMT + #define MY_CPU_NAME "armt" + #else + #define MY_CPU_ARM32 + #define MY_CPU_NAME "arm" + #endif + /* #define MY_CPU_32BIT */ + #define MY_CPU_SIZEOF_POINTER 4 +#endif + + +#if defined(_M_IA64) \ + || defined(__ia64__) + #define MY_CPU_IA64 + #define MY_CPU_NAME "ia64" + #define MY_CPU_64BIT +#endif + + +#if defined(__mips64) \ + || defined(__mips64__) \ + || (defined(__mips) && (__mips == 64 || __mips == 4 || __mips == 3)) + #define MY_CPU_NAME "mips64" + #define MY_CPU_64BIT +#elif defined(__mips__) + #define MY_CPU_NAME "mips" + /* #define MY_CPU_32BIT */ +#endif + + +#if defined(__ppc64__) \ + || defined(__powerpc64__) \ + || defined(__ppc__) \ + || defined(__powerpc__) \ + || defined(__PPC__) \ + || defined(_POWER) + +#define MY_CPU_PPC_OR_PPC64 + +#if defined(__ppc64__) \ + || defined(__powerpc64__) \ + || defined(_LP64) \ + || defined(__64BIT__) + #ifdef __ILP32__ + #define MY_CPU_NAME "ppc64-32" + #define MY_CPU_SIZEOF_POINTER 4 + #else + #define MY_CPU_NAME "ppc64" + #define MY_CPU_SIZEOF_POINTER 8 + #endif + #define MY_CPU_64BIT +#else + #define MY_CPU_NAME "ppc" + #define MY_CPU_SIZEOF_POINTER 4 + /* #define MY_CPU_32BIT */ +#endif +#endif + + +#if defined(__sparc__) \ + || defined(__sparc) + #define MY_CPU_SPARC + #if defined(__LP64__) \ + || defined(_LP64) \ + || defined(__SIZEOF_POINTER__) && (__SIZEOF_POINTER__ == 8) + #define MY_CPU_NAME "sparcv9" + #define MY_CPU_SIZEOF_POINTER 8 + #define MY_CPU_64BIT + #elif defined(__sparc_v9__) \ + || defined(__sparcv9) + #define MY_CPU_64BIT + #if defined(__SIZEOF_POINTER__) && (__SIZEOF_POINTER__ == 4) + #define MY_CPU_NAME "sparcv9-32" + #else + #define MY_CPU_NAME "sparcv9m" + #endif + #elif defined(__sparc_v8__) \ + || defined(__sparcv8) + #define MY_CPU_NAME "sparcv8" + #define MY_CPU_SIZEOF_POINTER 4 + #else + #define MY_CPU_NAME "sparc" + #endif +#endif + + +#if defined(__riscv) \ + || defined(__riscv__) + #define MY_CPU_RISCV + #if __riscv_xlen == 32 + #define MY_CPU_NAME "riscv32" + #elif __riscv_xlen == 64 + #define MY_CPU_NAME "riscv64" + #else + #define MY_CPU_NAME "riscv" + #endif +#endif + + +#if defined(__loongarch__) + #define MY_CPU_LOONGARCH + #if defined(__loongarch64) || defined(__loongarch_grlen) && (__loongarch_grlen == 64) + #define MY_CPU_64BIT + #endif + #if defined(__loongarch64) + #define MY_CPU_NAME "loongarch64" + #define MY_CPU_LOONGARCH64 + #else + #define MY_CPU_NAME "loongarch" + #endif +#endif + + +// #undef MY_CPU_NAME +// #undef MY_CPU_SIZEOF_POINTER +// #define __e2k__ +// #define __SIZEOF_POINTER__ 4 +#if defined(__e2k__) + #define MY_CPU_E2K + #if defined(__ILP32__) || defined(__SIZEOF_POINTER__) && (__SIZEOF_POINTER__ == 4) + #define MY_CPU_NAME "e2k-32" + #define MY_CPU_SIZEOF_POINTER 4 + #else + #define MY_CPU_NAME "e2k" + #if defined(__LP64__) || defined(__SIZEOF_POINTER__) && (__SIZEOF_POINTER__ == 8) + #define MY_CPU_SIZEOF_POINTER 8 + #endif + #endif + #define MY_CPU_64BIT +#endif + #if defined(MY_CPU_X86) || defined(MY_CPU_AMD64) #define MY_CPU_X86_OR_AMD64 #endif -#if defined(MY_CPU_X86) || defined(_M_ARM) -#define MY_CPU_32BIT +#if defined(MY_CPU_ARM) || defined(MY_CPU_ARM64) +#define MY_CPU_ARM_OR_ARM64 #endif -#if defined(_WIN32) && defined(_M_ARM) -#define MY_CPU_ARM_LE + +#ifdef _WIN32 + + #ifdef MY_CPU_ARM + #define MY_CPU_ARM_LE + #endif + + #ifdef MY_CPU_ARM64 + #define MY_CPU_ARM64_LE + #endif + + #ifdef _M_IA64 + #define MY_CPU_IA64_LE + #endif + #endif -#if defined(_WIN32) && defined(_M_IA64) -#define MY_CPU_IA64_LE + +#if defined(MY_CPU_X86_OR_AMD64) \ + || defined(MY_CPU_ARM_LE) \ + || defined(MY_CPU_ARM64_LE) \ + || defined(MY_CPU_IA64_LE) \ + || defined(_LITTLE_ENDIAN) \ + || defined(__LITTLE_ENDIAN__) \ + || defined(__ARMEL__) \ + || defined(__THUMBEL__) \ + || defined(__AARCH64EL__) \ + || defined(__MIPSEL__) \ + || defined(__MIPSEL) \ + || defined(_MIPSEL) \ + || defined(__BFIN__) \ + || (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)) + #define MY_CPU_LE #endif -#if defined(MY_CPU_X86_OR_AMD64) -#define MY_CPU_LE_UNALIGN +#if defined(__BIG_ENDIAN__) \ + || defined(__ARMEB__) \ + || defined(__THUMBEB__) \ + || defined(__AARCH64EB__) \ + || defined(__MIPSEB__) \ + || defined(__MIPSEB) \ + || defined(_MIPSEB) \ + || defined(__m68k__) \ + || defined(__s390__) \ + || defined(__s390x__) \ + || defined(__zarch__) \ + || (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)) + #define MY_CPU_BE #endif -#if defined(MY_CPU_X86_OR_AMD64) || defined(MY_CPU_ARM_LE) || defined(MY_CPU_IA64_LE) || defined(__ARMEL__) || defined(__MIPSEL__) || defined(__LITTLE_ENDIAN__) -#define MY_CPU_LE -#endif - -#if defined(__BIG_ENDIAN__) -#define MY_CPU_BE -#endif #if defined(MY_CPU_LE) && defined(MY_CPU_BE) -Stop_Compiling_Bad_Endian + #error Stop_Compiling_Bad_Endian #endif -#ifdef MY_CPU_LE_UNALIGN +#if !defined(MY_CPU_LE) && !defined(MY_CPU_BE) + #error Stop_Compiling_CPU_ENDIAN_must_be_detected_at_compile_time +#endif -#define GetUi16(p) (*(const UInt16 *)(p)) -#define GetUi32(p) (*(const UInt32 *)(p)) -#define GetUi64(p) (*(const UInt64 *)(p)) -#define SetUi16(p, d) *(UInt16 *)(p) = (d); -#define SetUi32(p, d) *(UInt32 *)(p) = (d); -#define SetUi64(p, d) *(UInt64 *)(p) = (d); +#if defined(MY_CPU_32BIT) && defined(MY_CPU_64BIT) + #error Stop_Compiling_Bad_32_64_BIT +#endif + +#ifdef __SIZEOF_POINTER__ + #ifdef MY_CPU_SIZEOF_POINTER + #if MY_CPU_SIZEOF_POINTER != __SIZEOF_POINTER__ + #error Stop_Compiling_Bad_MY_CPU_PTR_SIZE + #endif + #else + #define MY_CPU_SIZEOF_POINTER __SIZEOF_POINTER__ + #endif +#endif + +#if defined(MY_CPU_SIZEOF_POINTER) && (MY_CPU_SIZEOF_POINTER == 4) +#if defined (_LP64) + #error Stop_Compiling_Bad_MY_CPU_PTR_SIZE +#endif +#endif + +#ifdef _MSC_VER + #if _MSC_VER >= 1300 + #define MY_CPU_pragma_pack_push_1 __pragma(pack(push, 1)) + #define MY_CPU_pragma_pop __pragma(pack(pop)) + #else + #define MY_CPU_pragma_pack_push_1 + #define MY_CPU_pragma_pop + #endif +#else + #ifdef __xlC__ + #define MY_CPU_pragma_pack_push_1 _Pragma("pack(1)") + #define MY_CPU_pragma_pop _Pragma("pack()") + #else + #define MY_CPU_pragma_pack_push_1 _Pragma("pack(push, 1)") + #define MY_CPU_pragma_pop _Pragma("pack(pop)") + #endif +#endif + + +#ifndef MY_CPU_NAME + // #define MY_CPU_IS_UNKNOWN + #ifdef MY_CPU_LE + #define MY_CPU_NAME "LE" + #elif defined(MY_CPU_BE) + #define MY_CPU_NAME "BE" + #else + /* + #define MY_CPU_NAME "" + */ + #endif +#endif + + + + + +#ifdef __has_builtin + #define Z7_has_builtin(x) __has_builtin(x) +#else + #define Z7_has_builtin(x) 0 +#endif + + +#define Z7_BSWAP32_CONST(v) \ + ( (((UInt32)(v) << 24) ) \ + | (((UInt32)(v) << 8) & (UInt32)0xff0000) \ + | (((UInt32)(v) >> 8) & (UInt32)0xff00 ) \ + | (((UInt32)(v) >> 24) )) + + +#if defined(_MSC_VER) && (_MSC_VER >= 1300) + +#include + +/* Note: these macros will use bswap instruction (486), that is unsupported in 386 cpu */ + +#pragma intrinsic(_byteswap_ushort) +#pragma intrinsic(_byteswap_ulong) +#pragma intrinsic(_byteswap_uint64) + +#define Z7_BSWAP16(v) _byteswap_ushort(v) +#define Z7_BSWAP32(v) _byteswap_ulong (v) +#define Z7_BSWAP64(v) _byteswap_uint64(v) +#define Z7_CPU_FAST_BSWAP_SUPPORTED + +/* GCC can generate slow code that calls function for __builtin_bswap32() for: + - GCC for RISCV, if Zbb/XTHeadBb extension is not used. + - GCC for SPARC. + The code from CLANG for SPARC also is not fastest. + So we don't define Z7_CPU_FAST_BSWAP_SUPPORTED in some cases. +*/ +#elif (!defined(MY_CPU_RISCV) || defined (__riscv_zbb) || defined(__riscv_xtheadbb)) \ + && !defined(MY_CPU_SPARC) \ + && ( \ + (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))) \ + || (defined(__clang__) && Z7_has_builtin(__builtin_bswap16)) \ + ) + +#define Z7_BSWAP16(v) __builtin_bswap16(v) +#define Z7_BSWAP32(v) __builtin_bswap32(v) +#define Z7_BSWAP64(v) __builtin_bswap64(v) +#define Z7_CPU_FAST_BSWAP_SUPPORTED #else -#define GetUi16(p) (((const Byte *)(p))[0] | ((UInt16)((const Byte *)(p))[1] << 8)) +#define Z7_BSWAP16(v) ((UInt16) \ + ( ((UInt32)(v) << 8) \ + | ((UInt32)(v) >> 8) \ + )) + +#define Z7_BSWAP32(v) Z7_BSWAP32_CONST(v) + +#define Z7_BSWAP64(v) \ + ( ( ( (UInt64)(v) ) << 8 * 7 ) \ + | ( ( (UInt64)(v) & ((UInt32)0xff << 8 * 1) ) << 8 * 5 ) \ + | ( ( (UInt64)(v) & ((UInt32)0xff << 8 * 2) ) << 8 * 3 ) \ + | ( ( (UInt64)(v) & ((UInt32)0xff << 8 * 3) ) << 8 * 1 ) \ + | ( ( (UInt64)(v) >> 8 * 1 ) & ((UInt32)0xff << 8 * 3) ) \ + | ( ( (UInt64)(v) >> 8 * 3 ) & ((UInt32)0xff << 8 * 2) ) \ + | ( ( (UInt64)(v) >> 8 * 5 ) & ((UInt32)0xff << 8 * 1) ) \ + | ( ( (UInt64)(v) >> 8 * 7 ) ) \ + ) + +#endif + + + +#ifdef MY_CPU_LE + #if defined(MY_CPU_X86_OR_AMD64) \ + || defined(MY_CPU_ARM64) \ + || defined(MY_CPU_RISCV) && defined(__riscv_misaligned_fast) \ + || defined(MY_CPU_E2K) && defined(__iset__) && (__iset__ >= 6) + #define MY_CPU_LE_UNALIGN + #define MY_CPU_LE_UNALIGN_64 + #elif defined(__ARM_FEATURE_UNALIGNED) +/* === ALIGNMENT on 32-bit arm and LDRD/STRD/LDM/STM instructions. + Description of problems: +problem-1 : 32-bit ARM architecture: + multi-access (pair of 32-bit accesses) instructions (LDRD/STRD/LDM/STM) + require 32-bit (WORD) alignment (by 32-bit ARM architecture). + So there is "Alignment fault exception", if data is not aligned for 32-bit. + +problem-2 : 32-bit kernels and arm64 kernels: + 32-bit linux kernels provide fixup for these "paired" instruction "Alignment fault exception". + So unaligned paired-access instructions work via exception handler in kernel in 32-bit linux. + + But some arm64 kernels do not handle these faults in 32-bit programs. + So we have unhandled exception for such instructions. + Probably some new arm64 kernels have fixed it, and unaligned + paired-access instructions work in new kernels? + +problem-3 : compiler for 32-bit arm: + Compilers use LDRD/STRD/LDM/STM for UInt64 accesses + and for another cases where two 32-bit accesses are fused + to one multi-access instruction. + So UInt64 variables must be aligned for 32-bit, and each + 32-bit access must be aligned for 32-bit, if we want to + avoid "Alignment fault" exception (handled or unhandled). + +problem-4 : performace: + Even if unaligned access is handled by kernel, it will be slow. + So if we allow unaligned access, we can get fast unaligned + single-access, and slow unaligned paired-access. + + We don't allow unaligned access on 32-bit arm, because compiler + genarates paired-access instructions that require 32-bit alignment, + and some arm64 kernels have no handler for these instructions. + Also unaligned paired-access instructions will be slow, if kernel handles them. +*/ + // it must be disabled: + // #define MY_CPU_LE_UNALIGN + #endif +#endif + + +#ifdef MY_CPU_LE_UNALIGN + +#define GetUi16(p) (*(const UInt16 *)(const void *)(p)) +#define GetUi32(p) (*(const UInt32 *)(const void *)(p)) +#ifdef MY_CPU_LE_UNALIGN_64 +#define GetUi64(p) (*(const UInt64 *)(const void *)(p)) +#define SetUi64(p, v) { *(UInt64 *)(void *)(p) = (v); } +#endif + +#define SetUi16(p, v) { *(UInt16 *)(void *)(p) = (v); } +#define SetUi32(p, v) { *(UInt32 *)(void *)(p) = (v); } + +#else + +#define GetUi16(p) ( (UInt16) ( \ + ((const Byte *)(p))[0] | \ + ((UInt16)((const Byte *)(p))[1] << 8) )) #define GetUi32(p) ( \ ((const Byte *)(p))[0] | \ @@ -79,30 +483,46 @@ Stop_Compiling_Bad_Endian ((UInt32)((const Byte *)(p))[2] << 16) | \ ((UInt32)((const Byte *)(p))[3] << 24)) -#define GetUi64(p) (GetUi32(p) | ((UInt64)GetUi32(((const Byte *)(p)) + 4) << 32)) +#define SetUi16(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \ + _ppp_[0] = (Byte)_vvv_; \ + _ppp_[1] = (Byte)(_vvv_ >> 8); } -#define SetUi16(p, d) { UInt32 _x_ = (d); \ - ((Byte *)(p))[0] = (Byte)_x_; \ - ((Byte *)(p))[1] = (Byte)(_x_ >> 8); } - -#define SetUi32(p, d) { UInt32 _x_ = (d); \ - ((Byte *)(p))[0] = (Byte)_x_; \ - ((Byte *)(p))[1] = (Byte)(_x_ >> 8); \ - ((Byte *)(p))[2] = (Byte)(_x_ >> 16); \ - ((Byte *)(p))[3] = (Byte)(_x_ >> 24); } - -#define SetUi64(p, d) { UInt64 _x64_ = (d); \ - SetUi32(p, (UInt32)_x64_); \ - SetUi32(((Byte *)(p)) + 4, (UInt32)(_x64_ >> 32)); } +#define SetUi32(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \ + _ppp_[0] = (Byte)_vvv_; \ + _ppp_[1] = (Byte)(_vvv_ >> 8); \ + _ppp_[2] = (Byte)(_vvv_ >> 16); \ + _ppp_[3] = (Byte)(_vvv_ >> 24); } #endif -#if defined(MY_CPU_LE_UNALIGN) && defined(_WIN64) && (_MSC_VER >= 1300) -#pragma intrinsic(_byteswap_ulong) -#pragma intrinsic(_byteswap_uint64) -#define GetBe32(p) _byteswap_ulong(*(const UInt32 *)(const Byte *)(p)) -#define GetBe64(p) _byteswap_uint64(*(const UInt64 *)(const Byte *)(p)) +#ifndef GetUi64 +#define GetUi64(p) (GetUi32(p) | ((UInt64)GetUi32(((const Byte *)(p)) + 4) << 32)) +#endif + +#ifndef SetUi64 +#define SetUi64(p, v) { Byte *_ppp2_ = (Byte *)(p); UInt64 _vvv2_ = (v); \ + SetUi32(_ppp2_ , (UInt32)_vvv2_) \ + SetUi32(_ppp2_ + 4, (UInt32)(_vvv2_ >> 32)) } +#endif + + +#if defined(MY_CPU_LE_UNALIGN) && defined(Z7_CPU_FAST_BSWAP_SUPPORTED) + +#if 0 +// Z7_BSWAP16 can be slow for x86-msvc +#define GetBe16_to32(p) (Z7_BSWAP16 (*(const UInt16 *)(const void *)(p))) +#else +#define GetBe16_to32(p) (Z7_BSWAP32 (*(const UInt16 *)(const void *)(p)) >> 16) +#endif + +#define GetBe32(p) Z7_BSWAP32 (*(const UInt32 *)(const void *)(p)) +#define SetBe32(p, v) { (*(UInt32 *)(void *)(p)) = Z7_BSWAP32(v); } + +#if defined(MY_CPU_LE_UNALIGN_64) +#define GetBe64(p) Z7_BSWAP64 (*(const UInt64 *)(const void *)(p)) +#define SetBe64(p, v) { (*(UInt64 *)(void *)(p)) = Z7_BSWAP64(v); } +#endif #else @@ -112,44 +532,147 @@ Stop_Compiling_Bad_Endian ((UInt32)((const Byte *)(p))[2] << 8) | \ ((const Byte *)(p))[3] ) -#define GetBe64(p) (((UInt64)GetBe32(p) << 32) | GetBe32(((const Byte *)(p)) + 4)) +#define SetBe32(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \ + _ppp_[0] = (Byte)(_vvv_ >> 24); \ + _ppp_[1] = (Byte)(_vvv_ >> 16); \ + _ppp_[2] = (Byte)(_vvv_ >> 8); \ + _ppp_[3] = (Byte)_vvv_; } #endif -#define GetBe16(p) (((UInt16)((const Byte *)(p))[0] << 8) | ((const Byte *)(p))[1]) +#ifndef GetBe64 +#define GetBe64(p) (((UInt64)GetBe32(p) << 32) | GetBe32(((const Byte *)(p)) + 4)) +#endif + +#ifndef SetBe64 +#define SetBe64(p, v) { Byte *_ppp_ = (Byte *)(p); UInt64 _vvv_ = (v); \ + _ppp_[0] = (Byte)(_vvv_ >> 56); \ + _ppp_[1] = (Byte)(_vvv_ >> 48); \ + _ppp_[2] = (Byte)(_vvv_ >> 40); \ + _ppp_[3] = (Byte)(_vvv_ >> 32); \ + _ppp_[4] = (Byte)(_vvv_ >> 24); \ + _ppp_[5] = (Byte)(_vvv_ >> 16); \ + _ppp_[6] = (Byte)(_vvv_ >> 8); \ + _ppp_[7] = (Byte)_vvv_; } +#endif + +#ifndef GetBe16 +#ifdef GetBe16_to32 +#define GetBe16(p) ( (UInt16) GetBe16_to32(p)) +#else +#define GetBe16(p) ( (UInt16) ( \ + ((UInt16)((const Byte *)(p))[0] << 8) | \ + ((const Byte *)(p))[1] )) +#endif +#endif + + +#if defined(MY_CPU_BE) +#define Z7_CONV_BE_TO_NATIVE_CONST32(v) (v) +#define Z7_CONV_LE_TO_NATIVE_CONST32(v) Z7_BSWAP32_CONST(v) +#define Z7_CONV_NATIVE_TO_BE_32(v) (v) +#elif defined(MY_CPU_LE) +#define Z7_CONV_BE_TO_NATIVE_CONST32(v) Z7_BSWAP32_CONST(v) +#define Z7_CONV_LE_TO_NATIVE_CONST32(v) (v) +#define Z7_CONV_NATIVE_TO_BE_32(v) Z7_BSWAP32(v) +#else +#error Stop_Compiling_Unknown_Endian_CONV +#endif + + +#if defined(MY_CPU_BE) + +#define GetBe64a(p) (*(const UInt64 *)(const void *)(p)) +#define GetBe32a(p) (*(const UInt32 *)(const void *)(p)) +#define GetBe16a(p) (*(const UInt16 *)(const void *)(p)) +#define SetBe32a(p, v) { *(UInt32 *)(void *)(p) = (v); } +#define SetBe16a(p, v) { *(UInt16 *)(void *)(p) = (v); } + +#define GetUi64a(p) GetUi64(p) +#define GetUi32a(p) GetUi32(p) +#define GetUi16a(p) GetUi16(p) +#define SetUi32a(p, v) SetUi32(p, v) +#define SetUi16a(p, v) SetUi16(p, v) + +#elif defined(MY_CPU_LE) + +#define GetUi64a(p) (*(const UInt64 *)(const void *)(p)) +#define GetUi32a(p) (*(const UInt32 *)(const void *)(p)) +#define GetUi16a(p) (*(const UInt16 *)(const void *)(p)) +#define SetUi32a(p, v) { *(UInt32 *)(void *)(p) = (v); } +#define SetUi16a(p, v) { *(UInt16 *)(void *)(p) = (v); } + +#define GetBe64a(p) GetBe64(p) +#define GetBe32a(p) GetBe32(p) +#define GetBe16a(p) GetBe16(p) +#define SetBe32a(p, v) SetBe32(p, v) +#define SetBe16a(p, v) SetBe16(p, v) + +#else +#error Stop_Compiling_Unknown_Endian_CPU_a +#endif + + +#ifndef GetBe16_to32 +#define GetBe16_to32(p) GetBe16(p) +#endif + + +#if defined(MY_CPU_X86_OR_AMD64) \ + || defined(MY_CPU_ARM_OR_ARM64) \ + || defined(MY_CPU_PPC_OR_PPC64) + #define Z7_CPU_FAST_ROTATE_SUPPORTED +#endif #ifdef MY_CPU_X86_OR_AMD64 -typedef struct -{ - UInt32 maxFunc; - UInt32 vendor[3]; - UInt32 ver; - UInt32 b; - UInt32 c; - UInt32 d; -} Cx86cpuid; +void Z7_FASTCALL z7_x86_cpuid(UInt32 a[4], UInt32 function); +UInt32 Z7_FASTCALL z7_x86_cpuid_GetMaxFunc(void); +#if defined(MY_CPU_AMD64) +#define Z7_IF_X86_CPUID_SUPPORTED +#else +#define Z7_IF_X86_CPUID_SUPPORTED if (z7_x86_cpuid_GetMaxFunc()) +#endif -enum -{ - CPU_FIRM_INTEL, - CPU_FIRM_AMD, - CPU_FIRM_VIA -}; +BoolInt CPU_IsSupported_AES(void); +BoolInt CPU_IsSupported_AVX(void); +BoolInt CPU_IsSupported_AVX2(void); +BoolInt CPU_IsSupported_AVX512F_AVX512VL(void); +BoolInt CPU_IsSupported_VAES_AVX2(void); +BoolInt CPU_IsSupported_CMOV(void); +BoolInt CPU_IsSupported_SSE(void); +BoolInt CPU_IsSupported_SSE2(void); +BoolInt CPU_IsSupported_SSSE3(void); +BoolInt CPU_IsSupported_SSE41(void); +BoolInt CPU_IsSupported_SHA(void); +BoolInt CPU_IsSupported_SHA512(void); +BoolInt CPU_IsSupported_PageGB(void); -Bool x86cpuid_CheckAndRead(Cx86cpuid *p); -int x86cpuid_GetFirm(const Cx86cpuid *p); +#elif defined(MY_CPU_ARM_OR_ARM64) -#define x86cpuid_GetFamily(p) (((p)->ver >> 8) & 0xFF00F) -#define x86cpuid_GetModel(p) (((p)->ver >> 4) & 0xF00F) -#define x86cpuid_GetStepping(p) ((p)->ver & 0xF) +BoolInt CPU_IsSupported_CRC32(void); +BoolInt CPU_IsSupported_NEON(void); -Bool CPU_Is_InOrder(); -Bool CPU_Is_Aes_Supported(); +#if defined(_WIN32) +BoolInt CPU_IsSupported_CRYPTO(void); +#define CPU_IsSupported_SHA1 CPU_IsSupported_CRYPTO +#define CPU_IsSupported_SHA2 CPU_IsSupported_CRYPTO +#define CPU_IsSupported_AES CPU_IsSupported_CRYPTO +#else +BoolInt CPU_IsSupported_SHA1(void); +BoolInt CPU_IsSupported_SHA2(void); +BoolInt CPU_IsSupported_AES(void); +#endif +BoolInt CPU_IsSupported_SHA512(void); #endif +#if defined(__APPLE__) +int z7_sysctlbyname_Get(const char *name, void *buf, size_t *bufSize); +int z7_sysctlbyname_Get_UInt32(const char *name, UInt32 *val); +#endif + EXTERN_C_END #endif diff --git a/common/LZMA/SDK/C/LzFind.c b/common/LZMA/SDK/C/LzFind.c index 1c8ee6b..1ce4046 100644 --- a/common/LZMA/SDK/C/LzFind.c +++ b/common/LZMA/SDK/C/LzFind.c @@ -1,754 +1,1746 @@ /* LzFind.c -- Match finder for LZ algorithms -2009-04-22 : Igor Pavlov : Public domain */ +2024-03-01 : Igor Pavlov : Public domain */ + +#include "Precomp.h" #include +// #include +#include "CpuArch.h" #include "LzFind.h" #include "LzHash.h" +#define kBlockMoveAlign (1 << 7) // alignment for memmove() +#define kBlockSizeAlign (1 << 16) // alignment for block allocation +#define kBlockSizeReserveMin (1 << 24) // it's 1/256 from 4 GB dictinary + #define kEmptyHashValue 0 -#define kMaxValForNormalize ((UInt32)0xFFFFFFFF) -#define kNormalizeStepMin (1 << 10) /* it must be power of 2 */ -#define kNormalizeMask (~(kNormalizeStepMin - 1)) -#define kMaxHistorySize ((UInt32)3 << 30) -#define kStartMaxLen 3 +#define kMaxValForNormalize ((UInt32)0) +// #define kMaxValForNormalize ((UInt32)(1 << 20) + 0xfff) // for debug -static void LzInWindow_Free(CMatchFinder *p, ISzAlloc *alloc) +// #define kNormalizeAlign (1 << 7) // alignment for speculated accesses + +#define GET_AVAIL_BYTES(p) \ + Inline_MatchFinder_GetNumAvailableBytes(p) + + +// #define kFix5HashSize (kHash2Size + kHash3Size + kHash4Size) +#define kFix5HashSize kFix4HashSize + +/* + HASH2_CALC: + if (hv) match, then cur[0] and cur[1] also match +*/ +#define HASH2_CALC hv = GetUi16(cur); + +// (crc[0 ... 255] & 0xFF) provides one-to-one correspondence to [0 ... 255] + +/* + HASH3_CALC: + if (cur[0]) and (h2) match, then cur[1] also match + if (cur[0]) and (hv) match, then cur[1] and cur[2] also match +*/ +#define HASH3_CALC { \ + UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ + h2 = temp & (kHash2Size - 1); \ + hv = (temp ^ ((UInt32)cur[2] << 8)) & p->hashMask; } + +#define HASH4_CALC { \ + UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ + h2 = temp & (kHash2Size - 1); \ + temp ^= ((UInt32)cur[2] << 8); \ + h3 = temp & (kHash3Size - 1); \ + hv = (temp ^ (p->crc[cur[3]] << kLzHash_CrcShift_1)) & p->hashMask; } + +#define HASH5_CALC { \ + UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ + h2 = temp & (kHash2Size - 1); \ + temp ^= ((UInt32)cur[2] << 8); \ + h3 = temp & (kHash3Size - 1); \ + temp ^= (p->crc[cur[3]] << kLzHash_CrcShift_1); \ + /* h4 = temp & p->hash4Mask; */ /* (kHash4Size - 1); */ \ + hv = (temp ^ (p->crc[cur[4]] << kLzHash_CrcShift_2)) & p->hashMask; } + +#define HASH_ZIP_CALC hv = ((cur[2] | ((UInt32)cur[0] << 8)) ^ p->crc[cur[1]]) & 0xFFFF; + + +static void LzInWindow_Free(CMatchFinder *p, ISzAllocPtr alloc) { - if (!p->directInput) - { - alloc->Free(alloc, p->bufferBase); - p->bufferBase = 0; - } + // if (!p->directInput) + { + ISzAlloc_Free(alloc, p->bufBase); + p->bufBase = NULL; + } } -/* keepSizeBefore + keepSizeAfter + keepSizeReserv must be < 4G) */ -static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAlloc *alloc) +static int LzInWindow_Create2(CMatchFinder *p, UInt32 blockSize, ISzAllocPtr alloc) { - UInt32 blockSize = p->keepSizeBefore + p->keepSizeAfter + keepSizeReserv; - if (p->directInput) + if (blockSize == 0) + return 0; + if (!p->bufBase || p->blockSize != blockSize) + { + // size_t blockSizeT; + LzInWindow_Free(p, alloc); + p->blockSize = blockSize; + // blockSizeT = blockSize; + + // printf("\nblockSize = 0x%x\n", blockSize); + /* + #if defined _WIN64 + // we can allocate 4GiB, but still use UInt32 for (p->blockSize) + // we use UInt32 type for (p->blockSize), because + // we don't want to wrap over 4 GiB, + // when we use (p->streamPos - p->pos) that is UInt32. + if (blockSize >= (UInt32)0 - (UInt32)kBlockSizeAlign) { - p->blockSize = blockSize; - return 1; + blockSizeT = ((size_t)1 << 32); + printf("\nchanged to blockSizeT = 4GiB\n"); } - if (p->bufferBase == 0 || p->blockSize != blockSize) - { - LzInWindow_Free(p, alloc); - p->blockSize = blockSize; - p->bufferBase = (Byte *)alloc->Alloc(alloc, (size_t)blockSize); - } - return (p->bufferBase != 0); + #endif + */ + + p->bufBase = (Byte *)ISzAlloc_Alloc(alloc, blockSize); + // printf("\nbufferBase = %p\n", p->bufBase); + // return 0; // for debug + } + return (p->bufBase != NULL); } -Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p) { return p->buffer; } -Byte MatchFinder_GetIndexByte(CMatchFinder *p, Int32 index) { return p->buffer[index]; } - -UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) { return p->streamPos - p->pos; } - -void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue) +static const Byte *MatchFinder_GetPointerToCurrentPos(void *p) { - p->posLimit -= subValue; - p->pos -= subValue; - p->streamPos -= subValue; + return ((CMatchFinder *)p)->buffer; } +static UInt32 MatchFinder_GetNumAvailableBytes(void *p) +{ + return GET_AVAIL_BYTES((CMatchFinder *)p); +} + + +Z7_NO_INLINE static void MatchFinder_ReadBlock(CMatchFinder *p) { - if (p->streamEndWasReached || p->result != SZ_OK) - return; - if (p->directInput) + if (p->streamEndWasReached || p->result != SZ_OK) + return; + + /* We use (p->streamPos - p->pos) value. + (p->streamPos < p->pos) is allowed. */ + + if (p->directInput) + { + UInt32 curSize = 0xFFFFFFFF - GET_AVAIL_BYTES(p); + if (curSize > p->directInputRem) + curSize = (UInt32)p->directInputRem; + p->streamPos += curSize; + p->directInputRem -= curSize; + if (p->directInputRem == 0) + p->streamEndWasReached = 1; + return; + } + + for (;;) + { + const Byte *dest = p->buffer + GET_AVAIL_BYTES(p); + size_t size = (size_t)(p->bufBase + p->blockSize - dest); + if (size == 0) { - UInt32 curSize = 0xFFFFFFFF - p->streamPos; - if (curSize > p->directInputRem) - curSize = (UInt32)p->directInputRem; - p->directInputRem -= curSize; - p->streamPos += curSize; - if (p->directInputRem == 0) - p->streamEndWasReached = 1; - return; + /* we call ReadBlock() after NeedMove() and MoveBlock(). + NeedMove() and MoveBlock() povide more than (keepSizeAfter) + to the end of (blockSize). + So we don't execute this branch in normal code flow. + We can go here, if we will call ReadBlock() before NeedMove(), MoveBlock(). + */ + // p->result = SZ_ERROR_FAIL; // we can show error here + return; } - for (;;) + + // #define kRead 3 + // if (size > kRead) size = kRead; // for debug + + /* + // we need cast (Byte *)dest. + #ifdef __clang__ + #pragma GCC diagnostic ignored "-Wcast-qual" + #endif + */ + p->result = ISeqInStream_Read(p->stream, + p->bufBase + (dest - p->bufBase), &size); + if (p->result != SZ_OK) + return; + if (size == 0) { - Byte *dest = p->buffer + (p->streamPos - p->pos); - size_t size = (p->bufferBase + p->blockSize - dest); - if (size == 0) - return; - p->result = p->stream->Read(p->stream, dest, &size); - if (p->result != SZ_OK) - return; - if (size == 0) - { - p->streamEndWasReached = 1; - return; - } - p->streamPos += (UInt32)size; - if (p->streamPos - p->pos > p->keepSizeAfter) - return; + p->streamEndWasReached = 1; + return; } + p->streamPos += (UInt32)size; + if (GET_AVAIL_BYTES(p) > p->keepSizeAfter) + return; + /* here and in another (p->keepSizeAfter) checks we keep on 1 byte more than was requested by Create() function + (GET_AVAIL_BYTES(p) >= p->keepSizeAfter) - minimal required size */ + } + + // on exit: (p->result != SZ_OK || p->streamEndWasReached || GET_AVAIL_BYTES(p) > p->keepSizeAfter) } + + +Z7_NO_INLINE void MatchFinder_MoveBlock(CMatchFinder *p) { - memmove(p->bufferBase, - p->buffer - p->keepSizeBefore, - (size_t)(p->streamPos - p->pos + p->keepSizeBefore)); - p->buffer = p->bufferBase + p->keepSizeBefore; + const size_t offset = (size_t)(p->buffer - p->bufBase) - p->keepSizeBefore; + const size_t keepBefore = (offset & (kBlockMoveAlign - 1)) + p->keepSizeBefore; + p->buffer = p->bufBase + keepBefore; + memmove(p->bufBase, + p->bufBase + (offset & ~((size_t)kBlockMoveAlign - 1)), + keepBefore + (size_t)GET_AVAIL_BYTES(p)); } +/* We call MoveBlock() before ReadBlock(). + So MoveBlock() can be wasteful operation, if the whole input data + can fit in current block even without calling MoveBlock(). + in important case where (dataSize <= historySize) + condition (p->blockSize > dataSize + p->keepSizeAfter) is met + So there is no MoveBlock() in that case case. +*/ + int MatchFinder_NeedMove(CMatchFinder *p) { - if (p->directInput) - return 0; - /* if (p->streamEndWasReached) return 0; */ - return ((size_t)(p->bufferBase + p->blockSize - p->buffer) <= p->keepSizeAfter); + if (p->directInput) + return 0; + if (p->streamEndWasReached || p->result != SZ_OK) + return 0; + return ((size_t)(p->bufBase + p->blockSize - p->buffer) <= p->keepSizeAfter); } void MatchFinder_ReadIfRequired(CMatchFinder *p) { - if (p->streamEndWasReached) - return; - if (p->keepSizeAfter >= p->streamPos - p->pos) - MatchFinder_ReadBlock(p); -} - -static void MatchFinder_CheckAndMoveAndRead(CMatchFinder *p) -{ - if (MatchFinder_NeedMove(p)) - MatchFinder_MoveBlock(p); + if (p->keepSizeAfter >= GET_AVAIL_BYTES(p)) MatchFinder_ReadBlock(p); } + + static void MatchFinder_SetDefaultSettings(CMatchFinder *p) { - p->cutValue = 32; - p->btMode = 1; - p->numHashBytes = 4; - p->bigHash = 0; + p->cutValue = 32; + p->btMode = 1; + p->numHashBytes = 4; + p->numHashBytes_Min = 2; + p->numHashOutBits = 0; + p->bigHash = 0; } #define kCrcPoly 0xEDB88320 void MatchFinder_Construct(CMatchFinder *p) { - UInt32 i; - p->bufferBase = 0; - p->directInput = 0; - p->hash = 0; - MatchFinder_SetDefaultSettings(p); + unsigned i; + p->buffer = NULL; + p->bufBase = NULL; + p->directInput = 0; + p->stream = NULL; + p->hash = NULL; + p->expectedDataSize = (UInt64)(Int64)-1; + MatchFinder_SetDefaultSettings(p); - for (i = 0; i < 256; i++) + for (i = 0; i < 256; i++) + { + UInt32 r = (UInt32)i; + unsigned j; + for (j = 0; j < 8; j++) + r = (r >> 1) ^ (kCrcPoly & ((UInt32)0 - (r & 1))); + p->crc[i] = r; + } +} + +#undef kCrcPoly + +static void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAllocPtr alloc) +{ + ISzAlloc_Free(alloc, p->hash); + p->hash = NULL; +} + +void MatchFinder_Free(CMatchFinder *p, ISzAllocPtr alloc) +{ + MatchFinder_FreeThisClassMemory(p, alloc); + LzInWindow_Free(p, alloc); +} + +static CLzRef* AllocRefs(size_t num, ISzAllocPtr alloc) +{ + const size_t sizeInBytes = (size_t)num * sizeof(CLzRef); + if (sizeInBytes / sizeof(CLzRef) != num) + return NULL; + return (CLzRef *)ISzAlloc_Alloc(alloc, sizeInBytes); +} + +#if (kBlockSizeReserveMin < kBlockSizeAlign * 2) + #error Stop_Compiling_Bad_Reserve +#endif + + + +static UInt32 GetBlockSize(CMatchFinder *p, UInt32 historySize) +{ + UInt32 blockSize = (p->keepSizeBefore + p->keepSizeAfter); + /* + if (historySize > kMaxHistorySize) + return 0; + */ + // printf("\nhistorySize == 0x%x\n", historySize); + + if (p->keepSizeBefore < historySize || blockSize < p->keepSizeBefore) // if 32-bit overflow + return 0; + + { + const UInt32 kBlockSizeMax = (UInt32)0 - (UInt32)kBlockSizeAlign; + const UInt32 rem = kBlockSizeMax - blockSize; + const UInt32 reserve = (blockSize >> (blockSize < ((UInt32)1 << 30) ? 1 : 2)) + + (1 << 12) + kBlockMoveAlign + kBlockSizeAlign; // do not overflow 32-bit here + if (blockSize >= kBlockSizeMax + || rem < kBlockSizeReserveMin) // we reject settings that will be slow + return 0; + if (reserve >= rem) + blockSize = kBlockSizeMax; + else { - UInt32 r = i; - int j; - for (j = 0; j < 8; j++) - r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1)); - p->crc[i] = r; + blockSize += reserve; + blockSize &= ~(UInt32)(kBlockSizeAlign - 1); } + } + // printf("\n LzFind_blockSize = %x\n", blockSize); + // printf("\n LzFind_blockSize = %d\n", blockSize >> 20); + return blockSize; } -static void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAlloc *alloc) + +// input is historySize +static UInt32 MatchFinder_GetHashMask2(CMatchFinder *p, UInt32 hs) { - alloc->Free(alloc, p->hash); - p->hash = 0; + if (p->numHashBytes == 2) + return (1 << 16) - 1; + if (hs != 0) + hs--; + hs |= (hs >> 1); + hs |= (hs >> 2); + hs |= (hs >> 4); + hs |= (hs >> 8); + // we propagated 16 bits in (hs). Low 16 bits must be set later + if (hs >= (1 << 24)) + { + if (p->numHashBytes == 3) + hs = (1 << 24) - 1; + /* if (bigHash) mode, GetHeads4b() in LzFindMt.c needs (hs >= ((1 << 24) - 1))) */ + } + // (hash_size >= (1 << 16)) : Required for (numHashBytes > 2) + hs |= (1 << 16) - 1; /* don't change it! */ + // bt5: we adjust the size with recommended minimum size + if (p->numHashBytes >= 5) + hs |= (256 << kLzHash_CrcShift_2) - 1; + return hs; } -void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc) +// input is historySize +static UInt32 MatchFinder_GetHashMask(CMatchFinder *p, UInt32 hs) { - MatchFinder_FreeThisClassMemory(p, alloc); - LzInWindow_Free(p, alloc); + if (p->numHashBytes == 2) + return (1 << 16) - 1; + if (hs != 0) + hs--; + hs |= (hs >> 1); + hs |= (hs >> 2); + hs |= (hs >> 4); + hs |= (hs >> 8); + // we propagated 16 bits in (hs). Low 16 bits must be set later + hs >>= 1; + if (hs >= (1 << 24)) + { + if (p->numHashBytes == 3) + hs = (1 << 24) - 1; + else + hs >>= 1; + /* if (bigHash) mode, GetHeads4b() in LzFindMt.c needs (hs >= ((1 << 24) - 1))) */ + } + // (hash_size >= (1 << 16)) : Required for (numHashBytes > 2) + hs |= (1 << 16) - 1; /* don't change it! */ + // bt5: we adjust the size with recommended minimum size + if (p->numHashBytes >= 5) + hs |= (256 << kLzHash_CrcShift_2) - 1; + return hs; } -static CLzRef* AllocRefs(UInt32 num, ISzAlloc *alloc) -{ - size_t sizeInBytes = (size_t)num * sizeof(CLzRef); - if (sizeInBytes / sizeof(CLzRef) != num) - return 0; - return (CLzRef *)alloc->Alloc(alloc, sizeInBytes); -} int MatchFinder_Create(CMatchFinder *p, UInt32 historySize, UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter, - ISzAlloc *alloc) + ISzAllocPtr alloc) { - UInt32 sizeReserv; - if (historySize > kMaxHistorySize) + /* we need one additional byte in (p->keepSizeBefore), + since we use MoveBlock() after (p->pos++) and before dictionary using */ + // keepAddBufferBefore = (UInt32)0xFFFFFFFF - (1 << 22); // for debug + p->keepSizeBefore = historySize + keepAddBufferBefore + 1; + + keepAddBufferAfter += matchMaxLen; + /* we need (p->keepSizeAfter >= p->numHashBytes) */ + if (keepAddBufferAfter < p->numHashBytes) + keepAddBufferAfter = p->numHashBytes; + // keepAddBufferAfter -= 2; // for debug + p->keepSizeAfter = keepAddBufferAfter; + + if (p->directInput) + p->blockSize = 0; + if (p->directInput || LzInWindow_Create2(p, GetBlockSize(p, historySize), alloc)) + { + size_t hashSizeSum; { - MatchFinder_Free(p, alloc); + UInt32 hs; + UInt32 hsCur; + + if (p->numHashOutBits != 0) + { + unsigned numBits = p->numHashOutBits; + const unsigned nbMax = + (p->numHashBytes == 2 ? 16 : + (p->numHashBytes == 3 ? 24 : 32)); + if (numBits > nbMax) + numBits = nbMax; + if (numBits >= 32) + hs = (UInt32)0 - 1; + else + hs = ((UInt32)1 << numBits) - 1; + // (hash_size >= (1 << 16)) : Required for (numHashBytes > 2) + hs |= (1 << 16) - 1; /* don't change it! */ + if (p->numHashBytes >= 5) + hs |= (256 << kLzHash_CrcShift_2) - 1; + { + const UInt32 hs2 = MatchFinder_GetHashMask2(p, historySize); + if (hs > hs2) + hs = hs2; + } + hsCur = hs; + if (p->expectedDataSize < historySize) + { + const UInt32 hs2 = MatchFinder_GetHashMask2(p, (UInt32)p->expectedDataSize); + if (hsCur > hs2) + hsCur = hs2; + } + } + else + { + hs = MatchFinder_GetHashMask(p, historySize); + hsCur = hs; + if (p->expectedDataSize < historySize) + { + hsCur = MatchFinder_GetHashMask(p, (UInt32)p->expectedDataSize); + if (hsCur > hs) // is it possible? + hsCur = hs; + } + } + + p->hashMask = hsCur; + + hashSizeSum = hs; + hashSizeSum++; + if (hashSizeSum < hs) return 0; + { + UInt32 fixedHashSize = 0; + if (p->numHashBytes > 2 && p->numHashBytes_Min <= 2) fixedHashSize += kHash2Size; + if (p->numHashBytes > 3 && p->numHashBytes_Min <= 3) fixedHashSize += kHash3Size; + // if (p->numHashBytes > 4) p->fixedHashSize += hs4; // kHash4Size; + hashSizeSum += fixedHashSize; + p->fixedHashSize = fixedHashSize; + } } - sizeReserv = historySize >> 1; - if (historySize > ((UInt32)2 << 30)) - sizeReserv = historySize >> 2; - sizeReserv += (keepAddBufferBefore + matchMaxLen + keepAddBufferAfter) / 2 + (1 << 19); - p->keepSizeBefore = historySize + keepAddBufferBefore + 1; - p->keepSizeAfter = matchMaxLen + keepAddBufferAfter; - /* we need one additional byte, since we use MoveBlock after pos++ and before dictionary using */ - if (LzInWindow_Create(p, sizeReserv, alloc)) - { - UInt32 newCyclicBufferSize = historySize + 1; - UInt32 hs; - p->matchMaxLen = matchMaxLen; - { - p->fixedHashSize = 0; - if (p->numHashBytes == 2) - hs = (1 << 16) - 1; - else - { - hs = historySize - 1; - hs |= (hs >> 1); - hs |= (hs >> 2); - hs |= (hs >> 4); - hs |= (hs >> 8); - hs >>= 1; - hs |= 0xFFFF; /* don't change it! It's required for Deflate */ - if (hs > (1 << 24)) - { - if (p->numHashBytes == 3) - hs = (1 << 24) - 1; - else - hs >>= 1; - } - } - p->hashMask = hs; - hs++; - if (p->numHashBytes > 2) p->fixedHashSize += kHash2Size; - if (p->numHashBytes > 3) p->fixedHashSize += kHash3Size; - if (p->numHashBytes > 4) p->fixedHashSize += kHash4Size; - hs += p->fixedHashSize; - } + p->matchMaxLen = matchMaxLen; { - UInt32 prevSize = p->hashSizeSum + p->numSons; - UInt32 newSize; - p->historySize = historySize; - p->hashSizeSum = hs; - p->cyclicBufferSize = newCyclicBufferSize; - p->numSons = (p->btMode ? newCyclicBufferSize * 2 : newCyclicBufferSize); - newSize = p->hashSizeSum + p->numSons; - if (p->hash != 0 && prevSize == newSize) - return 1; - MatchFinder_FreeThisClassMemory(p, alloc); - p->hash = AllocRefs(newSize, alloc); - if (p->hash != 0) - { - p->son = p->hash + p->hashSizeSum; - return 1; - } + size_t newSize; + size_t numSons; + const UInt32 newCyclicBufferSize = historySize + 1; // do not change it + p->historySize = historySize; + p->cyclicBufferSize = newCyclicBufferSize; // it must be = (historySize + 1) + + numSons = newCyclicBufferSize; + if (p->btMode) + numSons <<= 1; + newSize = hashSizeSum + numSons; + + if (numSons < newCyclicBufferSize || newSize < numSons) + return 0; + + // aligned size is not required here, but it can be better for some loops + #define NUM_REFS_ALIGN_MASK 0xF + newSize = (newSize + NUM_REFS_ALIGN_MASK) & ~(size_t)NUM_REFS_ALIGN_MASK; + + // 22.02: we don't reallocate buffer, if old size is enough + if (p->hash && p->numRefs >= newSize) + return 1; + + MatchFinder_FreeThisClassMemory(p, alloc); + p->numRefs = newSize; + p->hash = AllocRefs(newSize, alloc); + + if (p->hash) + { + p->son = p->hash + hashSizeSum; + return 1; + } } - } - MatchFinder_Free(p, alloc); - return 0; + } + + MatchFinder_Free(p, alloc); + return 0; } + static void MatchFinder_SetLimits(CMatchFinder *p) { - UInt32 limit = kMaxValForNormalize - p->pos; - UInt32 limit2 = p->cyclicBufferSize - p->cyclicBufferPos; - if (limit2 < limit) - limit = limit2; - limit2 = p->streamPos - p->pos; - if (limit2 <= p->keepSizeAfter) + UInt32 k; + UInt32 n = kMaxValForNormalize - p->pos; + if (n == 0) + n = (UInt32)(Int32)-1; // we allow (pos == 0) at start even with (kMaxValForNormalize == 0) + + k = p->cyclicBufferSize - p->cyclicBufferPos; + if (k < n) + n = k; + + k = GET_AVAIL_BYTES(p); + { + const UInt32 ksa = p->keepSizeAfter; + UInt32 mm = p->matchMaxLen; + if (k > ksa) + k -= ksa; // we must limit exactly to keepSizeAfter for ReadBlock + else if (k >= mm) { - if (limit2 > 0) - limit2 = 1; + // the limitation for (p->lenLimit) update + k -= mm; // optimization : to reduce the number of checks + k++; + // k = 1; // non-optimized version : for debug } else - limit2 -= p->keepSizeAfter; - if (limit2 < limit) - limit = limit2; { - UInt32 lenLimit = p->streamPos - p->pos; - if (lenLimit > p->matchMaxLen) - lenLimit = p->matchMaxLen; - p->lenLimit = lenLimit; + mm = k; + if (k != 0) + k = 1; } - p->posLimit = p->pos + limit; + p->lenLimit = mm; + } + if (k < n) + n = k; + + p->posLimit = p->pos + n; } -void MatchFinder_Init(CMatchFinder *p) + +void MatchFinder_Init_LowHash(CMatchFinder *p) { - UInt32 i; - for (i = 0; i < p->hashSizeSum; i++) - p->hash[i] = kEmptyHashValue; - p->cyclicBufferPos = 0; - p->buffer = p->bufferBase; - p->pos = p->streamPos = p->cyclicBufferSize; - p->result = SZ_OK; - p->streamEndWasReached = 0; - MatchFinder_ReadBlock(p); - MatchFinder_SetLimits(p); + size_t i; + CLzRef *items = p->hash; + const size_t numItems = p->fixedHashSize; + for (i = 0; i < numItems; i++) + items[i] = kEmptyHashValue; } -static UInt32 MatchFinder_GetSubValue(CMatchFinder *p) + +void MatchFinder_Init_HighHash(CMatchFinder *p) { - return (p->pos - p->historySize - 1) & kNormalizeMask; + size_t i; + CLzRef *items = p->hash + p->fixedHashSize; + const size_t numItems = (size_t)p->hashMask + 1; + for (i = 0; i < numItems; i++) + items[i] = kEmptyHashValue; } -void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems) + +void MatchFinder_Init_4(CMatchFinder *p) { - UInt32 i; - for (i = 0; i < numItems; i++) + if (!p->directInput) + p->buffer = p->bufBase; + { + /* kEmptyHashValue = 0 (Zero) is used in hash tables as NO-VALUE marker. + the code in CMatchFinderMt expects (pos = 1) */ + p->pos = + p->streamPos = + 1; // it's smallest optimal value. do not change it + // 0; // for debug + } + p->result = SZ_OK; + p->streamEndWasReached = 0; +} + + +// (CYC_TO_POS_OFFSET == 0) is expected by some optimized code +#define CYC_TO_POS_OFFSET 0 +// #define CYC_TO_POS_OFFSET 1 // for debug + +void MatchFinder_Init(void *_p) +{ + CMatchFinder *p = (CMatchFinder *)_p; + MatchFinder_Init_HighHash(p); + MatchFinder_Init_LowHash(p); + MatchFinder_Init_4(p); + // if (readData) + MatchFinder_ReadBlock(p); + + /* if we init (cyclicBufferPos = pos), then we can use one variable + instead of both (cyclicBufferPos) and (pos) : only before (cyclicBufferPos) wrapping */ + p->cyclicBufferPos = (p->pos - CYC_TO_POS_OFFSET); // init with relation to (pos) + // p->cyclicBufferPos = 0; // smallest value + // p->son[0] = p->son[1] = 0; // unused: we can init skipped record for speculated accesses. + MatchFinder_SetLimits(p); +} + + + +#ifdef MY_CPU_X86_OR_AMD64 + #if defined(__clang__) && (__clang_major__ >= 4) \ + || defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION >= 40701) + // || defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1900) + + #define USE_LZFIND_SATUR_SUB_128 + #define USE_LZFIND_SATUR_SUB_256 + #define LZFIND_ATTRIB_SSE41 __attribute__((__target__("sse4.1"))) + #define LZFIND_ATTRIB_AVX2 __attribute__((__target__("avx2"))) + #elif defined(_MSC_VER) + #if (_MSC_VER >= 1600) + #define USE_LZFIND_SATUR_SUB_128 + #endif + #if (_MSC_VER >= 1900) + #define USE_LZFIND_SATUR_SUB_256 + #endif + #endif + +#elif defined(MY_CPU_ARM64) \ + /* || (defined(__ARM_ARCH) && (__ARM_ARCH >= 7)) */ + + #if defined(Z7_CLANG_VERSION) && (Z7_CLANG_VERSION >= 30800) \ + || defined(__GNUC__) && (__GNUC__ >= 6) + #define USE_LZFIND_SATUR_SUB_128 + #ifdef MY_CPU_ARM64 + // #define LZFIND_ATTRIB_SSE41 __attribute__((__target__(""))) + #else + #define LZFIND_ATTRIB_SSE41 __attribute__((__target__("fpu=neon"))) + #endif + + #elif defined(_MSC_VER) + #if (_MSC_VER >= 1910) + #define USE_LZFIND_SATUR_SUB_128 + #endif + #endif + + #if defined(Z7_MSC_VER_ORIGINAL) && defined(MY_CPU_ARM64) + #include + #else + #include + #endif + +#endif + + +#ifdef USE_LZFIND_SATUR_SUB_128 + +// #define Z7_SHOW_HW_STATUS + +#ifdef Z7_SHOW_HW_STATUS +#include +#define PRF(x) x +PRF(;) +#else +#define PRF(x) +#endif + + +#ifdef MY_CPU_ARM_OR_ARM64 + +#ifdef MY_CPU_ARM64 +// #define FORCE_LZFIND_SATUR_SUB_128 +#endif +typedef uint32x4_t LzFind_v128; +#define SASUB_128_V(v, s) \ + vsubq_u32(vmaxq_u32(v, s), s) + +#else // MY_CPU_ARM_OR_ARM64 + +#include // sse4.1 + +typedef __m128i LzFind_v128; +// SSE 4.1 +#define SASUB_128_V(v, s) \ + _mm_sub_epi32(_mm_max_epu32(v, s), s) + +#endif // MY_CPU_ARM_OR_ARM64 + + +#define SASUB_128(i) \ + *( LzFind_v128 *)( void *)(items + (i) * 4) = SASUB_128_V( \ + *(const LzFind_v128 *)(const void *)(items + (i) * 4), sub2); + + +Z7_NO_INLINE +static +#ifdef LZFIND_ATTRIB_SSE41 +LZFIND_ATTRIB_SSE41 +#endif +void +Z7_FASTCALL +LzFind_SaturSub_128(UInt32 subValue, CLzRef *items, const CLzRef *lim) +{ + const LzFind_v128 sub2 = + #ifdef MY_CPU_ARM_OR_ARM64 + vdupq_n_u32(subValue); + #else + _mm_set_epi32((Int32)subValue, (Int32)subValue, (Int32)subValue, (Int32)subValue); + #endif + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + do + { + SASUB_128(0) SASUB_128(1) items += 2 * 4; + SASUB_128(0) SASUB_128(1) items += 2 * 4; + } + while (items != lim); +} + + + +#ifdef USE_LZFIND_SATUR_SUB_256 + +#include // avx +/* +clang :immintrin.h uses +#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ + defined(__AVX2__) +#include +#endif +so we need for clang-cl */ + +#if defined(__clang__) +#include +#include +#endif + +// AVX2: +#define SASUB_256(i) \ + *( __m256i *)( void *)(items + (i) * 8) = \ + _mm256_sub_epi32(_mm256_max_epu32( \ + *(const __m256i *)(const void *)(items + (i) * 8), sub2), sub2); + +Z7_NO_INLINE +static +#ifdef LZFIND_ATTRIB_AVX2 +LZFIND_ATTRIB_AVX2 +#endif +void +Z7_FASTCALL +LzFind_SaturSub_256(UInt32 subValue, CLzRef *items, const CLzRef *lim) +{ + const __m256i sub2 = _mm256_set_epi32( + (Int32)subValue, (Int32)subValue, (Int32)subValue, (Int32)subValue, + (Int32)subValue, (Int32)subValue, (Int32)subValue, (Int32)subValue); + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + do + { + SASUB_256(0) SASUB_256(1) items += 2 * 8; + SASUB_256(0) SASUB_256(1) items += 2 * 8; + } + while (items != lim); +} +#endif // USE_LZFIND_SATUR_SUB_256 + +#ifndef FORCE_LZFIND_SATUR_SUB_128 +typedef void (Z7_FASTCALL *LZFIND_SATUR_SUB_CODE_FUNC)( + UInt32 subValue, CLzRef *items, const CLzRef *lim); +static LZFIND_SATUR_SUB_CODE_FUNC g_LzFind_SaturSub; +#endif // FORCE_LZFIND_SATUR_SUB_128 + +#endif // USE_LZFIND_SATUR_SUB_128 + + +// kEmptyHashValue must be zero +// #define SASUB_32(i) { UInt32 v = items[i]; UInt32 m = v - subValue; if (v < subValue) m = kEmptyHashValue; items[i] = m; } +#define SASUB_32(i) { UInt32 v = items[i]; if (v < subValue) v = subValue; items[i] = v - subValue; } + +#ifdef FORCE_LZFIND_SATUR_SUB_128 + +#define DEFAULT_SaturSub LzFind_SaturSub_128 + +#else + +#define DEFAULT_SaturSub LzFind_SaturSub_32 + +Z7_NO_INLINE +static +void +Z7_FASTCALL +LzFind_SaturSub_32(UInt32 subValue, CLzRef *items, const CLzRef *lim) +{ + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + do + { + SASUB_32(0) SASUB_32(1) items += 2; + SASUB_32(0) SASUB_32(1) items += 2; + SASUB_32(0) SASUB_32(1) items += 2; + SASUB_32(0) SASUB_32(1) items += 2; + } + while (items != lim); +} + +#endif + + +Z7_NO_INLINE +void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, size_t numItems) +{ + #define LZFIND_NORM_ALIGN_BLOCK_SIZE (1 << 7) + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + for (; numItems != 0 && ((unsigned)(ptrdiff_t)items & (LZFIND_NORM_ALIGN_BLOCK_SIZE - 1)) != 0; numItems--) + { + SASUB_32(0) + items++; + } + { + const size_t k_Align_Mask = (LZFIND_NORM_ALIGN_BLOCK_SIZE / 4 - 1); + CLzRef *lim = items + (numItems & ~(size_t)k_Align_Mask); + numItems &= k_Align_Mask; + if (items != lim) { - UInt32 value = items[i]; - if (value <= subValue) - value = kEmptyHashValue; + #if defined(USE_LZFIND_SATUR_SUB_128) && !defined(FORCE_LZFIND_SATUR_SUB_128) + if (g_LzFind_SaturSub) + g_LzFind_SaturSub(subValue, items, lim); else - value -= subValue; - items[i] = value; + #endif + DEFAULT_SaturSub(subValue, items, lim); } + items = lim; + } + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + for (; numItems != 0; numItems--) + { + SASUB_32(0) + items++; + } } -static void MatchFinder_Normalize(CMatchFinder *p) -{ - UInt32 subValue = MatchFinder_GetSubValue(p); - MatchFinder_Normalize3(subValue, p->hash, p->hashSizeSum + p->numSons); - MatchFinder_ReduceOffsets(p, subValue); -} + +// call MatchFinder_CheckLimits() only after (p->pos++) update + +Z7_NO_INLINE static void MatchFinder_CheckLimits(CMatchFinder *p) { - if (p->pos == kMaxValForNormalize) - MatchFinder_Normalize(p); - if (!p->streamEndWasReached && p->keepSizeAfter == p->streamPos - p->pos) - MatchFinder_CheckAndMoveAndRead(p); - if (p->cyclicBufferPos == p->cyclicBufferSize) - p->cyclicBufferPos = 0; - MatchFinder_SetLimits(p); -} + if (// !p->streamEndWasReached && p->result == SZ_OK && + p->keepSizeAfter == GET_AVAIL_BYTES(p)) + { + // we try to read only in exact state (p->keepSizeAfter == GET_AVAIL_BYTES(p)) + if (MatchFinder_NeedMove(p)) + MatchFinder_MoveBlock(p); + MatchFinder_ReadBlock(p); + } -static UInt32 * Hc_GetMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, - UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue, - UInt32 *distances, UInt32 maxLen) -{ - son[_cyclicBufferPos] = curMatch; - for (;;) + if (p->pos == kMaxValForNormalize) + if (GET_AVAIL_BYTES(p) >= p->numHashBytes) // optional optimization for last bytes of data. + /* + if we disable normalization for last bytes of data, and + if (data_size == 4 GiB), we don't call wastfull normalization, + but (pos) will be wrapped over Zero (0) in that case. + And we cannot resume later to normal operation + */ + { + // MatchFinder_Normalize(p); + /* after normalization we need (p->pos >= p->historySize + 1); */ + /* we can reduce subValue to aligned value, if want to keep alignment + of (p->pos) and (p->buffer) for speculated accesses. */ + const UInt32 subValue = (p->pos - p->historySize - 1) /* & ~(UInt32)(kNormalizeAlign - 1) */; + // const UInt32 subValue = (1 << 15); // for debug + // printf("\nMatchFinder_Normalize() subValue == 0x%x\n", subValue); + MatchFinder_REDUCE_OFFSETS(p, subValue) + MatchFinder_Normalize3(subValue, p->hash, (size_t)p->hashMask + 1 + p->fixedHashSize); { - UInt32 delta = pos - curMatch; - if (cutValue-- == 0 || delta >= _cyclicBufferSize) - return distances; - { - const Byte *pb = cur - delta; - curMatch = son[_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)]; - if (pb[maxLen] == cur[maxLen] && *pb == *cur) - { - UInt32 len = 0; - while (++len != lenLimit) - if (pb[len] != cur[len]) - break; - if (maxLen < len) - { - *distances++ = maxLen = len; - *distances++ = delta - 1; - if (len == lenLimit) - return distances; - } - } - } + size_t numSonRefs = p->cyclicBufferSize; + if (p->btMode) + numSonRefs <<= 1; + MatchFinder_Normalize3(subValue, p->son, numSonRefs); } + } + + if (p->cyclicBufferPos == p->cyclicBufferSize) + p->cyclicBufferPos = 0; + + MatchFinder_SetLimits(p); } + +/* + (lenLimit > maxLen) +*/ +Z7_FORCE_INLINE +static UInt32 * Hc_GetMatchesSpec(size_t lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, + size_t _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue, + UInt32 *d, unsigned maxLen) +{ + /* + son[_cyclicBufferPos] = curMatch; + for (;;) + { + UInt32 delta = pos - curMatch; + if (cutValue-- == 0 || delta >= _cyclicBufferSize) + return d; + { + const Byte *pb = cur - delta; + curMatch = son[_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)]; + if (pb[maxLen] == cur[maxLen] && *pb == *cur) + { + UInt32 len = 0; + while (++len != lenLimit) + if (pb[len] != cur[len]) + break; + if (maxLen < len) + { + maxLen = len; + *d++ = len; + *d++ = delta - 1; + if (len == lenLimit) + return d; + } + } + } + } + */ + + const Byte *lim = cur + lenLimit; + son[_cyclicBufferPos] = curMatch; + + do + { + UInt32 delta; + + if (curMatch == 0) + break; + // if (curMatch2 >= curMatch) return NULL; + delta = pos - curMatch; + if (delta >= _cyclicBufferSize) + break; + { + ptrdiff_t diff; + curMatch = son[_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)]; + diff = (ptrdiff_t)0 - (ptrdiff_t)delta; + if (cur[maxLen] == cur[(ptrdiff_t)maxLen + diff]) + { + const Byte *c = cur; + while (*c == c[diff]) + { + if (++c == lim) + { + d[0] = (UInt32)(lim - cur); + d[1] = delta - 1; + return d + 2; + } + } + { + const unsigned len = (unsigned)(c - cur); + if (maxLen < len) + { + maxLen = len; + d[0] = (UInt32)len; + d[1] = delta - 1; + d += 2; + } + } + } + } + } + while (--cutValue); + + return d; +} + + +Z7_FORCE_INLINE UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, - UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue, - UInt32 *distances, UInt32 maxLen) + size_t _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue, + UInt32 *d, UInt32 maxLen) { - CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1; - CLzRef *ptr1 = son + (_cyclicBufferPos << 1); - UInt32 len0 = 0, len1 = 0; - for (;;) + CLzRef *ptr0 = son + ((size_t)_cyclicBufferPos << 1) + 1; + CLzRef *ptr1 = son + ((size_t)_cyclicBufferPos << 1); + unsigned len0 = 0, len1 = 0; + + UInt32 cmCheck; + + // if (curMatch >= pos) { *ptr0 = *ptr1 = kEmptyHashValue; return NULL; } + + cmCheck = (UInt32)(pos - _cyclicBufferSize); + if ((UInt32)pos <= _cyclicBufferSize) + cmCheck = 0; + + if (cmCheck < curMatch) + do + { + const UInt32 delta = pos - curMatch; { - UInt32 delta = pos - curMatch; - if (cutValue-- == 0 || delta >= _cyclicBufferSize) + CLzRef *pair = son + ((size_t)(_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1); + const Byte *pb = cur - delta; + unsigned len = (len0 < len1 ? len0 : len1); + const UInt32 pair0 = pair[0]; + if (pb[len] == cur[len]) + { + if (++len != lenLimit && pb[len] == cur[len]) + while (++len != lenLimit) + if (pb[len] != cur[len]) + break; + if (maxLen < len) { - *ptr0 = *ptr1 = kEmptyHashValue; - return distances; - } - { - CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1); - const Byte *pb = cur - delta; - UInt32 len = (len0 < len1 ? len0 : len1); - if (pb[len] == cur[len]) - { - if (++len != lenLimit && pb[len] == cur[len]) - while (++len != lenLimit) - if (pb[len] != cur[len]) - break; - if (maxLen < len) - { - *distances++ = maxLen = len; - *distances++ = delta - 1; - if (len == lenLimit) - { - *ptr1 = pair[0]; - *ptr0 = pair[1]; - return distances; - } - } - } - if (pb[len] < cur[len]) - { - *ptr1 = curMatch; - ptr1 = pair + 1; - curMatch = *ptr1; - len1 = len; - } - else - { - *ptr0 = curMatch; - ptr0 = pair; - curMatch = *ptr0; - len0 = len; + maxLen = (UInt32)len; + *d++ = (UInt32)len; + *d++ = delta - 1; + if (len == lenLimit) + { + *ptr1 = pair0; + *ptr0 = pair[1]; + return d; + } } + } + if (pb[len] < cur[len]) + { + *ptr1 = curMatch; + // const UInt32 curMatch2 = pair[1]; + // if (curMatch2 >= curMatch) { *ptr0 = *ptr1 = kEmptyHashValue; return NULL; } + // curMatch = curMatch2; + curMatch = pair[1]; + ptr1 = pair + 1; + len1 = len; + } + else + { + *ptr0 = curMatch; + curMatch = pair[0]; + ptr0 = pair; + len0 = len; + } } - } + } + while(--cutValue && cmCheck < curMatch); + + *ptr0 = *ptr1 = kEmptyHashValue; + return d; } + static void SkipMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, - UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue) + size_t _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue) { - CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1; - CLzRef *ptr1 = son + (_cyclicBufferPos << 1); - UInt32 len0 = 0, len1 = 0; - for (;;) + CLzRef *ptr0 = son + ((size_t)_cyclicBufferPos << 1) + 1; + CLzRef *ptr1 = son + ((size_t)_cyclicBufferPos << 1); + unsigned len0 = 0, len1 = 0; + + UInt32 cmCheck; + + cmCheck = (UInt32)(pos - _cyclicBufferSize); + if ((UInt32)pos <= _cyclicBufferSize) + cmCheck = 0; + + if (// curMatch >= pos || // failure + cmCheck < curMatch) + do + { + const UInt32 delta = pos - curMatch; { - UInt32 delta = pos - curMatch; - if (cutValue-- == 0 || delta >= _cyclicBufferSize) + CLzRef *pair = son + ((size_t)(_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1); + const Byte *pb = cur - delta; + unsigned len = (len0 < len1 ? len0 : len1); + if (pb[len] == cur[len]) + { + while (++len != lenLimit) + if (pb[len] != cur[len]) + break; { - *ptr0 = *ptr1 = kEmptyHashValue; + if (len == lenLimit) + { + *ptr1 = pair[0]; + *ptr0 = pair[1]; return; + } } - { - CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1); - const Byte *pb = cur - delta; - UInt32 len = (len0 < len1 ? len0 : len1); - if (pb[len] == cur[len]) - { - while (++len != lenLimit) - if (pb[len] != cur[len]) - break; - { - if (len == lenLimit) - { - *ptr1 = pair[0]; - *ptr0 = pair[1]; - return; - } - } - } - if (pb[len] < cur[len]) - { - *ptr1 = curMatch; - ptr1 = pair + 1; - curMatch = *ptr1; - len1 = len; - } - else - { - *ptr0 = curMatch; - ptr0 = pair; - curMatch = *ptr0; - len0 = len; - } - } + } + if (pb[len] < cur[len]) + { + *ptr1 = curMatch; + curMatch = pair[1]; + ptr1 = pair + 1; + len1 = len; + } + else + { + *ptr0 = curMatch; + curMatch = pair[0]; + ptr0 = pair; + len0 = len; + } } + } + while(--cutValue && cmCheck < curMatch); + + *ptr0 = *ptr1 = kEmptyHashValue; + return; } + #define MOVE_POS \ - ++p->cyclicBufferPos; \ + p->cyclicBufferPos++; \ p->buffer++; \ - if (++p->pos == p->posLimit) MatchFinder_CheckLimits(p); + { const UInt32 pos1 = p->pos + 1; \ + p->pos = pos1; \ + if (pos1 == p->posLimit) MatchFinder_CheckLimits(p); } -#define MOVE_POS_RET MOVE_POS return offset; +#define MOVE_POS_RET MOVE_POS return distances; -static void MatchFinder_MovePos(CMatchFinder *p) { MOVE_POS; } +Z7_NO_INLINE +static void MatchFinder_MovePos(CMatchFinder *p) +{ + /* we go here at the end of stream data, when (avail < num_hash_bytes) + We don't update sons[cyclicBufferPos << btMode]. + So (sons) record will contain junk. And we cannot resume match searching + to normal operation, even if we will provide more input data in buffer. + p->sons[p->cyclicBufferPos << p->btMode] = 0; // kEmptyHashValue + if (p->btMode) + p->sons[(p->cyclicBufferPos << p->btMode) + 1] = 0; // kEmptyHashValue + */ + MOVE_POS +} #define GET_MATCHES_HEADER2(minLen, ret_op) \ - UInt32 lenLimit; UInt32 hashValue; const Byte *cur; UInt32 curMatch; \ - lenLimit = p->lenLimit; { if (lenLimit < minLen) { MatchFinder_MovePos(p); ret_op; }} \ + UInt32 hv; const Byte *cur; UInt32 curMatch; \ + UInt32 lenLimit = p->lenLimit; \ + if (lenLimit < minLen) { MatchFinder_MovePos(p); ret_op; } \ cur = p->buffer; -#define GET_MATCHES_HEADER(minLen) GET_MATCHES_HEADER2(minLen, return 0) -#define SKIP_HEADER(minLen) GET_MATCHES_HEADER2(minLen, continue) +#define GET_MATCHES_HEADER(minLen) GET_MATCHES_HEADER2(minLen, return distances) +#define SKIP_HEADER(minLen) \ + do { GET_MATCHES_HEADER2(minLen, continue) -#define MF_PARAMS(p) p->pos, p->buffer, p->son, p->cyclicBufferPos, p->cyclicBufferSize, p->cutValue +#define MF_PARAMS(p) lenLimit, curMatch, p->pos, p->buffer, p->son, \ + p->cyclicBufferPos, p->cyclicBufferSize, p->cutValue -#define GET_MATCHES_FOOTER(offset, maxLen) \ - offset = (UInt32)(GetMatchesSpec1(lenLimit, curMatch, MF_PARAMS(p), \ - distances + offset, maxLen) - distances); MOVE_POS_RET; +#define SKIP_FOOTER \ + SkipMatchesSpec(MF_PARAMS(p)); \ + MOVE_POS \ + } while (--num); -#define SKIP_FOOTER \ - SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); MOVE_POS; +#define GET_MATCHES_FOOTER_BASE(_maxLen_, func) \ + distances = func(MF_PARAMS(p), distances, (UInt32)_maxLen_); \ + MOVE_POS_RET -static UInt32 Bt2_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) +#define GET_MATCHES_FOOTER_BT(_maxLen_) \ + GET_MATCHES_FOOTER_BASE(_maxLen_, GetMatchesSpec1) + +#define GET_MATCHES_FOOTER_HC(_maxLen_) \ + GET_MATCHES_FOOTER_BASE(_maxLen_, Hc_GetMatchesSpec) + + + +#define UPDATE_maxLen { \ + const ptrdiff_t diff = (ptrdiff_t)0 - (ptrdiff_t)d2; \ + const Byte *c = cur + maxLen; \ + const Byte *lim = cur + lenLimit; \ + for (; c != lim; c++) if (*(c + diff) != *c) break; \ + maxLen = (unsigned)(c - cur); } + +static UInt32* Bt2_MatchFinder_GetMatches(void *_p, UInt32 *distances) { - UInt32 offset; - GET_MATCHES_HEADER(2) - HASH2_CALC; - curMatch = p->hash[hashValue]; - p->hash[hashValue] = p->pos; - offset = 0; - GET_MATCHES_FOOTER(offset, 1) + CMatchFinder *p = (CMatchFinder *)_p; + GET_MATCHES_HEADER(2) + HASH2_CALC + curMatch = p->hash[hv]; + p->hash[hv] = p->pos; + GET_MATCHES_FOOTER_BT(1) } -UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) +UInt32* Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) { - UInt32 offset; - GET_MATCHES_HEADER(3) - HASH_ZIP_CALC; - curMatch = p->hash[hashValue]; - p->hash[hashValue] = p->pos; - offset = 0; - GET_MATCHES_FOOTER(offset, 2) + GET_MATCHES_HEADER(3) + HASH_ZIP_CALC + curMatch = p->hash[hv]; + p->hash[hv] = p->pos; + GET_MATCHES_FOOTER_BT(2) } -static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) + +#define SET_mmm \ + mmm = p->cyclicBufferSize; \ + if (pos < mmm) \ + mmm = pos; + + +static UInt32* Bt3_MatchFinder_GetMatches(void *_p, UInt32 *distances) { - UInt32 hash2Value, delta2, maxLen, offset; - GET_MATCHES_HEADER(3) + CMatchFinder *p = (CMatchFinder *)_p; + UInt32 mmm; + UInt32 h2, d2, pos; + unsigned maxLen; + UInt32 *hash; + GET_MATCHES_HEADER(3) - HASH3_CALC; + HASH3_CALC - delta2 = p->pos - p->hash[hash2Value]; - curMatch = p->hash[kFix3HashSize + hashValue]; + hash = p->hash; + pos = p->pos; - p->hash[hash2Value] = - p->hash[kFix3HashSize + hashValue] = p->pos; + d2 = pos - hash[h2]; - maxLen = 2; - offset = 0; - if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur) + curMatch = (hash + kFix3HashSize)[hv]; + + hash[h2] = pos; + (hash + kFix3HashSize)[hv] = pos; + + SET_mmm + + maxLen = 2; + + if (d2 < mmm && *(cur - d2) == *cur) + { + UPDATE_maxLen + distances[0] = (UInt32)maxLen; + distances[1] = d2 - 1; + distances += 2; + if (maxLen == lenLimit) { - for (; maxLen != lenLimit; maxLen++) - if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen]) - break; - distances[0] = maxLen; - distances[1] = delta2 - 1; - offset = 2; - if (maxLen == lenLimit) - { - SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); - MOVE_POS_RET; - } + SkipMatchesSpec(MF_PARAMS(p)); + MOVE_POS_RET } - GET_MATCHES_FOOTER(offset, maxLen) + } + + GET_MATCHES_FOOTER_BT(maxLen) } -static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) + +static UInt32* Bt4_MatchFinder_GetMatches(void *_p, UInt32 *distances) { - UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset; - GET_MATCHES_HEADER(4) + CMatchFinder *p = (CMatchFinder *)_p; + UInt32 mmm; + UInt32 h2, h3, d2, d3, pos; + unsigned maxLen; + UInt32 *hash; + GET_MATCHES_HEADER(4) - HASH4_CALC; + HASH4_CALC - delta2 = p->pos - p->hash[hash2Value]; - delta3 = p->pos - p->hash[kFix3HashSize + hash3Value]; - curMatch = p->hash[kFix4HashSize + hashValue]; + hash = p->hash; + pos = p->pos; - p->hash[hash2Value] = - p->hash[kFix3HashSize + hash3Value] = - p->hash[kFix4HashSize + hashValue] = p->pos; + d2 = pos - hash [h2]; + d3 = pos - (hash + kFix3HashSize)[h3]; + curMatch = (hash + kFix4HashSize)[hv]; - maxLen = 1; - offset = 0; - if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur) + hash [h2] = pos; + (hash + kFix3HashSize)[h3] = pos; + (hash + kFix4HashSize)[hv] = pos; + + SET_mmm + + maxLen = 3; + + for (;;) + { + if (d2 < mmm && *(cur - d2) == *cur) { - distances[0] = maxLen = 2; - distances[1] = delta2 - 1; - offset = 2; + distances[0] = 2; + distances[1] = d2 - 1; + distances += 2; + if (*(cur - d2 + 2) == cur[2]) + { + // distances[-2] = 3; + } + else if (d3 < mmm && *(cur - d3) == *cur) + { + d2 = d3; + distances[1] = d3 - 1; + distances += 2; + } + else + break; } - if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur) + else if (d3 < mmm && *(cur - d3) == *cur) { - maxLen = 3; - distances[offset + 1] = delta3 - 1; - offset += 2; - delta2 = delta3; + d2 = d3; + distances[1] = d3 - 1; + distances += 2; } - if (offset != 0) + else + break; + + UPDATE_maxLen + distances[-2] = (UInt32)maxLen; + if (maxLen == lenLimit) { - for (; maxLen != lenLimit; maxLen++) - if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen]) - break; - distances[offset - 2] = maxLen; - if (maxLen == lenLimit) - { - SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); - MOVE_POS_RET; - } + SkipMatchesSpec(MF_PARAMS(p)); + MOVE_POS_RET } - if (maxLen < 3) - maxLen = 3; - GET_MATCHES_FOOTER(offset, maxLen) + break; + } + + GET_MATCHES_FOOTER_BT(maxLen) } -static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) + +static UInt32* Bt5_MatchFinder_GetMatches(void *_p, UInt32 *distances) { - UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset; - GET_MATCHES_HEADER(4) + CMatchFinder *p = (CMatchFinder *)_p; + UInt32 mmm; + UInt32 h2, h3, d2, d3, pos; + unsigned maxLen; + UInt32 *hash; + GET_MATCHES_HEADER(5) - HASH4_CALC; + HASH5_CALC - delta2 = p->pos - p->hash[hash2Value]; - delta3 = p->pos - p->hash[kFix3HashSize + hash3Value]; - curMatch = p->hash[kFix4HashSize + hashValue]; + hash = p->hash; + pos = p->pos; - p->hash[hash2Value] = - p->hash[kFix3HashSize + hash3Value] = - p->hash[kFix4HashSize + hashValue] = p->pos; + d2 = pos - hash [h2]; + d3 = pos - (hash + kFix3HashSize)[h3]; + // d4 = pos - (hash + kFix4HashSize)[h4]; - maxLen = 1; - offset = 0; - if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur) + curMatch = (hash + kFix5HashSize)[hv]; + + hash [h2] = pos; + (hash + kFix3HashSize)[h3] = pos; + // (hash + kFix4HashSize)[h4] = pos; + (hash + kFix5HashSize)[hv] = pos; + + SET_mmm + + maxLen = 4; + + for (;;) + { + if (d2 < mmm && *(cur - d2) == *cur) { - distances[0] = maxLen = 2; - distances[1] = delta2 - 1; - offset = 2; + distances[0] = 2; + distances[1] = d2 - 1; + distances += 2; + if (*(cur - d2 + 2) == cur[2]) + { + } + else if (d3 < mmm && *(cur - d3) == *cur) + { + distances[1] = d3 - 1; + distances += 2; + d2 = d3; + } + else + break; } - if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur) + else if (d3 < mmm && *(cur - d3) == *cur) { - maxLen = 3; - distances[offset + 1] = delta3 - 1; - offset += 2; - delta2 = delta3; + distances[1] = d3 - 1; + distances += 2; + d2 = d3; } - if (offset != 0) + else + break; + + distances[-2] = 3; + if (*(cur - d2 + 3) != cur[3]) + break; + UPDATE_maxLen + distances[-2] = (UInt32)maxLen; + if (maxLen == lenLimit) { - for (; maxLen != lenLimit; maxLen++) - if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen]) - break; - distances[offset - 2] = maxLen; - if (maxLen == lenLimit) - { - p->son[p->cyclicBufferPos] = curMatch; - MOVE_POS_RET; - } + SkipMatchesSpec(MF_PARAMS(p)); + MOVE_POS_RET } - if (maxLen < 3) - maxLen = 3; - offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p), - distances + offset, maxLen) - (distances)); - MOVE_POS_RET + break; + } + + GET_MATCHES_FOOTER_BT(maxLen) } -UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) + +static UInt32* Hc4_MatchFinder_GetMatches(void *_p, UInt32 *distances) { - UInt32 offset; - GET_MATCHES_HEADER(3) - HASH_ZIP_CALC; - curMatch = p->hash[hashValue]; - p->hash[hashValue] = p->pos; - offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p), - distances, 2) - (distances)); - MOVE_POS_RET + CMatchFinder *p = (CMatchFinder *)_p; + UInt32 mmm; + UInt32 h2, h3, d2, d3, pos; + unsigned maxLen; + UInt32 *hash; + GET_MATCHES_HEADER(4) + + HASH4_CALC + + hash = p->hash; + pos = p->pos; + + d2 = pos - hash [h2]; + d3 = pos - (hash + kFix3HashSize)[h3]; + curMatch = (hash + kFix4HashSize)[hv]; + + hash [h2] = pos; + (hash + kFix3HashSize)[h3] = pos; + (hash + kFix4HashSize)[hv] = pos; + + SET_mmm + + maxLen = 3; + + for (;;) + { + if (d2 < mmm && *(cur - d2) == *cur) + { + distances[0] = 2; + distances[1] = d2 - 1; + distances += 2; + if (*(cur - d2 + 2) == cur[2]) + { + // distances[-2] = 3; + } + else if (d3 < mmm && *(cur - d3) == *cur) + { + d2 = d3; + distances[1] = d3 - 1; + distances += 2; + } + else + break; + } + else if (d3 < mmm && *(cur - d3) == *cur) + { + d2 = d3; + distances[1] = d3 - 1; + distances += 2; + } + else + break; + + UPDATE_maxLen + distances[-2] = (UInt32)maxLen; + if (maxLen == lenLimit) + { + p->son[p->cyclicBufferPos] = curMatch; + MOVE_POS_RET + } + break; + } + + GET_MATCHES_FOOTER_HC(maxLen) } -static void Bt2_MatchFinder_Skip(CMatchFinder *p, UInt32 num) + +static UInt32 * Hc5_MatchFinder_GetMatches(void *_p, UInt32 *distances) { - do + CMatchFinder *p = (CMatchFinder *)_p; + UInt32 mmm; + UInt32 h2, h3, d2, d3, pos; + unsigned maxLen; + UInt32 *hash; + GET_MATCHES_HEADER(5) + + HASH5_CALC + + hash = p->hash; + pos = p->pos; + + d2 = pos - hash [h2]; + d3 = pos - (hash + kFix3HashSize)[h3]; + // d4 = pos - (hash + kFix4HashSize)[h4]; + + curMatch = (hash + kFix5HashSize)[hv]; + + hash [h2] = pos; + (hash + kFix3HashSize)[h3] = pos; + // (hash + kFix4HashSize)[h4] = pos; + (hash + kFix5HashSize)[hv] = pos; + + SET_mmm + + maxLen = 4; + + for (;;) + { + if (d2 < mmm && *(cur - d2) == *cur) { - SKIP_HEADER(2) - HASH2_CALC; - curMatch = p->hash[hashValue]; - p->hash[hashValue] = p->pos; - SKIP_FOOTER - } while (--num != 0); + distances[0] = 2; + distances[1] = d2 - 1; + distances += 2; + if (*(cur - d2 + 2) == cur[2]) + { + } + else if (d3 < mmm && *(cur - d3) == *cur) + { + distances[1] = d3 - 1; + distances += 2; + d2 = d3; + } + else + break; + } + else if (d3 < mmm && *(cur - d3) == *cur) + { + distances[1] = d3 - 1; + distances += 2; + d2 = d3; + } + else + break; + + distances[-2] = 3; + if (*(cur - d2 + 3) != cur[3]) + break; + UPDATE_maxLen + distances[-2] = (UInt32)maxLen; + if (maxLen == lenLimit) + { + p->son[p->cyclicBufferPos] = curMatch; + MOVE_POS_RET + } + break; + } + + GET_MATCHES_FOOTER_HC(maxLen) +} + + +UInt32* Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) +{ + GET_MATCHES_HEADER(3) + HASH_ZIP_CALC + curMatch = p->hash[hv]; + p->hash[hv] = p->pos; + GET_MATCHES_FOOTER_HC(2) +} + + +static void Bt2_MatchFinder_Skip(void *_p, UInt32 num) +{ + CMatchFinder *p = (CMatchFinder *)_p; + SKIP_HEADER(2) + { + HASH2_CALC + curMatch = p->hash[hv]; + p->hash[hv] = p->pos; + } + SKIP_FOOTER } void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num) { - do - { - SKIP_HEADER(3) - HASH_ZIP_CALC; - curMatch = p->hash[hashValue]; - p->hash[hashValue] = p->pos; - SKIP_FOOTER - } while (--num != 0); + SKIP_HEADER(3) + { + HASH_ZIP_CALC + curMatch = p->hash[hv]; + p->hash[hv] = p->pos; + } + SKIP_FOOTER } -static void Bt3_MatchFinder_Skip(CMatchFinder *p, UInt32 num) +static void Bt3_MatchFinder_Skip(void *_p, UInt32 num) { - do - { - UInt32 hash2Value; - SKIP_HEADER(3) - HASH3_CALC; - curMatch = p->hash[kFix3HashSize + hashValue]; - p->hash[hash2Value] = - p->hash[kFix3HashSize + hashValue] = p->pos; - SKIP_FOOTER - } while (--num != 0); + CMatchFinder *p = (CMatchFinder *)_p; + SKIP_HEADER(3) + { + UInt32 h2; + UInt32 *hash; + HASH3_CALC + hash = p->hash; + curMatch = (hash + kFix3HashSize)[hv]; + hash[h2] = + (hash + kFix3HashSize)[hv] = p->pos; + } + SKIP_FOOTER } -static void Bt4_MatchFinder_Skip(CMatchFinder *p, UInt32 num) +static void Bt4_MatchFinder_Skip(void *_p, UInt32 num) { - do - { - UInt32 hash2Value, hash3Value; - SKIP_HEADER(4) - HASH4_CALC; - curMatch = p->hash[kFix4HashSize + hashValue]; - p->hash[hash2Value] = - p->hash[kFix3HashSize + hash3Value] = p->pos; - p->hash[kFix4HashSize + hashValue] = p->pos; - SKIP_FOOTER - } while (--num != 0); + CMatchFinder *p = (CMatchFinder *)_p; + SKIP_HEADER(4) + { + UInt32 h2, h3; + UInt32 *hash; + HASH4_CALC + hash = p->hash; + curMatch = (hash + kFix4HashSize)[hv]; + hash [h2] = + (hash + kFix3HashSize)[h3] = + (hash + kFix4HashSize)[hv] = p->pos; + } + SKIP_FOOTER } -static void Hc4_MatchFinder_Skip(CMatchFinder *p, UInt32 num) +static void Bt5_MatchFinder_Skip(void *_p, UInt32 num) { - do - { - UInt32 hash2Value, hash3Value; - SKIP_HEADER(4) - HASH4_CALC; - curMatch = p->hash[kFix4HashSize + hashValue]; - p->hash[hash2Value] = - p->hash[kFix3HashSize + hash3Value] = - p->hash[kFix4HashSize + hashValue] = p->pos; - p->son[p->cyclicBufferPos] = curMatch; - MOVE_POS - } while (--num != 0); + CMatchFinder *p = (CMatchFinder *)_p; + SKIP_HEADER(5) + { + UInt32 h2, h3; + UInt32 *hash; + HASH5_CALC + hash = p->hash; + curMatch = (hash + kFix5HashSize)[hv]; + hash [h2] = + (hash + kFix3HashSize)[h3] = + // (hash + kFix4HashSize)[h4] = + (hash + kFix5HashSize)[hv] = p->pos; + } + SKIP_FOOTER } + +#define HC_SKIP_HEADER(minLen) \ + do { if (p->lenLimit < minLen) { MatchFinder_MovePos(p); num--; continue; } { \ + const Byte *cur; \ + UInt32 *hash; \ + UInt32 *son; \ + UInt32 pos = p->pos; \ + UInt32 num2 = num; \ + /* (p->pos == p->posLimit) is not allowed here !!! */ \ + { const UInt32 rem = p->posLimit - pos; if (num2 > rem) num2 = rem; } \ + num -= num2; \ + { const UInt32 cycPos = p->cyclicBufferPos; \ + son = p->son + cycPos; \ + p->cyclicBufferPos = cycPos + num2; } \ + cur = p->buffer; \ + hash = p->hash; \ + do { \ + UInt32 curMatch; \ + UInt32 hv; + + +#define HC_SKIP_FOOTER \ + cur++; pos++; *son++ = curMatch; \ + } while (--num2); \ + p->buffer = cur; \ + p->pos = pos; \ + if (pos == p->posLimit) MatchFinder_CheckLimits(p); \ + }} while(num); \ + + +static void Hc4_MatchFinder_Skip(void *_p, UInt32 num) +{ + CMatchFinder *p = (CMatchFinder *)_p; + HC_SKIP_HEADER(4) + + UInt32 h2, h3; + HASH4_CALC + curMatch = (hash + kFix4HashSize)[hv]; + hash [h2] = + (hash + kFix3HashSize)[h3] = + (hash + kFix4HashSize)[hv] = pos; + + HC_SKIP_FOOTER +} + + +static void Hc5_MatchFinder_Skip(void *_p, UInt32 num) +{ + CMatchFinder *p = (CMatchFinder *)_p; + HC_SKIP_HEADER(5) + + UInt32 h2, h3; + HASH5_CALC + curMatch = (hash + kFix5HashSize)[hv]; + hash [h2] = + (hash + kFix3HashSize)[h3] = + // (hash + kFix4HashSize)[h4] = + (hash + kFix5HashSize)[hv] = pos; + + HC_SKIP_FOOTER +} + + void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num) { - do - { - SKIP_HEADER(3) - HASH_ZIP_CALC; - curMatch = p->hash[hashValue]; - p->hash[hashValue] = p->pos; - p->son[p->cyclicBufferPos] = curMatch; - MOVE_POS - } while (--num != 0); + HC_SKIP_HEADER(3) + + HASH_ZIP_CALC + curMatch = hash[hv]; + hash[hv] = pos; + + HC_SKIP_FOOTER } -void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable) + +void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder2 *vTable) { - vTable->Init = (Mf_Init_Func)MatchFinder_Init; - vTable->GetIndexByte = (Mf_GetIndexByte_Func)MatchFinder_GetIndexByte; - vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinder_GetNumAvailableBytes; - vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinder_GetPointerToCurrentPos; - if (!p->btMode) + vTable->Init = MatchFinder_Init; + vTable->GetNumAvailableBytes = MatchFinder_GetNumAvailableBytes; + vTable->GetPointerToCurrentPos = MatchFinder_GetPointerToCurrentPos; + if (!p->btMode) + { + if (p->numHashBytes <= 4) { - vTable->GetMatches = (Mf_GetMatches_Func)Hc4_MatchFinder_GetMatches; - vTable->Skip = (Mf_Skip_Func)Hc4_MatchFinder_Skip; - } - else if (p->numHashBytes == 2) - { - vTable->GetMatches = (Mf_GetMatches_Func)Bt2_MatchFinder_GetMatches; - vTable->Skip = (Mf_Skip_Func)Bt2_MatchFinder_Skip; - } - else if (p->numHashBytes == 3) - { - vTable->GetMatches = (Mf_GetMatches_Func)Bt3_MatchFinder_GetMatches; - vTable->Skip = (Mf_Skip_Func)Bt3_MatchFinder_Skip; + vTable->GetMatches = Hc4_MatchFinder_GetMatches; + vTable->Skip = Hc4_MatchFinder_Skip; } else { - vTable->GetMatches = (Mf_GetMatches_Func)Bt4_MatchFinder_GetMatches; - vTable->Skip = (Mf_Skip_Func)Bt4_MatchFinder_Skip; + vTable->GetMatches = Hc5_MatchFinder_GetMatches; + vTable->Skip = Hc5_MatchFinder_Skip; } -} \ No newline at end of file + } + else if (p->numHashBytes == 2) + { + vTable->GetMatches = Bt2_MatchFinder_GetMatches; + vTable->Skip = Bt2_MatchFinder_Skip; + } + else if (p->numHashBytes == 3) + { + vTable->GetMatches = Bt3_MatchFinder_GetMatches; + vTable->Skip = Bt3_MatchFinder_Skip; + } + else if (p->numHashBytes == 4) + { + vTable->GetMatches = Bt4_MatchFinder_GetMatches; + vTable->Skip = Bt4_MatchFinder_Skip; + } + else + { + vTable->GetMatches = Bt5_MatchFinder_GetMatches; + vTable->Skip = Bt5_MatchFinder_Skip; + } +} + + + +void LzFindPrepare(void) +{ + #ifndef FORCE_LZFIND_SATUR_SUB_128 + #ifdef USE_LZFIND_SATUR_SUB_128 + LZFIND_SATUR_SUB_CODE_FUNC f = NULL; + #ifdef MY_CPU_ARM_OR_ARM64 + { + if (CPU_IsSupported_NEON()) + { + // #pragma message ("=== LzFind NEON") + PRF(printf("\n=== LzFind NEON\n")); + f = LzFind_SaturSub_128; + } + // f = 0; // for debug + } + #else // MY_CPU_ARM_OR_ARM64 + if (CPU_IsSupported_SSE41()) + { + // #pragma message ("=== LzFind SSE41") + PRF(printf("\n=== LzFind SSE41\n")); + f = LzFind_SaturSub_128; + + #ifdef USE_LZFIND_SATUR_SUB_256 + if (CPU_IsSupported_AVX2()) + { + // #pragma message ("=== LzFind AVX2") + PRF(printf("\n=== LzFind AVX2\n")); + f = LzFind_SaturSub_256; + } + #endif + } + #endif // MY_CPU_ARM_OR_ARM64 + g_LzFind_SaturSub = f; + #endif // USE_LZFIND_SATUR_SUB_128 + #endif // FORCE_LZFIND_SATUR_SUB_128 +} + + +#undef MOVE_POS +#undef MOVE_POS_RET +#undef PRF diff --git a/common/LZMA/SDK/C/LzFind.h b/common/LZMA/SDK/C/LzFind.h index 010c4b9..67e8a6e 100644 --- a/common/LZMA/SDK/C/LzFind.h +++ b/common/LZMA/SDK/C/LzFind.h @@ -1,80 +1,121 @@ /* LzFind.h -- Match finder for LZ algorithms -2009-04-22 : Igor Pavlov : Public domain */ +2024-01-22 : Igor Pavlov : Public domain */ -#ifndef __LZ_FIND_H -#define __LZ_FIND_H +#ifndef ZIP7_INC_LZ_FIND_H +#define ZIP7_INC_LZ_FIND_H -#include "Types.h" +#include "7zTypes.h" -#ifdef __cplusplus -extern "C" { -#endif +EXTERN_C_BEGIN typedef UInt32 CLzRef; -typedef struct _CMatchFinder +typedef struct { - Byte *buffer; + const Byte *buffer; UInt32 pos; UInt32 posLimit; - UInt32 streamPos; + UInt32 streamPos; /* wrap over Zero is allowed (streamPos < pos). Use (UInt32)(streamPos - pos) */ UInt32 lenLimit; UInt32 cyclicBufferPos; UInt32 cyclicBufferSize; /* it must be = (historySize + 1) */ + Byte streamEndWasReached; + Byte btMode; + Byte bigHash; + Byte directInput; + UInt32 matchMaxLen; CLzRef *hash; CLzRef *son; UInt32 hashMask; UInt32 cutValue; - Byte *bufferBase; - ISeqInStream *stream; - int streamEndWasReached; - + Byte *bufBase; + ISeqInStreamPtr stream; + UInt32 blockSize; UInt32 keepSizeBefore; UInt32 keepSizeAfter; UInt32 numHashBytes; - int directInput; size_t directInputRem; - int btMode; - int bigHash; UInt32 historySize; UInt32 fixedHashSize; - UInt32 hashSizeSum; - UInt32 numSons; + Byte numHashBytes_Min; + Byte numHashOutBits; + Byte _pad2_[2]; SRes result; UInt32 crc[256]; + size_t numRefs; + + UInt64 expectedDataSize; } CMatchFinder; -#define Inline_MatchFinder_GetPointerToCurrentPos(p) ((p)->buffer) -#define Inline_MatchFinder_GetIndexByte(p, index) ((p)->buffer[(Int32)(index)]) +#define Inline_MatchFinder_GetPointerToCurrentPos(p) ((const Byte *)(p)->buffer) -#define Inline_MatchFinder_GetNumAvailableBytes(p) ((p)->streamPos - (p)->pos) +#define Inline_MatchFinder_GetNumAvailableBytes(p) ((UInt32)((p)->streamPos - (p)->pos)) +/* +#define Inline_MatchFinder_IsFinishedOK(p) \ + ((p)->streamEndWasReached \ + && (p)->streamPos == (p)->pos \ + && (!(p)->directInput || (p)->directInputRem == 0)) +*/ + int MatchFinder_NeedMove(CMatchFinder *p); -Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p); +/* Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p); */ void MatchFinder_MoveBlock(CMatchFinder *p); void MatchFinder_ReadIfRequired(CMatchFinder *p); void MatchFinder_Construct(CMatchFinder *p); -/* Conditions: - historySize <= 3 GB - keepAddBufferBefore + matchMaxLen + keepAddBufferAfter < 511MB +/* (directInput = 0) is default value. + It's required to provide correct (directInput) value + before calling MatchFinder_Create(). + You can set (directInput) by any of the following calls: + - MatchFinder_SET_DIRECT_INPUT_BUF() + - MatchFinder_SET_STREAM() + - MatchFinder_SET_STREAM_MODE() */ + +#define MatchFinder_SET_DIRECT_INPUT_BUF(p, _src_, _srcLen_) { \ + (p)->stream = NULL; \ + (p)->directInput = 1; \ + (p)->buffer = (_src_); \ + (p)->directInputRem = (_srcLen_); } + +/* +#define MatchFinder_SET_STREAM_MODE(p) { \ + (p)->directInput = 0; } +*/ + +#define MatchFinder_SET_STREAM(p, _stream_) { \ + (p)->stream = _stream_; \ + (p)->directInput = 0; } + + int MatchFinder_Create(CMatchFinder *p, UInt32 historySize, UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter, - ISzAlloc *alloc); -void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc); -void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems); -void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue); + ISzAllocPtr alloc); +void MatchFinder_Free(CMatchFinder *p, ISzAllocPtr alloc); +void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, size_t numItems); + +/* +#define MatchFinder_INIT_POS(p, val) \ + (p)->pos = (val); \ + (p)->streamPos = (val); +*/ + +// void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue); +#define MatchFinder_REDUCE_OFFSETS(p, subValue) \ + (p)->pos -= (subValue); \ + (p)->streamPos -= (subValue); + UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *buffer, CLzRef *son, - UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue, + size_t _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue, UInt32 *distances, UInt32 maxLen); /* @@ -84,32 +125,36 @@ Conditions: */ typedef void (*Mf_Init_Func)(void *object); -typedef Byte (*Mf_GetIndexByte_Func)(void *object, Int32 index); typedef UInt32 (*Mf_GetNumAvailableBytes_Func)(void *object); typedef const Byte * (*Mf_GetPointerToCurrentPos_Func)(void *object); -typedef UInt32 (*Mf_GetMatches_Func)(void *object, UInt32 *distances); +typedef UInt32 * (*Mf_GetMatches_Func)(void *object, UInt32 *distances); typedef void (*Mf_Skip_Func)(void *object, UInt32); -typedef struct _IMatchFinder +typedef struct { Mf_Init_Func Init; - Mf_GetIndexByte_Func GetIndexByte; Mf_GetNumAvailableBytes_Func GetNumAvailableBytes; Mf_GetPointerToCurrentPos_Func GetPointerToCurrentPos; Mf_GetMatches_Func GetMatches; Mf_Skip_Func Skip; -} IMatchFinder; +} IMatchFinder2; -void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable); +void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder2 *vTable); + +void MatchFinder_Init_LowHash(CMatchFinder *p); +void MatchFinder_Init_HighHash(CMatchFinder *p); +void MatchFinder_Init_4(CMatchFinder *p); +// void MatchFinder_Init(CMatchFinder *p); +void MatchFinder_Init(void *p); + +UInt32* Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances); +UInt32* Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances); -void MatchFinder_Init(CMatchFinder *p); -UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances); -UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances); void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num); void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num); -#ifdef __cplusplus -} -#endif +void LzFindPrepare(void); + +EXTERN_C_END #endif diff --git a/common/LZMA/SDK/C/LzHash.h b/common/LZMA/SDK/C/LzHash.h index f3e8996..2b6290b 100644 --- a/common/LZMA/SDK/C/LzHash.h +++ b/common/LZMA/SDK/C/LzHash.h @@ -1,54 +1,34 @@ -/* LzHash.h -- HASH functions for LZ algorithms -2009-02-07 : Igor Pavlov : Public domain */ +/* LzHash.h -- HASH constants for LZ algorithms +2023-03-05 : Igor Pavlov : Public domain */ -#ifndef __LZ_HASH_H -#define __LZ_HASH_H +#ifndef ZIP7_INC_LZ_HASH_H +#define ZIP7_INC_LZ_HASH_H + +/* + (kHash2Size >= (1 << 8)) : Required + (kHash3Size >= (1 << 16)) : Required +*/ #define kHash2Size (1 << 10) #define kHash3Size (1 << 16) -#define kHash4Size (1 << 20) +// #define kHash4Size (1 << 20) #define kFix3HashSize (kHash2Size) #define kFix4HashSize (kHash2Size + kHash3Size) -#define kFix5HashSize (kHash2Size + kHash3Size + kHash4Size) +// #define kFix5HashSize (kHash2Size + kHash3Size + kHash4Size) -#define HASH2_CALC hashValue = cur[0] | ((UInt32)cur[1] << 8); +/* + We use up to 3 crc values for hash: + crc0 + crc1 << Shift_1 + crc2 << Shift_2 + (Shift_1 = 5) and (Shift_2 = 10) is good tradeoff. + Small values for Shift are not good for collision rate. + Big value for Shift_2 increases the minimum size + of hash table, that will be slow for small files. +*/ -#define HASH3_CALC { \ - UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ - hash2Value = temp & (kHash2Size - 1); \ - hashValue = (temp ^ ((UInt32)cur[2] << 8)) & p->hashMask; } - -#define HASH4_CALC { \ - UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ - hash2Value = temp & (kHash2Size - 1); \ - hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \ - hashValue = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & p->hashMask; } - -#define HASH5_CALC { \ - UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ - hash2Value = temp & (kHash2Size - 1); \ - hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \ - hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)); \ - hashValue = (hash4Value ^ (p->crc[cur[4]] << 3)) & p->hashMask; \ - hash4Value &= (kHash4Size - 1); } - -/* #define HASH_ZIP_CALC hashValue = ((cur[0] | ((UInt32)cur[1] << 8)) ^ p->crc[cur[2]]) & 0xFFFF; */ -#define HASH_ZIP_CALC hashValue = ((cur[2] | ((UInt32)cur[0] << 8)) ^ p->crc[cur[1]]) & 0xFFFF; - - -#define MT_HASH2_CALC \ - hash2Value = (p->crc[cur[0]] ^ cur[1]) & (kHash2Size - 1); - -#define MT_HASH3_CALC { \ - UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ - hash2Value = temp & (kHash2Size - 1); \ - hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); } - -#define MT_HASH4_CALC { \ - UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ - hash2Value = temp & (kHash2Size - 1); \ - hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \ - hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & (kHash4Size - 1); } +#define kLzHash_CrcShift_1 5 +#define kLzHash_CrcShift_2 10 #endif diff --git a/common/LZMA/SDK/C/LzmaDec.c b/common/LZMA/SDK/C/LzmaDec.c index 9be3eec..69bb8bb 100644 --- a/common/LZMA/SDK/C/LzmaDec.c +++ b/common/LZMA/SDK/C/LzmaDec.c @@ -1,79 +1,107 @@ /* LzmaDec.c -- LZMA Decoder -2009-09-20 : Igor Pavlov : Public domain*/ +2023-04-07 : Igor Pavlov : Public domain */ -#include "LzmaDec.h" +#include "Precomp.h" #include -#define kNumTopBits 24 -#define kTopValue ((UInt32)1 << kNumTopBits) +/* #include "CpuArch.h" */ +#include "LzmaDec.h" + +// #define kNumTopBits 24 +#define kTopValue ((UInt32)1 << 24) #define kNumBitModelTotalBits 11 #define kBitModelTotal (1 << kNumBitModelTotalBits) -#define kNumMoveBits 5 #define RC_INIT_SIZE 5 +#ifndef Z7_LZMA_DEC_OPT + +#define kNumMoveBits 5 #define NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | (*buf++); } -#define IF_BIT_0(p) ttt = *(p); NORMALIZE; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound) +#define IF_BIT_0(p) ttt = *(p); NORMALIZE; bound = (range >> kNumBitModelTotalBits) * (UInt32)ttt; if (code < bound) #define UPDATE_0(p) range = bound; *(p) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); #define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits)); #define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \ - { UPDATE_0(p); i = (i + i); A0; } else \ - { UPDATE_1(p); i = (i + i) + 1; A1; } -#define GET_BIT(p, i) GET_BIT2(p, i, ; , ;) + { UPDATE_0(p) i = (i + i); A0; } else \ + { UPDATE_1(p) i = (i + i) + 1; A1; } + +#define TREE_GET_BIT(probs, i) { GET_BIT2(probs + i, i, ;, ;); } + +#define REV_BIT(p, i, A0, A1) IF_BIT_0(p + i) \ + { UPDATE_0(p + i) A0; } else \ + { UPDATE_1(p + i) A1; } +#define REV_BIT_VAR( p, i, m) REV_BIT(p, i, i += m; m += m, m += m; i += m; ) +#define REV_BIT_CONST(p, i, m) REV_BIT(p, i, i += m; , i += m * 2; ) +#define REV_BIT_LAST( p, i, m) REV_BIT(p, i, i -= m , ; ) -#define TREE_GET_BIT(probs, i) { GET_BIT((probs + i), i); } #define TREE_DECODE(probs, limit, i) \ - { i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; } + { i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; } -/* #define _LZMA_SIZE_OPT */ +/* #define Z7_LZMA_SIZE_OPT */ -#ifdef _LZMA_SIZE_OPT +#ifdef Z7_LZMA_SIZE_OPT #define TREE_6_DECODE(probs, i) TREE_DECODE(probs, (1 << 6), i) #else #define TREE_6_DECODE(probs, i) \ - { i = 1; \ - TREE_GET_BIT(probs, i); \ - TREE_GET_BIT(probs, i); \ - TREE_GET_BIT(probs, i); \ - TREE_GET_BIT(probs, i); \ - TREE_GET_BIT(probs, i); \ - TREE_GET_BIT(probs, i); \ + { i = 1; \ + TREE_GET_BIT(probs, i) \ + TREE_GET_BIT(probs, i) \ + TREE_GET_BIT(probs, i) \ + TREE_GET_BIT(probs, i) \ + TREE_GET_BIT(probs, i) \ + TREE_GET_BIT(probs, i) \ i -= 0x40; } #endif -#define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); } +#define NORMAL_LITER_DEC TREE_GET_BIT(prob, symbol) +#define MATCHED_LITER_DEC \ + matchByte += matchByte; \ + bit = offs; \ + offs &= matchByte; \ + probLit = prob + (offs + bit + symbol); \ + GET_BIT2(probLit, symbol, offs ^= bit; , ;) -#define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound) +#endif // Z7_LZMA_DEC_OPT + + +#define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_INPUT_EOF; range <<= 8; code = (code << 8) | (*buf++); } + +#define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK bound = (range >> kNumBitModelTotalBits) * (UInt32)ttt; if (code < bound) #define UPDATE_0_CHECK range = bound; #define UPDATE_1_CHECK range -= bound; code -= bound; #define GET_BIT2_CHECK(p, i, A0, A1) IF_BIT_0_CHECK(p) \ - { UPDATE_0_CHECK; i = (i + i); A0; } else \ - { UPDATE_1_CHECK; i = (i + i) + 1; A1; } + { UPDATE_0_CHECK i = (i + i); A0; } else \ + { UPDATE_1_CHECK i = (i + i) + 1; A1; } #define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ; , ;) #define TREE_DECODE_CHECK(probs, limit, i) \ - { i = 1; do { GET_BIT_CHECK(probs + i, i) } while (i < limit); i -= limit; } + { i = 1; do { GET_BIT_CHECK(probs + i, i) } while (i < limit); i -= limit; } + + +#define REV_BIT_CHECK(p, i, m) IF_BIT_0_CHECK(p + i) \ + { UPDATE_0_CHECK i += m; m += m; } else \ + { UPDATE_1_CHECK m += m; i += m; } + #define kNumPosBitsMax 4 #define kNumPosStatesMax (1 << kNumPosBitsMax) #define kLenNumLowBits 3 #define kLenNumLowSymbols (1 << kLenNumLowBits) -#define kLenNumMidBits 3 -#define kLenNumMidSymbols (1 << kLenNumMidBits) #define kLenNumHighBits 8 #define kLenNumHighSymbols (1 << kLenNumHighBits) -#define LenChoice 0 -#define LenChoice2 (LenChoice + 1) -#define LenLow (LenChoice2 + 1) -#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits)) -#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits)) +#define LenLow 0 +#define LenHigh (LenLow + 2 * (kNumPosStatesMax << kLenNumLowBits)) #define kNumLenProbs (LenHigh + kLenNumHighSymbols) +#define LenChoice LenLow +#define LenChoice2 (LenLow + (1 << kLenNumLowBits)) + #define kNumStates 12 +#define kNumStates2 16 #define kNumLitStates 7 #define kStartPosModelIndex 4 @@ -87,901 +115,1249 @@ #define kAlignTableSize (1 << kNumAlignBits) #define kMatchMinLen 2 -#define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols) +#define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols * 2 + kLenNumHighSymbols) -#define IsMatch 0 -#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax)) +#define kMatchSpecLen_Error_Data (1 << 9) +#define kMatchSpecLen_Error_Fail (kMatchSpecLen_Error_Data - 1) + +/* External ASM code needs same CLzmaProb array layout. So don't change it. */ + +/* (probs_1664) is faster and better for code size at some platforms */ +/* +#ifdef MY_CPU_X86_OR_AMD64 +*/ +#define kStartOffset 1664 +#define GET_PROBS p->probs_1664 +/* +#define GET_PROBS p->probs + kStartOffset +#else +#define kStartOffset 0 +#define GET_PROBS p->probs +#endif +*/ + +#define SpecPos (-kStartOffset) +#define IsRep0Long (SpecPos + kNumFullDistances) +#define RepLenCoder (IsRep0Long + (kNumStates2 << kNumPosBitsMax)) +#define LenCoder (RepLenCoder + kNumLenProbs) +#define IsMatch (LenCoder + kNumLenProbs) +#define Align (IsMatch + (kNumStates2 << kNumPosBitsMax)) +#define IsRep (Align + kAlignTableSize) #define IsRepG0 (IsRep + kNumStates) #define IsRepG1 (IsRepG0 + kNumStates) #define IsRepG2 (IsRepG1 + kNumStates) -#define IsRep0Long (IsRepG2 + kNumStates) -#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax)) -#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits)) -#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex) -#define LenCoder (Align + kAlignTableSize) -#define RepLenCoder (LenCoder + kNumLenProbs) -#define Literal (RepLenCoder + kNumLenProbs) +#define PosSlot (IsRepG2 + kNumStates) +#define Literal (PosSlot + (kNumLenToPosStates << kNumPosSlotBits)) +#define NUM_BASE_PROBS (Literal + kStartOffset) -#define LZMA_BASE_SIZE 1846 -#define LZMA_LIT_SIZE 768 - -#define LzmaProps_GetNumProbs(p) ((UInt32)LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((p)->lc + (p)->lp))) - -#if Literal != LZMA_BASE_SIZE -StopCompilingDueBUG +#if Align != 0 && kStartOffset != 0 + #error Stop_Compiling_Bad_LZMA_kAlign #endif +#if NUM_BASE_PROBS != 1984 + #error Stop_Compiling_Bad_LZMA_PROBS +#endif + + +#define LZMA_LIT_SIZE 0x300 + +#define LzmaProps_GetNumProbs(p) (NUM_BASE_PROBS + ((UInt32)LZMA_LIT_SIZE << ((p)->lc + (p)->lp))) + + +#define CALC_POS_STATE(processedPos, pbMask) (((processedPos) & (pbMask)) << 4) +#define COMBINED_PS_STATE (posState + state) +#define GET_LEN_STATE (posState) + #define LZMA_DIC_MIN (1 << 12) -/* First LZMA-symbol is always decoded. -And it decodes new LZMA-symbols while (buf < bufLimit), but "buf" is with last normalization -Out: -Result: -SZ_OK - OK -SZ_ERROR_DATA - Error -p->remainLen: -< kMatchSpecLenStart : normal remain -= kMatchSpecLenStart : finished -= kMatchSpecLenStart + 1 : Flush marker -= kMatchSpecLenStart + 2 : State Init Marker +/* +p->remainLen : shows status of LZMA decoder: + < kMatchSpecLenStart : the number of bytes to be copied with (p->rep0) offset + = kMatchSpecLenStart : the LZMA stream was finished with end mark + = kMatchSpecLenStart + 1 : need init range coder + = kMatchSpecLenStart + 2 : need init range coder and state + = kMatchSpecLen_Error_Fail : Internal Code Failure + = kMatchSpecLen_Error_Data + [0 ... 273] : LZMA Data Error */ -static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte *bufLimit) +/* ---------- LZMA_DECODE_REAL ---------- */ +/* +LzmaDec_DecodeReal_3() can be implemented in external ASM file. +3 - is the code compatibility version of that function for check at link time. +*/ + +#define LZMA_DECODE_REAL LzmaDec_DecodeReal_3 + +/* +LZMA_DECODE_REAL() +In: + RangeCoder is normalized + if (p->dicPos == limit) + { + LzmaDec_TryDummy() was called before to exclude LITERAL and MATCH-REP cases. + So first symbol can be only MATCH-NON-REP. And if that MATCH-NON-REP symbol + is not END_OF_PAYALOAD_MARKER, then the function doesn't write any byte to dictionary, + the function returns SZ_OK, and the caller can use (p->remainLen) and (p->reps[0]) later. + } + +Processing: + The first LZMA symbol will be decoded in any case. + All main checks for limits are at the end of main loop, + It decodes additional LZMA-symbols while (p->buf < bufLimit && dicPos < limit), + RangeCoder is still without last normalization when (p->buf < bufLimit) is being checked. + But if (p->buf < bufLimit), the caller provided at least (LZMA_REQUIRED_INPUT_MAX + 1) bytes for + next iteration before limit (bufLimit + LZMA_REQUIRED_INPUT_MAX), + that is enough for worst case LZMA symbol with one additional RangeCoder normalization for one bit. + So that function never reads bufLimit [LZMA_REQUIRED_INPUT_MAX] byte. + +Out: + RangeCoder is normalized + Result: + SZ_OK - OK + p->remainLen: + < kMatchSpecLenStart : the number of bytes to be copied with (p->reps[0]) offset + = kMatchSpecLenStart : the LZMA stream was finished with end mark + + SZ_ERROR_DATA - error, when the MATCH-Symbol refers out of dictionary + p->remainLen : undefined + p->reps[*] : undefined +*/ + + +#ifdef Z7_LZMA_DEC_OPT + +int Z7_FASTCALL LZMA_DECODE_REAL(CLzmaDec *p, SizeT limit, const Byte *bufLimit); + +#else + +static +int Z7_FASTCALL LZMA_DECODE_REAL(CLzmaDec *p, SizeT limit, const Byte *bufLimit) { - CLzmaProb *probs = p->probs; + CLzmaProb *probs = GET_PROBS; + unsigned state = (unsigned)p->state; + UInt32 rep0 = p->reps[0], rep1 = p->reps[1], rep2 = p->reps[2], rep3 = p->reps[3]; + unsigned pbMask = ((unsigned)1 << (p->prop.pb)) - 1; + unsigned lc = p->prop.lc; + unsigned lpMask = ((unsigned)0x100 << p->prop.lp) - ((unsigned)0x100 >> lc); - unsigned state = p->state; - UInt32 rep0 = p->reps[0], rep1 = p->reps[1], rep2 = p->reps[2], rep3 = p->reps[3]; - unsigned pbMask = ((unsigned)1 << (p->prop.pb)) - 1; - unsigned lpMask = ((unsigned)1 << (p->prop.lp)) - 1; - unsigned lc = p->prop.lc; + Byte *dic = p->dic; + SizeT dicBufSize = p->dicBufSize; + SizeT dicPos = p->dicPos; + + UInt32 processedPos = p->processedPos; + UInt32 checkDicSize = p->checkDicSize; + unsigned len = 0; - Byte *dic = p->dic; - SizeT dicBufSize = p->dicBufSize; - SizeT dicPos = p->dicPos; + const Byte *buf = p->buf; + UInt32 range = p->range; + UInt32 code = p->code; - UInt32 processedPos = p->processedPos; - UInt32 checkDicSize = p->checkDicSize; - unsigned len = 0; + do + { + CLzmaProb *prob; + UInt32 bound; + unsigned ttt; + unsigned posState = CALC_POS_STATE(processedPos, pbMask); - const Byte *buf = p->buf; - UInt32 range = p->range; - UInt32 code = p->code; - - do - { - CLzmaProb *prob; - UInt32 bound; - unsigned ttt; - unsigned posState = processedPos & pbMask; - - prob = probs + IsMatch + (state << kNumPosBitsMax) + posState; - IF_BIT_0(prob) - { - unsigned symbol; - UPDATE_0(prob); - prob = probs + Literal; - if (checkDicSize != 0 || processedPos != 0) - prob += (LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) + - (dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc)))); - - if (state < kNumLitStates) - { - state -= (state < 4) ? state : 3; - symbol = 1; - do { GET_BIT(prob + symbol, symbol) } while (symbol < 0x100); - } - else - { - unsigned matchByte = p->dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; - unsigned offs = 0x100; - state -= (state < 10) ? 3 : 6; - symbol = 1; - do - { - unsigned bit; - CLzmaProb *probLit; - matchByte <<= 1; - bit = (matchByte & offs); - probLit = prob + offs + bit + symbol; - GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit) - } while (symbol < 0x100); - } - dic[dicPos++] = (Byte)symbol; - processedPos++; - continue; - } -else -{ - UPDATE_1(prob); - prob = probs + IsRep + state; + prob = probs + IsMatch + COMBINED_PS_STATE; IF_BIT_0(prob) { - UPDATE_0(prob); + unsigned symbol; + UPDATE_0(prob) + prob = probs + Literal; + if (processedPos != 0 || checkDicSize != 0) + prob += (UInt32)3 * ((((processedPos << 8) + dic[(dicPos == 0 ? dicBufSize : dicPos) - 1]) & lpMask) << lc); + processedPos++; + + if (state < kNumLitStates) + { + state -= (state < 4) ? state : 3; + symbol = 1; + #ifdef Z7_LZMA_SIZE_OPT + do { NORMAL_LITER_DEC } while (symbol < 0x100); + #else + NORMAL_LITER_DEC + NORMAL_LITER_DEC + NORMAL_LITER_DEC + NORMAL_LITER_DEC + NORMAL_LITER_DEC + NORMAL_LITER_DEC + NORMAL_LITER_DEC + NORMAL_LITER_DEC + #endif + } + else + { + unsigned matchByte = dic[dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0)]; + unsigned offs = 0x100; + state -= (state < 10) ? 3 : 6; + symbol = 1; + #ifdef Z7_LZMA_SIZE_OPT + do + { + unsigned bit; + CLzmaProb *probLit; + MATCHED_LITER_DEC + } + while (symbol < 0x100); + #else + { + unsigned bit; + CLzmaProb *probLit; + MATCHED_LITER_DEC + MATCHED_LITER_DEC + MATCHED_LITER_DEC + MATCHED_LITER_DEC + MATCHED_LITER_DEC + MATCHED_LITER_DEC + MATCHED_LITER_DEC + MATCHED_LITER_DEC + } + #endif + } + + dic[dicPos++] = (Byte)symbol; + continue; + } + + { + UPDATE_1(prob) + prob = probs + IsRep + state; + IF_BIT_0(prob) + { + UPDATE_0(prob) state += kNumStates; prob = probs + LenCoder; - } -else -{ - UPDATE_1(prob); - if (checkDicSize == 0 && processedPos == 0) - return SZ_ERROR_DATA; - prob = probs + IsRepG0 + state; - IF_BIT_0(prob) - { - UPDATE_0(prob); - prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState; + } + else + { + UPDATE_1(prob) + prob = probs + IsRepG0 + state; IF_BIT_0(prob) { - UPDATE_0(prob); - dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; + UPDATE_0(prob) + prob = probs + IsRep0Long + COMBINED_PS_STATE; + IF_BIT_0(prob) + { + UPDATE_0(prob) + + // that case was checked before with kBadRepCode + // if (checkDicSize == 0 && processedPos == 0) { len = kMatchSpecLen_Error_Data + 1; break; } + // The caller doesn't allow (dicPos == limit) case here + // so we don't need the following check: + // if (dicPos == limit) { state = state < kNumLitStates ? 9 : 11; len = 1; break; } + + dic[dicPos] = dic[dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0)]; dicPos++; processedPos++; state = state < kNumLitStates ? 9 : 11; continue; + } + UPDATE_1(prob) } - UPDATE_1(prob); - } - else - { - UInt32 distance; - UPDATE_1(prob); - prob = probs + IsRepG1 + state; - IF_BIT_0(prob) + else { - UPDATE_0(prob); + UInt32 distance; + UPDATE_1(prob) + prob = probs + IsRepG1 + state; + IF_BIT_0(prob) + { + UPDATE_0(prob) distance = rep1; - } + } else { - UPDATE_1(prob); - prob = probs + IsRepG2 + state; - IF_BIT_0(prob) - { - UPDATE_0(prob); - distance = rep2; - } + UPDATE_1(prob) + prob = probs + IsRepG2 + state; + IF_BIT_0(prob) + { + UPDATE_0(prob) + distance = rep2; + } else { - UPDATE_1(prob); - distance = rep3; - rep3 = rep2; + UPDATE_1(prob) + distance = rep3; + rep3 = rep2; } rep2 = rep1; } rep1 = rep0; rep0 = distance; - } - state = state < kNumLitStates ? 8 : 11; - prob = probs + RepLenCoder; -} + } + state = state < kNumLitStates ? 8 : 11; + prob = probs + RepLenCoder; + } + + #ifdef Z7_LZMA_SIZE_OPT { - unsigned limit, offset; - CLzmaProb *probLen = prob + LenChoice; + unsigned lim, offset; + CLzmaProb *probLen = prob + LenChoice; + IF_BIT_0(probLen) + { + UPDATE_0(probLen) + probLen = prob + LenLow + GET_LEN_STATE; + offset = 0; + lim = (1 << kLenNumLowBits); + } + else + { + UPDATE_1(probLen) + probLen = prob + LenChoice2; IF_BIT_0(probLen) { - UPDATE_0(probLen); - probLen = prob + LenLow + (posState << kLenNumLowBits); - offset = 0; - limit = (1 << kLenNumLowBits); + UPDATE_0(probLen) + probLen = prob + LenLow + GET_LEN_STATE + (1 << kLenNumLowBits); + offset = kLenNumLowSymbols; + lim = (1 << kLenNumLowBits); } - else - { - UPDATE_1(probLen); - probLen = prob + LenChoice2; - IF_BIT_0(probLen) - { - UPDATE_0(probLen); - probLen = prob + LenMid + (posState << kLenNumMidBits); - offset = kLenNumLowSymbols; - limit = (1 << kLenNumMidBits); - } else { - UPDATE_1(probLen); - probLen = prob + LenHigh; - offset = kLenNumLowSymbols + kLenNumMidSymbols; - limit = (1 << kLenNumHighBits); + UPDATE_1(probLen) + probLen = prob + LenHigh; + offset = kLenNumLowSymbols * 2; + lim = (1 << kLenNumHighBits); } } - TREE_DECODE(probLen, limit, len); + TREE_DECODE(probLen, lim, len) len += offset; } - -if (state >= kNumStates) -{ - UInt32 distance; - prob = probs + PosSlot + - ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << kNumPosSlotBits); - TREE_6_DECODE(prob, distance); - if (distance >= kStartPosModelIndex) - { - unsigned posSlot = (unsigned)distance; - int numDirectBits = (int)(((distance >> 1) - 1)); - distance = (2 | (distance & 1)); - if (posSlot < kEndPosModelIndex) + #else + { + CLzmaProb *probLen = prob + LenChoice; + IF_BIT_0(probLen) { - distance <<= numDirectBits; - prob = probs + SpecPos + distance - posSlot - 1; - { - UInt32 mask = 1; - unsigned i = 1; - do - { - GET_BIT2(prob + i, i, ;, distance |= mask); - mask <<= 1; - } while (--numDirectBits != 0); - } + UPDATE_0(probLen) + probLen = prob + LenLow + GET_LEN_STATE; + len = 1; + TREE_GET_BIT(probLen, len) + TREE_GET_BIT(probLen, len) + TREE_GET_BIT(probLen, len) + len -= 8; } else { + UPDATE_1(probLen) + probLen = prob + LenChoice2; + IF_BIT_0(probLen) + { + UPDATE_0(probLen) + probLen = prob + LenLow + GET_LEN_STATE + (1 << kLenNumLowBits); + len = 1; + TREE_GET_BIT(probLen, len) + TREE_GET_BIT(probLen, len) + TREE_GET_BIT(probLen, len) + } + else + { + UPDATE_1(probLen) + probLen = prob + LenHigh; + TREE_DECODE(probLen, (1 << kLenNumHighBits), len) + len += kLenNumLowSymbols * 2; + } + } + } + #endif + + if (state >= kNumStates) + { + UInt32 distance; + prob = probs + PosSlot + + ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << kNumPosSlotBits); + TREE_6_DECODE(prob, distance) + if (distance >= kStartPosModelIndex) + { + unsigned posSlot = (unsigned)distance; + unsigned numDirectBits = (unsigned)(((distance >> 1) - 1)); + distance = (2 | (distance & 1)); + if (posSlot < kEndPosModelIndex) + { + distance <<= numDirectBits; + prob = probs + SpecPos; + { + UInt32 m = 1; + distance++; + do + { + REV_BIT_VAR(prob, distance, m) + } + while (--numDirectBits); + distance -= m; + } + } + else + { numDirectBits -= kNumAlignBits; do { - NORMALIZE - range >>= 1; - - { - UInt32 t; - code -= range; - t = (0 - ((UInt32)code >> 31)); /* (UInt32)((Int32)code >> 31) */ - distance = (distance << 1) + (t + 1); - code += range & t; - } - /* - distance <<= 1; - if (code >= range) - { + NORMALIZE + range >>= 1; + + { + UInt32 t; + code -= range; + t = (0 - ((UInt32)code >> 31)); /* (UInt32)((Int32)code >> 31) */ + distance = (distance << 1) + (t + 1); + code += range & t; + } + /* + distance <<= 1; + if (code >= range) + { code -= range; distance |= 1; - } - */ - } while (--numDirectBits != 0); + } + */ + } + while (--numDirectBits); prob = probs + Align; distance <<= kNumAlignBits; { - unsigned i = 1; - GET_BIT2(prob + i, i, ;, distance |= 1); - GET_BIT2(prob + i, i, ;, distance |= 2); - GET_BIT2(prob + i, i, ;, distance |= 4); - GET_BIT2(prob + i, i, ;, distance |= 8); + unsigned i = 1; + REV_BIT_CONST(prob, i, 1) + REV_BIT_CONST(prob, i, 2) + REV_BIT_CONST(prob, i, 4) + REV_BIT_LAST (prob, i, 8) + distance |= i; } if (distance == (UInt32)0xFFFFFFFF) { - len += kMatchSpecLenStart; - state -= kNumStates; - break; + len = kMatchSpecLenStart; + state -= kNumStates; + break; } + } } - } - rep3 = rep2; - rep2 = rep1; - rep1 = rep0; - rep0 = distance + 1; - if (checkDicSize == 0) - { - if (distance >= processedPos) - return SZ_ERROR_DATA; - } - else if (distance >= checkDicSize) - return SZ_ERROR_DATA; - state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3; -} - -len += kMatchMinLen; - -if (limit == dicPos) -return SZ_ERROR_DATA; -{ - SizeT rem = limit - dicPos; - unsigned curLen = ((rem < len) ? (unsigned)rem : len); - SizeT pos = (dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0); - - processedPos += curLen; - - len -= curLen; - if (pos + curLen <= dicBufSize) - { - Byte *dest = dic + dicPos; - ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos; - const Byte *lim = dest + curLen; - dicPos += curLen; - do - *(dest) = (Byte)*(dest + src); - while (++dest != lim); - } - else - { - do + + rep3 = rep2; + rep2 = rep1; + rep1 = rep0; + rep0 = distance + 1; + state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3; + if (distance >= (checkDicSize == 0 ? processedPos: checkDicSize)) { + len += kMatchSpecLen_Error_Data + kMatchMinLen; + // len = kMatchSpecLen_Error_Data; + // len += kMatchMinLen; + break; + } + } + + len += kMatchMinLen; + + { + SizeT rem; + unsigned curLen; + SizeT pos; + + if ((rem = limit - dicPos) == 0) + { + /* + We stop decoding and return SZ_OK, and we can resume decoding later. + Any error conditions can be tested later in caller code. + For more strict mode we can stop decoding with error + // len += kMatchSpecLen_Error_Data; + */ + break; + } + + curLen = ((rem < len) ? (unsigned)rem : len); + pos = dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0); + + processedPos += (UInt32)curLen; + + len -= curLen; + if (curLen <= dicBufSize - pos) + { + Byte *dest = dic + dicPos; + ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos; + const Byte *lim = dest + curLen; + dicPos += (SizeT)curLen; + do + *(dest) = (Byte)*(dest + src); + while (++dest != lim); + } + else + { + do + { dic[dicPos++] = dic[pos]; if (++pos == dicBufSize) - pos = 0; - } while (--curLen != 0); - } -} -} - } while (dicPos < limit && buf < bufLimit); - NORMALIZE; - p->buf = buf; - p->range = range; - p->code = code; - p->remainLen = len; - p->dicPos = dicPos; - p->processedPos = processedPos; - p->reps[0] = rep0; - p->reps[1] = rep1; - p->reps[2] = rep2; - p->reps[3] = rep3; - p->state = state; - - return SZ_OK; -} - -static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit) -{ - if (p->remainLen != 0 && p->remainLen < kMatchSpecLenStart) - { - Byte *dic = p->dic; - SizeT dicPos = p->dicPos; - SizeT dicBufSize = p->dicBufSize; - unsigned len = p->remainLen; - UInt32 rep0 = p->reps[0]; - if (limit - dicPos < len) - len = (unsigned)(limit - dicPos); - - if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len) - p->checkDicSize = p->prop.dicSize; - - p->processedPos += len; - p->remainLen -= len; - while (len-- != 0) - { - dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; - dicPos++; + pos = 0; + } + while (--curLen != 0); } - p->dicPos = dicPos; + } } -} + } + while (dicPos < limit && buf < bufLimit); -static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit) + NORMALIZE + + p->buf = buf; + p->range = range; + p->code = code; + p->remainLen = (UInt32)len; // & (kMatchSpecLen_Error_Data - 1); // we can write real length for error matches too. + p->dicPos = dicPos; + p->processedPos = processedPos; + p->reps[0] = rep0; + p->reps[1] = rep1; + p->reps[2] = rep2; + p->reps[3] = rep3; + p->state = (UInt32)state; + if (len >= kMatchSpecLen_Error_Data) + return SZ_ERROR_DATA; + return SZ_OK; +} +#endif + + + +static void Z7_FASTCALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit) { + unsigned len = (unsigned)p->remainLen; + if (len == 0 /* || len >= kMatchSpecLenStart */) + return; + { + SizeT dicPos = p->dicPos; + Byte *dic; + SizeT dicBufSize; + SizeT rep0; /* we use SizeT to avoid the BUG of VC14 for AMD64 */ + { + SizeT rem = limit - dicPos; + if (rem < len) + { + len = (unsigned)(rem); + if (len == 0) + return; + } + } + + if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len) + p->checkDicSize = p->prop.dicSize; + + p->processedPos += (UInt32)len; + p->remainLen -= (UInt32)len; + dic = p->dic; + rep0 = p->reps[0]; + dicBufSize = p->dicBufSize; do { - SizeT limit2 = limit; - if (p->checkDicSize == 0) - { - UInt32 rem = p->prop.dicSize - p->processedPos; - if (limit - p->dicPos > rem) - limit2 = p->dicPos + rem; - } - RINOK(LzmaDec_DecodeReal(p, limit2, bufLimit)); - if (p->processedPos >= p->prop.dicSize) - p->checkDicSize = p->prop.dicSize; - LzmaDec_WriteRem(p, limit); - } while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart); - - if (p->remainLen > kMatchSpecLenStart) - { - p->remainLen = kMatchSpecLenStart; + dic[dicPos] = dic[dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0)]; + dicPos++; } - return 0; + while (--len); + p->dicPos = dicPos; + } } + +/* +At staring of new stream we have one of the following symbols: + - Literal - is allowed + - Non-Rep-Match - is allowed only if it's end marker symbol + - Rep-Match - is not allowed +We use early check of (RangeCoder:Code) over kBadRepCode to simplify main decoding code +*/ + +#define kRange0 0xFFFFFFFF +#define kBound0 ((kRange0 >> kNumBitModelTotalBits) << (kNumBitModelTotalBits - 1)) +#define kBadRepCode (kBound0 + (((kRange0 - kBound0) >> kNumBitModelTotalBits) << (kNumBitModelTotalBits - 1))) +#if kBadRepCode != (0xC0000000 - 0x400) + #error Stop_Compiling_Bad_LZMA_Check +#endif + + +/* +LzmaDec_DecodeReal2(): + It calls LZMA_DECODE_REAL() and it adjusts limit according (p->checkDicSize). + +We correct (p->checkDicSize) after LZMA_DECODE_REAL() and in LzmaDec_WriteRem(), +and we support the following state of (p->checkDicSize): + if (total_processed < p->prop.dicSize) then + { + (total_processed == p->processedPos) + (p->checkDicSize == 0) + } + else + (p->checkDicSize == p->prop.dicSize) +*/ + +static int Z7_FASTCALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit) +{ + if (p->checkDicSize == 0) + { + UInt32 rem = p->prop.dicSize - p->processedPos; + if (limit - p->dicPos > rem) + limit = p->dicPos + rem; + } + { + int res = LZMA_DECODE_REAL(p, limit, bufLimit); + if (p->checkDicSize == 0 && p->processedPos >= p->prop.dicSize) + p->checkDicSize = p->prop.dicSize; + return res; + } +} + + + typedef enum { - DUMMY_ERROR, /* unexpected end of input stream */ - DUMMY_LIT, - DUMMY_MATCH, - DUMMY_REP + DUMMY_INPUT_EOF, /* need more input data */ + DUMMY_LIT, + DUMMY_MATCH, + DUMMY_REP } ELzmaDummy; -static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inSize) + +#define IS_DUMMY_END_MARKER_POSSIBLE(dummyRes) ((dummyRes) == DUMMY_MATCH) + +static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, const Byte **bufOut) { - UInt32 range = p->range; - UInt32 code = p->code; - const Byte *bufLimit = buf + inSize; - CLzmaProb *probs = p->probs; - unsigned state = p->state; - ELzmaDummy res; + UInt32 range = p->range; + UInt32 code = p->code; + const Byte *bufLimit = *bufOut; + const CLzmaProb *probs = GET_PROBS; + unsigned state = (unsigned)p->state; + ELzmaDummy res; - { - CLzmaProb *prob; - UInt32 bound; - unsigned ttt; - unsigned posState = (p->processedPos) & ((1 << p->prop.pb) - 1); + for (;;) + { + const CLzmaProb *prob; + UInt32 bound; + unsigned ttt; + unsigned posState = CALC_POS_STATE(p->processedPos, ((unsigned)1 << p->prop.pb) - 1); - prob = probs + IsMatch + (state << kNumPosBitsMax) + posState; - IF_BIT_0_CHECK(prob) - { - UPDATE_0_CHECK - - /* if (bufLimit - buf >= 7) return DUMMY_LIT; */ - - prob = probs + Literal; - if (p->checkDicSize != 0 || p->processedPos != 0) - prob += (LZMA_LIT_SIZE * - ((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) + - (p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc)))); - - if (state < kNumLitStates) - { - unsigned symbol = 1; - do { GET_BIT_CHECK(prob + symbol, symbol) } while (symbol < 0x100); - } - else - { - unsigned matchByte = p->dic[p->dicPos - p->reps[0] + - ((p->dicPos < p->reps[0]) ? p->dicBufSize : 0)]; - unsigned offs = 0x100; - unsigned symbol = 1; - do - { - unsigned bit; - CLzmaProb *probLit; - matchByte <<= 1; - bit = (matchByte & offs); - probLit = prob + offs + bit + symbol; - GET_BIT2_CHECK(probLit, symbol, offs &= ~bit, offs &= bit) - } while (symbol < 0x100); - } - res = DUMMY_LIT; - } -else -{ - unsigned len; - UPDATE_1_CHECK; - - prob = probs + IsRep + state; + prob = probs + IsMatch + COMBINED_PS_STATE; IF_BIT_0_CHECK(prob) { - UPDATE_0_CHECK; + UPDATE_0_CHECK + + prob = probs + Literal; + if (p->checkDicSize != 0 || p->processedPos != 0) + prob += ((UInt32)LZMA_LIT_SIZE * + ((((p->processedPos) & (((unsigned)1 << (p->prop.lp)) - 1)) << p->prop.lc) + + ((unsigned)p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc)))); + + if (state < kNumLitStates) + { + unsigned symbol = 1; + do { GET_BIT_CHECK(prob + symbol, symbol) } while (symbol < 0x100); + } + else + { + unsigned matchByte = p->dic[p->dicPos - p->reps[0] + + (p->dicPos < p->reps[0] ? p->dicBufSize : 0)]; + unsigned offs = 0x100; + unsigned symbol = 1; + do + { + unsigned bit; + const CLzmaProb *probLit; + matchByte += matchByte; + bit = offs; + offs &= matchByte; + probLit = prob + (offs + bit + symbol); + GET_BIT2_CHECK(probLit, symbol, offs ^= bit; , ; ) + } + while (symbol < 0x100); + } + res = DUMMY_LIT; + } + else + { + unsigned len; + UPDATE_1_CHECK + + prob = probs + IsRep + state; + IF_BIT_0_CHECK(prob) + { + UPDATE_0_CHECK state = 0; prob = probs + LenCoder; res = DUMMY_MATCH; - } -else -{ - UPDATE_1_CHECK; - res = DUMMY_REP; - prob = probs + IsRepG0 + state; - IF_BIT_0_CHECK(prob) - { - UPDATE_0_CHECK; - prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState; + } + else + { + UPDATE_1_CHECK + res = DUMMY_REP; + prob = probs + IsRepG0 + state; IF_BIT_0_CHECK(prob) { - UPDATE_0_CHECK; - NORMALIZE_CHECK; - return DUMMY_REP; - } + UPDATE_0_CHECK + prob = probs + IsRep0Long + COMBINED_PS_STATE; + IF_BIT_0_CHECK(prob) + { + UPDATE_0_CHECK + break; + } else { - UPDATE_1_CHECK; + UPDATE_1_CHECK } - } + } else { - UPDATE_1_CHECK; - prob = probs + IsRepG1 + state; - IF_BIT_0_CHECK(prob) - { - UPDATE_0_CHECK; - } + UPDATE_1_CHECK + prob = probs + IsRepG1 + state; + IF_BIT_0_CHECK(prob) + { + UPDATE_0_CHECK + } else { - UPDATE_1_CHECK; - prob = probs + IsRepG2 + state; - IF_BIT_0_CHECK(prob) - { - UPDATE_0_CHECK; - } + UPDATE_1_CHECK + prob = probs + IsRepG2 + state; + IF_BIT_0_CHECK(prob) + { + UPDATE_0_CHECK + } else { - UPDATE_1_CHECK; + UPDATE_1_CHECK } } } state = kNumStates; prob = probs + RepLenCoder; -} + } { - unsigned limit, offset; - CLzmaProb *probLen = prob + LenChoice; - IF_BIT_0_CHECK(probLen) - { - UPDATE_0_CHECK; - probLen = prob + LenLow + (posState << kLenNumLowBits); - offset = 0; - limit = 1 << kLenNumLowBits; - } + unsigned limit, offset; + const CLzmaProb *probLen = prob + LenChoice; + IF_BIT_0_CHECK(probLen) + { + UPDATE_0_CHECK + probLen = prob + LenLow + GET_LEN_STATE; + offset = 0; + limit = 1 << kLenNumLowBits; + } else { - UPDATE_1_CHECK; - probLen = prob + LenChoice2; - IF_BIT_0_CHECK(probLen) - { - UPDATE_0_CHECK; - probLen = prob + LenMid + (posState << kLenNumMidBits); - offset = kLenNumLowSymbols; - limit = 1 << kLenNumMidBits; - } + UPDATE_1_CHECK + probLen = prob + LenChoice2; + IF_BIT_0_CHECK(probLen) + { + UPDATE_0_CHECK + probLen = prob + LenLow + GET_LEN_STATE + (1 << kLenNumLowBits); + offset = kLenNumLowSymbols; + limit = 1 << kLenNumLowBits; + } else { - UPDATE_1_CHECK; - probLen = prob + LenHigh; - offset = kLenNumLowSymbols + kLenNumMidSymbols; - limit = 1 << kLenNumHighBits; + UPDATE_1_CHECK + probLen = prob + LenHigh; + offset = kLenNumLowSymbols * 2; + limit = 1 << kLenNumHighBits; } } - TREE_DECODE_CHECK(probLen, limit, len); + TREE_DECODE_CHECK(probLen, limit, len) len += offset; } -if (state < 4) -{ - unsigned posSlot; - prob = probs + PosSlot + - ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << - kNumPosSlotBits); - TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot); - if (posSlot >= kStartPosModelIndex) - { - int numDirectBits = ((posSlot >> 1) - 1); - - /* if (bufLimit - buf >= 8) return DUMMY_MATCH; */ - - if (posSlot < kEndPosModelIndex) - { - prob = probs + SpecPos + ((2 | (posSlot & 1)) << numDirectBits) - posSlot - 1; - } - else + if (state < 4) + { + unsigned posSlot; + prob = probs + PosSlot + + ((len < kNumLenToPosStates - 1 ? len : kNumLenToPosStates - 1) << + kNumPosSlotBits); + TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot) + if (posSlot >= kStartPosModelIndex) { + unsigned numDirectBits = ((posSlot >> 1) - 1); + + if (posSlot < kEndPosModelIndex) + { + prob = probs + SpecPos + ((2 | (posSlot & 1)) << numDirectBits); + } + else + { numDirectBits -= kNumAlignBits; do { - NORMALIZE_CHECK - range >>= 1; - code -= range & (((code - range) >> 31) - 1); - /* if (code >= range) code -= range; */ - } while (--numDirectBits != 0); + NORMALIZE_CHECK + range >>= 1; + code -= range & (((code - range) >> 31) - 1); + /* if (code >= range) code -= range; */ + } + while (--numDirectBits); prob = probs + Align; numDirectBits = kNumAlignBits; - } - { - unsigned i = 1; - do - { - GET_BIT_CHECK(prob + i, i); - } while (--numDirectBits != 0); } + { + unsigned i = 1; + unsigned m = 1; + do + { + REV_BIT_CHECK(prob, i, m) + } + while (--numDirectBits); + } + } + } } -} -} - } - NORMALIZE_CHECK; - return res; + break; + } + NORMALIZE_CHECK + + *bufOut = buf; + return res; } -static void LzmaDec_InitRc(CLzmaDec *p, const Byte *data) +void LzmaDec_InitDicAndState(CLzmaDec *p, BoolInt initDic, BoolInt initState); +void LzmaDec_InitDicAndState(CLzmaDec *p, BoolInt initDic, BoolInt initState) { - p->code = ((UInt32)data[1] << 24) | ((UInt32)data[2] << 16) | ((UInt32)data[3] << 8) | ((UInt32)data[4]); - p->range = 0xFFFFFFFF; - p->needFlush = 0; -} + p->remainLen = kMatchSpecLenStart + 1; + p->tempBufSize = 0; -void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState) -{ - p->needFlush = 1; - p->remainLen = 0; - p->tempBufSize = 0; - - if (initDic) - { - p->processedPos = 0; - p->checkDicSize = 0; - p->needInitState = 1; - } - if (initState) - p->needInitState = 1; + if (initDic) + { + p->processedPos = 0; + p->checkDicSize = 0; + p->remainLen = kMatchSpecLenStart + 2; + } + if (initState) + p->remainLen = kMatchSpecLenStart + 2; } void LzmaDec_Init(CLzmaDec *p) { - p->dicPos = 0; - LzmaDec_InitDicAndState(p, True, True); + p->dicPos = 0; + LzmaDec_InitDicAndState(p, True, True); } -static void LzmaDec_InitStateReal(CLzmaDec *p) -{ - UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (p->prop.lc + p->prop.lp)); - UInt32 i; - CLzmaProb *probs = p->probs; - for (i = 0; i < numProbs; i++) - probs[i] = kBitModelTotal >> 1; - p->reps[0] = p->reps[1] = p->reps[2] = p->reps[3] = 1; - p->state = 0; - p->needInitState = 0; -} + +/* +LZMA supports optional end_marker. +So the decoder can lookahead for one additional LZMA-Symbol to check end_marker. +That additional LZMA-Symbol can require up to LZMA_REQUIRED_INPUT_MAX bytes in input stream. +When the decoder reaches dicLimit, it looks (finishMode) parameter: + if (finishMode == LZMA_FINISH_ANY), the decoder doesn't lookahead + if (finishMode != LZMA_FINISH_ANY), the decoder lookahead, if end_marker is possible for current position + +When the decoder lookahead, and the lookahead symbol is not end_marker, we have two ways: + 1) Strict mode (default) : the decoder returns SZ_ERROR_DATA. + 2) The relaxed mode (alternative mode) : we could return SZ_OK, and the caller + must check (status) value. The caller can show the error, + if the end of stream is expected, and the (status) is noit + LZMA_STATUS_FINISHED_WITH_MARK or LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK. +*/ + + +#define RETURN_NOT_FINISHED_FOR_FINISH \ + *status = LZMA_STATUS_NOT_FINISHED; \ + return SZ_ERROR_DATA; // for strict mode + // return SZ_OK; // for relaxed mode + SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status) { - SizeT inSize = *srcLen; - (*srcLen) = 0; + SizeT inSize = *srcLen; + (*srcLen) = 0; + *status = LZMA_STATUS_NOT_SPECIFIED; + + if (p->remainLen > kMatchSpecLenStart) + { + if (p->remainLen > kMatchSpecLenStart + 2) + return p->remainLen == kMatchSpecLen_Error_Fail ? SZ_ERROR_FAIL : SZ_ERROR_DATA; + + for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--) + p->tempBuf[p->tempBufSize++] = *src++; + if (p->tempBufSize != 0 && p->tempBuf[0] != 0) + return SZ_ERROR_DATA; + if (p->tempBufSize < RC_INIT_SIZE) + { + *status = LZMA_STATUS_NEEDS_MORE_INPUT; + return SZ_OK; + } + p->code = + ((UInt32)p->tempBuf[1] << 24) + | ((UInt32)p->tempBuf[2] << 16) + | ((UInt32)p->tempBuf[3] << 8) + | ((UInt32)p->tempBuf[4]); + + if (p->checkDicSize == 0 + && p->processedPos == 0 + && p->code >= kBadRepCode) + return SZ_ERROR_DATA; + + p->range = 0xFFFFFFFF; + p->tempBufSize = 0; + + if (p->remainLen > kMatchSpecLenStart + 1) + { + SizeT numProbs = LzmaProps_GetNumProbs(&p->prop); + SizeT i; + CLzmaProb *probs = p->probs; + for (i = 0; i < numProbs; i++) + probs[i] = kBitModelTotal >> 1; + p->reps[0] = p->reps[1] = p->reps[2] = p->reps[3] = 1; + p->state = 0; + } + + p->remainLen = 0; + } + + for (;;) + { + if (p->remainLen == kMatchSpecLenStart) + { + if (p->code != 0) + return SZ_ERROR_DATA; + *status = LZMA_STATUS_FINISHED_WITH_MARK; + return SZ_OK; + } + LzmaDec_WriteRem(p, dicLimit); - *status = LZMA_STATUS_NOT_SPECIFIED; - - while (p->remainLen != kMatchSpecLenStart) { - int checkEndMarkNow; + // (p->remainLen == 0 || p->dicPos == dicLimit) - if (p->needFlush != 0) + int checkEndMarkNow = 0; + + if (p->dicPos >= dicLimit) + { + if (p->remainLen == 0 && p->code == 0) { - for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--) - p->tempBuf[p->tempBufSize++] = *src++; - if (p->tempBufSize < RC_INIT_SIZE) - { - *status = LZMA_STATUS_NEEDS_MORE_INPUT; - return SZ_OK; - } - if (p->tempBuf[0] != 0) - return SZ_ERROR_DATA; - - LzmaDec_InitRc(p, p->tempBuf); - p->tempBufSize = 0; + *status = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK; + return SZ_OK; } - - checkEndMarkNow = 0; - if (p->dicPos >= dicLimit) + if (finishMode == LZMA_FINISH_ANY) { - if (p->remainLen == 0 && p->code == 0) - { - *status = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK; - return SZ_OK; - } - if (finishMode == LZMA_FINISH_ANY) - { - *status = LZMA_STATUS_NOT_FINISHED; - return SZ_OK; - } - if (p->remainLen != 0) - { - *status = LZMA_STATUS_NOT_FINISHED; - return SZ_ERROR_DATA; - } - checkEndMarkNow = 1; + *status = LZMA_STATUS_NOT_FINISHED; + return SZ_OK; } - - if (p->needInitState) - LzmaDec_InitStateReal(p); - - if (p->tempBufSize == 0) + if (p->remainLen != 0) { - SizeT processed; - const Byte *bufLimit; - if (inSize < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow) - { - int dummyRes = LzmaDec_TryDummy(p, src, inSize); - if (dummyRes == DUMMY_ERROR) - { - memcpy(p->tempBuf, src, inSize); - p->tempBufSize = (unsigned)inSize; - (*srcLen) += inSize; - *status = LZMA_STATUS_NEEDS_MORE_INPUT; - return SZ_OK; - } - if (checkEndMarkNow && dummyRes != DUMMY_MATCH) - { - *status = LZMA_STATUS_NOT_FINISHED; - return SZ_ERROR_DATA; - } - bufLimit = src; - } - else - bufLimit = src + inSize - LZMA_REQUIRED_INPUT_MAX; - p->buf = src; - if (LzmaDec_DecodeReal2(p, dicLimit, bufLimit) != 0) - return SZ_ERROR_DATA; - processed = (SizeT)(p->buf - src); - (*srcLen) += processed; - src += processed; - inSize -= processed; + RETURN_NOT_FINISHED_FOR_FINISH + } + checkEndMarkNow = 1; + } + + // (p->remainLen == 0) + + if (p->tempBufSize == 0) + { + const Byte *bufLimit; + int dummyProcessed = -1; + + if (inSize < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow) + { + const Byte *bufOut = src + inSize; + + ELzmaDummy dummyRes = LzmaDec_TryDummy(p, src, &bufOut); + + if (dummyRes == DUMMY_INPUT_EOF) + { + size_t i; + if (inSize >= LZMA_REQUIRED_INPUT_MAX) + break; + (*srcLen) += inSize; + p->tempBufSize = (unsigned)inSize; + for (i = 0; i < inSize; i++) + p->tempBuf[i] = src[i]; + *status = LZMA_STATUS_NEEDS_MORE_INPUT; + return SZ_OK; + } + + dummyProcessed = (int)(bufOut - src); + if ((unsigned)dummyProcessed > LZMA_REQUIRED_INPUT_MAX) + break; + + if (checkEndMarkNow && !IS_DUMMY_END_MARKER_POSSIBLE(dummyRes)) + { + unsigned i; + (*srcLen) += (unsigned)dummyProcessed; + p->tempBufSize = (unsigned)dummyProcessed; + for (i = 0; i < (unsigned)dummyProcessed; i++) + p->tempBuf[i] = src[i]; + // p->remainLen = kMatchSpecLen_Error_Data; + RETURN_NOT_FINISHED_FOR_FINISH + } + + bufLimit = src; + // we will decode only one iteration } else + bufLimit = src + inSize - LZMA_REQUIRED_INPUT_MAX; + + p->buf = src; + { - unsigned rem = p->tempBufSize, lookAhead = 0; - while (rem < LZMA_REQUIRED_INPUT_MAX && lookAhead < inSize) - p->tempBuf[rem++] = src[lookAhead++]; - p->tempBufSize = rem; - if (rem < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow) - { - int dummyRes = LzmaDec_TryDummy(p, p->tempBuf, rem); - if (dummyRes == DUMMY_ERROR) - { - (*srcLen) += lookAhead; - *status = LZMA_STATUS_NEEDS_MORE_INPUT; - return SZ_OK; - } - if (checkEndMarkNow && dummyRes != DUMMY_MATCH) - { - *status = LZMA_STATUS_NOT_FINISHED; - return SZ_ERROR_DATA; - } - } - p->buf = p->tempBuf; - if (LzmaDec_DecodeReal2(p, dicLimit, p->buf) != 0) - return SZ_ERROR_DATA; - lookAhead -= (rem - (unsigned)(p->buf - p->tempBuf)); - (*srcLen) += lookAhead; - src += lookAhead; - inSize -= lookAhead; - p->tempBufSize = 0; + int res = LzmaDec_DecodeReal2(p, dicLimit, bufLimit); + + SizeT processed = (SizeT)(p->buf - src); + + if (dummyProcessed < 0) + { + if (processed > inSize) + break; + } + else if ((unsigned)dummyProcessed != processed) + break; + + src += processed; + inSize -= processed; + (*srcLen) += processed; + + if (res != SZ_OK) + { + p->remainLen = kMatchSpecLen_Error_Data; + return SZ_ERROR_DATA; + } } + continue; + } + + { + // we have some data in (p->tempBuf) + // in strict mode: tempBufSize is not enough for one Symbol decoding. + // in relaxed mode: tempBufSize not larger than required for one Symbol decoding. + + unsigned rem = p->tempBufSize; + unsigned ahead = 0; + int dummyProcessed = -1; + + while (rem < LZMA_REQUIRED_INPUT_MAX && ahead < inSize) + p->tempBuf[rem++] = src[ahead++]; + + // ahead - the size of new data copied from (src) to (p->tempBuf) + // rem - the size of temp buffer including new data from (src) + + if (rem < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow) + { + const Byte *bufOut = p->tempBuf + rem; + + ELzmaDummy dummyRes = LzmaDec_TryDummy(p, p->tempBuf, &bufOut); + + if (dummyRes == DUMMY_INPUT_EOF) + { + if (rem >= LZMA_REQUIRED_INPUT_MAX) + break; + p->tempBufSize = rem; + (*srcLen) += (SizeT)ahead; + *status = LZMA_STATUS_NEEDS_MORE_INPUT; + return SZ_OK; + } + + dummyProcessed = (int)(bufOut - p->tempBuf); + + if ((unsigned)dummyProcessed < p->tempBufSize) + break; + + if (checkEndMarkNow && !IS_DUMMY_END_MARKER_POSSIBLE(dummyRes)) + { + (*srcLen) += (unsigned)dummyProcessed - p->tempBufSize; + p->tempBufSize = (unsigned)dummyProcessed; + // p->remainLen = kMatchSpecLen_Error_Data; + RETURN_NOT_FINISHED_FOR_FINISH + } + } + + p->buf = p->tempBuf; + + { + // we decode one symbol from (p->tempBuf) here, so the (bufLimit) is equal to (p->buf) + int res = LzmaDec_DecodeReal2(p, dicLimit, p->buf); + + SizeT processed = (SizeT)(p->buf - p->tempBuf); + rem = p->tempBufSize; + + if (dummyProcessed < 0) + { + if (processed > LZMA_REQUIRED_INPUT_MAX) + break; + if (processed < rem) + break; + } + else if ((unsigned)dummyProcessed != processed) + break; + + processed -= rem; + + src += processed; + inSize -= processed; + (*srcLen) += processed; + p->tempBufSize = 0; + + if (res != SZ_OK) + { + p->remainLen = kMatchSpecLen_Error_Data; + return SZ_ERROR_DATA; + } + } + } } - if (p->code == 0) - *status = LZMA_STATUS_FINISHED_WITH_MARK; - return (p->code == 0) ? SZ_OK : SZ_ERROR_DATA; + } + + /* Some unexpected error: internal error of code, memory corruption or hardware failure */ + p->remainLen = kMatchSpecLen_Error_Fail; + return SZ_ERROR_FAIL; } + + SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status) { - SizeT outSize = *destLen; - SizeT inSize = *srcLen; - *srcLen = *destLen = 0; - for (;;) + SizeT outSize = *destLen; + SizeT inSize = *srcLen; + *srcLen = *destLen = 0; + for (;;) + { + SizeT inSizeCur = inSize, outSizeCur, dicPos; + ELzmaFinishMode curFinishMode; + SRes res; + if (p->dicPos == p->dicBufSize) + p->dicPos = 0; + dicPos = p->dicPos; + if (outSize > p->dicBufSize - dicPos) { - SizeT inSizeCur = inSize, outSizeCur, dicPos; - ELzmaFinishMode curFinishMode; - SRes res; - if (p->dicPos == p->dicBufSize) - p->dicPos = 0; - dicPos = p->dicPos; - if (outSize > p->dicBufSize - dicPos) - { - outSizeCur = p->dicBufSize; - curFinishMode = LZMA_FINISH_ANY; - } - else - { - outSizeCur = dicPos + outSize; - curFinishMode = finishMode; - } - - res = LzmaDec_DecodeToDic(p, outSizeCur, src, &inSizeCur, curFinishMode, status); - src += inSizeCur; - inSize -= inSizeCur; - *srcLen += inSizeCur; - outSizeCur = p->dicPos - dicPos; - memcpy(dest, p->dic + dicPos, outSizeCur); - dest += outSizeCur; - outSize -= outSizeCur; - *destLen += outSizeCur; - if (res != 0) - return res; - if (outSizeCur == 0 || outSize == 0) - return SZ_OK; + outSizeCur = p->dicBufSize; + curFinishMode = LZMA_FINISH_ANY; } + else + { + outSizeCur = dicPos + outSize; + curFinishMode = finishMode; + } + + res = LzmaDec_DecodeToDic(p, outSizeCur, src, &inSizeCur, curFinishMode, status); + src += inSizeCur; + inSize -= inSizeCur; + *srcLen += inSizeCur; + outSizeCur = p->dicPos - dicPos; + memcpy(dest, p->dic + dicPos, outSizeCur); + dest += outSizeCur; + outSize -= outSizeCur; + *destLen += outSizeCur; + if (res != 0) + return res; + if (outSizeCur == 0 || outSize == 0) + return SZ_OK; + } } -void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc) +void LzmaDec_FreeProbs(CLzmaDec *p, ISzAllocPtr alloc) { - alloc->Free(alloc, p->probs); - p->probs = 0; + ISzAlloc_Free(alloc, p->probs); + p->probs = NULL; } -static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc) +static void LzmaDec_FreeDict(CLzmaDec *p, ISzAllocPtr alloc) { - alloc->Free(alloc, p->dic); - p->dic = 0; + ISzAlloc_Free(alloc, p->dic); + p->dic = NULL; } -void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc) +void LzmaDec_Free(CLzmaDec *p, ISzAllocPtr alloc) { - LzmaDec_FreeProbs(p, alloc); - LzmaDec_FreeDict(p, alloc); + LzmaDec_FreeProbs(p, alloc); + LzmaDec_FreeDict(p, alloc); } SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size) { - UInt32 dicSize; - Byte d; + UInt32 dicSize; + Byte d; + + if (size < LZMA_PROPS_SIZE) + return SZ_ERROR_UNSUPPORTED; + else + dicSize = data[1] | ((UInt32)data[2] << 8) | ((UInt32)data[3] << 16) | ((UInt32)data[4] << 24); + + if (dicSize < LZMA_DIC_MIN) + dicSize = LZMA_DIC_MIN; + p->dicSize = dicSize; - if (size < LZMA_PROPS_SIZE) - return SZ_ERROR_UNSUPPORTED; - else - dicSize = data[1] | ((UInt32)data[2] << 8) | ((UInt32)data[3] << 16) | ((UInt32)data[4] << 24); + d = data[0]; + if (d >= (9 * 5 * 5)) + return SZ_ERROR_UNSUPPORTED; - if (dicSize < LZMA_DIC_MIN) - dicSize = LZMA_DIC_MIN; - p->dicSize = dicSize; + p->lc = (Byte)(d % 9); + d /= 9; + p->pb = (Byte)(d / 5); + p->lp = (Byte)(d % 5); - d = data[0]; - if (d >= (9 * 5 * 5)) - return SZ_ERROR_UNSUPPORTED; - - p->lc = d % 9; - d /= 9; - p->pb = d / 5; - p->lp = d % 5; - - return SZ_OK; + return SZ_OK; } -static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc) +static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAllocPtr alloc) { - UInt32 numProbs = LzmaProps_GetNumProbs(propNew); - if (p->probs == 0 || numProbs != p->numProbs) + UInt32 numProbs = LzmaProps_GetNumProbs(propNew); + if (!p->probs || numProbs != p->numProbs) + { + LzmaDec_FreeProbs(p, alloc); + p->probs = (CLzmaProb *)ISzAlloc_Alloc(alloc, numProbs * sizeof(CLzmaProb)); + if (!p->probs) + return SZ_ERROR_MEM; + p->probs_1664 = p->probs + 1664; + p->numProbs = numProbs; + } + return SZ_OK; +} + +SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAllocPtr alloc) +{ + CLzmaProps propNew; + RINOK(LzmaProps_Decode(&propNew, props, propsSize)) + RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)) + p->prop = propNew; + return SZ_OK; +} + +SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAllocPtr alloc) +{ + CLzmaProps propNew; + SizeT dicBufSize; + RINOK(LzmaProps_Decode(&propNew, props, propsSize)) + RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)) + + { + UInt32 dictSize = propNew.dicSize; + SizeT mask = ((UInt32)1 << 12) - 1; + if (dictSize >= ((UInt32)1 << 30)) mask = ((UInt32)1 << 22) - 1; + else if (dictSize >= ((UInt32)1 << 22)) mask = ((UInt32)1 << 20) - 1; + dicBufSize = ((SizeT)dictSize + mask) & ~mask; + if (dicBufSize < dictSize) + dicBufSize = dictSize; + } + + if (!p->dic || dicBufSize != p->dicBufSize) + { + LzmaDec_FreeDict(p, alloc); + p->dic = (Byte *)ISzAlloc_Alloc(alloc, dicBufSize); + if (!p->dic) { - LzmaDec_FreeProbs(p, alloc); - p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb)); - p->numProbs = numProbs; - if (p->probs == 0) - return SZ_ERROR_MEM; + LzmaDec_FreeProbs(p, alloc); + return SZ_ERROR_MEM; } - return SZ_OK; -} - -SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc) -{ - CLzmaProps propNew; - RINOK(LzmaProps_Decode(&propNew, props, propsSize)); - RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)); - p->prop = propNew; - return SZ_OK; -} - -SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc) -{ - CLzmaProps propNew; - SizeT dicBufSize; - RINOK(LzmaProps_Decode(&propNew, props, propsSize)); - RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)); - dicBufSize = propNew.dicSize; - if (p->dic == 0 || dicBufSize != p->dicBufSize) - { - LzmaDec_FreeDict(p, alloc); - p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize); - if (p->dic == 0) - { - LzmaDec_FreeProbs(p, alloc); - return SZ_ERROR_MEM; - } - } - p->dicBufSize = dicBufSize; - p->prop = propNew; - return SZ_OK; + } + p->dicBufSize = dicBufSize; + p->prop = propNew; + return SZ_OK; } SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, - ELzmaStatus *status, ISzAlloc *alloc) + ELzmaStatus *status, ISzAllocPtr alloc) { - CLzmaDec p; - SRes res; - SizeT inSize = *srcLen; - SizeT outSize = *destLen; - *srcLen = *destLen = 0; - if (inSize < RC_INIT_SIZE) - return SZ_ERROR_INPUT_EOF; - - LzmaDec_Construct(&p); - res = LzmaDec_AllocateProbs(&p, propData, propSize, alloc); - if (res != 0) - return res; - p.dic = dest; - p.dicBufSize = outSize; - - LzmaDec_Init(&p); - - *srcLen = inSize; - res = LzmaDec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status); - - if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT) - res = SZ_ERROR_INPUT_EOF; - - (*destLen) = p.dicPos; - LzmaDec_FreeProbs(&p, alloc); - return res; -} \ No newline at end of file + CLzmaDec p; + SRes res; + SizeT outSize = *destLen, inSize = *srcLen; + *destLen = *srcLen = 0; + *status = LZMA_STATUS_NOT_SPECIFIED; + if (inSize < RC_INIT_SIZE) + return SZ_ERROR_INPUT_EOF; + LzmaDec_CONSTRUCT(&p) + RINOK(LzmaDec_AllocateProbs(&p, propData, propSize, alloc)) + p.dic = dest; + p.dicBufSize = outSize; + LzmaDec_Init(&p); + *srcLen = inSize; + res = LzmaDec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status); + *destLen = p.dicPos; + if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT) + res = SZ_ERROR_INPUT_EOF; + LzmaDec_FreeProbs(&p, alloc); + return res; +} diff --git a/common/LZMA/SDK/C/LzmaDec.h b/common/LZMA/SDK/C/LzmaDec.h index bf7f084..b0ce28f 100644 --- a/common/LZMA/SDK/C/LzmaDec.h +++ b/common/LZMA/SDK/C/LzmaDec.h @@ -1,33 +1,36 @@ /* LzmaDec.h -- LZMA Decoder -2009-02-07 : Igor Pavlov : Public domain */ +2023-04-02 : Igor Pavlov : Public domain */ -#ifndef __LZMA_DEC_H -#define __LZMA_DEC_H +#ifndef ZIP7_INC_LZMA_DEC_H +#define ZIP7_INC_LZMA_DEC_H -#include "Types.h" +#include "7zTypes.h" -#ifdef __cplusplus -extern "C" { -#endif +EXTERN_C_BEGIN -/* #define _LZMA_PROB32 */ -/* _LZMA_PROB32 can increase the speed on some CPUs, +/* #define Z7_LZMA_PROB32 */ +/* Z7_LZMA_PROB32 can increase the speed on some CPUs, but memory usage for CLzmaDec::probs will be doubled in that case */ -#ifdef _LZMA_PROB32 -#define CLzmaProb UInt32 +typedef +#ifdef Z7_LZMA_PROB32 + UInt32 #else -#define CLzmaProb UInt16 + UInt16 #endif + CLzmaProb; /* ---------- LZMA Properties ---------- */ #define LZMA_PROPS_SIZE 5 -typedef struct _CLzmaProps +typedef struct { - unsigned lc, lp, pb; + Byte lc; + Byte lp; + Byte pb; + Byte _pad_; UInt32 dicSize; } CLzmaProps; @@ -49,32 +52,35 @@ SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size); typedef struct { + /* Don't change this structure. ASM code can use it. */ CLzmaProps prop; CLzmaProb *probs; + CLzmaProb *probs_1664; Byte *dic; - const Byte *buf; - UInt32 range, code; - SizeT dicPos; SizeT dicBufSize; + SizeT dicPos; + const Byte *buf; + UInt32 range; + UInt32 code; UInt32 processedPos; UInt32 checkDicSize; - unsigned state; UInt32 reps[4]; - unsigned remainLen; - int needFlush; - int needInitState; + UInt32 state; + UInt32 remainLen; + UInt32 numProbs; unsigned tempBufSize; Byte tempBuf[LZMA_REQUIRED_INPUT_MAX]; } CLzmaDec; -#define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; } +#define LzmaDec_CONSTRUCT(p) { (p)->dic = NULL; (p)->probs = NULL; } +#define LzmaDec_Construct(p) LzmaDec_CONSTRUCT(p) void LzmaDec_Init(CLzmaDec *p); /* There are two types of LZMA streams: - 0) Stream with end mark. That end mark adds about 6 bytes to compressed size. - 1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */ + - Stream with end mark. That end mark adds about 6 bytes to compressed size. + - Stream without end mark. You must know exact uncompressed size to decompress such stream. */ typedef enum { @@ -131,11 +137,11 @@ LzmaDec_Allocate* can return: SZ_ERROR_UNSUPPORTED - Unsupported properties */ -SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc); -void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc); +SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAllocPtr alloc); +void LzmaDec_FreeProbs(CLzmaDec *p, ISzAllocPtr alloc); -SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc); -void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc); +SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAllocPtr alloc); +void LzmaDec_Free(CLzmaDec *p, ISzAllocPtr alloc); /* ---------- Dictionary Interface ---------- */ @@ -144,7 +150,7 @@ void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc); You must work with CLzmaDec variables directly in this interface. STEPS: - LzmaDec_Constr() + LzmaDec_Construct() LzmaDec_Allocate() for (each new stream) { @@ -176,6 +182,7 @@ Returns: LZMA_STATUS_NEEDS_MORE_INPUT LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK SZ_ERROR_DATA - Data error + SZ_ERROR_FAIL - Some unexpected error: internal error of code, memory corruption or hardware failure */ SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, @@ -218,14 +225,13 @@ Returns: SZ_ERROR_MEM - Memory allocation error SZ_ERROR_UNSUPPORTED - Unsupported properties SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src). + SZ_ERROR_FAIL - Some unexpected error: internal error of code, memory corruption or hardware failure */ SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, - ELzmaStatus *status, ISzAlloc *alloc); + ELzmaStatus *status, ISzAllocPtr alloc); -#ifdef __cplusplus -} -#endif +EXTERN_C_END #endif diff --git a/common/LZMA/SDK/C/LzmaEnc.c b/common/LZMA/SDK/C/LzmaEnc.c index 11fdfe0..088b78f 100644 --- a/common/LZMA/SDK/C/LzmaEnc.c +++ b/common/LZMA/SDK/C/LzmaEnc.c @@ -1,5 +1,7 @@ /* LzmaEnc.c -- LZMA Encoder -2010-04-16 : Igor Pavlov : Public domain*/ +Igor Pavlov : Public domain */ + +#include "Precomp.h" #include @@ -10,28 +12,36 @@ #include #endif +#include "CpuArch.h" #include "LzmaEnc.h" #include "LzFind.h" -#ifndef _7ZIP_ST +#ifndef Z7_ST #include "LzFindMt.h" #endif +/* the following LzmaEnc_* declarations is internal LZMA interface for LZMA2 encoder */ + +SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle p, ISeqInStreamPtr inStream, UInt32 keepWindowSize, + ISzAllocPtr alloc, ISzAllocPtr allocBig); +SRes LzmaEnc_MemPrepare(CLzmaEncHandle p, const Byte *src, SizeT srcLen, + UInt32 keepWindowSize, ISzAllocPtr alloc, ISzAllocPtr allocBig); +SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle p, BoolInt reInit, + Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize); +const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle p); +void LzmaEnc_Finish(CLzmaEncHandle p); +void LzmaEnc_SaveState(CLzmaEncHandle p); +void LzmaEnc_RestoreState(CLzmaEncHandle p); + #ifdef SHOW_STAT -static int ttt = 0; +static unsigned g_STAT_OFFSET = 0; #endif -#define kBlockSizeMax ((1 << LZMA_NUM_BLOCK_SIZE_BITS) - 1) +/* for good normalization speed we still reserve 256 MB before 4 GB range */ +#define kLzmaMaxHistorySize ((UInt32)15 << 28) -#define kBlockSize (9 << 10) -#define kUnpackBlockSize (1 << 18) -#define kMatchArraySize (1 << 21) -#define kMatchRecordMaxSize ((LZMA_MATCH_LEN_MAX * 2 + 3) * LZMA_MATCH_LEN_MAX) - -#define kNumMaxDirectBits (31) - -#define kNumTopBits 24 -#define kTopValue ((UInt32)1 << kNumTopBits) +// #define kNumTopBits 24 +#define kTopValue ((UInt32)1 << 24) #define kNumBitModelTotalBits 11 #define kBitModelTotal (1 << kNumBitModelTotalBits) @@ -40,124 +50,238 @@ static int ttt = 0; #define kNumMoveReducingBits 4 #define kNumBitPriceShiftBits 4 -#define kBitPrice (1 << kNumBitPriceShiftBits) +// #define kBitPrice (1 << kNumBitPriceShiftBits) + +#define REP_LEN_COUNT 64 void LzmaEncProps_Init(CLzmaEncProps *p) { - p->level = 5; - p->dictSize = p->mc = 0; - p->lc = p->lp = p->pb = p->algo = p->fb = p->btMode = p->numHashBytes = p->numThreads = -1; - p->writeEndMark = 0; + p->level = 5; + p->dictSize = p->mc = 0; + p->reduceSize = (UInt64)(Int64)-1; + p->lc = p->lp = p->pb = p->algo = p->fb = p->btMode = p->numHashBytes = p->numThreads = -1; + p->numHashOutBits = 0; + p->writeEndMark = 0; + p->affinity = 0; } void LzmaEncProps_Normalize(CLzmaEncProps *p) { - int level = p->level; - if (level < 0) level = 5; - p->level = level; - if (p->dictSize == 0) p->dictSize = (level <= 5 ? (1 << (level * 2 + 14)) : (level == 6 ? (1 << 25) : (1 << 26))); - if (p->lc < 0) p->lc = 3; - if (p->lp < 0) p->lp = 0; - if (p->pb < 0) p->pb = 2; - if (p->algo < 0) p->algo = (level < 5 ? 0 : 1); - if (p->fb < 0) p->fb = (level < 7 ? 32 : 64); - if (p->btMode < 0) p->btMode = (p->algo == 0 ? 0 : 1); - if (p->numHashBytes < 0) p->numHashBytes = 4; - if (p->mc == 0) p->mc = (16 + (p->fb >> 1)) >> (p->btMode ? 0 : 1); - if (p->numThreads < 0) - p->numThreads = -#ifndef _7ZIP_ST - ((p->btMode && p->algo) ? 2 : 1); -#else - 1; -#endif + int level = p->level; + if (level < 0) level = 5; + p->level = level; + + if (p->dictSize == 0) + p->dictSize = (unsigned)level <= 4 ? + (UInt32)1 << (level * 2 + 16) : + (unsigned)level <= sizeof(size_t) / 2 + 4 ? + (UInt32)1 << (level + 20) : + (UInt32)1 << (sizeof(size_t) / 2 + 24); + + if (p->dictSize > p->reduceSize) + { + UInt32 v = (UInt32)p->reduceSize; + const UInt32 kReduceMin = ((UInt32)1 << 12); + if (v < kReduceMin) + v = kReduceMin; + if (p->dictSize > v) + p->dictSize = v; + } + + if (p->lc < 0) p->lc = 3; + if (p->lp < 0) p->lp = 0; + if (p->pb < 0) p->pb = 2; + + if (p->algo < 0) p->algo = (unsigned)level < 5 ? 0 : 1; + if (p->fb < 0) p->fb = (unsigned)level < 7 ? 32 : 64; + if (p->btMode < 0) p->btMode = (p->algo == 0 ? 0 : 1); + if (p->numHashBytes < 0) p->numHashBytes = (p->btMode ? 4 : 5); + if (p->mc == 0) p->mc = (16 + ((unsigned)p->fb >> 1)) >> (p->btMode ? 0 : 1); + + if (p->numThreads < 0) + p->numThreads = + #ifndef Z7_ST + ((p->btMode && p->algo) ? 2 : 1); + #else + 1; + #endif } UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2) { - CLzmaEncProps props = *props2; - LzmaEncProps_Normalize(&props); - return props.dictSize; + CLzmaEncProps props = *props2; + LzmaEncProps_Normalize(&props); + return props.dictSize; } -/* #define LZMA_LOG_BSR */ -/* Define it for Intel's CPU */ + +/* +x86/x64: + +BSR: + IF (SRC == 0) ZF = 1, DEST is undefined; + AMD : DEST is unchanged; + IF (SRC != 0) ZF = 0; DEST is index of top non-zero bit + BSR is slow in some processors + +LZCNT: + IF (SRC == 0) CF = 1, DEST is size_in_bits_of_register(src) (32 or 64) + IF (SRC != 0) CF = 0, DEST = num_lead_zero_bits + IF (DEST == 0) ZF = 1; + +LZCNT works only in new processors starting from Haswell. +if LZCNT is not supported by processor, then it's executed as BSR. +LZCNT can be faster than BSR, if supported. +*/ + +// #define LZMA_LOG_BSR + +#if defined(MY_CPU_ARM_OR_ARM64) /* || defined(MY_CPU_X86_OR_AMD64) */ + + #if (defined(__clang__) && (__clang_major__ >= 6)) \ + || (defined(__GNUC__) && (__GNUC__ >= 6)) + #define LZMA_LOG_BSR + #elif defined(_MSC_VER) && (_MSC_VER >= 1300) + // #if defined(MY_CPU_ARM_OR_ARM64) + #define LZMA_LOG_BSR + // #endif + #endif +#endif + +// #include #ifdef LZMA_LOG_BSR -#define kDicLogSizeMaxCompress 30 +#if defined(__clang__) \ + || defined(__GNUC__) -#define BSR2_RET(pos, res) { unsigned long i; _BitScanReverse(&i, (pos)); res = (i + i) + ((pos >> (i - 1)) & 1); } +/* + C code: : (30 - __builtin_clz(x)) + gcc9/gcc10 for x64 /x86 : 30 - (bsr(x) xor 31) + clang10 for x64 : 31 + (bsr(x) xor -32) +*/ -UInt32 GetPosSlot1(UInt32 pos) + #define MY_clz(x) ((unsigned)__builtin_clz(x)) + // __lzcnt32 + // __builtin_ia32_lzcnt_u32 + +#else // #if defined(_MSC_VER) + + #ifdef MY_CPU_ARM_OR_ARM64 + + #define MY_clz _CountLeadingZeros + + #else // if defined(MY_CPU_X86_OR_AMD64) + + // #define MY_clz __lzcnt // we can use lzcnt (unsupported by old CPU) + // _BitScanReverse code is not optimal for some MSVC compilers + #define BSR2_RET(pos, res) { unsigned long zz; _BitScanReverse(&zz, (pos)); zz--; \ + res = (zz + zz) + (pos >> zz); } + + #endif // MY_CPU_X86_OR_AMD64 + +#endif // _MSC_VER + + +#ifndef BSR2_RET + + #define BSR2_RET(pos, res) { unsigned zz = 30 - MY_clz(pos); \ + res = (zz + zz) + (pos >> zz); } + +#endif + + +unsigned GetPosSlot1(UInt32 pos); +unsigned GetPosSlot1(UInt32 pos) { - UInt32 res; - BSR2_RET(pos, res); - return res; + unsigned res; + BSR2_RET(pos, res) + return res; } -#define GetPosSlot2(pos, res) { BSR2_RET(pos, res); } -#define GetPosSlot(pos, res) { if (pos < 2) res = pos; else BSR2_RET(pos, res); } +#define GetPosSlot2(pos, res) { BSR2_RET(pos, res) } +#define GetPosSlot(pos, res) { if (pos < 2) res = pos; else BSR2_RET(pos, res) } -#else -#define kNumLogBits (9 + (int)sizeof(size_t) / 2) +#else // ! LZMA_LOG_BSR + +#define kNumLogBits (11 + sizeof(size_t) / 8 * 3) + #define kDicLogSizeMaxCompress ((kNumLogBits - 1) * 2 + 7) -void LzmaEnc_FastPosInit(Byte *g_FastPos) +static void LzmaEnc_FastPosInit(Byte *g_FastPos) { - int c = 2, slotFast; - g_FastPos[0] = 0; - g_FastPos[1] = 1; - - for (slotFast = 2; slotFast < kNumLogBits * 2; slotFast++) - { - UInt32 k = (1 << ((slotFast >> 1) - 1)); - UInt32 j; - for (j = 0; j < k; j++, c++) - g_FastPos[c] = (Byte)slotFast; - } + unsigned slot; + g_FastPos[0] = 0; + g_FastPos[1] = 1; + g_FastPos += 2; + + for (slot = 2; slot < kNumLogBits * 2; slot++) + { + size_t k = ((size_t)1 << ((slot >> 1) - 1)); + size_t j; + for (j = 0; j < k; j++) + g_FastPos[j] = (Byte)slot; + g_FastPos += k; + } } -#define BSR2_RET(pos, res) { UInt32 i = 6 + ((kNumLogBits - 1) & \ +/* we can use ((limit - pos) >> 31) only if (pos < ((UInt32)1 << 31)) */ +/* +#define BSR2_RET(pos, res) { unsigned zz = 6 + ((kNumLogBits - 1) & \ (0 - (((((UInt32)1 << (kNumLogBits + 6)) - 1) - pos) >> 31))); \ - res = p->g_FastPos[pos >> i] + (i * 2); } + res = p->g_FastPos[pos >> zz] + (zz * 2); } +*/ + +/* +#define BSR2_RET(pos, res) { unsigned zz = 6 + ((kNumLogBits - 1) & \ + (0 - (((((UInt32)1 << (kNumLogBits)) - 1) - (pos >> 6)) >> 31))); \ + res = p->g_FastPos[pos >> zz] + (zz * 2); } +*/ + +#define BSR2_RET(pos, res) { unsigned zz = (pos < (1 << (kNumLogBits + 6))) ? 6 : 6 + kNumLogBits - 1; \ + res = p->g_FastPos[pos >> zz] + (zz * 2); } + /* #define BSR2_RET(pos, res) { res = (pos < (1 << (kNumLogBits + 6))) ? \ p->g_FastPos[pos >> 6] + 12 : \ p->g_FastPos[pos >> (6 + kNumLogBits - 1)] + (6 + (kNumLogBits - 1)) * 2; } - */ +*/ #define GetPosSlot1(pos) p->g_FastPos[pos] #define GetPosSlot2(pos, res) { BSR2_RET(pos, res); } -#define GetPosSlot(pos, res) { if (pos < kNumFullDistances) res = p->g_FastPos[pos]; else BSR2_RET(pos, res); } +#define GetPosSlot(pos, res) { if (pos < kNumFullDistances) res = p->g_FastPos[pos & (kNumFullDistances - 1)]; else BSR2_RET(pos, res); } + +#endif // LZMA_LOG_BSR -#endif #define LZMA_NUM_REPS 4 -typedef unsigned CState; +typedef UInt16 CState; +typedef UInt16 CExtra; typedef struct { - UInt32 price; - - CState state; - int prev1IsChar; - int prev2; - - UInt32 posPrev2; - UInt32 backPrev2; - - UInt32 posPrev; - UInt32 backPrev; - UInt32 backs[LZMA_NUM_REPS]; + UInt32 price; + CState state; + CExtra extra; + // 0 : normal + // 1 : LIT : MATCH + // > 1 : MATCH (extra-1) : LIT : REP0 (len) + UInt32 len; + UInt32 dist; + UInt32 reps[LZMA_NUM_REPS]; } COptimal; -#define kNumOpts (1 << 12) + +// 18.06 +#define kNumOpts (1 << 11) +#define kPackReserve (kNumOpts * 8) +// #define kNumOpts (1 << 12) +// #define kPackReserve (1 + kNumOpts * 2) #define kNumLenToPosStates 4 #define kNumPosSlotBits 6 -#define kDicLogSizeM0 +// #define kDicLogSizeMin 0 #define kDicLogSizeMax 32 #define kDistTableSizeMax (kDicLogSizeMax * 2) @@ -167,15 +291,15 @@ typedef struct #define kStartPosModelIndex 4 #define kEndPosModelIndex 14 -#define kNumPosModels (kEndPosModelIndex - kStartPosModelIndex) - #define kNumFullDistances (1 << (kEndPosModelIndex >> 1)) -#ifdef _LZMA_PROB32 -#define CLzmaProb UInt32 +typedef +#ifdef Z7_LZMA_PROB32 + UInt32 #else -#define CLzmaProb UInt16 + UInt16 #endif + CLzmaProb; #define LZMA_PB_MAX 4 #define LZMA_LC_MAX 8 @@ -185,2064 +309,2836 @@ typedef struct #define kLenNumLowBits 3 #define kLenNumLowSymbols (1 << kLenNumLowBits) -#define kLenNumMidBits 3 -#define kLenNumMidSymbols (1 << kLenNumMidBits) #define kLenNumHighBits 8 #define kLenNumHighSymbols (1 << kLenNumHighBits) - -#define kLenNumSymbolsTotal (kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols) +#define kLenNumSymbolsTotal (kLenNumLowSymbols * 2 + kLenNumHighSymbols) #define LZMA_MATCH_LEN_MIN 2 #define LZMA_MATCH_LEN_MAX (LZMA_MATCH_LEN_MIN + kLenNumSymbolsTotal - 1) #define kNumStates 12 + typedef struct { - CLzmaProb choice; - CLzmaProb choice2; - CLzmaProb low[LZMA_NUM_PB_STATES_MAX << kLenNumLowBits]; - CLzmaProb mid[LZMA_NUM_PB_STATES_MAX << kLenNumMidBits]; - CLzmaProb high[kLenNumHighSymbols]; + CLzmaProb low[LZMA_NUM_PB_STATES_MAX << (kLenNumLowBits + 1)]; + CLzmaProb high[kLenNumHighSymbols]; } CLenEnc; + typedef struct { - CLenEnc p; - UInt32 prices[LZMA_NUM_PB_STATES_MAX][kLenNumSymbolsTotal]; - UInt32 tableSize; - UInt32 counters[LZMA_NUM_PB_STATES_MAX]; + unsigned tableSize; + UInt32 prices[LZMA_NUM_PB_STATES_MAX][kLenNumSymbolsTotal]; + // UInt32 prices1[LZMA_NUM_PB_STATES_MAX][kLenNumLowSymbols * 2]; + // UInt32 prices2[kLenNumSymbolsTotal]; } CLenPriceEnc; +#define GET_PRICE_LEN(p, posState, len) \ + ((p)->prices[posState][(size_t)(len) - LZMA_MATCH_LEN_MIN]) + +/* +#define GET_PRICE_LEN(p, posState, len) \ + ((p)->prices2[(size_t)(len) - 2] + ((p)->prices1[posState][((len) - 2) & (kLenNumLowSymbols * 2 - 1)] & (((len) - 2 - kLenNumLowSymbols * 2) >> 9))) +*/ + typedef struct { - UInt32 range; - Byte cache; - UInt64 low; - UInt64 cacheSize; - Byte *buf; - Byte *bufLim; - Byte *bufBase; - ISeqOutStream *outStream; - UInt64 processed; - SRes res; + UInt32 range; + unsigned cache; + UInt64 low; + UInt64 cacheSize; + Byte *buf; + Byte *bufLim; + Byte *bufBase; + ISeqOutStreamPtr outStream; + UInt64 processed; + SRes res; } CRangeEnc; + typedef struct { - CLzmaProb *litProbs; + CLzmaProb *litProbs; - CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX]; - CLzmaProb isRep[kNumStates]; - CLzmaProb isRepG0[kNumStates]; - CLzmaProb isRepG1[kNumStates]; - CLzmaProb isRepG2[kNumStates]; - CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX]; + unsigned state; + UInt32 reps[LZMA_NUM_REPS]; - CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits]; - CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex]; - CLzmaProb posAlignEncoder[1 << kNumAlignBits]; + CLzmaProb posAlignEncoder[1 << kNumAlignBits]; + CLzmaProb isRep[kNumStates]; + CLzmaProb isRepG0[kNumStates]; + CLzmaProb isRepG1[kNumStates]; + CLzmaProb isRepG2[kNumStates]; + CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX]; + CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX]; - CLenPriceEnc lenEnc; - CLenPriceEnc repLenEnc; + CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits]; + CLzmaProb posEncoders[kNumFullDistances]; + + CLenEnc lenProbs; + CLenEnc repLenProbs; - UInt32 reps[LZMA_NUM_REPS]; - UInt32 state; } CSaveState; -typedef struct + +typedef UInt32 CProbPrice; + + +struct CLzmaEnc { - IMatchFinder matchFinder; - void *matchFinderObj; + void *matchFinderObj; + IMatchFinder2 matchFinder; -#ifndef _7ZIP_ST - Bool mtMode; - CMatchFinderMt matchFinderMt; + unsigned optCur; + unsigned optEnd; + + unsigned longestMatchLen; + unsigned numPairs; + UInt32 numAvail; + + unsigned state; + unsigned numFastBytes; + unsigned additionalOffset; + UInt32 reps[LZMA_NUM_REPS]; + unsigned lpMask, pbMask; + CLzmaProb *litProbs; + CRangeEnc rc; + + UInt32 backRes; + + unsigned lc, lp, pb; + unsigned lclp; + + BoolInt fastMode; + BoolInt writeEndMark; + BoolInt finished; + BoolInt multiThread; + BoolInt needInit; + // BoolInt _maxMode; + + UInt64 nowPos64; + + unsigned matchPriceCount; + // unsigned alignPriceCount; + int repLenEncCounter; + + unsigned distTableSize; + + UInt32 dictSize; + SRes result; + + #ifndef Z7_ST + BoolInt mtMode; + // begin of CMatchFinderMt is used in LZ thread + CMatchFinderMt matchFinderMt; + // end of CMatchFinderMt is used in BT and HASH threads + // #else + // CMatchFinder matchFinderBase; + #endif + CMatchFinder matchFinderBase; + + + // we suppose that we have 8-bytes alignment after CMatchFinder + + #ifndef Z7_ST + Byte pad[128]; + #endif + + // LZ thread + CProbPrice ProbPrices[kBitModelTotal >> kNumMoveReducingBits]; + + // we want {len , dist} pairs to be 8-bytes aligned in matches array + UInt32 matches[LZMA_MATCH_LEN_MAX * 2 + 2]; + + // we want 8-bytes alignment here + UInt32 alignPrices[kAlignTableSize]; + UInt32 posSlotPrices[kNumLenToPosStates][kDistTableSizeMax]; + UInt32 distancesPrices[kNumLenToPosStates][kNumFullDistances]; + + CLzmaProb posAlignEncoder[1 << kNumAlignBits]; + CLzmaProb isRep[kNumStates]; + CLzmaProb isRepG0[kNumStates]; + CLzmaProb isRepG1[kNumStates]; + CLzmaProb isRepG2[kNumStates]; + CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX]; + CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX]; + CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits]; + CLzmaProb posEncoders[kNumFullDistances]; + + CLenEnc lenProbs; + CLenEnc repLenProbs; + + #ifndef LZMA_LOG_BSR + Byte g_FastPos[1 << kNumLogBits]; + #endif + + CLenPriceEnc lenEnc; + CLenPriceEnc repLenEnc; + + COptimal opt[kNumOpts]; + + CSaveState saveState; + + // BoolInt mf_Failure; + #ifndef Z7_ST + Byte pad2[128]; + #endif +}; + + +#define MFB (p->matchFinderBase) +/* +#ifndef Z7_ST +#define MFB (p->matchFinderMt.MatchFinder) #endif +*/ - CMatchFinder matchFinderBase; +// #define GET_CLzmaEnc_p CLzmaEnc *p = (CLzmaEnc*)(void *)p; +// #define GET_const_CLzmaEnc_p const CLzmaEnc *p = (const CLzmaEnc*)(const void *)p; -#ifndef _7ZIP_ST - Byte pad[128]; -#endif +#define COPY_ARR(dest, src, arr) memcpy((dest)->arr, (src)->arr, sizeof((src)->arr)); - UInt32 optimumEndIndex; - UInt32 optimumCurrentIndex; +#define COPY_LZMA_ENC_STATE(d, s, p) \ + (d)->state = (s)->state; \ + COPY_ARR(d, s, reps) \ + COPY_ARR(d, s, posAlignEncoder) \ + COPY_ARR(d, s, isRep) \ + COPY_ARR(d, s, isRepG0) \ + COPY_ARR(d, s, isRepG1) \ + COPY_ARR(d, s, isRepG2) \ + COPY_ARR(d, s, isMatch) \ + COPY_ARR(d, s, isRep0Long) \ + COPY_ARR(d, s, posSlotEncoder) \ + COPY_ARR(d, s, posEncoders) \ + (d)->lenProbs = (s)->lenProbs; \ + (d)->repLenProbs = (s)->repLenProbs; \ + memcpy((d)->litProbs, (s)->litProbs, ((size_t)0x300 * sizeof(CLzmaProb)) << (p)->lclp); - UInt32 longestMatchLength; - UInt32 numPairs; - UInt32 numAvail; - COptimal opt[kNumOpts]; - -#ifndef LZMA_LOG_BSR - Byte g_FastPos[1 << kNumLogBits]; -#endif - - UInt32 ProbPrices[kBitModelTotal >> kNumMoveReducingBits]; - UInt32 matches[LZMA_MATCH_LEN_MAX * 2 + 2 + 1]; - UInt32 numFastBytes; - UInt32 additionalOffset; - UInt32 reps[LZMA_NUM_REPS]; - UInt32 state; - - UInt32 posSlotPrices[kNumLenToPosStates][kDistTableSizeMax]; - UInt32 distancesPrices[kNumLenToPosStates][kNumFullDistances]; - UInt32 alignPrices[kAlignTableSize]; - UInt32 alignPriceCount; - - UInt32 distTableSize; - - unsigned lc, lp, pb; - unsigned lpMask, pbMask; - - CLzmaProb *litProbs; - - CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX]; - CLzmaProb isRep[kNumStates]; - CLzmaProb isRepG0[kNumStates]; - CLzmaProb isRepG1[kNumStates]; - CLzmaProb isRepG2[kNumStates]; - CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX]; - - CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits]; - CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex]; - CLzmaProb posAlignEncoder[1 << kNumAlignBits]; - - CLenPriceEnc lenEnc; - CLenPriceEnc repLenEnc; - - unsigned lclp; - - Bool fastMode; - - CRangeEnc rc; - - Bool writeEndMark; - UInt64 nowPos64; - UInt32 matchPriceCount; - Bool finished; - Bool multiThread; - - SRes result; - UInt32 dictSize; - UInt32 matchFinderCycles; - - int needInit; - - CSaveState saveState; -} CLzmaEnc; - -void LzmaEnc_SaveState(CLzmaEncHandle pp) +void LzmaEnc_SaveState(CLzmaEncHandle p) { - CLzmaEnc *p = (CLzmaEnc *)pp; - CSaveState *dest = &p->saveState; - int i; - dest->lenEnc = p->lenEnc; - dest->repLenEnc = p->repLenEnc; - dest->state = p->state; - - for (i = 0; i < kNumStates; i++) - { - memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i])); - memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i])); - } - for (i = 0; i < kNumLenToPosStates; i++) - memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i])); - memcpy(dest->isRep, p->isRep, sizeof(p->isRep)); - memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0)); - memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1)); - memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2)); - memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders)); - memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder)); - memcpy(dest->reps, p->reps, sizeof(p->reps)); - memcpy(dest->litProbs, p->litProbs, (0x300 << p->lclp) * sizeof(CLzmaProb)); + // GET_CLzmaEnc_p + CSaveState *v = &p->saveState; + COPY_LZMA_ENC_STATE(v, p, p) } -void LzmaEnc_RestoreState(CLzmaEncHandle pp) +void LzmaEnc_RestoreState(CLzmaEncHandle p) { - CLzmaEnc *dest = (CLzmaEnc *)pp; - const CSaveState *p = &dest->saveState; - int i; - dest->lenEnc = p->lenEnc; - dest->repLenEnc = p->repLenEnc; - dest->state = p->state; - - for (i = 0; i < kNumStates; i++) - { - memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i])); - memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i])); - } - for (i = 0; i < kNumLenToPosStates; i++) - memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i])); - memcpy(dest->isRep, p->isRep, sizeof(p->isRep)); - memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0)); - memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1)); - memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2)); - memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders)); - memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder)); - memcpy(dest->reps, p->reps, sizeof(p->reps)); - memcpy(dest->litProbs, p->litProbs, (0x300 << dest->lclp) * sizeof(CLzmaProb)); + // GET_CLzmaEnc_p + const CSaveState *v = &p->saveState; + COPY_LZMA_ENC_STATE(p, v, p) } -SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2) + +Z7_NO_INLINE +SRes LzmaEnc_SetProps(CLzmaEncHandle p, const CLzmaEncProps *props2) { - CLzmaEnc *p = (CLzmaEnc *)pp; - CLzmaEncProps props = *props2; - LzmaEncProps_Normalize(&props); + // GET_CLzmaEnc_p + CLzmaEncProps props = *props2; + LzmaEncProps_Normalize(&props); - if (props.lc > LZMA_LC_MAX || props.lp > LZMA_LP_MAX || props.pb > LZMA_PB_MAX || - props.dictSize > ((UInt32)1 << kDicLogSizeMaxCompress) || props.dictSize > ((UInt32)1 << 30)) - return SZ_ERROR_PARAM; - p->dictSize = props.dictSize; - p->matchFinderCycles = props.mc; + if (props.lc > LZMA_LC_MAX + || props.lp > LZMA_LP_MAX + || props.pb > LZMA_PB_MAX) + return SZ_ERROR_PARAM; + + + if (props.dictSize > kLzmaMaxHistorySize) + props.dictSize = kLzmaMaxHistorySize; + + #ifndef LZMA_LOG_BSR + { + const UInt64 dict64 = props.dictSize; + if (dict64 > ((UInt64)1 << kDicLogSizeMaxCompress)) + return SZ_ERROR_PARAM; + } + #endif + + p->dictSize = props.dictSize; + { + unsigned fb = (unsigned)props.fb; + if (fb < 5) + fb = 5; + if (fb > LZMA_MATCH_LEN_MAX) + fb = LZMA_MATCH_LEN_MAX; + p->numFastBytes = fb; + } + p->lc = (unsigned)props.lc; + p->lp = (unsigned)props.lp; + p->pb = (unsigned)props.pb; + p->fastMode = (props.algo == 0); + // p->_maxMode = True; + MFB.btMode = (Byte)(props.btMode ? 1 : 0); + // MFB.btMode = (Byte)(props.btMode); + { + unsigned numHashBytes = 4; + if (props.btMode) { - unsigned fb = props.fb; - if (fb < 5) - fb = 5; - if (fb > LZMA_MATCH_LEN_MAX) - fb = LZMA_MATCH_LEN_MAX; - p->numFastBytes = fb; - } - p->lc = props.lc; - p->lp = props.lp; - p->pb = props.pb; - p->fastMode = (props.algo == 0); - p->matchFinderBase.btMode = props.btMode; - { - UInt32 numHashBytes = 4; - if (props.btMode) - { - if (props.numHashBytes < 2) - numHashBytes = 2; - else if (props.numHashBytes < 4) - numHashBytes = props.numHashBytes; - } - p->matchFinderBase.numHashBytes = numHashBytes; + if (props.numHashBytes < 2) numHashBytes = 2; + else if (props.numHashBytes < 4) numHashBytes = (unsigned)props.numHashBytes; } + if (props.numHashBytes >= 5) numHashBytes = 5; - p->matchFinderBase.cutValue = props.mc; + MFB.numHashBytes = numHashBytes; + // MFB.numHashBytes_Min = 2; + MFB.numHashOutBits = (Byte)props.numHashOutBits; + } - p->writeEndMark = props.writeEndMark; + MFB.cutValue = props.mc; -#ifndef _7ZIP_ST - /* - if (newMultiThread != _multiThread) - { + p->writeEndMark = (BoolInt)props.writeEndMark; + + #ifndef Z7_ST + /* + if (newMultiThread != _multiThread) + { ReleaseMatchFinder(); _multiThread = newMultiThread; - } - */ - p->multiThread = (props.numThreads > 1); -#endif + } + */ + p->multiThread = (props.numThreads > 1); + p->matchFinderMt.btSync.affinity = + p->matchFinderMt.hashSync.affinity = props.affinity; + #endif - return SZ_OK; + return SZ_OK; } -static const int kLiteralNextStates[kNumStates] = { 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5 }; -static const int kMatchNextStates[kNumStates] = { 7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10 }; -static const int kRepNextStates[kNumStates] = { 8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11 }; -static const int kShortRepNextStates[kNumStates] = { 9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11 }; -#define IsCharState(s) ((s) < 7) +void LzmaEnc_SetDataSize(CLzmaEncHandle p, UInt64 expectedDataSiize) +{ + // GET_CLzmaEnc_p + MFB.expectedDataSize = expectedDataSiize; +} + +#define kState_Start 0 +#define kState_LitAfterMatch 4 +#define kState_LitAfterRep 5 +#define kState_MatchAfterLit 7 +#define kState_RepAfterLit 8 + +static const Byte kLiteralNextStates[kNumStates] = {0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5}; +static const Byte kMatchNextStates[kNumStates] = {7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10}; +static const Byte kRepNextStates[kNumStates] = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11}; +static const Byte kShortRepNextStates[kNumStates]= {9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11}; + +#define IsLitState(s) ((s) < 7) +#define GetLenToPosState2(len) (((len) < kNumLenToPosStates - 1) ? (len) : kNumLenToPosStates - 1) #define GetLenToPosState(len) (((len) < kNumLenToPosStates + 1) ? (len) - 2 : kNumLenToPosStates - 1) #define kInfinityPrice (1 << 30) static void RangeEnc_Construct(CRangeEnc *p) { - p->outStream = 0; - p->bufBase = 0; + p->outStream = NULL; + p->bufBase = NULL; } -#define RangeEnc_GetProcessed(p) ((p)->processed + ((p)->buf - (p)->bufBase) + (p)->cacheSize) +#define RangeEnc_GetProcessed(p) ( (p)->processed + (size_t)((p)->buf - (p)->bufBase) + (p)->cacheSize) +#define RangeEnc_GetProcessed_sizet(p) ((size_t)(p)->processed + (size_t)((p)->buf - (p)->bufBase) + (size_t)(p)->cacheSize) #define RC_BUF_SIZE (1 << 16) -static int RangeEnc_Alloc(CRangeEnc *p, ISzAlloc *alloc) + +static int RangeEnc_Alloc(CRangeEnc *p, ISzAllocPtr alloc) { - if (p->bufBase == 0) - { - p->bufBase = (Byte *)alloc->Alloc(alloc, RC_BUF_SIZE); - if (p->bufBase == 0) - return 0; - p->bufLim = p->bufBase + RC_BUF_SIZE; - } - return 1; + if (!p->bufBase) + { + p->bufBase = (Byte *)ISzAlloc_Alloc(alloc, RC_BUF_SIZE); + if (!p->bufBase) + return 0; + p->bufLim = p->bufBase + RC_BUF_SIZE; + } + return 1; } -static void RangeEnc_Free(CRangeEnc *p, ISzAlloc *alloc) +static void RangeEnc_Free(CRangeEnc *p, ISzAllocPtr alloc) { - alloc->Free(alloc, p->bufBase); - p->bufBase = 0; + ISzAlloc_Free(alloc, p->bufBase); + p->bufBase = NULL; } static void RangeEnc_Init(CRangeEnc *p) { - /* Stream.Init(); */ - p->low = 0; - p->range = 0xFFFFFFFF; - p->cacheSize = 1; - p->cache = 0; + p->range = 0xFFFFFFFF; + p->cache = 0; + p->low = 0; + p->cacheSize = 0; - p->buf = p->bufBase; + p->buf = p->bufBase; - p->processed = 0; - p->res = SZ_OK; + p->processed = 0; + p->res = SZ_OK; } -static void RangeEnc_FlushStream(CRangeEnc *p) +Z7_NO_INLINE static void RangeEnc_FlushStream(CRangeEnc *p) { - size_t num; - if (p->res != SZ_OK) - return; - num = p->buf - p->bufBase; - if (num != p->outStream->Write(p->outStream, p->bufBase, num)) - p->res = SZ_ERROR_WRITE; - p->processed += num; - p->buf = p->bufBase; + const size_t num = (size_t)(p->buf - p->bufBase); + if (p->res == SZ_OK) + { + if (num != ISeqOutStream_Write(p->outStream, p->bufBase, num)) + p->res = SZ_ERROR_WRITE; + } + p->processed += num; + p->buf = p->bufBase; } -static void MY_FAST_CALL RangeEnc_ShiftLow(CRangeEnc *p) +Z7_NO_INLINE static void Z7_FASTCALL RangeEnc_ShiftLow(CRangeEnc *p) { - if ((UInt32)p->low < (UInt32)0xFF000000 || (int)(p->low >> 32) != 0) + UInt32 low = (UInt32)p->low; + unsigned high = (unsigned)(p->low >> 32); + p->low = (UInt32)(low << 8); + if (low < (UInt32)0xFF000000 || high != 0) + { { - Byte temp = p->cache; - do - { - Byte *buf = p->buf; - *buf++ = (Byte)(temp + (Byte)(p->low >> 32)); - p->buf = buf; - if (buf == p->bufLim) - RangeEnc_FlushStream(p); - temp = 0xFF; - } while (--p->cacheSize != 0); - p->cache = (Byte)((UInt32)p->low >> 24); + Byte *buf = p->buf; + *buf++ = (Byte)(p->cache + high); + p->cache = (unsigned)(low >> 24); + p->buf = buf; + if (buf == p->bufLim) + RangeEnc_FlushStream(p); + if (p->cacheSize == 0) + return; } - p->cacheSize++; - p->low = (UInt32)p->low << 8; + high += 0xFF; + for (;;) + { + Byte *buf = p->buf; + *buf++ = (Byte)(high); + p->buf = buf; + if (buf == p->bufLim) + RangeEnc_FlushStream(p); + if (--p->cacheSize == 0) + return; + } + } + p->cacheSize++; } static void RangeEnc_FlushData(CRangeEnc *p) { - int i; - for (i = 0; i < 5; i++) - RangeEnc_ShiftLow(p); + int i; + for (i = 0; i < 5; i++) + RangeEnc_ShiftLow(p); } -static void RangeEnc_EncodeDirectBits(CRangeEnc *p, UInt32 value, int numBits) +#define RC_NORM(p) if (range < kTopValue) { range <<= 8; RangeEnc_ShiftLow(p); } + +#define RC_BIT_PRE(p, prob) \ + ttt = *(prob); \ + newBound = (range >> kNumBitModelTotalBits) * ttt; + +// #define Z7_LZMA_ENC_USE_BRANCH + +#ifdef Z7_LZMA_ENC_USE_BRANCH + +#define RC_BIT(p, prob, bit) { \ + RC_BIT_PRE(p, prob) \ + if (bit == 0) { range = newBound; ttt += (kBitModelTotal - ttt) >> kNumMoveBits; } \ + else { (p)->low += newBound; range -= newBound; ttt -= ttt >> kNumMoveBits; } \ + *(prob) = (CLzmaProb)ttt; \ + RC_NORM(p) \ + } + +#else + +#define RC_BIT(p, prob, bit) { \ + UInt32 mask; \ + RC_BIT_PRE(p, prob) \ + mask = 0 - (UInt32)bit; \ + range &= mask; \ + mask &= newBound; \ + range -= mask; \ + (p)->low += mask; \ + mask = (UInt32)bit - 1; \ + range += newBound & mask; \ + mask &= (kBitModelTotal - ((1 << kNumMoveBits) - 1)); \ + mask += ((1 << kNumMoveBits) - 1); \ + ttt += (UInt32)((Int32)(mask - ttt) >> kNumMoveBits); \ + *(prob) = (CLzmaProb)ttt; \ + RC_NORM(p) \ + } + +#endif + + + + +#define RC_BIT_0_BASE(p, prob) \ + range = newBound; *(prob) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); + +#define RC_BIT_1_BASE(p, prob) \ + range -= newBound; (p)->low += newBound; *(prob) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits)); \ + +#define RC_BIT_0(p, prob) \ + RC_BIT_0_BASE(p, prob) \ + RC_NORM(p) + +#define RC_BIT_1(p, prob) \ + RC_BIT_1_BASE(p, prob) \ + RC_NORM(p) + +static void RangeEnc_EncodeBit_0(CRangeEnc *p, CLzmaProb *prob) { - do - { - p->range >>= 1; - p->low += p->range & (0 - ((value >> --numBits) & 1)); - if (p->range < kTopValue) - { - p->range <<= 8; - RangeEnc_ShiftLow(p); - } - } while (numBits != 0); + UInt32 range, ttt, newBound; + range = p->range; + RC_BIT_PRE(p, prob) + RC_BIT_0(p, prob) + p->range = range; } -static void RangeEnc_EncodeBit(CRangeEnc *p, CLzmaProb *prob, UInt32 symbol) +static void LitEnc_Encode(CRangeEnc *p, CLzmaProb *probs, UInt32 sym) { - UInt32 ttt = *prob; - UInt32 newBound = (p->range >> kNumBitModelTotalBits) * ttt; - if (symbol == 0) + UInt32 range = p->range; + sym |= 0x100; + do + { + UInt32 ttt, newBound; + // RangeEnc_EncodeBit(p, probs + (sym >> 8), (sym >> 7) & 1); + CLzmaProb *prob = probs + (sym >> 8); + UInt32 bit = (sym >> 7) & 1; + sym <<= 1; + RC_BIT(p, prob, bit) + } + while (sym < 0x10000); + p->range = range; +} + +static void LitEnc_EncodeMatched(CRangeEnc *p, CLzmaProb *probs, UInt32 sym, UInt32 matchByte) +{ + UInt32 range = p->range; + UInt32 offs = 0x100; + sym |= 0x100; + do + { + UInt32 ttt, newBound; + CLzmaProb *prob; + UInt32 bit; + matchByte <<= 1; + // RangeEnc_EncodeBit(p, probs + (offs + (matchByte & offs) + (sym >> 8)), (sym >> 7) & 1); + prob = probs + (offs + (matchByte & offs) + (sym >> 8)); + bit = (sym >> 7) & 1; + sym <<= 1; + offs &= ~(matchByte ^ sym); + RC_BIT(p, prob, bit) + } + while (sym < 0x10000); + p->range = range; +} + + + +static void LzmaEnc_InitPriceTables(CProbPrice *ProbPrices) +{ + UInt32 i; + for (i = 0; i < (kBitModelTotal >> kNumMoveReducingBits); i++) + { + const unsigned kCyclesBits = kNumBitPriceShiftBits; + UInt32 w = (i << kNumMoveReducingBits) + (1 << (kNumMoveReducingBits - 1)); + unsigned bitCount = 0; + unsigned j; + for (j = 0; j < kCyclesBits; j++) { - p->range = newBound; - ttt += (kBitModelTotal - ttt) >> kNumMoveBits; - } - else - { - p->low += newBound; - p->range -= newBound; - ttt -= ttt >> kNumMoveBits; - } - *prob = (CLzmaProb)ttt; - if (p->range < kTopValue) - { - p->range <<= 8; - RangeEnc_ShiftLow(p); + w = w * w; + bitCount <<= 1; + while (w >= ((UInt32)1 << 16)) + { + w >>= 1; + bitCount++; + } } + ProbPrices[i] = (CProbPrice)(((unsigned)kNumBitModelTotalBits << kCyclesBits) - 15 - bitCount); + // printf("\n%3d: %5d", i, ProbPrices[i]); + } } -static void LitEnc_Encode(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol) -{ - symbol |= 0x100; - do - { - RangeEnc_EncodeBit(p, probs + (symbol >> 8), (symbol >> 7) & 1); - symbol <<= 1; - } while (symbol < 0x10000); -} -static void LitEnc_EncodeMatched(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol, UInt32 matchByte) -{ - UInt32 offs = 0x100; - symbol |= 0x100; - do - { - matchByte <<= 1; - RangeEnc_EncodeBit(p, probs + (offs + (matchByte & offs) + (symbol >> 8)), (symbol >> 7) & 1); - symbol <<= 1; - offs &= ~(matchByte ^ symbol); - } while (symbol < 0x10000); -} +#define GET_PRICE(prob, bit) \ + p->ProbPrices[((prob) ^ (unsigned)(((-(int)(bit))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits] -void LzmaEnc_InitPriceTables(UInt32 *ProbPrices) -{ - UInt32 i; - for (i = (1 << kNumMoveReducingBits) / 2; i < kBitModelTotal; i += (1 << kNumMoveReducingBits)) - { - const int kCyclesBits = kNumBitPriceShiftBits; - UInt32 w = i; - UInt32 bitCount = 0; - int j; - for (j = 0; j < kCyclesBits; j++) - { - w = w * w; - bitCount <<= 1; - while (w >= ((UInt32)1 << 16)) - { - w >>= 1; - bitCount++; - } - } - ProbPrices[i >> kNumMoveReducingBits] = ((kNumBitModelTotalBits << kCyclesBits) - 15 - bitCount); - } -} - -#define GET_PRICE(prob, symbol) \ - p->ProbPrices[((prob) ^ (((-(int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits]; - -#define GET_PRICEa(prob, symbol) \ - ProbPrices[((prob) ^ ((-((int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits]; +#define GET_PRICEa(prob, bit) \ + ProbPrices[((prob) ^ (unsigned)((-((int)(bit))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits] #define GET_PRICE_0(prob) p->ProbPrices[(prob) >> kNumMoveReducingBits] #define GET_PRICE_1(prob) p->ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits] -#define GET_PRICE_0a(prob) ProbPrices[(prob) >> kNumMoveReducingBits] -#define GET_PRICE_1a(prob) ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits] +#define GET_PRICEa_0(prob) ProbPrices[(prob) >> kNumMoveReducingBits] +#define GET_PRICEa_1(prob) ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits] -static UInt32 LitEnc_GetPrice(const CLzmaProb *probs, UInt32 symbol, UInt32 *ProbPrices) + +static UInt32 LitEnc_GetPrice(const CLzmaProb *probs, UInt32 sym, const CProbPrice *ProbPrices) { - UInt32 price = 0; - symbol |= 0x100; - do - { - price += GET_PRICEa(probs[symbol >> 8], (symbol >> 7) & 1); - symbol <<= 1; - } while (symbol < 0x10000); - return price; + UInt32 price = 0; + sym |= 0x100; + do + { + unsigned bit = sym & 1; + sym >>= 1; + price += GET_PRICEa(probs[sym], bit); + } + while (sym >= 2); + return price; } -static UInt32 LitEnc_GetPriceMatched(const CLzmaProb *probs, UInt32 symbol, UInt32 matchByte, UInt32 *ProbPrices) + +static UInt32 LitEnc_Matched_GetPrice(const CLzmaProb *probs, UInt32 sym, UInt32 matchByte, const CProbPrice *ProbPrices) { - UInt32 price = 0; - UInt32 offs = 0x100; - symbol |= 0x100; - do - { - matchByte <<= 1; - price += GET_PRICEa(probs[offs + (matchByte & offs) + (symbol >> 8)], (symbol >> 7) & 1); - symbol <<= 1; - offs &= ~(matchByte ^ symbol); - } while (symbol < 0x10000); - return price; + UInt32 price = 0; + UInt32 offs = 0x100; + sym |= 0x100; + do + { + matchByte <<= 1; + price += GET_PRICEa(probs[offs + (matchByte & offs) + (sym >> 8)], (sym >> 7) & 1); + sym <<= 1; + offs &= ~(matchByte ^ sym); + } + while (sym < 0x10000); + return price; } -static void RcTree_Encode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol) + +static void RcTree_ReverseEncode(CRangeEnc *rc, CLzmaProb *probs, unsigned numBits, unsigned sym) { - UInt32 m = 1; - int i; - for (i = numBitLevels; i != 0;) - { - UInt32 bit; - i--; - bit = (symbol >> i) & 1; - RangeEnc_EncodeBit(rc, probs + m, bit); - m = (m << 1) | bit; - } + UInt32 range = rc->range; + unsigned m = 1; + do + { + UInt32 ttt, newBound; + unsigned bit = sym & 1; + // RangeEnc_EncodeBit(rc, probs + m, bit); + sym >>= 1; + RC_BIT(rc, probs + m, bit) + m = (m << 1) | bit; + } + while (--numBits); + rc->range = range; } -static void RcTree_ReverseEncode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol) -{ - UInt32 m = 1; - int i; - for (i = 0; i < numBitLevels; i++) - { - UInt32 bit = symbol & 1; - RangeEnc_EncodeBit(rc, probs + m, bit); - m = (m << 1) | bit; - symbol >>= 1; - } -} -static UInt32 RcTree_GetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices) -{ - UInt32 price = 0; - symbol |= (1 << numBitLevels); - while (symbol != 1) - { - price += GET_PRICEa(probs[symbol >> 1], symbol & 1); - symbol >>= 1; - } - return price; -} - -static UInt32 RcTree_ReverseGetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices) -{ - UInt32 price = 0; - UInt32 m = 1; - int i; - for (i = numBitLevels; i != 0; i--) - { - UInt32 bit = symbol & 1; - symbol >>= 1; - price += GET_PRICEa(probs[m], bit); - m = (m << 1) | bit; - } - return price; -} static void LenEnc_Init(CLenEnc *p) { - unsigned i; - p->choice = p->choice2 = kProbInitValue; - for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << kLenNumLowBits); i++) - p->low[i] = kProbInitValue; - for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << kLenNumMidBits); i++) - p->mid[i] = kProbInitValue; - for (i = 0; i < kLenNumHighSymbols; i++) - p->high[i] = kProbInitValue; + unsigned i; + for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << (kLenNumLowBits + 1)); i++) + p->low[i] = kProbInitValue; + for (i = 0; i < kLenNumHighSymbols; i++) + p->high[i] = kProbInitValue; } -static void LenEnc_Encode(CLenEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState) +static void LenEnc_Encode(CLenEnc *p, CRangeEnc *rc, unsigned sym, unsigned posState) { - if (symbol < kLenNumLowSymbols) + UInt32 range, ttt, newBound; + CLzmaProb *probs = p->low; + range = rc->range; + RC_BIT_PRE(rc, probs) + if (sym >= kLenNumLowSymbols) + { + RC_BIT_1(rc, probs) + probs += kLenNumLowSymbols; + RC_BIT_PRE(rc, probs) + if (sym >= kLenNumLowSymbols * 2) { - RangeEnc_EncodeBit(rc, &p->choice, 0); - RcTree_Encode(rc, p->low + (posState << kLenNumLowBits), kLenNumLowBits, symbol); - } - else - { - RangeEnc_EncodeBit(rc, &p->choice, 1); - if (symbol < kLenNumLowSymbols + kLenNumMidSymbols) - { - RangeEnc_EncodeBit(rc, &p->choice2, 0); - RcTree_Encode(rc, p->mid + (posState << kLenNumMidBits), kLenNumMidBits, symbol - kLenNumLowSymbols); - } - else - { - RangeEnc_EncodeBit(rc, &p->choice2, 1); - RcTree_Encode(rc, p->high, kLenNumHighBits, symbol - kLenNumLowSymbols - kLenNumMidSymbols); - } + RC_BIT_1(rc, probs) + rc->range = range; + // RcTree_Encode(rc, p->high, kLenNumHighBits, sym - kLenNumLowSymbols * 2); + LitEnc_Encode(rc, p->high, sym - kLenNumLowSymbols * 2); + return; } + sym -= kLenNumLowSymbols; + } + + // RcTree_Encode(rc, probs + (posState << kLenNumLowBits), kLenNumLowBits, sym); + { + unsigned m; + unsigned bit; + RC_BIT_0(rc, probs) + probs += (posState << (1 + kLenNumLowBits)); + bit = (sym >> 2) ; RC_BIT(rc, probs + 1, bit) m = (1 << 1) + bit; + bit = (sym >> 1) & 1; RC_BIT(rc, probs + m, bit) m = (m << 1) + bit; + bit = sym & 1; RC_BIT(rc, probs + m, bit) + rc->range = range; + } } -static void LenEnc_SetPrices(CLenEnc *p, UInt32 posState, UInt32 numSymbols, UInt32 *prices, UInt32 *ProbPrices) +static void SetPrices_3(const CLzmaProb *probs, UInt32 startPrice, UInt32 *prices, const CProbPrice *ProbPrices) { - UInt32 a0 = GET_PRICE_0a(p->choice); - UInt32 a1 = GET_PRICE_1a(p->choice); - UInt32 b0 = a1 + GET_PRICE_0a(p->choice2); - UInt32 b1 = a1 + GET_PRICE_1a(p->choice2); - UInt32 i = 0; - for (i = 0; i < kLenNumLowSymbols; i++) - { - if (i >= numSymbols) - return; - prices[i] = a0 + RcTree_GetPrice(p->low + (posState << kLenNumLowBits), kLenNumLowBits, i, ProbPrices); - } - for (; i < kLenNumLowSymbols + kLenNumMidSymbols; i++) - { - if (i >= numSymbols) - return; - prices[i] = b0 + RcTree_GetPrice(p->mid + (posState << kLenNumMidBits), kLenNumMidBits, i - kLenNumLowSymbols, ProbPrices); - } - for (; i < numSymbols; i++) - prices[i] = b1 + RcTree_GetPrice(p->high, kLenNumHighBits, i - kLenNumLowSymbols - kLenNumMidSymbols, ProbPrices); + unsigned i; + for (i = 0; i < 8; i += 2) + { + UInt32 price = startPrice; + UInt32 prob; + price += GET_PRICEa(probs[1 ], (i >> 2)); + price += GET_PRICEa(probs[2 + (i >> 2)], (i >> 1) & 1); + prob = probs[4 + (i >> 1)]; + prices[i ] = price + GET_PRICEa_0(prob); + prices[i + 1] = price + GET_PRICEa_1(prob); + } } -static void MY_FAST_CALL LenPriceEnc_UpdateTable(CLenPriceEnc *p, UInt32 posState, UInt32 *ProbPrices) -{ - LenEnc_SetPrices(&p->p, posState, p->tableSize, p->prices[posState], ProbPrices); - p->counters[posState] = p->tableSize; -} -static void LenPriceEnc_UpdateTables(CLenPriceEnc *p, UInt32 numPosStates, UInt32 *ProbPrices) +Z7_NO_INLINE static void Z7_FASTCALL LenPriceEnc_UpdateTables( + CLenPriceEnc *p, + unsigned numPosStates, + const CLenEnc *enc, + const CProbPrice *ProbPrices) { - UInt32 posState; + UInt32 b; + + { + unsigned prob = enc->low[0]; + UInt32 a, c; + unsigned posState; + b = GET_PRICEa_1(prob); + a = GET_PRICEa_0(prob); + c = b + GET_PRICEa_0(enc->low[kLenNumLowSymbols]); for (posState = 0; posState < numPosStates; posState++) - LenPriceEnc_UpdateTable(p, posState, ProbPrices); -} - -static void LenEnc_Encode2(CLenPriceEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState, Bool updatePrice, UInt32 *ProbPrices) -{ - LenEnc_Encode(&p->p, rc, symbol, posState); - if (updatePrice) - if (--p->counters[posState] == 0) - LenPriceEnc_UpdateTable(p, posState, ProbPrices); -} - -static void MovePos(CLzmaEnc *p, UInt32 num) -{ -#ifdef SHOW_STAT - ttt += num; - printf("\n MovePos %d", num); -#endif - if (num != 0) { - p->additionalOffset += num; - p->matchFinder.Skip(p->matchFinderObj, num); + UInt32 *prices = p->prices[posState]; + const CLzmaProb *probs = enc->low + (posState << (1 + kLenNumLowBits)); + SetPrices_3(probs, a, prices, ProbPrices); + SetPrices_3(probs + kLenNumLowSymbols, c, prices + kLenNumLowSymbols, ProbPrices); } -} + } -static UInt32 ReadMatchDistances(CLzmaEnc *p, UInt32 *numDistancePairsRes) -{ - UInt32 lenRes = 0, numPairs; - p->numAvail = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj); - numPairs = p->matchFinder.GetMatches(p->matchFinderObj, p->matches); -#ifdef SHOW_STAT - printf("\n i = %d numPairs = %d ", ttt, numPairs / 2); - ttt++; + /* + { + unsigned i; + UInt32 b; + a = GET_PRICEa_0(enc->low[0]); + for (i = 0; i < kLenNumLowSymbols; i++) + p->prices2[i] = a; + a = GET_PRICEa_1(enc->low[0]); + b = a + GET_PRICEa_0(enc->low[kLenNumLowSymbols]); + for (i = kLenNumLowSymbols; i < kLenNumLowSymbols * 2; i++) + p->prices2[i] = b; + a += GET_PRICEa_1(enc->low[kLenNumLowSymbols]); + } + */ + + // p->counter = numSymbols; + // p->counter = 64; + + { + unsigned i = p->tableSize; + + if (i > kLenNumLowSymbols * 2) { - UInt32 i; - for (i = 0; i < numPairs; i += 2) - printf("%2d %6d | ", p->matches[i], p->matches[i + 1]); - } -#endif - if (numPairs > 0) - { - lenRes = p->matches[numPairs - 2]; - if (lenRes == p->numFastBytes) + const CLzmaProb *probs = enc->high; + UInt32 *prices = p->prices[0] + kLenNumLowSymbols * 2; + i -= kLenNumLowSymbols * 2 - 1; + i >>= 1; + b += GET_PRICEa_1(enc->low[kLenNumLowSymbols]); + do + { + /* + p->prices2[i] = a + + // RcTree_GetPrice(enc->high, kLenNumHighBits, i - kLenNumLowSymbols * 2, ProbPrices); + LitEnc_GetPrice(probs, i - kLenNumLowSymbols * 2, ProbPrices); + */ + // UInt32 price = a + RcTree_GetPrice(probs, kLenNumHighBits - 1, sym, ProbPrices); + unsigned sym = --i + (1 << (kLenNumHighBits - 1)); + UInt32 price = b; + do { - const Byte *pby = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; - UInt32 distance = p->matches[numPairs - 1] + 1; - UInt32 numAvail = p->numAvail; - if (numAvail > LZMA_MATCH_LEN_MAX) - numAvail = LZMA_MATCH_LEN_MAX; - { - const Byte *pby2 = pby - distance; - for (; lenRes < numAvail && pby[lenRes] == pby2[lenRes]; lenRes++); - } + const unsigned bit = sym & 1; + sym >>= 1; + price += GET_PRICEa(probs[sym], bit); } + while (sym >= 2); + + { + const unsigned prob = probs[(size_t)i + (1 << (kLenNumHighBits - 1))]; + prices[(size_t)i * 2 ] = price + GET_PRICEa_0(prob); + prices[(size_t)i * 2 + 1] = price + GET_PRICEa_1(prob); + } + } + while (i); + + { + unsigned posState; + const size_t num = (p->tableSize - kLenNumLowSymbols * 2) * sizeof(p->prices[0][0]); + for (posState = 1; posState < numPosStates; posState++) + memcpy(p->prices[posState] + kLenNumLowSymbols * 2, p->prices[0] + kLenNumLowSymbols * 2, num); + } } - p->additionalOffset++; - *numDistancePairsRes = numPairs; - return lenRes; + } } -#define MakeAsChar(p) (p)->backPrev = (UInt32)(-1); (p)->prev1IsChar = False; -#define MakeAsShortRep(p) (p)->backPrev = 0; (p)->prev1IsChar = False; -#define IsShortRep(p) ((p)->backPrev == 0) +/* + #ifdef SHOW_STAT + g_STAT_OFFSET += num; + printf("\n MovePos %u", num); + #endif +*/ + +#define MOVE_POS(p, num) { \ + p->additionalOffset += (num); \ + p->matchFinder.Skip(p->matchFinderObj, (UInt32)(num)); } -static UInt32 GetRepLen1Price(CLzmaEnc *p, UInt32 state, UInt32 posState) -{ - return - GET_PRICE_0(p->isRepG0[state]) + - GET_PRICE_0(p->isRep0Long[state][posState]); -} -static UInt32 GetPureRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 state, UInt32 posState) +static unsigned ReadMatchDistances(CLzmaEnc *p, unsigned *numPairsRes) { - UInt32 price; - if (repIndex == 0) + unsigned numPairs; + + p->additionalOffset++; + p->numAvail = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj); + { + const UInt32 *d = p->matchFinder.GetMatches(p->matchFinderObj, p->matches); + // if (!d) { p->mf_Failure = True; *numPairsRes = 0; return 0; } + numPairs = (unsigned)(d - p->matches); + } + *numPairsRes = numPairs; + + #ifdef SHOW_STAT + printf("\n i = %u numPairs = %u ", g_STAT_OFFSET, numPairs / 2); + g_STAT_OFFSET++; + { + unsigned i; + for (i = 0; i < numPairs; i += 2) + printf("%2u %6u | ", p->matches[i], p->matches[i + 1]); + } + #endif + + if (numPairs == 0) + return 0; + { + const unsigned len = p->matches[(size_t)numPairs - 2]; + if (len != p->numFastBytes) + return len; { - price = GET_PRICE_0(p->isRepG0[state]); - price += GET_PRICE_1(p->isRep0Long[state][posState]); + UInt32 numAvail = p->numAvail; + if (numAvail > LZMA_MATCH_LEN_MAX) + numAvail = LZMA_MATCH_LEN_MAX; + { + const Byte *p1 = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; + const Byte *p2 = p1 + len; + const ptrdiff_t dif = (ptrdiff_t)-1 - (ptrdiff_t)p->matches[(size_t)numPairs - 1]; + const Byte *lim = p1 + numAvail; + for (; p2 != lim && *p2 == p2[dif]; p2++) + {} + return (unsigned)(p2 - p1); + } } + } +} + +#define MARK_LIT ((UInt32)(Int32)-1) + +#define MakeAs_Lit(p) { (p)->dist = MARK_LIT; (p)->extra = 0; } +#define MakeAs_ShortRep(p) { (p)->dist = 0; (p)->extra = 0; } +#define IsShortRep(p) ((p)->dist == 0) + + +#define GetPrice_ShortRep(p, state, posState) \ + ( GET_PRICE_0(p->isRepG0[state]) + GET_PRICE_0(p->isRep0Long[state][posState])) + +#define GetPrice_Rep_0(p, state, posState) ( \ + GET_PRICE_1(p->isMatch[state][posState]) \ + + GET_PRICE_1(p->isRep0Long[state][posState])) \ + + GET_PRICE_1(p->isRep[state]) \ + + GET_PRICE_0(p->isRepG0[state]) + +Z7_FORCE_INLINE +static UInt32 GetPrice_PureRep(const CLzmaEnc *p, unsigned repIndex, size_t state, size_t posState) +{ + UInt32 price; + UInt32 prob = p->isRepG0[state]; + if (repIndex == 0) + { + price = GET_PRICE_0(prob); + price += GET_PRICE_1(p->isRep0Long[state][posState]); + } + else + { + price = GET_PRICE_1(prob); + prob = p->isRepG1[state]; + if (repIndex == 1) + price += GET_PRICE_0(prob); else { - price = GET_PRICE_1(p->isRepG0[state]); - if (repIndex == 1) - price += GET_PRICE_0(p->isRepG1[state]); - else - { - price += GET_PRICE_1(p->isRepG1[state]); - price += GET_PRICE(p->isRepG2[state], repIndex - 2); - } + price += GET_PRICE_1(prob); + price += GET_PRICE(p->isRepG2[state], repIndex - 2); } - return price; + } + return price; } -static UInt32 GetRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 len, UInt32 state, UInt32 posState) + +static unsigned Backward(CLzmaEnc *p, unsigned cur) { - return p->repLenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN] + - GetPureRepPrice(p, repIndex, state, posState); -} + unsigned wr = cur + 1; + p->optEnd = wr; -static UInt32 Backward(CLzmaEnc *p, UInt32 *backRes, UInt32 cur) -{ - UInt32 posMem = p->opt[cur].posPrev; - UInt32 backMem = p->opt[cur].backPrev; - p->optimumEndIndex = cur; - do + for (;;) + { + UInt32 dist = p->opt[cur].dist; + unsigned len = (unsigned)p->opt[cur].len; + unsigned extra = (unsigned)p->opt[cur].extra; + cur -= len; + + if (extra) { - if (p->opt[cur].prev1IsChar) - { - MakeAsChar(&p->opt[posMem]) - p->opt[posMem].posPrev = posMem - 1; - if (p->opt[cur].prev2) - { - p->opt[posMem - 1].prev1IsChar = False; - p->opt[posMem - 1].posPrev = p->opt[cur].posPrev2; - p->opt[posMem - 1].backPrev = p->opt[cur].backPrev2; - } - } - { - UInt32 posPrev = posMem; - UInt32 backCur = backMem; - - backMem = p->opt[posPrev].backPrev; - posMem = p->opt[posPrev].posPrev; - - p->opt[posPrev].backPrev = backCur; - p->opt[posPrev].posPrev = cur; - cur = posPrev; + wr--; + p->opt[wr].len = (UInt32)len; + cur -= extra; + len = extra; + if (extra == 1) + { + p->opt[wr].dist = dist; + dist = MARK_LIT; + } + else + { + p->opt[wr].dist = 0; + len--; + wr--; + p->opt[wr].dist = MARK_LIT; + p->opt[wr].len = 1; + } } - } while (cur != 0); - *backRes = p->opt[0].backPrev; - p->optimumCurrentIndex = p->opt[0].posPrev; - return p->optimumCurrentIndex; + + if (cur == 0) + { + p->backRes = dist; + p->optCur = wr; + return len; + } + + wr--; + p->opt[wr].dist = dist; + p->opt[wr].len = (UInt32)len; + } } -#define LIT_PROBS(pos, prevByte) (p->litProbs + ((((pos) & p->lpMask) << p->lc) + ((prevByte) >> (8 - p->lc))) * 0x300) -static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes) + +#define LIT_PROBS(pos, prevByte) \ + (p->litProbs + (UInt32)3 * (((((pos) << 8) + (prevByte)) & p->lpMask) << p->lc)) + + +static unsigned GetOptimum(CLzmaEnc *p, UInt32 position) { - UInt32 numAvail, mainLen, numPairs, repMaxIndex, i, posState, lenEnd, len, cur; - UInt32 matchPrice, repMatchPrice, normalMatchPrice; - UInt32 reps[LZMA_NUM_REPS], repLens[LZMA_NUM_REPS]; - UInt32 *matches; + unsigned last, cur; + UInt32 reps[LZMA_NUM_REPS]; + unsigned repLens[LZMA_NUM_REPS]; + UInt32 *matches; + + { + UInt32 numAvail; + unsigned numPairs, mainLen, repMaxIndex, i, posState; + UInt32 matchPrice, repMatchPrice; const Byte *data; Byte curByte, matchByte; - if (p->optimumEndIndex != p->optimumCurrentIndex) - { - const COptimal *opt = &p->opt[p->optimumCurrentIndex]; - UInt32 lenRes = opt->posPrev - p->optimumCurrentIndex; - *backRes = opt->backPrev; - p->optimumCurrentIndex = opt->posPrev; - return lenRes; - } - p->optimumCurrentIndex = p->optimumEndIndex = 0; - + + p->optCur = p->optEnd = 0; + if (p->additionalOffset == 0) - mainLen = ReadMatchDistances(p, &numPairs); + mainLen = ReadMatchDistances(p, &numPairs); else { - mainLen = p->longestMatchLength; - numPairs = p->numPairs; + mainLen = p->longestMatchLen; + numPairs = p->numPairs; } - + numAvail = p->numAvail; if (numAvail < 2) { - *backRes = (UInt32)(-1); - return 1; + p->backRes = MARK_LIT; + return 1; } if (numAvail > LZMA_MATCH_LEN_MAX) - numAvail = LZMA_MATCH_LEN_MAX; - + numAvail = LZMA_MATCH_LEN_MAX; + data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; repMaxIndex = 0; + for (i = 0; i < LZMA_NUM_REPS; i++) { - UInt32 lenTest; - const Byte *data2; - reps[i] = p->reps[i]; - data2 = data - (reps[i] + 1); - if (data[0] != data2[0] || data[1] != data2[1]) - { - repLens[i] = 0; - continue; - } - for (lenTest = 2; lenTest < numAvail && data[lenTest] == data2[lenTest]; lenTest++); - repLens[i] = lenTest; - if (lenTest > repLens[repMaxIndex]) - repMaxIndex = i; + unsigned len; + const Byte *data2; + reps[i] = p->reps[i]; + data2 = data - reps[i]; + if (data[0] != data2[0] || data[1] != data2[1]) + { + repLens[i] = 0; + continue; + } + for (len = 2; len < numAvail && data[len] == data2[len]; len++) + {} + repLens[i] = len; + if (len > repLens[repMaxIndex]) + repMaxIndex = i; + if (len == LZMA_MATCH_LEN_MAX) // 21.03 : optimization + break; } + if (repLens[repMaxIndex] >= p->numFastBytes) { - UInt32 lenRes; - *backRes = repMaxIndex; - lenRes = repLens[repMaxIndex]; - MovePos(p, lenRes - 1); - return lenRes; + unsigned len; + p->backRes = (UInt32)repMaxIndex; + len = repLens[repMaxIndex]; + MOVE_POS(p, len - 1) + return len; } - + matches = p->matches; + #define MATCHES matches + // #define MATCHES p->matches + if (mainLen >= p->numFastBytes) { - *backRes = matches[numPairs - 1] + LZMA_NUM_REPS; - MovePos(p, mainLen - 1); - return mainLen; + p->backRes = MATCHES[(size_t)numPairs - 1] + LZMA_NUM_REPS; + MOVE_POS(p, mainLen - 1) + return mainLen; } + curByte = *data; - matchByte = *(data - (reps[0] + 1)); + matchByte = *(data - reps[0]); - if (mainLen < 2 && curByte != matchByte && repLens[repMaxIndex] < 2) + last = repLens[repMaxIndex]; + if (last <= mainLen) + last = mainLen; + + if (last < 2 && curByte != matchByte) { - *backRes = (UInt32)-1; - return 1; + p->backRes = MARK_LIT; + return 1; } - + p->opt[0].state = (CState)p->state; - + posState = (position & p->pbMask); - + { - const CLzmaProb *probs = LIT_PROBS(position, *(data - 1)); - p->opt[1].price = GET_PRICE_0(p->isMatch[p->state][posState]) + - (!IsCharState(p->state) ? - LitEnc_GetPriceMatched(probs, curByte, matchByte, p->ProbPrices) : - LitEnc_GetPrice(probs, curByte, p->ProbPrices)); + const CLzmaProb *probs = LIT_PROBS(position, *(data - 1)); + p->opt[1].price = GET_PRICE_0(p->isMatch[p->state][posState]) + + (!IsLitState(p->state) ? + LitEnc_Matched_GetPrice(probs, curByte, matchByte, p->ProbPrices) : + LitEnc_GetPrice(probs, curByte, p->ProbPrices)); } - MakeAsChar(&p->opt[1]); - + MakeAs_Lit(&p->opt[1]) + matchPrice = GET_PRICE_1(p->isMatch[p->state][posState]); repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[p->state]); - - if (matchByte == curByte) + + // 18.06 + if (matchByte == curByte && repLens[0] == 0) { - UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, p->state, posState); - if (shortRepPrice < p->opt[1].price) - { - p->opt[1].price = shortRepPrice; - MakeAsShortRep(&p->opt[1]); - } - } - lenEnd = ((mainLen >= repLens[repMaxIndex]) ? mainLen : repLens[repMaxIndex]); - - if (lenEnd < 2) - { - *backRes = p->opt[1].backPrev; + UInt32 shortRepPrice = repMatchPrice + GetPrice_ShortRep(p, p->state, posState); + if (shortRepPrice < p->opt[1].price) + { + p->opt[1].price = shortRepPrice; + MakeAs_ShortRep(&p->opt[1]) + } + if (last < 2) + { + p->backRes = p->opt[1].dist; return 1; + } } - - p->opt[1].posPrev = 0; - for (i = 0; i < LZMA_NUM_REPS; i++) - p->opt[0].backs[i] = reps[i]; - - len = lenEnd; - do - p->opt[len--].price = kInfinityPrice; - while (len >= 2); - + + p->opt[1].len = 1; + + p->opt[0].reps[0] = reps[0]; + p->opt[0].reps[1] = reps[1]; + p->opt[0].reps[2] = reps[2]; + p->opt[0].reps[3] = reps[3]; + + // ---------- REP ---------- + for (i = 0; i < LZMA_NUM_REPS; i++) { - UInt32 repLen = repLens[i]; - UInt32 price; - if (repLen < 2) - continue; - price = repMatchPrice + GetPureRepPrice(p, i, p->state, posState); - do + unsigned repLen = repLens[i]; + UInt32 price; + if (repLen < 2) + continue; + price = repMatchPrice + GetPrice_PureRep(p, i, p->state, posState); + do + { + UInt32 price2 = price + GET_PRICE_LEN(&p->repLenEnc, posState, repLen); + COptimal *opt = &p->opt[repLen]; + if (price2 < opt->price) { - UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][repLen - 2]; - COptimal *opt = &p->opt[repLen]; - if (curAndLenPrice < opt->price) - { - opt->price = curAndLenPrice; - opt->posPrev = 0; - opt->backPrev = i; - opt->prev1IsChar = False; - } - } while (--repLen >= 2); - } - - normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[p->state]); - - len = ((repLens[0] >= 2) ? repLens[0] + 1 : 2); - if (len <= mainLen) - { - UInt32 offs = 0; - while (len > matches[offs]) - offs += 2; - for (;; len++) - { - COptimal *opt; - UInt32 distance = matches[offs + 1]; - - UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN]; - UInt32 lenToPosState = GetLenToPosState(len); - if (distance < kNumFullDistances) - curAndLenPrice += p->distancesPrices[lenToPosState][distance]; - else - { - UInt32 slot; - GetPosSlot2(distance, slot); - curAndLenPrice += p->alignPrices[distance & kAlignMask] + p->posSlotPrices[lenToPosState][slot]; - } - opt = &p->opt[len]; - if (curAndLenPrice < opt->price) - { - opt->price = curAndLenPrice; - opt->posPrev = 0; - opt->backPrev = distance + LZMA_NUM_REPS; - opt->prev1IsChar = False; - } - if (len == matches[offs]) - { - offs += 2; - if (offs == numPairs) - break; - } + opt->price = price2; + opt->len = (UInt32)repLen; + opt->dist = (UInt32)i; + opt->extra = 0; } + } + while (--repLen >= 2); } + + + // ---------- MATCH ---------- + { + unsigned len = repLens[0] + 1; + if (len <= mainLen) + { + unsigned offs = 0; + UInt32 normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[p->state]); + + if (len < 2) + len = 2; + else + while (len > MATCHES[offs]) + offs += 2; + + for (; ; len++) + { + COptimal *opt; + UInt32 dist = MATCHES[(size_t)offs + 1]; + UInt32 price = normalMatchPrice + GET_PRICE_LEN(&p->lenEnc, posState, len); + unsigned lenToPosState = GetLenToPosState(len); + + if (dist < kNumFullDistances) + price += p->distancesPrices[lenToPosState][dist & (kNumFullDistances - 1)]; + else + { + unsigned slot; + GetPosSlot2(dist, slot) + price += p->alignPrices[dist & kAlignMask]; + price += p->posSlotPrices[lenToPosState][slot]; + } + + opt = &p->opt[len]; + + if (price < opt->price) + { + opt->price = price; + opt->len = (UInt32)len; + opt->dist = dist + LZMA_NUM_REPS; + opt->extra = 0; + } + + if (len == MATCHES[offs]) + { + offs += 2; + if (offs == numPairs) + break; + } + } + } + } + cur = 0; -#ifdef SHOW_STAT2 - if (position >= 0) + #ifdef SHOW_STAT2 + /* if (position >= 0) */ { - unsigned i; - printf("\n pos = %4X", position); - for (i = cur; i <= lenEnd; i++) - printf("\nprice[%4X] = %d", position - cur + i, p->opt[i].price); + unsigned i; + printf("\n pos = %4X", position); + for (i = cur; i <= last; i++) + printf("\nprice[%4X] = %u", position - cur + i, p->opt[i].price); } -#endif + #endif + } - for (;;) + + + // ---------- Optimal Parsing ---------- + + for (;;) + { + unsigned numAvail; + UInt32 numAvailFull; + unsigned newLen, numPairs, prev, state, posState, startLen; + UInt32 litPrice, matchPrice, repMatchPrice; + BoolInt nextIsLit; + Byte curByte, matchByte; + const Byte *data; + COptimal *curOpt, *nextOpt; + + if (++cur == last) + break; + + // 18.06 + if (cur >= kNumOpts - 64) { - UInt32 numAvailFull, newLen, numPairs, posPrev, state, posState, startLen; - UInt32 curPrice, curAnd1Price, matchPrice, repMatchPrice; - Bool nextIsChar; - Byte curByte, matchByte; - const Byte *data; - COptimal *curOpt; - COptimal *nextOpt; - - cur++; - if (cur == lenEnd) - return Backward(p, backRes, cur); - - newLen = ReadMatchDistances(p, &numPairs); - if (newLen >= p->numFastBytes) + unsigned j, best; + UInt32 price = p->opt[cur].price; + best = cur; + for (j = cur + 1; j <= last; j++) + { + UInt32 price2 = p->opt[j].price; + if (price >= price2) { - p->numPairs = numPairs; - p->longestMatchLength = newLen; - return Backward(p, backRes, cur); + price = price2; + best = j; } - position++; - curOpt = &p->opt[cur]; - posPrev = curOpt->posPrev; - if (curOpt->prev1IsChar) + } + { + unsigned delta = best - cur; + if (delta != 0) { - posPrev--; - if (curOpt->prev2) - { - state = p->opt[curOpt->posPrev2].state; - if (curOpt->backPrev2 < LZMA_NUM_REPS) - state = kRepNextStates[state]; - else - state = kMatchNextStates[state]; - } - else - state = p->opt[posPrev].state; - state = kLiteralNextStates[state]; + MOVE_POS(p, delta) } + } + cur = best; + break; + } + + newLen = ReadMatchDistances(p, &numPairs); + + if (newLen >= p->numFastBytes) + { + p->numPairs = numPairs; + p->longestMatchLen = newLen; + break; + } + + curOpt = &p->opt[cur]; + + position++; + + // we need that check here, if skip_items in p->opt are possible + /* + if (curOpt->price >= kInfinityPrice) + continue; + */ + + prev = cur - curOpt->len; + + if (curOpt->len == 1) + { + state = (unsigned)p->opt[prev].state; + if (IsShortRep(curOpt)) + state = kShortRepNextStates[state]; + else + state = kLiteralNextStates[state]; + } + else + { + const COptimal *prevOpt; + UInt32 b0; + UInt32 dist = curOpt->dist; + + if (curOpt->extra) + { + prev -= (unsigned)curOpt->extra; + state = kState_RepAfterLit; + if (curOpt->extra == 1) + state = (dist < LZMA_NUM_REPS ? kState_RepAfterLit : kState_MatchAfterLit); + } + else + { + state = (unsigned)p->opt[prev].state; + if (dist < LZMA_NUM_REPS) + state = kRepNextStates[state]; else - state = p->opt[posPrev].state; - if (posPrev == cur - 1) + state = kMatchNextStates[state]; + } + + prevOpt = &p->opt[prev]; + b0 = prevOpt->reps[0]; + + if (dist < LZMA_NUM_REPS) + { + if (dist == 0) { - if (IsShortRep(curOpt)) - state = kShortRepNextStates[state]; - else - state = kLiteralNextStates[state]; + reps[0] = b0; + reps[1] = prevOpt->reps[1]; + reps[2] = prevOpt->reps[2]; + reps[3] = prevOpt->reps[3]; } else { - UInt32 pos; - const COptimal *prevOpt; - if (curOpt->prev1IsChar && curOpt->prev2) + reps[1] = b0; + b0 = prevOpt->reps[1]; + if (dist == 1) + { + reps[0] = b0; + reps[2] = prevOpt->reps[2]; + reps[3] = prevOpt->reps[3]; + } + else + { + reps[2] = b0; + reps[0] = prevOpt->reps[dist]; + reps[3] = prevOpt->reps[dist ^ 1]; + } + } + } + else + { + reps[0] = (dist - LZMA_NUM_REPS + 1); + reps[1] = b0; + reps[2] = prevOpt->reps[1]; + reps[3] = prevOpt->reps[2]; + } + } + + curOpt->state = (CState)state; + curOpt->reps[0] = reps[0]; + curOpt->reps[1] = reps[1]; + curOpt->reps[2] = reps[2]; + curOpt->reps[3] = reps[3]; + + data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; + curByte = *data; + matchByte = *(data - reps[0]); + + posState = (position & p->pbMask); + + /* + The order of Price checks: + < LIT + <= SHORT_REP + < LIT : REP_0 + < REP [ : LIT : REP_0 ] + < MATCH [ : LIT : REP_0 ] + */ + + { + UInt32 curPrice = curOpt->price; + unsigned prob = p->isMatch[state][posState]; + matchPrice = curPrice + GET_PRICE_1(prob); + litPrice = curPrice + GET_PRICE_0(prob); + } + + nextOpt = &p->opt[(size_t)cur + 1]; + nextIsLit = False; + + // here we can allow skip_items in p->opt, if we don't check (nextOpt->price < kInfinityPrice) + // 18.new.06 + if ((nextOpt->price < kInfinityPrice + // && !IsLitState(state) + && matchByte == curByte) + || litPrice > nextOpt->price + ) + litPrice = 0; + else + { + const CLzmaProb *probs = LIT_PROBS(position, *(data - 1)); + litPrice += (!IsLitState(state) ? + LitEnc_Matched_GetPrice(probs, curByte, matchByte, p->ProbPrices) : + LitEnc_GetPrice(probs, curByte, p->ProbPrices)); + + if (litPrice < nextOpt->price) + { + nextOpt->price = litPrice; + nextOpt->len = 1; + MakeAs_Lit(nextOpt) + nextIsLit = True; + } + } + + repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[state]); + + numAvailFull = p->numAvail; + { + unsigned temp = kNumOpts - 1 - cur; + if (numAvailFull > temp) + numAvailFull = (UInt32)temp; + } + + // 18.06 + // ---------- SHORT_REP ---------- + if (IsLitState(state)) // 18.new + if (matchByte == curByte) + if (repMatchPrice < nextOpt->price) // 18.new + // if (numAvailFull < 2 || data[1] != *(data - reps[0] + 1)) + if ( + // nextOpt->price >= kInfinityPrice || + nextOpt->len < 2 // we can check nextOpt->len, if skip items are not allowed in p->opt + || (nextOpt->dist != 0 + // && nextOpt->extra <= 1 // 17.old + ) + ) + { + UInt32 shortRepPrice = repMatchPrice + GetPrice_ShortRep(p, state, posState); + // if (shortRepPrice <= nextOpt->price) // 17.old + if (shortRepPrice < nextOpt->price) // 18.new + { + nextOpt->price = shortRepPrice; + nextOpt->len = 1; + MakeAs_ShortRep(nextOpt) + nextIsLit = False; + } + } + + if (numAvailFull < 2) + continue; + numAvail = (numAvailFull <= p->numFastBytes ? numAvailFull : p->numFastBytes); + + // numAvail <= p->numFastBytes + + // ---------- LIT : REP_0 ---------- + + if (!nextIsLit + && litPrice != 0 // 18.new + && matchByte != curByte + && numAvailFull > 2) + { + const Byte *data2 = data - reps[0]; + if (data[1] == data2[1] && data[2] == data2[2]) + { + unsigned len; + unsigned limit = p->numFastBytes + 1; + if (limit > numAvailFull) + limit = numAvailFull; + for (len = 3; len < limit && data[len] == data2[len]; len++) + {} + + { + unsigned state2 = kLiteralNextStates[state]; + unsigned posState2 = (position + 1) & p->pbMask; + UInt32 price = litPrice + GetPrice_Rep_0(p, state2, posState2); + { + unsigned offset = cur + len; + + if (last < offset) + last = offset; + + // do { - posPrev = curOpt->posPrev2; - pos = curOpt->backPrev2; - state = kRepNextStates[state]; + UInt32 price2; + COptimal *opt; + len--; + // price2 = price + GetPrice_Len_Rep_0(p, len, state2, posState2); + price2 = price + GET_PRICE_LEN(&p->repLenEnc, posState2, len); + + opt = &p->opt[offset]; + // offset--; + if (price2 < opt->price) + { + opt->price = price2; + opt->len = (UInt32)len; + opt->dist = 0; + opt->extra = 1; + } } - else + // while (len >= 3); + } + } + } + } + + startLen = 2; /* speed optimization */ + + { + // ---------- REP ---------- + unsigned repIndex = 0; // 17.old + // unsigned repIndex = IsLitState(state) ? 0 : 1; // 18.notused + for (; repIndex < LZMA_NUM_REPS; repIndex++) + { + unsigned len; + UInt32 price; + const Byte *data2 = data - reps[repIndex]; + if (data[0] != data2[0] || data[1] != data2[1]) + continue; + + for (len = 2; len < numAvail && data[len] == data2[len]; len++) + {} + + // if (len < startLen) continue; // 18.new: speed optimization + + { + unsigned offset = cur + len; + if (last < offset) + last = offset; + } + { + unsigned len2 = len; + price = repMatchPrice + GetPrice_PureRep(p, repIndex, state, posState); + do + { + UInt32 price2 = price + GET_PRICE_LEN(&p->repLenEnc, posState, len2); + COptimal *opt = &p->opt[cur + len2]; + if (price2 < opt->price) { - pos = curOpt->backPrev; - if (pos < LZMA_NUM_REPS) - state = kRepNextStates[state]; - else - state = kMatchNextStates[state]; + opt->price = price2; + opt->len = (UInt32)len2; + opt->dist = (UInt32)repIndex; + opt->extra = 0; } - prevOpt = &p->opt[posPrev]; - if (pos < LZMA_NUM_REPS) + } + while (--len2 >= 2); + } + + if (repIndex == 0) startLen = len + 1; // 17.old + // startLen = len + 1; // 18.new + + /* if (_maxMode) */ + { + // ---------- REP : LIT : REP_0 ---------- + // numFastBytes + 1 + numFastBytes + + unsigned len2 = len + 1; + unsigned limit = len2 + p->numFastBytes; + if (limit > numAvailFull) + limit = numAvailFull; + + len2 += 2; + if (len2 <= limit) + if (data[len2 - 2] == data2[len2 - 2]) + if (data[len2 - 1] == data2[len2 - 1]) + { + unsigned state2 = kRepNextStates[state]; + unsigned posState2 = (position + len) & p->pbMask; + price += GET_PRICE_LEN(&p->repLenEnc, posState, len) + + GET_PRICE_0(p->isMatch[state2][posState2]) + + LitEnc_Matched_GetPrice(LIT_PROBS(position + len, data[(size_t)len - 1]), + data[len], data2[len], p->ProbPrices); + + // state2 = kLiteralNextStates[state2]; + state2 = kState_LitAfterRep; + posState2 = (posState2 + 1) & p->pbMask; + + + price += GetPrice_Rep_0(p, state2, posState2); + + for (; len2 < limit && data[len2] == data2[len2]; len2++) + {} + + len2 -= len; + // if (len2 >= 3) + { { - UInt32 i; - reps[0] = prevOpt->backs[pos]; - for (i = 1; i <= pos; i++) - reps[i] = prevOpt->backs[i - 1]; - for (; i < LZMA_NUM_REPS; i++) - reps[i] = prevOpt->backs[i]; - } - else - { - UInt32 i; - reps[0] = (pos - LZMA_NUM_REPS); - for (i = 1; i < LZMA_NUM_REPS; i++) - reps[i] = prevOpt->backs[i - 1]; - } - } - curOpt->state = (CState)state; + unsigned offset = cur + len + len2; - curOpt->backs[0] = reps[0]; - curOpt->backs[1] = reps[1]; - curOpt->backs[2] = reps[2]; - curOpt->backs[3] = reps[3]; - - curPrice = curOpt->price; - nextIsChar = False; - data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; - curByte = *data; - matchByte = *(data - (reps[0] + 1)); - - posState = (position & p->pbMask); - - curAnd1Price = curPrice + GET_PRICE_0(p->isMatch[state][posState]); - { - const CLzmaProb *probs = LIT_PROBS(position, *(data - 1)); - curAnd1Price += - (!IsCharState(state) ? - LitEnc_GetPriceMatched(probs, curByte, matchByte, p->ProbPrices) : - LitEnc_GetPrice(probs, curByte, p->ProbPrices)); - } - - nextOpt = &p->opt[cur + 1]; - - if (curAnd1Price < nextOpt->price) - { - nextOpt->price = curAnd1Price; - nextOpt->posPrev = cur; - MakeAsChar(nextOpt); - nextIsChar = True; - } - - matchPrice = curPrice + GET_PRICE_1(p->isMatch[state][posState]); - repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[state]); - - if (matchByte == curByte && !(nextOpt->posPrev < cur && nextOpt->backPrev == 0)) - { - UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, state, posState); - if (shortRepPrice <= nextOpt->price) - { - nextOpt->price = shortRepPrice; - nextOpt->posPrev = cur; - MakeAsShortRep(nextOpt); - nextIsChar = True; - } - } - numAvailFull = p->numAvail; - { - UInt32 temp = kNumOpts - 1 - cur; - if (temp < numAvailFull) - numAvailFull = temp; - } - - if (numAvailFull < 2) - continue; - numAvail = (numAvailFull <= p->numFastBytes ? numAvailFull : p->numFastBytes); - - if (!nextIsChar && matchByte != curByte) /* speed optimization */ - { - /* try Literal + rep0 */ - UInt32 temp; - UInt32 lenTest2; - const Byte *data2 = data - (reps[0] + 1); - UInt32 limit = p->numFastBytes + 1; - if (limit > numAvailFull) - limit = numAvailFull; - - for (temp = 1; temp < limit && data[temp] == data2[temp]; temp++); - lenTest2 = temp - 1; - if (lenTest2 >= 2) - { - UInt32 state2 = kLiteralNextStates[state]; - UInt32 posStateNext = (position + 1) & p->pbMask; - UInt32 nextRepMatchPrice = curAnd1Price + - GET_PRICE_1(p->isMatch[state2][posStateNext]) + - GET_PRICE_1(p->isRep[state2]); - /* for (; lenTest2 >= 2; lenTest2--) */ - { - UInt32 curAndLenPrice; - COptimal *opt; - UInt32 offset = cur + 1 + lenTest2; - while (lenEnd < offset) - p->opt[++lenEnd].price = kInfinityPrice; - curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext); - opt = &p->opt[offset]; - if (curAndLenPrice < opt->price) - { - opt->price = curAndLenPrice; - opt->posPrev = cur + 1; - opt->backPrev = 0; - opt->prev1IsChar = True; - opt->prev2 = False; - } - } - } - } - - startLen = 2; /* speed optimization */ - { - UInt32 repIndex; - for (repIndex = 0; repIndex < LZMA_NUM_REPS; repIndex++) - { - UInt32 lenTest; - UInt32 lenTestTemp; - UInt32 price; - const Byte *data2 = data - (reps[repIndex] + 1); - if (data[0] != data2[0] || data[1] != data2[1]) - continue; - for (lenTest = 2; lenTest < numAvail && data[lenTest] == data2[lenTest]; lenTest++); - while (lenEnd < cur + lenTest) - p->opt[++lenEnd].price = kInfinityPrice; - lenTestTemp = lenTest; - price = repMatchPrice + GetPureRepPrice(p, repIndex, state, posState); - do - { - UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][lenTest - 2]; - COptimal *opt = &p->opt[cur + lenTest]; - if (curAndLenPrice < opt->price) - { - opt->price = curAndLenPrice; - opt->posPrev = cur; - opt->backPrev = repIndex; - opt->prev1IsChar = False; - } - } while (--lenTest >= 2); - lenTest = lenTestTemp; - - if (repIndex == 0) - startLen = lenTest + 1; - - /* if (_maxMode) */ - { - UInt32 lenTest2 = lenTest + 1; - UInt32 limit = lenTest2 + p->numFastBytes; - UInt32 nextRepMatchPrice; - if (limit > numAvailFull) - limit = numAvailFull; - for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++); - lenTest2 -= lenTest + 1; - if (lenTest2 >= 2) - { - UInt32 state2 = kRepNextStates[state]; - UInt32 posStateNext = (position + lenTest) & p->pbMask; - UInt32 curAndLenCharPrice = - price + p->repLenEnc.prices[posState][lenTest - 2] + - GET_PRICE_0(p->isMatch[state2][posStateNext]) + - LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]), - data[lenTest], data2[lenTest], p->ProbPrices); - state2 = kLiteralNextStates[state2]; - posStateNext = (position + lenTest + 1) & p->pbMask; - nextRepMatchPrice = curAndLenCharPrice + - GET_PRICE_1(p->isMatch[state2][posStateNext]) + - GET_PRICE_1(p->isRep[state2]); - - /* for (; lenTest2 >= 2; lenTest2--) */ - { - UInt32 curAndLenPrice; - COptimal *opt; - UInt32 offset = cur + lenTest + 1 + lenTest2; - while (lenEnd < offset) - p->opt[++lenEnd].price = kInfinityPrice; - curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext); - opt = &p->opt[offset]; - if (curAndLenPrice < opt->price) - { - opt->price = curAndLenPrice; - opt->posPrev = cur + lenTest + 1; - opt->backPrev = 0; - opt->prev1IsChar = True; - opt->prev2 = True; - opt->posPrev2 = cur; - opt->backPrev2 = repIndex; - } - } - } - } - } - } - /* for (UInt32 lenTest = 2; lenTest <= newLen; lenTest++) */ - if (newLen > numAvail) - { - newLen = numAvail; - for (numPairs = 0; newLen > matches[numPairs]; numPairs += 2); - matches[numPairs] = newLen; - numPairs += 2; - } - if (newLen >= startLen) - { - UInt32 normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[state]); - UInt32 offs, curBack, posSlot; - UInt32 lenTest; - while (lenEnd < cur + newLen) - p->opt[++lenEnd].price = kInfinityPrice; - - offs = 0; - while (startLen > matches[offs]) - offs += 2; - curBack = matches[offs + 1]; - GetPosSlot2(curBack, posSlot); - for (lenTest = /*2*/ startLen;; lenTest++) - { - UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][lenTest - LZMA_MATCH_LEN_MIN]; - UInt32 lenToPosState = GetLenToPosState(lenTest); + if (last < offset) + last = offset; + // do + { + UInt32 price2; COptimal *opt; - if (curBack < kNumFullDistances) - curAndLenPrice += p->distancesPrices[lenToPosState][curBack]; - else - curAndLenPrice += p->posSlotPrices[lenToPosState][posSlot] + p->alignPrices[curBack & kAlignMask]; + len2--; + // price2 = price + GetPrice_Len_Rep_0(p, len2, state2, posState2); + price2 = price + GET_PRICE_LEN(&p->repLenEnc, posState2, len2); - opt = &p->opt[cur + lenTest]; - if (curAndLenPrice < opt->price) + opt = &p->opt[offset]; + // offset--; + if (price2 < opt->price) { - opt->price = curAndLenPrice; - opt->posPrev = cur; - opt->backPrev = curBack + LZMA_NUM_REPS; - opt->prev1IsChar = False; - } - - if (/*_maxMode && */lenTest == matches[offs]) - { - /* Try Match + Literal + Rep0 */ - const Byte *data2 = data - (curBack + 1); - UInt32 lenTest2 = lenTest + 1; - UInt32 limit = lenTest2 + p->numFastBytes; - UInt32 nextRepMatchPrice; - if (limit > numAvailFull) - limit = numAvailFull; - for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++); - lenTest2 -= lenTest + 1; - if (lenTest2 >= 2) - { - UInt32 state2 = kMatchNextStates[state]; - UInt32 posStateNext = (position + lenTest) & p->pbMask; - UInt32 curAndLenCharPrice = curAndLenPrice + - GET_PRICE_0(p->isMatch[state2][posStateNext]) + - LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]), - data[lenTest], data2[lenTest], p->ProbPrices); - state2 = kLiteralNextStates[state2]; - posStateNext = (posStateNext + 1) & p->pbMask; - nextRepMatchPrice = curAndLenCharPrice + - GET_PRICE_1(p->isMatch[state2][posStateNext]) + - GET_PRICE_1(p->isRep[state2]); - - /* for (; lenTest2 >= 2; lenTest2--) */ - { - UInt32 offset = cur + lenTest + 1 + lenTest2; - UInt32 curAndLenPrice; - COptimal *opt; - while (lenEnd < offset) - p->opt[++lenEnd].price = kInfinityPrice; - curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext); - opt = &p->opt[offset]; - if (curAndLenPrice < opt->price) - { - opt->price = curAndLenPrice; - opt->posPrev = cur + lenTest + 1; - opt->backPrev = 0; - opt->prev1IsChar = True; - opt->prev2 = True; - opt->posPrev2 = cur; - opt->backPrev2 = curBack + LZMA_NUM_REPS; - } - } - } - offs += 2; - if (offs == numPairs) - break; - curBack = matches[offs + 1]; - if (curBack >= kNumFullDistances) - GetPosSlot2(curBack, posSlot); + opt->price = price2; + opt->len = (UInt32)len2; + opt->extra = (CExtra)(len + 1); + opt->dist = (UInt32)repIndex; } + } + // while (len2 >= 3); } + } + } } + } } + + + // ---------- MATCH ---------- + /* for (unsigned len = 2; len <= newLen; len++) */ + if (newLen > numAvail) + { + newLen = numAvail; + for (numPairs = 0; newLen > MATCHES[numPairs]; numPairs += 2); + MATCHES[numPairs] = (UInt32)newLen; + numPairs += 2; + } + + // startLen = 2; /* speed optimization */ + + if (newLen >= startLen) + { + UInt32 normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[state]); + UInt32 dist; + unsigned offs, posSlot, len; + + { + unsigned offset = cur + newLen; + if (last < offset) + last = offset; + } + + offs = 0; + while (startLen > MATCHES[offs]) + offs += 2; + dist = MATCHES[(size_t)offs + 1]; + + // if (dist >= kNumFullDistances) + GetPosSlot2(dist, posSlot) + + for (len = /*2*/ startLen; ; len++) + { + UInt32 price = normalMatchPrice + GET_PRICE_LEN(&p->lenEnc, posState, len); + { + COptimal *opt; + unsigned lenNorm = len - 2; + lenNorm = GetLenToPosState2(lenNorm); + if (dist < kNumFullDistances) + price += p->distancesPrices[lenNorm][dist & (kNumFullDistances - 1)]; + else + price += p->posSlotPrices[lenNorm][posSlot] + p->alignPrices[dist & kAlignMask]; + + opt = &p->opt[cur + len]; + if (price < opt->price) + { + opt->price = price; + opt->len = (UInt32)len; + opt->dist = dist + LZMA_NUM_REPS; + opt->extra = 0; + } + } + + if (len == MATCHES[offs]) + { + // if (p->_maxMode) { + // MATCH : LIT : REP_0 + + const Byte *data2 = data - dist - 1; + unsigned len2 = len + 1; + unsigned limit = len2 + p->numFastBytes; + if (limit > numAvailFull) + limit = numAvailFull; + + len2 += 2; + if (len2 <= limit) + if (data[len2 - 2] == data2[len2 - 2]) + if (data[len2 - 1] == data2[len2 - 1]) + { + for (; len2 < limit && data[len2] == data2[len2]; len2++) + {} + + len2 -= len; + + // if (len2 >= 3) + { + unsigned state2 = kMatchNextStates[state]; + unsigned posState2 = (position + len) & p->pbMask; + unsigned offset; + price += GET_PRICE_0(p->isMatch[state2][posState2]); + price += LitEnc_Matched_GetPrice(LIT_PROBS(position + len, data[(size_t)len - 1]), + data[len], data2[len], p->ProbPrices); + + // state2 = kLiteralNextStates[state2]; + state2 = kState_LitAfterMatch; + + posState2 = (posState2 + 1) & p->pbMask; + price += GetPrice_Rep_0(p, state2, posState2); + + offset = cur + len + len2; + + if (last < offset) + last = offset; + // do + { + UInt32 price2; + COptimal *opt; + len2--; + // price2 = price + GetPrice_Len_Rep_0(p, len2, state2, posState2); + price2 = price + GET_PRICE_LEN(&p->repLenEnc, posState2, len2); + opt = &p->opt[offset]; + // offset--; + if (price2 < opt->price) + { + opt->price = price2; + opt->len = (UInt32)len2; + opt->extra = (CExtra)(len + 1); + opt->dist = dist + LZMA_NUM_REPS; + } + } + // while (len2 >= 3); + } + + } + + offs += 2; + if (offs == numPairs) + break; + dist = MATCHES[(size_t)offs + 1]; + // if (dist >= kNumFullDistances) + GetPosSlot2(dist, posSlot) + } + } + } + } + + do + p->opt[last].price = kInfinityPrice; + while (--last); + + return Backward(p, cur); } + + #define ChangePair(smallDist, bigDist) (((bigDist) >> 7) > (smallDist)) -static UInt32 GetOptimumFast(CLzmaEnc *p, UInt32 *backRes) + + +static unsigned GetOptimumFast(CLzmaEnc *p) { - UInt32 numAvail, mainLen, mainDist, numPairs, repIndex, repLen, i; - const Byte *data; - const UInt32 *matches; + UInt32 numAvail, mainDist; + unsigned mainLen, numPairs, repIndex, repLen, i; + const Byte *data; - if (p->additionalOffset == 0) - mainLen = ReadMatchDistances(p, &numPairs); - else + if (p->additionalOffset == 0) + mainLen = ReadMatchDistances(p, &numPairs); + else + { + mainLen = p->longestMatchLen; + numPairs = p->numPairs; + } + + numAvail = p->numAvail; + p->backRes = MARK_LIT; + if (numAvail < 2) + return 1; + // if (mainLen < 2 && p->state == 0) return 1; // 18.06.notused + if (numAvail > LZMA_MATCH_LEN_MAX) + numAvail = LZMA_MATCH_LEN_MAX; + data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; + repLen = repIndex = 0; + + for (i = 0; i < LZMA_NUM_REPS; i++) + { + unsigned len; + const Byte *data2 = data - p->reps[i]; + if (data[0] != data2[0] || data[1] != data2[1]) + continue; + for (len = 2; len < numAvail && data[len] == data2[len]; len++) + {} + if (len >= p->numFastBytes) { - mainLen = p->longestMatchLength; - numPairs = p->numPairs; + p->backRes = (UInt32)i; + MOVE_POS(p, len - 1) + return len; } - - numAvail = p->numAvail; - *backRes = (UInt32)-1; - if (numAvail < 2) - return 1; - if (numAvail > LZMA_MATCH_LEN_MAX) - numAvail = LZMA_MATCH_LEN_MAX; - data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; - - repLen = repIndex = 0; - for (i = 0; i < LZMA_NUM_REPS; i++) + if (len > repLen) { - UInt32 len; - const Byte *data2 = data - (p->reps[i] + 1); - if (data[0] != data2[0] || data[1] != data2[1]) - continue; - for (len = 2; len < numAvail && data[len] == data2[len]; len++); - if (len >= p->numFastBytes) - { - *backRes = i; - MovePos(p, len - 1); - return len; - } - if (len > repLen) - { - repIndex = i; - repLen = len; - } + repIndex = i; + repLen = len; } + } - matches = p->matches; - if (mainLen >= p->numFastBytes) - { - *backRes = matches[numPairs - 1] + LZMA_NUM_REPS; - MovePos(p, mainLen - 1); - return mainLen; - } - - mainDist = 0; /* for GCC */ - if (mainLen >= 2) - { - mainDist = matches[numPairs - 1]; - while (numPairs > 2 && mainLen == matches[numPairs - 4] + 1) - { - if (!ChangePair(matches[numPairs - 3], mainDist)) - break; - numPairs -= 2; - mainLen = matches[numPairs - 2]; - mainDist = matches[numPairs - 1]; - } - if (mainLen == 2 && mainDist >= 0x80) - mainLen = 1; - } - - if (repLen >= 2 && ( - (repLen + 1 >= mainLen) || - (repLen + 2 >= mainLen && mainDist >= (1 << 9)) || - (repLen + 3 >= mainLen && mainDist >= (1 << 15)))) - { - *backRes = repIndex; - MovePos(p, repLen - 1); - return repLen; - } - - if (mainLen < 2 || numAvail <= 2) - return 1; - - p->longestMatchLength = ReadMatchDistances(p, &p->numPairs); - if (p->longestMatchLength >= 2) - { - UInt32 newDistance = matches[p->numPairs - 1]; - if ((p->longestMatchLength >= mainLen && newDistance < mainDist) || - (p->longestMatchLength == mainLen + 1 && !ChangePair(mainDist, newDistance)) || - (p->longestMatchLength > mainLen + 1) || - (p->longestMatchLength + 1 >= mainLen && mainLen >= 3 && ChangePair(newDistance, mainDist))) - return 1; - } - - data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; - for (i = 0; i < LZMA_NUM_REPS; i++) - { - UInt32 len, limit; - const Byte *data2 = data - (p->reps[i] + 1); - if (data[0] != data2[0] || data[1] != data2[1]) - continue; - limit = mainLen - 1; - for (len = 2; len < limit && data[len] == data2[len]; len++); - if (len >= limit) - return 1; - } - *backRes = mainDist + LZMA_NUM_REPS; - MovePos(p, mainLen - 2); + if (mainLen >= p->numFastBytes) + { + p->backRes = p->matches[(size_t)numPairs - 1] + LZMA_NUM_REPS; + MOVE_POS(p, mainLen - 1) return mainLen; + } + + mainDist = 0; /* for GCC */ + + if (mainLen >= 2) + { + mainDist = p->matches[(size_t)numPairs - 1]; + while (numPairs > 2) + { + UInt32 dist2; + if (mainLen != p->matches[(size_t)numPairs - 4] + 1) + break; + dist2 = p->matches[(size_t)numPairs - 3]; + if (!ChangePair(dist2, mainDist)) + break; + numPairs -= 2; + mainLen--; + mainDist = dist2; + } + if (mainLen == 2 && mainDist >= 0x80) + mainLen = 1; + } + + if (repLen >= 2) + if ( repLen + 1 >= mainLen + || (repLen + 2 >= mainLen && mainDist >= (1 << 9)) + || (repLen + 3 >= mainLen && mainDist >= (1 << 15))) + { + p->backRes = (UInt32)repIndex; + MOVE_POS(p, repLen - 1) + return repLen; + } + + if (mainLen < 2 || numAvail <= 2) + return 1; + + { + unsigned len1 = ReadMatchDistances(p, &p->numPairs); + p->longestMatchLen = len1; + + if (len1 >= 2) + { + UInt32 newDist = p->matches[(size_t)p->numPairs - 1]; + if ( (len1 >= mainLen && newDist < mainDist) + || (len1 == mainLen + 1 && !ChangePair(mainDist, newDist)) + || (len1 > mainLen + 1) + || (len1 + 1 >= mainLen && mainLen >= 3 && ChangePair(newDist, mainDist))) + return 1; + } + } + + data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; + + for (i = 0; i < LZMA_NUM_REPS; i++) + { + unsigned len, limit; + const Byte *data2 = data - p->reps[i]; + if (data[0] != data2[0] || data[1] != data2[1]) + continue; + limit = mainLen - 1; + for (len = 2;; len++) + { + if (len >= limit) + return 1; + if (data[len] != data2[len]) + break; + } + } + + p->backRes = mainDist + LZMA_NUM_REPS; + if (mainLen != 2) + { + MOVE_POS(p, mainLen - 2) + } + return mainLen; } -static void WriteEndMarker(CLzmaEnc *p, UInt32 posState) + + + +static void WriteEndMarker(CLzmaEnc *p, unsigned posState) { - UInt32 len; - RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 1); - RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0); - p->state = kMatchNextStates[p->state]; - len = LZMA_MATCH_LEN_MIN; - LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices); - RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, (1 << kNumPosSlotBits) - 1); - RangeEnc_EncodeDirectBits(&p->rc, (((UInt32)1 << 30) - 1) >> kNumAlignBits, 30 - kNumAlignBits); - RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, kAlignMask); + UInt32 range; + range = p->rc.range; + { + UInt32 ttt, newBound; + CLzmaProb *prob = &p->isMatch[p->state][posState]; + RC_BIT_PRE(&p->rc, prob) + RC_BIT_1(&p->rc, prob) + prob = &p->isRep[p->state]; + RC_BIT_PRE(&p->rc, prob) + RC_BIT_0(&p->rc, prob) + } + p->state = kMatchNextStates[p->state]; + + p->rc.range = range; + LenEnc_Encode(&p->lenProbs, &p->rc, 0, posState); + range = p->rc.range; + + { + // RcTree_Encode_PosSlot(&p->rc, p->posSlotEncoder[0], (1 << kNumPosSlotBits) - 1); + CLzmaProb *probs = p->posSlotEncoder[0]; + unsigned m = 1; + do + { + UInt32 ttt, newBound; + RC_BIT_PRE(p, probs + m) + RC_BIT_1(&p->rc, probs + m) + m = (m << 1) + 1; + } + while (m < (1 << kNumPosSlotBits)); + } + { + // RangeEnc_EncodeDirectBits(&p->rc, ((UInt32)1 << (30 - kNumAlignBits)) - 1, 30 - kNumAlignBits); UInt32 range = p->range; + unsigned numBits = 30 - kNumAlignBits; + do + { + range >>= 1; + p->rc.low += range; + RC_NORM(&p->rc) + } + while (--numBits); + } + + { + // RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, kAlignMask); + CLzmaProb *probs = p->posAlignEncoder; + unsigned m = 1; + do + { + UInt32 ttt, newBound; + RC_BIT_PRE(p, probs + m) + RC_BIT_1(&p->rc, probs + m) + m = (m << 1) + 1; + } + while (m < kAlignTableSize); + } + p->rc.range = range; } + static SRes CheckErrors(CLzmaEnc *p) { - if (p->result != SZ_OK) - return p->result; - if (p->rc.res != SZ_OK) - p->result = SZ_ERROR_WRITE; - if (p->matchFinderBase.result != SZ_OK) - p->result = SZ_ERROR_READ; - if (p->result != SZ_OK) - p->finished = True; + if (p->result != SZ_OK) return p->result; -} + if (p->rc.res != SZ_OK) + p->result = SZ_ERROR_WRITE; -static SRes Flush(CLzmaEnc *p, UInt32 nowPos) -{ - /* ReleaseMFStream(); */ + #ifndef Z7_ST + if ( + // p->mf_Failure || + (p->mtMode && + ( // p->matchFinderMt.failure_LZ_LZ || + p->matchFinderMt.failure_LZ_BT)) + ) + { + p->result = MY_HRES_ERROR_INTERNAL_ERROR; + // printf("\nCheckErrors p->matchFinderMt.failureLZ\n"); + } + #endif + + if (MFB.result != SZ_OK) + p->result = SZ_ERROR_READ; + + if (p->result != SZ_OK) p->finished = True; - if (p->writeEndMark) - WriteEndMarker(p, nowPos & p->pbMask); - RangeEnc_FlushData(&p->rc); - RangeEnc_FlushStream(&p->rc); - return CheckErrors(p); + return p->result; } -static void FillAlignPrices(CLzmaEnc *p) + +Z7_NO_INLINE static SRes Flush(CLzmaEnc *p, UInt32 nowPos) { - UInt32 i; - for (i = 0; i < kAlignTableSize; i++) - p->alignPrices[i] = RcTree_ReverseGetPrice(p->posAlignEncoder, kNumAlignBits, i, p->ProbPrices); - p->alignPriceCount = 0; + /* ReleaseMFStream(); */ + p->finished = True; + if (p->writeEndMark) + WriteEndMarker(p, nowPos & p->pbMask); + RangeEnc_FlushData(&p->rc); + RangeEnc_FlushStream(&p->rc); + return CheckErrors(p); } -static void FillDistancesPrices(CLzmaEnc *p) + +Z7_NO_INLINE static void FillAlignPrices(CLzmaEnc *p) { - UInt32 tempPrices[kNumFullDistances]; - UInt32 i, lenToPosState; - for (i = kStartPosModelIndex; i < kNumFullDistances; i++) + unsigned i; + const CProbPrice *ProbPrices = p->ProbPrices; + const CLzmaProb *probs = p->posAlignEncoder; + // p->alignPriceCount = 0; + for (i = 0; i < kAlignTableSize / 2; i++) + { + UInt32 price = 0; + unsigned sym = i; + unsigned m = 1; + unsigned bit; + UInt32 prob; + bit = sym & 1; sym >>= 1; price += GET_PRICEa(probs[m], bit); m = (m << 1) + bit; + bit = sym & 1; sym >>= 1; price += GET_PRICEa(probs[m], bit); m = (m << 1) + bit; + bit = sym & 1; sym >>= 1; price += GET_PRICEa(probs[m], bit); m = (m << 1) + bit; + prob = probs[m]; + p->alignPrices[i ] = price + GET_PRICEa_0(prob); + p->alignPrices[i + 8] = price + GET_PRICEa_1(prob); + // p->alignPrices[i] = RcTree_ReverseGetPrice(p->posAlignEncoder, kNumAlignBits, i, p->ProbPrices); + } +} + + +Z7_NO_INLINE static void FillDistancesPrices(CLzmaEnc *p) +{ + // int y; for (y = 0; y < 100; y++) { + + UInt32 tempPrices[kNumFullDistances]; + unsigned i, lps; + + const CProbPrice *ProbPrices = p->ProbPrices; + p->matchPriceCount = 0; + + for (i = kStartPosModelIndex / 2; i < kNumFullDistances / 2; i++) + { + unsigned posSlot = GetPosSlot1(i); + unsigned footerBits = (posSlot >> 1) - 1; + unsigned base = ((2 | (posSlot & 1)) << footerBits); + const CLzmaProb *probs = p->posEncoders + (size_t)base * 2; + // tempPrices[i] = RcTree_ReverseGetPrice(p->posEncoders + base, footerBits, i - base, p->ProbPrices); + UInt32 price = 0; + unsigned m = 1; + unsigned sym = i; + unsigned offset = (unsigned)1 << footerBits; + base += i; + + if (footerBits) + do { - UInt32 posSlot = GetPosSlot1(i); - UInt32 footerBits = ((posSlot >> 1) - 1); - UInt32 base = ((2 | (posSlot & 1)) << footerBits); - tempPrices[i] = RcTree_ReverseGetPrice(p->posEncoders + base - posSlot - 1, footerBits, i - base, p->ProbPrices); + unsigned bit = sym & 1; + sym >>= 1; + price += GET_PRICEa(probs[m], bit); + m = (m << 1) + bit; + } + while (--footerBits); + + { + unsigned prob = probs[m]; + tempPrices[base ] = price + GET_PRICEa_0(prob); + tempPrices[base + offset] = price + GET_PRICEa_1(prob); + } + } + + for (lps = 0; lps < kNumLenToPosStates; lps++) + { + unsigned slot; + unsigned distTableSize2 = (p->distTableSize + 1) >> 1; + UInt32 *posSlotPrices = p->posSlotPrices[lps]; + const CLzmaProb *probs = p->posSlotEncoder[lps]; + + for (slot = 0; slot < distTableSize2; slot++) + { + // posSlotPrices[slot] = RcTree_GetPrice(encoder, kNumPosSlotBits, slot, p->ProbPrices); + UInt32 price; + unsigned bit; + unsigned sym = slot + (1 << (kNumPosSlotBits - 1)); + unsigned prob; + bit = sym & 1; sym >>= 1; price = GET_PRICEa(probs[sym], bit); + bit = sym & 1; sym >>= 1; price += GET_PRICEa(probs[sym], bit); + bit = sym & 1; sym >>= 1; price += GET_PRICEa(probs[sym], bit); + bit = sym & 1; sym >>= 1; price += GET_PRICEa(probs[sym], bit); + bit = sym & 1; sym >>= 1; price += GET_PRICEa(probs[sym], bit); + prob = probs[(size_t)slot + (1 << (kNumPosSlotBits - 1))]; + posSlotPrices[(size_t)slot * 2 ] = price + GET_PRICEa_0(prob); + posSlotPrices[(size_t)slot * 2 + 1] = price + GET_PRICEa_1(prob); + } + + { + UInt32 delta = ((UInt32)((kEndPosModelIndex / 2 - 1) - kNumAlignBits) << kNumBitPriceShiftBits); + for (slot = kEndPosModelIndex / 2; slot < distTableSize2; slot++) + { + posSlotPrices[(size_t)slot * 2 ] += delta; + posSlotPrices[(size_t)slot * 2 + 1] += delta; + delta += ((UInt32)1 << kNumBitPriceShiftBits); + } } - for (lenToPosState = 0; lenToPosState < kNumLenToPosStates; lenToPosState++) { - UInt32 posSlot; - const CLzmaProb *encoder = p->posSlotEncoder[lenToPosState]; - UInt32 *posSlotPrices = p->posSlotPrices[lenToPosState]; - for (posSlot = 0; posSlot < p->distTableSize; posSlot++) - posSlotPrices[posSlot] = RcTree_GetPrice(encoder, kNumPosSlotBits, posSlot, p->ProbPrices); - for (posSlot = kEndPosModelIndex; posSlot < p->distTableSize; posSlot++) - posSlotPrices[posSlot] += ((((posSlot >> 1) - 1) - kNumAlignBits) << kNumBitPriceShiftBits); + UInt32 *dp = p->distancesPrices[lps]; + + dp[0] = posSlotPrices[0]; + dp[1] = posSlotPrices[1]; + dp[2] = posSlotPrices[2]; + dp[3] = posSlotPrices[3]; + for (i = 4; i < kNumFullDistances; i += 2) + { + UInt32 slotPrice = posSlotPrices[GetPosSlot1(i)]; + dp[i ] = slotPrice + tempPrices[i]; + dp[i + 1] = slotPrice + tempPrices[i + 1]; + } + } + } + // } +} + + + +static void LzmaEnc_Construct(CLzmaEnc *p) +{ + RangeEnc_Construct(&p->rc); + MatchFinder_Construct(&MFB); + + #ifndef Z7_ST + p->matchFinderMt.MatchFinder = &MFB; + MatchFinderMt_Construct(&p->matchFinderMt); + #endif + + { + CLzmaEncProps props; + LzmaEncProps_Init(&props); + LzmaEnc_SetProps((CLzmaEncHandle)(void *)p, &props); + } + + #ifndef LZMA_LOG_BSR + LzmaEnc_FastPosInit(p->g_FastPos); + #endif + + LzmaEnc_InitPriceTables(p->ProbPrices); + p->litProbs = NULL; + p->saveState.litProbs = NULL; +} + +CLzmaEncHandle LzmaEnc_Create(ISzAllocPtr alloc) +{ + void *p; + p = ISzAlloc_Alloc(alloc, sizeof(CLzmaEnc)); + if (p) + LzmaEnc_Construct((CLzmaEnc *)p); + return p; +} + +static void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAllocPtr alloc) +{ + ISzAlloc_Free(alloc, p->litProbs); + ISzAlloc_Free(alloc, p->saveState.litProbs); + p->litProbs = NULL; + p->saveState.litProbs = NULL; +} + +static void LzmaEnc_Destruct(CLzmaEnc *p, ISzAllocPtr alloc, ISzAllocPtr allocBig) +{ + #ifndef Z7_ST + MatchFinderMt_Destruct(&p->matchFinderMt, allocBig); + #endif + + MatchFinder_Free(&MFB, allocBig); + LzmaEnc_FreeLits(p, alloc); + RangeEnc_Free(&p->rc, alloc); +} + +void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAllocPtr alloc, ISzAllocPtr allocBig) +{ + // GET_CLzmaEnc_p + LzmaEnc_Destruct(p, alloc, allocBig); + ISzAlloc_Free(alloc, p); +} + + +Z7_NO_INLINE +static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, UInt32 maxPackSize, UInt32 maxUnpackSize) +{ + UInt32 nowPos32, startPos32; + if (p->needInit) + { + #ifndef Z7_ST + if (p->mtMode) + { + RINOK(MatchFinderMt_InitMt(&p->matchFinderMt)) + } + #endif + p->matchFinder.Init(p->matchFinderObj); + p->needInit = 0; + } + + if (p->finished) + return p->result; + RINOK(CheckErrors(p)) + + nowPos32 = (UInt32)p->nowPos64; + startPos32 = nowPos32; + + if (p->nowPos64 == 0) + { + unsigned numPairs; + Byte curByte; + if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0) + return Flush(p, nowPos32); + ReadMatchDistances(p, &numPairs); + RangeEnc_EncodeBit_0(&p->rc, &p->isMatch[kState_Start][0]); + // p->state = kLiteralNextStates[p->state]; + curByte = *(p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset); + LitEnc_Encode(&p->rc, p->litProbs, curByte); + p->additionalOffset--; + nowPos32++; + } + + if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) != 0) + + for (;;) + { + UInt32 dist; + unsigned len, posState; + UInt32 range, ttt, newBound; + CLzmaProb *probs; + + if (p->fastMode) + len = GetOptimumFast(p); + else + { + unsigned oci = p->optCur; + if (p->optEnd == oci) + len = GetOptimum(p, nowPos32); + else + { + const COptimal *opt = &p->opt[oci]; + len = opt->len; + p->backRes = opt->dist; + p->optCur = oci + 1; + } + } + + posState = (unsigned)nowPos32 & p->pbMask; + range = p->rc.range; + probs = &p->isMatch[p->state][posState]; + + RC_BIT_PRE(&p->rc, probs) + + dist = p->backRes; + + #ifdef SHOW_STAT2 + printf("\n pos = %6X, len = %3u pos = %6u", nowPos32, len, dist); + #endif + + if (dist == MARK_LIT) + { + Byte curByte; + const Byte *data; + unsigned state; + + RC_BIT_0(&p->rc, probs) + p->rc.range = range; + data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset; + probs = LIT_PROBS(nowPos32, *(data - 1)); + curByte = *data; + state = p->state; + p->state = kLiteralNextStates[state]; + if (IsLitState(state)) + LitEnc_Encode(&p->rc, probs, curByte); + else + LitEnc_EncodeMatched(&p->rc, probs, curByte, *(data - p->reps[0])); + } + else + { + RC_BIT_1(&p->rc, probs) + probs = &p->isRep[p->state]; + RC_BIT_PRE(&p->rc, probs) + + if (dist < LZMA_NUM_REPS) + { + RC_BIT_1(&p->rc, probs) + probs = &p->isRepG0[p->state]; + RC_BIT_PRE(&p->rc, probs) + if (dist == 0) { - UInt32 *distancesPrices = p->distancesPrices[lenToPosState]; - UInt32 i; - for (i = 0; i < kStartPosModelIndex; i++) - distancesPrices[i] = posSlotPrices[i]; - for (; i < kNumFullDistances; i++) - distancesPrices[i] = posSlotPrices[GetPosSlot1(i)] + tempPrices[i]; - } - } - p->matchPriceCount = 0; -} - -void LzmaEnc_Construct(CLzmaEnc *p) -{ - RangeEnc_Construct(&p->rc); - MatchFinder_Construct(&p->matchFinderBase); -#ifndef _7ZIP_ST - MatchFinderMt_Construct(&p->matchFinderMt); - p->matchFinderMt.MatchFinder = &p->matchFinderBase; -#endif - - { - CLzmaEncProps props; - LzmaEncProps_Init(&props); - LzmaEnc_SetProps(p, &props); - } - -#ifndef LZMA_LOG_BSR - LzmaEnc_FastPosInit(p->g_FastPos); -#endif - - LzmaEnc_InitPriceTables(p->ProbPrices); - p->litProbs = 0; - p->saveState.litProbs = 0; -} - -CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc) -{ - void *p; - p = alloc->Alloc(alloc, sizeof(CLzmaEnc)); - if (p != 0) - LzmaEnc_Construct((CLzmaEnc *)p); - return p; -} - -void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAlloc *alloc) -{ - alloc->Free(alloc, p->litProbs); - alloc->Free(alloc, p->saveState.litProbs); - p->litProbs = 0; - p->saveState.litProbs = 0; -} - -void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig) -{ -#ifndef _7ZIP_ST - MatchFinderMt_Destruct(&p->matchFinderMt, allocBig); -#endif - MatchFinder_Free(&p->matchFinderBase, allocBig); - LzmaEnc_FreeLits(p, alloc); - RangeEnc_Free(&p->rc, alloc); -} - -void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig) -{ - LzmaEnc_Destruct((CLzmaEnc *)p, alloc, allocBig); - alloc->Free(alloc, p); -} - -static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize, UInt32 maxUnpackSize) -{ - UInt32 nowPos32, startPos32; - if (p->needInit) - { - p->matchFinder.Init(p->matchFinderObj); - p->needInit = 0; - } - - if (p->finished) - return p->result; - RINOK(CheckErrors(p)); - - nowPos32 = (UInt32)p->nowPos64; - startPos32 = nowPos32; - - if (p->nowPos64 == 0) - { - UInt32 numPairs; - Byte curByte; - if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0) - return Flush(p, nowPos32); - ReadMatchDistances(p, &numPairs); - RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][0], 0); - p->state = kLiteralNextStates[p->state]; - curByte = p->matchFinder.GetIndexByte(p->matchFinderObj, 0 - p->additionalOffset); - LitEnc_Encode(&p->rc, p->litProbs, curByte); - p->additionalOffset--; - nowPos32++; - } - - if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) != 0) - for (;;) - { - UInt32 pos, len, posState; - - if (p->fastMode) - len = GetOptimumFast(p, &pos); - else - len = GetOptimum(p, nowPos32, &pos); - -#ifdef SHOW_STAT2 - printf("\n pos = %4X, len = %d pos = %d", nowPos32, len, pos); -#endif - - posState = nowPos32 & p->pbMask; - if (len == 1 && pos == (UInt32)-1) - { - Byte curByte; - CLzmaProb *probs; - const Byte *data; - - RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 0); - data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset; - curByte = *data; - probs = LIT_PROBS(nowPos32, *(data - 1)); - if (IsCharState(p->state)) - LitEnc_Encode(&p->rc, probs, curByte); - else - LitEnc_EncodeMatched(&p->rc, probs, curByte, *(data - p->reps[0] - 1)); - p->state = kLiteralNextStates[p->state]; + RC_BIT_0(&p->rc, probs) + probs = &p->isRep0Long[p->state][posState]; + RC_BIT_PRE(&p->rc, probs) + if (len != 1) + { + RC_BIT_1_BASE(&p->rc, probs) + } + else + { + RC_BIT_0_BASE(&p->rc, probs) + p->state = kShortRepNextStates[p->state]; + } } else { - RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 1); - if (pos < LZMA_NUM_REPS) + RC_BIT_1(&p->rc, probs) + probs = &p->isRepG1[p->state]; + RC_BIT_PRE(&p->rc, probs) + if (dist == 1) + { + RC_BIT_0_BASE(&p->rc, probs) + dist = p->reps[1]; + } + else + { + RC_BIT_1(&p->rc, probs) + probs = &p->isRepG2[p->state]; + RC_BIT_PRE(&p->rc, probs) + if (dist == 2) { - RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 1); - if (pos == 0) - { - RangeEnc_EncodeBit(&p->rc, &p->isRepG0[p->state], 0); - RangeEnc_EncodeBit(&p->rc, &p->isRep0Long[p->state][posState], ((len == 1) ? 0 : 1)); - } - else - { - UInt32 distance = p->reps[pos]; - RangeEnc_EncodeBit(&p->rc, &p->isRepG0[p->state], 1); - if (pos == 1) - RangeEnc_EncodeBit(&p->rc, &p->isRepG1[p->state], 0); - else - { - RangeEnc_EncodeBit(&p->rc, &p->isRepG1[p->state], 1); - RangeEnc_EncodeBit(&p->rc, &p->isRepG2[p->state], pos - 2); - if (pos == 3) - p->reps[3] = p->reps[2]; - p->reps[2] = p->reps[1]; - } - p->reps[1] = p->reps[0]; - p->reps[0] = distance; - } - if (len == 1) - p->state = kShortRepNextStates[p->state]; - else - { - LenEnc_Encode2(&p->repLenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices); - p->state = kRepNextStates[p->state]; - } + RC_BIT_0_BASE(&p->rc, probs) + dist = p->reps[2]; } else { - UInt32 posSlot; - RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0); - p->state = kMatchNextStates[p->state]; - LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices); - pos -= LZMA_NUM_REPS; - GetPosSlot(pos, posSlot); - RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, posSlot); - - if (posSlot >= kStartPosModelIndex) - { - UInt32 footerBits = ((posSlot >> 1) - 1); - UInt32 base = ((2 | (posSlot & 1)) << footerBits); - UInt32 posReduced = pos - base; - - if (posSlot < kEndPosModelIndex) - RcTree_ReverseEncode(&p->rc, p->posEncoders + base - posSlot - 1, footerBits, posReduced); - else - { - RangeEnc_EncodeDirectBits(&p->rc, posReduced >> kNumAlignBits, footerBits - kNumAlignBits); - RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, posReduced & kAlignMask); - p->alignPriceCount++; - } - } - p->reps[3] = p->reps[2]; - p->reps[2] = p->reps[1]; - p->reps[1] = p->reps[0]; - p->reps[0] = pos; - p->matchPriceCount++; + RC_BIT_1_BASE(&p->rc, probs) + dist = p->reps[3]; + p->reps[3] = p->reps[2]; } + p->reps[2] = p->reps[1]; + } + p->reps[1] = p->reps[0]; + p->reps[0] = dist; } - p->additionalOffset -= len; - nowPos32 += len; - if (p->additionalOffset == 0) + + RC_NORM(&p->rc) + + p->rc.range = range; + + if (len != 1) { - UInt32 processed; - if (!p->fastMode) - { - if (p->matchPriceCount >= (1 << 7)) - FillDistancesPrices(p); - if (p->alignPriceCount >= kAlignTableSize) - FillAlignPrices(p); - } - if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0) - break; - processed = nowPos32 - startPos32; - if (useLimits) - { - if (processed + kNumOpts + 300 >= maxUnpackSize || - RangeEnc_GetProcessed(&p->rc) + kNumOpts * 2 >= maxPackSize) - break; - } - else if (processed >= (1 << 15)) - { - p->nowPos64 += nowPos32 - startPos32; - return CheckErrors(p); - } + LenEnc_Encode(&p->repLenProbs, &p->rc, len - LZMA_MATCH_LEN_MIN, posState); + --p->repLenEncCounter; + p->state = kRepNextStates[p->state]; } + } + else + { + unsigned posSlot; + RC_BIT_0(&p->rc, probs) + p->rc.range = range; + p->state = kMatchNextStates[p->state]; + + LenEnc_Encode(&p->lenProbs, &p->rc, len - LZMA_MATCH_LEN_MIN, posState); + // --p->lenEnc.counter; + + dist -= LZMA_NUM_REPS; + p->reps[3] = p->reps[2]; + p->reps[2] = p->reps[1]; + p->reps[1] = p->reps[0]; + p->reps[0] = dist + 1; + + p->matchPriceCount++; + GetPosSlot(dist, posSlot) + // RcTree_Encode_PosSlot(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], posSlot); + { + UInt32 sym = (UInt32)posSlot + (1 << kNumPosSlotBits); + range = p->rc.range; + probs = p->posSlotEncoder[GetLenToPosState(len)]; + do + { + CLzmaProb *prob = probs + (sym >> kNumPosSlotBits); + UInt32 bit = (sym >> (kNumPosSlotBits - 1)) & 1; + sym <<= 1; + RC_BIT(&p->rc, prob, bit) + } + while (sym < (1 << kNumPosSlotBits * 2)); + p->rc.range = range; } - p->nowPos64 += nowPos32 - startPos32; - return Flush(p, nowPos32); + + if (dist >= kStartPosModelIndex) + { + unsigned footerBits = ((posSlot >> 1) - 1); + + if (dist < kNumFullDistances) + { + unsigned base = ((2 | (posSlot & 1)) << footerBits); + RcTree_ReverseEncode(&p->rc, p->posEncoders + base, footerBits, (unsigned)(dist /* - base */)); + } + else + { + UInt32 pos2 = (dist | 0xF) << (32 - footerBits); + range = p->rc.range; + // RangeEnc_EncodeDirectBits(&p->rc, posReduced >> kNumAlignBits, footerBits - kNumAlignBits); + /* + do + { + range >>= 1; + p->rc.low += range & (0 - ((dist >> --footerBits) & 1)); + RC_NORM(&p->rc) + } + while (footerBits > kNumAlignBits); + */ + do + { + range >>= 1; + p->rc.low += range & (0 - (pos2 >> 31)); + pos2 += pos2; + RC_NORM(&p->rc) + } + while (pos2 != 0xF0000000); + + + // RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, posReduced & kAlignMask); + + { + unsigned m = 1; + unsigned bit; + bit = dist & 1; dist >>= 1; RC_BIT(&p->rc, p->posAlignEncoder + m, bit) m = (m << 1) + bit; + bit = dist & 1; dist >>= 1; RC_BIT(&p->rc, p->posAlignEncoder + m, bit) m = (m << 1) + bit; + bit = dist & 1; dist >>= 1; RC_BIT(&p->rc, p->posAlignEncoder + m, bit) m = (m << 1) + bit; + bit = dist & 1; RC_BIT(&p->rc, p->posAlignEncoder + m, bit) + p->rc.range = range; + // p->alignPriceCount++; + } + } + } + } + } + + nowPos32 += (UInt32)len; + p->additionalOffset -= len; + + if (p->additionalOffset == 0) + { + UInt32 processed; + + if (!p->fastMode) + { + /* + if (p->alignPriceCount >= 16) // kAlignTableSize + FillAlignPrices(p); + if (p->matchPriceCount >= 128) + FillDistancesPrices(p); + if (p->lenEnc.counter <= 0) + LenPriceEnc_UpdateTables(&p->lenEnc, 1 << p->pb, &p->lenProbs, p->ProbPrices); + */ + if (p->matchPriceCount >= 64) + { + FillAlignPrices(p); + // { int y; for (y = 0; y < 100; y++) { + FillDistancesPrices(p); + // }} + LenPriceEnc_UpdateTables(&p->lenEnc, (unsigned)1 << p->pb, &p->lenProbs, p->ProbPrices); + } + if (p->repLenEncCounter <= 0) + { + p->repLenEncCounter = REP_LEN_COUNT; + LenPriceEnc_UpdateTables(&p->repLenEnc, (unsigned)1 << p->pb, &p->repLenProbs, p->ProbPrices); + } + } + + if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0) + break; + processed = nowPos32 - startPos32; + + if (maxPackSize) + { + if (processed + kNumOpts + 300 >= maxUnpackSize + || RangeEnc_GetProcessed_sizet(&p->rc) + kPackReserve >= maxPackSize) + break; + } + else if (processed >= (1 << 17)) + { + p->nowPos64 += nowPos32 - startPos32; + return CheckErrors(p); + } + } + } + + p->nowPos64 += nowPos32 - startPos32; + return Flush(p, nowPos32); } + + #define kBigHashDicLimit ((UInt32)1 << 24) -static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig) +static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAllocPtr alloc, ISzAllocPtr allocBig) { - UInt32 beforeSize = kNumOpts; - if (!RangeEnc_Alloc(&p->rc, alloc)) - return SZ_ERROR_MEM; + UInt32 beforeSize = kNumOpts; + UInt32 dictSize; -#ifndef _7ZIP_ST - { - Bool btMode = (p->matchFinderBase.btMode != 0); - p->mtMode = (p->multiThread && !p->fastMode && btMode); - } -#endif + if (!RangeEnc_Alloc(&p->rc, alloc)) + return SZ_ERROR_MEM; - { - unsigned lclp = p->lc + p->lp; - if (p->litProbs == 0 || p->saveState.litProbs == 0 || p->lclp != lclp) - { - LzmaEnc_FreeLits(p, alloc); - p->litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300 << lclp) * sizeof(CLzmaProb)); - p->saveState.litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300 << lclp) * sizeof(CLzmaProb)); - if (p->litProbs == 0 || p->saveState.litProbs == 0) - { - LzmaEnc_FreeLits(p, alloc); - return SZ_ERROR_MEM; - } - p->lclp = lclp; - } - } - - p->matchFinderBase.bigHash = (p->dictSize > kBigHashDicLimit); - - if (beforeSize + p->dictSize < keepWindowSize) - beforeSize = keepWindowSize - p->dictSize; - -#ifndef _7ZIP_ST - if (p->mtMode) - { - RINOK(MatchFinderMt_Create(&p->matchFinderMt, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig)); - p->matchFinderObj = &p->matchFinderMt; - MatchFinderMt_CreateVTable(&p->matchFinderMt, &p->matchFinder); - } - else -#endif - { - if (!MatchFinder_Create(&p->matchFinderBase, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig)) - return SZ_ERROR_MEM; - p->matchFinderObj = &p->matchFinderBase; - MatchFinder_CreateVTable(&p->matchFinderBase, &p->matchFinder); - } - return SZ_OK; -} - -void LzmaEnc_Init(CLzmaEnc *p) -{ - UInt32 i; - p->state = 0; - for (i = 0; i < LZMA_NUM_REPS; i++) - p->reps[i] = 0; - - RangeEnc_Init(&p->rc); - - for (i = 0; i < kNumStates; i++) - { - UInt32 j; - for (j = 0; j < LZMA_NUM_PB_STATES_MAX; j++) - { - p->isMatch[i][j] = kProbInitValue; - p->isRep0Long[i][j] = kProbInitValue; - } - p->isRep[i] = kProbInitValue; - p->isRepG0[i] = kProbInitValue; - p->isRepG1[i] = kProbInitValue; - p->isRepG2[i] = kProbInitValue; - } + #ifndef Z7_ST + p->mtMode = (p->multiThread && !p->fastMode && (MFB.btMode != 0)); + #endif { - UInt32 num = 0x300 << (p->lp + p->lc); - for (i = 0; i < num; i++) - p->litProbs[i] = kProbInitValue; - } - - { - for (i = 0; i < kNumLenToPosStates; i++) + const unsigned lclp = p->lc + p->lp; + if (!p->litProbs || !p->saveState.litProbs || p->lclp != lclp) + { + LzmaEnc_FreeLits(p, alloc); + p->litProbs = (CLzmaProb *)ISzAlloc_Alloc(alloc, ((size_t)0x300 * sizeof(CLzmaProb)) << lclp); + p->saveState.litProbs = (CLzmaProb *)ISzAlloc_Alloc(alloc, ((size_t)0x300 * sizeof(CLzmaProb)) << lclp); + if (!p->litProbs || !p->saveState.litProbs) { - CLzmaProb *probs = p->posSlotEncoder[i]; - UInt32 j; - for (j = 0; j < (1 << kNumPosSlotBits); j++) - probs[j] = kProbInitValue; + LzmaEnc_FreeLits(p, alloc); + return SZ_ERROR_MEM; } + p->lclp = lclp; + } + } + + MFB.bigHash = (Byte)(p->dictSize > kBigHashDicLimit ? 1 : 0); + + + dictSize = p->dictSize; + if (dictSize == ((UInt32)2 << 30) || + dictSize == ((UInt32)3 << 30)) + { + /* 21.03 : here we reduce the dictionary for 2 reasons: + 1) we don't want 32-bit back_distance matches in decoder for 2 GB dictionary. + 2) we want to elimate useless last MatchFinder_Normalize3() for corner cases, + where data size is aligned for 1 GB: 5/6/8 GB. + That reducing must be >= 1 for such corner cases. */ + dictSize -= 1; + } + + if (beforeSize + dictSize < keepWindowSize) + beforeSize = keepWindowSize - dictSize; + + /* in worst case we can look ahead for + max(LZMA_MATCH_LEN_MAX, numFastBytes + 1 + numFastBytes) bytes. + we send larger value for (keepAfter) to MantchFinder_Create(): + (numFastBytes + LZMA_MATCH_LEN_MAX + 1) + */ + + #ifndef Z7_ST + if (p->mtMode) + { + RINOK(MatchFinderMt_Create(&p->matchFinderMt, dictSize, beforeSize, + p->numFastBytes, LZMA_MATCH_LEN_MAX + 1 /* 18.04 */ + , allocBig)) + p->matchFinderObj = &p->matchFinderMt; + MFB.bigHash = (Byte)(MFB.hashMask >= 0xFFFFFF ? 1 : 0); + MatchFinderMt_CreateVTable(&p->matchFinderMt, &p->matchFinder); + } + else + #endif + { + if (!MatchFinder_Create(&MFB, dictSize, beforeSize, + p->numFastBytes, LZMA_MATCH_LEN_MAX + 1 /* 21.03 */ + , allocBig)) + return SZ_ERROR_MEM; + p->matchFinderObj = &MFB; + MatchFinder_CreateVTable(&MFB, &p->matchFinder); + } + + return SZ_OK; +} + +static void LzmaEnc_Init(CLzmaEnc *p) +{ + unsigned i; + p->state = 0; + p->reps[0] = + p->reps[1] = + p->reps[2] = + p->reps[3] = 1; + + RangeEnc_Init(&p->rc); + + for (i = 0; i < (1 << kNumAlignBits); i++) + p->posAlignEncoder[i] = kProbInitValue; + + for (i = 0; i < kNumStates; i++) + { + unsigned j; + for (j = 0; j < LZMA_NUM_PB_STATES_MAX; j++) + { + p->isMatch[i][j] = kProbInitValue; + p->isRep0Long[i][j] = kProbInitValue; + } + p->isRep[i] = kProbInitValue; + p->isRepG0[i] = kProbInitValue; + p->isRepG1[i] = kProbInitValue; + p->isRepG2[i] = kProbInitValue; + } + + { + for (i = 0; i < kNumLenToPosStates; i++) + { + CLzmaProb *probs = p->posSlotEncoder[i]; + unsigned j; + for (j = 0; j < (1 << kNumPosSlotBits); j++) + probs[j] = kProbInitValue; + } } { - for (i = 0; i < kNumFullDistances - kEndPosModelIndex; i++) - p->posEncoders[i] = kProbInitValue; + for (i = 0; i < kNumFullDistances; i++) + p->posEncoders[i] = kProbInitValue; } - LenEnc_Init(&p->lenEnc.p); - LenEnc_Init(&p->repLenEnc.p); + { + const size_t num = (size_t)0x300 << (p->lp + p->lc); + size_t k; + CLzmaProb *probs = p->litProbs; + for (k = 0; k < num; k++) + probs[k] = kProbInitValue; + } - for (i = 0; i < (1 << kNumAlignBits); i++) - p->posAlignEncoder[i] = kProbInitValue; - p->optimumEndIndex = 0; - p->optimumCurrentIndex = 0; - p->additionalOffset = 0; + LenEnc_Init(&p->lenProbs); + LenEnc_Init(&p->repLenProbs); - p->pbMask = (1 << p->pb) - 1; - p->lpMask = (1 << p->lp) - 1; + p->optEnd = 0; + p->optCur = 0; + + { + for (i = 0; i < kNumOpts; i++) + p->opt[i].price = kInfinityPrice; + } + + p->additionalOffset = 0; + + p->pbMask = ((unsigned)1 << p->pb) - 1; + p->lpMask = ((UInt32)0x100 << p->lp) - ((unsigned)0x100 >> p->lc); + + // p->mf_Failure = False; } -void LzmaEnc_InitPrices(CLzmaEnc *p) + +static void LzmaEnc_InitPrices(CLzmaEnc *p) { - if (!p->fastMode) - { - FillDistancesPrices(p); - FillAlignPrices(p); - } + if (!p->fastMode) + { + FillDistancesPrices(p); + FillAlignPrices(p); + } - p->lenEnc.tableSize = - p->repLenEnc.tableSize = - p->numFastBytes + 1 - LZMA_MATCH_LEN_MIN; - LenPriceEnc_UpdateTables(&p->lenEnc, 1 << p->pb, p->ProbPrices); - LenPriceEnc_UpdateTables(&p->repLenEnc, 1 << p->pb, p->ProbPrices); + p->lenEnc.tableSize = + p->repLenEnc.tableSize = + p->numFastBytes + 1 - LZMA_MATCH_LEN_MIN; + + p->repLenEncCounter = REP_LEN_COUNT; + + LenPriceEnc_UpdateTables(&p->lenEnc, (unsigned)1 << p->pb, &p->lenProbs, p->ProbPrices); + LenPriceEnc_UpdateTables(&p->repLenEnc, (unsigned)1 << p->pb, &p->repLenProbs, p->ProbPrices); } -static SRes LzmaEnc_AllocAndInit(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig) +static SRes LzmaEnc_AllocAndInit(CLzmaEnc *p, UInt32 keepWindowSize, ISzAllocPtr alloc, ISzAllocPtr allocBig) { - UInt32 i; - for (i = 0; i < (UInt32)kDicLogSizeMaxCompress; i++) - if (p->dictSize <= ((UInt32)1 << i)) - break; - p->distTableSize = i * 2; + unsigned i; + for (i = kEndPosModelIndex / 2; i < kDicLogSizeMax; i++) + if (p->dictSize <= ((UInt32)1 << i)) + break; + p->distTableSize = i * 2; - p->finished = False; - p->result = SZ_OK; - RINOK(LzmaEnc_Alloc(p, keepWindowSize, alloc, allocBig)); - LzmaEnc_Init(p); - LzmaEnc_InitPrices(p); - p->nowPos64 = 0; - return SZ_OK; + p->finished = False; + p->result = SZ_OK; + p->nowPos64 = 0; + p->needInit = 1; + RINOK(LzmaEnc_Alloc(p, keepWindowSize, alloc, allocBig)) + LzmaEnc_Init(p); + LzmaEnc_InitPrices(p); + return SZ_OK; } -static SRes LzmaEnc_Prepare(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, - ISzAlloc *alloc, ISzAlloc *allocBig) +static SRes LzmaEnc_Prepare(CLzmaEncHandle p, + ISeqOutStreamPtr outStream, + ISeqInStreamPtr inStream, + ISzAllocPtr alloc, ISzAllocPtr allocBig) { - CLzmaEnc *p = (CLzmaEnc *)pp; - p->matchFinderBase.stream = inStream; - p->needInit = 1; - p->rc.outStream = outStream; - return LzmaEnc_AllocAndInit(p, 0, alloc, allocBig); + // GET_CLzmaEnc_p + MatchFinder_SET_STREAM(&MFB, inStream) + p->rc.outStream = outStream; + return LzmaEnc_AllocAndInit(p, 0, alloc, allocBig); } -SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle pp, - ISeqInStream *inStream, UInt32 keepWindowSize, - ISzAlloc *alloc, ISzAlloc *allocBig) +SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle p, + ISeqInStreamPtr inStream, UInt32 keepWindowSize, + ISzAllocPtr alloc, ISzAllocPtr allocBig) { - CLzmaEnc *p = (CLzmaEnc *)pp; - p->matchFinderBase.stream = inStream; - p->needInit = 1; - return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig); + // GET_CLzmaEnc_p + MatchFinder_SET_STREAM(&MFB, inStream) + return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig); } -static void LzmaEnc_SetInputBuf(CLzmaEnc *p, const Byte *src, SizeT srcLen) +SRes LzmaEnc_MemPrepare(CLzmaEncHandle p, + const Byte *src, SizeT srcLen, + UInt32 keepWindowSize, + ISzAllocPtr alloc, ISzAllocPtr allocBig) { - p->matchFinderBase.directInput = 1; - p->matchFinderBase.bufferBase = (Byte *)src; - p->matchFinderBase.directInputRem = srcLen; + // GET_CLzmaEnc_p + MatchFinder_SET_DIRECT_INPUT_BUF(&MFB, src, srcLen) + LzmaEnc_SetDataSize(p, srcLen); + return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig); } -SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen, - UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig) +void LzmaEnc_Finish(CLzmaEncHandle p) { - CLzmaEnc *p = (CLzmaEnc *)pp; - LzmaEnc_SetInputBuf(p, src, srcLen); - p->needInit = 1; - - return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig); + #ifndef Z7_ST + // GET_CLzmaEnc_p + if (p->mtMode) + MatchFinderMt_ReleaseStream(&p->matchFinderMt); + #else + UNUSED_VAR(p) + #endif } -void LzmaEnc_Finish(CLzmaEncHandle pp) -{ -#ifndef _7ZIP_ST - CLzmaEnc *p = (CLzmaEnc *)pp; - if (p->mtMode) - MatchFinderMt_ReleaseStream(&p->matchFinderMt); -#else - (void)pp; -#endif -} typedef struct { - ISeqOutStream funcTable; - Byte *data; - SizeT rem; - Bool overflow; -} CSeqOutStreamBuf; + ISeqOutStream vt; + Byte *data; + size_t rem; + BoolInt overflow; +} CLzmaEnc_SeqOutStreamBuf; -static size_t MyWrite(void *pp, const void *data, size_t size) +static size_t SeqOutStreamBuf_Write(ISeqOutStreamPtr pp, const void *data, size_t size) { - CSeqOutStreamBuf *p = (CSeqOutStreamBuf *)pp; - if (p->rem < size) - { - size = p->rem; - p->overflow = True; - } + Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CLzmaEnc_SeqOutStreamBuf) + if (p->rem < size) + { + size = p->rem; + p->overflow = True; + } + if (size != 0) + { memcpy(p->data, data, size); p->rem -= size; p->data += size; - return size; + } + return size; } -UInt32 LzmaEnc_GetNumAvailableBytes(CLzmaEncHandle pp) + +/* +UInt32 LzmaEnc_GetNumAvailableBytes(CLzmaEncHandle p) { - const CLzmaEnc *p = (CLzmaEnc *)pp; - return p->matchFinder.GetNumAvailableBytes(p->matchFinderObj); + GET_const_CLzmaEnc_p + return p->matchFinder.GetNumAvailableBytes(p->matchFinderObj); } +*/ -const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle pp) +const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle p) { - const CLzmaEnc *p = (CLzmaEnc *)pp; - return p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset; + // GET_const_CLzmaEnc_p + return p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset; } -SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit, + +// (desiredPackSize == 0) is not allowed +SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle p, BoolInt reInit, Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize) { - CLzmaEnc *p = (CLzmaEnc *)pp; - UInt64 nowPos64; - SRes res; - CSeqOutStreamBuf outStream; + // GET_CLzmaEnc_p + UInt64 nowPos64; + SRes res; + CLzmaEnc_SeqOutStreamBuf outStream; - outStream.funcTable.Write = MyWrite; - outStream.data = dest; - outStream.rem = *destLen; - outStream.overflow = False; + outStream.vt.Write = SeqOutStreamBuf_Write; + outStream.data = dest; + outStream.rem = *destLen; + outStream.overflow = False; - p->writeEndMark = False; - p->finished = False; - p->result = SZ_OK; + p->writeEndMark = False; + p->finished = False; + p->result = SZ_OK; - if (reInit) - LzmaEnc_Init(p); - LzmaEnc_InitPrices(p); - nowPos64 = p->nowPos64; - RangeEnc_Init(&p->rc); - p->rc.outStream = &outStream.funcTable; + if (reInit) + LzmaEnc_Init(p); + LzmaEnc_InitPrices(p); + RangeEnc_Init(&p->rc); + p->rc.outStream = &outStream.vt; + nowPos64 = p->nowPos64; + + res = LzmaEnc_CodeOneBlock(p, desiredPackSize, *unpackSize); + + *unpackSize = (UInt32)(p->nowPos64 - nowPos64); + *destLen -= outStream.rem; + if (outStream.overflow) + return SZ_ERROR_OUTPUT_EOF; - res = LzmaEnc_CodeOneBlock(p, True, desiredPackSize, *unpackSize); - - *unpackSize = (UInt32)(p->nowPos64 - nowPos64); - *destLen -= outStream.rem; - if (outStream.overflow) - return SZ_ERROR_OUTPUT_EOF; - - return res; + return res; } -static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress) + +Z7_NO_INLINE +static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgressPtr progress) { - SRes res = SZ_OK; + SRes res = SZ_OK; -#ifndef _7ZIP_ST - Byte allocaDummy[0x300]; - int i = 0; - for (i = 0; i < 16; i++) - allocaDummy[i] = (Byte)i; -#endif + #ifndef Z7_ST + Byte allocaDummy[0x300]; + allocaDummy[0] = 0; + allocaDummy[1] = allocaDummy[0]; + #endif - for (;;) + for (;;) + { + res = LzmaEnc_CodeOneBlock(p, 0, 0); + if (res != SZ_OK || p->finished) + break; + if (progress) { - res = LzmaEnc_CodeOneBlock(p, False, 0, 0); - if (res != SZ_OK || p->finished != 0) - break; - if (progress != 0) - { - res = progress->Progress(progress, p->nowPos64, RangeEnc_GetProcessed(&p->rc)); - if (res != SZ_OK) - { - res = SZ_ERROR_PROGRESS; - break; - } - } + res = ICompressProgress_Progress(progress, p->nowPos64, RangeEnc_GetProcessed(&p->rc)); + if (res != SZ_OK) + { + res = SZ_ERROR_PROGRESS; + break; + } } - LzmaEnc_Finish(p); - return res; + } + + LzmaEnc_Finish((CLzmaEncHandle)(void *)p); + + /* + if (res == SZ_OK && !Inline_MatchFinder_IsFinishedOK(&MFB)) + res = SZ_ERROR_FAIL; + } + */ + + return res; } -SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress, - ISzAlloc *alloc, ISzAlloc *allocBig) + +SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStreamPtr outStream, ISeqInStreamPtr inStream, ICompressProgressPtr progress, + ISzAllocPtr alloc, ISzAllocPtr allocBig) { - RINOK(LzmaEnc_Prepare(pp, outStream, inStream, alloc, allocBig)); - return LzmaEnc_Encode2((CLzmaEnc *)pp, progress); + // GET_CLzmaEnc_p + RINOK(LzmaEnc_Prepare(p, outStream, inStream, alloc, allocBig)) + return LzmaEnc_Encode2(p, progress); } -SRes LzmaEnc_WriteProperties(CLzmaEncHandle pp, Byte *props, SizeT *size) + +SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *props, SizeT *size) { - CLzmaEnc *p = (CLzmaEnc *)pp; - int i; - UInt32 dictSize = p->dictSize; - if (*size < LZMA_PROPS_SIZE) - return SZ_ERROR_PARAM; - *size = LZMA_PROPS_SIZE; + if (*size < LZMA_PROPS_SIZE) + return SZ_ERROR_PARAM; + *size = LZMA_PROPS_SIZE; + { + // GET_CLzmaEnc_p + const UInt32 dictSize = p->dictSize; + UInt32 v; props[0] = (Byte)((p->pb * 5 + p->lp) * 9 + p->lc); - - for (i = 11; i <= 30; i++) + + // we write aligned dictionary value to properties for lzma decoder + if (dictSize >= ((UInt32)1 << 21)) { - if (dictSize <= ((UInt32)2 << i)) - { - dictSize = (2 << i); - break; - } - if (dictSize <= ((UInt32)3 << i)) - { - dictSize = (3 << i); - break; - } + const UInt32 kDictMask = ((UInt32)1 << 20) - 1; + v = (dictSize + kDictMask) & ~kDictMask; + if (v < dictSize) + v = dictSize; + } + else + { + unsigned i = 11 * 2; + do + { + v = (UInt32)(2 + (i & 1)) << (i >> 1); + i++; + } + while (v < dictSize); } - for (i = 0; i < 4; i++) - props[1 + i] = (Byte)(dictSize >> (8 * i)); + SetUi32(props + 1, v) return SZ_OK; + } } -SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, - int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig) + +unsigned LzmaEnc_IsWriteEndMark(CLzmaEncHandle p) { - SRes res; - CLzmaEnc *p = (CLzmaEnc *)pp; - - CSeqOutStreamBuf outStream; - - LzmaEnc_SetInputBuf(p, src, srcLen); - - outStream.funcTable.Write = MyWrite; - outStream.data = dest; - outStream.rem = *destLen; - outStream.overflow = False; - - p->writeEndMark = writeEndMark; - - p->rc.outStream = &outStream.funcTable; - res = LzmaEnc_MemPrepare(pp, src, srcLen, 0, alloc, allocBig); - if (res == SZ_OK) - res = LzmaEnc_Encode2(p, progress); - - *destLen -= outStream.rem; - if (outStream.overflow) - return SZ_ERROR_OUTPUT_EOF; - return res; + // GET_CLzmaEnc_p + return (unsigned)p->writeEndMark; } + +SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, + int writeEndMark, ICompressProgressPtr progress, ISzAllocPtr alloc, ISzAllocPtr allocBig) +{ + SRes res; + // GET_CLzmaEnc_p + + CLzmaEnc_SeqOutStreamBuf outStream; + + outStream.vt.Write = SeqOutStreamBuf_Write; + outStream.data = dest; + outStream.rem = *destLen; + outStream.overflow = False; + + p->writeEndMark = writeEndMark; + p->rc.outStream = &outStream.vt; + + res = LzmaEnc_MemPrepare(p, src, srcLen, 0, alloc, allocBig); + + if (res == SZ_OK) + { + res = LzmaEnc_Encode2(p, progress); + if (res == SZ_OK && p->nowPos64 != srcLen) + res = SZ_ERROR_FAIL; + } + + *destLen -= (SizeT)outStream.rem; + if (outStream.overflow) + return SZ_ERROR_OUTPUT_EOF; + return res; +} + + SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark, - ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig) + ICompressProgressPtr progress, ISzAllocPtr alloc, ISzAllocPtr allocBig) { - CLzmaEnc *p = (CLzmaEnc *)LzmaEnc_Create(alloc); - SRes res; - if (p == 0) - return SZ_ERROR_MEM; + CLzmaEncHandle p = LzmaEnc_Create(alloc); + SRes res; + if (!p) + return SZ_ERROR_MEM; - res = LzmaEnc_SetProps(p, props); + res = LzmaEnc_SetProps(p, props); + if (res == SZ_OK) + { + res = LzmaEnc_WriteProperties(p, propsEncoded, propsSize); if (res == SZ_OK) - { - res = LzmaEnc_WriteProperties(p, propsEncoded, propsSize); - if (res == SZ_OK) - res = LzmaEnc_MemEncode(p, dest, destLen, src, srcLen, - writeEndMark, progress, alloc, allocBig); - } + res = LzmaEnc_MemEncode(p, dest, destLen, src, srcLen, + writeEndMark, progress, alloc, allocBig); + } - LzmaEnc_Destroy(p, alloc, allocBig); - return res; + LzmaEnc_Destroy(p, alloc, allocBig); + return res; } + + +/* +#ifndef Z7_ST +void LzmaEnc_GetLzThreads(CLzmaEncHandle p, HANDLE lz_threads[2]) +{ + GET_const_CLzmaEnc_p + lz_threads[0] = p->matchFinderMt.hashSync.thread; + lz_threads[1] = p->matchFinderMt.btSync.thread; +} +#endif +*/ diff --git a/common/LZMA/SDK/C/LzmaEnc.h b/common/LZMA/SDK/C/LzmaEnc.h index 200d60e..9f8039a 100644 --- a/common/LZMA/SDK/C/LzmaEnc.h +++ b/common/LZMA/SDK/C/LzmaEnc.h @@ -1,23 +1,21 @@ /* LzmaEnc.h -- LZMA Encoder -2009-02-07 : Igor Pavlov : Public domain */ +2023-04-13 : Igor Pavlov : Public domain */ -#ifndef __LZMA_ENC_H -#define __LZMA_ENC_H +#ifndef ZIP7_INC_LZMA_ENC_H +#define ZIP7_INC_LZMA_ENC_H -#include "Types.h" +#include "7zTypes.h" -#ifdef __cplusplus -extern "C" { -#endif +EXTERN_C_BEGIN #define LZMA_PROPS_SIZE 5 -typedef struct _CLzmaEncProps +typedef struct { - int level; /* 0 <= level <= 9 */ + int level; /* 0 <= level <= 9 */ UInt32 dictSize; /* (1 << 12) <= dictSize <= (1 << 27) for 32-bit version - (1 << 12) <= dictSize <= (1 << 30) for 64-bit version - default = (1 << 24) */ + (1 << 12) <= dictSize <= (3 << 29) for 64-bit version + default = (1 << 24) */ int lc; /* 0 <= lc <= 8, default = 3 */ int lp; /* 0 <= lp <= 4, default = 0 */ int pb; /* 0 <= pb <= 4, default = 2 */ @@ -25,9 +23,17 @@ typedef struct _CLzmaEncProps int fb; /* 5 <= fb <= 273, default = 32 */ int btMode; /* 0 - hashChain Mode, 1 - binTree mode - normal, default = 1 */ int numHashBytes; /* 2, 3 or 4, default = 4 */ - UInt32 mc; /* 1 <= mc <= (1 << 30), default = 32 */ + unsigned numHashOutBits; /* default = ? */ + UInt32 mc; /* 1 <= mc <= (1 << 30), default = 32 */ unsigned writeEndMark; /* 0 - do not write EOPM, 1 - write EOPM, default = 0 */ int numThreads; /* 1 or 2, default = 2 */ + + // int _pad; + + UInt64 reduceSize; /* estimated size of data that will be compressed. default = (UInt64)(Int64)-1. + Encoder uses this value to reduce dictionary size */ + + UInt64 affinity; } CLzmaEncProps; void LzmaEncProps_Init(CLzmaEncProps *p); @@ -37,44 +43,41 @@ UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2); /* ---------- CLzmaEncHandle Interface ---------- */ -/* LzmaEnc_* functions can return the following exit codes: -Returns: +/* LzmaEnc* functions can return the following exit codes: +SRes: SZ_OK - OK SZ_ERROR_MEM - Memory allocation error SZ_ERROR_PARAM - Incorrect paramater in props - SZ_ERROR_WRITE - Write callback error. + SZ_ERROR_WRITE - ISeqOutStream write callback error + SZ_ERROR_OUTPUT_EOF - output buffer overflow - version with (Byte *) output SZ_ERROR_PROGRESS - some break from progress callback - SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version) + SZ_ERROR_THREAD - error in multithreading functions (only for Mt version) */ -typedef void * CLzmaEncHandle; +typedef struct CLzmaEnc CLzmaEnc; +typedef CLzmaEnc * CLzmaEncHandle; +// Z7_DECLARE_HANDLE(CLzmaEncHandle) + +CLzmaEncHandle LzmaEnc_Create(ISzAllocPtr alloc); +void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAllocPtr alloc, ISzAllocPtr allocBig); -CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc); -void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig); SRes LzmaEnc_SetProps(CLzmaEncHandle p, const CLzmaEncProps *props); +void LzmaEnc_SetDataSize(CLzmaEncHandle p, UInt64 expectedDataSiize); SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *properties, SizeT *size); -SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStream *outStream, ISeqInStream *inStream, - ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); +unsigned LzmaEnc_IsWriteEndMark(CLzmaEncHandle p); + +SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStreamPtr outStream, ISeqInStreamPtr inStream, + ICompressProgressPtr progress, ISzAllocPtr alloc, ISzAllocPtr allocBig); SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, - int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); + int writeEndMark, ICompressProgressPtr progress, ISzAllocPtr alloc, ISzAllocPtr allocBig); + /* ---------- One Call Interface ---------- */ -/* LzmaEncode -Return code: - SZ_OK - OK - SZ_ERROR_MEM - Memory allocation error - SZ_ERROR_PARAM - Incorrect paramater - SZ_ERROR_OUTPUT_EOF - output buffer overflow - SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version) -*/ - SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark, - ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); + ICompressProgressPtr progress, ISzAllocPtr alloc, ISzAllocPtr allocBig); -#ifdef __cplusplus -} -#endif +EXTERN_C_END #endif diff --git a/common/LZMA/SDK/C/Precomp.h b/common/LZMA/SDK/C/Precomp.h new file mode 100644 index 0000000..98a0a33 --- /dev/null +++ b/common/LZMA/SDK/C/Precomp.h @@ -0,0 +1,130 @@ +/* Precomp.h -- precompilation file +2024-01-25 : Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_PRECOMP_H +#define ZIP7_INC_PRECOMP_H + +/* + this file must be included before another *.h files and before . + this file is included from the following files: + C\*.c + C\Util\*\Precomp.h <- C\Util\*\*.c + CPP\Common\Common.h <- *\StdAfx.h <- *\*.cpp + + this file can set the following macros: + Z7_LARGE_PAGES 1 + Z7_LONG_PATH 1 + Z7_WIN32_WINNT_MIN 0x0500 (or higher) : we require at least win2000+ for 7-Zip + _WIN32_WINNT 0x0500 (or higher) + WINVER _WIN32_WINNT + UNICODE 1 + _UNICODE 1 +*/ + +#include "Compiler.h" + +// UEFITool: use single-threaded LzFind +#define Z7_ST + +#ifdef _MSC_VER +// #pragma warning(disable : 4206) // nonstandard extension used : translation unit is empty +#if _MSC_VER >= 1912 +// #pragma warning(disable : 5039) // pointer or reference to potentially throwing function passed to 'extern "C"' function under - EHc.Undefined behavior may occur if this function throws an exception. +#endif +#endif + +/* +// for debug: +#define UNICODE 1 +#define _UNICODE 1 +#define _WIN32_WINNT 0x0500 // win2000 +#ifndef WINVER + #define WINVER _WIN32_WINNT +#endif +*/ + +#ifdef _WIN32 +/* + this "Precomp.h" file must be included before , + if we want to define _WIN32_WINNT before . +*/ + +#ifndef Z7_LARGE_PAGES +#ifndef Z7_NO_LARGE_PAGES +#define Z7_LARGE_PAGES 1 +#endif +#endif + +#ifndef Z7_LONG_PATH +#ifndef Z7_NO_LONG_PATH +#define Z7_LONG_PATH 1 +#endif +#endif + +#ifndef Z7_DEVICE_FILE +#ifndef Z7_NO_DEVICE_FILE +// #define Z7_DEVICE_FILE 1 +#endif +#endif + +// we don't change macros if included after +#ifndef _WINDOWS_ + +#ifndef Z7_WIN32_WINNT_MIN + #if defined(_M_ARM64) || defined(__aarch64__) + // #define Z7_WIN32_WINNT_MIN 0x0a00 // win10 + #define Z7_WIN32_WINNT_MIN 0x0600 // vista + #elif defined(_M_ARM) && defined(_M_ARMT) && defined(_M_ARM_NT) + // #define Z7_WIN32_WINNT_MIN 0x0602 // win8 + #define Z7_WIN32_WINNT_MIN 0x0600 // vista + #elif defined(_M_X64) || defined(_M_AMD64) || defined(__x86_64__) || defined(_M_IA64) + #define Z7_WIN32_WINNT_MIN 0x0503 // win2003 + // #elif defined(_M_IX86) || defined(__i386__) + // #define Z7_WIN32_WINNT_MIN 0x0500 // win2000 + #else // x86 and another(old) systems + #define Z7_WIN32_WINNT_MIN 0x0500 // win2000 + // #define Z7_WIN32_WINNT_MIN 0x0502 // win2003 // for debug + #endif +#endif // Z7_WIN32_WINNT_MIN + + +#ifndef Z7_DO_NOT_DEFINE_WIN32_WINNT +#ifdef _WIN32_WINNT + // #error Stop_Compiling_Bad_WIN32_WINNT +#else + #ifndef Z7_NO_DEFINE_WIN32_WINNT +Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER + #define _WIN32_WINNT Z7_WIN32_WINNT_MIN +Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER + #endif +#endif // _WIN32_WINNT + +#ifndef WINVER + #define WINVER _WIN32_WINNT +#endif +#endif // Z7_DO_NOT_DEFINE_WIN32_WINNT + + +#ifndef _MBCS +#ifndef Z7_NO_UNICODE +// UNICODE and _UNICODE are used by and by 7-zip code. + +#ifndef UNICODE +#define UNICODE 1 +#endif + +#ifndef _UNICODE +Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER +#define _UNICODE 1 +Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER +#endif + +#endif // Z7_NO_UNICODE +#endif // _MBCS +#endif // _WINDOWS_ + +// #include "7zWindows.h" + +#endif // _WIN32 + +#endif diff --git a/common/LZMA/SDK/C/RotateDefs.h b/common/LZMA/SDK/C/RotateDefs.h new file mode 100644 index 0000000..c16b4f8 --- /dev/null +++ b/common/LZMA/SDK/C/RotateDefs.h @@ -0,0 +1,50 @@ +/* RotateDefs.h -- Rotate functions +2023-06-18 : Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_ROTATE_DEFS_H +#define ZIP7_INC_ROTATE_DEFS_H + +#ifdef _MSC_VER + +#include + +/* don't use _rotl with old MINGW. It can insert slow call to function. */ + +/* #if (_MSC_VER >= 1200) */ +#pragma intrinsic(_rotl) +#pragma intrinsic(_rotr) +/* #endif */ + +#define rotlFixed(x, n) _rotl((x), (n)) +#define rotrFixed(x, n) _rotr((x), (n)) + +#if (_MSC_VER >= 1300) +#define Z7_ROTL64(x, n) _rotl64((x), (n)) +#define Z7_ROTR64(x, n) _rotr64((x), (n)) +#else +#define Z7_ROTL64(x, n) (((x) << (n)) | ((x) >> (64 - (n)))) +#define Z7_ROTR64(x, n) (((x) >> (n)) | ((x) << (64 - (n)))) +#endif + +#else + +/* new compilers can translate these macros to fast commands. */ + +#if defined(__clang__) && (__clang_major__ >= 4) \ + || defined(__GNUC__) && (__GNUC__ >= 5) +/* GCC 4.9.0 and clang 3.5 can recognize more correct version: */ +#define rotlFixed(x, n) (((x) << (n)) | ((x) >> (-(n) & 31))) +#define rotrFixed(x, n) (((x) >> (n)) | ((x) << (-(n) & 31))) +#define Z7_ROTL64(x, n) (((x) << (n)) | ((x) >> (-(n) & 63))) +#define Z7_ROTR64(x, n) (((x) >> (n)) | ((x) << (-(n) & 63))) +#else +/* for old GCC / clang: */ +#define rotlFixed(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) +#define rotrFixed(x, n) (((x) >> (n)) | ((x) << (32 - (n)))) +#define Z7_ROTL64(x, n) (((x) << (n)) | ((x) >> (64 - (n)))) +#define Z7_ROTR64(x, n) (((x) >> (n)) | ((x) << (64 - (n)))) +#endif + +#endif + +#endif diff --git a/common/LZMA/SDK/C/Types.h b/common/LZMA/SDK/C/Types.h deleted file mode 100644 index 90f6752..0000000 --- a/common/LZMA/SDK/C/Types.h +++ /dev/null @@ -1,256 +0,0 @@ -/* Types.h -- Basic types -2010-10-09 : Igor Pavlov : Public domain */ - -#ifndef __7Z_TYPES_H -#define __7Z_TYPES_H - -#include "../../UefiLzma.h" - -#include - -#ifdef _WIN32 -#include -#endif - -#ifndef EXTERN_C_BEGIN -#ifdef __cplusplus -#define EXTERN_C_BEGIN extern "C" { -#define EXTERN_C_END } -#else -#define EXTERN_C_BEGIN -#define EXTERN_C_END -#endif -#endif - -EXTERN_C_BEGIN - -#define SZ_OK 0 - -#define SZ_ERROR_DATA 1 -#define SZ_ERROR_MEM 2 -#define SZ_ERROR_CRC 3 -#define SZ_ERROR_UNSUPPORTED 4 -#define SZ_ERROR_PARAM 5 -#define SZ_ERROR_INPUT_EOF 6 -#define SZ_ERROR_OUTPUT_EOF 7 -#define SZ_ERROR_READ 8 -#define SZ_ERROR_WRITE 9 -#define SZ_ERROR_PROGRESS 10 -#define SZ_ERROR_FAIL 11 -#define SZ_ERROR_THREAD 12 - -#define SZ_ERROR_ARCHIVE 16 -#define SZ_ERROR_NO_ARCHIVE 17 - -typedef int SRes; - -#ifdef _WIN32 -typedef DWORD WRes; -#else -typedef int WRes; -#endif - -#ifndef RINOK -#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; } -#endif - -typedef unsigned char Byte; -typedef short Int16; -typedef unsigned short UInt16; - -#ifdef _LZMA_UINT32_IS_ULONG -typedef long Int32; -typedef unsigned long UInt32; -#else -typedef int Int32; -typedef unsigned int UInt32; -#endif - -#ifdef _SZ_NO_INT_64 - -/* define _SZ_NO_INT_64, if your compiler doesn't support 64-bit integers. - NOTES: Some code will work incorrectly in that case! */ - -typedef long Int64; -typedef unsigned long UInt64; - -#else - -#if defined(_MSC_VER) || defined(__BORLANDC__) -typedef __int64 Int64; -typedef unsigned __int64 UInt64; -#define UINT64_CONST(n) n -#else -typedef long long int Int64; -typedef unsigned long long int UInt64; -#define UINT64_CONST(n) n ## ULL -#endif - -#endif - -#ifdef _LZMA_NO_SYSTEM_SIZE_T -typedef UInt32 SizeT; -#else -typedef size_t SizeT; -#endif - -typedef int Bool; -#define True 1 -#define False 0 - - -#ifdef _WIN32 -#define MY_STD_CALL __stdcall -#else -#define MY_STD_CALL -#endif - -#ifdef _MSC_VER - -#if _MSC_VER >= 1300 -#define MY_NO_INLINE __declspec(noinline) -#else -#define MY_NO_INLINE -#endif - -#define MY_CDECL __cdecl -#define MY_FAST_CALL __fastcall - -#else - -#define MY_CDECL -#define MY_FAST_CALL - -#endif - - -/* The following interfaces use first parameter as pointer to structure */ - -typedef struct -{ - Byte (*Read)(void *p); /* reads one byte, returns 0 in case of EOF or error */ -} IByteIn; - -typedef struct -{ - void (*Write)(void *p, Byte b); -} IByteOut; - -typedef struct -{ - SRes (*Read)(void *p, void *buf, size_t *size); - /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. - (output(*size) < input(*size)) is allowed */ -} ISeqInStream; - -/* it can return SZ_ERROR_INPUT_EOF */ -SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size); -SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType); -SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf); - -typedef struct -{ - size_t (*Write)(void *p, const void *buf, size_t size); - /* Returns: result - the number of actually written bytes. - (result < size) means error */ -} ISeqOutStream; - -typedef enum -{ - SZ_SEEK_SET = 0, - SZ_SEEK_CUR = 1, - SZ_SEEK_END = 2 -} ESzSeek; - -typedef struct -{ - SRes (*Read)(void *p, void *buf, size_t *size); /* same as ISeqInStream::Read */ - SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin); -} ISeekInStream; - -typedef struct -{ - SRes (*Look)(void *p, const void **buf, size_t *size); - /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. - (output(*size) > input(*size)) is not allowed - (output(*size) < input(*size)) is allowed */ - SRes (*Skip)(void *p, size_t offset); - /* offset must be <= output(*size) of Look */ - - SRes (*Read)(void *p, void *buf, size_t *size); - /* reads directly (without buffer). It's same as ISeqInStream::Read */ - SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin); -} ILookInStream; - -SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size); -SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset); - -/* reads via ILookInStream::Read */ -SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType); -SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size); - -#define LookToRead_BUF_SIZE (1 << 14) - -typedef struct -{ - ILookInStream s; - ISeekInStream *realStream; - size_t pos; - size_t size; - Byte buf[LookToRead_BUF_SIZE]; -} CLookToRead; - -void LookToRead_CreateVTable(CLookToRead *p, int lookahead); -void LookToRead_Init(CLookToRead *p); - -typedef struct -{ - ISeqInStream s; - ILookInStream *realStream; -} CSecToLook; - -void SecToLook_CreateVTable(CSecToLook *p); - -typedef struct -{ - ISeqInStream s; - ILookInStream *realStream; -} CSecToRead; - -void SecToRead_CreateVTable(CSecToRead *p); - -typedef struct -{ - SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize); - /* Returns: result. (result != SZ_OK) means break. - Value (UInt64)(Int64)-1 for size means unknown value. */ -} ICompressProgress; - -typedef struct -{ - void *(*Alloc)(void *p, size_t size); - void (*Free)(void *p, void *address); /* address can be 0 */ -} ISzAlloc; - -#define IAlloc_Alloc(p, size) (p)->Alloc((p), size) -#define IAlloc_Free(p, a) (p)->Free((p), a) - -#ifdef _WIN32 - -#define CHAR_PATH_SEPARATOR '\\' -#define WCHAR_PATH_SEPARATOR L'\\' -#define STRING_PATH_SEPARATOR "\\" -#define WSTRING_PATH_SEPARATOR L"\\" - -#else - -#define CHAR_PATH_SEPARATOR '/' -#define WCHAR_PATH_SEPARATOR L'/' -#define STRING_PATH_SEPARATOR "/" -#define WSTRING_PATH_SEPARATOR L"/" - -#endif - -EXTERN_C_END - -#endif diff --git a/common/LZMA/UefiLzma.h b/common/LZMA/UefiLzma.h deleted file mode 100644 index 2ef4b0e..0000000 --- a/common/LZMA/UefiLzma.h +++ /dev/null @@ -1,31 +0,0 @@ -/* LZMA UEFI header file - - Copyright (c) 2009, Intel Corporation. All rights reserved. - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -*/ - -#ifndef __UEFILZMA_H__ -#define __UEFILZMA_H__ - -#include "../basetypes.h" - -#ifdef _WIN32 -#undef _WIN32 -#endif - -#ifdef _WIN64 -#undef _WIN64 -#endif - -#define _LZMA_SIZE_OPT -#define _7ZIP_ST - -#endif // __UEFILZMA_H__ - diff --git a/common/Tiano/EfiTianoCompress.c b/common/Tiano/EfiTianoCompress.c index a2fe4bf..896c3bf 100644 --- a/common/Tiano/EfiTianoCompress.c +++ b/common/Tiano/EfiTianoCompress.c @@ -69,18 +69,15 @@ PutDword( STATIC EFI_STATUS -AllocateMemory ( - ); +AllocateMemory (VOID); STATIC VOID -FreeMemory ( - ); +FreeMemory (VOID); STATIC VOID -InitSlide ( - ); +InitSlide (VOID); STATIC NODE @@ -105,28 +102,23 @@ Split ( STATIC VOID -InsertNode ( - ); +InsertNode (VOID); STATIC VOID -DeleteNode ( - ); +DeleteNode (VOID); STATIC VOID -GetNextMatch ( - ); +GetNextMatch (VOID); STATIC EFI_STATUS -Encode ( - ); +Encode (VOID); STATIC VOID -CountTFreq ( - ); +CountTFreq (VOID); STATIC VOID @@ -138,8 +130,7 @@ WritePTLen ( STATIC VOID -WriteCLen ( - ); +WriteCLen (VOID); STATIC VOID @@ -155,8 +146,7 @@ EncodeP ( STATIC VOID -SendBlock ( - ); +SendBlock (VOID); STATIC VOID @@ -167,18 +157,15 @@ Output ( STATIC VOID -HufEncodeStart ( - ); +HufEncodeStart (VOID); STATIC VOID -HufEncodeEnd ( - ); +HufEncodeEnd (VOID); STATIC VOID -MakeCrcTable ( - ); +MakeCrcTable (VOID); STATIC VOID @@ -196,8 +183,7 @@ FreadCrc ( STATIC VOID -InitPutBits ( - ); +InitPutBits (VOID); STATIC VOID @@ -550,39 +536,14 @@ Returns: (VOID) --*/ { - if (mText) { free (mText); - } - - if (mLevel) { free (mLevel); - } - - if (mChildCount) { free (mChildCount); - } - - if (mPosition) { free (mPosition); - } - - if (mParent) { free (mParent); - } - - if (mPrev) { free (mPrev); - } - - if (mNext) { free (mNext); - } - - if (mBuf) { free (mBuf); - } - - return; } @@ -1598,7 +1559,7 @@ Returns: (VOID) INT32 i; UINT16 Start[18]; - Start[1] = 0; + memset(Start, 0, sizeof(Start)); for (i = 1; i <= 16; i++) { Start[i + 1] = (UINT16)((Start[i] + mLenCnt[i]) << 1); } diff --git a/common/Tiano/EfiTianoCompress.h b/common/Tiano/EfiTianoCompress.h index 9dc042e..512c39b 100644 --- a/common/Tiano/EfiTianoCompress.h +++ b/common/Tiano/EfiTianoCompress.h @@ -56,22 +56,20 @@ extern "C" { --*/ EFI_STATUS - TianoCompress( - CONST VOID *SrcBuffer, - UINT32 SrcSize, - VOID *DstBuffer, - UINT32 *DstSize - ) - ; + TianoCompress ( + IN CONST VOID *SrcBuffer, + IN UINT32 SrcSize, + IN VOID *DstBuffer, + IN OUT UINT32 *DstSize + ); EFI_STATUS TianoCompressLegacy( - CONST VOID *SrcBuffer, - UINT32 SrcSize, - VOID *DstBuffer, - UINT32 *DstSize - ) - ; + CONST VOID *SrcBuffer, + UINT32 SrcSize, + VOID *DstBuffer, + UINT32 *DstSize + ); /*++ Routine Description: @@ -96,21 +94,20 @@ extern "C" { --*/ EFI_STATUS - EfiCompress( - CONST VOID *SrcBuffer, - UINT32 SrcSize, - VOID *DstBuffer, - UINT32 *DstSize - ) - ; + EfiCompress ( + IN CONST VOID *SrcBuffer, + IN UINT32 SrcSize, + IN VOID *DstBuffer, + IN OUT UINT32 *DstSize + ); + EFI_STATUS EfiCompressLegacy( - CONST VOID *SrcBuffer, - UINT32 SrcSize, - VOID *DstBuffer, - UINT32 *DstSize - ) - ; + CONST VOID *SrcBuffer, + UINT32 SrcSize, + VOID *DstBuffer, + UINT32 *DstSize + ); #ifdef __cplusplus } diff --git a/common/Tiano/EfiTianoCompressLegacy.c b/common/Tiano/EfiTianoCompressLegacy.c index 11e071c..e81fc30 100644 --- a/common/Tiano/EfiTianoCompressLegacy.c +++ b/common/Tiano/EfiTianoCompressLegacy.c @@ -580,39 +580,14 @@ VOID --*/ { - if (mText != NULL) { free (mText); - } - - if (mLevel != NULL) { free (mLevel); - } - - if (mChildCount != NULL) { free (mChildCount); - } - - if (mPosition != NULL) { free (mPosition); - } - - if (mParent != NULL) { free (mParent); - } - - if (mPrev != NULL) { free (mPrev); - } - - if (mNext != NULL) { free (mNext); - } - - if (mBuf != NULL) { free (mBuf); - } - - return ; } STATIC diff --git a/common/Tiano/EfiTianoDecompress.c b/common/Tiano/EfiTianoDecompress.c index 156392c..fbcd8ca 100644 --- a/common/Tiano/EfiTianoDecompress.c +++ b/common/Tiano/EfiTianoDecompress.c @@ -1,7 +1,8 @@ /*++ EfiTianoDecompress.c -Copyright (c) 2015, Nikolaj Schlej. All rights reserved.
-Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.
+Copyright (c) 2018, LongSoft. All rights reserved.
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -16,7 +17,7 @@ Decompress.c Abstract: -Decompressor. Algorithm Ported from OPSD code (Decomp.asm) +UEFI Decompress Library implementation refer to UEFI specification. --*/ @@ -80,37 +81,86 @@ typedef struct { } SCRATCH_DATA; STATIC -VOID -FillBuf( -IN SCRATCH_DATA *Sd, -IN UINT16 NumOfBits -) -/*++ - -Routine Description: - -Shift mBitBuf NumOfBits left. Read in NumOfBits of bits from source. - -Arguments: - -Sd - The global scratch data -NumOfBits - The number of bits to shift and read. - -Returns: (VOID) - ---*/ +UINT64 +EFIAPI +LShiftU64 ( + UINT64 Operand, + UINT32 Count + ) { - Sd->mBitBuf = (UINT32)(Sd->mBitBuf << NumOfBits); + return Operand << Count; +} +STATIC +VOID * +EFIAPI +SetMem ( + OUT VOID *Buffer, + IN UINTN Length, + IN UINT8 Value + ) +{ + return memset (Buffer, Value, Length); +} + +STATIC +VOID * +EFIAPI +SetMem16 ( + OUT VOID *Buffer, + IN UINTN Length, + IN UINT16 Value + ) +{ + UINTN Index; + UINT16* Buf = (UINT16*)Buffer; + + if (Buffer == NULL || Length == 0) { + return Buffer; + } + + Length /= sizeof(UINT16); + + for (Index = 0; Index < Length; Index++) { + Buf[Index] = Value; + } + + return Buffer; +} + +/** + Read NumOfBit of bits from source into mBitBuf. + + Shift mBitBuf NumOfBits left. Read in NumOfBits of bits from source. + + @param Sd The global scratch data. + @param NumOfBits The number of bits to shift and read. + +**/ +STATIC +VOID +FillBuf ( + IN SCRATCH_DATA *Sd, + IN UINT16 NumOfBits + ) +{ + // + // Left shift NumOfBits of bits in advance + // + Sd->mBitBuf = (UINT32)LShiftU64 (((UINT64)Sd->mBitBuf), NumOfBits); + + // + // Copy data needed in bytes into mSbuBitBuf + // while (NumOfBits > Sd->mBitCount) { - Sd->mBitBuf |= (UINT32)(Sd->mSubBitBuf << (NumOfBits = (UINT16)(NumOfBits - Sd->mBitCount))); + NumOfBits = (UINT16)(NumOfBits - Sd->mBitCount); + Sd->mBitBuf |= (UINT32)LShiftU64 (((UINT64)Sd->mSubBitBuf), NumOfBits); if (Sd->mCompSize > 0) { // // Get 1 byte into SubBitBuf // Sd->mCompSize--; - Sd->mSubBitBuf = 0; Sd->mSubBitBuf = Sd->mSrcBase[Sd->mInBuf++]; Sd->mBitCount = 8; } @@ -123,73 +173,78 @@ Returns: (VOID) } } + // + // Calculate additional bit count read to update mBitCount + // Sd->mBitCount = (UINT16)(Sd->mBitCount - NumOfBits); + + // + // Copy NumOfBits of bits from mSubBitBuf into mBitBuf + // Sd->mBitBuf |= Sd->mSubBitBuf >> Sd->mBitCount; } +/** + Get NumOfBits of bits out from mBitBuf. + + Get NumOfBits of bits out from mBitBuf. Fill mBitBuf with subsequent + NumOfBits of bits from source. Returns NumOfBits of bits that are + popped out. + + @param Sd The global scratch data. + @param NumOfBits The number of bits to pop and read. + + @return The bits that are popped out. + +**/ STATIC UINT32 -GetBits( -IN SCRATCH_DATA *Sd, -IN UINT16 NumOfBits -) -/*++ - -Routine Description: - -Get NumOfBits of bits out from mBitBuf. Fill mBitBuf with subsequent -NumOfBits of bits from source. Returns NumOfBits of bits that are -popped out. - -Arguments: - -Sd - The global scratch data. -NumOfBits - The number of bits to pop and read. - -Returns: - -The bits that are popped out. - ---*/ +GetBits ( + IN SCRATCH_DATA *Sd, + IN UINT16 NumOfBits + ) { UINT32 OutBits; + // + // Pop NumOfBits of Bits from Left + // OutBits = (UINT32)(Sd->mBitBuf >> (BITBUFSIZ - NumOfBits)); - FillBuf(Sd, NumOfBits); + // + // Fill up mBitBuf from source + // + FillBuf (Sd, NumOfBits); return OutBits; } +/** + Creates Huffman Code mapping table according to code length array. + + Creates Huffman Code mapping table for Extra Set, Char&Len Set + and Position Set according to code length array. + If TableBits > 16, then ASSERT (). + + @param Sd The global scratch data. + @param NumOfChar The number of symbols in the symbol set. + @param BitLen Code length array. + @param TableBits The width of the mapping table. + @param Table The table to be created. + + @retval 0 OK. + @retval BAD_TABLE The table is corrupted. + +**/ STATIC UINT16 -MakeTable( -IN SCRATCH_DATA *Sd, -IN UINT16 NumOfChar, -IN UINT8 *BitLen, -IN UINT16 TableBits, -OUT UINT16 *Table -) -/*++ - -Routine Description: - -Creates Huffman Code mapping table according to code length array. - -Arguments: - -Sd - The global scratch data -NumOfChar - Number of symbols in the symbol set -BitLen - Code length array -TableBits - The width of the mapping table -Table - The table - -Returns: - -0 - OK. -BAD_TABLE - The table is corrupted. - ---*/ +MakeTable ( + IN SCRATCH_DATA *Sd, + IN UINT16 NumOfChar, + IN UINT8 *BitLen, + IN UINT16 TableBits, + OUT UINT16 *Table + ) { UINT16 Count[17]; UINT16 Weight[17]; @@ -203,9 +258,13 @@ BAD_TABLE - The table is corrupted. UINT16 Avail; UINT16 NextCode; UINT16 Mask; + UINT16 WordOfStart; + UINT16 WordOfCount; + UINT16 MaxTableLength; // - // TableBits should not be greater than 16. + // The maximum mapping table width supported by this internal + // working function is 16. // if (TableBits >= (sizeof(Count) / sizeof(UINT16))) { return (UINT16)BAD_TABLE; @@ -219,22 +278,19 @@ BAD_TABLE - The table is corrupted. } for (Index = 0; Index < NumOfChar; Index++) { - // - // Count array index should not be greater than or equal to its size. - // - if (BitLen[Index] < (sizeof(Count) / sizeof(UINT16))) { - Count[BitLen[Index]]++; - } - else { + if (BitLen[Index] > 16) { return (UINT16)BAD_TABLE; } + Count[BitLen[Index]]++; } Start[0] = 0; Start[1] = 0; for (Index = 1; Index <= 16; Index++) { - Start[Index + 1] = (UINT16)(Start[Index] + (Count[Index] << (16 - Index))); + WordOfStart = Start[Index]; + WordOfCount = Count[Index]; + Start[Index + 1] = (UINT16)(WordOfStart + (WordOfCount << (16 - Index))); } if (Start[17] != 0) { @@ -244,6 +300,7 @@ BAD_TABLE - The table is corrupted. JuBits = (UINT16)(16 - TableBits); + Weight[0] = 0; for (Index = 1; Index <= TableBits; Index++) { Start[Index] >>= JuBits; Weight[Index] = (UINT16)(1U << (TableBits - Index)); @@ -258,13 +315,14 @@ BAD_TABLE - The table is corrupted. if (Index != 0) { Index3 = (UINT16)(1U << TableBits); - while (Index != Index3) { - Table[Index++] = 0; + if (Index < Index3) { + SetMem16 (Table + Index, (Index3 - Index) * sizeof(*Table), 0); } } Avail = NumOfChar; Mask = (UINT16)(1U << (15 - TableBits)); + MaxTableLength = (UINT16)(1U << TableBits); for (Char = 0; Char < NumOfChar; Char++) { Len = BitLen[Char]; @@ -275,12 +333,14 @@ BAD_TABLE - The table is corrupted. NextCode = (UINT16)(Start[Len] + Weight[Len]); if (Len <= TableBits) { + for (Index = Start[Len]; Index < NextCode; Index++) { - // Check to prevent possible heap corruption - if (Index >= (UINT16)(1U << TableBits)) + if (Index >= MaxTableLength) { return (UINT16)BAD_TABLE; + } Table[Index] = Char; } + } else { Index3 = Start[Len]; @@ -288,22 +348,18 @@ BAD_TABLE - The table is corrupted. Index = (UINT16)(Len - TableBits); while (Index != 0) { - // - // Avail should be lesser than size of mRight and mLeft to prevent buffer overflow. - // - if ((*Pointer == 0) && (Avail < sizeof(Sd->mRight) / sizeof(UINT16)) && (Avail < sizeof(Sd->mLeft) / sizeof(UINT16))) { + if (*Pointer == 0 && Avail < (2 * NC - 1)) { Sd->mRight[Avail] = Sd->mLeft[Avail] = 0; *Pointer = Avail++; } - // - // *Pointer should be lesser than size of mRight and mLeft to prevent buffer overflow. - // - if ((Index3 & Mask) && (*Pointer < (sizeof(Sd->mRight) / sizeof(UINT16)))) { - Pointer = &Sd->mRight[*Pointer]; - } - else if (*Pointer < (sizeof(Sd->mLeft) / sizeof(UINT16))) { - Pointer = &Sd->mLeft[*Pointer]; + if (*Pointer < (2 * NC - 1)) { + if ((Index3 & Mask) != 0) { + Pointer = &Sd->mRight[*Pointer]; + } + else { + Pointer = &Sd->mLeft[*Pointer]; + } } Index3 <<= 1; @@ -311,6 +367,7 @@ BAD_TABLE - The table is corrupted. } *Pointer = Char; + } Start[Len] = NextCode; @@ -321,26 +378,20 @@ BAD_TABLE - The table is corrupted. return 0; } -STATIC +/** + Decodes a position value. + + Get a position value according to Position Huffman Table. + + @param Sd The global scratch data. + + @return The position value decoded. + +**/ UINT32 -DecodeP( -IN SCRATCH_DATA *Sd -) -/*++ - -Routine Description: - -Decodes a position value. - -Arguments: - -Sd - the global scratch data - -Returns: - -The position value decoded. - ---*/ +DecodeP ( + IN SCRATCH_DATA *Sd + ) { UINT16 Val; UINT32 Mask; @@ -352,7 +403,7 @@ The position value decoded. Mask = 1U << (BITBUFSIZ - 1 - 8); do { - if (Sd->mBitBuf & Mask) { + if ((Sd->mBitBuf & Mask) != 0) { Val = Sd->mRight[Val]; } else { @@ -365,50 +416,50 @@ The position value decoded. // // Advance what we have read // - FillBuf(Sd, Sd->mPTLen[Val]); + FillBuf (Sd, Sd->mPTLen[Val]); Pos = Val; if (Val > 1) { - Pos = (UINT32)((1U << (Val - 1)) + GetBits(Sd, (UINT16)(Val - 1))); + Pos = (UINT32)((1U << (Val - 1)) + GetBits (Sd, (UINT16)(Val - 1))); } return Pos; } +/** + Reads code lengths for the Extra Set or the Position Set. + + Read in the Extra Set or Position Set Length Array, then + generate the Huffman code mapping for them. + + @param Sd The global scratch data. + @param nn The number of symbols. + @param nbit The number of bits needed to represent nn. + @param Special The special symbol that needs to be taken care of. + + @retval 0 OK. + @retval BAD_TABLE Table is corrupted. + +**/ STATIC UINT16 -ReadPTLen( -IN SCRATCH_DATA *Sd, -IN UINT16 nn, -IN UINT16 nbit, -IN UINT16 Special -) -/*++ - -Routine Description: - -Reads code lengths for the Extra Set or the Position Set - -Arguments: - -Sd - The global scratch data -nn - Number of symbols -nbit - Number of bits needed to represent nn -Special - The special symbol that needs to be taken care of - -Returns: - -0 - OK. -BAD_TABLE - Table is corrupted. - ---*/ +ReadPTLen ( + IN SCRATCH_DATA *Sd, + IN UINT16 nn, + IN UINT16 nbit, + IN UINT16 Special + ) { UINT16 Number; UINT16 CharC; UINT16 Index; UINT32 Mask; - Number = (UINT16)GetBits(Sd, nbit); + + // + // Read Extra Set Code Length Array size + // + Number = (UINT16)GetBits (Sd, nbit); if ((Number > sizeof(Sd->mPTLen)) || (nn > sizeof(Sd->mPTLen))) { // @@ -418,24 +469,29 @@ BAD_TABLE - Table is corrupted. } if (Number == 0) { - CharC = (UINT16)GetBits(Sd, nbit); + // + // This represents only Huffman code used + // + CharC = (UINT16)GetBits (Sd, nbit); - for (Index = 0; Index < 256; Index++) { - Sd->mPTTable[Index] = CharC; - } + SetMem16 (&Sd->mPTTable[0], sizeof(Sd->mPTTable), CharC); - for (Index = 0; Index < nn; Index++) { - Sd->mPTLen[Index] = 0; - } + SetMem (Sd->mPTLen, nn, 0); return 0; } Index = 0; - while (Index < Number) { + while (Index < Number && Index < NPT) { + CharC = (UINT16)(Sd->mBitBuf >> (BITBUFSIZ - 3)); + // + // If a code length is less than 7, then it is encoded as a 3-bit + // value. Or it is encoded as a series of "1"s followed by a + // terminating "0". The number of "1"s = Code length - 4. + // if (CharC == 7) { Mask = 1U << (BITBUFSIZ - 1 - 3); while (Mask & Sd->mBitBuf) { @@ -448,74 +504,69 @@ BAD_TABLE - Table is corrupted. Sd->mPTLen[Index++] = (UINT8)CharC; + // + // For Code&Len Set, + // After the third length of the code length concatenation, + // a 2-bit value is used to indicated the number of consecutive + // zero lengths after the third length. + // if (Index == Special) { - CharC = (UINT16)GetBits(Sd, 2); - while ((INT16)(--CharC) >= 0) { - if (Index >= sizeof(Sd->mPTLen)) { - // - // Fail if Index is greater than or equal to mPTLen - // - return (UINT16)BAD_TABLE; - } + CharC = (UINT16)GetBits (Sd, 2); + while ((INT16)(--CharC) >= 0 && Index < NPT) { Sd->mPTLen[Index++] = 0; } } } - while (Index < nn) { + while (Index < nn && Index < NPT) { Sd->mPTLen[Index++] = 0; } - return MakeTable(Sd, nn, Sd->mPTLen, 8, Sd->mPTTable); + return MakeTable (Sd, nn, Sd->mPTLen, 8, Sd->mPTTable); } +/** + Reads code lengths for Char&Len Set. + + Read in and decode the Char&Len Set Code Length Array, then + generate the Huffman Code mapping table for the Char&Len Set. + + @param Sd The global scratch data. + +**/ STATIC VOID -ReadCLen( -SCRATCH_DATA *Sd -) -/*++ - -Routine Description: - -Reads code lengths for Char&Len Set. - -Arguments: - -Sd - the global scratch data - -Returns: (VOID) - ---*/ +ReadCLen ( + SCRATCH_DATA *Sd + ) { - UINT16 Number; - UINT16 CharC; - UINT16 Index; - UINT32 Mask; + UINT16 Number; + UINT16 CharC; + UINT16 Index; + UINT32 Mask; - Number = (UINT16)GetBits(Sd, CBIT); + Number = (UINT16)GetBits (Sd, CBIT); if (Number == 0) { - CharC = (UINT16)GetBits(Sd, CBIT); + // + // This represents only Huffman code used + // + CharC = (UINT16)GetBits (Sd, CBIT); - for (Index = 0; Index < NC; Index++) { - Sd->mCLen[Index] = 0; - } - - for (Index = 0; Index < 4096; Index++) { - Sd->mCTable[Index] = CharC; - } + SetMem (Sd->mCLen, NC, 0); + SetMem16 (&Sd->mCTable[0], sizeof(Sd->mCTable), CharC); return; } Index = 0; - while (Index < Number) { + while (Index < Number && Index < NC) { CharC = Sd->mPTTable[Sd->mBitBuf >> (BITBUFSIZ - 8)]; if (CharC >= NT) { Mask = 1U << (BITBUFSIZ - 1 - 8); do { + if (Mask & Sd->mBitBuf) { CharC = Sd->mRight[CharC]; } @@ -524,62 +575,62 @@ Returns: (VOID) } Mask >>= 1; + } while (CharC >= NT); } // // Advance what we have read // - FillBuf(Sd, Sd->mPTLen[CharC]); + FillBuf (Sd, Sd->mPTLen[CharC]); if (CharC <= 2) { + if (CharC == 0) { CharC = 1; } else if (CharC == 1) { - CharC = (UINT16)(GetBits(Sd, 4) + 3); + CharC = (UINT16)(GetBits (Sd, 4) + 3); } else if (CharC == 2) { - CharC = (UINT16)(GetBits(Sd, CBIT) + 20); + CharC = (UINT16)(GetBits (Sd, CBIT) + 20); } - while ((INT16)(--CharC) >= 0) { + while ((INT16)(--CharC) >= 0 && Index < NC) { Sd->mCLen[Index++] = 0; } + } else { + Sd->mCLen[Index++] = (UINT8)(CharC - 2); + } } - while (Index < NC) { - Sd->mCLen[Index++] = 0; - } + SetMem (Sd->mCLen + Index, NC - Index, 0); - MakeTable(Sd, NC, Sd->mCLen, 12, Sd->mCTable); + MakeTable (Sd, NC, Sd->mCLen, 12, Sd->mCTable); return; } +/** + Decode a character/length value. + + Read one value from mBitBuf, Get one code from mBitBuf. If it is at block boundary, generates + Huffman code mapping table for Extra Set, Code&Len Set and + Position Set. + + @param Sd The global scratch data. + + @return The value decoded. + +**/ STATIC UINT16 -DecodeC( -SCRATCH_DATA *Sd -) -/*++ - -Routine Description: - -Decode a character/length value. - -Arguments: - -Sd - The global scratch data. - -Returns: - -The value decoded. - ---*/ +DecodeC ( + SCRATCH_DATA *Sd + ) { UINT16 Index2; UINT32 Mask; @@ -587,21 +638,38 @@ The value decoded. if (Sd->mBlockSize == 0) { // // Starting a new block + // Read BlockSize from block header // - Sd->mBlockSize = (UINT16)GetBits(Sd, 16); - Sd->mBadTableFlag = ReadPTLen(Sd, NT, TBIT, 3); + Sd->mBlockSize = (UINT16)GetBits (Sd, 16); + + // + // Read in the Extra Set Code Length Array, + // Generate the Huffman code mapping table for Extra Set. + // + Sd->mBadTableFlag = ReadPTLen (Sd, NT, TBIT, 3); if (Sd->mBadTableFlag != 0) { return 0; } - ReadCLen(Sd); + // + // Read in and decode the Char&Len Set Code Length Array, + // Generate the Huffman code mapping table for Char&Len Set. + // + ReadCLen (Sd); - Sd->mBadTableFlag = ReadPTLen(Sd, MAXNP, Sd->mPBit, (UINT16)(-1)); + // + // Read in the Position Set Code Length Array, + // Generate the Huffman code mapping table for the Position Set. + // + Sd->mBadTableFlag = ReadPTLen (Sd, MAXNP, Sd->mPBit, (UINT16)(-1)); if (Sd->mBadTableFlag != 0) { return 0; } } + // + // Get one code according to Code&Set Huffman Table + // Sd->mBlockSize--; Index2 = Sd->mCTable[Sd->mBitBuf >> (BITBUFSIZ - 12)]; @@ -609,7 +677,7 @@ The value decoded. Mask = 1U << (BITBUFSIZ - 1 - 12); do { - if (Sd->mBitBuf & Mask) { + if ((Sd->mBitBuf & Mask) != 0) { Index2 = Sd->mRight[Index2]; } else { @@ -622,42 +690,34 @@ The value decoded. // // Advance what we have read // - FillBuf(Sd, Sd->mCLen[Index2]); + FillBuf (Sd, Sd->mCLen[Index2]); return Index2; } +/** + Decode the source data and put the resulting data into the destination buffer. + + @param Sd The global scratch data. + +**/ STATIC VOID -Decode( -SCRATCH_DATA *Sd -) -/*++ - -Routine Description: - -Decode the source data and put the resulting data into the destination buffer. - -Arguments: - -Sd - The global scratch data - -Returns: (VOID) - ---*/ +Decode ( + SCRATCH_DATA *Sd + ) { UINT16 BytesRemain; UINT32 DataIdx; UINT16 CharC; - BytesRemain = (UINT16)(-1); - - DataIdx = 0; - for (;;) { + // + // Get one code from mBitBuf + // CharC = DecodeC(Sd); if (Sd->mBadTableFlag != 0) { - return; + goto Done; } if (CharC < 256) { @@ -665,127 +725,167 @@ Returns: (VOID) // Process an Original character // if (Sd->mOutBuf >= Sd->mOrigSize) { - return; + goto Done; } else { + // + // Write orignal character into mDstBase + // Sd->mDstBase[Sd->mOutBuf++] = (UINT8)CharC; } + } else { // // Process a Pointer // - CharC = (UINT16)(CharC - (UINT8_MAX + 1 - THRESHOLD)); + CharC = (UINT16)(CharC - (0x00000100U - THRESHOLD)); + // + // Get string length + // BytesRemain = CharC; + // + // Locate string position + // DataIdx = Sd->mOutBuf - DecodeP(Sd) - 1; - // Check to prevent possible heap corruption - if (DataIdx >= Sd->mOrigSize - BytesRemain) { - Sd->mBadTableFlag = 1; - return; - } - + // + // Write BytesRemain of bytes into mDstBase + // BytesRemain--; + while ((INT16)(BytesRemain) >= 0) { - Sd->mDstBase[Sd->mOutBuf++] = Sd->mDstBase[DataIdx++]; if (Sd->mOutBuf >= Sd->mOrigSize) { - return; + goto Done; } + if (DataIdx >= Sd->mOrigSize) { + Sd->mBadTableFlag = (UINT16)BAD_TABLE; + goto Done; + } + Sd->mDstBase[Sd->mOutBuf++] = Sd->mDstBase[DataIdx++]; BytesRemain--; } + + // + // Once mOutBuf is fully filled, directly return + // + if (Sd->mOutBuf >= Sd->mOrigSize) { + goto Done; + } } } + +Done: + return; } +/** + Given a compressed source buffer, this function retrieves the size of + the uncompressed buffer and the size of the scratch buffer required + to decompress the compressed source buffer. + + Retrieves the size of the uncompressed buffer and the temporary scratch buffer + required to decompress the buffer specified by Source and SourceSize. + If the size of the uncompressed buffer or the size of the scratch buffer cannot + be determined from the compressed data specified by Source and SourceData, + then EFI_INVALID_PARAMETER is returned. Otherwise, the size of the uncompressed + buffer is returned in DestinationSize, the size of the scratch buffer is returned + in ScratchSize, and EFI_SUCCESS is returned. + This function does not have scratch buffer available to perform a thorough + checking of the validity of the source data. It just retrieves the "Original Size" + field from the beginning bytes of the source data and output it as DestinationSize. + And ScratchSize is specific to the decompression implementation. + + @param Source The source buffer containing the compressed data. + @param SourceSize The size, in bytes, of the source buffer. + @param DestinationSize A pointer to the size, in bytes, of the uncompressed buffer + that will be generated when the compressed buffer specified + by Source and SourceSize is decompressed. + @param ScratchSize A pointer to the size, in bytes, of the scratch buffer that + is required to decompress the compressed buffer specified + by Source and SourceSize. + + @retval EFI_SUCCESS The size of the uncompressed data was returned + in DestinationSize, and the size of the scratch + buffer was returned in ScratchSize. + @retval EFI_INVALID_PARAMETER + The size of the uncompressed data or the size of + the scratch buffer cannot be determined from + the compressed data specified by Source + and SourceSize. +**/ EFI_STATUS -GetInfo( -IN const VOID *Source, -IN UINT32 SrcSize, -OUT UINT32 *DstSize, -OUT UINT32 *ScratchSize -) -/*++ - -Routine Description: - -The internal implementation of *_DECOMPRESS_PROTOCOL.GetInfo(). - -Arguments: - -Source - The source buffer containing the compressed data. -SrcSize - The size of source buffer -DstSize - The size of destination buffer. -ScratchSize - The size of scratch buffer. - -Returns: - -EFI_SUCCESS - The size of destination buffer and the size of scratch buffer are successull retrieved. -EFI_INVALID_PARAMETER - The source data is corrupted - ---*/ +EFIAPI +GetInfo ( + IN CONST VOID *Source, + IN UINT32 SourceSize, + OUT UINT32 *DestinationSize, + OUT UINT32 *ScratchSize + ) { - const UINT8 *Src; + UINT32 CompressedSize; - *ScratchSize = sizeof(SCRATCH_DATA); - - Src = Source; - if (SrcSize < 8) { + if (Source == NULL || DestinationSize == NULL || ScratchSize == NULL || SourceSize < 8) { return EFI_INVALID_PARAMETER; } - *DstSize = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24); + CompressedSize = *(UINT32 *)Source; + if (SourceSize < (CompressedSize + 8) || (CompressedSize + 8) < 8) { + return EFI_INVALID_PARAMETER; + } + + *ScratchSize = sizeof(SCRATCH_DATA); + *DestinationSize = *((UINT32 *)Source + 1); + return EFI_SUCCESS; } +/** + Decompresses a compressed source buffer. + + Extracts decompressed data to its original form. + This function is designed so that the decompression algorithm can be implemented + without using any memory services. As a result, this function is not allowed to + call any memory allocation services in its implementation. It is the caller's + responsibility to allocate and free the Destination and Scratch buffers. + If the compressed source data specified by Source is successfully decompressed + into Destination, then RETURN_SUCCESS is returned. If the compressed source data + specified by Source is not in a valid compressed data format, + then RETURN_INVALID_PARAMETER is returned. + + @param Source The source buffer containing the compressed data. + @param Destination The destination buffer to store the decompressed data. + @param Scratch A temporary scratch buffer that is used to perform the decompression. + This is an optional parameter that may be NULL if the + required scratch buffer size is 0. + + @retval EFI_SUCCESS Decompression completed successfully, and + the uncompressed buffer is returned in Destination. + @retval EFI_INVALID_PARAMETER + The source buffer specified by Source is corrupted + (not in a valid compressed format). +**/ EFI_STATUS -Decompress( -IN const VOID *Source, -IN UINT32 SrcSize, -IN OUT VOID *Destination, -IN UINT32 DstSize, -IN OUT VOID *Scratch, -IN UINT32 ScratchSize, -IN UINT8 Version -) -/*++ - -Routine Description: - -The internal implementation of *_DECOMPRESS_PROTOCOL.Decompress(). - -Arguments: - -Source - The source buffer containing the compressed data. -SrcSize - The size of source buffer -Destination - The destination buffer to store the decompressed data -DstSize - The size of destination buffer. -Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data. -ScratchSize - The size of scratch buffer. -Version - The version of de/compression algorithm. -Version 1 for EFI 1.1 de/compression algorithm. -Version 2 for Tiano de/compression algorithm. - -Returns: - -EFI_SUCCESS - Decompression is successful -EFI_INVALID_PARAMETER - The source data is corrupted - ---*/ +EFIAPI +Decompress ( + IN CONST VOID *Source, + IN UINT32 SrcSize, + IN OUT VOID *Destination, + IN UINT32 DstSize, + IN OUT VOID *Scratch, + IN UINT32 ScratchSize, + IN UINT8 Version + ) { - UINT32 Index; - UINT32 CompSize; - UINT32 OrigSize; - EFI_STATUS Status; - SCRATCH_DATA *Sd; - const UINT8 *Src; - UINT8 *Dst; - - Status = EFI_SUCCESS; - Src = Source; - Dst = Destination; + UINT32 CompSize; + UINT32 OrigSize; + SCRATCH_DATA *Sd; + CONST UINT8 *Src = Source; + UINT8 *Dst = Destination; + EFI_STATUS Status = EFI_SUCCESS; if (ScratchSize < sizeof(SCRATCH_DATA)) { return EFI_INVALID_PARAMETER; @@ -817,9 +917,7 @@ EFI_INVALID_PARAMETER - The source data is corrupted Src = Src + 8; - for (Index = 0; Index < sizeof(SCRATCH_DATA); Index++) { - ((UINT8 *)Sd)[Index] = 0; - } + SetMem (Sd, sizeof(SCRATCH_DATA), 0); // // The length of the field 'Position Set Code Length Array Size' in Block Header. // For EFI 1.1 de/compression algorithm(Version 1), mPBit = 4 @@ -843,18 +941,21 @@ EFI_INVALID_PARAMETER - The source data is corrupted Sd->mSrcBase = (UINT8*)Src; Sd->mDstBase = Dst; + // + // CompSize and OrigSize are calculated in bytes + // Sd->mCompSize = CompSize; Sd->mOrigSize = OrigSize; // // Fill the first BITBUFSIZ bits // - FillBuf(Sd, BITBUFSIZ); + FillBuf (Sd, BITBUFSIZ); // // Decompress it // - Decode(Sd); + Decode (Sd); if (Sd->mBadTableFlag != 0) { // @@ -866,14 +967,6 @@ EFI_INVALID_PARAMETER - The source data is corrupted return Status; } -EFI_STATUS -EFIAPI -EfiTianoGetInfo( -IN const VOID *Source, -IN UINT32 SrcSize, -OUT UINT32 *DstSize, -OUT UINT32 *ScratchSize -) /*++ Routine Description: @@ -894,25 +987,18 @@ EFI_SUCCESS - The size of destination buffer and the size of scratch b EFI_INVALID_PARAMETER - The source data is corrupted --*/ -{ - return GetInfo( - Source, - SrcSize, - DstSize, - ScratchSize - ); -} - EFI_STATUS EFIAPI -EfiDecompress( -IN const VOID *Source, -IN UINT32 SrcSize, -IN OUT VOID *Destination, -IN UINT32 DstSize, -IN OUT VOID *Scratch, -IN UINT32 ScratchSize -) +EfiTianoGetInfo ( + IN CONST VOID *Source, + IN UINT32 SrcSize, + OUT UINT32 *DstSize, + OUT UINT32 *ScratchSize + ) +{ + return GetInfo (Source, SrcSize, DstSize, ScratchSize); +} + /*++ Routine Description: @@ -935,11 +1021,21 @@ EFI_SUCCESS - Decompression is successful EFI_INVALID_PARAMETER - The source data is corrupted --*/ +EFI_STATUS +EFIAPI +EfiDecompress ( + IN CONST VOID *Source, + IN UINT32 SrcSize, + IN OUT VOID *Destination, + IN UINT32 DstSize, + IN OUT VOID *Scratch, + IN UINT32 ScratchSize + ) { // // For EFI 1.1 de/compression algorithm, the version is 1. // - return Decompress( + return Decompress ( Source, SrcSize, Destination, @@ -950,16 +1046,6 @@ EFI_INVALID_PARAMETER - The source data is corrupted ); } -EFI_STATUS -EFIAPI -TianoDecompress( -IN const VOID *Source, -IN UINT32 SrcSize, -IN OUT VOID *Destination, -IN UINT32 DstSize, -IN OUT VOID *Scratch, -IN UINT32 ScratchSize -) /*++ Routine Description: @@ -982,11 +1068,21 @@ EFI_SUCCESS - Decompression is successful EFI_INVALID_PARAMETER - The source data is corrupted --*/ +EFI_STATUS +EFIAPI +TianoDecompress ( + IN CONST VOID *Source, + IN UINT32 SrcSize, + IN OUT VOID *Destination, + IN UINT32 DstSize, + IN OUT VOID *Scratch, + IN UINT32 ScratchSize + ) { // // For Tiano de/compression algorithm, the version is 2. // - return Decompress( + return Decompress ( Source, SrcSize, Destination, diff --git a/common/Tiano/EfiTianoDecompress.h b/common/Tiano/EfiTianoDecompress.h index f6efd6e..d2f747e 100644 --- a/common/Tiano/EfiTianoDecompress.h +++ b/common/Tiano/EfiTianoDecompress.h @@ -37,14 +37,6 @@ typedef struct EFI_TIANO_HEADER_ { UINT32 OrigSize; } EFI_TIANO_HEADER; -EFI_STATUS -EFIAPI -EfiTianoGetInfo( - const VOID *Source, - UINT32 SrcSize, - UINT32 *DstSize, - UINT32 *ScratchSize - ) /*++ Routine Description: @@ -64,18 +56,16 @@ EFI_SUCCESS - The size of destination buffer and the size of scratch b EFI_INVALID_PARAMETER - The source data is corrupted --*/ -; - EFI_STATUS EFIAPI -EfiDecompress( - const VOID *Source, - UINT32 SrcSize, - VOID *Destination, - UINT32 DstSize, - VOID *Scratch, - UINT32 ScratchSize - ); +EfiTianoGetInfo ( + IN CONST VOID *Source, + IN UINT32 SrcSize, + OUT UINT32 *DstSize, + OUT UINT32 *ScratchSize + ); + + /*++ Routine Description: @@ -97,18 +87,17 @@ EFI_SUCCESS - Decompression is successful EFI_INVALID_PARAMETER - The source data is corrupted --*/ -; - EFI_STATUS EFIAPI -TianoDecompress( - const VOID *Source, - UINT32 SrcSize, - VOID *Destination, - UINT32 DstSize, - VOID *Scratch, - UINT32 ScratchSize - ) +EfiDecompress( + IN CONST VOID *Source, + IN UINT32 SrcSize, + IN OUT VOID *Destination, + IN UINT32 DstSize, + IN OUT VOID *Scratch, + IN UINT32 ScratchSize +); + /*++ Routine Description: @@ -130,7 +119,16 @@ EFI_SUCCESS - Decompression is successful EFI_INVALID_PARAMETER - The source data is corrupted --*/ -; +EFI_STATUS +EFIAPI +TianoDecompress( + IN CONST VOID *Source, + IN UINT32 SrcSize, + IN OUT VOID *Destination, + IN UINT32 DstSize, + IN OUT VOID *Scratch, + IN UINT32 ScratchSize + ); #ifdef __cplusplus } diff --git a/common/basetypes.h b/common/basetypes.h index b4d4bc1..89c94f9 100644 --- a/common/basetypes.h +++ b/common/basetypes.h @@ -16,8 +16,10 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include #include +#include -typedef uint8_t USTATUS; +// TODO: improve +typedef size_t USTATUS; #define U_SUCCESS 0 #define U_INVALID_PARAMETER 1 #define U_BUFFER_TOO_SMALL 2 @@ -44,39 +46,69 @@ typedef uint8_t USTATUS; #define U_CUSTOMIZED_COMPRESSION_FAILED 23 #define U_STANDARD_DECOMPRESSION_FAILED 24 #define U_CUSTOMIZED_DECOMPRESSION_FAILED 25 -#define U_UNKNOWN_COMPRESSION_TYPE 26 -#define U_DEPEX_PARSE_FAILED 27 -#define U_UNKNOWN_EXTRACT_MODE 28 -#define U_UNKNOWN_REPLACE_MODE 29 -#define U_UNKNOWN_IMAGE_TYPE 30 -#define U_UNKNOWN_PE_OPTIONAL_HEADER_TYPE 31 -#define U_UNKNOWN_RELOCATION_TYPE 32 -#define U_DIR_ALREADY_EXIST 33 -#define U_DIR_CREATE 34 -#define U_DIR_CHANGE 35 -#define U_TRUNCATED_IMAGE 36 -#define U_INVALID_CAPSULE 37 -#define U_STORES_NOT_FOUND 38 -#define U_NOT_IMPLEMENTED 0xFF +#define U_GZIP_DECOMPRESSION_FAILED 26 +#define U_UNKNOWN_COMPRESSION_TYPE 27 +#define U_DEPEX_PARSE_FAILED 28 +#define U_UNKNOWN_EXTRACT_MODE 29 +#define U_UNKNOWN_REPLACE_MODE 30 +#define U_UNKNOWN_IMAGE_TYPE 31 +#define U_UNKNOWN_PE_OPTIONAL_HEADER_TYPE 32 +#define U_UNKNOWN_RELOCATION_TYPE 33 +#define U_DIR_ALREADY_EXIST 34 +#define U_DIR_CREATE 35 +#define U_DIR_CHANGE 36 +#define U_TRUNCATED_IMAGE 37 +#define U_INVALID_CAPSULE 38 +#define U_STORES_NOT_FOUND 39 +#define U_INVALID_IMAGE 40 +#define U_INVALID_RAW_AREA 41 +#define U_INVALID_FIT 42 +#define U_INVALID_MICROCODE 43 +#define U_INVALID_ACM 44 +#define U_INVALID_BOOT_GUARD_KEY_MANIFEST 45 +#define U_INVALID_BOOT_GUARD_BOOT_POLICY 46 +#define U_INVALID_TXT_CONF 47 +#define U_ELEMENTS_NOT_FOUND 48 +#define U_PEI_CORE_ENTRY_POINT_NOT_FOUND 49 +#define U_INVALID_STORE_SIZE 50 +#define U_UNKNOWN_COMPRESSION_ALGORITHM 51 +#define U_NOTHING_TO_PATCH 52 +#define U_UNKNOWN_PATCH_TYPE 53 +#define U_PATCH_OFFSET_OUT_OF_BOUNDS 54 +#define U_INVALID_SYMBOL 55 +#define U_ZLIB_DECOMPRESSION_FAILED 56 +#define U_INVALID_STORE 57 -// UDK porting definitions -typedef uint8_t BOOLEAN; -typedef int8_t INT8; -typedef uint8_t UINT8; -typedef int16_t INT16; -typedef uint16_t UINT16; -typedef int32_t INT32; -typedef uint32_t UINT32; -typedef int64_t INT64; -typedef uint64_t UINT64; -typedef char CHAR8; -typedef uint16_t CHAR16; -typedef unsigned int UINTN; +#define U_INVALID_MANIFEST 251 +#define U_UNKNOWN_MANIFEST_HEADER_VERSION 252 +#define U_INVALID_ME_PARTITION_TABLE 253 +#define U_INVALID_ME_PARTITION 254 + +#define U_NOT_IMPLEMENTED 255 + +// EDK2 porting definitions +typedef uint8_t BOOLEAN; +typedef int8_t INT8; +typedef uint8_t UINT8; +typedef int16_t INT16; +typedef uint16_t UINT16; +typedef int32_t INT32; +typedef uint32_t UINT32; +typedef int64_t INT64; +typedef uint64_t UINT64; +typedef char CHAR8; +typedef uint16_t CHAR16; +typedef size_t UINTN; +typedef ptrdiff_t INTN; #define CONST const #define VOID void #define STATIC static +#ifndef INT32_MAX +#define INT32_MAX 0x7fffffff +#endif + #ifndef TRUE #define TRUE ((BOOLEAN)(1==1)) #endif @@ -96,13 +128,16 @@ typedef unsigned int UINTN; #define EFI_ERROR(X) (X) // Compression algorithms -#define COMPRESSION_ALGORITHM_UNKNOWN 0 -#define COMPRESSION_ALGORITHM_NONE 1 -#define COMPRESSION_ALGORITHM_EFI11 2 -#define COMPRESSION_ALGORITHM_TIANO 3 -#define COMPRESSION_ALGORITHM_UNDECIDED 4 -#define COMPRESSION_ALGORITHM_LZMA 5 -#define COMPRESSION_ALGORITHM_IMLZMA 6 +#define COMPRESSION_ALGORITHM_UNKNOWN 0 +#define COMPRESSION_ALGORITHM_NONE 1 +#define COMPRESSION_ALGORITHM_EFI11 2 +#define COMPRESSION_ALGORITHM_TIANO 3 +#define COMPRESSION_ALGORITHM_UNDECIDED 4 +#define COMPRESSION_ALGORITHM_LZMA 5 +#define COMPRESSION_ALGORITHM_LZMA_INTEL_LEGACY 6 +#define COMPRESSION_ALGORITHM_LZMAF86 7 +#define COMPRESSION_ALGORITHM_GZIP 8 +#define COMPRESSION_ALGORITHM_ZLIB 9 // Item create modes #define CREATE_MODE_APPEND 0 @@ -139,7 +174,10 @@ typedef unsigned int UINTN; // EFI GUID typedef struct EFI_GUID_ { - UINT8 Data[16]; + UINT32 Data1; + UINT16 Data2; + UINT16 Data3; + UINT8 Data4[8]; } EFI_GUID; // EFI Time @@ -150,20 +188,42 @@ typedef struct EFI_TIME_ { UINT8 Hour; // Hour: 0 - 23 UINT8 Minute; // Minute: 0 - 59 UINT8 Second; // Second: 0 - 59 - UINT8 : 8; + UINT8 Reserved0; UINT32 Nanosecond; // Nanosecond: 0 - 999,999,999 INT16 TimeZone; // TimeZone: -1440 to 1440 or UNSPECIFIED (0x07FF) - UINT8 Daylight; // Daylight: ADJUST_DAYLIGHT (1) or IN_DAYLIGHT (2) - UINT8 : 8; + UINT8 Daylight; // Daylight: ADJUST_DAYLIGHT (1) or IN_DAYLIGHT (2) + UINT8 Reserved1; } EFI_TIME; +// Align to 4 or 8 bytes #define ALIGN4(Value) (((Value)+3) & ~3) #define ALIGN8(Value) (((Value)+7) & ~7) +// Unused parameter declaration +#define U_UNUSED_PARAMETER(x) ((void)x) + +// Assert macro #include #define ASSERT(x) assert(x) -// SHA256 hash size in bytes +// Hash sizes in bytes +#define SHA1_HASH_SIZE 0x14 #define SHA256_HASH_SIZE 0x20 +#define SHA384_HASH_SIZE 0x30 +#define SHA512_HASH_SIZE 0x40 +#define SM3_HASH_SIZE 0x20 + +// TCG Algorithm Registry: Table 2 +#define TCG_HASH_ALGORITHM_ID_SHA1 0x0004 +#define TCG_HASH_ALGORITHM_ID_SHA256 0x000B +#define TCG_HASH_ALGORITHM_ID_SHA384 0x000C +#define TCG_HASH_ALGORITHM_ID_SHA512 0x000D +#define TCG_HASH_ALGORITHM_ID_NULL 0x0010 +#define TCG_HASH_ALGORITHM_ID_SM3 0x0012 + +// A workaround for compilers not supporting c++11 and c11 +// for using PRIX64. +#define __STDC_FORMAT_MACROS +#include #endif // BASETYPES_H diff --git a/bstrlib/LICENSE b/common/bstrlib/LICENSE similarity index 100% rename from bstrlib/LICENSE rename to common/bstrlib/LICENSE diff --git a/bstrlib/bstrlib.c b/common/bstrlib/bstrlib.c similarity index 98% rename from bstrlib/bstrlib.c rename to common/bstrlib/bstrlib.c index aa2c000..bc6d207 100644 --- a/bstrlib/bstrlib.c +++ b/common/bstrlib/bstrlib.c @@ -102,7 +102,7 @@ static int snapUpSize (int i) { /* int balloc (bstring b, int len) * - * Increase the size of the memory backing the bstring b to at least len. + * Increase the size of the memory backing the bstring b to at least olen + 1. */ int balloc (bstring b, int olen) { int len; @@ -124,14 +124,14 @@ int balloc (bstring b, int olen) { reallocStrategy:; - x = (unsigned char *) bstr__realloc (b->data, (size_t) len); + x = (unsigned char *) bstr__realloc (b->data, (size_t) len + 1); if (x == NULL) { /* Since we failed, try allocating the tighest possible allocation */ len = olen; - x = (unsigned char *) bstr__realloc (b->data, (size_t) olen); + x = (unsigned char *) bstr__realloc (b->data, (size_t) len + 1); if (NULL == x) { return BSTR_ERR; } @@ -142,7 +142,7 @@ int balloc (bstring b, int olen) { the extra bytes that are allocated, but not considered part of the string */ - if (NULL == (x = (unsigned char *) bstr__alloc ((size_t) len))) { + if (NULL == (x = (unsigned char *) bstr__alloc ((size_t) len + 1))) { /* Perhaps there is no available memory for the two allocations to be in memory at once */ @@ -317,7 +317,7 @@ char * r; if (b == NULL || b->slen < 0 || b->data == NULL) return NULL; l = b->slen; - r = (char *) bstr__alloc ((size_t) (l + 1)); + r = (char *) bstr__alloc ((size_t)l + 1); if (r == NULL) return r; for (i=0; i < l; i ++) { @@ -557,7 +557,7 @@ size_t len; a->slen = i; len = strlen (str + i); - if (len + 1 > INT_MAX - i || + if (len + 1 > (size_t) INT_MAX - i || 0 > balloc (a, (int) (i + len + 1))) return BSTR_ERR; bBlockCopy (a->data + i, str + i, (size_t) len + 1); a->slen += (int) len; @@ -739,24 +739,8 @@ int i; * termination characters are not treated in any special way. */ int biseqcaseless (const_bstring b0, const_bstring b1) { -#if 0 -int i, n; - - if (bdata (b0) == NULL || b0->slen < 0 || - bdata (b1) == NULL || b1->slen < 0) return BSTR_ERR; - if (b0->slen != b1->slen) return BSTR_OK; - if (b0->data == b1->data || b0->slen == 0) return 1; - for (i=0, n=b0->slen; i < n; i++) { - if (b0->data[i] != b1->data[i]) { - unsigned char c = (unsigned char) downcase (b0->data[i]); - if (c != (unsigned char) downcase (b1->data[i])) return 0; - } - } - return 1; -#else if (NULL == b1) return BSTR_ERR; return biseqcaselessblk (b0, b1->data, b1->slen); -#endif } /* int bisstemeqcaselessblk (const_bstring b0, const void * blk, int len) @@ -2414,8 +2398,14 @@ int i, c, v; } else { v = (bl->qty - 1) * len; if ((bl->qty > 512 || len > 127) && - v / len != bl->qty - 1) return NULL; /* Overflow */ - if (v > INT_MAX - c) return NULL; /* Overflow */ + v / len != bl->qty - 1) { + bstr__free (b); + return NULL; /* Overflow */ + } + if (v > INT_MAX - c) { + bstr__free (b); + return NULL; /* Overflow */ + } c += v; p = b->data = (unsigned char *) bstr__alloc (c); if (p == NULL) { @@ -2448,7 +2438,7 @@ int i, c, v; * NULL is returned, otherwise a bstring with the correct result is returned. */ bstring bjoin (const struct bstrList * bl, const_bstring sep) { - if (sep != NULL && (sep->slen < 0 || sep->data == NULL)) return NULL; + if (sep == NULL || (sep->slen < 0 || sep->data == NULL)) return NULL; return bjoinblk (bl, sep->data, sep->slen); } @@ -2474,9 +2464,9 @@ bstring bjoin (const struct bstrList * bl, const_bstring sep) { */ int bssplitscb (struct bStream * s, const_bstring splitStr, int (* cb) (void * parm, int ofs, const_bstring entry), void * parm) { -struct charField chrs; -bstring buff; -int i, p, ret; + struct charField chrs; + bstring buff; + int i = 0, p = 0, ret = 0; if (cb == NULL || s == NULL || s->readFnPtr == NULL || splitStr == NULL || splitStr->slen < 0) return BSTR_ERR; @@ -2489,7 +2479,6 @@ int i, p, ret; ret = 0; } else { buildCharField (&chrs, splitStr); - ret = p = i = 0; for (;;) { if (i >= buff->slen) { bsreada (buff, s, BSSSC_BUFF_LEN); @@ -2541,8 +2530,8 @@ int i, p, ret; */ int bssplitstrcb (struct bStream * s, const_bstring splitStr, int (* cb) (void * parm, int ofs, const_bstring entry), void * parm) { -bstring buff; -int i, p, ret; + bstring buff; + int i = 0, p = 0, ret = 0; if (cb == NULL || s == NULL || s->readFnPtr == NULL || splitStr == NULL || splitStr->slen < 0) return BSTR_ERR; @@ -2559,10 +2548,10 @@ int i, p, ret; } buff->slen = 0; } + bdestroy (buff); return BSTR_OK; } else { - ret = p = i = 0; - for (i=p=0;;) { + for (;;) { if ((ret = binstr (buff, 0, splitStr)) >= 0) { struct tagbstring t; blk2tbstr (t, buff->data, ret); diff --git a/bstrlib/bstrlib.h b/common/bstrlib/bstrlib.h similarity index 96% rename from bstrlib/bstrlib.h rename to common/bstrlib/bstrlib.h index fd0874c..81b6a82 100644 --- a/bstrlib/bstrlib.h +++ b/common/bstrlib/bstrlib.h @@ -29,6 +29,12 @@ extern "C" { # endif #endif +#if defined(__clang__) || defined(__GNUC__) +#define ATTRIBUTE_FORMAT_(t,f,a) __attribute__((format(t, f, a))) +#else +#define ATTRIBUTE_FORMAT_(t,f,a) +#endif + #define BSTR_ERR (-1) #define BSTR_OK (0) #define BSTR_BS_BUFF_LENGTH_GET (0) @@ -36,6 +42,11 @@ extern "C" { typedef struct tagbstring * bstring; typedef const struct tagbstring * const_bstring; +/* Version */ +#define BSTR_VER_MAJOR 1 +#define BSTR_VER_MINOR 0 +#define BSTR_VER_UPDATE 0 + /* Copy functions */ #define cstr2bstr bfromcstr extern bstring bfromcstr (const char * str); @@ -133,9 +144,9 @@ extern int brtrimws (bstring b); extern int btrimws (bstring b); #if !defined (BSTRLIB_NOVSNP) -extern bstring bformat (const char * fmt, ...); -extern int bformata (bstring b, const char * fmt, ...); -extern int bassignformat (bstring b, const char * fmt, ...); +extern bstring bformat (const char * fmt, ...) ATTRIBUTE_FORMAT_(printf, 1, 2); +extern int bformata (bstring b, const char * fmt, ...) ATTRIBUTE_FORMAT_(printf, 2, 3); +extern int bassignformat (bstring b, const char * fmt, ...) ATTRIBUTE_FORMAT_(printf, 2, 3); extern int bvcformata (bstring b, int count, const char * fmt, va_list arglist); #define bvformata(ret, b, fmt, lastarg) { \ diff --git a/bstrlib/bstrwrap.cpp b/common/bstrlib/bstrwrap.cpp similarity index 99% rename from bstrlib/bstrwrap.cpp rename to common/bstrlib/bstrwrap.cpp index 2ec38c1..3f25514 100644 --- a/bstrlib/bstrwrap.cpp +++ b/common/bstrlib/bstrwrap.cpp @@ -697,9 +697,9 @@ int CBString::find (const CBString& b, int pos) const { int CBString::find (const char * b, int pos) const { int ii, j; unsigned char c0; -register int i, l; -register unsigned char cx; -register unsigned char * pdata; +int i, l; +unsigned char cx; +unsigned char * pdata; if (NULL == b) { #ifdef BSTRLIB_THROWS_EXCEPTIONS @@ -1490,9 +1490,8 @@ int p, i; } static int streamSplitCb (void * parm, int ofs, const_bstring entry) { -CBStringList * r = (CBStringList *) parm; - - ofs = ofs; + CBStringList * r = (CBStringList *) parm; + (void)ofs; r->push_back (CBString (*entry)); return 0; } @@ -1540,7 +1539,7 @@ std::istream& operator >> (std::istream& sin, CBString& b) { do { b.gets ((bNgetc) istreamGets, &sin, '\n'); if (b.slen > 0 && b.data[b.slen-1] == '\n') b.slen--; - } while (b.slen == 0 && !sin.eof ()); + } while (b.slen == 0 && !sin.eof() && !sin.fail()); return sin; } diff --git a/bstrlib/bstrwrap.h b/common/bstrlib/bstrwrap.h similarity index 93% rename from bstrlib/bstrwrap.h rename to common/bstrlib/bstrwrap.h index 88e0f14..5532bee 100644 --- a/bstrlib/bstrwrap.h +++ b/common/bstrlib/bstrwrap.h @@ -51,7 +51,7 @@ #include #include "bstrlib.h" -#include "../common/ubytearray.h" +#include "../ubytearray.h" #ifdef __cplusplus @@ -331,8 +331,8 @@ struct CBString : public tagbstring { void trunc (int len); // Miscellaneous methods. - void format (const char * fmt, ...); - void formata (const char * fmt, ...); + void format (const char * fmt, ...) ATTRIBUTE_FORMAT_(printf, 2, 3); + void formata (const char * fmt, ...) ATTRIBUTE_FORMAT_(printf, 2, 3); void fill (int length, unsigned char fill = ' '); void repeat (int count); void ltrim (const CBString& b = CBString (bsStaticBlkParms (" \t\v\f\r\n"))); @@ -361,16 +361,18 @@ struct CBString : public tagbstring { int gets (bNgetc getcPtr, void * parm, char terminator = '\n'); int read (bNread readPtr, void * parm); - // QString compatibility methods - CBString toLocal8Bit() const { return *this; } - bool isEmpty() const { return slen == 0; } - void clear() { *this = ""; } - CBString left(int len) const { return midstr(0, len); } - CBString mid(int pos, int len) const { return midstr(pos, len); } - static CBString fromUtf16(const unsigned short* str) { // Naive implementation assuming that only ASCII part of UCS2 is used - CBString msg; while (*str) { msg += *(char*)str; str++; } return msg; - } - CBString leftJustified(int length) { if (length > slen) { return *this + CBString(' ', length - slen); } return *this; } + // QString compatibility methods + const char *toLocal8Bit() const { return *this; } + bool contains(const char *str) { return find(str) >= 0; } + bool startsWith(const char *str) { return find(str) == 0; } + bool endsWith(const char *str) { int len = strlen(str); return (slen >= len && (find(str, slen - len) == (slen - len))); } + bool isEmpty() const { return slen == 0; } + void clear() { *this = ""; } + CBString left(int len) const { return midstr(0, len); } + CBString mid(int pos, int len) const { return midstr(pos, len); } + CBString chopped(int len) const { return midstr(slen - len, len); } + void chop(int len) { trunc(((slen > len) ? slen - len : 0)); } + CBString leftJustified(int length) { if (length > slen) { return *this + CBString(' ', length - slen); } return *this; } }; extern const CBString operator + (const char *a, const CBString& b); extern const CBString operator + (const unsigned char *a, const CBString& b); diff --git a/common/descriptor.cpp b/common/descriptor.cpp index 5082875..324b005 100644 --- a/common/descriptor.cpp +++ b/common/descriptor.cpp @@ -1,14 +1,14 @@ /* descriptor.cpp -Copyright (c) 2015, Nikolaj Schlej. All rights reserved. -This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php + Copyright (c) 2015, Nikolaj Schlej. All rights reserved. + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -*/ + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + */ #include "descriptor.h" @@ -37,4 +37,217 @@ UINT32 calculateRegionSize(const UINT16 base, const UINT16 limit) if (limit) return (limit + 1 - base) * 0x1000; return 0; -} \ No newline at end of file +} + +// Return human-readable chip name for given JEDEC ID +UString jedecIdToUString(UINT8 vendorId, UINT8 deviceId0, UINT8 deviceId1) +{ + UINT32 jedecId = (UINT32)deviceId1 + ((UINT32)deviceId0 << 8) + ((UINT32)vendorId << 16); + switch (jedecId) { + // Winbond + case 0xEF3010: return UString("Winbond W25X05"); + case 0xEF3011: return UString("Winbond W25X10"); + case 0xEF3012: return UString("Winbond W25X20"); + case 0xEF3013: return UString("Winbond W25X40"); + case 0xEF3014: return UString("Winbond W25X80"); + case 0xEF3015: return UString("Winbond W25X16"); + case 0xEF3016: return UString("Winbond W25X32"); + case 0xEF3017: return UString("Winbond W25X64"); + case 0xEF4012: return UString("Winbond W25Q20"); + case 0xEF4013: return UString("Winbond W25Q40"); + case 0xEF4014: return UString("Winbond W25Q80"); + case 0xEF4015: return UString("Winbond W25Q16"); + case 0xEF4016: return UString("Winbond W25Q32"); + case 0xEF4017: return UString("Winbond W25Q64"); + case 0xEF4018: return UString("Winbond W25Q128"); + case 0xEF4019: return UString("Winbond W25Q256"); + case 0xEF6011: return UString("Winbond W25Q10"); + case 0xEF6012: return UString("Winbond W25Q20"); + case 0xEF6013: return UString("Winbond W25Q40"); + case 0xEF6014: return UString("Winbond W25Q80"); + case 0xEF6015: return UString("Winbond W25Q16"); + case 0xEF6016: return UString("Winbond W25Q32"); + case 0xEF6017: return UString("Winbond W25Q64"); + case 0xEF6018: return UString("Winbond W25Q128"); + case 0xEF6019: return UString("Winbond W25Q256"); + case 0xEF7118: return UString("Winbond W25M256"); + case 0xEF7119: return UString("Winbond W25M512"); + + // Macronix + case 0xC22013: return UString("Macronix MX25L40"); + case 0xC22014: return UString("Macronix MX25L80"); + case 0xC22015: return UString("Macronix MX25L16"); + case 0xC22016: return UString("Macronix MX25U16"); + case 0xC22017: return UString("Macronix MX25L64"); + case 0xC22018: return UString("Macronix MX25L128"); + case 0xC22019: return UString("Macronix MX25L256"); + case 0xC2201A: return UString("Macronix MX66L512"); + case 0xC22415: return UString("Macronix MX25L16"); + case 0xC22515: return UString("Macronix MX25L16"); + case 0xC22534: return UString("Macronix MX25U80"); + case 0xC22535: return UString("Macronix MX25U16"); + case 0xC22536: return UString("Macronix MX25U32"); + case 0xC22537: return UString("Macronix MX25U64"); + case 0xC22538: return UString("Macronix MX25U128"); + case 0xC22539: return UString("Macronix MX25U256"); + case 0xC2253A: return UString("Macronix MX25U512"); + case 0xC22617: return UString("Macronix MX25L64"); + case 0xC22618: return UString("Macronix MX25L128"); + case 0xC25E16: return UString("Macronix MX25L32"); + case 0xC27518: return UString("Macronix MX77L12850F"); + case 0xC29517: return UString("Macronix MX25L64"); + + // Micron + case 0x202014: return UString("Micron M25P80"); + case 0x202015: return UString("Micron M25P16"); + case 0x202016: return UString("Micron M25P32"); + case 0x202017: return UString("Micron M25P64"); + case 0x202018: return UString("Micron M25P128"); + case 0x204011: return UString("Micron M45PE10"); + case 0x204012: return UString("Micron M45PE20"); + case 0x204013: return UString("Micron M45PE40"); + case 0x204014: return UString("Micron M45PE80"); + case 0x204015: return UString("Micron M45PE16"); + case 0x204017: return UString("Micron XM25QH64C"); + case 0x204018: return UString("Micron XM25QH128C"); + case 0x204019: return UString("Micron XM25QH256C"); + case 0x204318: return UString("Micron XM25RH128C"); + case 0x207114: return UString("Micron M25PX80"); + case 0x207115: return UString("Micron M25PX16"); + case 0x207116: return UString("Micron M25PX32"); + case 0x207117: return UString("Micron M25PX64"); + case 0x208011: return UString("Micron M25PE10"); + case 0x208012: return UString("Micron M25PE20"); + case 0x208013: return UString("Micron M25PE40"); + case 0x208014: return UString("Micron M25PE80"); + case 0x208015: return UString("Micron M25PE16"); + case 0x20BA15: return UString("Micron N25Q016"); + case 0x20BA16: return UString("Micron N25Q032"); + case 0x20BA17: return UString("Micron N25Q064"); + case 0x20BA18: return UString("Micron N25Q128"); + case 0x20BA19: return UString("Micron N25Q256"); + case 0x20BA20: return UString("Micron N25Q512"); + case 0x20BA21: return UString("Micron N25Q00A"); + case 0x20BB15: return UString("Micron N25Q016"); + case 0x20BB16: return UString("Micron N25Q032"); + case 0x20BB17: return UString("Micron N25Q064"); + case 0x20BB18: return UString("Micron MT25Q128"); + case 0x20BB19: return UString("Micron MT25Q256"); + case 0x20BB20: return UString("Micron MT25Q512"); + + // Intel + case 0x898911: return UString("Intel 25F160S33B8"); + case 0x898912: return UString("Intel 25F320S33B8"); + case 0x898913: return UString("Intel 25F640S33B8"); + case 0x898915: return UString("Intel 25F160S33T8"); + case 0x898916: return UString("Intel 25F320S33T8"); + case 0x898917: return UString("Intel 25F640S33T8"); + + // Atmel / Adesto + case 0x1F3217: return UString("Atmel AT25SF641"); + case 0x1F4216: return UString("Atmel AT25SL321"); + case 0x1F4218: return UString("Atmel AT25SL128A"); + case 0x1F4317: return UString("Atmel AT25SL641"); + case 0x1F4500: return UString("Atmel AT26DF081"); + case 0x1F4501: return UString("Atmel AT26DF081A"); + case 0x1F4502: return UString("Atmel AT25DF081"); + case 0x1F4600: return UString("Atmel AT26DF161"); + case 0x1F4601: return UString("Atmel AT26DF161A"); + case 0x1F4602: return UString("Atmel AT25DF161"); + case 0x1F4700: return UString("Atmel AT25DF321"); + case 0x1F4701: return UString("Atmel AT25DF321A"); + case 0x1F4800: return UString("Atmel AT25DF641"); + case 0x1F7018: return UString("Atmel AT25QF128"); + case 0x1F8600: return UString("Atmel AT25DQ161"); + case 0x1F8800: return UString("Atmel AT25DQ641"); + + // Microchip + case 0xBF2541: return UString("Microchip SST25VF016B"); + case 0xBF254A: return UString("Microchip SST25VF032B"); + case 0xBF258D: return UString("Microchip SST25VF040B"); + case 0xBF258E: return UString("Microchip SST25VF080B"); + case 0xBF254B: return UString("Microchip SST25VF064C"); + + // EON / ESMT + case 0x1C3013: return UString("EON EN25Q40"); + case 0x1C3014: return UString("EON EN25Q80"); + case 0x1C3015: return UString("EON EN25Q16"); + case 0x1C3016: return UString("EON EN25Q32"); + case 0x1C3017: return UString("EON EN25Q64"); + case 0x1C3018: return UString("EON EN25Q128"); + case 0x1C3114: return UString("EON EN25F80"); + case 0x1C3115: return UString("EON EN25F16"); + case 0x1C3116: return UString("EON EN25F32"); + case 0x1C3117: return UString("EON EN25F64"); + case 0x1C3811: return UString("EON EN25S10"); + case 0x1C3812: return UString("EON EN25S20"); + case 0x1C3813: return UString("EON EN25S40"); + case 0x1C3814: return UString("EON EN25S80"); + case 0x1C3815: return UString("EON EN25S16"); + case 0x1C3816: return UString("EON EN25S32"); + case 0x1C3817: return UString("EON EN25S64"); + case 0x1C7014: return UString("EON EN25QH80"); + case 0x1C7015: return UString("EON EN25QH16"); + case 0x1C7016: return UString("EON EN25QH32"); + case 0x1C7017: return UString("EON EN25QH64"); + case 0x1C7018: return UString("EON EN25QH128"); + case 0x1C7019: return UString("EON EN25QH256"); + + // GigaDevice + case 0xC84014: return UString("GigaDevice GD25x80"); + case 0xC84015: return UString("GigaDevice GD25x16"); + case 0xC84016: return UString("GigaDevice GD25x32"); + case 0xC84017: return UString("GigaDevice GD25x64"); + case 0xC84018: return UString("GigaDevice GD25x128"); + case 0xC84019: return UString("GigaDevice GD25x256C"); + case 0xC86015: return UString("GigaDevice GD25LQ16V"); + case 0xC86017: return UString("GigaDevice GD25Lx64"); + case 0xC86018: return UString("GigaDevice GD25Lx128"); + case 0xC86019: return UString("GigaDevice GD25LQ256C"); + + // Fidelix + case 0xF83215: return UString("Fidelix FM25Q16"); + case 0xF83216: return UString("Fidelix FM25Q32"); + case 0xF83217: return UString("Fidelix FM25Q64"); + case 0xF83218: return UString("Fidelix FM25Q128"); + + // Spansion + case 0x014015: return UString("Spansion S25FL116K"); + case 0x014016: return UString("Spansion S25FL132K"); + case 0x014017: return UString("Spansion S25FL164K"); + + // AMIC Technology + case 0x373015: return UString("AMIC A25L016"); + case 0x373016: return UString("AMIC A25L032"); + case 0x374015: return UString("AMIC A25LQ16"); + case 0x374016: return UString("AMIC A25LQ32A"); + case 0x374017: return UString("AMIC A25LQ64"); + + // PMC + case 0x9DF713: return UString("PMC Pm25LV080B"); + case 0x9DF714: return UString("PMC Pm25LV016B"); + case 0x9DF744: return UString("PMC Pm25LQ080C"); + case 0x9DF745: return UString("PMC Pm25LQ016C"); + case 0x9DF746: return UString("PMC Pm25LQ032C"); + case 0x9DF77B: return UString("PMC Pm25LV512A"); + case 0x9DF77C: return UString("PMC Pm25LV010A"); + case 0x9DF77D: return UString("PMC Pm25LV020"); + case 0x9DF77E: return UString("PMC Pm25LV040"); + + // ISSI + case 0x9D6014: return UString("ISSI Ix25LP080"); + case 0x9D6015: return UString("ISSI Ix25LP016"); + case 0x9D6016: return UString("ISSI Ix25LP032"); + case 0x9D6017: return UString("ISSI Ix25LP064"); + case 0x9D6018: return UString("ISSI Ix25LP128"); + case 0x9D6019: return UString("ISSI Ix25LP256"); + case 0x9D7014: return UString("ISSI Ix25WP080"); + case 0x9D7015: return UString("ISSI Ix25WP016"); + case 0x9D7016: return UString("ISSI Ix25WP032"); + case 0x9D7017: return UString("ISSI Ix25WP064"); + case 0x9D7018: return UString("ISSI Ix25WP128"); + case 0x9D7019: return UString("ISSI Ix25WP256"); + } + + return usprintf("Unknown %08Xh", jedecId); +} diff --git a/common/descriptor.h b/common/descriptor.h index fa77101..0254ce4 100644 --- a/common/descriptor.h +++ b/common/descriptor.h @@ -14,6 +14,8 @@ WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #define DESCRIPTOR_H #include "basetypes.h" +#include "ustring.h" +#include "ubytearray.h" // Make sure we use right packing rules #pragma pack(push,1) @@ -33,6 +35,19 @@ typedef struct FLASH_DESCRIPTOR_HEADER_ { // Maximum base value in descriptor map #define FLASH_DESCRIPTOR_MAX_BASE 0xE0 +// Descriptor version was reserved in older firmware +#define FLASH_DESCRIPTOR_VERSION_INVALID 0xFFFFFFFF +// The only known version found in Coffee Lake +#define FLASH_DESCRIPTOR_VERSION_MAJOR 1 +#define FLASH_DESCRIPTOR_VERSION_MINOR 0 + +// Descriptor version present in Coffee Lake and newer +typedef struct _FLASH_DESCRIPTOR_VERSION { + UINT32 Reserved : 14; + UINT32 Minor : 7; + UINT32 Major : 11; +} FLASH_DESCRIPTOR_VERSION; + // Descriptor map // Base fields are storing bits [11:4] of actual base addresses, all other bits are 0 typedef struct FLASH_DESCRIPTOR_MAP_ { @@ -53,45 +68,22 @@ typedef struct FLASH_DESCRIPTOR_MAP_ { UINT32 ProcStrapsBase : 8; UINT32 NumberOfProcStraps : 8; // One-based number of UINT32s to read as processor straps, min=0, max=255 (1 Kb) UINT32 : 16; + // FLMAP 3 + UINT32 DescriptorVersion; // Reserved prior to Coffee Lake } FLASH_DESCRIPTOR_MAP; -// Component section +// Component section structure // Flash parameters DWORD structure typedef struct FLASH_PARAMETERS_ { - UINT8 FirstChipDensity : 4; - UINT8 SecondChipDensity : 4; + UINT16 : 16; + UINT8 : 1; + UINT8 ReadClockFrequency : 3; // Hardcoded value of 20 Mhz (000b) in v1 descriptors + UINT8 : 4; UINT8 : 8; - UINT8 : 1; - UINT8 ReadClockFrequency : 3; // Hardcoded value of 20 Mhz (000b) in v1 descriptors and 17 Mhz (110b) in v2 ones - UINT8 FastReadEnabled : 1; - UINT8 FastReadFrequency : 3; - UINT8 FlashWriteFrequency : 3; - UINT8 FlashReadStatusFrequency : 3; - UINT8 DualOutputFastReadSupported : 1; - UINT8 : 1; } FLASH_PARAMETERS; -// Flash densities -#define FLASH_DENSITY_512KB 0x00 -#define FLASH_DENSITY_1MB 0x01 -#define FLASH_DENSITY_2MB 0x02 -#define FLASH_DENSITY_4MB 0x03 -#define FLASH_DENSITY_8MB 0x04 -#define FLASH_DENSITY_16MB 0x05 -#define FLASH_DENSITY_32MB 0x06 -#define FLASH_DENSITY_64MB 0x07 -#define FLASH_DENSITY_UNUSED 0x0F - -// Flash frequencies -#define FLASH_FREQUENCY_20MHZ 0x00 -#define FLASH_FREQUENCY_33MHZ 0x01 -#define FLASH_FREQUENCY_48MHZ 0x02 -#define FLASH_FREQUENCY_50MHZ_30MHZ 0x04 -#define FLASH_FREQUENCY_17MHZ 0x06 - -// Component section structure typedef struct FLASH_DESCRIPTOR_COMPONENT_SECTION_ { - FLASH_PARAMETERS FlashParameters; + FLASH_PARAMETERS FlashParameters; // Bit field with SPI flash parameters, changes almost every CPU generation, so will remain mostly undefined for now UINT8 InvalidInstruction0; // Instructions for SPI chip, that must not be executed, like FLASH ERASE UINT8 InvalidInstruction1; // UINT8 InvalidInstruction2; // @@ -105,25 +97,37 @@ typedef struct FLASH_DESCRIPTOR_COMPONENT_SECTION_ { // If limit is zero - region is not present typedef struct FLASH_DESCRIPTOR_REGION_SECTION_ { UINT16 DescriptorBase; // Descriptor - UINT16 DescriptorLimit; // + UINT16 DescriptorLimit; // UINT16 BiosBase; // BIOS UINT16 BiosLimit; // - UINT16 MeBase; // ME + UINT16 MeBase; // Management Engine UINT16 MeLimit; // - UINT16 GbeBase; // GbE + UINT16 GbeBase; // Gigabit Ethernet UINT16 GbeLimit; // - UINT16 PdrBase; // PDR + UINT16 PdrBase; // Platform Data UINT16 PdrLimit; // - UINT16 Reserved1Base; // Reserved1 - UINT16 Reserved1Limit; // - UINT16 Reserved2Base; // Reserved2 - UINT16 Reserved2Limit; // - UINT16 Reserved3Base; // Reserved3 - UINT16 Reserved3Limit; // - UINT16 EcBase; // EC + UINT16 DevExp1Base; // Device Expansion 1 + UINT16 DevExp1Limit; // + UINT16 Bios2Base; // Secondary BIOS + UINT16 Bios2Limit; // + UINT16 MicrocodeBase; // CPU microcode + UINT16 MicrocodeLimit; // + UINT16 EcBase; // Embedded Controller UINT16 EcLimit; // - UINT16 Reserved4Base; // Reserved4 - UINT16 Reserved4Limit; // + UINT16 DevExp2Base; // Device Expansion 2 + UINT16 DevExp2Limit; // + UINT16 IeBase; // Innovation Engine + UINT16 IeLimit; // + UINT16 Tgbe1Base; // 10 Gigabit Ethernet 1 + UINT16 Tgbe1Limit; // + UINT16 Tgbe2Base; // 10 Gigabit Ethernet 2 + UINT16 Tgbe2Limit; // + UINT16 Reserved1Base; // Reserved 1 + UINT16 Reserved1Limit; // + UINT16 Reserved2Base; // Reserved 2 + UINT16 Reserved2Limit; // + UINT16 PttBase; // Platform Trust Technology + UINT16 PttLimit; // } FLASH_DESCRIPTOR_REGION_SECTION; // Master section @@ -201,4 +205,7 @@ extern UINT32 calculateRegionOffset(const UINT16 base); // Calculate size of region using it's base and limit extern UINT32 calculateRegionSize(const UINT16 base, const UINT16 limit); +// Return human-readable chip name for given JEDEC ID +extern UString jedecIdToUString(UINT8 vendorId, UINT8 deviceId0, UINT8 deviceId1); + #endif // DESCRIPTOR_H diff --git a/common/digest/sha1.c b/common/digest/sha1.c new file mode 100644 index 0000000..683e2df --- /dev/null +++ b/common/digest/sha1.c @@ -0,0 +1,230 @@ +/* sha1.c + + Copyright (c) 2022, Nikolaj Schlej. All rights reserved. + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + */ + +// +// This implementations are based on LibTomCrypt that was released into +// public domain by Tom St Denis. +// +#include "sha1.h" +#include +#include + +/* ulong64: 64-bit data type */ +#ifdef _MSC_VER + #define CONST64(n) n ## ui64 + typedef unsigned __int64 ulong64; +#else + #define CONST64(n) n ## ULL + typedef uint64_t ulong64; +#endif + +typedef uint32_t ulong32; + +#define LOAD32H(x, y) \ + do { x = ((ulong32)((y)[0] & 255)<<24) | \ + ((ulong32)((y)[1] & 255)<<16) | \ + ((ulong32)((y)[2] & 255)<<8) | \ + ((ulong32)((y)[3] & 255)); } while(0) + +#ifndef MIN +#define MIN(x, y) (((x) < (y)) ? (x) : (y)) +#endif + +#define ROL(x, y) ( (((ulong32)(x)<<(ulong32)((y)&31)) | (((ulong32)(x)&0xFFFFFFFFUL)>>(ulong32)((32-((y)&31))&31))) & 0xFFFFFFFFUL) +#define ROLc(x, y) ( (((ulong32)(x)<<(ulong32)((y)&31)) | (((ulong32)(x)&0xFFFFFFFFUL)>>(ulong32)((32-((y)&31))&31))) & 0xFFFFFFFFUL) + +#define STORE32H(x, y) \ + do { (y)[0] = (unsigned char)(((x)>>24)&255); (y)[1] = (unsigned char)(((x)>>16)&255); \ + (y)[2] = (unsigned char)(((x)>>8)&255); (y)[3] = (unsigned char)((x)&255); } while(0) + +#define STORE64H(x, y) \ +do { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \ + (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \ + (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \ + (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); } while(0) + +#define F0(x,y,z) (z ^ (x & (y ^ z))) +#define F1(x,y,z) (x ^ y ^ z) +#define F2(x,y,z) ((x & y) | (z & (x | y))) +#define F3(x,y,z) (x ^ y ^ z) + +struct sha1_state { + ulong64 length; + ulong32 state[5], curlen; + unsigned char buf[64]; +}; + +static int s_sha1_compress(struct sha1_state *md, const unsigned char *buf) +{ + ulong32 a,b,c,d,e,W[80],i; + ulong32 t; + + /* copy the state into 512-bits into W[0..15] */ + for (i = 0; i < 16; i++) { + LOAD32H(W[i], buf + (4*i)); + } + + /* copy state */ + a = md->state[0]; + b = md->state[1]; + c = md->state[2]; + d = md->state[3]; + e = md->state[4]; + + /* expand it */ + for (i = 16; i < 80; i++) { + W[i] = ROL(W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16], 1); + } + + /* compress */ + /* round one */ + #define FF0(a,b,c,d,e,i) e = (ROLc(a, 5) + F0(b,c,d) + e + W[i] + 0x5a827999UL); b = ROLc(b, 30); + #define FF1(a,b,c,d,e,i) e = (ROLc(a, 5) + F1(b,c,d) + e + W[i] + 0x6ed9eba1UL); b = ROLc(b, 30); + #define FF2(a,b,c,d,e,i) e = (ROLc(a, 5) + F2(b,c,d) + e + W[i] + 0x8f1bbcdcUL); b = ROLc(b, 30); + #define FF3(a,b,c,d,e,i) e = (ROLc(a, 5) + F3(b,c,d) + e + W[i] + 0xca62c1d6UL); b = ROLc(b, 30); + + for (i = 0; i < 20; ) { + FF0(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t; + } + for (; i < 40; ) { + FF1(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t; + } + for (; i < 60; ) { + FF2(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t; + } + for (; i < 80; ) { + FF3(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t; + } + + #undef FF0 + #undef FF1 + #undef FF2 + #undef FF3 + + /* store */ + md->state[0] = md->state[0] + a; + md->state[1] = md->state[1] + b; + md->state[2] = md->state[2] + c; + md->state[3] = md->state[3] + d; + md->state[4] = md->state[4] + e; + + return 0; +} + +static int sha1_init(struct sha1_state * md) +{ + if (md == NULL) return -1; + md->state[0] = 0x67452301UL; + md->state[1] = 0xefcdab89UL; + md->state[2] = 0x98badcfeUL; + md->state[3] = 0x10325476UL; + md->state[4] = 0xc3d2e1f0UL; + md->curlen = 0; + md->length = 0; + return 0; +} + +static int sha1_process(struct sha1_state * md, const unsigned char *in, unsigned long inlen) +{ + unsigned long n; + int err; + if (md == NULL) return -1; + if (in == NULL) return -1; + if (md->curlen > sizeof(md->buf)) { + return -1; + } + if (((md->length + inlen * 8) < md->length) + || ((inlen * 8) < inlen)) { + return -1; + } + while (inlen > 0) { + if (md->curlen == 0 && inlen >= 64) { + if ((err = s_sha1_compress(md, in)) != 0) { + return err; + } + md->length += 64 * 8; + in += 64; + inlen -= 64; + } else { + n = MIN(inlen, (64 - md->curlen)); + memcpy(md->buf + md->curlen, in, (size_t)n); + md->curlen += n; + in += n; + inlen -= n; + if (md->curlen == 64) { + if ((err = s_sha1_compress(md, md->buf)) != 0) { + return err; + } + md->length += 8 * 64; + md->curlen = 0; + } + } + } + return 0; +} + +static int sha1_done(struct sha1_state * md, unsigned char *out) +{ + int i; + + if (md == NULL) return -1; + if (out == NULL) return -1; + + if (md->curlen >= sizeof(md->buf)) { + return -1; + } + + /* increase the length of the message */ + md->length += md->curlen * 8; + + /* append the '1' bit */ + md->buf[md->curlen++] = (unsigned char)0x80; + + /* if the length is currently above 56 bytes we append zeros + * then compress. Then we can fall back to padding zeros and length + * encoding like normal. + */ + if (md->curlen > 56) { + while (md->curlen < 64) { + md->buf[md->curlen++] = (unsigned char)0; + } + s_sha1_compress(md, md->buf); + md->curlen = 0; + } + + /* pad upto 56 bytes of zeroes */ + while (md->curlen < 56) { + md->buf[md->curlen++] = (unsigned char)0; + } + + /* store length */ + STORE64H(md->length, md->buf+56); + s_sha1_compress(md, md->buf); + + /* copy output */ + for (i = 0; i < 5; i++) { + STORE32H(md->state[i], out+(4*i)); + } + + return 0; +} + +void sha1(const void *in, unsigned long inlen, void* out) +{ + struct sha1_state ctx; + sha1_init(&ctx); + sha1_process(&ctx, (const unsigned char*)in, inlen); + sha1_done(&ctx, (unsigned char *)out); +} + + diff --git a/common/digest/sha1.h b/common/digest/sha1.h new file mode 100644 index 0000000..e698090 --- /dev/null +++ b/common/digest/sha1.h @@ -0,0 +1,25 @@ +/* sha1.h + +Copyright (c) 2022, Nikolaj Schlej. All rights reserved. +This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +*/ + +#ifndef SHA1_H +#define SHA1_H +#ifdef __cplusplus +extern "C" { +#endif + +void sha1(const void *in, unsigned long inlen, void* out); + +#ifdef __cplusplus +} +#endif +#endif // SHA2_H diff --git a/common/digest/sha2.h b/common/digest/sha2.h new file mode 100644 index 0000000..59b4c5d --- /dev/null +++ b/common/digest/sha2.h @@ -0,0 +1,27 @@ +/* sha2.h + +Copyright (c) 2017, Nikolaj Schlej. All rights reserved. +This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +*/ + +#ifndef SHA2_H +#define SHA2_H +#ifdef __cplusplus +extern "C" { +#endif + +void sha256(const void *in, unsigned long inlen, void* out); +void sha384(const void *in, unsigned long inlen, void* out); +void sha512(const void *in, unsigned long inlen, void* out); + +#ifdef __cplusplus +} +#endif +#endif // SHA2_H diff --git a/common/digest/sha256.c b/common/digest/sha256.c new file mode 100644 index 0000000..a9b086d --- /dev/null +++ b/common/digest/sha256.c @@ -0,0 +1,279 @@ +/* sha256.c + + Copyright (c) 2017, Nikolaj Schlej. All rights reserved. + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + */ + +// +// This implementations are based on LibTomCrypt that was released into +// public domain by Tom St Denis. +// + +#include "sha2.h" +#include +#include + +/* ulong64: 64-bit data type */ +#ifdef _MSC_VER + #define CONST64(n) n ## ui64 + typedef unsigned __int64 ulong64; +#else + #define CONST64(n) n ## ULL + typedef uint64_t ulong64; +#endif + +typedef uint32_t ulong32; + +#define LOAD32H(x, y) \ + do { x = ((ulong32)((y)[0] & 255)<<24) | \ + ((ulong32)((y)[1] & 255)<<16) | \ + ((ulong32)((y)[2] & 255)<<8) | \ + ((ulong32)((y)[3] & 255)); } while(0) + +#ifndef MIN +#define MIN(x, y) (((x) < (y)) ? (x) : (y)) +#endif + +#define RORc(x, y) ( ((((ulong32)(x)&0xFFFFFFFFUL)>>(ulong32)((y)&31)) | ((ulong32)(x)<<(ulong32)((32-((y)&31))&31))) & 0xFFFFFFFFUL) + +#define STORE32H(x, y) \ + do { (y)[0] = (unsigned char)(((x)>>24)&255); (y)[1] = (unsigned char)(((x)>>16)&255); \ + (y)[2] = (unsigned char)(((x)>>8)&255); (y)[3] = (unsigned char)((x)&255); } while(0) + +#define STORE64H(x, y) \ +do { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \ + (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \ + (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \ + (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); } while(0) + +/* Various logical functions */ +#define Ch(x,y,z) (z ^ (x & (y ^ z))) +#define Maj(x,y,z) (((x | y) & z) | (x & y)) +#define S(x, n) RORc((x),(n)) +#define R(x, n) (((x)&0xFFFFFFFFUL)>>(n)) +#define Sigma0(x) (S(x, 2) ^ S(x, 13) ^ S(x, 22)) +#define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25)) +#define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3)) +#define Gamma1(x) (S(x, 17) ^ S(x, 19) ^ R(x, 10)) + +struct sha256_state { + ulong64 length; + ulong32 state[8], curlen; + unsigned char buf[32*2]; +}; + +/* compress 512-bits */ +static int s_sha256_compress(struct sha256_state * md, const unsigned char *buf) +{ + ulong32 S[8], W[64], t0, t1; + int i; + + /* copy state into S */ + for (i = 0; i < 8; i++) { + S[i] = md->state[i]; + } + + /* copy the state into 512-bits into W[0..15] */ + for (i = 0; i < 16; i++) { + LOAD32H(W[i], buf + (4*i)); + } + + /* fill W[16..63] */ + for (i = 16; i < 64; i++) { + W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16]; + } + + /* Compress */ +#define RND(a,b,c,d,e,f,g,h,i,ki) \ + t0 = h + Sigma1(e) + Ch(e, f, g) + ki + W[i]; \ + t1 = Sigma0(a) + Maj(a, b, c); \ + d += t0; \ + h = t0 + t1; + + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],0,0x428a2f98); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],1,0x71374491); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],2,0xb5c0fbcf); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],3,0xe9b5dba5); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],4,0x3956c25b); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],5,0x59f111f1); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],6,0x923f82a4); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],7,0xab1c5ed5); + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],8,0xd807aa98); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],9,0x12835b01); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],10,0x243185be); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],11,0x550c7dc3); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],12,0x72be5d74); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],13,0x80deb1fe); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],14,0x9bdc06a7); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],15,0xc19bf174); + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],16,0xe49b69c1); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],17,0xefbe4786); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],18,0x0fc19dc6); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],19,0x240ca1cc); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],20,0x2de92c6f); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],21,0x4a7484aa); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],22,0x5cb0a9dc); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],23,0x76f988da); + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],24,0x983e5152); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],25,0xa831c66d); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],26,0xb00327c8); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],27,0xbf597fc7); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],28,0xc6e00bf3); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],29,0xd5a79147); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],30,0x06ca6351); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],31,0x14292967); + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],32,0x27b70a85); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],33,0x2e1b2138); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],34,0x4d2c6dfc); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],35,0x53380d13); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],36,0x650a7354); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],37,0x766a0abb); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],38,0x81c2c92e); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],39,0x92722c85); + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],40,0xa2bfe8a1); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],41,0xa81a664b); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],42,0xc24b8b70); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],43,0xc76c51a3); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],44,0xd192e819); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],45,0xd6990624); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],46,0xf40e3585); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],47,0x106aa070); + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],48,0x19a4c116); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],49,0x1e376c08); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],50,0x2748774c); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],51,0x34b0bcb5); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],52,0x391c0cb3); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],53,0x4ed8aa4a); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],54,0x5b9cca4f); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],55,0x682e6ff3); + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],56,0x748f82ee); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],57,0x78a5636f); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],58,0x84c87814); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],59,0x8cc70208); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],60,0x90befffa); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],61,0xa4506ceb); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],62,0xbef9a3f7); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],63,0xc67178f2); +#undef RND + + /* feedback */ + for (i = 0; i < 8; i++) { + md->state[i] = md->state[i] + S[i]; + } + return 0; +} + +static int sha256_init(struct sha256_state * md) +{ + if (md == NULL) return -1; + md->curlen = 0; + md->length = 0; + md->state[0] = 0x6A09E667UL; + md->state[1] = 0xBB67AE85UL; + md->state[2] = 0x3C6EF372UL; + md->state[3] = 0xA54FF53AUL; + md->state[4] = 0x510E527FUL; + md->state[5] = 0x9B05688CUL; + md->state[6] = 0x1F83D9ABUL; + md->state[7] = 0x5BE0CD19UL; + return 0; +} + +static int sha256_process(struct sha256_state * md, const unsigned char *in, unsigned long inlen) +{ + unsigned long n; + int err; + if (md == NULL) return -1; + if (in == NULL) return -1; + if (md->curlen > sizeof(md->buf)) { + return -1; + } + if (((md->length + inlen * 8) < md->length) + || ((inlen * 8) < inlen)) { + return -1; + } + while (inlen > 0) { + if (md->curlen == 0 && inlen >= 64) { + if ((err = s_sha256_compress(md, in)) != 0) { + return err; + } + md->length += 64 * 8; + in += 64; + inlen -= 64; + } else { + n = MIN(inlen, (64 - md->curlen)); + memcpy(md->buf + md->curlen, in, (size_t)n); + md->curlen += n; + in += n; + inlen -= n; + if (md->curlen == 64) { + if ((err = s_sha256_compress(md, md->buf)) != 0) { + return err; + } + md->length += 8 * 64; + md->curlen = 0; + } + } + } + return 0; +} + +static int sha256_done(struct sha256_state * md, unsigned char *out) +{ + int i; + + if (md == NULL) return -1; + if (out == NULL) return -1; + + if (md->curlen >= sizeof(md->buf)) { + return -1; + } + + /* increase the length of the message */ + md->length += md->curlen * 8; + + /* append the '1' bit */ + md->buf[md->curlen++] = (unsigned char)0x80; + + /* if the length is currently above 56 bytes we append zeros + * then compress. Then we can fall back to padding zeros and length + * encoding like normal. + */ + if (md->curlen > 56) { + while (md->curlen < 64) { + md->buf[md->curlen++] = (unsigned char)0; + } + s_sha256_compress(md, md->buf); + md->curlen = 0; + } + + /* pad upto 56 bytes of zeroes */ + while (md->curlen < 56) { + md->buf[md->curlen++] = (unsigned char)0; + } + + /* store length */ + STORE64H(md->length, md->buf+56); + s_sha256_compress(md, md->buf); + + /* copy output */ + for (i = 0; i < 8; i++) { + STORE32H(md->state[i], out+(4*i)); + } + return 0; +} + +void sha256(const void *in, unsigned long inlen, void* out) +{ + struct sha256_state ctx; + sha256_init(&ctx); + sha256_process(&ctx, (const unsigned char*)in, inlen); + sha256_done(&ctx, (unsigned char *)out); +} diff --git a/common/digest/sha512.c b/common/digest/sha512.c new file mode 100644 index 0000000..e99ea14 --- /dev/null +++ b/common/digest/sha512.c @@ -0,0 +1,312 @@ +/* sha512.c + + Copyright (c) 2022, Nikolaj Schlej. All rights reserved. + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + */ + +// +// This implementations are based on LibTomCrypt that was released into +// public domain by Tom St Denis. +// + +#include "sha2.h" +#include +#include + +/* ulong64: 64-bit data type */ +#ifdef _MSC_VER + #define CONST64(n) n ## ui64 + typedef unsigned __int64 ulong64; + typedef __int64 long64; +#else + #define CONST64(n) n ## ULL + typedef unsigned long long ulong64; + typedef long long long64; +#endif + +#define ROR64c(x, y) \ + ( ((((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)(y)&CONST64(63))) | \ + ((x)<<(((ulong64)64-((y)&63))&63))) & CONST64(0xFFFFFFFFFFFFFFFF)) + +#define LOAD64H(x, y) \ +do { x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48) | \ + (((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32) | \ + (((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16) | \ + (((ulong64)((y)[6] & 255))<<8)|(((ulong64)((y)[7] & 255))); } while(0) + +#define STORE64H(x, y) \ +do { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \ + (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \ + (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \ + (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); } while(0) + +#ifndef MIN +#define MIN(x, y) (((x) < (y)) ? (x) : (y)) +#endif + +/* the K array */ +static const ulong64 K[80] = { +CONST64(0x428a2f98d728ae22), CONST64(0x7137449123ef65cd), +CONST64(0xb5c0fbcfec4d3b2f), CONST64(0xe9b5dba58189dbbc), +CONST64(0x3956c25bf348b538), CONST64(0x59f111f1b605d019), +CONST64(0x923f82a4af194f9b), CONST64(0xab1c5ed5da6d8118), +CONST64(0xd807aa98a3030242), CONST64(0x12835b0145706fbe), +CONST64(0x243185be4ee4b28c), CONST64(0x550c7dc3d5ffb4e2), +CONST64(0x72be5d74f27b896f), CONST64(0x80deb1fe3b1696b1), +CONST64(0x9bdc06a725c71235), CONST64(0xc19bf174cf692694), +CONST64(0xe49b69c19ef14ad2), CONST64(0xefbe4786384f25e3), +CONST64(0x0fc19dc68b8cd5b5), CONST64(0x240ca1cc77ac9c65), +CONST64(0x2de92c6f592b0275), CONST64(0x4a7484aa6ea6e483), +CONST64(0x5cb0a9dcbd41fbd4), CONST64(0x76f988da831153b5), +CONST64(0x983e5152ee66dfab), CONST64(0xa831c66d2db43210), +CONST64(0xb00327c898fb213f), CONST64(0xbf597fc7beef0ee4), +CONST64(0xc6e00bf33da88fc2), CONST64(0xd5a79147930aa725), +CONST64(0x06ca6351e003826f), CONST64(0x142929670a0e6e70), +CONST64(0x27b70a8546d22ffc), CONST64(0x2e1b21385c26c926), +CONST64(0x4d2c6dfc5ac42aed), CONST64(0x53380d139d95b3df), +CONST64(0x650a73548baf63de), CONST64(0x766a0abb3c77b2a8), +CONST64(0x81c2c92e47edaee6), CONST64(0x92722c851482353b), +CONST64(0xa2bfe8a14cf10364), CONST64(0xa81a664bbc423001), +CONST64(0xc24b8b70d0f89791), CONST64(0xc76c51a30654be30), +CONST64(0xd192e819d6ef5218), CONST64(0xd69906245565a910), +CONST64(0xf40e35855771202a), CONST64(0x106aa07032bbd1b8), +CONST64(0x19a4c116b8d2d0c8), CONST64(0x1e376c085141ab53), +CONST64(0x2748774cdf8eeb99), CONST64(0x34b0bcb5e19b48a8), +CONST64(0x391c0cb3c5c95a63), CONST64(0x4ed8aa4ae3418acb), +CONST64(0x5b9cca4f7763e373), CONST64(0x682e6ff3d6b2b8a3), +CONST64(0x748f82ee5defb2fc), CONST64(0x78a5636f43172f60), +CONST64(0x84c87814a1f0ab72), CONST64(0x8cc702081a6439ec), +CONST64(0x90befffa23631e28), CONST64(0xa4506cebde82bde9), +CONST64(0xbef9a3f7b2c67915), CONST64(0xc67178f2e372532b), +CONST64(0xca273eceea26619c), CONST64(0xd186b8c721c0c207), +CONST64(0xeada7dd6cde0eb1e), CONST64(0xf57d4f7fee6ed178), +CONST64(0x06f067aa72176fba), CONST64(0x0a637dc5a2c898a6), +CONST64(0x113f9804bef90dae), CONST64(0x1b710b35131c471b), +CONST64(0x28db77f523047d84), CONST64(0x32caab7b40c72493), +CONST64(0x3c9ebe0a15c9bebc), CONST64(0x431d67c49c100d4c), +CONST64(0x4cc5d4becb3e42b6), CONST64(0x597f299cfc657e2a), +CONST64(0x5fcb6fab3ad6faec), CONST64(0x6c44198c4a475817) +}; + +/* Various logical functions */ +#define Ch(x,y,z) (z ^ (x & (y ^ z))) +#define Maj(x,y,z) (((x | y) & z) | (x & y)) +#define S(x, n) ROR64c(x, n) +#define R(x, n) (((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)n)) +#define Sigma0(x) (S(x, 28) ^ S(x, 34) ^ S(x, 39)) +#define Sigma1(x) (S(x, 14) ^ S(x, 18) ^ S(x, 41)) +#define Gamma0(x) (S(x, 1) ^ S(x, 8) ^ R(x, 7)) +#define Gamma1(x) (S(x, 19) ^ S(x, 61) ^ R(x, 6)) + +struct sha512_state { + ulong64 length, state[8]; + unsigned long curlen; + unsigned char buf[128]; +}; + +/* compress 1024-bits */ +static int s_sha512_compress(struct sha512_state * md, const unsigned char *buf) +{ + ulong64 S[8], W[80], t0, t1; + int i; + + /* copy state into S */ + for (i = 0; i < 8; i++) { + S[i] = md->state[i]; + } + + /* copy the state into 1024-bits into W[0..15] */ + for (i = 0; i < 16; i++) { + LOAD64H(W[i], buf + (8*i)); + } + + /* fill W[16..79] */ + for (i = 16; i < 80; i++) { + W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16]; + } + + /* Compress */ +#define RND(a,b,c,d,e,f,g,h,i) \ + t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \ + t1 = Sigma0(a) + Maj(a, b, c); \ + d += t0; \ + h = t0 + t1; + + for (i = 0; i < 80; i += 8) { + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],i+0); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],i+1); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],i+2); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],i+3); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],i+4); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],i+5); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],i+6); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],i+7); + } + + /* feedback */ + for (i = 0; i < 8; i++) { + md->state[i] = md->state[i] + S[i]; + } + + return 0; +} + +static int sha512_init(struct sha512_state * md) +{ + if (md == NULL) return -1; + md->curlen = 0; + md->length = 0; + md->state[0] = CONST64(0x6a09e667f3bcc908); + md->state[1] = CONST64(0xbb67ae8584caa73b); + md->state[2] = CONST64(0x3c6ef372fe94f82b); + md->state[3] = CONST64(0xa54ff53a5f1d36f1); + md->state[4] = CONST64(0x510e527fade682d1); + md->state[5] = CONST64(0x9b05688c2b3e6c1f); + md->state[6] = CONST64(0x1f83d9abfb41bd6b); + md->state[7] = CONST64(0x5be0cd19137e2179); + return 0; +} + +static int sha512_process(struct sha512_state * md, const unsigned char *in, unsigned long inlen) +{ + unsigned long n; + int err; + if (md == NULL) return -1; + if (in == NULL) return -1; + if (md->curlen > sizeof(md->buf)) { + return -1; + } + if (((md->length + inlen * 8) < md->length) + || ((inlen * 8) < inlen)) { + return -1; + } + while (inlen > 0) { + if (md->curlen == 0 && inlen >= 128) { + if ((err = s_sha512_compress(md, in)) != 0) { + return err; + } + md->length += 128 * 8; + in += 128; + inlen -= 128; + } else { + n = MIN(inlen, (128 - md->curlen)); + memcpy(md->buf + md->curlen, in, (size_t)n); + md->curlen += n; + in += n; + inlen -= n; + if (md->curlen == 128) { + if ((err = s_sha512_compress(md, md->buf)) != 0) { + return err; + } + md->length += 8 * 128; + md->curlen = 0; + } + } + } + return 0; +} + +static int sha512_done(struct sha512_state * md, unsigned char *out) +{ + int i; + + if (md == NULL) return -1; + if (out == NULL) return -1; + + if (md->curlen >= sizeof(md->buf)) { + return -1; + } + + /* increase the length of the message */ + md->length += md->curlen * CONST64(8); + + /* append the '1' bit */ + md->buf[md->curlen++] = (unsigned char)0x80; + + /* if the length is currently above 112 bytes we append zeros + * then compress. Then we can fall back to padding zeros and length + * encoding like normal. + */ + if (md->curlen > 112) { + while (md->curlen < 128) { + md->buf[md->curlen++] = (unsigned char)0; + } + s_sha512_compress(md, md->buf); + md->curlen = 0; + } + + /* pad upto 120 bytes of zeroes + * note: that from 112 to 120 is the 64 MSB of the length. We assume that you won't hash + * > 2^64 bits of data... :-) + */ + while (md->curlen < 120) { + md->buf[md->curlen++] = (unsigned char)0; + } + + /* store length */ + STORE64H(md->length, md->buf+120); + s_sha512_compress(md, md->buf); + + /* copy output */ + for (i = 0; i < 8; i++) { + STORE64H(md->state[i], out+(8*i)); + } + + return 0; +} + +static int sha384_init(struct sha512_state * md) +{ + if (md == NULL) return -1; + + md->curlen = 0; + md->length = 0; + md->state[0] = CONST64(0xcbbb9d5dc1059ed8); + md->state[1] = CONST64(0x629a292a367cd507); + md->state[2] = CONST64(0x9159015a3070dd17); + md->state[3] = CONST64(0x152fecd8f70e5939); + md->state[4] = CONST64(0x67332667ffc00b31); + md->state[5] = CONST64(0x8eb44a8768581511); + md->state[6] = CONST64(0xdb0c2e0d64f98fa7); + md->state[7] = CONST64(0x47b5481dbefa4fa4); + return 0; +} + +static int sha384_done(struct sha512_state * md, unsigned char *out) +{ + unsigned char buf[64]; + + if (md == NULL) return -1; + if (out == NULL) return -1;; + + if (md->curlen >= sizeof(md->buf)) { + return -1; + } + + sha512_done(md, buf); + memcpy(out, buf, 48); + return 0; +} + +void sha384(const void *in, unsigned long inlen, void* out) +{ + struct sha512_state ctx; + sha384_init(&ctx); + sha512_process(&ctx, (const unsigned char*)in, inlen); + sha384_done(&ctx, (unsigned char *)out); +} + +void sha512(const void *in, unsigned long inlen, void* out) +{ + struct sha512_state ctx; + sha512_init(&ctx); + sha512_process(&ctx, (const unsigned char*)in, inlen); + sha512_done(&ctx, (unsigned char *)out); +} diff --git a/common/digest/sm3.c b/common/digest/sm3.c new file mode 100644 index 0000000..9f25e6b --- /dev/null +++ b/common/digest/sm3.c @@ -0,0 +1,234 @@ +// SPDX-License-Identifier: BSD-2-Clause +/* + * Copyright (c) 2019 Huawei Technologies Co., Ltd + */ +#include "sm3.h" +#include + +struct sm3_context { + uint32_t total[2]; /* number of bytes processed */ + uint32_t state[8]; /* intermediate digest state */ + uint8_t buffer[64]; /* data block being processed */ + uint8_t ipad[64]; /* HMAC: inner padding */ + uint8_t opad[64]; /* HMAC: outer padding */ +}; + +static void sm3_init(struct sm3_context *ctx); +static void sm3_update(struct sm3_context *ctx, const uint8_t *input, size_t ilen); +static void sm3_final(struct sm3_context *ctx, uint8_t* output); + +#define GET_UINT32_BE(n, b, i) \ + do { \ + (n) = ((uint32_t)(b)[(i)] << 24) | \ + ((uint32_t)(b)[(i) + 1] << 16) | \ + ((uint32_t)(b)[(i) + 2] << 8) | \ + ((uint32_t)(b)[(i) + 3]); \ + } while (0) + +#define PUT_UINT32_BE(n, b, i) \ + do { \ + (b)[(i)] = (uint8_t)((n) >> 24); \ + (b)[(i) + 1] = (uint8_t)((n) >> 16); \ + (b)[(i) + 2] = (uint8_t)((n) >> 8); \ + (b)[(i) + 3] = (uint8_t)((n)); \ + } while (0) + +static void sm3_init(struct sm3_context *ctx) +{ + ctx->total[0] = 0; + ctx->total[1] = 0; + + ctx->state[0] = 0x7380166F; + ctx->state[1] = 0x4914B2B9; + ctx->state[2] = 0x172442D7; + ctx->state[3] = 0xDA8A0600; + ctx->state[4] = 0xA96F30BC; + ctx->state[5] = 0x163138AA; + ctx->state[6] = 0xE38DEE4D; + ctx->state[7] = 0xB0FB0E4E; +} + +static void sm3_process(struct sm3_context *ctx, const uint8_t data[64]) +{ + uint32_t SS1, SS2, TT1, TT2, W[68], W1[64]; + uint32_t A, B, C, D, E, F, G, H; + uint32_t T[64]; + uint32_t Temp1, Temp2, Temp3, Temp4, Temp5; + int j; + + for (j = 0; j < 16; j++) + T[j] = 0x79CC4519; + for (j = 16; j < 64; j++) + T[j] = 0x7A879D8A; + + GET_UINT32_BE(W[0], data, 0); + GET_UINT32_BE(W[1], data, 4); + GET_UINT32_BE(W[2], data, 8); + GET_UINT32_BE(W[3], data, 12); + GET_UINT32_BE(W[4], data, 16); + GET_UINT32_BE(W[5], data, 20); + GET_UINT32_BE(W[6], data, 24); + GET_UINT32_BE(W[7], data, 28); + GET_UINT32_BE(W[8], data, 32); + GET_UINT32_BE(W[9], data, 36); + GET_UINT32_BE(W[10], data, 40); + GET_UINT32_BE(W[11], data, 44); + GET_UINT32_BE(W[12], data, 48); + GET_UINT32_BE(W[13], data, 52); + GET_UINT32_BE(W[14], data, 56); + GET_UINT32_BE(W[15], data, 60); + +#define FF0(x, y, z) ((x) ^ (y) ^ (z)) +#define FF1(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z))) + +#define GG0(x, y, z) ((x) ^ (y) ^ (z)) +#define GG1(x, y, z) (((x) & (y)) | ((~(x)) & (z))) + +#define SHL(x, n) ((x) << (n)) +#define ROTL(x, y) ( (((uint32_t)(x)<<(uint32_t)((y)&31)) | (((uint32_t)(x)&0xFFFFFFFFUL)>>(uint32_t)((32-((y)&31))&31))) & 0xFFFFFFFFUL) + +#define P0(x) ((x) ^ ROTL((x), 9) ^ ROTL((x), 17)) +#define P1(x) ((x) ^ ROTL((x), 15) ^ ROTL((x), 23)) + + for (j = 16; j < 68; j++) { + /* + * W[j] = P1( W[j-16] ^ W[j-9] ^ ROTL(W[j-3],15)) ^ + * ROTL(W[j - 13],7 ) ^ W[j-6]; + */ + + Temp1 = W[j - 16] ^ W[j - 9]; + Temp2 = ROTL(W[j - 3], 15); + Temp3 = Temp1 ^ Temp2; + Temp4 = P1(Temp3); + Temp5 = ROTL(W[j - 13], 7) ^ W[j - 6]; + W[j] = Temp4 ^ Temp5; + } + + for (j = 0; j < 64; j++) + W1[j] = W[j] ^ W[j + 4]; + + A = ctx->state[0]; + B = ctx->state[1]; + C = ctx->state[2]; + D = ctx->state[3]; + E = ctx->state[4]; + F = ctx->state[5]; + G = ctx->state[6]; + H = ctx->state[7]; + + for (j = 0; j < 16; j++) { + SS1 = ROTL(ROTL(A, 12) + E + ROTL(T[j], j), 7); + SS2 = SS1 ^ ROTL(A, 12); + TT1 = FF0(A, B, C) + D + SS2 + W1[j]; + TT2 = GG0(E, F, G) + H + SS1 + W[j]; + D = C; + C = ROTL(B, 9); + B = A; + A = TT1; + H = G; + G = ROTL(F, 19); + F = E; + E = P0(TT2); + } + + for (j = 16; j < 64; j++) { + SS1 = ROTL(ROTL(A, 12) + E + ROTL(T[j], j), 7); + SS2 = SS1 ^ ROTL(A, 12); + TT1 = FF1(A, B, C) + D + SS2 + W1[j]; + TT2 = GG1(E, F, G) + H + SS1 + W[j]; + D = C; + C = ROTL(B, 9); + B = A; + A = TT1; + H = G; + G = ROTL(F, 19); + F = E; + E = P0(TT2); + } + + ctx->state[0] ^= A; + ctx->state[1] ^= B; + ctx->state[2] ^= C; + ctx->state[3] ^= D; + ctx->state[4] ^= E; + ctx->state[5] ^= F; + ctx->state[6] ^= G; + ctx->state[7] ^= H; +} + +static void sm3_update(struct sm3_context *ctx, const uint8_t *input, size_t ilen) +{ + size_t fill; + size_t left; + + if (!ilen) + return; + + left = ctx->total[0] & 0x3F; + fill = 64 - left; + + ctx->total[0] += ilen; + + if (ctx->total[0] < ilen) + ctx->total[1]++; + + if (left && ilen >= fill) { + memcpy(ctx->buffer + left, input, fill); + sm3_process(ctx, ctx->buffer); + input += fill; + ilen -= fill; + left = 0; + } + + while (ilen >= 64) { + sm3_process(ctx, input); + input += 64; + ilen -= 64; + } + + if (ilen > 0) + memcpy(ctx->buffer + left, input, ilen); +} + +static const uint8_t sm3_padding[64] = { + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +static void sm3_final(struct sm3_context *ctx, uint8_t* output) +{ + uint32_t last, padn; + uint32_t high, low; + uint8_t msglen[8]; + + high = (ctx->total[0] >> 29) | (ctx->total[1] << 3); + low = ctx->total[0] << 3; + + PUT_UINT32_BE(high, msglen, 0); + PUT_UINT32_BE(low, msglen, 4); + + last = ctx->total[0] & 0x3F; + padn = (last < 56) ? (56 - last) : (120 - last); + + sm3_update(ctx, sm3_padding, padn); + sm3_update(ctx, msglen, 8); + + PUT_UINT32_BE(ctx->state[0], output, 0); + PUT_UINT32_BE(ctx->state[1], output, 4); + PUT_UINT32_BE(ctx->state[2], output, 8); + PUT_UINT32_BE(ctx->state[3], output, 12); + PUT_UINT32_BE(ctx->state[4], output, 16); + PUT_UINT32_BE(ctx->state[5], output, 20); + PUT_UINT32_BE(ctx->state[6], output, 24); + PUT_UINT32_BE(ctx->state[7], output, 28); +} + +void sm3(const void *in, unsigned long inlen, void* out) +{ + struct sm3_context ctx; + sm3_init(&ctx); + sm3_update(&ctx, (const uint8_t *)in, (size_t)inlen); + sm3_final(&ctx, (uint8_t*)out); +} diff --git a/common/digest/sm3.h b/common/digest/sm3.h new file mode 100644 index 0000000..0d248b6 --- /dev/null +++ b/common/digest/sm3.h @@ -0,0 +1,32 @@ +/* sm3.h + +Copyright (c) 2022, Nikolaj Schlej. All rights reserved. +This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +*/ + +/* SPDX-License-Identifier: BSD-2-Clause */ +/* + * Copyright (c) 2019 Huawei Technologies Co., Ltd + */ +#ifndef SM3_H +#define SM3_H +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +void sm3(const void *in, unsigned long inlen, void* out); + +#ifdef __cplusplus +} +#endif +#endif /* SM3_H */ diff --git a/common/ffs.cpp b/common/ffs.cpp index 29ed276..c9b7ac2 100644 --- a/common/ffs.cpp +++ b/common/ffs.cpp @@ -1,109 +1,416 @@ /* ffs.cpp + + Copyright (c) 2015, Nikolaj Schlej. All rights reserved. + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + */ -Copyright (c) 2015, Nikolaj Schlej. All rights reserved. -This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php +#include -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -*/ - -#include "ustring.h" #include "ffs.h" +#include "guiddatabase.h" +#include "ubytearray.h" -// This is a workaround for the lack of static std::vector initializer before C++11 -const UByteArray FFSv2VolumesInt[] = { +// +// GUIDs mentioned in by ffs.h +// +// Standard FMP capsule GUID +extern const UByteArray EFI_FMP_CAPSULE_GUID // 6DCBD5ED-E82D-4C44-BDA1-7194199AD92A +("\xED\xD5\xCB\x6D\x2D\xE8\x44\x4C\xBD\xA1\x71\x94\x19\x9A\xD9\x2A", 16); +// Standard EFI capsule GUID +extern const UByteArray EFI_CAPSULE_GUID // 3B6686BD-0D76-4030-B70E-B5519E2FC5A0 +("\xBD\x86\x66\x3B\x76\x0D\x30\x40\xB7\x0E\xB5\x51\x9E\x2F\xC5\xA0", 16); +// Intel capsule GUID +extern const UByteArray INTEL_CAPSULE_GUID // 539182B9-ABB5-4391-B69A-E3A943F72FCC +("\xB9\x82\x91\x53\xB5\xAB\x91\x43\xB6\x9A\xE3\xA9\x43\xF7\x2F\xCC", 16); +// Lenovo capsule GUID +extern const UByteArray LENOVO_CAPSULE_GUID // E20BAFD3-9914-4F4F-9537-3129E090EB3C +("\xD3\xAF\x0B\xE2\x14\x99\x4F\x4F\x95\x37\x31\x29\xE0\x90\xEB\x3C", 16); +// Another Lenovo capsule GUID +extern const UByteArray LENOVO2_CAPSULE_GUID // 25B5FE76-8243-4A5C-A9BD-7EE3246198B5 +("\x76\xFE\xB5\x25\x43\x82\x5C\x4A\xA9\xBD\x7E\xE3\x24\x61\x98\xB5", 16); +// Toshiba capsule GUID +extern const UByteArray TOSHIBA_CAPSULE_GUID // 3BE07062-1D51-45D2-832B-F093257ED461 +("\x62\x70\xE0\x3B\x51\x1D\xD2\x45\x83\x2B\xF0\x93\x25\x7E\xD4\x61", 16); +// AMI Aptio signed extended capsule GUID +extern const UByteArray APTIO_SIGNED_CAPSULE_GUID // 4A3CA68B-7723-48FB-803D-578CC1FEC44D +("\x8B\xA6\x3C\x4A\x23\x77\xFB\x48\x80\x3D\x57\x8C\xC1\xFE\xC4\x4D", 16); +// AMI Aptio unsigned extended capsule GUID +extern const UByteArray APTIO_UNSIGNED_CAPSULE_GUID // 14EEBB90-890A-43DB-AED1-5D3C4588A418 +("\x90\xBB\xEE\x14\x0A\x89\xDB\x43\xAE\xD1\x5D\x3C\x45\x88\xA4\x18", 16); +// Standard file system GUIDs +extern const UByteArray EFI_FIRMWARE_FILE_SYSTEM_GUID // 7A9354D9-0468-444A-81CE-0BF617D890DF +("\xD9\x54\x93\x7A\x68\x04\x4A\x44\x81\xCE\x0B\xF6\x17\xD8\x90\xDF", 16); +extern const UByteArray EFI_FIRMWARE_FILE_SYSTEM2_GUID // 8C8CE578-8A3D-4F1C-9935-896185C32DD3 +("\x78\xE5\x8C\x8C\x3D\x8A\x1C\x4F\x99\x35\x89\x61\x85\xC3\x2D\xD3", 16); +extern const UByteArray EFI_FIRMWARE_FILE_SYSTEM3_GUID // 5473C07A-3DCB-4DCA-BD6F-1E9689E7349A +("\x7A\xC0\x73\x54\xCB\x3D\xCA\x4D\xBD\x6F\x1E\x96\x89\xE7\x34\x9A", 16); +// Vendor-specific file system GUIDs +extern const UByteArray EFI_APPLE_IMMUTABLE_FV_GUID // 04ADEEAD-61FF-4D31-B6BA-64F8BF901F5A +("\xAD\xEE\xAD\x04\xFF\x61\x31\x4D\xB6\xBA\x64\xF8\xBF\x90\x1F\x5A", 16); +extern const UByteArray EFI_APPLE_AUTHENTICATION_FV_GUID // BD001B8C-6A71-487B-A14F-0C2A2DCF7A5D +("\x8C\x1B\x00\xBD\x71\x6A\x7B\x48\xA1\x4F\x0C\x2A\x2D\xCF\x7A\x5D", 16); +extern const UByteArray EFI_APPLE_MICROCODE_VOLUME_GUID // 153D2197-29BD-44DC-AC59-887F70E41A6B +("\x97\x21\x3D\x15\xBD\x29\xDC\x44\xAC\x59\x88\x7F\x70\xE4\x1A\x6B", 16); +extern const UByteArray EFI_INTEL_FILE_SYSTEM_GUID // AD3FFFFF-D28B-44C4-9F13-9EA98A97F9F0 +("\xFF\xFF\x3F\xAD\x8B\xD2\xC4\x44\x9F\x13\x9E\xA9\x8A\x97\xF9\xF0", 16); +extern const UByteArray EFI_INTEL_FILE_SYSTEM2_GUID // D6A1CD70-4B33-4994-A6EA-375F2CCC5437 +("\x70\xCD\xA1\xD6\x33\x4B\x94\x49\xA6\xEA\x37\x5F\x2C\xCC\x54\x37", 16); +extern const UByteArray EFI_SONY_FILE_SYSTEM_GUID // 4F494156-AED6-4D64-A537-B8A5557BCEEC +("\x56\x41\x49\x4F\xD6\xAE\x64\x4D\xA5\x37\xB8\xA5\x55\x7B\xCE\xEC", 16); +// PEI apriori file +extern const UByteArray EFI_PEI_APRIORI_FILE_GUID // 1B45CC0A-156A-428A-AF62-49864DA0E6E6 +("\x0A\xCC\x45\x1B\x6A\x15\x8A\x42\xAF\x62\x49\x86\x4D\xA0\xE6\xE6", 16); +// DXE apriori file +extern const UByteArray EFI_DXE_APRIORI_FILE_GUID // FC510EE7-FFDC-11D4-BD41-0080C73C8881 +("\xE7\x0E\x51\xFC\xDC\xFF\xD4\x11\xBD\x41\x00\x80\xC7\x3C\x88\x81", 16); +// Volume top file +extern const UByteArray EFI_FFS_VOLUME_TOP_FILE_GUID // 1BA0062E-C779-4582-8566-336AE8F78F09 +("\x2E\x06\xA0\x1B\x79\xC7\x82\x45\x85\x66\x33\x6A\xE8\xF7\x8F\x09", 16); +// Padding file GUID +extern const UByteArray EFI_FFS_PAD_FILE_GUID // E4536585-7909-4A60-B5C6-ECDEA6EBFB5 +("\x85\x65\x53\xE4\x09\x79\x60\x4A\xB5\xC6\xEC\xDE\xA6\xEB\xFB\x54", 16); +// AMI DXE core file +extern const UByteArray AMI_CORE_DXE_GUID // 5AE3F37E-4EAE-41AE-8240-35465B5E81EB +("\x7E\xF3\xE3\x5A\xAE\x4E\xAE\x41\x82\x40\x35\x46\x5B\x5E\x81\xEB", 16); +// EDK2 DXE core file +extern const UByteArray EFI_DXE_CORE_GUID // D6A2CB7F-6A18-4E2F-B43B-9920A733700A +("\x7F\xCB\xA2\xD6\x18\x6A\x2F\x4E\xB4\x3B\x99\x20\xA7\x33\x70\x0A", 16); +// AMD compressed raw file +extern const UByteArray AMD_COMPRESSED_RAW_FILE_GUID //20BC8AC9-94D1-4208-AB28-5D673FD73487 +("\xC9\x8A\xBC\x20\xD1\x94\x08\x42\xAB\x28\x5D\x67\x3F\xD7\x34\x87", 16); + +// Insyde Flash Device Map GUIDs +extern const UByteArray INSYDE_FLASH_MAP_REGION_BOOT_FV_GUID +("\x56\x6d\xd7\xe3\x8a\x98\x6b\x4d\x89\x13\x64\xf2\xdf\x1d\xf6\xa6", 16); +extern const UByteArray INSYDE_FLASH_MAP_REGION_BVDT_GUID +("\xFC\x5D\x41\x32\x06\xD1\xC7\x48\x9E\xB5\x80\x6C\x11\x4D\xD1\x07", 16); +extern const UByteArray INSYDE_FLASH_MAP_REGION_EC_GUID +("\xBF\xF3\x3E\xA7\xCC\x33\xA9\x43\xB3\x9C\xA9\x12\xC7\x48\x9A\x57", 16); +extern const UByteArray INSYDE_FLASH_MAP_REGION_FTW_BACKUP_GUID +("\xD3\x15\x8E\xB7\xA5\xF0\x48\x42\x8E\x2F\xD3\x15\x7A\xEF\x88\x36", 16); +extern const UByteArray INSYDE_FLASH_MAP_REGION_FTW_STATE_GUID +("\x04\x6E\x41\xC8\x34\x99\x79\x40\xBE\x9A\x39\xF8\xD6\x02\x84\x98", 16); +extern const UByteArray INSYDE_FLASH_MAP_REGION_FV_GUID +("\x58\xE7\xE8\xB5\xE6\xA7\x8B\x4C\xAB\x85\xFF\x2A\x95\x9B\x99\xBA", 16); +extern const UByteArray INSYDE_FLASH_MAP_REGION_FLASH_DEVICE_MAP_GUID +("\xA0\xC1\x78\xF0\x52\xFC\x3F\x4C\xBE\x1F\xD6\x88\x81\x5A\x62\xC0", 16); +extern const UByteArray INSYDE_FLASH_MAP_REGION_LOGO_GUID +("\x69\xAB\xCF\xDA\x77\xF9\x84\x47\x8A\xD8\x77\x24\xA6\xF4\xB4\x40", 16); +extern const UByteArray INSYDE_FLASH_MAP_REGION_MICROCODE_GUID +("\xF8\x66\x98\xB4\xD2\x8C\xE4\x49\xA1\x6D\xB6\x0F\xBE\xC3\x1C\x4B", 16); +extern const UByteArray INSYDE_FLASH_MAP_REGION_MSDM_TABLE_GUID +("\x1A\xEB\x44\xB3\x7E\xF9\x14\x4F\xA1\xE1\x7E\x63\xBC\x40\xC8\xCE", 16); +extern const UByteArray INSYDE_FLASH_MAP_REGION_MULTI_CONFIG_GUID +("\x92\xB5\x94\x59\x14\x2F\xD5\x48\xBB\x40\xBD\x27\x96\x9C\x77\x80", 16); +extern const UByteArray INSYDE_FLASH_MAP_REGION_VAR_DEFAULT_GUID +("\xA2\xAC\xDD\xD9\x16\x08\xF3\x48\xAD\xED\x6B\x71\x65\x6B\x24\x8A", 16); +extern const UByteArray INSYDE_FLASH_MAP_REGION_SMBIOS_UPDATE_GUID +("\xDC\xFE\x64\x89\xE7\x6F\x1E\x4E\xA5\x5E\xFF\x82\x1D\x71\xFF\xCF", 16); +extern const UByteArray INSYDE_FLASH_MAP_REGION_VAR_GUID +("\x74\x53\x3C\x77\xD1\x81\x43\x4D\xB2\x93\xF3\xD7\x4F\x18\x1D\x6B", 16); +extern const UByteArray INSYDE_FLASH_MAP_REGION_UNKNOWN_GUID +("\xE5\x65\x1D\x20\x23\xBE\x75\x48\x80\xF8\xB1\xD4\x79\x5E\x7E\x08", 16); +extern const UByteArray INSYDE_FLASH_MAP_REGION_UNUSED_GUID +("\x20\xB0\xC8\x13\x27\x4F\x3B\x45\x8F\x80\x1B\xFC\xA1\x87\x38\x0F", 16); +extern const UByteArray INSYDE_FLASH_MAP_REGION_USB_OPTION_ROM_GUID +("\x0F\xF3\x7B\x60\x2B\x5F\xA2\x4D\xAE\xED\x56\xF9\xBD\xCD\x2D\x21", 16); +extern const UByteArray INSYDE_FLASH_MAP_REGION_DXE_FV_GUID +("\xCE\xBA\xD0\x1F\x0A\x6F\x85\x40\x90\x1E\xF6\x21\x03\x85\xCB\x6F", 16); +extern const UByteArray INSYDE_FLASH_MAP_REGION_PEI_FV_GUID +("\xC5\x06\x14\xCF\xEC\x3F\xEB\x47\xA6\xC3\xB7\x1A\x3E\xE0\x0B\x95", 16); +extern const UByteArray INSYDE_FLASH_MAP_REGION_UNSIGNED_FV_GUID +("\xB6\x16\xA0\xF2\x14\xE8\x2E\x40\xA3\x95\x46\xD3\xCF\x75\x26\x4A", 16); + +// GUIDs of GUID-defined sections +extern const UByteArray EFI_GUIDED_SECTION_CRC32 // FC1BCDB0-7D31-49AA-936A-A4600D9DD083 +("\xB0\xCD\x1B\xFC\x31\x7D\xAA\x49\x93\x6A\xA4\x60\x0D\x9D\xD0\x83", 16); +extern const UByteArray EFI_GUIDED_SECTION_TIANO // A31280AD-481E-41B6-95E8-127F4C984779 +("\xAD\x80\x12\xA3\x1E\x48\xB6\x41\x95\xE8\x12\x7F\x4C\x98\x47\x79", 16); +extern const UByteArray EFI_GUIDED_SECTION_LZMA // EE4E5898-3914-4259-9D6E-DC7BD79403CF +("\x98\x58\x4E\xEE\x14\x39\x59\x42\x9D\x6E\xDC\x7B\xD7\x94\x03\xCF", 16); +extern const UByteArray EFI_GUIDED_SECTION_LZMA_HP // 0ED85E23-F253-413F-A03C-901987B04397 +("\x23\x5E\xD8\x0E\x53\xF2\x3F\x41\xA0\x3C\x90\x19\x87\xB0\x43\x97", 16); +extern const UByteArray EFI_GUIDED_SECTION_LZMA_MS // BD9921EA-ED91-404A-8B2F-B4D724747C8C +("\xEA\x21\x99\xBD\x91\xED\x4A\x40\x8B\x2F\xB4\xD7\x24\x74\x7C\x8C", 16); +extern const UByteArray EFI_GUIDED_SECTION_LZMAF86 // D42AE6BD-1352-4BFB-909A-CA72A6EAE889 +("\xBD\xE6\x2A\xD4\x52\x13\xFB\x4B\x90\x9A\xCA\x72\xA6\xEA\xE8\x89", 16); +extern const UByteArray EFI_GUIDED_SECTION_GZIP // 1D301FE9-BE79-4353-91C2-D23BC959AE0C +("\xE9\x1F\x30\x1D\x79\xBE\x53\x43\x91\xC2\xD2\x3B\xC9\x59\xAE\x0C", 16); +extern const UByteArray EFI_GUIDED_SECTION_ZLIB_AMD // CE3233F5-2CD6-4D87-9152-4A238BB6D1C4 +("\xF5\x33\x32\xCE\xD6\x2C\x87\x4D\x91\x52\x4A\x23\x8B\xB6\xD1\xC4", 16); +extern const UByteArray EFI_GUIDED_SECTION_ZLIB_AMD2 // 991EFAC0-E260-416B-A4B8-3B153072B804 +("\xC0\xFA\x1E\x99\x60\xE2\x6B\x41\xA4\xB8\x3B\x15\x30\x72\xB8\x04", 16); +extern const UByteArray EFI_FIRMWARE_CONTENTS_SIGNED_GUID // 0F9D89E8-9259-4F76-A5AF-0C89E34023DF +("\xE8\x89\x9D\x0F\x59\x92\x76\x4F\xA5\xAF\x0C\x89\xE3\x40\x23\xDF", 16); +extern const UByteArray EFI_CERT_TYPE_RSA2048_SHA256_GUID // A7717414-C616-4977-9420-844712A735BF + ("\x14\x74\x71\xA7\x16\xC6\x77\x49\x94\x20\x84\x47\x12\xA7\x35\xBF"); +extern const UByteArray EFI_HASH_ALGORITHM_SHA256_GUID // 51AA59DE-FDF2-4EA3-BC63-875FB7842EE9 +("\xde\x59\xAA\x51\xF2\xFD\xA3\x4E\xBC\x63\x87\x5F\xB7\x84\x2E\xE9"); + +// Protected range files +extern const UByteArray PROTECTED_RANGE_VENDOR_HASH_FILE_GUID_PHOENIX // 389CC6F2-1EA8-467B-AB8A-78E769AE2A15 +("\xF2\xC6\x9C\x38\xA8\x1E\x7B\x46\xAB\x8A\x78\xE7\x69\xAE\x2A\x15", 16); +extern const UByteArray PROTECTED_RANGE_VENDOR_HASH_FILE_GUID_AMI // CBC91F44-A4BC-4A5B-8696-703451D0B053 +("\x44\x1F\xC9\xCB\xBC\xA4\x5B\x4A\x86\x96\x70\x34\x51\xD0\xB0\x53", 16); + +// AMI ROM Hole files +extern const UByteArray AMI_ROM_HOLE_FILE_GUID_0 //05CA01FC-0FC1-11DC-9011-00173153EBA8 +("\xFC\x01\xCA\x05\xC1\x0F\xDC\x11\x90\x11\x00\x17\x31\x53\xEB\xA8", 16); +extern const UByteArray AMI_ROM_HOLE_FILE_GUID_1 //05CA01FD-0FC1-11DC-9011-00173153EBA8 +("\xFD\x01\xCA\x05\xC1\x0F\xDC\x11\x90\x11\x00\x17\x31\x53\xEB\xA8", 16); +extern const UByteArray AMI_ROM_HOLE_FILE_GUID_2 //05CA01FE-0FC1-11DC-9011-00173153EBA8 +("\xFE\x01\xCA\x05\xC1\x0F\xDC\x11\x90\x11\x00\x17\x31\x53\xEB\xA8", 16); +extern const UByteArray AMI_ROM_HOLE_FILE_GUID_3 //05CA01FF-0FC1-11DC-9011-00173153EBA8 +("\xFF\x01\xCA\x05\xC1\x0F\xDC\x11\x90\x11\x00\x17\x31\x53\xEB\xA8", 16); +extern const UByteArray AMI_ROM_HOLE_FILE_GUID_4 //05CA0200-0FC1-11DC-9011-00173153EBA8 +("\x00\x02\xCA\x05\xC1\x0F\xDC\x11\x90\x11\x00\x17\x31\x53\xEB\xA8", 16); +extern const UByteArray AMI_ROM_HOLE_FILE_GUID_5 //05CA0201-0FC1-11DC-9011-00173153EBA8 +("\x01\x02\xCA\x05\xC1\x0F\xDC\x11\x90\x11\x00\x17\x31\x53\xEB\xA8", 16); +extern const UByteArray AMI_ROM_HOLE_FILE_GUID_6 //05CA0202-0FC1-11DC-9011-00173153EBA8 +("\x02\x02\xCA\x05\xC1\x0F\xDC\x11\x90\x11\x00\x17\x31\x53\xEB\xA8", 16); +extern const UByteArray AMI_ROM_HOLE_FILE_GUID_7 //05CA0203-0FC1-11DC-9011-00173153EBA8 +("\x03\x02\xCA\x05\xC1\x0F\xDC\x11\x90\x11\x00\x17\x31\x53\xEB\xA8", 16); +extern const UByteArray AMI_ROM_HOLE_FILE_GUID_8 //05CA0204-0FC1-11DC-9011-00173153EBA8 +("\x04\x02\xCA\x05\xC1\x0F\xDC\x11\x90\x11\x00\x17\x31\x53\xEB\xA8", 16); +extern const UByteArray AMI_ROM_HOLE_FILE_GUID_9 //05CA0205-0FC1-11DC-9011-00173153EBA8 +("\x05\x02\xCA\x05\xC1\x0F\xDC\x11\x90\x11\x00\x17\x31\x53\xEB\xA8", 16); +extern const UByteArray AMI_ROM_HOLE_FILE_GUID_10 //05CA0206-0FC1-11DC-9011-00173153EBA8 +("\x06\x02\xCA\x05\xC1\x0F\xDC\x11\x90\x11\x00\x17\x31\x53\xEB\xA8", 16); +extern const UByteArray AMI_ROM_HOLE_FILE_GUID_11 //05CA0207-0FC1-11DC-9011-00173153EBA8 +("\x07\x02\xCA\x05\xC1\x0F\xDC\x11\x90\x11\x00\x17\x31\x53\xEB\xA8", 16); +extern const UByteArray AMI_ROM_HOLE_FILE_GUID_12 //05CA0208-0FC1-11DC-9011-00173153EBA8 +("\x08\x02\xCA\x05\xC1\x0F\xDC\x11\x90\x11\x00\x17\x31\x53\xEB\xA8", 16); +extern const UByteArray AMI_ROM_HOLE_FILE_GUID_13 //05CA0209-0FC1-11DC-9011-00173153EBA8 +("\x09\x02\xCA\x05\xC1\x0F\xDC\x11\x90\x11\x00\x17\x31\x53\xEB\xA8", 16); +extern const UByteArray AMI_ROM_HOLE_FILE_GUID_14 //05CA020A-0FC1-11DC-9011-00173153EBA8 +("\x0A\x02\xCA\x05\xC1\x0F\xDC\x11\x90\x11\x00\x17\x31\x53\xEB\xA8", 16); +extern const UByteArray AMI_ROM_HOLE_FILE_GUID_15 //05CA020B-0FC1-11DC-9011-00173153EBA8 +("\x0B\x02\xCA\x05\xC1\x0F\xDC\x11\x90\x11\x00\x17\x31\x53\xEB\xA8", 16); + +const std::vector FFSv2Volumes({ EFI_FIRMWARE_FILE_SYSTEM_GUID, EFI_FIRMWARE_FILE_SYSTEM2_GUID, - EFI_APPLE_BOOT_VOLUME_FILE_SYSTEM_GUID, - EFI_APPLE_BOOT_VOLUME_FILE_SYSTEM2_GUID, + EFI_APPLE_AUTHENTICATION_FV_GUID, + EFI_APPLE_IMMUTABLE_FV_GUID, EFI_INTEL_FILE_SYSTEM_GUID, EFI_INTEL_FILE_SYSTEM2_GUID, EFI_SONY_FILE_SYSTEM_GUID -}; -// This number must be updated if the array above is grown -#define FFSv2VolumesIntSize 7 -const std::vector FFSv2Volumes(FFSv2VolumesInt, FFSv2VolumesInt + FFSv2VolumesIntSize); -// Luckily, FFSv3Volumes now only has 1 element -const std::vector FFSv3Volumes(1, EFI_FIRMWARE_FILE_SYSTEM3_GUID); +}); + +const std::vector FFSv3Volumes({EFI_FIRMWARE_FILE_SYSTEM3_GUID}); const UINT8 ffsAlignmentTable[] = { 0, 4, 7, 9, 10, 12, 15, 16 }; +const UINT8 ffsAlignment2Table[] = +{ 17, 18, 19, 20, 21, 22, 23, 24 }; + +extern const UByteArray RECOVERY_STARTUP_AP_DATA_X86_128K // jmp far F000:FFD0, EAD0FF00F0 +("\xEA\xD0\xFF\x00\xF0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x27\x2D", RECOVERY_STARTUP_AP_DATA_X86_SIZE); + VOID uint32ToUint24(UINT32 size, UINT8* ffsSize) { - ffsSize[2] = (UINT8)((size) >> 16); - ffsSize[1] = (UINT8)((size) >> 8); + ffsSize[2] = (UINT8)((size) >> 16U); + ffsSize[1] = (UINT8)((size) >> 8U); ffsSize[0] = (UINT8)((size)); } UINT32 uint24ToUint32(const UINT8* ffsSize) { - return *(UINT32*)ffsSize & 0x00FFFFFF; + return (UINT32) ffsSize[0] + + ((UINT32) ffsSize[1] << 8U) + + ((UINT32) ffsSize[2] << 16U); } -UString guidToUString(const EFI_GUID & guid) +UString guidToUString(const EFI_GUID & guid, bool convertToString) { + if (convertToString) { + UString readableName = guidDatabaseLookup(guid); + if (!readableName.isEmpty()) + return readableName; + } + return usprintf("%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X", - *(const UINT32*)&guid.Data[0], - *(const UINT16*)&guid.Data[4], - *(const UINT16*)&guid.Data[6], - guid.Data[8], - guid.Data[9], - guid.Data[10], - guid.Data[11], - guid.Data[12], - guid.Data[13], - guid.Data[14], - guid.Data[15]); + guid.Data1, + guid.Data2, + guid.Data3, + guid.Data4[0], + guid.Data4[1], + guid.Data4[2], + guid.Data4[3], + guid.Data4[4], + guid.Data4[5], + guid.Data4[6], + guid.Data4[7]); +} + + +bool ustringToGuid(const UString & str, EFI_GUID & guid) +{ + unsigned long p0; + unsigned p1, p2, p3, p4, p5, p6, p7, p8, p9, p10; + + int err = std::sscanf(str.toLocal8Bit(), "%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X", + &p0, &p1, &p2, &p3, &p4, &p5, &p6, &p7, &p8, &p9, &p10); + if (err == 0) + return false; + + guid.Data1 = (UINT32)p0; + guid.Data2 = (UINT16)p1; + guid.Data3 = (UINT16)p2; + guid.Data4[0] = (UINT8)p3; + guid.Data4[1] = (UINT8)p4; + guid.Data4[2] = (UINT8)p5; + guid.Data4[3] = (UINT8)p6; + guid.Data4[4] = (UINT8)p7; + guid.Data4[5] = (UINT8)p8; + guid.Data4[6] = (UINT8)p9; + guid.Data4[7] = (UINT8)p10; + + return true; } UString fileTypeToUString(const UINT8 type) { - switch (type) - { - case EFI_FV_FILETYPE_RAW: return UString("Raw"); - case EFI_FV_FILETYPE_FREEFORM: return UString("Freeform"); - case EFI_FV_FILETYPE_SECURITY_CORE: return UString("SEC core"); - case EFI_FV_FILETYPE_PEI_CORE: return UString("PEI core"); - case EFI_FV_FILETYPE_DXE_CORE: return UString("DXE core"); - case EFI_FV_FILETYPE_PEIM: return UString("PEI module"); - case EFI_FV_FILETYPE_DRIVER: return UString("DXE driver"); - case EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER: return UString("Combined PEI/DXE"); - case EFI_FV_FILETYPE_APPLICATION: return UString("Application"); - case EFI_FV_FILETYPE_SMM: return UString("SMM module"); - case EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE: return UString("Volume image"); - case EFI_FV_FILETYPE_COMBINED_SMM_DXE: return UString("Combined SMM/DXE"); - case EFI_FV_FILETYPE_SMM_CORE: return UString("SMM core"); - case EFI_FV_FILETYPE_PAD: return UString("Pad"); - default: return UString("Unknown"); + switch (type) { + case EFI_FV_FILETYPE_RAW: return UString("Raw"); + case EFI_FV_FILETYPE_FREEFORM: return UString("Freeform"); + case EFI_FV_FILETYPE_SECURITY_CORE: return UString("SEC core"); + case EFI_FV_FILETYPE_PEI_CORE: return UString("PEI core"); + case EFI_FV_FILETYPE_DXE_CORE: return UString("DXE core"); + case EFI_FV_FILETYPE_PEIM: return UString("PEI module"); + case EFI_FV_FILETYPE_DRIVER: return UString("DXE driver"); + case EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER: return UString("Combined PEI/DXE"); + case EFI_FV_FILETYPE_APPLICATION: return UString("Application"); + case EFI_FV_FILETYPE_MM: return UString("SMM module"); + case EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE: return UString("Volume image"); + case EFI_FV_FILETYPE_COMBINED_MM_DXE: return UString("Combined SMM/DXE"); + case EFI_FV_FILETYPE_MM_CORE: return UString("SMM core"); + case EFI_FV_FILETYPE_MM_STANDALONE: return UString("MM standalone module"); + case EFI_FV_FILETYPE_MM_CORE_STANDALONE: return UString("MM standalone core"); + case EFI_FV_FILETYPE_PAD: return UString("Pad"); }; + return usprintf("Unknown %02Xh", type); } UString sectionTypeToUString(const UINT8 type) { - switch (type) - { - case EFI_SECTION_COMPRESSION: return UString("Compressed"); - case EFI_SECTION_GUID_DEFINED: return UString("GUID defined"); - case EFI_SECTION_DISPOSABLE: return UString("Disposable"); - case EFI_SECTION_PE32: return UString("PE32 image"); - case EFI_SECTION_PIC: return UString("PIC image"); - case EFI_SECTION_TE: return UString("TE image"); - case EFI_SECTION_DXE_DEPEX: return UString("DXE dependency"); - case EFI_SECTION_VERSION: return UString("Version"); - case EFI_SECTION_USER_INTERFACE: return UString("UI"); - case EFI_SECTION_COMPATIBILITY16: return UString("16-bit image"); - case EFI_SECTION_FIRMWARE_VOLUME_IMAGE: return UString("Volume image"); - case EFI_SECTION_FREEFORM_SUBTYPE_GUID: return UString("Freeform subtype GUID"); - case EFI_SECTION_RAW: return UString("Raw"); - case EFI_SECTION_PEI_DEPEX: return UString("PEI dependency"); - case EFI_SECTION_SMM_DEPEX: return UString("SMM dependency"); - case INSYDE_SECTION_POSTCODE: return UString("Insyde postcode"); - case PHOENIX_SECTION_POSTCODE: return UString("Phoenix postcode"); - default: return UString("Unknown"); + switch (type) { + case EFI_SECTION_COMPRESSION: return UString("Compressed"); + case EFI_SECTION_GUID_DEFINED: return UString("GUID defined"); + case EFI_SECTION_DISPOSABLE: return UString("Disposable"); + case EFI_SECTION_PE32: return UString("PE32 image"); + case EFI_SECTION_PIC: return UString("PIC image"); + case EFI_SECTION_TE: return UString("TE image"); + case EFI_SECTION_DXE_DEPEX: return UString("DXE dependency"); + case EFI_SECTION_VERSION: return UString("Version"); + case EFI_SECTION_USER_INTERFACE: return UString("UI"); + case EFI_SECTION_COMPATIBILITY16: return UString("16-bit image"); + case EFI_SECTION_FIRMWARE_VOLUME_IMAGE: return UString("Volume image"); + case EFI_SECTION_FREEFORM_SUBTYPE_GUID: return UString("Freeform subtype GUID"); + case EFI_SECTION_RAW: return UString("Raw"); + case EFI_SECTION_PEI_DEPEX: return UString("PEI dependency"); + case EFI_SECTION_MM_DEPEX: return UString("MM dependency"); + case INSYDE_SECTION_POSTCODE: return UString("Insyde postcode"); + case PHOENIX_SECTION_POSTCODE: return UString("Phoenix postcode"); } + return usprintf("Unknown %02Xh", type); } +UString bpdtEntryTypeToUString(const UINT16 type) +{ + switch (type) { + case BPDT_ENTRY_TYPE_SMIP: return UString("OEM SMIP"); + case BPDT_ENTRY_TYPE_RBEP: return UString("ROM Boot Extensions"); + case BPDT_ENTRY_TYPE_FTPR: return UString("Bring Up"); + case BPDT_ENTRY_TYPE_UCOD: return UString("Microcode"); + case BPDT_ENTRY_TYPE_IBBP: return UString("IBB"); + case BPDT_ENTRY_TYPE_S_BPDT: return UString("Secondary BPDT"); + case BPDT_ENTRY_TYPE_OBBP: return UString("OBB"); + case BPDT_ENTRY_TYPE_NFTP: return UString("Main"); + case BPDT_ENTRY_TYPE_ISHC: return UString("ISH"); + case BPDT_ENTRY_TYPE_DLMP: return UString("Debug Launch Module"); + case BPDT_ENTRY_TYPE_UEBP: return UString("IFP Bypass"); + case BPDT_ENTRY_TYPE_UTOK: return UString("Debug Tokens"); + case BPDT_ENTRY_TYPE_UFS_PHY: return UString("UFS PHY Config"); + case BPDT_ENTRY_TYPE_UFS_GPP_LUN: return UString("UFS GPP LUN"); + case BPDT_ENTRY_TYPE_PMCP: return UString("PMC"); + case BPDT_ENTRY_TYPE_IUNP: return UString("iUnit"); + case BPDT_ENTRY_TYPE_NVMC: return UString("NVM Config"); + case BPDT_ENTRY_TYPE_UEP: return UString("Unified Emulation"); + case BPDT_ENTRY_TYPE_WCOD: return UString("WLAN Microcode"); + case BPDT_ENTRY_TYPE_LOCL: return UString("LOCL Sprites"); + case BPDT_ENTRY_TYPE_OEMP: return UString("OEM Key Manifest"); + case BPDT_ENTRY_TYPE_FITC: return UString("fitc.cfg"); + case BPDT_ENTRY_TYPE_PAVP: return UString("PAVP"); + case BPDT_ENTRY_TYPE_IOMP: return UString("TCSS FW IOM"); + case BPDT_ENTRY_TYPE_XPHY: return UString("TCSS FW PHY"); + case BPDT_ENTRY_TYPE_TBTP: return UString("TCSS TBT"); + case BPDT_ENTRY_TYPE_PLTS: return UString("Platform Settings"); + case BPDT_ENTRY_TYPE_RES27: return UString("Reserved 27"); + case BPDT_ENTRY_TYPE_RES28: return UString("Reserved 28"); + case BPDT_ENTRY_TYPE_RES29: return UString("Reserved 29"); + case BPDT_ENTRY_TYPE_RES30: return UString("Reserved 30"); + case BPDT_ENTRY_TYPE_DPHY: return UString("Dekel PHY"); + case BPDT_ENTRY_TYPE_PCHC: return UString("PCH Config"); + case BPDT_ENTRY_TYPE_ISIF: return UString("ISI FW"); + case BPDT_ENTRY_TYPE_ISIC: return UString("ISI Config"); + case BPDT_ENTRY_TYPE_HBMI: return UString("HBM IO"); + case BPDT_ENTRY_TYPE_OMSM: return UString("OOB MSM"); + case BPDT_ENTRY_TYPE_GTGP: return UString("GT-GPU"); + case BPDT_ENTRY_TYPE_MDFI: return UString("MDF IO"); + case BPDT_ENTRY_TYPE_PUNP: return UString("PUnit"); + case BPDT_ENTRY_TYPE_PHYP: return UString("GSC PHY"); + case BPDT_ENTRY_TYPE_SAMF: return UString("SAM FW"); + case BPDT_ENTRY_TYPE_PPHY: return UString("PPHY"); + case BPDT_ENTRY_TYPE_GBST: return UString("GBST"); + case BPDT_ENTRY_TYPE_TCCP: return UString("TCC"); + case BPDT_ENTRY_TYPE_PSEP: return UString("PSE"); + } + return usprintf("Unknown %04Xh", type); +} + +UString cpdExtensionTypeToUstring(const UINT32 type) +{ + switch (type) { + case CPD_EXT_TYPE_SYSTEM_INFO: return UString("System Info"); + case CPD_EXT_TYPE_INIT_SCRIPT: return UString("Init Script"); + case CPD_EXT_TYPE_FEATURE_PERMISSIONS: return UString("Feature Permissions"); + case CPD_EXT_TYPE_PARTITION_INFO: return UString("Partition Info"); + case CPD_EXT_TYPE_SHARED_LIB_ATTRIBUTES: return UString("Shared Lib Attributes"); + case CPD_EXT_TYPE_PROCESS_ATTRIBUTES: return UString("Process Attributes"); + case CPD_EXT_TYPE_THREAD_ATTRIBUTES: return UString("Thread Attributes"); + case CPD_EXT_TYPE_DEVICE_TYPE: return UString("Device Type"); + case CPD_EXT_TYPE_MMIO_RANGE: return UString("MMIO Range"); + case CPD_EXT_TYPE_SPEC_FILE_PRODUCER: return UString("Spec File Producer"); + case CPD_EXT_TYPE_MODULE_ATTRIBUTES: return UString("Module Attributes"); + case CPD_EXT_TYPE_LOCKED_RANGES: return UString("Locked Ranges"); + case CPD_EXT_TYPE_CLIENT_SYSTEM_INFO: return UString("Client System Info"); + case CPD_EXT_TYPE_USER_INFO: return UString("User Info"); + case CPD_EXT_TYPE_KEY_MANIFEST: return UString("Key Manifest"); + case CPD_EXT_TYPE_SIGNED_PACKAGE_INFO: return UString("Signed Package Info"); + case CPD_EXT_TYPE_ANTI_CLONING_SKU_ID: return UString("Anti-cloning SKU ID"); + case CPD_EXT_TYPE_CAVS: return UString("cAVS"); + case CPD_EXT_TYPE_IMR_INFO: return UString("IMR Info"); + case CPD_EXT_TYPE_RCIP_INFO: return UString("RCIP Info"); + case CPD_EXT_TYPE_BOOT_POLICY: return UString("Boot Policy"); + case CPD_EXT_TYPE_SECURE_TOKEN: return UString("Secure Token"); + case CPD_EXT_TYPE_IFWI_PARTITION_MANIFEST: return UString("IFWI Partition Manifest"); + case CPD_EXT_TYPE_FD_HASH: return UString("FD Hash"); + case CPD_EXT_TYPE_IOM_METADATA: return UString("IOM Metadata"); + case CPD_EXT_TYPE_MGP_METADATA: return UString("MGP Metadata"); + case CPD_EXT_TYPE_TBT_METADATA: return UString("TBT Metadata"); + case CPD_EXT_TYPE_GMF_CERTIFICATE: return UString("Golden Measurement File Certificate"); + case CPD_EXT_TYPE_GMF_BODY: return UString("Golden Measurement File Body"); + case CPD_EXT_TYPE_KEY_MANIFEST_EXT: return UString("Extended Key Manifest"); + case CPD_EXT_TYPE_SIGNED_PACKAGE_INFO_EXT: return UString("Extended Signed Package Info"); + case CPD_EXT_TYPE_SPS_PLATFORM_ID: return UString("SPS Platform ID"); + } + return usprintf("Unknown %08Xh", type); +} diff --git a/common/ffs.h b/common/ffs.h index 34f8141..e515421 100644 --- a/common/ffs.h +++ b/common/ffs.h @@ -15,26 +15,28 @@ WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include +#include "basetypes.h" #include "ubytearray.h" #include "ustring.h" -#include "basetypes.h" // Make sure we use right packing rules #pragma pack(push,1) -extern UString guidToUString(const EFI_GUID& guid); +extern UString guidToUString(const EFI_GUID& guid, bool convertToString = true); +extern bool ustringToGuid(const UString& str, EFI_GUID& guid); extern UString fileTypeToUString(const UINT8 type); extern UString sectionTypeToUString(const UINT8 type); - +extern UString bpdtEntryTypeToUString(const UINT16 type); +extern UString cpdExtensionTypeToUstring(const UINT32 type); //***************************************************************************** // EFI Capsule //***************************************************************************** // Capsule header typedef struct EFI_CAPSULE_HEADER_ { - EFI_GUID CapsuleGuid; - UINT32 HeaderSize; - UINT32 Flags; - UINT32 CapsuleImageSize; + EFI_GUID CapsuleGuid; + UINT32 HeaderSize; + UINT32 Flags; + UINT32 CapsuleImageSize; } EFI_CAPSULE_HEADER; // Capsule flags @@ -42,50 +44,46 @@ typedef struct EFI_CAPSULE_HEADER_ { #define EFI_CAPSULE_HEADER_FLAG_PERSIST_ACROSS_RESET 0x00010000 #define EFI_CAPSULE_HEADER_FLAG_POPULATE_SYSTEM_TABLE 0x00020000 +// Standard FMP capsule GUID +extern const UByteArray EFI_FMP_CAPSULE_GUID; // 6DCBD5ED-E82D-4C44-BDA1-7194199AD92A + // Standard EFI capsule GUID -const UByteArray EFI_CAPSULE_GUID -("\xBD\x86\x66\x3B\x76\x0D\x30\x40\xB7\x0E\xB5\x51\x9E\x2F\xC5\xA0", 16); +extern const UByteArray EFI_CAPSULE_GUID; // 3B6686BD-0D76-4030-B70E-B5519E2FC5A0 // Intel capsule GUID -const UByteArray INTEL_CAPSULE_GUID -("\xB9\x82\x91\x53\xB5\xAB\x91\x43\xB6\x9A\xE3\xA9\x43\xF7\x2F\xCC", 16); +extern const UByteArray INTEL_CAPSULE_GUID; // 539182B9-ABB5-4391-B69A-E3A943F72FCC // Lenovo capsule GUID -const UByteArray LENOVO_CAPSULE_GUID -("\xD3\xAF\x0B\xE2\x14\x99\x4F\x4F\x95\x37\x31\x29\xE0\x90\xEB\x3C", 16); +extern const UByteArray LENOVO_CAPSULE_GUID; // E20BAFD3-9914-4F4F-9537-3129E090EB3C // Another Lenovo capsule GUID -const UByteArray LENOVO2_CAPSULE_GUID -("\x76\xFE\xB5\x25\x43\x82\x5C\x4A\xA9\xBD\x7E\xE3\x24\x61\x98\xB5", 16); +extern const UByteArray LENOVO2_CAPSULE_GUID; // 25B5FE76-8243-4A5C-A9BD-7EE3246198B5 // Toshiba EFI Capsule header typedef struct TOSHIBA_CAPSULE_HEADER_ { - EFI_GUID CapsuleGuid; - UINT32 HeaderSize; - UINT32 FullSize; - UINT32 Flags; + EFI_GUID CapsuleGuid; + UINT32 HeaderSize; + UINT32 FullSize; + UINT32 Flags; } TOSHIBA_CAPSULE_HEADER; // Toshiba capsule GUID -const UByteArray TOSHIBA_CAPSULE_GUID -("\x62\x70\xE0\x3B\x51\x1D\xD2\x45\x83\x2B\xF0\x93\x25\x7E\xD4\x61", 16); +extern const UByteArray TOSHIBA_CAPSULE_GUID; // 3BE07062-1D51-45D2-832B-F093257ED461 // AMI Aptio extended capsule header typedef struct APTIO_CAPSULE_HEADER_ { - EFI_CAPSULE_HEADER CapsuleHeader; - UINT16 RomImageOffset; // offset in bytes from the beginning of the capsule header to the start of the capsule volume - UINT16 RomLayoutOffset; // offset to the table of the module descriptors in the capsule's volume that are included in the signature calculation - //FW_CERTIFICATE FWCert; - //ROM_AREA RomAreaMap[1]; + EFI_CAPSULE_HEADER CapsuleHeader; + UINT16 RomImageOffset; // offset in bytes from the beginning of the capsule header to the start of the capsule volume + UINT16 RomLayoutOffset; // offset to the table of the module descriptors in the capsule's volume that are included in the signature calculation + //FW_CERTIFICATE FWCert; + //ROM_AREA RomAreaMap[]; } APTIO_CAPSULE_HEADER; // AMI Aptio signed extended capsule GUID -const UByteArray APTIO_SIGNED_CAPSULE_GUID -("\x8B\xA6\x3C\x4A\x23\x77\xFB\x48\x80\x3D\x57\x8C\xC1\xFE\xC4\x4D", 16); +extern const UByteArray APTIO_SIGNED_CAPSULE_GUID; // 4A3CA68B-7723-48FB-803D-578CC1FEC44D // AMI Aptio unsigned extended capsule GUID -const UByteArray APTIO_UNSIGNED_CAPSULE_GUID -("\x90\xBB\xEE\x14\x0A\x89\xDB\x43\xAE\xD1\x5D\x3C\x45\x88\xA4\x18", 16); +extern const UByteArray APTIO_UNSIGNED_CAPSULE_GUID; // 14EEBB90-890A-43DB-AED1-5D3C4588A418 //***************************************************************************** // EFI Firmware Volume @@ -93,73 +91,69 @@ const UByteArray APTIO_UNSIGNED_CAPSULE_GUID // Firmware block map entry // FvBlockMap ends with an entry {0x00000000, 0x00000000} typedef struct EFI_FV_BLOCK_MAP_ENTRY_ { - UINT32 NumBlocks; - UINT32 Length; + UINT32 NumBlocks; + UINT32 Length; } EFI_FV_BLOCK_MAP_ENTRY; // Volume header typedef struct EFI_FIRMWARE_VOLUME_HEADER_ { - UINT8 ZeroVector[16]; - EFI_GUID FileSystemGuid; - UINT64 FvLength; - UINT32 Signature; - UINT32 Attributes; - UINT16 HeaderLength; - UINT16 Checksum; - UINT16 ExtHeaderOffset; //Reserved in Revision 1 - UINT8 Reserved; - UINT8 Revision; + UINT8 ZeroVector[16]; + EFI_GUID FileSystemGuid; + UINT64 FvLength; + UINT32 Signature; + UINT32 Attributes; + UINT16 HeaderLength; + UINT16 Checksum; + UINT16 ExtHeaderOffset; //Reserved in Revision 1 + UINT8 Reserved; + UINT8 Revision; //EFI_FV_BLOCK_MAP_ENTRY FvBlockMap[2]; } EFI_FIRMWARE_VOLUME_HEADER; // Standard file system GUIDs -const UByteArray EFI_FIRMWARE_FILE_SYSTEM_GUID -("\xD9\x54\x93\x7A\x68\x04\x4A\x44\x81\xCE\x0B\xF6\x17\xD8\x90\xDF", 16); -const UByteArray EFI_FIRMWARE_FILE_SYSTEM2_GUID -("\x78\xE5\x8C\x8C\x3D\x8A\x1C\x4F\x99\x35\x89\x61\x85\xC3\x2D\xD3", 16); +extern const UByteArray EFI_FIRMWARE_FILE_SYSTEM_GUID; // 7A9354D9-0468-444A-81CE-0BF617D890DF + +extern const UByteArray EFI_FIRMWARE_FILE_SYSTEM2_GUID; // 8C8CE578-8A3D-4F1C-9935-896185C32DD3 + +extern const UByteArray EFI_FIRMWARE_FILE_SYSTEM3_GUID; // 5473C07A-3DCB-4DCA-BD6F-1E9689E7349A + // Vendor-specific file system GUIDs -const UByteArray EFI_APPLE_BOOT_VOLUME_FILE_SYSTEM_GUID -("\xAD\xEE\xAD\x04\xFF\x61\x31\x4D\xB6\xBA\x64\xF8\xBF\x90\x1F\x5A", 16); -const UByteArray EFI_APPLE_BOOT_VOLUME_FILE_SYSTEM2_GUID -("\x8C\x1B\x00\xBD\x71\x6A\x7B\x48\xA1\x4F\x0C\x2A\x2D\xCF\x7A\x5D", 16); +extern const UByteArray EFI_APPLE_IMMUTABLE_FV_GUID; // 04ADEEAD-61FF-4D31-B6BA-64F8BF901F5A -// AD3FFFFF-D28B-44C4-9F13-9EA98A97F9F0 // Intel 1 -const UByteArray EFI_INTEL_FILE_SYSTEM_GUID -("\xFF\xFF\x3F\xAD\x8B\xD2\xC4\x44\x9F\x13\x9E\xA9\x8A\x97\xF9\xF0", 16); -// D6A1CD70-4B33-4994-A6EA-375F2CCC5437 // Intel 2 -const UByteArray EFI_INTEL_FILE_SYSTEM2_GUID -("\x70\xCD\xA1\xD6\x33\x4B\x94\x49\xA6\xEA\x37\x5F\x2C\xCC\x54\x37", 16); -// 4F494156-AED6-4D64-A537-B8A5557BCEEC // Sony 1 -const UByteArray EFI_SONY_FILE_SYSTEM_GUID -("\x56\x41\x49\x4F\xD6\xAE\x64\x4D\xA5\x37\xB8\xA5\x55\x7B\xCE\xEC", 16); +extern const UByteArray EFI_APPLE_AUTHENTICATION_FV_GUID; // BD001B8C-6A71-487B-A14F-0C2A2DCF7A5D +extern const UByteArray EFI_APPLE_MICROCODE_VOLUME_GUID; // 153D2197-29BD-44DC-AC59-887F70E41A6B +#define EFI_APPLE_MICROCODE_VOLUME_HEADER_SIZE 0x100 + +extern const UByteArray EFI_INTEL_FILE_SYSTEM_GUID; // AD3FFFFF-D28B-44C4-9F13-9EA98A97F9F0 + +extern const UByteArray EFI_INTEL_FILE_SYSTEM2_GUID; // D6A1CD70-4B33-4994-A6EA-375F2CCC5437 + +extern const UByteArray EFI_SONY_FILE_SYSTEM_GUID; // 4F494156-AED6-4D64-A537-B8A5557BCEEC // Vector of volume GUIDs with FFSv2-compatible files extern const std::vector FFSv2Volumes; -const UByteArray EFI_FIRMWARE_FILE_SYSTEM3_GUID // 5473C07A-3DCB-4DCA-BD6F-1E9689E7349A -("\x7A\xC0\x73\x54\xCB\x3D\xCA\x4D\xBD\x6F\x1E\x96\x89\xE7\x34\x9A", 16); - // Vector of volume GUIDs with FFSv3-compatible files extern const std::vector FFSv3Volumes; // Firmware volume signature -const UByteArray EFI_FV_SIGNATURE("_FVH", 4); +#define EFI_FV_SIGNATURE 0x4856465F // _FVH #define EFI_FV_SIGNATURE_OFFSET 0x28 // Firmware volume attributes // Revision 1 -#define EFI_FVB_READ_DISABLED_CAP 0x00000001 -#define EFI_FVB_READ_ENABLED_CAP 0x00000002 -#define EFI_FVB_READ_STATUS 0x00000004 -#define EFI_FVB_WRITE_DISABLED_CAP 0x00000008 -#define EFI_FVB_WRITE_ENABLED_CAP 0x00000010 -#define EFI_FVB_WRITE_STATUS 0x00000020 -#define EFI_FVB_LOCK_CAP 0x00000040 -#define EFI_FVB_LOCK_STATUS 0x00000080 -#define EFI_FVB_STICKY_WRITE 0x00000200 -#define EFI_FVB_MEMORY_MAPPED 0x00000400 -#define EFI_FVB_ERASE_POLARITY 0x00000800 +#define EFI_FVB_READ_DISABLED_CAP 0x00000001 +#define EFI_FVB_READ_ENABLED_CAP 0x00000002 +#define EFI_FVB_READ_STATUS 0x00000004 +#define EFI_FVB_WRITE_DISABLED_CAP 0x00000008 +#define EFI_FVB_WRITE_ENABLED_CAP 0x00000010 +#define EFI_FVB_WRITE_STATUS 0x00000020 +#define EFI_FVB_LOCK_CAP 0x00000040 +#define EFI_FVB_LOCK_STATUS 0x00000080 +#define EFI_FVB_STICKY_WRITE 0x00000200 +#define EFI_FVB_MEMORY_MAPPED 0x00000400 +#define EFI_FVB_ERASE_POLARITY 0x00000800 #define EFI_FVB_ALIGNMENT_CAP 0x00008000 #define EFI_FVB_ALIGNMENT_2 0x00010000 #define EFI_FVB_ALIGNMENT_4 0x00020000 @@ -230,8 +224,8 @@ const UByteArray EFI_FV_SIGNATURE("_FVH", 4); // Extended firmware volume header typedef struct EFI_FIRMWARE_VOLUME_EXT_HEADER_ { - EFI_GUID FvName; - UINT32 ExtHeaderSize; + EFI_GUID FvName; + UINT32 ExtHeaderSize; } EFI_FIRMWARE_VOLUME_EXT_HEADER; // Extended header entry @@ -239,16 +233,16 @@ typedef struct EFI_FIRMWARE_VOLUME_EXT_HEADER_ { // terminated by ExtHeaderType EFI_FV_EXT_TYPE_END #define EFI_FV_EXT_TYPE_END 0x0000 typedef struct EFI_FIRMWARE_VOLUME_EXT_ENTRY_ { - UINT16 ExtEntrySize; - UINT16 ExtEntryType; + UINT16 ExtEntrySize; + UINT16 ExtEntryType; } EFI_FIRMWARE_VOLUME_EXT_ENTRY; // GUID that maps OEM file types to GUIDs #define EFI_FV_EXT_TYPE_OEM_TYPE 0x0001 typedef struct EFI_FIRMWARE_VOLUME_EXT_HEADER_OEM_TYPE_ { - EFI_FIRMWARE_VOLUME_EXT_ENTRY Header; - UINT32 TypeMask; - //EFI_GUID Types[1]; + EFI_FIRMWARE_VOLUME_EXT_ENTRY Header; + UINT32 TypeMask; + //EFI_GUID Types[]; } EFI_FIRMWARE_VOLUME_EXT_HEADER_OEM_TYPE; #define EFI_FV_EXT_TYPE_GUID_TYPE 0x0002 @@ -264,8 +258,8 @@ typedef struct EFI_FIRMWARE_VOLUME_EXT_ENTRY_GUID_TYPE_ { // Integrity check typedef union { struct { - UINT8 Header; - UINT8 File; + UINT8 Header; + UINT8 File; } Checksum; UINT16 TailReference; // Revision 1 UINT16 Checksum16; // Revision 2 @@ -286,10 +280,21 @@ EFI_GUID Name; EFI_FFS_INTEGRITY_CHECK IntegrityCheck; UINT8 Type; UINT8 Attributes; -UINT8 Size[3]; // Set to 0xFFFFFF +UINT8 Size[3]; // Set to 0xFFFFFF or 0x000000 +UINT8 State; +UINT64 ExtendedSize; +} EFI_FFS_FILE_HEADER2; + +// Lenovo large file header +typedef struct EFI_FFS_FILE_HEADER2_LENOVO_ { +EFI_GUID Name; +EFI_FFS_INTEGRITY_CHECK IntegrityCheck; +UINT8 Type; +UINT8 Attributes; +UINT8 Size[3]; // Set to 0x000000 UINT8 State; UINT32 ExtendedSize; -} EFI_FFS_FILE_HEADER2; +} EFI_FFS_FILE_HEADER2_LENOVO; // Standard data checksum, used if FFS_ATTRIB_CHECKSUM is clear #define FFS_FIXED_CHECKSUM 0x5A @@ -306,10 +311,12 @@ UINT32 ExtendedSize; #define EFI_FV_FILETYPE_DRIVER 0x07 #define EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER 0x08 #define EFI_FV_FILETYPE_APPLICATION 0x09 -#define EFI_FV_FILETYPE_SMM 0x0A +#define EFI_FV_FILETYPE_MM 0x0A #define EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE 0x0B -#define EFI_FV_FILETYPE_COMBINED_SMM_DXE 0x0C -#define EFI_FV_FILETYPE_SMM_CORE 0x0D +#define EFI_FV_FILETYPE_COMBINED_MM_DXE 0x0C +#define EFI_FV_FILETYPE_MM_CORE 0x0D +#define EFI_FV_FILETYPE_MM_STANDALONE 0x0E +#define EFI_FV_FILETYPE_MM_CORE_STANDALONE 0x0F #define EFI_FV_FILETYPE_OEM_MIN 0xC0 #define EFI_FV_FILETYPE_OEM_MAX 0xDF #define EFI_FV_FILETYPE_DEBUG_MIN 0xE0 @@ -321,7 +328,8 @@ UINT32 ExtendedSize; // File attributes #define FFS_ATTRIB_TAIL_PRESENT 0x01 // Valid only for revision 1 volumes #define FFS_ATTRIB_RECOVERY 0x02 // Valid only for revision 1 volumes -#define FFS_ATTRIB_LARGE_FILE 0x01 // Valid only for FFSv3 volumes +#define FFS_ATTRIB_LARGE_FILE 0x01 // Valid only for FFSv3 volumes or FFSv2 volumes with Lenovo large files +#define FFS_ATTRIB_DATA_ALIGNMENT2 0x02 // Valid only for revision 2 volumes, added in UEFI PI 1.6 #define FFS_ATTRIB_FIXED 0x04 #define FFS_ATTRIB_DATA_ALIGNMENT 0x38 #define FFS_ATTRIB_CHECKSUM 0x40 @@ -329,6 +337,9 @@ UINT32 ExtendedSize; // FFS alignment table extern const UINT8 ffsAlignmentTable[]; +// Extended FFS alignment table, added in UEFI PI 1.6 +extern const UINT8 ffsAlignment2Table[]; + // File states #define EFI_FILE_HEADER_CONSTRUCTION 0x01 #define EFI_FILE_HEADER_VALID 0x02 @@ -336,22 +347,28 @@ extern const UINT8 ffsAlignmentTable[]; #define EFI_FILE_MARKED_FOR_UPDATE 0x08 #define EFI_FILE_DELETED 0x10 #define EFI_FILE_HEADER_INVALID 0x20 +#define EFI_FILE_ERASE_POLARITY 0x80 // Defined as "all other bits must be set to ERASE_POLARITY" in UEFI PI // PEI apriori file -const UByteArray EFI_PEI_APRIORI_FILE_GUID -("\x0A\xCC\x45\x1B\x6A\x15\x8A\x42\xAF\x62\x49\x86\x4D\xA0\xE6\xE6", 16); +extern const UByteArray EFI_PEI_APRIORI_FILE_GUID; // 1B45CC0A-156A-428A-AF62-49864DA0E6E6 // DXE apriori file -const UByteArray EFI_DXE_APRIORI_FILE_GUID -("\xE7\x0E\x51\xFC\xDC\xFF\xD4\x11\xBD\x41\x00\x80\xC7\x3C\x88\x81", 16); +extern const UByteArray EFI_DXE_APRIORI_FILE_GUID; // FC510EE7-FFDC-11D4-BD41-0080C73C8881 // Volume top file -const UByteArray EFI_FFS_VOLUME_TOP_FILE_GUID -("\x2E\x06\xA0\x1B\x79\xC7\x82\x45\x85\x66\x33\x6A\xE8\xF7\x8F\x09", 16); +extern const UByteArray EFI_FFS_VOLUME_TOP_FILE_GUID; // 1BA0062E-C779-4582-8566-336AE8F78F09 -// Pad file GUID -const UByteArray EFI_FFS_PAD_FILE_GUID -("\x85\x65\x53\xE4\x09\x79\x60\x4A\xB5\xC6\xEC\xDE\xA6\xEB\xFB\x54", 16); +// AMI padding file GUID +extern const UByteArray EFI_FFS_PAD_FILE_GUID; // E4536585-7909-4A60-B5C6-ECDEA6EBFB5 + +// AMI DXE core file +extern const UByteArray AMI_CORE_DXE_GUID; // 5AE3F37E-4EAE-41AE-8240-35465B5E81EB + +// EDK2 DXE core file +extern const UByteArray EFI_DXE_CORE_GUID; // D6A2CB7F-6A18-4E2F-B43B-9920A733700A + +// AMD compressed raw file +extern const UByteArray AMD_COMPRESSED_RAW_FILE_GUID; //20BC8AC9-94D1-4208-AB28-5D673FD73487 // FFS size conversion routines extern VOID uint32ToUint24(UINT32 size, UINT8* ffsSize); @@ -362,30 +379,20 @@ extern UINT32 uint24ToUint32(const UINT8* ffsSize); //***************************************************************************** // Common section header typedef struct EFI_COMMON_SECTION_HEADER_ { - UINT8 Size[3]; - UINT8 Type; + UINT8 Size[3]; + UINT8 Type; } EFI_COMMON_SECTION_HEADER; // Large file common section header typedef struct EFI_COMMON_SECTION_HEADER2_ { - UINT8 Size[3]; // Must be 0xFFFFFF for this header to be used - UINT8 Type; - UINT32 ExtendedSize; + UINT8 Size[3]; // Must be 0xFFFFFF for this header to be used + UINT8 Type; + UINT32 ExtendedSize; } EFI_COMMON_SECTION_HEADER2; -// Apple common section header -typedef struct EFI_COMMON_SECTION_HEADER_APPLE { - UINT8 Size[3]; - UINT8 Type; - UINT32 Reserved; // Must be 0x7FFF for this header to be used -} EFI_COMMON_SECTION_HEADER_APPLE; - // Section2 usage indicator #define EFI_SECTION2_IS_USED 0xFFFFFF -// Apple section usage indicator -#define EFI_SECTION_APPLE_USED 0x7FFF - // File section types #define EFI_SECTION_ALL 0x00 // Impossible attribute for file in the FS @@ -406,25 +413,21 @@ typedef struct EFI_COMMON_SECTION_HEADER_APPLE { #define EFI_SECTION_FREEFORM_SUBTYPE_GUID 0x18 #define EFI_SECTION_RAW 0x19 #define EFI_SECTION_PEI_DEPEX 0x1B -#define EFI_SECTION_SMM_DEPEX 0x1C +#define EFI_SECTION_MM_DEPEX 0x1C #define PHOENIX_SECTION_POSTCODE 0xF0 // Specific to Phoenix SCT images #define INSYDE_SECTION_POSTCODE 0x20 // Specific to Insyde H2O images // Compression section typedef struct EFI_COMPRESSION_SECTION_ { - UINT32 UncompressedLength; - UINT8 CompressionType; + UINT32 UncompressedLength; + UINT8 CompressionType; } EFI_COMPRESSION_SECTION; -typedef struct EFI_COMPRESSION_SECTION_APPLE_ { - UINT32 UncompressedLength; - UINT32 CompressionType; -} EFI_COMPRESSION_SECTION_APPLE; - // Compression types -#define EFI_NOT_COMPRESSED 0x00 -#define EFI_STANDARD_COMPRESSION 0x01 -#define EFI_CUSTOMIZED_COMPRESSION 0x02 +#define EFI_NOT_COMPRESSED 0x00 +#define EFI_STANDARD_COMPRESSION 0x01 +#define EFI_CUSTOMIZED_COMPRESSION 0x02 +#define EFI_CUSTOMIZED_COMPRESSION_LZMAF86 0x86 //GUID defined section typedef struct EFI_GUID_DEFINED_SECTION_ { @@ -433,32 +436,31 @@ typedef struct EFI_GUID_DEFINED_SECTION_ { UINT16 Attributes; } EFI_GUID_DEFINED_SECTION; -typedef struct EFI_GUID_DEFINED_SECTION_APPLE_ { - EFI_GUID SectionDefinitionGuid; - UINT16 DataOffset; - UINT16 Attributes; - UINT32 Reserved; -} EFI_GUID_DEFINED_SECTION_APPLE; - // Attributes for GUID defined section #define EFI_GUIDED_SECTION_PROCESSING_REQUIRED 0x01 #define EFI_GUIDED_SECTION_AUTH_STATUS_VALID 0x02 // GUIDs of GUID-defined sections -const UByteArray EFI_GUIDED_SECTION_CRC32 // FC1BCDB0-7D31-49AA-936A-A4600D9DD083 -("\xB0\xCD\x1B\xFC\x31\x7D\xAA\x49\x93\x6A\xA4\x60\x0D\x9D\xD0\x83", 16); +extern const UByteArray EFI_GUIDED_SECTION_CRC32; // FC1BCDB0-7D31-49AA-936A-A4600D9DD083 +extern const UByteArray EFI_GUIDED_SECTION_TIANO; // A31280AD-481E-41B6-95E8-127F4C984779 +extern const UByteArray EFI_GUIDED_SECTION_LZMA; // EE4E5898-3914-4259-9D6E-DC7BD79403CF +extern const UByteArray EFI_GUIDED_SECTION_LZMA_HP; // 0ED85E23-F253-413F-A03C-901987B04397 +extern const UByteArray EFI_GUIDED_SECTION_LZMA_MS; // BD9921EA-ED91-404A-8B2F-B4D724747C8C +extern const UByteArray EFI_GUIDED_SECTION_LZMAF86; // D42AE6BD-1352-4BFB-909A-CA72A6EAE889 +extern const UByteArray EFI_GUIDED_SECTION_GZIP; // 1D301FE9-BE79-4353-91C2-D23BC959AE0C +extern const UByteArray EFI_GUIDED_SECTION_ZLIB_AMD; // CE3233F5-2CD6-4D87-9152-4A238BB6D1C4 +extern const UByteArray EFI_GUIDED_SECTION_ZLIB_AMD2; // 991EFAC0-E260-416B-A4B8-3B153072B804 +extern const UByteArray EFI_FIRMWARE_CONTENTS_SIGNED_GUID; // 0F9D89E8-9259-4F76-A5AF-0C89E34023DF -const UByteArray EFI_GUIDED_SECTION_TIANO // A31280AD-481E-41B6-95E8-127F4C984779 -("\xAD\x80\x12\xA3\x1E\x48\xB6\x41\x95\xE8\x12\x7F\x4C\x98\x47\x79", 16); +#define WIN_CERT_TYPE_EFI_GUID 0x0EF1 -const UByteArray EFI_GUIDED_SECTION_LZMA // EE4E5898-3914-4259-9D6E-DC7BD79403CF -("\x98\x58\x4E\xEE\x14\x39\x59\x42\x9D\x6E\xDC\x7B\xD7\x94\x03\xCF", 16); - -const UByteArray EFI_FIRMWARE_CONTENTS_SIGNED_GUID // 0F9D89E8-9259-4F76-A5AF-0C89E34023DF -("\xE8\x89\x9D\x0F\x59\x92\x76\x4F\xA5\xAF\x0C\x89\xE3\x40\x23\xDF", 16); - -//#define WIN_CERT_TYPE_PKCS_SIGNED_DATA 0x0002 -#define WIN_CERT_TYPE_EFI_GUID 0x0EF1 +// AMD Zlib-compressed section header +typedef struct EFI_AMD_ZLIB_SECTION_HEADER_ { + UINT8 ZeroHeader[0x14]; + UINT32 CompressedSize; + UINT8 ZeroFooter[0x100 - sizeof(UINT32) - 0x14]; + //UINT8 CompressedData[] +} EFI_AMD_ZLIB_SECTION_HEADER; typedef struct WIN_CERTIFICATE_ { UINT32 Length; @@ -468,25 +470,26 @@ typedef struct WIN_CERTIFICATE_ { } WIN_CERTIFICATE; typedef struct WIN_CERTIFICATE_UEFI_GUID_ { - WIN_CERTIFICATE Header; // Standard WIN_CERTIFICATE - EFI_GUID CertType; // Determines format of CertData - // UINT8 CertData[]; // Certificate data follows + WIN_CERTIFICATE Header; // Standard WIN_CERTIFICATE + EFI_GUID CertType; // Determines format of CertData + // UINT8 CertData[]; // Certificate data follows } WIN_CERTIFICATE_UEFI_GUID; // WIN_CERTIFICATE_UEFI_GUID.CertType -const UByteArray EFI_CERT_TYPE_RSA2048_SHA256_GUID -("\x14\x74\x71\xA7\x16\xC6\x77\x49\x94\x20\x84\x47\x12\xA7\x35\xBF"); +extern const UByteArray EFI_CERT_TYPE_RSA2048_SHA256_GUID; // A7717414-C616-4977-9420-844712A735BF // WIN_CERTIFICATE_UEFI_GUID.CertData -typedef struct EFI_CERT_BLOCK_RSA_2048_SHA256_ { - UINT32 HashType; - UINT8 PublicKey[256]; - UINT8 Signature[256]; -} EFI_CERT_BLOCK_RSA_2048_SHA256; +typedef struct EFI_CERT_BLOCK_RSA2048_SHA256_ { + EFI_GUID HashType; + UINT8 PublicKey[256]; + UINT8 Signature[256]; +} EFI_CERT_BLOCK_RSA2048_SHA256; + +extern const UByteArray EFI_HASH_ALGORITHM_SHA256_GUID; // 51AA59DE-FDF2-4EA3-BC63-875FB7842EE9 // Version section typedef struct EFI_VERSION_SECTION_ { - UINT16 BuildNumber; + UINT16 BuildNumber; } EFI_VERSION_SECTION; // Freeform subtype GUID section @@ -496,11 +499,11 @@ typedef struct EFI_FREEFORM_SUBTYPE_GUID_SECTION_ { // Phoenix SCT and Insyde postcode section typedef struct POSTCODE_SECTION_ { - UINT32 Postcode; + UINT32 Postcode; } POSTCODE_SECTION; //***************************************************************************** -// EFI Dependency Expression +// EFI DXE Dependency Expression //***************************************************************************** #define EFI_DEP_OPCODE_SIZE 1 @@ -531,6 +534,434 @@ typedef struct POSTCODE_SECTION_ { /// #define EFI_DEP_SOR 0x09 +//***************************************************************************** +// X86 Startup AP Data +//***************************************************************************** +#define RECOVERY_STARTUP_AP_DATA_X86_SIZE 0x10 +extern const UByteArray RECOVERY_STARTUP_AP_DATA_X86_64K; +extern const UByteArray RECOVERY_STARTUP_AP_DATA_X86_128K; + +//***************************************************************************** +// X86 Reset Vector Data +//***************************************************************************** +typedef struct X86_RESET_VECTOR_DATA_ { + UINT8 ApEntryVector[8]; // Base: 0xffffffd0 + UINT8 Reserved0[8]; + UINT32 PeiCoreEntryPoint; // Base: 0xffffffe0 + UINT8 Reserved1[12]; + UINT8 ResetVector[8]; // Base: 0xfffffff0 + UINT32 ApStartupSegment; // Base: 0xfffffff8 + UINT32 BootFvBaseAddress; // Base: 0xfffffffc +} X86_RESET_VECTOR_DATA; + +#define X86_RESET_VECTOR_DATA_UNPOPULATED 0x12345678 + +//***************************************************************************** +// IFWI +//***************************************************************************** + +// BPDT +#define BPDT_GREEN_SIGNATURE 0x000055AA +#define BPDT_YELLOW_SIGNATURE 0x00AA55AA + +typedef struct BPDT_HEADER_ { + UINT32 Signature; + UINT16 NumEntries; + UINT8 HeaderVersion; + UINT8 RedundancyFlag; // Reserved zero in version 1 + UINT32 Checksum; + UINT32 IfwiVersion; + UINT16 FitcMajor; + UINT16 FitcMinor; + UINT16 FitcHotfix; + UINT16 FitcBuild; +} BPDT_HEADER; + +#define BPDT_HEADER_VERSION_1 1 +#define BPDT_HEADER_VERSION_2 2 + +typedef struct BPDT_ENTRY_ { + UINT32 Type : 16; + UINT32 SplitSubPartitionFirstPart : 1; + UINT32 SplitSubPartitionSecondPart : 1; + UINT32 CodeSubPartition : 1; + UINT32 UmaCacheable : 1; + UINT32 Reserved: 12; + UINT32 Offset; + UINT32 Size; +} BPDT_ENTRY; + +// https://github.com/platomav/MEAnalyzer/blob/master/MEA.py#L10595 +#define BPDT_ENTRY_TYPE_SMIP 0 +#define BPDT_ENTRY_TYPE_RBEP 1 +#define BPDT_ENTRY_TYPE_FTPR 2 +#define BPDT_ENTRY_TYPE_UCOD 3 +#define BPDT_ENTRY_TYPE_IBBP 4 +#define BPDT_ENTRY_TYPE_S_BPDT 5 +#define BPDT_ENTRY_TYPE_OBBP 6 +#define BPDT_ENTRY_TYPE_NFTP 7 +#define BPDT_ENTRY_TYPE_ISHC 8 +#define BPDT_ENTRY_TYPE_DLMP 9 +#define BPDT_ENTRY_TYPE_UEBP 10 +#define BPDT_ENTRY_TYPE_UTOK 11 +#define BPDT_ENTRY_TYPE_UFS_PHY 12 +#define BPDT_ENTRY_TYPE_UFS_GPP_LUN 13 +#define BPDT_ENTRY_TYPE_PMCP 14 +#define BPDT_ENTRY_TYPE_IUNP 15 +#define BPDT_ENTRY_TYPE_NVMC 16 +#define BPDT_ENTRY_TYPE_UEP 17 +#define BPDT_ENTRY_TYPE_WCOD 18 +#define BPDT_ENTRY_TYPE_LOCL 19 +#define BPDT_ENTRY_TYPE_OEMP 20 +#define BPDT_ENTRY_TYPE_FITC 21 +#define BPDT_ENTRY_TYPE_PAVP 22 +#define BPDT_ENTRY_TYPE_IOMP 23 +#define BPDT_ENTRY_TYPE_XPHY 24 +#define BPDT_ENTRY_TYPE_TBTP 25 +#define BPDT_ENTRY_TYPE_PLTS 26 +#define BPDT_ENTRY_TYPE_RES27 27 +#define BPDT_ENTRY_TYPE_RES28 28 +#define BPDT_ENTRY_TYPE_RES29 29 +#define BPDT_ENTRY_TYPE_RES30 30 +#define BPDT_ENTRY_TYPE_DPHY 31 +#define BPDT_ENTRY_TYPE_PCHC 32 +#define BPDT_ENTRY_TYPE_ISIF 33 +#define BPDT_ENTRY_TYPE_ISIC 34 +#define BPDT_ENTRY_TYPE_HBMI 35 +#define BPDT_ENTRY_TYPE_OMSM 36 +#define BPDT_ENTRY_TYPE_GTGP 37 +#define BPDT_ENTRY_TYPE_MDFI 38 +#define BPDT_ENTRY_TYPE_PUNP 39 +#define BPDT_ENTRY_TYPE_PHYP 40 +#define BPDT_ENTRY_TYPE_SAMF 41 +#define BPDT_ENTRY_TYPE_PPHY 42 +#define BPDT_ENTRY_TYPE_GBST 43 +#define BPDT_ENTRY_TYPE_TCCP 44 +#define BPDT_ENTRY_TYPE_PSEP 45 + +// CPD +#define CPD_SIGNATURE 0x44504324 //$CPD + +typedef struct CPD_REV1_HEADER_ { + UINT32 Signature; + UINT32 NumEntries; + UINT8 HeaderVersion; // 1 + UINT8 EntryVersion; + UINT8 HeaderLength; + UINT8 HeaderChecksum; + UINT8 ShortName[4]; +} CPD_REV1_HEADER; + +typedef struct CPD_REV2_HEADER_ { + UINT32 Signature; + UINT32 NumEntries; + UINT8 HeaderVersion; // 2 + UINT8 EntryVersion; + UINT8 HeaderLength; + UINT8 Reserved; + UINT8 ShortName[4]; + UINT32 Checksum; +} CPD_REV2_HEADER; + +typedef struct CPD_ENTRY_ { + UINT8 EntryName[12]; + struct { + UINT32 Offset : 25; + UINT32 HuffmanCompressed : 1; + UINT32 Reserved : 6; + } Offset; + UINT32 Length; + UINT32 Reserved; +} CPD_ENTRY; + +typedef struct CPD_MANIFEST_HEADER_ { + UINT32 HeaderType; + UINT32 HeaderLength; + UINT32 HeaderVersion; + UINT32 Flags; + UINT32 Vendor; + UINT32 Date; + UINT32 Size; + UINT32 HeaderId; + UINT32 Reserved1; + UINT16 VersionMajor; + UINT16 VersionMinor; + UINT16 VersionBugfix; + UINT16 VersionBuild; + UINT32 SecurityVersion; + UINT8 Reserved2[8]; + UINT8 Reserved3[64]; + UINT32 ModulusSize; + UINT32 ExponentSize; + //manifest_rsa_key_t public_key; + //manifest_signature_t signature; +} CPD_MANIFEST_HEADER; + +typedef struct CPD_EXTENTION_HEADER_ { + UINT32 Type; + UINT32 Length; +} CPD_EXTENTION_HEADER; + +#define CPD_EXT_TYPE_SYSTEM_INFO 0 +#define CPD_EXT_TYPE_INIT_SCRIPT 1 +#define CPD_EXT_TYPE_FEATURE_PERMISSIONS 2 +#define CPD_EXT_TYPE_PARTITION_INFO 3 +#define CPD_EXT_TYPE_SHARED_LIB_ATTRIBUTES 4 +#define CPD_EXT_TYPE_PROCESS_ATTRIBUTES 5 +#define CPD_EXT_TYPE_THREAD_ATTRIBUTES 6 +#define CPD_EXT_TYPE_DEVICE_TYPE 7 +#define CPD_EXT_TYPE_MMIO_RANGE 8 +#define CPD_EXT_TYPE_SPEC_FILE_PRODUCER 9 +#define CPD_EXT_TYPE_MODULE_ATTRIBUTES 10 +#define CPD_EXT_TYPE_LOCKED_RANGES 11 +#define CPD_EXT_TYPE_CLIENT_SYSTEM_INFO 12 +#define CPD_EXT_TYPE_USER_INFO 13 +#define CPD_EXT_TYPE_KEY_MANIFEST 14 +#define CPD_EXT_TYPE_SIGNED_PACKAGE_INFO 15 +#define CPD_EXT_TYPE_ANTI_CLONING_SKU_ID 16 +#define CPD_EXT_TYPE_CAVS 17 +#define CPD_EXT_TYPE_IMR_INFO 18 +#define CPD_EXT_TYPE_BOOT_POLICY 19 +#define CPD_EXT_TYPE_RCIP_INFO 20 +#define CPD_EXT_TYPE_SECURE_TOKEN 21 +#define CPD_EXT_TYPE_IFWI_PARTITION_MANIFEST 22 +#define CPD_EXT_TYPE_FD_HASH 23 +#define CPD_EXT_TYPE_IOM_METADATA 24 +#define CPD_EXT_TYPE_MGP_METADATA 25 +#define CPD_EXT_TYPE_TBT_METADATA 26 +#define CPD_EXT_TYPE_GMF_CERTIFICATE 30 +#define CPD_EXT_TYPE_GMF_BODY 31 +#define CPD_EXT_TYPE_KEY_MANIFEST_EXT 34 +#define CPD_EXT_TYPE_SIGNED_PACKAGE_INFO_EXT 35 +#define CPD_EXT_TYPE_SPS_PLATFORM_ID 50 + +typedef struct CPD_EXT_SIGNED_PACKAGE_INFO_MODULE_ { + UINT8 Name[12]; + UINT8 Type; + UINT8 HashAlgorithm; + UINT16 HashSize; + UINT32 MetadataSize; + // UINT8 MetadataHash[]; with the actual hash size is 32 or 48 bytes +} CPD_EXT_SIGNED_PACKAGE_INFO_MODULE; + +static const size_t CpdExtSignedPkgMetadataHashOffset = sizeof(CPD_EXT_SIGNED_PACKAGE_INFO_MODULE); + +typedef struct CPD_EXT_SIGNED_PACKAGE_INFO_ { + UINT32 ExtensionType; + UINT32 ExtensionLength; + UINT8 PackageName[4]; + UINT32 Vcn; + UINT8 UsageBitmap[16]; + UINT32 Svn; + UINT8 Reserved[16]; + // EXT_SIGNED_PACKAGE_INFO_MODULE Modules[]; +} CPD_EXT_SIGNED_PACKAGE_INFO; + +typedef struct CPD_EXT_MODULE_ATTRIBUTES_ { + UINT32 ExtensionType; + UINT32 ExtensionLength; + UINT32 CompressionType; + UINT32 UncompressedSize; + UINT32 CompressedSize; + UINT32 GlobalModuleId; + // UINT8 ImageHash[]; with the actual hash size is 32 or 48 bytes +} CPD_EXT_MODULE_ATTRIBUTES; + +static const size_t CpdExtModuleImageHashOffset = sizeof(CPD_EXT_MODULE_ATTRIBUTES); + +#define CPD_EXT_MODULE_COMPRESSION_TYPE_UNCOMPRESSED 0 +#define CPD_EXT_MODULE_COMPRESSION_TYPE_HUFFMAN 1 +#define CPD_EXT_MODULE_COMPRESSION_TYPE_LZMA 2 + +typedef struct CPD_EXT_IFWI_PARTITION_MANIFEST_ { + UINT32 ExtensionType; + UINT32 ExtensionLength; + UINT8 PartitionName[4]; + UINT32 CompletePartitionLength; + UINT16 PartitionVersionMinor; + UINT16 PartitionVersionMajor; + UINT32 DataFormatVersion; + UINT32 InstanceId; + UINT32 SupportMultipleInstances : 1; + UINT32 SupportApiVersionBasedUpdate : 1; + UINT32 ActionOnUpdate : 2; + UINT32 ObeyFullUpdateRules : 1; + UINT32 IfrEnableOnly : 1; + UINT32 AllowCrossPointUpdate : 1; + UINT32 AllowCrossHotfixUpdate : 1; + UINT32 PartialUpdateOnly : 1; + UINT32 ReservedFlags : 23; + UINT32 HashAlgorithm : 8; + UINT32 HashSize : 24; + UINT8 CompletePartitionHash[48]; + UINT8 Reserved[4]; +} CPD_EXT_IFWI_PARTITION_MANIFEST; + +//***************************************************************************** +// Protected range +//***************************************************************************** +extern const UByteArray PROTECTED_RANGE_VENDOR_HASH_FILE_GUID_PHOENIX; // 389CC6F2-1EA8-467B-AB8A-78E769AE2A15 + +#define BG_VENDOR_HASH_FILE_SIGNATURE_PHOENIX 0x4C42544853414824ULL // '$HASHTBL' + +extern const UByteArray PROTECTED_RANGE_VENDOR_HASH_FILE_GUID_AMI; // CBC91F44-A4BC-4A5B-8696-703451D0B053 + +typedef struct BG_VENDOR_HASH_FILE_ENTRY +{ + UINT8 Hash[SHA256_HASH_SIZE]; + UINT32 Base; + UINT32 Size; +} PROTECTED_RANGE_VENDOR_HASH_FILE_ENTRY; + +typedef struct PROTECTED_RANGE_VENDOR_HASH_FILE_HEADER_PHOENIX_ +{ + UINT64 Signature; + UINT32 NumEntries; + //BG_VENDOR_HASH_FILE_ENTRY Entries[]; +} PROTECTED_RANGE_VENDOR_HASH_FILE_HEADER_PHOENIX; + +typedef struct PROTECTED_RANGE_VENDOR_HASH_FILE_HEADER_AMI_V1_ +{ + UINT8 Hash[SHA256_HASH_SIZE]; + UINT32 Size; + // Base is derived from flash map, will be detected as root volume with DXE core +} PROTECTED_RANGE_VENDOR_HASH_FILE_HEADER_AMI_V1; + +typedef struct PROTECTED_RANGE_VENDOR_HASH_FILE_HEADER_AMI_V2_ +{ + BG_VENDOR_HASH_FILE_ENTRY Hash0; + BG_VENDOR_HASH_FILE_ENTRY Hash1; +} PROTECTED_RANGE_VENDOR_HASH_FILE_HEADER_AMI_V2; + +typedef struct PROTECTED_RANGE_VENDOR_HASH_FILE_HEADER_AMI_V3_ +{ + UINT8 Hash[SHA256_HASH_SIZE]; + UINT32 FvMainSegmentBase[3]; + UINT32 FvMainSegmentSize[3]; + UINT32 NestedFvBase; + UINT32 NestedFvSize; + UINT8 Reserved[48]; +} PROTECTED_RANGE_VENDOR_HASH_FILE_HEADER_AMI_V3; + +// +// AMI ROM Hole files +// +extern const UByteArray AMI_ROM_HOLE_FILE_GUID_0; // 05CA01FC-0FC1-11DC-9011-00173153EBA8 +extern const UByteArray AMI_ROM_HOLE_FILE_GUID_1; // 05CA01FD-0FC1-11DC-9011-00173153EBA8 +extern const UByteArray AMI_ROM_HOLE_FILE_GUID_2; // 05CA01FE-0FC1-11DC-9011-00173153EBA8 +extern const UByteArray AMI_ROM_HOLE_FILE_GUID_3; // 05CA01FF-0FC1-11DC-9011-00173153EBA8 +extern const UByteArray AMI_ROM_HOLE_FILE_GUID_4; // 05CA0200-0FC1-11DC-9011-00173153EBA8 +extern const UByteArray AMI_ROM_HOLE_FILE_GUID_5; // 05CA0201-0FC1-11DC-9011-00173153EBA8 +extern const UByteArray AMI_ROM_HOLE_FILE_GUID_6; // 05CA0202-0FC1-11DC-9011-00173153EBA8 +extern const UByteArray AMI_ROM_HOLE_FILE_GUID_7; // 05CA0203-0FC1-11DC-9011-00173153EBA8 +extern const UByteArray AMI_ROM_HOLE_FILE_GUID_8; // 05CA0204-0FC1-11DC-9011-00173153EBA8 +extern const UByteArray AMI_ROM_HOLE_FILE_GUID_9; // 05CA0205-0FC1-11DC-9011-00173153EBA8 +extern const UByteArray AMI_ROM_HOLE_FILE_GUID_10; // 05CA0206-0FC1-11DC-9011-00173153EBA8 +extern const UByteArray AMI_ROM_HOLE_FILE_GUID_11; // 05CA0207-0FC1-11DC-9011-00173153EBA8 +extern const UByteArray AMI_ROM_HOLE_FILE_GUID_12; // 05CA0208-0FC1-11DC-9011-00173153EBA8 +extern const UByteArray AMI_ROM_HOLE_FILE_GUID_13; // 05CA0209-0FC1-11DC-9011-00173153EBA8 +extern const UByteArray AMI_ROM_HOLE_FILE_GUID_14; // 05CA020A-0FC1-11DC-9011-00173153EBA8 +extern const UByteArray AMI_ROM_HOLE_FILE_GUID_15; // 05CA020B-0FC1-11DC-9011-00173153EBA8 + +// +// Insyde Flash Device Map +// +#define INSYDE_FLASH_DEVICE_MAP_SIGNATURE 0x4D444648 // HFDM + +typedef struct _INSYDE_FLASH_DEVICE_MAP_HEADER { + UINT32 Signature; + UINT32 Size; + UINT32 DataOffset; + UINT32 EntrySize; + UINT8 EntryFormat; + UINT8 Revision; + UINT8 ExtensionCount; + UINT8 Checksum; + UINT64 FdBaseAddress; +//INSYDE_FLASH_DEVICE_MAP_EXTENSION Extensions[ExtensionCount]; +} INSYDE_FLASH_DEVICE_MAP_HEADER; + +typedef struct _INSYDE_FLASH_DEVICE_MAP_EXTENSION { + UINT16 EntryOffset; + UINT16 EntryCount; +} INSYDE_FLASH_DEVICE_MAP_EXTENSION; + +typedef struct _INSYDE_FLASH_DEVICE_MAP_ENTRY { + EFI_GUID RegionTypeGuid; + UINT8 RegionId[16]; + UINT64 RegionOffset; + UINT64 RegionSize; + UINT32 Attributes; +//UINT8 Hash[]; // Size depends on EntryFormat and EntrySize of the header +} INSYDE_FLASH_DEVICE_MAP_ENTRY; + +typedef struct _INSYDE_FLASH_DEVICE_MAP_BOARD_ID_MAP { + UINT32 BoardIdIndex; + UINT32 BoardIdCount; +//UINT64 BoardIds[Count]; +} INSYDE_FLASH_DEVICE_MAP_BOARD_ID_MAP; + +#define INSYDE_FLASH_DEVICE_MAP_ENTRY_ATTRIBUTE_MODIFIABLE 0x00000001 + +extern const UByteArray INSYDE_FLASH_MAP_REGION_BOOT_FV_GUID; +extern const UByteArray INSYDE_FLASH_MAP_REGION_BVDT_GUID; +extern const UByteArray INSYDE_FLASH_MAP_REGION_EC_GUID; +extern const UByteArray INSYDE_FLASH_MAP_REGION_FTW_BACKUP_GUID; +extern const UByteArray INSYDE_FLASH_MAP_REGION_FTW_STATE_GUID; +extern const UByteArray INSYDE_FLASH_MAP_REGION_FV_GUID; +extern const UByteArray INSYDE_FLASH_MAP_REGION_FLASH_DEVICE_MAP_GUID; +extern const UByteArray INSYDE_FLASH_MAP_REGION_LOGO_GUID; +extern const UByteArray INSYDE_FLASH_MAP_REGION_MICROCODE_GUID; +extern const UByteArray INSYDE_FLASH_MAP_REGION_MSDM_TABLE_GUID; +extern const UByteArray INSYDE_FLASH_MAP_REGION_MULTI_CONFIG_GUID; +extern const UByteArray INSYDE_FLASH_MAP_REGION_VAR_DEFAULT_GUID; +extern const UByteArray INSYDE_FLASH_MAP_REGION_SMBIOS_UPDATE_GUID; +extern const UByteArray INSYDE_FLASH_MAP_REGION_VAR_GUID; +extern const UByteArray INSYDE_FLASH_MAP_REGION_UNKNOWN_GUID; +extern const UByteArray INSYDE_FLASH_MAP_REGION_UNUSED_GUID; +extern const UByteArray INSYDE_FLASH_MAP_REGION_USB_OPTION_ROM_GUID; +extern const UByteArray INSYDE_FLASH_MAP_REGION_DXE_FV_GUID; +extern const UByteArray INSYDE_FLASH_MAP_REGION_PEI_FV_GUID; +extern const UByteArray INSYDE_FLASH_MAP_REGION_UNSIGNED_FV_GUID; + +// +// Dell variables +// +#define DVAR_STORE_SIGNATURE 0x52415644 + +typedef struct _DVAR_STORE_HEADER { + UINT32 Signature; + UINT32 StoreSizeC; + UINT8 FlagsC; + // DVAR_ENTRY Entries[]; +} DVAR_STORE_HEADER; + +typedef struct _DVAR_ENTRY_HEADER { + UINT8 StateC; // Values are stored in 2-complement format, can be converted with (Val = 0xFF - ValC) + UINT8 FlagsC; + UINT8 TypeC; + UINT8 AttributesC; + UINT8 NamespaceIdC; + // The rest is variable depending on Flags and Types + // EFI_GUID NamespaceGuid; + // UINT8 or UINT16 NameId; + // UINT8 or UINT16 DataSize; + // UINT8 Data[DataSize]; +} DVAR_ENTRY_HEADER; + +#define DVAR_ENTRY_STATE_STORING 0x01 +#define DVAR_ENTRY_STATE_STORED 0x05 +#define DVAR_ENTRY_STATE_DELETING 0x15 +#define DVAR_ENTRY_STATE_DELETED 0x55 + +//#define DVAR_ENTRY_FLAG_NAME_UTF8 0x01 // Haven't seen any samples yet, so this is a guesswork for now +#define DVAR_ENTRY_FLAG_NAME_ID 0x02 +#define DVAR_ENTRY_FLAG_NAMESPACE_GUID 0x04 // This kind of variables is used to store namespace guids, the "deleted" state for them is ignored + +#define DVAR_ENTRY_TYPE_NAME_ID_8_DATA_SIZE_8 0x00 // Both NameId and DataSize are UINT8 +#define DVAR_ENTRY_TYPE_NAME_ID_16_DATA_SIZE_8 0x04 // NameId is UINT16, DataSize is UINT8 +#define DVAR_ENTRY_TYPE_NAME_ID_16_DATA_SIZE_16 0x05 // Both NameId and DataSize are UINT16 + // Restore previous packing rules #pragma pack(pop) diff --git a/common/ffsbuilder.cpp b/common/ffsbuilder.cpp index 1b4b9a1..dac3fa5 100644 --- a/common/ffsbuilder.cpp +++ b/common/ffsbuilder.cpp @@ -1,25 +1,46 @@ -/* fssbuilder.cpp - -Copyright (c) 2015, Nikolaj Schlej. All rights reserved. -This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -*/ +/* fssbuilder.cpp + + Copyright (c) 2015, Nikolaj Schlej. All rights reserved. + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + */ #include "ffsbuilder.h" +#include "descriptor.h" +#include "ffs.h" +#include "peimage.h" +#include "utility.h" +#include "nvram.h" + +#include + USTATUS FfsBuilder::erase(const UModelIndex & index, UByteArray & erased) { // Sanity check if (!index.isValid()) return U_INVALID_PARAMETER; - - PARSING_DATA pdata = parsingDataFromUModelIndex(index); - erased.fill(pdata.emptyByte); + + // Try to get emptyByte value from item's parsing data + UINT8 emptyByte = 0xFF; + if (!model->hasEmptyParsingData(index)) { + if (model->type(index) == Types::Volume) { + VOLUME_PARSING_DATA pdata = *(VOLUME_PARSING_DATA*)model->parsingData(index).constData(); + emptyByte = pdata.emptyByte; + } + else if (model->type(index) == Types::File) { + FILE_PARSING_DATA pdata = *(FILE_PARSING_DATA*)model->parsingData(index).constData(); + emptyByte = pdata.emptyByte; + } + } + + erased = UByteArray(model->header(index).size() + model->body(index).size() + model->tail(index).size(), emptyByte); + return U_SUCCESS; } @@ -28,7 +49,7 @@ USTATUS FfsBuilder::build(const UModelIndex & root, UByteArray & image) // Sanity check if (!root.isValid()) return U_INVALID_PARAMETER; - + if (model->type(root) == Types::Capsule) { return buildCapsule(root, image); } @@ -40,7 +61,7 @@ USTATUS FfsBuilder::build(const UModelIndex & root, UByteArray & image) return buildRawArea(root, image); } } - + return U_NOT_IMPLEMENTED; } @@ -49,31 +70,29 @@ USTATUS FfsBuilder::buildCapsule(const UModelIndex & index, UByteArray & capsule // Sanity check if (!index.isValid()) return U_INVALID_PARAMETER; - - // No action required + + // No action if (model->action(index) == Actions::NoAction) { // Use original item data - capsule = model->header(index).append(model->body(index)); + capsule = model->header(index) + model->body(index) + model->tail(index); return U_SUCCESS; } - + // Rebuild or Replace - else if (model->action(index) == Actions::Rebuild - || model->action(index) == Actions::Replace) { + else if (model->action(index) == Actions::Rebuild + || model->action(index) == Actions::Replace) { if (model->rowCount(index)) { // Clear the supplied UByteArray capsule.clear(); - + // Right now there is only one capsule image element supported if (model->rowCount(index) != 1) { - //msg(UString("buildCapsule: building of capsules with %1 elements are not supported, original item data is used").arg(model->rowCount(index)), index); - // Use original item data - capsule = model->header(index).append(model->body(index)); - return U_SUCCESS; + msg(usprintf("buildCapsule: building of capsules with %d items is not yet supported", model->rowCount(index)), index); + return U_NOT_IMPLEMENTED; } // Build image - UModelIndex imageIndex = index.child(0, 0); + UModelIndex imageIndex = index.model()->index(0, 0, index); UByteArray imageData; // Check image type @@ -86,46 +105,44 @@ USTATUS FfsBuilder::buildCapsule(const UModelIndex & index, UByteArray & capsule result = buildRawArea(imageIndex, imageData); } else { - //msg(UString("buildCapsule: unexpected item of subtype %1 can't be processed, original item data is used").arg(model->subtype(imageIndex)), imageIndex); - capsule.append(model->header(imageIndex)).append(model->body(imageIndex)); + msg(UString("buildCapsule: unexpected item subtype ") + itemSubtypeToUString(model->type(imageIndex), model->subtype(imageIndex)), imageIndex); + return U_UNKNOWN_ITEM_TYPE; } // Check build result if (result) { - //msg(UString("buildCapsule: building of \"%1\" failed with error \"%2\", original item data is used").arg(model->name(imageIndex)).arg(errorCodeToUString(result)), imageIndex); - capsule.append(model->header(imageIndex)).append(model->body(imageIndex)); + msg(UString("buildCapsule: building of ") + model->name(imageIndex) + UString(" failed with error ") + errorCodeToUString(result), imageIndex); + return result; } else - capsule.append(imageData); + capsule += imageData; } else { - //msg(UString("buildCapsule: unexpected item of type %1 can't be processed, original item data is used").arg(model->type(imageIndex)), imageIndex); - capsule.append(model->header(imageIndex)).append(model->body(imageIndex)); + msg(UString("buildCapsule: unexpected item type ") + itemTypeToUString(model->type(imageIndex)), imageIndex); + return U_UNKNOWN_ITEM_TYPE; } - // Check size of reconstructed capsule, it must remain the same - UINT32 newSize = capsule.size(); - UINT32 oldSize = model->body(index).size(); + // Check size of reconstructed capsule body, it must remain the same + UINT32 newSize = (UINT32)capsule.size(); + UINT32 oldSize = (UINT32)model->body(index).size(); if (newSize > oldSize) { - //msg(UString("buildCapsule: new capsule body size %1h (%2) is bigger than the original %3h (%4)") - // .hexarg(newSize).arg(newSize).hexarg(oldSize).arg(oldSize),index); - return U_INVALID_PARAMETER; + msg(usprintf("buildCapsule: new capsule size %Xh (%u) is bigger than the original %Xh (%u)", newSize, newSize, oldSize, oldSize), index); + return U_INVALID_CAPSULE; } else if (newSize < oldSize) { - //msg(UString("buildCapsule: new capsule body size %1h (%2) is smaller than the original %3h (%4)") - // .hexarg(newSize).arg(newSize).hexarg(oldSize).arg(oldSize), index); - return U_INVALID_PARAMETER; + msg(usprintf("buildCapsule: new capsule size %Xh (%u) is smaller than the original %Xh (%u)", newSize, newSize, oldSize, oldSize), index); + return U_INVALID_CAPSULE; } } else capsule = model->body(index); - - // Build successful, append header - capsule = model->header(index).append(capsule); + + // Build successful, append header and tail + capsule = model->header(index) + capsule + model->tail(index); return U_SUCCESS; } - - //msg(UString("buildCapsule: unexpected action \"%1\"").arg(actionTypeToQString(model->action(index))), index); + + msg(UString("buildCapsule: unexpected action " + actionTypeToUString(model->action(index))), index); return U_NOT_IMPLEMENTED; } @@ -137,111 +154,124 @@ USTATUS FfsBuilder::buildIntelImage(const UModelIndex & index, UByteArray & inte // No action if (model->action(index) == Actions::NoAction) { - intelImage = model->header(index).append(model->body(index)); + intelImage = model->header(index) + model->body(index) + model->tail(index); + return U_SUCCESS; + } + // Remove + else if (model->action(index) == Actions::Remove) { + intelImage.clear(); return U_SUCCESS; } - // Rebuild else if (model->action(index) == Actions::Rebuild) { - intelImage.clear(); - - // First child will always be descriptor for this type of image, and it's read only - intelImage.append(model->header(index.child(0, 0)).append(model->body(index.child(0, 0)))); + // First child will always be descriptor for this type of image, and it's read only for now + intelImage = model->header(index.model()->index(0, 0, index)) + model->body(index.model()->index(0, 0, index)) + model->tail(index.model()->index(0, 0, index)); // Process other regions for (int i = 1; i < model->rowCount(index); i++) { - UModelIndex currentRegion = index.child(i, 0); - + UModelIndex currentRegion = index.model()->index(i, 0, index); + // Skip regions with Remove action if (model->action(currentRegion) == Actions::Remove) continue; - + // Check item type to be either region or padding UINT8 type = model->type(currentRegion); if (type == Types::Padding) { // Add padding as is - intelImage.append(model->header(currentRegion).append(model->body(currentRegion))); + intelImage += model->header(currentRegion) + model->body(currentRegion) + model->tail(currentRegion); continue; } - + // Check region subtype USTATUS result; UByteArray region; UINT8 regionType = model->subtype(currentRegion); switch (regionType) { - case Subtypes::BiosRegion: - case Subtypes::PdrRegion: - result = buildRawArea(currentRegion, region); - if (result) { - //msg(UString("buildIntelImage: building of %1 region failed with error \"%2\", original item data is used").arg(regionTypeToQString(regionType)).arg(errorCodeToQString(result)), currentRegion); - region = model->header(currentRegion).append(model->body(currentRegion)); - } - break; - case Subtypes::GbeRegion: - case Subtypes::MeRegion: - case Subtypes::EcRegion: - case Subtypes::Reserved1Region: - case Subtypes::Reserved2Region: - case Subtypes::Reserved3Region: - case Subtypes::Reserved4Region: - // Add region as is - region = model->header(currentRegion).append(model->body(currentRegion)); - break; - default: - msg(UString("buildIntelImage: don't know how to build region of unknown type"), index); - return U_UNKNOWN_ITEM_TYPE; + case Subtypes::BiosRegion: + case Subtypes::PdrRegion: + result = buildRawArea(currentRegion, region); + if (result) { + msg(UString("buildIntelImage: building of region ") + regionTypeToUString(regionType) + UString(" failed with error ") + errorCodeToUString(result), currentRegion); + return result; + } + break; + case Subtypes::MeRegion: + case Subtypes::GbeRegion: + case Subtypes::DevExp1Region: + case Subtypes::Bios2Region: + case Subtypes::MicrocodeRegion: + case Subtypes::EcRegion: + case Subtypes::DevExp2Region: + case Subtypes::IeRegion: + case Subtypes::Tgbe1Region: + case Subtypes::Tgbe2Region: + case Subtypes::Reserved1Region: + case Subtypes::Reserved2Region: + case Subtypes::PttRegion: + // Add region as is + region = model->header(currentRegion) + model->body(currentRegion); + break; + default: + msg(UString("buildIntelImage: unknown region type"), currentRegion); + return U_UNKNOWN_ITEM_TYPE; } - + // Append the resulting region - intelImage.append(region); + intelImage += region; } // Check size of new image, it must be same as old one - UINT32 newSize = intelImage.size(); - UINT32 oldSize = model->body(index).size(); + UINT32 newSize = (UINT32)intelImage.size(); + UINT32 oldSize = (UINT32)model->body(index).size(); if (newSize > oldSize) { - //msg(UString("buildIntelImage: new image size %1h (%2) is bigger than the original %3h (%4)") - // .hexarg(newSize).arg(newSize).hexarg(oldSize).arg(oldSize), index); - return U_INVALID_PARAMETER; + msg(usprintf("buildIntelImage: new image size %Xh (%u) is bigger than the original %Xh (%u)", newSize, newSize, oldSize, oldSize), index); + return U_INVALID_IMAGE; } else if (newSize < oldSize) { - //msg(UString("buildIntelImage: new image size %1h (%2) is smaller than the original %3h (%4)") - // .hexarg(newSize).arg(newSize).hexarg(oldSize).arg(oldSize), index); - return U_INVALID_PARAMETER; + msg(usprintf("buildIntelImage: new image size %Xh (%u) is smaller than the original %Xh (%u)", newSize, newSize, oldSize, oldSize), index); + return U_INVALID_IMAGE; } - - // Reconstruction successful + + // Build successful, append header and tail + intelImage = model->header(index) + intelImage + model->tail(index); return U_SUCCESS; } - - //msg(UString("buildIntelImage: unexpected action \"%1\"").arg(actionTypeToQString(model->action(index))), index); + + msg(UString("buildIntelImage: unexpected action " + actionTypeToUString(model->action(index))), index); return U_NOT_IMPLEMENTED; } -USTATUS FfsBuilder::buildRawArea(const UModelIndex & index, UByteArray & rawArea, bool addHeader) +USTATUS FfsBuilder::buildRawArea(const UModelIndex & index, UByteArray & rawArea) { // Sanity check if (!index.isValid()) return U_INVALID_PARAMETER; - + // No action required if (model->action(index) == Actions::NoAction) { - rawArea = model->header(index).append(model->body(index)); + rawArea = model->header(index) + model->body(index) + model->tail(index); + return U_SUCCESS; + } + // Remove + else if (model->action(index) == Actions::Remove) { + rawArea.clear(); return U_SUCCESS; } - // Rebuild or Replace - else if (model->action(index) == Actions::Rebuild - || model->action(index) == Actions::Replace) { + else if (model->action(index) == Actions::Rebuild + || model->action(index) == Actions::Replace) { + // Rebuild if there is at least 1 child if (model->rowCount(index)) { // Clear the supplied UByteArray rawArea.clear(); - + // Build children for (int i = 0; i < model->rowCount(index); i++) { USTATUS result = U_SUCCESS; - UModelIndex currentChild = index.child(i, 0); + UModelIndex currentChild = index.model()->index(i, 0, index); UByteArray currentData; + // Check child type if (model->type(currentChild) == Types::Volume) { result = buildVolume(currentChild, currentData); @@ -250,42 +280,41 @@ USTATUS FfsBuilder::buildRawArea(const UModelIndex & index, UByteArray & rawArea result = buildPadding(currentChild, currentData); } else { - //msg(UString("buildRawArea: unexpected item of type %1 can't be processed, original item data is used").arg(model->type(currentChild)), currentChild); - currentData = model->header(currentChild).append(model->body(currentChild)); + msg(UString("buildRawArea: unexpected item type ") + itemTypeToUString(model->type(currentChild)), currentChild); + return U_UNKNOWN_ITEM_TYPE; } // Check build result if (result) { - //msg(UString("buildRawArea: building of %1 failed with error \"%2\", original item data is used").arg(model->name(currentChild)).arg(errorCodeToQString(result)), currentChild); - currentData = model->header(currentChild).append(model->body(currentChild)); + msg(UString("buildRawArea: building of ") + model->name(currentChild) + UString(" failed with error ") + errorCodeToUString(result), currentChild); + return result; } // Append current data - rawArea.append(currentData); + rawArea += currentData; } - + // Check size of new raw area, it must be same as original one - UINT32 newSize = rawArea.size(); - UINT32 oldSize = model->body(index).size(); + UINT32 newSize = (UINT32)rawArea.size(); + UINT32 oldSize = (UINT32)model->body(index).size(); if (newSize > oldSize) { - //msg(UString("buildRawArea: new area size %1h (%2) is bigger than the original %3h (%4)") - // .hexarg(newSize).arg(newSize).hexarg(oldSize).arg(oldSize), index); - return U_INVALID_PARAMETER; + msg(usprintf("buildRawArea: new area size %Xh (%u) is bigger than the original %Xh (%u)", newSize, newSize, oldSize, oldSize), index); + return U_INVALID_RAW_AREA; } else if (newSize < oldSize) { - //msg(UString("buildRawArea: new area size %1h (%2) is smaller than the original %3h (%4)") - // .hexarg(newSize).arg(newSize).hexarg(oldSize).arg(oldSize), index); - return U_INVALID_PARAMETER; + msg(usprintf("buildRawArea: new area size %Xh (%u) is smaller than the original %Xh (%u)", newSize, newSize, oldSize, oldSize), index); + return U_INVALID_RAW_AREA; } } - else + // No need to rebuild a raw area with no children + else { rawArea = model->body(index); - + } + // Build successful, add header if needed - if (addHeader) - rawArea = model->header(index).append(rawArea); + rawArea = model->header(index) + rawArea + model->tail(index); return U_SUCCESS; } - - //msg(UString("buildRawArea: unexpected action \"%1\"").arg(actionTypeToQString(model->action(index))), index); + + msg(UString("buildRawArea: unexpected action " + actionTypeToUString(model->action(index))), index); return U_NOT_IMPLEMENTED; } @@ -294,22 +323,23 @@ USTATUS FfsBuilder::buildPadding(const UModelIndex & index, UByteArray & padding // Sanity check if (!index.isValid()) return U_INVALID_PARAMETER; - + // No action required if (model->action(index) == Actions::NoAction) { - padding = model->header(index).append(model->body(index)); + padding = model->header(index) + model->body(index) + model->tail(index); + return U_SUCCESS; + } + // Remove + else if (model->action(index) == Actions::Remove) { + padding.clear(); return U_SUCCESS; } - // Erase else if (model->action(index) == Actions::Erase) { - padding = model->header(index).append(model->body(index)); - if(erase(index, padding)) - msg(UString("buildPadding: erase failed, original item data is used"), index); - return U_SUCCESS; + return erase(index, padding); } - - //msg(UString("buildPadding: unexpected action \"%1\"").arg(actionTypeToUString(model->action(index))), index); + + msg(UString("buildPadding: unexpected action " + actionTypeToUString(model->action(index))), index); return U_NOT_IMPLEMENTED; } @@ -318,22 +348,25 @@ USTATUS FfsBuilder::buildNonUefiData(const UModelIndex & index, UByteArray & dat // Sanity check if (!index.isValid()) return U_INVALID_PARAMETER; - + // No action required if (model->action(index) == Actions::NoAction) { - data = model->header(index).append(model->body(index)); + data = model->header(index) + model->body(index) + model->tail(index); + return U_SUCCESS; + } + // Remove + else if (model->action(index) == Actions::Remove) { + data.clear(); return U_SUCCESS; } - // Erase else if (model->action(index) == Actions::Erase) { - data = model->header(index).append(model->body(index)); - if (erase(index, data)) - msg(UString("buildNonUefiData: erase failed, original item data is used"), index); - return U_SUCCESS; + return erase(index, data); } - - //msg(UString("buildNonUefiData: unexpected action \"%1\"").arg(actionTypeToUString(model->action(index))), index); + + // TODO: rebuild properly + + msg(UString("buildNoUefiData: unexpected action " + actionTypeToUString(model->action(index))), index); return U_NOT_IMPLEMENTED; } @@ -342,34 +375,41 @@ USTATUS FfsBuilder::buildFreeSpace(const UModelIndex & index, UByteArray & freeS // Sanity check if (!index.isValid()) return U_INVALID_PARAMETER; - - // No action required - if (model->action(index) == Actions::NoAction) { - freeSpace = model->header(index).append(model->body(index)); - return U_SUCCESS; - } - - //msg(UString("buildFreeSpace: unexpected action \"%1\"").arg(actionTypeToQString(model->action(index))), index); - return U_NOT_IMPLEMENTED; + + // No actions possible for free space + freeSpace = model->header(index) + model->body(index) + model->tail(index); + return U_SUCCESS; } USTATUS FfsBuilder::buildVolume(const UModelIndex & index, UByteArray & volume) { + U_UNUSED_PARAMETER(index); + U_UNUSED_PARAMETER(volume); + return U_NOT_IMPLEMENTED; } USTATUS FfsBuilder::buildPadFile(const UModelIndex & index, UByteArray & padFile) { + U_UNUSED_PARAMETER(index); + U_UNUSED_PARAMETER(padFile); + return U_NOT_IMPLEMENTED; } USTATUS FfsBuilder::buildFile(const UModelIndex & index, UByteArray & file) { + U_UNUSED_PARAMETER(index); + U_UNUSED_PARAMETER(file); + return U_NOT_IMPLEMENTED; } USTATUS FfsBuilder::buildSection(const UModelIndex & index, UByteArray & section) { + U_UNUSED_PARAMETER(index); + U_UNUSED_PARAMETER(section); + return U_NOT_IMPLEMENTED; } diff --git a/common/ffsbuilder.h b/common/ffsbuilder.h index 0669ec2..03dbc62 100644 --- a/common/ffsbuilder.h +++ b/common/ffsbuilder.h @@ -16,14 +16,10 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include +#include "basetypes.h" #include "ubytearray.h" #include "ustring.h" -#include "basetypes.h" #include "treemodel.h" -#include "descriptor.h" -#include "ffs.h" -#include "peimage.h" -#include "utility.h" class FfsBuilder { @@ -45,7 +41,7 @@ private: USTATUS buildCapsule(const UModelIndex & index, UByteArray & capsule); USTATUS buildIntelImage(const UModelIndex & index, UByteArray & intelImage); - USTATUS buildRawArea(const UModelIndex & index, UByteArray & rawArea, bool addHeader = true); + USTATUS buildRawArea(const UModelIndex & index, UByteArray & rawArea); USTATUS buildPadding(const UModelIndex & index, UByteArray & padding); USTATUS buildVolume(const UModelIndex & index, UByteArray & volume); USTATUS buildNonUefiData(const UModelIndex & index, UByteArray & data); diff --git a/common/ffsops.cpp b/common/ffsops.cpp index 27cd0f4..2d6e5be 100644 --- a/common/ffsops.cpp +++ b/common/ffsops.cpp @@ -1,106 +1,70 @@ /* fssops.cpp - -Copyright (c) 2015, Nikolaj Schlej. All rights reserved. -This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -*/ + + Copyright (c) 2015, Nikolaj Schlej. All rights reserved. + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + */ #include "ffsops.h" +#include "ffs.h" +#include "utility.h" USTATUS FfsOperations::extract(const UModelIndex & index, UString & name, UByteArray & extracted, const UINT8 mode) { // Sanity check if (!index.isValid()) return U_INVALID_PARAMETER; - - // Get data from parsing data - PARSING_DATA pdata = parsingDataFromUModelIndex(index); - - // Construct a name for extracted data - UString itemName = model->name(index); - UString itemText = model->text(index); - + // Default name - name = itemName.replace(' ', '_').replace('/', '_').replace('-', '_'); - - switch (model->type(index)) { - case Types::Volume: if (pdata.volume.hasExtendedHeader) name = guidToUString(pdata.volume.extendedHeaderGuid).replace('-', '_'); break; - case Types::NvarEntry: - case Types::VssEntry: - case Types::FsysEntry: - case Types::EvsaEntry: - case Types::FlashMapEntry: - case Types::File: name = itemText.isEmpty() ? itemName : itemText.replace(' ', '_').replace('-', '_'); break; - case Types::Section: { - // Get parent file name - UModelIndex fileIndex = model->findParentOfType(index, Types::File); - UString fileText = model->text(fileIndex); - name = fileText.isEmpty() ? model->name(fileIndex) : fileText.replace(' ', '_').replace('-', '_'); - // Append section subtype name - name += '_' + itemName.replace(' ', '_'); - } break; - } - + name = uniqueItemName(index); + // Get extracted data if (mode == EXTRACT_MODE_AS_IS) { // Extract as is, with header body and tail extracted.clear(); - extracted.append(model->header(index)); - extracted.append(model->body(index)); - extracted.append(model->tail(index)); + extracted += model->header(index); + extracted += model->body(index); + extracted += model->tail(index); } else if (mode == EXTRACT_MODE_BODY) { - name += QObject::tr("_body"); + name += UString("_body"); // Extract without header and tail extracted.clear(); - extracted.append(model->body(index)); + extracted += model->body(index); } else if (mode == EXTRACT_MODE_BODY_UNCOMPRESSED) { - name += QObject::tr("_body_unc"); - // Extract without header and tail, uncompressed + name += UString("_body_uncompressed"); extracted.clear(); - // There is no need to redo decompression, we can use child items - for (int i = 0; i < model->rowCount(index); i++) { - UModelIndex childIndex = index.child(i, 0); - // Ensure 4-byte alignment of current section - extracted.append(UByteArray('\x00', ALIGN4((UINT32)extracted.size()) - (UINT32)extracted.size())); - // Add current section header, body and tail - extracted.append(model->header(childIndex)); - extracted.append(model->body(childIndex)); - extracted.append(model->tail(childIndex)); - } + extracted += model->uncompressedData(index); } else return U_UNKNOWN_EXTRACT_MODE; - + return U_SUCCESS; } -USTATUS FfsOperations::replace(const UModelIndex & index, const UString & data, const UINT8 mode) +USTATUS FfsOperations::replace(const UModelIndex & index, UByteArray & data, const UINT8 mode) { + U_UNUSED_PARAMETER(data); + // Sanity check if (!index.isValid()) return U_INVALID_PARAMETER; - - // Get data from parsing data - //PARSING_DATA pdata = parsingDataFromQModelIndex(index); - + if (mode == REPLACE_MODE_AS_IS) { return U_NOT_IMPLEMENTED; } else if (mode == REPLACE_MODE_BODY) { return U_NOT_IMPLEMENTED; } - else - return U_UNKNOWN_REPLACE_MODE; - return U_NOT_IMPLEMENTED; + return U_UNKNOWN_REPLACE_MODE; } USTATUS FfsOperations::remove(const UModelIndex & index) @@ -108,10 +72,10 @@ USTATUS FfsOperations::remove(const UModelIndex & index) // Sanity check if (!index.isValid()) return U_INVALID_PARAMETER; - + // Set remove action model->setAction(index, Actions::Remove); - + return U_SUCCESS; } @@ -120,20 +84,20 @@ USTATUS FfsOperations::rebuild(const UModelIndex & index) // Sanity check if (!index.isValid()) return U_INVALID_PARAMETER; - + // On insert action, set insert action for children //if (action == Actions::Insert) // for (int i = 0; i < item->childCount(); i++) // setAction(index.child(i, 0), Actions::Insert); - + // Set rebuild action model->setAction(index, Actions::Rebuild); - + // Rebuild parent, if it has no action now UModelIndex parent = index.parent(); if (parent.isValid() && model->type(parent) != Types::Root && model->action(parent) == Actions::NoAction) - rebuild(parent); + rebuild(parent); return U_SUCCESS; } diff --git a/common/ffsops.h b/common/ffsops.h index b9a7862..ee5ae0b 100644 --- a/common/ffsops.h +++ b/common/ffsops.h @@ -16,12 +16,11 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include +#include "basetypes.h" #include "ubytearray.h" #include "ustring.h" -#include "basetypes.h" #include "treemodel.h" -#include "ffs.h" -#include "utility.h" +#include "ffsparser.h" class FfsOperations { @@ -34,13 +33,14 @@ public: void clearMessages() { messagesVector.clear(); } USTATUS extract(const UModelIndex & index, UString & name, UByteArray & extracted, const UINT8 mode); - USTATUS replace(const UModelIndex & index, const UString & data, const UINT8 mode); + USTATUS replace(const UModelIndex & index, UByteArray & data, const UINT8 mode); USTATUS remove(const UModelIndex & index); USTATUS rebuild(const UModelIndex & index); private: - TreeModel* model; + TreeModel * model; + std::vector > messagesVector; void msg(const UString & message, const UModelIndex &index = UModelIndex()) { diff --git a/common/ffsparser.cpp b/common/ffsparser.cpp index 9a1e17d..a1af649 100644 --- a/common/ffsparser.cpp +++ b/common/ffsparser.cpp @@ -1,274 +1,342 @@ /* ffsparser.cpp - -Copyright (c) 2016, Nikolaj Schlej. All rights reserved. -This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -*/ + + Copyright (c) 2018, Nikolaj Schlej. All rights reserved. + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + */ #include "ffsparser.h" #include -#include #include -#include +#include -// Region info structure definition -struct REGION_INFO { - UINT32 offset; - UINT32 length; - UINT8 type; - UByteArray data; - friend bool operator< (const REGION_INFO & lhs, const REGION_INFO & rhs){ return lhs.offset < rhs.offset; } -}; +#include "descriptor.h" +#include "ffs.h" +#include "gbe.h" +#include "me.h" +#include "intel_fit.h" +#include "nvram.h" +#include "peimage.h" +#include "parsingdata.h" +#include "types.h" +#include "utility.h" + +#include "nvramparser.h" +#include "meparser.h" +#include "fitparser.h" + +#include "digest/sha1.h" +#include "digest/sha2.h" +#include "digest/sm3.h" + +#include "umemstream.h" +#include "kaitai/kaitaistream.h" +#include "generated/insyde_fdm.h" + +#ifdef U_ENABLE_NVRAM_PARSING_SUPPORT +#include "generated/dell_dvar.h" +#endif + +// Constructor +FfsParser::FfsParser(TreeModel* treeModel) : model(treeModel), +imageBase(0), addressDiff(0x100000000ULL), protectedRegionsBase(0) { + fitParser = new FitParser(treeModel, this); + nvramParser = new NvramParser(treeModel, this); + meParser = new MeParser(treeModel, this); +} + +// Destructor +FfsParser::~FfsParser() { + delete nvramParser; + delete meParser; + delete fitParser; +} + +// Obtain parser messages +std::vector > FfsParser::getMessages() const { + std::vector > meVector = meParser->getMessages(); + std::vector > nvramVector = nvramParser->getMessages(); + std::vector > fitVector = fitParser->getMessages(); + std::vector > resultVector = messagesVector; + resultVector.insert(resultVector.end(), meVector.begin(), meVector.end()); + resultVector.insert(resultVector.end(), nvramVector.begin(), nvramVector.end());\ + resultVector.insert(resultVector.end(), fitVector.begin(), fitVector.end()); + return resultVector; +} + +// Obtain FIT table from FIT parser +std::vector, UModelIndex> > FfsParser::getFitTable() const +{ + return fitParser->getFitTable(); +} + +// Obtain security info from FIT parser +UString FfsParser::getSecurityInfo() const { + return securityInfo + fitParser->getSecurityInfo(); +} // Firmware image parsing functions -USTATUS FfsParser::parse(const UByteArray & buffer) +USTATUS FfsParser::parse(const UByteArray & buffer) { UModelIndex root; + + // Reset global parser state + openedImage = buffer; + imageBase = 0; + addressDiff = 0x100000000ULL; + protectedRegionsBase = 0; + securityInfo = ""; + protectedRanges.clear(); + lastVtf = UModelIndex(); + dxeCore = UModelIndex(); + + // Parse input buffer USTATUS result = performFirstPass(buffer, root); - addOffsetsRecursive(root); - if (result) - return result; - - if (lastVtf.isValid()) - result = performSecondPass(root); - else - msg(("parse: not a single Volume Top File is found, the image may be corrupted")); - + if (result == U_SUCCESS) { + if (lastVtf.isValid()) { + result = performSecondPass(root); + } + else { + msg(usprintf("%s: not a single Volume Top File is found, the image may be corrupted", __FUNCTION__)); + } + } + + addInfoRecursive(root); return result; } USTATUS FfsParser::performFirstPass(const UByteArray & buffer, UModelIndex & index) { - // Reset capsule offset fixup value - capsuleOffsetFixup = 0; - - // Check buffer size to be more than or equal to size of EFI_CAPSULE_HEADER - if ((UINT32)buffer.size() <= sizeof(EFI_CAPSULE_HEADER)) { - msg(UString("performFirstPass: image file is smaller than minimum size of 1Ch (28) bytes")); + // Sanity check + if (buffer.isEmpty()) { return U_INVALID_PARAMETER; } - - UINT32 capsuleHeaderSize = 0; - // Check buffer for being normal EFI capsule header - if (buffer.startsWith(EFI_CAPSULE_GUID) - || buffer.startsWith(INTEL_CAPSULE_GUID) - || buffer.startsWith(LENOVO_CAPSULE_GUID) - || buffer.startsWith(LENOVO2_CAPSULE_GUID)) { - // Get info - const EFI_CAPSULE_HEADER* capsuleHeader = (const EFI_CAPSULE_HEADER*)buffer.constData(); - - // Check sanity of HeaderSize and CapsuleImageSize values - if (capsuleHeader->HeaderSize == 0 || capsuleHeader->HeaderSize > (UINT32)buffer.size() || capsuleHeader->HeaderSize > capsuleHeader->CapsuleImageSize) { - msg(usprintf("performFirstPass: UEFI capsule header size of %Xh (%u) bytes is invalid", - capsuleHeader->HeaderSize, - capsuleHeader->HeaderSize)); - return U_INVALID_CAPSULE; - } - if (capsuleHeader->CapsuleImageSize == 0 || capsuleHeader->CapsuleImageSize > (UINT32)buffer.size()) { - msg(usprintf("performFirstPass: UEFI capsule image size of %Xh (%u) bytes is invalid", - capsuleHeader->CapsuleImageSize, - capsuleHeader->CapsuleImageSize)); - return U_INVALID_CAPSULE; - } - - capsuleHeaderSize = capsuleHeader->HeaderSize; - UByteArray header = buffer.left(capsuleHeaderSize); - UByteArray body = buffer.mid(capsuleHeaderSize); - UString name("UEFI capsule"); - UString info = UString("Capsule GUID: ") + guidToUString(capsuleHeader->CapsuleGuid) + - usprintf("\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nImage size: %Xh (%u)\nFlags: %08Xh", - buffer.size(), buffer.size(), - capsuleHeaderSize, capsuleHeaderSize, - capsuleHeader->CapsuleImageSize - capsuleHeaderSize, capsuleHeader->CapsuleImageSize - capsuleHeaderSize, - capsuleHeader->Flags); - - // Set capsule offset fixup for correct volume allignment warnings - capsuleOffsetFixup = capsuleHeaderSize; - - // Add tree item - index = model->addItem(Types::Capsule, Subtypes::UefiCapsule, name, UString(), info, header, body, UByteArray(), true); + + // Try parsing as UEFI Capsule + if (U_SUCCESS == parseCapsule(buffer, 0, UModelIndex(), index)) { + return U_SUCCESS; } - // Check buffer for being Toshiba capsule header - else if (buffer.startsWith(TOSHIBA_CAPSULE_GUID)) { - // Get info - const TOSHIBA_CAPSULE_HEADER* capsuleHeader = (const TOSHIBA_CAPSULE_HEADER*)buffer.constData(); - - // Check sanity of HeaderSize and FullSize values - if (capsuleHeader->HeaderSize == 0 || capsuleHeader->HeaderSize > (UINT32)buffer.size() || capsuleHeader->HeaderSize > capsuleHeader->FullSize) { - msg(usprintf("performFirstPass: Toshiba capsule header size of %Xh (%u) bytes is invalid", - capsuleHeader->HeaderSize, capsuleHeader->HeaderSize)); - return U_INVALID_CAPSULE; - } - if (capsuleHeader->FullSize == 0 || capsuleHeader->FullSize > (UINT32)buffer.size()) { - msg(usprintf("performFirstPass: Toshiba capsule full size of %Xh (%u) bytes is invalid", - capsuleHeader->FullSize, capsuleHeader->FullSize)); - return U_INVALID_CAPSULE; - } - - capsuleHeaderSize = capsuleHeader->HeaderSize; - UByteArray header = buffer.left(capsuleHeaderSize); - UByteArray body = buffer.mid(capsuleHeaderSize); - UString name("Toshiba capsule"); - UString info = UString("Capsule GUID: ") + guidToUString(capsuleHeader->CapsuleGuid) + - usprintf("\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nImage size: %Xh (%u)\nFlags: %08Xh", - buffer.size(), buffer.size(), - capsuleHeaderSize, capsuleHeaderSize, - capsuleHeader->FullSize - capsuleHeaderSize, capsuleHeader->FullSize - capsuleHeaderSize, - capsuleHeader->Flags); - - // Set capsule offset fixup for correct volume allignment warnings - capsuleOffsetFixup = capsuleHeaderSize; - - // Add tree item - index = model->addItem(Types::Capsule, Subtypes::ToshibaCapsule, name, UString(), info, header, body, UByteArray(), true); + + // Try parsing as Intel image + if (U_SUCCESS == parseIntelImage(buffer, 0, UModelIndex(), index)) { + return U_SUCCESS; } - // Check buffer for being extended Aptio capsule header - else if (buffer.startsWith(APTIO_SIGNED_CAPSULE_GUID) || buffer.startsWith(APTIO_UNSIGNED_CAPSULE_GUID)) { - bool signedCapsule = buffer.startsWith(APTIO_SIGNED_CAPSULE_GUID); - - if ((UINT32)buffer.size() <= sizeof(APTIO_CAPSULE_HEADER)) { - msg(UString("performFirstPass: AMI capsule image file is smaller than minimum size of 20h (32) bytes")); - return U_INVALID_PARAMETER; - } - - // Get info - const APTIO_CAPSULE_HEADER* capsuleHeader = (const APTIO_CAPSULE_HEADER*)buffer.constData(); - - // Check sanity of RomImageOffset and CapsuleImageSize values - if (capsuleHeader->RomImageOffset == 0 || capsuleHeader->RomImageOffset > (UINT32)buffer.size() || capsuleHeader->RomImageOffset > capsuleHeader->CapsuleHeader.CapsuleImageSize) { - msg(usprintf("performFirstPass: AMI capsule image offset of %Xh (%u) bytes is invalid", - capsuleHeader->RomImageOffset, capsuleHeader->RomImageOffset)); - return U_INVALID_CAPSULE; - } - if (capsuleHeader->CapsuleHeader.CapsuleImageSize == 0 || capsuleHeader->CapsuleHeader.CapsuleImageSize > (UINT32)buffer.size()) { - msg(usprintf("performFirstPass: AMI capsule image size of %Xh (%u) bytes is invalid", - capsuleHeader->CapsuleHeader.CapsuleImageSize, - capsuleHeader->CapsuleHeader.CapsuleImageSize)); - return U_INVALID_CAPSULE; - } - - capsuleHeaderSize = capsuleHeader->RomImageOffset; - UByteArray header = buffer.left(capsuleHeaderSize); - UByteArray body = buffer.mid(capsuleHeaderSize); - UString name("AMI Aptio capsule"); - UString info = UString("Capsule GUID: ") + guidToUString(capsuleHeader->CapsuleHeader.CapsuleGuid) + - usprintf("\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nImage size: %Xh (%u)\nFlags: %08Xh", - buffer.size(), buffer.size(), - capsuleHeaderSize, capsuleHeaderSize, - capsuleHeader->CapsuleHeader.CapsuleImageSize - capsuleHeaderSize, capsuleHeader->CapsuleHeader.CapsuleImageSize - capsuleHeaderSize, - capsuleHeader->CapsuleHeader.Flags); - - // Set capsule offset fixup for correct volume allignment warnings - capsuleOffsetFixup = capsuleHeaderSize; - - // Add tree item - index = model->addItem(Types::Capsule, signedCapsule ? Subtypes::AptioSignedCapsule : Subtypes::AptioUnsignedCapsule, name, UString(), info, header, body, UByteArray(), true); - - // Show message about possible Aptio signature break - if (signedCapsule) { - msg(UString("performFirstPass: Aptio capsule signature may become invalid after image modifications"), index); - } - } - - // Skip capsule header to have flash chip image - UByteArray flashImage = buffer.mid(capsuleHeaderSize); - - // Check for Intel flash descriptor presence - const FLASH_DESCRIPTOR_HEADER* descriptorHeader = (const FLASH_DESCRIPTOR_HEADER*)flashImage.constData(); - - // Check descriptor signature - USTATUS result; - if (descriptorHeader->Signature == FLASH_DESCRIPTOR_SIGNATURE) { - // Parse as Intel image - UModelIndex imageIndex; - result = parseIntelImage(flashImage, capsuleHeaderSize, index, imageIndex); - if (result != U_INVALID_FLASH_DESCRIPTOR) { - if (!index.isValid()) - index = imageIndex; - return result; - } - } - - // Get info - UString name("UEFI image"); - UString info = usprintf("Full size: %Xh (%u)", flashImage.size(), flashImage.size()); - - // Construct parsing data - PARSING_DATA pdata = parsingDataFromUModelIndex(index); - pdata.offset = capsuleHeaderSize; - - // Add tree item - UModelIndex biosIndex = model->addItem(Types::Image, Subtypes::UefiImage, name, UString(), info, UByteArray(), flashImage, UByteArray(), true, parsingDataToUByteArray(pdata), index); - - // Parse the image - result = parseRawArea(biosIndex); - if (!index.isValid()) - index = biosIndex; - return result; + + // Parse as generic image + return parseGenericImage(buffer, 0, UModelIndex(), index); } -USTATUS FfsParser::parseIntelImage(const UByteArray & intelImage, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index) +USTATUS FfsParser::parseGenericImage(const UByteArray & buffer, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index) { - // Sanity check - if (intelImage.isEmpty()) - return EFI_INVALID_PARAMETER; + // Parse as generic UEFI image + UString name("UEFI image"); + UString info = usprintf("Full size: %Xh (%u)", (UINT32)buffer.size(), (UINT32)buffer.size()); + + // Add tree item + index = model->addItem(localOffset, Types::Image, Subtypes::UefiImage, name, UString(), info, UByteArray(), buffer, UByteArray(), Fixed, parent); + + // Parse the image as raw area + imageBase = model->base(parent) + localOffset; + protectedRegionsBase = imageBase; + return parseRawArea(index); +} - // Get parent's parsing data - PARSING_DATA pdata = parsingDataFromUModelIndex(parent); - - // Store the beginning of descriptor as descriptor base address - const UINT8* descriptor = (const UINT8*)intelImage.constData(); +USTATUS FfsParser::parseCapsule(const UByteArray & capsule, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index) +{ + // Check buffer size to be more than or equal to size of EFI_CAPSULE_HEADER + if ((UINT32)capsule.size() < sizeof(EFI_CAPSULE_HEADER)) { + return U_ITEM_NOT_FOUND; + } + + UINT32 capsuleHeaderSize = 0; + // Check buffer for being normal EFI capsule header + if (capsule.startsWith(EFI_CAPSULE_GUID) + || capsule.startsWith(EFI_FMP_CAPSULE_GUID) + || capsule.startsWith(INTEL_CAPSULE_GUID) + || capsule.startsWith(LENOVO_CAPSULE_GUID) + || capsule.startsWith(LENOVO2_CAPSULE_GUID)) { + // Get info + const EFI_CAPSULE_HEADER* capsuleHeader = (const EFI_CAPSULE_HEADER*)capsule.constData(); + + // Check sanity of HeaderSize and CapsuleImageSize values + if (capsuleHeader->HeaderSize == 0 || capsuleHeader->HeaderSize > (UINT32)capsule.size() + || capsuleHeader->HeaderSize > capsuleHeader->CapsuleImageSize) { + msg(usprintf("%s: UEFI capsule header size of %Xh (%u) bytes is invalid", __FUNCTION__, + capsuleHeader->HeaderSize, + capsuleHeader->HeaderSize)); + return U_INVALID_CAPSULE; + } + if (capsuleHeader->CapsuleImageSize > (UINT32)capsule.size()) { + msg(usprintf("%s: UEFI capsule image size of %Xh (%u) bytes is invalid", __FUNCTION__, + capsuleHeader->CapsuleImageSize, + capsuleHeader->CapsuleImageSize)); + return U_INVALID_CAPSULE; + } + + capsuleHeaderSize = capsuleHeader->HeaderSize; + UByteArray header = capsule.left(capsuleHeaderSize); + UByteArray body = capsule.mid(capsuleHeaderSize); + UString name("UEFI capsule"); + UString info = UString("Capsule GUID: ") + guidToUString(capsuleHeader->CapsuleGuid, false) + + usprintf("\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nImage size: %Xh (%u)\nFlags: %08Xh", + (UINT32)capsule.size(), (UINT32)capsule.size(), + capsuleHeaderSize, capsuleHeaderSize, + capsuleHeader->CapsuleImageSize - capsuleHeaderSize, capsuleHeader->CapsuleImageSize - capsuleHeaderSize, + capsuleHeader->Flags); + + // Add tree item + index = model->addItem(localOffset, Types::Capsule, Subtypes::UefiCapsule, name, UString(), info, header, body, UByteArray(), Fixed, parent); + } + // Check buffer for being Toshiba capsule header + else if (capsule.startsWith(TOSHIBA_CAPSULE_GUID)) { + // Get info + const TOSHIBA_CAPSULE_HEADER* capsuleHeader = (const TOSHIBA_CAPSULE_HEADER*)capsule.constData(); + + // Check sanity of HeaderSize and FullSize values + if (capsuleHeader->HeaderSize == 0 || capsuleHeader->HeaderSize > (UINT32)capsule.size() + || capsuleHeader->HeaderSize > capsuleHeader->FullSize) { + msg(usprintf("%s: Toshiba capsule header size of %Xh (%u) bytes is invalid", __FUNCTION__, + capsuleHeader->HeaderSize, capsuleHeader->HeaderSize)); + return U_INVALID_CAPSULE; + } + if (capsuleHeader->FullSize > (UINT32)capsule.size()) { + msg(usprintf("%s: Toshiba capsule full size of %Xh (%u) bytes is invalid", __FUNCTION__, + capsuleHeader->FullSize, capsuleHeader->FullSize)); + return U_INVALID_CAPSULE; + } + + capsuleHeaderSize = capsuleHeader->HeaderSize; + UByteArray header = capsule.left(capsuleHeaderSize); + UByteArray body = capsule.mid(capsuleHeaderSize); + UString name("Toshiba capsule"); + UString info = UString("Capsule GUID: ") + guidToUString(capsuleHeader->CapsuleGuid, false) + + usprintf("\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nImage size: %Xh (%u)\nFlags: %08Xh", + (UINT32)capsule.size(), (UINT32)capsule.size(), + capsuleHeaderSize, capsuleHeaderSize, + capsuleHeader->FullSize - capsuleHeaderSize, capsuleHeader->FullSize - capsuleHeaderSize, + capsuleHeader->Flags); + + // Add tree item + index = model->addItem(localOffset, Types::Capsule, Subtypes::ToshibaCapsule, name, UString(), info, header, body, UByteArray(), Fixed, parent); + } + // Check buffer for being extended Aptio capsule header + else if (capsule.startsWith(APTIO_SIGNED_CAPSULE_GUID) + || capsule.startsWith(APTIO_UNSIGNED_CAPSULE_GUID)) { + bool signedCapsule = capsule.startsWith(APTIO_SIGNED_CAPSULE_GUID); + + if ((UINT32)capsule.size() <= sizeof(APTIO_CAPSULE_HEADER)) { + msg(usprintf("%s: AMI capsule image file is smaller than minimum size of 20h (32) bytes", __FUNCTION__)); + return U_INVALID_CAPSULE; + } + + // Get info + const APTIO_CAPSULE_HEADER* capsuleHeader = (const APTIO_CAPSULE_HEADER*)capsule.constData(); + + // Check sanity of RomImageOffset and CapsuleImageSize values + if (capsuleHeader->RomImageOffset == 0 || capsuleHeader->RomImageOffset > (UINT32)capsule.size() + || capsuleHeader->RomImageOffset > capsuleHeader->CapsuleHeader.CapsuleImageSize) { + msg(usprintf("%s: AMI capsule image offset of %Xh (%u) bytes is invalid", __FUNCTION__, + capsuleHeader->RomImageOffset, capsuleHeader->RomImageOffset)); + return U_INVALID_CAPSULE; + } + if (capsuleHeader->CapsuleHeader.CapsuleImageSize > (UINT32)capsule.size()) { + msg(usprintf("%s: AMI capsule image size of %Xh (%u) bytes is invalid", __FUNCTION__, + capsuleHeader->CapsuleHeader.CapsuleImageSize, + capsuleHeader->CapsuleHeader.CapsuleImageSize)); + return U_INVALID_CAPSULE; + } + + capsuleHeaderSize = capsuleHeader->RomImageOffset; + UByteArray header = capsule.left(capsuleHeaderSize); + UByteArray body = capsule.mid(capsuleHeaderSize); + UString name("AMI Aptio capsule"); + UString info = UString("Capsule GUID: ") + guidToUString(capsuleHeader->CapsuleHeader.CapsuleGuid, false) + + usprintf("\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nImage size: %Xh (%u)\nFlags: %08Xh", + (UINT32)capsule.size(), (UINT32)capsule.size(), + capsuleHeaderSize, capsuleHeaderSize, + capsuleHeader->CapsuleHeader.CapsuleImageSize - capsuleHeaderSize, capsuleHeader->CapsuleHeader.CapsuleImageSize - capsuleHeaderSize, + capsuleHeader->CapsuleHeader.Flags); + + // Add tree item + index = model->addItem(localOffset, Types::Capsule, signedCapsule ? Subtypes::AptioSignedCapsule : Subtypes::AptioUnsignedCapsule, name, UString(), info, header, body, UByteArray(), Fixed, parent); + + // Show message about possible Aptio signature break + if (signedCapsule) { + msg(usprintf("%s: Aptio capsule signature may become invalid after image modifications", __FUNCTION__), index); + } + } + + // Capsule present + if (capsuleHeaderSize > 0) { + UByteArray image = capsule.mid(capsuleHeaderSize); + UModelIndex imageIndex; + + // Try parsing as Intel image + if (U_SUCCESS == parseIntelImage(image, capsuleHeaderSize, index, imageIndex)) { + return U_SUCCESS; + } + + // Parse as generic image + return parseGenericImage(image, capsuleHeaderSize, index, imageIndex); + } + + return U_ITEM_NOT_FOUND; +} +USTATUS FfsParser::parseIntelImage(const UByteArray & intelImage, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index) +{ // Check for buffer size to be greater or equal to descriptor region size if (intelImage.size() < FLASH_DESCRIPTOR_SIZE) { - msg(usprintf("parseIntelImage: input file is smaller than minimum descriptor size of %Xh (%u) bytes", FLASH_DESCRIPTOR_SIZE, FLASH_DESCRIPTOR_SIZE)); - return U_INVALID_FLASH_DESCRIPTOR; + msg(usprintf("%s: input file is smaller than minimum descriptor size of %Xh (%u) bytes", __FUNCTION__, FLASH_DESCRIPTOR_SIZE, FLASH_DESCRIPTOR_SIZE)); + return U_ITEM_NOT_FOUND; } - + + // Store the beginning of descriptor as descriptor base address + const FLASH_DESCRIPTOR_HEADER* descriptor = (const FLASH_DESCRIPTOR_HEADER*)intelImage.constData(); + + // Check descriptor signature + if (descriptor->Signature != FLASH_DESCRIPTOR_SIGNATURE) { + return U_ITEM_NOT_FOUND; + } + // Parse descriptor map - const FLASH_DESCRIPTOR_MAP* descriptorMap = (const FLASH_DESCRIPTOR_MAP*)(descriptor + sizeof(FLASH_DESCRIPTOR_HEADER)); - const FLASH_DESCRIPTOR_UPPER_MAP* upperMap = (const FLASH_DESCRIPTOR_UPPER_MAP*)(descriptor + FLASH_DESCRIPTOR_UPPER_MAP_BASE); - + const FLASH_DESCRIPTOR_MAP* descriptorMap = (const FLASH_DESCRIPTOR_MAP*)((UINT8*)descriptor + sizeof(FLASH_DESCRIPTOR_HEADER)); + const FLASH_DESCRIPTOR_UPPER_MAP* upperMap = (const FLASH_DESCRIPTOR_UPPER_MAP*)((UINT8*)descriptor + FLASH_DESCRIPTOR_UPPER_MAP_BASE); + // Check sanity of base values if (descriptorMap->MasterBase > FLASH_DESCRIPTOR_MAX_BASE || descriptorMap->MasterBase == descriptorMap->RegionBase || descriptorMap->MasterBase == descriptorMap->ComponentBase) { - msg(usprintf("parseIntelImage: invalid descriptor master base %02Xh", descriptorMap->MasterBase)); + msg(usprintf("%s: invalid descriptor master base %02Xh", __FUNCTION__, descriptorMap->MasterBase)); return U_INVALID_FLASH_DESCRIPTOR; } if (descriptorMap->RegionBase > FLASH_DESCRIPTOR_MAX_BASE || descriptorMap->RegionBase == descriptorMap->ComponentBase) { - msg(usprintf("parseIntelImage: invalid descriptor region base %02Xh", descriptorMap->RegionBase)); + msg(usprintf("%s: invalid descriptor region base %02Xh", __FUNCTION__, descriptorMap->RegionBase)); return U_INVALID_FLASH_DESCRIPTOR; } if (descriptorMap->ComponentBase > FLASH_DESCRIPTOR_MAX_BASE) { - msg(usprintf("parseIntelImage: invalid descriptor component base %02Xh", descriptorMap->ComponentBase)); + msg(usprintf("%s: invalid descriptor component base %02Xh", __FUNCTION__, descriptorMap->ComponentBase)); return U_INVALID_FLASH_DESCRIPTOR; } - - const FLASH_DESCRIPTOR_REGION_SECTION* regionSection = (const FLASH_DESCRIPTOR_REGION_SECTION*)calculateAddress8(descriptor, descriptorMap->RegionBase); - const FLASH_DESCRIPTOR_COMPONENT_SECTION* componentSection = (const FLASH_DESCRIPTOR_COMPONENT_SECTION*)calculateAddress8(descriptor, descriptorMap->ComponentBase); - - // Check descriptor version by getting hardcoded value of FlashParameters.ReadClockFrequency - UINT8 descriptorVersion = 0; - if (componentSection->FlashParameters.ReadClockFrequency == FLASH_FREQUENCY_20MHZ) // Old descriptor + + const FLASH_DESCRIPTOR_REGION_SECTION* regionSection = (const FLASH_DESCRIPTOR_REGION_SECTION*)calculateAddress8((UINT8*)descriptor, descriptorMap->RegionBase); + const FLASH_DESCRIPTOR_COMPONENT_SECTION* componentSection = (const FLASH_DESCRIPTOR_COMPONENT_SECTION*)calculateAddress8((UINT8*)descriptor, descriptorMap->ComponentBase); + + UINT8 descriptorVersion = 2; + // Check descriptor version by getting hardcoded value of zero in FlashParameters.ReadClockFrequency + if (componentSection->FlashParameters.ReadClockFrequency == 0) descriptorVersion = 1; - else if (componentSection->FlashParameters.ReadClockFrequency == FLASH_FREQUENCY_17MHZ) // Skylake+ descriptor - descriptorVersion = 2; - else { - msg(usprintf("parseIntelImage: unknown descriptor version with ReadClockFrequency %02Xh", componentSection->FlashParameters.ReadClockFrequency)); - return U_INVALID_FLASH_DESCRIPTOR; - } - + // Regions std::vector regions; - + // ME region REGION_INFO me; me.type = Subtypes::MeRegion; @@ -277,145 +345,96 @@ USTATUS FfsParser::parseIntelImage(const UByteArray & intelImage, const UINT32 p if (regionSection->MeLimit) { me.offset = calculateRegionOffset(regionSection->MeBase); me.length = calculateRegionSize(regionSection->MeBase, regionSection->MeLimit); + if ((UINT32)intelImage.size() < me.offset + me.length) { + msg(usprintf("%s: ", __FUNCTION__) + + itemSubtypeToUString(Types::Region, me.type) + + UString(" region is located outside of the opened image. If your system uses dual-chip storage, please append another part to the opened image"), + index); + return U_TRUNCATED_IMAGE; + } me.data = intelImage.mid(me.offset, me.length); regions.push_back(me); } - + // BIOS region - REGION_INFO bios; - bios.type = Subtypes::BiosRegion; - bios.offset = 0; - bios.length = 0; if (regionSection->BiosLimit) { + REGION_INFO bios; + bios.type = Subtypes::BiosRegion; bios.offset = calculateRegionOffset(regionSection->BiosBase); bios.length = calculateRegionSize(regionSection->BiosBase, regionSection->BiosLimit); - + // Check for Gigabyte specific descriptor map if (bios.length == (UINT32)intelImage.size()) { if (!me.offset) { - msg(("parseIntelImage: can't determine BIOS region start from Gigabyte-specific descriptor")); + msg(usprintf("%s: can't determine BIOS region start from Gigabyte-specific descriptor", __FUNCTION__)); return U_INVALID_FLASH_DESCRIPTOR; } // Use ME region end as BIOS region offset bios.offset = me.offset + me.length; bios.length = (UINT32)intelImage.size() - bios.offset; - bios.data = intelImage.mid(bios.offset, bios.length); - } - // Normal descriptor map - else { - bios.data = intelImage.mid(bios.offset, bios.length); } + if ((UINT32)intelImage.size() < bios.offset + bios.length) { + msg(usprintf("%s: ", __FUNCTION__) + + itemSubtypeToUString(Types::Region, bios.type) + + UString(" region is located outside of the opened image. If your system uses dual-chip storage, please append another part to the opened image"), + index); + return U_TRUNCATED_IMAGE; + } + bios.data = intelImage.mid(bios.offset, bios.length); regions.push_back(bios); } else { - msg(("parseIntelImage: descriptor parsing failed, BIOS region not found in descriptor")); + msg(usprintf("%s: descriptor parsing failed, BIOS region not found in descriptor", __FUNCTION__)); return U_INVALID_FLASH_DESCRIPTOR; } - - // GbE region - REGION_INFO gbe; - gbe.type = Subtypes::GbeRegion; - gbe.offset = 0; - gbe.length = 0; - if (regionSection->GbeLimit) { - gbe.offset = calculateRegionOffset(regionSection->GbeBase); - gbe.length = calculateRegionSize(regionSection->GbeBase, regionSection->GbeLimit); - gbe.data = intelImage.mid(gbe.offset, gbe.length); - regions.push_back(gbe); - } - - // PDR region - REGION_INFO pdr; - pdr.type = Subtypes::PdrRegion; - pdr.offset = 0; - pdr.length = 0; - if (regionSection->PdrLimit) { - pdr.offset = calculateRegionOffset(regionSection->PdrBase); - pdr.length = calculateRegionSize(regionSection->PdrBase, regionSection->PdrLimit); - pdr.data = intelImage.mid(pdr.offset, pdr.length); - regions.push_back(pdr); - } - - // Reserved1 region - REGION_INFO reserved1; - reserved1.type = Subtypes::Reserved1Region; - reserved1.offset = 0; - reserved1.length = 0; - if (regionSection->Reserved1Limit && regionSection->Reserved1Base != 0xFFFF && regionSection->Reserved1Limit != 0xFFFF) { - reserved1.offset = calculateRegionOffset(regionSection->Reserved1Base); - reserved1.length = calculateRegionSize(regionSection->Reserved1Base, regionSection->Reserved1Limit); - reserved1.data = intelImage.mid(reserved1.offset, reserved1.length); - regions.push_back(reserved1); - } - - // Reserved2 region - REGION_INFO reserved2; - reserved2.type = Subtypes::Reserved2Region; - reserved2.offset = 0; - reserved2.length = 0; - if (regionSection->Reserved2Limit && regionSection->Reserved2Base != 0xFFFF && regionSection->Reserved2Limit != 0xFFFF) { - reserved2.offset = calculateRegionOffset(regionSection->Reserved2Base); - reserved2.length = calculateRegionSize(regionSection->Reserved2Base, regionSection->Reserved2Limit); - reserved2.data = intelImage.mid(reserved2.offset, reserved2.length); - regions.push_back(reserved2); - } - - // Reserved3 region - REGION_INFO reserved3; - reserved3.type = Subtypes::Reserved3Region; - reserved3.offset = 0; - reserved3.length = 0; - - // EC region - REGION_INFO ec; - ec.type = Subtypes::EcRegion; - ec.offset = 0; - ec.length = 0; - - // Reserved4 region - REGION_INFO reserved4; - reserved3.type = Subtypes::Reserved4Region; - reserved4.offset = 0; - reserved4.length = 0; - - // Check for EC and reserved region 4 only for v2 descriptor - if (descriptorVersion == 2) { - if (regionSection->Reserved3Limit) { - reserved3.offset = calculateRegionOffset(regionSection->Reserved3Base); - reserved3.length = calculateRegionSize(regionSection->Reserved3Base, regionSection->Reserved3Limit); - reserved3.data = intelImage.mid(reserved3.offset, reserved3.length); - regions.push_back(reserved3); - } - - if (regionSection->EcLimit) { - ec.offset = calculateRegionOffset(regionSection->EcBase); - ec.length = calculateRegionSize(regionSection->EcBase, regionSection->EcLimit); - ec.data = intelImage.mid(ec.offset, ec.length); - regions.push_back(ec); - } - if (regionSection->Reserved4Limit) { - reserved4.offset = calculateRegionOffset(regionSection->Reserved4Base); - reserved4.length = calculateRegionSize(regionSection->Reserved4Base, regionSection->Reserved4Limit); - reserved4.data = intelImage.mid(reserved4.offset, reserved4.length); - regions.push_back(reserved4); + // Add all other regions + for (UINT8 i = Subtypes::GbeRegion; i <= Subtypes::PttRegion; i++) { + if (descriptorVersion == 1 && i == Subtypes::MicrocodeRegion) + break; // Do not parse Microcode and other following regions for legacy descriptors + + const UINT16* RegionBase = ((const UINT16*)regionSection) + 2 * i; + const UINT16* RegionLimit = ((const UINT16*)regionSection) + 2 * i + 1; + if (*RegionLimit && !(*RegionBase == 0xFFFF && *RegionLimit == 0xFFFF)) { + REGION_INFO region; + region.type = i; + region.offset = calculateRegionOffset(*RegionBase); + region.length = calculateRegionSize(*RegionBase, *RegionLimit); + if (region.length != 0) { + if ((UINT32)intelImage.size() < region.offset + region.length) { + msg(usprintf("%s: ", __FUNCTION__) + + itemSubtypeToUString(Types::Region, region.type) + + UString(" region is located outside of the opened image. If your system uses dual-chip storage, please append another part to the opened image"), + index); + return U_TRUNCATED_IMAGE; + } + region.data = intelImage.mid(region.offset, region.length); + regions.push_back(region); + } } } - + + // Regions can not be empty here + if (regions.empty()) { + msg(usprintf("%s: descriptor parsing failed, no regions found", __FUNCTION__)); + return U_INVALID_FLASH_DESCRIPTOR; + } + // Sort regions in ascending order std::sort(regions.begin(), regions.end()); - + // Check for intersections and paddings between regions REGION_INFO region; // Check intersection with the descriptor if (regions.front().offset < FLASH_DESCRIPTOR_SIZE) { - msg(UString("parseIntelImage: ") + itemSubtypeToUString(Types::Region, regions.front().type) + msg(usprintf("%s: ", __FUNCTION__) + + itemSubtypeToUString(Types::Region, regions.front().type) + UString(" region has intersection with flash descriptor"), index); return U_INVALID_FLASH_DESCRIPTOR; } - // Check for padding between descriptor and the first region + // Check for padding between descriptor and the first region else if (regions.front().offset > FLASH_DESCRIPTOR_SIZE) { region.offset = FLASH_DESCRIPTOR_SIZE; region.length = regions.front().offset - FLASH_DESCRIPTOR_SIZE; @@ -426,18 +445,12 @@ USTATUS FfsParser::parseIntelImage(const UByteArray & intelImage, const UINT32 p // Check for intersections/paddings between regions for (size_t i = 1; i < regions.size(); i++) { UINT32 previousRegionEnd = regions[i-1].offset + regions[i-1].length; - // Check that current region is fully present in the image - if (regions[i].offset + regions[i].length > (UINT32)intelImage.size()) { - msg(UString("parseIntelImage: ") + itemSubtypeToUString(Types::Region, regions[i].type) - + UString(" region is located outside of opened image, if your system uses dual-chip storage, please append another part to the opened image"), - index); - return U_TRUNCATED_IMAGE; - } - // Check for intersection with previous region if (regions[i].offset < previousRegionEnd) { - msg(UString("parseIntelImage: ") + itemSubtypeToUString(Types::Region, regions[i].type) - + UString(" region has intersection with ") + itemSubtypeToUString(Types::Region, regions[i - 1].type) +UString(" region"), + msg(usprintf("%s: ", __FUNCTION__) + + itemSubtypeToUString(Types::Region, regions[i].type) + + UString(" region has intersection with ") + itemSubtypeToUString(Types::Region, regions[i - 1].type) + + UString(" region"), index); return U_INVALID_FLASH_DESCRIPTOR; } @@ -448,542 +461,943 @@ USTATUS FfsParser::parseIntelImage(const UByteArray & intelImage, const UINT32 p region.data = intelImage.mid(region.offset, region.length); region.type = getPaddingType(region.data); std::vector::iterator iter = regions.begin(); - std::advance(iter, i - 1); + std::advance(iter, i); regions.insert(iter, region); } } // Check for padding after the last region - if (regions.back().offset + regions.back().length < (UINT32)intelImage.size()) { + if ((UINT64)regions.back().offset + (UINT64)regions.back().length < (UINT64)intelImage.size()) { region.offset = regions.back().offset + regions.back().length; - region.length = intelImage.size() - region.offset; + region.length = (UINT32)(intelImage.size() - region.offset); region.data = intelImage.mid(region.offset, region.length); region.type = getPaddingType(region.data); regions.push_back(region); } // Region map is consistent - + // Intel image UString name("Intel image"); UString info = usprintf("Full size: %Xh (%u)\nFlash chips: %u\nRegions: %u\nMasters: %u\nPCH straps: %u\nPROC straps: %u", - intelImage.size(), intelImage.size(), - descriptorMap->NumberOfFlashChips + 1, // - descriptorMap->NumberOfRegions + 1, // Zero-based numbers in storage - descriptorMap->NumberOfMasters + 1, // - descriptorMap->NumberOfPchStraps, - descriptorMap->NumberOfProcStraps); - - // Construct parsing data - pdata.offset = parentOffset; - + (UINT32)intelImage.size(), (UINT32)intelImage.size(), + descriptorMap->NumberOfFlashChips + 1, // + descriptorMap->NumberOfRegions + 1, // Zero-based numbers in storage + descriptorMap->NumberOfMasters + 1, // + descriptorMap->NumberOfPchStraps, + descriptorMap->NumberOfProcStraps); + + // Set image base + imageBase = model->base(parent) + localOffset; + // Add Intel image tree item - index = model->addItem(Types::Image, Subtypes::IntelImage, name, UString(), info, UByteArray(), intelImage, UByteArray(), true, parsingDataToUByteArray(pdata), parent); - + index = model->addItem(localOffset, Types::Image, Subtypes::IntelImage, name, UString(), info, UByteArray(), intelImage, UByteArray(), Fixed, parent); + // Descriptor // Get descriptor info UByteArray body = intelImage.left(FLASH_DESCRIPTOR_SIZE); name = UString("Descriptor region"); - info = usprintf("Full size: %Xh (%u)", FLASH_DESCRIPTOR_SIZE, FLASH_DESCRIPTOR_SIZE); + info = usprintf("ReservedVector:\n%02X %02X %02X %02X %02X %02X %02X %02X\n" + "%02X %02X %02X %02X %02X %02X %02X %02X\nFull size: %Xh (%u)", + descriptor->ReservedVector[0], descriptor->ReservedVector[1], descriptor->ReservedVector[2], descriptor->ReservedVector[3], + descriptor->ReservedVector[4], descriptor->ReservedVector[5], descriptor->ReservedVector[6], descriptor->ReservedVector[7], + descriptor->ReservedVector[8], descriptor->ReservedVector[9], descriptor->ReservedVector[10], descriptor->ReservedVector[11], + descriptor->ReservedVector[12], descriptor->ReservedVector[13], descriptor->ReservedVector[14], descriptor->ReservedVector[15], + FLASH_DESCRIPTOR_SIZE, FLASH_DESCRIPTOR_SIZE); // Add offsets of actual regions for (size_t i = 0; i < regions.size(); i++) { if (regions[i].type != Subtypes::ZeroPadding && regions[i].type != Subtypes::OnePadding && regions[i].type != Subtypes::DataPadding) - info += UString("\n") + itemSubtypeToUString(Types::Region, regions[i].type) - + usprintf(" region offset: %Xh", regions[i].offset + parentOffset); + info += "\n" + itemSubtypeToUString(Types::Region, regions[i].type) + + usprintf(" region offset: %Xh", regions[i].offset + localOffset); } - + // Region access settings if (descriptorVersion == 1) { - const FLASH_DESCRIPTOR_MASTER_SECTION* masterSection = (const FLASH_DESCRIPTOR_MASTER_SECTION*)calculateAddress8(descriptor, descriptorMap->MasterBase); + const FLASH_DESCRIPTOR_MASTER_SECTION* masterSection = (const FLASH_DESCRIPTOR_MASTER_SECTION*)calculateAddress8((UINT8*)descriptor, descriptorMap->MasterBase); info += UString("\nRegion access settings:"); info += usprintf("\nBIOS: %02Xh %02Xh ME: %02Xh %02Xh\nGbE: %02Xh %02Xh", - masterSection->BiosRead, - masterSection->BiosWrite, - masterSection->MeRead, - masterSection->MeWrite, - masterSection->GbeRead, - masterSection->GbeWrite); - + masterSection->BiosRead, + masterSection->BiosWrite, + masterSection->MeRead, + masterSection->MeWrite, + masterSection->GbeRead, + masterSection->GbeWrite); + // BIOS access table info += UString("\nBIOS access table:") - + UString("\n Read Write") - + usprintf("\nDesc %s %s", masterSection->BiosRead & FLASH_DESCRIPTOR_REGION_ACCESS_DESC ? "Yes " : "No ", - masterSection->BiosWrite & FLASH_DESCRIPTOR_REGION_ACCESS_DESC ? "Yes " : "No "); + + UString("\n Read Write") + + usprintf("\nDesc %s %s", masterSection->BiosRead & FLASH_DESCRIPTOR_REGION_ACCESS_DESC ? "Yes " : "No ", + masterSection->BiosWrite & FLASH_DESCRIPTOR_REGION_ACCESS_DESC ? "Yes " : "No "); info += UString("\nBIOS Yes Yes") - + usprintf("\nME %s %s", masterSection->BiosRead & FLASH_DESCRIPTOR_REGION_ACCESS_ME ? "Yes " : "No ", - masterSection->BiosWrite & FLASH_DESCRIPTOR_REGION_ACCESS_ME ? "Yes " : "No "); + + usprintf("\nME %s %s", masterSection->BiosRead & FLASH_DESCRIPTOR_REGION_ACCESS_ME ? "Yes " : "No ", + masterSection->BiosWrite & FLASH_DESCRIPTOR_REGION_ACCESS_ME ? "Yes " : "No "); info += usprintf("\nGbE %s %s", masterSection->BiosRead & FLASH_DESCRIPTOR_REGION_ACCESS_GBE ? "Yes " : "No ", - masterSection->BiosWrite & FLASH_DESCRIPTOR_REGION_ACCESS_GBE ? "Yes " : "No "); + masterSection->BiosWrite & FLASH_DESCRIPTOR_REGION_ACCESS_GBE ? "Yes " : "No "); info += usprintf("\nPDR %s %s", masterSection->BiosRead & FLASH_DESCRIPTOR_REGION_ACCESS_PDR ? "Yes " : "No ", - masterSection->BiosWrite & FLASH_DESCRIPTOR_REGION_ACCESS_PDR ? "Yes " : "No "); + masterSection->BiosWrite & FLASH_DESCRIPTOR_REGION_ACCESS_PDR ? "Yes " : "No "); } else if (descriptorVersion == 2) { - const FLASH_DESCRIPTOR_MASTER_SECTION_V2* masterSection = (const FLASH_DESCRIPTOR_MASTER_SECTION_V2*)calculateAddress8(descriptor, descriptorMap->MasterBase); + const FLASH_DESCRIPTOR_MASTER_SECTION_V2* masterSection = (const FLASH_DESCRIPTOR_MASTER_SECTION_V2*)calculateAddress8((UINT8*)descriptor, descriptorMap->MasterBase); info += UString("\nRegion access settings:"); - info += usprintf("\nBIOS: %03Xh %03Xh ME: %03Xh %03Xh\nGbE: %03Xh %03Xh EC: %03Xh %03Xh", - masterSection->BiosRead, - masterSection->BiosWrite, - masterSection->MeRead, - masterSection->MeWrite, - masterSection->GbeRead, - masterSection->GbeWrite, - masterSection->EcRead, - masterSection->EcWrite); - + info += usprintf("\nBIOS: %03Xh %03Xh" + "\nME: %03Xh %03Xh" + "\nGbE: %03Xh %03Xh" + "\nEC: %03Xh %03Xh", + masterSection->BiosRead, + masterSection->BiosWrite, + masterSection->MeRead, + masterSection->MeWrite, + masterSection->GbeRead, + masterSection->GbeWrite, + masterSection->EcRead, + masterSection->EcWrite); + // BIOS access table info += UString("\nBIOS access table:") - + UString("\n Read Write") - + usprintf("\nDesc %s %s", - masterSection->BiosRead & FLASH_DESCRIPTOR_REGION_ACCESS_DESC ? "Yes " : "No ", - masterSection->BiosWrite & FLASH_DESCRIPTOR_REGION_ACCESS_DESC ? "Yes " : "No "); + + UString("\n Read Write") + + usprintf("\nDesc %s %s", + masterSection->BiosRead & FLASH_DESCRIPTOR_REGION_ACCESS_DESC ? "Yes " : "No ", + masterSection->BiosWrite & FLASH_DESCRIPTOR_REGION_ACCESS_DESC ? "Yes " : "No "); info += UString("\nBIOS Yes Yes") - + usprintf("\nME %s %s", - masterSection->BiosRead & FLASH_DESCRIPTOR_REGION_ACCESS_ME ? "Yes " : "No ", - masterSection->BiosWrite & FLASH_DESCRIPTOR_REGION_ACCESS_ME ? "Yes " : "No "); + + usprintf("\nME %s %s", + masterSection->BiosRead & FLASH_DESCRIPTOR_REGION_ACCESS_ME ? "Yes " : "No ", + masterSection->BiosWrite & FLASH_DESCRIPTOR_REGION_ACCESS_ME ? "Yes " : "No "); info += usprintf("\nGbE %s %s", - masterSection->BiosRead & FLASH_DESCRIPTOR_REGION_ACCESS_GBE ? "Yes " : "No ", - masterSection->BiosWrite & FLASH_DESCRIPTOR_REGION_ACCESS_GBE ? "Yes " : "No "); + masterSection->BiosRead & FLASH_DESCRIPTOR_REGION_ACCESS_GBE ? "Yes " : "No ", + masterSection->BiosWrite & FLASH_DESCRIPTOR_REGION_ACCESS_GBE ? "Yes " : "No "); info += usprintf("\nPDR %s %s", - masterSection->BiosRead & FLASH_DESCRIPTOR_REGION_ACCESS_PDR ? "Yes " : "No ", - masterSection->BiosWrite & FLASH_DESCRIPTOR_REGION_ACCESS_PDR ? "Yes " : "No "); + masterSection->BiosRead & FLASH_DESCRIPTOR_REGION_ACCESS_PDR ? "Yes " : "No ", + masterSection->BiosWrite & FLASH_DESCRIPTOR_REGION_ACCESS_PDR ? "Yes " : "No "); info += usprintf("\nEC %s %s", - masterSection->BiosRead & FLASH_DESCRIPTOR_REGION_ACCESS_EC ? "Yes " : "No ", - masterSection->BiosWrite & FLASH_DESCRIPTOR_REGION_ACCESS_EC ? "Yes " : "No "); + masterSection->BiosRead & FLASH_DESCRIPTOR_REGION_ACCESS_EC ? "Yes " : "No ", + masterSection->BiosWrite & FLASH_DESCRIPTOR_REGION_ACCESS_EC ? "Yes " : "No "); + + // Prepend descriptor version if present + if (descriptorMap->DescriptorVersion != FLASH_DESCRIPTOR_VERSION_INVALID) { + const FLASH_DESCRIPTOR_VERSION* version = (const FLASH_DESCRIPTOR_VERSION*)&descriptorMap->DescriptorVersion; + UString versionStr = usprintf("Flash descriptor version: %d.%d", version->Major, version->Minor); + if (version->Major != FLASH_DESCRIPTOR_VERSION_MAJOR || version->Minor != FLASH_DESCRIPTOR_VERSION_MINOR) { + versionStr += ", unknown"; + msg(usprintf("%s: unknown flash descriptor version %d.%d", __FUNCTION__, version->Major, version->Minor)); + } + info = versionStr + "\n" + info; + } } - + // VSCC table - const VSCC_TABLE_ENTRY* vsccTableEntry = (const VSCC_TABLE_ENTRY*)(descriptor + ((UINT16)upperMap->VsccTableBase << 4)); + const VSCC_TABLE_ENTRY* vsccTableEntry = (const VSCC_TABLE_ENTRY*)((UINT8*)descriptor + ((UINT16)upperMap->VsccTableBase << 4)); info += UString("\nFlash chips in VSCC table:"); UINT8 vsscTableSize = upperMap->VsccTableSize * sizeof(UINT32) / sizeof(VSCC_TABLE_ENTRY); - for (int i = 0; i < vsscTableSize; i++) { - info += usprintf("\n%02X%02X%02Xh", - vsccTableEntry->VendorId, vsccTableEntry->DeviceId0, vsccTableEntry->DeviceId1); + for (UINT8 i = 0; i < vsscTableSize; i++) { + UString jedecId = jedecIdToUString(vsccTableEntry->VendorId, vsccTableEntry->DeviceId0, vsccTableEntry->DeviceId1); + info += usprintf("\n%02X%02X%02X (", vsccTableEntry->VendorId, vsccTableEntry->DeviceId0, vsccTableEntry->DeviceId1) + + jedecId + + UString(")"); + if (jedecId.startsWith("Unknown")) { + msg(usprintf("%s: SPI flash with unknown JEDEC ID %02X%02X%02X found in VSCC table", __FUNCTION__, + vsccTableEntry->VendorId, vsccTableEntry->DeviceId0, vsccTableEntry->DeviceId1), index); + } vsccTableEntry++; } - + // Add descriptor tree item - UModelIndex regionIndex = model->addItem(Types::Region, Subtypes::DescriptorRegion, name, UString(), info, UByteArray(), body, UByteArray(), true, parsingDataToUByteArray(pdata), index); + UModelIndex regionIndex = model->addItem(localOffset, Types::Region, Subtypes::DescriptorRegion, name, UString(), info, UByteArray(), body, UByteArray(), Fixed, index); // Parse regions - UINT8 result = U_SUCCESS; - UINT8 parseResult = U_SUCCESS; + USTATUS result = U_SUCCESS; + USTATUS parseResult = U_SUCCESS; for (size_t i = 0; i < regions.size(); i++) { region = regions[i]; switch (region.type) { - case Subtypes::BiosRegion: - result = parseBiosRegion(region.data, region.offset, index, regionIndex); - break; - case Subtypes::MeRegion: - result = parseMeRegion(region.data, region.offset, index, regionIndex); - break; - case Subtypes::GbeRegion: - result = parseGbeRegion(region.data, region.offset, index, regionIndex); - break; - case Subtypes::PdrRegion: - result = parsePdrRegion(region.data, region.offset, index, regionIndex); - break; - case Subtypes::Reserved1Region: - case Subtypes::Reserved2Region: - case Subtypes::Reserved3Region: - case Subtypes::EcRegion: - case Subtypes::Reserved4Region: - result = parseGeneralRegion(region.type, region.data, region.offset, index, regionIndex); - break; - case Subtypes::ZeroPadding: - case Subtypes::OnePadding: - case Subtypes::DataPadding: { - // Add padding between regions - UByteArray padding = intelImage.mid(region.offset, region.length); - - // Get parent's parsing data - PARSING_DATA pdata = parsingDataFromUModelIndex(index); - - // Get info - name = UString("Padding"); - info = usprintf("Full size: %Xh (%u)", - padding.size(), padding.size()); - - // Construct parsing data - pdata.offset = parentOffset + region.offset; - - // Add tree item - regionIndex = model->addItem(Types::Padding, getPaddingType(padding), name, UString(), info, UByteArray(), padding, UByteArray(), true, parsingDataToUByteArray(pdata), index); - result = U_SUCCESS; + case Subtypes::BiosRegion: + result = parseBiosRegion(region.data, region.offset, index, regionIndex); + break; + case Subtypes::MeRegion: + result = parseMeRegion(region.data, region.offset, index, regionIndex); + break; + case Subtypes::GbeRegion: + result = parseGbeRegion(region.data, region.offset, index, regionIndex); + break; + case Subtypes::PdrRegion: + result = parsePdrRegion(region.data, region.offset, index, regionIndex); + break; + case Subtypes::DevExp1Region: + result = parseDevExp1Region(region.data, region.offset, index, regionIndex); + break; + case Subtypes::Bios2Region: + case Subtypes::MicrocodeRegion: + case Subtypes::EcRegion: + case Subtypes::DevExp2Region: + case Subtypes::IeRegion: + case Subtypes::Tgbe1Region: + case Subtypes::Tgbe2Region: + case Subtypes::Reserved1Region: + case Subtypes::Reserved2Region: + case Subtypes::PttRegion: + result = parseGenericRegion(region.type, region.data, region.offset, index, regionIndex); + break; + case Subtypes::ZeroPadding: + case Subtypes::OnePadding: + case Subtypes::DataPadding: { + // Add padding between regions + UByteArray padding = intelImage.mid(region.offset, region.length); + + // Get info + name = UString("Padding"); + info = usprintf("Full size: %Xh (%u)", + (UINT32)padding.size(), (UINT32)padding.size()); + + // Add tree item + regionIndex = model->addItem(region.offset, Types::Padding, getPaddingType(padding), name, UString(), info, UByteArray(), padding, UByteArray(), Fixed, index); + result = U_SUCCESS; } break; - default: - msg(("parseIntelImage: region of unknown type found"), index); - result = U_INVALID_FLASH_DESCRIPTOR; + default: + msg(usprintf("%s: region of unknown type found", __FUNCTION__), index); + result = U_INVALID_FLASH_DESCRIPTOR; } // Store the first failed result as a final result - if (!parseResult && result) + if (!parseResult && result) { parseResult = result; + } } - + return parseResult; } -USTATUS FfsParser::parseGbeRegion(const UByteArray & gbe, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index) +USTATUS FfsParser::parseGbeRegion(const UByteArray & gbe, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index) { // Check sanity if (gbe.isEmpty()) return U_EMPTY_REGION; if ((UINT32)gbe.size() < GBE_VERSION_OFFSET + sizeof(GBE_VERSION)) return U_INVALID_REGION; - - // Get parent's parsing data - PARSING_DATA pdata = parsingDataFromUModelIndex(parent); - + // Get info UString name("GbE region"); const GBE_MAC_ADDRESS* mac = (const GBE_MAC_ADDRESS*)gbe.constData(); const GBE_VERSION* version = (const GBE_VERSION*)(gbe.constData() + GBE_VERSION_OFFSET); UString info = usprintf("Full size: %Xh (%u)\nMAC: %02X:%02X:%02X:%02X:%02X:%02X\nVersion: %u.%u", - gbe.size(), gbe.size(), - mac->vendor[0], mac->vendor[1], mac->vendor[2], - mac->device[0], mac->device[1], mac->device[2], - version->major, - version->minor); - - // Construct parsing data - pdata.offset += parentOffset; - + (UINT32)gbe.size(), (UINT32)gbe.size(), + mac->vendor[0], mac->vendor[1], mac->vendor[2], + mac->device[0], mac->device[1], mac->device[2], + version->major, + version->minor); + // Add tree item - index = model->addItem(Types::Region, Subtypes::GbeRegion, name, UString(), info, UByteArray(), gbe, UByteArray(), true, parsingDataToUByteArray(pdata), parent); - + index = model->addItem(localOffset, Types::Region, Subtypes::GbeRegion, name, UString(), info, UByteArray(), gbe, UByteArray(), Fixed, parent); + return U_SUCCESS; } -USTATUS FfsParser::parseMeRegion(const UByteArray & me, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index) +USTATUS FfsParser::parseMeRegion(const UByteArray & me, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index) { // Check sanity if (me.isEmpty()) return U_EMPTY_REGION; - - // Get parent's parsing data - PARSING_DATA pdata = parsingDataFromUModelIndex(parent); - + // Get info UString name("ME region"); - UString info = usprintf("Full size: %Xh (%u)", me.size(), me.size()); - + UString info = usprintf("Full size: %Xh (%u)", (UINT32)me.size(), (UINT32)me.size()); + // Parse region bool versionFound = true; bool emptyRegion = false; // Check for empty region - if (me.size() == me.count('\xFF') || me.size() == me.count('\x00')) { + if (me.size() == me.count('\xFF')) { // Further parsing not needed emptyRegion = true; - info += ("\nState: empty"); + info += ("\nState: empty (0xFF)"); + } + else if (me.size() == me.count('\x00')) { + // Further parsing not needed + emptyRegion = true; + info += ("\nState: empty (0x00)"); } else { // Search for new signature - INT32 versionOffset = me.indexOf(ME_VERSION_SIGNATURE2); - if (versionOffset < 0){ // New signature not found + UINT32 sig2Value = ME_VERSION_SIGNATURE2; + UByteArray sig2((const char*)&sig2Value, sizeof(sig2Value)); + INT32 versionOffset = (INT32)me.indexOf(sig2); + if (versionOffset < 0) { // New signature not found // Search for old signature - versionOffset = me.indexOf(ME_VERSION_SIGNATURE); - if (versionOffset < 0){ + UINT32 sigValue = ME_VERSION_SIGNATURE; + UByteArray sig((const char*)&sigValue, sizeof(sigValue)); + versionOffset = (INT32)me.indexOf(sig); + if (versionOffset < 0) { info += ("\nVersion: unknown"); versionFound = false; } } - - // Check sanity - if ((UINT32)me.size() < (UINT32)versionOffset + sizeof(ME_VERSION)) - return U_INVALID_REGION; - + // Add version information if (versionFound) { + if ((UINT32)me.size() < (UINT32)versionOffset + sizeof(ME_VERSION)) + return U_INVALID_REGION; + const ME_VERSION* version = (const ME_VERSION*)(me.constData() + versionOffset); info += usprintf("\nVersion: %u.%u.%u.%u", - version->major, - version->minor, - version->bugfix, - version->build); + version->Major, + version->Minor, + version->Bugfix, + version->Build); } } - - // Construct parsing data - pdata.offset += parentOffset; - + // Add tree item - index = model->addItem(Types::Region, Subtypes::MeRegion, name, UString(), info, UByteArray(), me, UByteArray(), true, parsingDataToUByteArray(pdata), parent); - + index = model->addItem(localOffset, Types::Region, Subtypes::MeRegion, name, UString(), info, UByteArray(), me, UByteArray(), Fixed, parent); + // Show messages if (emptyRegion) { - msg(UString("parseMeRegion: ME region is empty"), index); + msg(usprintf("%s: ME region is empty", __FUNCTION__), index); } else if (!versionFound) { - msg(UString("parseMeRegion: ME version is unknown, it can be damaged"), index); + msg(usprintf("%s: ME version is unknown, it can be damaged", __FUNCTION__), index); } - + else { + meParser->parseMeRegionBody(index); + } + return U_SUCCESS; } -USTATUS FfsParser::parsePdrRegion(const UByteArray & pdr, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index) +USTATUS FfsParser::parsePdrRegion(const UByteArray & pdr, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index) { // Check sanity if (pdr.isEmpty()) return U_EMPTY_REGION; - - // Get parent's parsing data - PARSING_DATA pdata = parsingDataFromUModelIndex(parent); - + // Get info UString name("PDR region"); - UString info = usprintf("Full size: %Xh (%u)", pdr.size(), pdr.size()); - - // Construct parsing data - pdata.offset += parentOffset; - + UString info = usprintf("Full size: %Xh (%u)", (UINT32)pdr.size(), (UINT32)pdr.size()); + + // Check for empty region + bool emptyRegion = false; + if (pdr.size() == pdr.count('\xFF')) { + // Further parsing not needed + emptyRegion = true; + info += ("\nState: empty (0xFF)"); + } + else if (pdr.size() == pdr.count('\x00')) { + // Further parsing not needed + emptyRegion = true; + info += ("\nState: empty (0x00)"); + } + // Add tree item - index = model->addItem(Types::Region, Subtypes::PdrRegion, name, UString(), info, UByteArray(), pdr, UByteArray(), true, parsingDataToUByteArray(pdata), parent); - - // Parse PDR region as BIOS space - UINT8 result = parseRawArea(index); - if (result && result != U_VOLUMES_NOT_FOUND && result != U_INVALID_VOLUME) - return result; - + index = model->addItem(localOffset, Types::Region, Subtypes::PdrRegion, name, UString(), info, UByteArray(), pdr, UByteArray(), Fixed, parent); + + if (!emptyRegion) { + // Parse PDR region as BIOS space + USTATUS result = parseRawArea(index); + if (result && result != U_VOLUMES_NOT_FOUND && result != U_INVALID_VOLUME && result != U_STORES_NOT_FOUND) + return result; + } + return U_SUCCESS; } -USTATUS FfsParser::parseGeneralRegion(const UINT8 subtype, const UByteArray & region, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index) +USTATUS FfsParser::parseDevExp1Region(const UByteArray & devExp1, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index) +{ + // Check sanity + if (devExp1.isEmpty()) + return U_EMPTY_REGION; + + // Get info + UString name("DevExp1 region"); + UString info = usprintf("Full size: %Xh (%u)", (UINT32)devExp1.size(), (UINT32)devExp1.size()); + + // Check for empty region + bool emptyRegion = false; + if (devExp1.size() == devExp1.count('\xFF')) { + // Further parsing not needed + emptyRegion = true; + info += ("\nState: empty (0xFF)"); + } + else if (devExp1.size() == devExp1.count('\x00')) { + // Further parsing not needed + emptyRegion = true; + info += ("\nState: empty (0x00)"); + } + + // Add tree item + index = model->addItem(localOffset, Types::Region, Subtypes::DevExp1Region, name, UString(), info, UByteArray(), devExp1, UByteArray(), Fixed, parent); + + if (!emptyRegion) { + meParser->parseMeRegionBody(index); + } + return U_SUCCESS; +} + +USTATUS FfsParser::parseGenericRegion(const UINT8 subtype, const UByteArray & region, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index) { // Check sanity if (region.isEmpty()) return U_EMPTY_REGION; - - // Get parent's parsing data - PARSING_DATA pdata = parsingDataFromUModelIndex(parent); - + // Get info UString name = itemSubtypeToUString(Types::Region, subtype) + UString(" region"); - UString info = usprintf("Full size: %Xh (%u)", region.size(), region.size()); - - // Construct parsing data - pdata.offset += parentOffset; - + UString info = usprintf("Full size: %Xh (%u)", (UINT32)region.size(), (UINT32)region.size()); + + // Check for empty region + bool emptyRegion = false; + if (region.size() == region.count('\xFF')) { + // Further parsing not needed + emptyRegion = true; + info += ("\nState: empty (0xFF)"); + } + else if (region.size() == region.count('\x00')) { + // Further parsing not needed + emptyRegion = true; + info += ("\nState: empty (0x00)"); + } + // Add tree item - index = model->addItem(Types::Region, subtype, name, UString(), info, UByteArray(), region, UByteArray(), true, parsingDataToUByteArray(pdata), parent); - + index = model->addItem(localOffset, Types::Region, subtype, name, UString(), info, UByteArray(), region, UByteArray(), Fixed, parent); + return U_SUCCESS; } -USTATUS FfsParser::parseBiosRegion(const UByteArray & bios, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index) +USTATUS FfsParser::parseBiosRegion(const UByteArray & bios, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index) { // Sanity check if (bios.isEmpty()) return U_EMPTY_REGION; - - // Get parent's parsing data - PARSING_DATA pdata = parsingDataFromUModelIndex(parent); - + // Get info UString name("BIOS region"); - UString info = usprintf("Full size: %Xh (%u)", bios.size(), bios.size()); - - // Construct parsing data - pdata.offset += parentOffset; - + UString info = usprintf("Full size: %Xh (%u)", (UINT32)bios.size(), (UINT32)bios.size()); + // Add tree item - index = model->addItem(Types::Region, Subtypes::BiosRegion, name, UString(), info, UByteArray(), bios, UByteArray(), true, parsingDataToUByteArray(pdata), parent); - + index = model->addItem(localOffset, Types::Region, Subtypes::BiosRegion, name, UString(), info, UByteArray(), bios, UByteArray(), Fixed, parent); + return parseRawArea(index); } -UINT8 FfsParser::getPaddingType(const UByteArray & padding) -{ - if (padding.count('\x00') == padding.size()) - return Subtypes::ZeroPadding; - if (padding.count('\xFF') == padding.size()) - return Subtypes::OnePadding; - return Subtypes::DataPadding; -} - USTATUS FfsParser::parseRawArea(const UModelIndex & index) { // Sanity check if (!index.isValid()) return U_INVALID_PARAMETER; - - // Get parsing data - PARSING_DATA pdata = parsingDataFromUModelIndex(index); - UINT32 headerSize = model->header(index).size(); - UINT32 offset = pdata.offset + headerSize; - + // Get item data UByteArray data = model->body(index); - - // Search for first volume + UINT32 headerSize = (UINT32)model->header(index).size(); + + // Obtain required information from parent volume, if it exists + UINT8 emptyByte = 0xFF; + UModelIndex parentVolumeIndex = model->findParentOfType(index, Types::Volume); + if (parentVolumeIndex.isValid() && model->hasEmptyParsingData(parentVolumeIndex) == false) { + UByteArray data = model->parsingData(parentVolumeIndex); + const VOLUME_PARSING_DATA* pdata = (const VOLUME_PARSING_DATA*)data.constData(); + emptyByte = pdata->emptyByte; + } + USTATUS result; - UINT32 prevVolumeOffset; - - result = findNextVolume(index, data, offset, 0, prevVolumeOffset); - if (result) - return result; - - // First volume is not at the beginning of RAW area UString name; UString info; - if (prevVolumeOffset > 0) { - // Get info - UByteArray padding = data.left(prevVolumeOffset); - name = UString("Padding"); - info = usprintf("Full size: %Xh (%u)", padding.size(), padding.size()); - - // Construct parsing data - pdata.offset = offset; - - // Add tree item - model->addItem(Types::Padding, getPaddingType(padding), name, UString(), info, UByteArray(), padding, UByteArray(), true, parsingDataToUByteArray(pdata), index); + + // Search for the first item + UINT8 prevItemType = 0; + UINT32 prevItemOffset = 0; + UINT32 prevItemSize = 0; + UINT32 prevItemAltSize = 0; + + result = findNextRawAreaItem(index, 0, prevItemType, prevItemOffset, prevItemSize, prevItemAltSize); + if (result) { + // No need to parse further + return U_SUCCESS; } - - // Search for and parse all volumes - UINT32 volumeOffset = prevVolumeOffset; - UINT32 prevVolumeSize = 0; - - while (!result) - { - // Padding between volumes - if (volumeOffset > prevVolumeOffset + prevVolumeSize) { - UINT32 paddingOffset = prevVolumeOffset + prevVolumeSize; - UINT32 paddingSize = volumeOffset - paddingOffset; + + // Set base of protected regions to be the first volume + if (model->type(index) == Types::Region + && model->subtype(index) == Subtypes::BiosRegion) { + protectedRegionsBase = (UINT64)model->base(index) + prevItemOffset; + } + + // First item is not at the beginning of this raw area + if (prevItemOffset > 0) { + // Get info + UByteArray padding = data.left(prevItemOffset); + name = UString("Padding"); + info = usprintf("Full size: %Xh (%u)", (UINT32)padding.size(), (UINT32)padding.size()); + + // Add tree item + model->addItem(headerSize, Types::Padding, getPaddingType(padding), name, UString(), info, UByteArray(), padding, UByteArray(), Fixed, index); + } + + // Search for and parse all items + UINT8 itemType = prevItemType; + UINT32 itemOffset = prevItemOffset; + UINT32 itemSize = prevItemSize; + UINT32 itemAltSize = prevItemAltSize; + + while (!result) { + // Padding between items + if (itemOffset > prevItemOffset + prevItemSize) { + UINT32 paddingOffset = prevItemOffset + prevItemSize; + UINT32 paddingSize = itemOffset - paddingOffset; UByteArray padding = data.mid(paddingOffset, paddingSize); - + // Get info name = UString("Padding"); - info = usprintf("Full size: %Xh (%u)", padding.size(), padding.size()); - - // Construct parsing data - pdata.offset = offset + paddingOffset; - + info = usprintf("Full size: %Xh (%u)", (UINT32)padding.size(), (UINT32)padding.size()); + // Add tree item - model->addItem(Types::Padding, getPaddingType(padding), name, UString(), info, UByteArray(), padding, UByteArray(), true, parsingDataToUByteArray(pdata), index); - } - - // Get volume size - UINT32 volumeSize = 0; - UINT32 bmVolumeSize = 0; - result = getVolumeSize(data, volumeOffset, volumeSize, bmVolumeSize); - if (result) { - msg(UString("parseRawArea: getVolumeSize failed with error ") + errorCodeToUString(result), index); - return result; + model->addItem(headerSize + paddingOffset, Types::Padding, getPaddingType(padding), name, UString(), info, UByteArray(), padding, UByteArray(), Fixed, index); } - // Check that volume is fully present in input - if (volumeSize > (UINT32)data.size() || volumeOffset + volumeSize > (UINT32)data.size()) { - msg(UString("parseRawArea: one of volumes inside overlaps the end of data"), index); - return U_INVALID_VOLUME; - } - - UByteArray volume = data.mid(volumeOffset, volumeSize); - if (volumeSize > (UINT32)volume.size()) { - // Mark the rest as padding and finish the parsing - UByteArray padding = data.right(volume.size()); - + // Check that item is fully present in input + if (itemSize > (UINT32)data.size() || itemOffset + itemSize > (UINT32)data.size()) { + // Mark the rest as padding and finish parsing + UByteArray padding = data.mid(itemOffset); + // Get info name = UString("Padding"); - info = usprintf("Full size: %Xh (%u)", padding.size(), padding.size()); - - // Construct parsing data - pdata.offset = offset + volumeOffset; - + info = usprintf("Full size: %Xh (%u)", (UINT32)padding.size(), (UINT32)padding.size()); + // Add tree item - UModelIndex paddingIndex = model->addItem(Types::Padding, getPaddingType(padding), name, UString(), info, UByteArray(), padding, UByteArray(), true, parsingDataToUByteArray(pdata), index); - msg(UString("parseRawArea: one of volumes inside overlaps the end of data"), paddingIndex); - + UModelIndex paddingIndex = model->addItem(headerSize + itemOffset, Types::Padding, getPaddingType(padding), name, UString(), info, UByteArray(), padding, UByteArray(), Fixed, index); + msg(usprintf("%s: one of objects inside overlaps the end of data", __FUNCTION__), paddingIndex); + // Update variables - prevVolumeOffset = volumeOffset; - prevVolumeSize = padding.size(); + prevItemOffset = itemOffset; + prevItemSize = (UINT32)padding.size(); break; } + + // Parse current volume header + if (itemType == Types::Volume) { + UModelIndex volumeIndex; + UByteArray volume = data.mid(itemOffset, itemSize); + result = parseVolumeHeader(volume, headerSize + itemOffset, index, volumeIndex); + if (result) { + msg(usprintf("%s: volume header parsing failed with error ", __FUNCTION__) + errorCodeToUString(result), index); + } else { + // Show messages + if (itemSize != itemAltSize) + msg(usprintf("%s: volume size stored in header %Xh differs from calculated using block map %Xh", __FUNCTION__, itemSize, itemAltSize), volumeIndex); + } + } + else if (itemType == Types::Microcode) { + UModelIndex microcodeIndex; + UByteArray microcode = data.mid(itemOffset, itemSize); + result = parseIntelMicrocodeHeader(microcode, headerSize + itemOffset, index, microcodeIndex); + if (result) { + msg(usprintf("%s: microcode header parsing failed with error ", __FUNCTION__) + errorCodeToUString(result), index); + } + } + else if (itemType == Types::BpdtStore) { + UByteArray bpdtStore = data.mid(itemOffset, itemSize); + + // Get info + name = UString("BPDT region"); + info = usprintf("Full size: %Xh (%u)", (UINT32)bpdtStore.size(), (UINT32)bpdtStore.size()); + + // Add tree item + UModelIndex bpdtIndex = model->addItem(headerSize + itemOffset, Types::BpdtStore, 0, name, UString(), info, UByteArray(), bpdtStore, UByteArray(), Fixed, index); + + // Parse BPDT region + UModelIndex bpdtPtIndex; + result = parseBpdtRegion(bpdtStore, 0, 0, bpdtIndex, bpdtPtIndex); + if (result) { + msg(usprintf("%s: BPDT store parsing failed with error ", __FUNCTION__) + errorCodeToUString(result), index); + } + } + else if (itemType == Types::InsydeFlashDeviceMapStore) { + try { + UByteArray fdm = data.mid(itemOffset, itemSize); + umemstream is(fdm.constData(), fdm.size()); + kaitai::kstream ks(&is); + insyde_fdm_t parsed(&ks); + UINT32 storeSize = (UINT32)fdm.size(); + + // Construct header and body + UByteArray header = fdm.left(parsed.data_offset()); + UByteArray body = fdm.mid(header.size(), storeSize - header.size()); + + // Add info + UString name = UString("Insyde H2O FlashDeviceMap"); + UString info = usprintf("Signature: HFDM\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nEntry size: %Xh (%u)\nEntry format: %02Xh\nRevision: %02Xh\nExtension count: %u\nFlash descriptor base address: %08Xh\nChecksum: %02Xh", + storeSize, storeSize, + (UINT32)header.size(), (UINT32)header.size(), + (UINT32)body.size(), (UINT32)body.size(), + parsed.entry_size(), parsed.entry_size(), + parsed.entry_format(), + parsed.revision(), + parsed.num_extensions(), + (UINT32)parsed.fd_base_address(), + parsed.checksum()); + + // Check header checksum + { + UByteArray tempHeader = data.mid(itemOffset, sizeof(INSYDE_FLASH_DEVICE_MAP_HEADER)); + INSYDE_FLASH_DEVICE_MAP_HEADER* tempFdmHeader = (INSYDE_FLASH_DEVICE_MAP_HEADER*)tempHeader.data(); + tempFdmHeader->Checksum = 0; + UINT8 calculated = calculateChecksum8((const UINT8*)tempFdmHeader, (UINT32)tempHeader.size()); + if (calculated == parsed.checksum()) { + info += UString(", valid"); + } + else { + info += usprintf(", invalid, should be %02Xh", calculated); + } + } + + // Add board IDs + if (!parsed._is_null_board_ids()) { + info += usprintf("\nRegion index: %Xh\nBoardId Count: %u", + parsed.board_ids()->region_index(), + parsed.board_ids()->num_board_ids()); + UINT32 i = 0; + for (const auto & boardId : *parsed.board_ids()->board_ids()) { + info += usprintf("\nBoardId #%u: %" PRIX64 "\n", i++, boardId); + } + } + + // Add header tree item + UModelIndex headerIndex = model->addItem(headerSize + itemOffset, Types::InsydeFlashDeviceMapStore, 0, name, UString(), info, header, body, UByteArray(), Fixed, index); + + // Add entries + UINT32 entryOffset = parsed.data_offset(); + bool protectedRangeFound = false; + for (const auto & entry : *parsed.entries()->entries()) { + const EFI_GUID guid = readUnaligned((const EFI_GUID*)entry->guid().c_str()); + name = insydeFlashDeviceMapEntryTypeGuidToUString(guid); + UString text; + header = data.mid(itemOffset + entryOffset, sizeof(INSYDE_FLASH_DEVICE_MAP_ENTRY)); + body = data.mid(itemOffset + entryOffset + header.size(), parsed.entry_size() - header.size()); + + // Add info + UINT32 entrySize = (UINT32)header.size() + (UINT32)body.size(); + info = UString("Region type: ") + guidToUString(guid, false) + "\n"; + info += UString("Region id: "); + for (UINT8 i = 0; i < 16; i++) { + info += usprintf("%02X", *(const UINT8*)(entry->region_id().c_str() + i)); + } + info += usprintf("\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nRegion address: %08Xh\nRegion size: %08Xh\nAttributes: %08Xh", + entrySize, entrySize, + (UINT32)header.size(), (UINT32)header.size(), + (UINT32)body.size(), (UINT32)body.size(), + (UINT32)entry->region_base(), + (UINT32)entry->region_size(), + entry->attributes()); + + if ((entry->attributes() & INSYDE_FLASH_DEVICE_MAP_ENTRY_ATTRIBUTE_MODIFIABLE) == 0) { + if (!protectedRangeFound) { + securityInfo += usprintf("Insyde Flash Device Map found at base %08Xh\nProtected ranges:\n", model->base(headerIndex)); + protectedRangeFound = true; + } + + // TODO: make sure that the only hash possible here is SHA256 + + // Add this region to the list of Insyde protected regions + PROTECTED_RANGE range = {}; + range.Offset = (UINT32)entry->region_base(); + range.Size = (UINT32)entry->region_size(); + range.AlgorithmId = TCG_HASH_ALGORITHM_ID_SHA256; + range.Type = PROTECTED_RANGE_VENDOR_HASH_INSYDE; + range.Hash = body; + protectedRanges.push_back(range); + + securityInfo += usprintf("Address: %08Xh Size: %Xh\nHash: ", range.Offset, range.Size) + UString(body.toHex().constData()) + "\n"; + } + + // Add tree item + model->addItem(entryOffset, Types::InsydeFlashDeviceMapEntry, 0, name, text, info, header, body, UByteArray(), Fixed, headerIndex); + + entryOffset += entrySize; + } + + if (protectedRangeFound) { + securityInfo += "\n"; + } + } + catch (...) { + // Parsing failed, need to add the candidate as Padding + UByteArray padding = data.mid(itemOffset, itemSize); + + // Get info + name = UString("Padding"); + info = usprintf("Full size: %Xh (%u)", (UINT32)padding.size(), (UINT32)padding.size()); + + // Add tree item + model->addItem(headerSize + itemOffset, Types::Padding, getPaddingType(padding), name, UString(), info, UByteArray(), padding, UByteArray(), Fixed, index); + } + } +#ifdef U_ENABLE_NVRAM_PARSING_SUPPORT + else if (itemType == Types::DellDvarStore) { + try { + UByteArray dvar = data.mid(itemOffset, itemSize); + umemstream is(dvar.constData(), dvar.size()); + kaitai::kstream ks(&is); + dell_dvar_t parsed(&ks); + UINT32 storeSize = (UINT32)dvar.size(); + + // Construct header and body + UByteArray header = dvar.left(parsed.data_offset()); + UByteArray body = dvar.mid(header.size(), storeSize - header.size()); + + // Add info + UString name = UString("Dell DVAR Store"); + UString info = usprintf("Signature: DVAR\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nFlags: %02Xh", + storeSize, storeSize, + (UINT32)header.size(), (UINT32)header.size(), + (UINT32)body.size(), (UINT32)body.size(), + parsed.flags()); + + // Add header tree item + UModelIndex headerIndex = model->addItem(headerSize + itemOffset, Types::DellDvarStore, 0, name, UString(), info, header, body, UByteArray(), Fixed, index); + + // Add entries + UINT32 entryOffset = parsed.data_offset(); + for (const auto & entry : *parsed.entries()) { + // This is the terminating entry, needs special processing + if (entry->_is_null_flags_c()) { + // Add free space or padding after all entries, if needed + if (entryOffset < storeSize) { + UByteArray freeSpace = dvar.mid(entryOffset, storeSize - entryOffset); + // Add info + info = usprintf("Full size: %Xh (%u)", (UINT32)freeSpace.size(), (UINT32)freeSpace.size()); + + // Check that remaining unparsed bytes are actually empty + if (freeSpace.count(emptyByte) == freeSpace.size()) { // Free space + // Add tree item + model->addItem(entryOffset, Types::FreeSpace, 0, UString("Free space"), UString(), info, UByteArray(), freeSpace, UByteArray(), Fixed, headerIndex); + } + else { + // Add tree item + model->addItem(entryOffset, Types::Padding, getPaddingType(freeSpace), UString("Padding"), UString(), info, UByteArray(), freeSpace, UByteArray(), Fixed, headerIndex); + } + } + break; + } + + // This is a normal entry + // Check state to be known + if (entry->state() != DVAR_ENTRY_STATE_STORING && + entry->state() != DVAR_ENTRY_STATE_STORED && + entry->state() != DVAR_ENTRY_STATE_DELETING && + entry->state() != DVAR_ENTRY_STATE_DELETED){ + // TODO: Add the rest as padding, as we encountered an unexpected entry and can't guarantee that the rest got parsed correctly + } + + // Check flags to be known + if (entry->flags() != DVAR_ENTRY_FLAG_NAME_ID && + entry->flags() != DVAR_ENTRY_FLAG_NAME_ID + DVAR_ENTRY_FLAG_NAMESPACE_GUID) { + // TODO: Add the rest as padding, as we encountered an unexpected entry and can't guarantee that the rest got parsed correctly + } + + // Check type to be known + if (entry->type() != DVAR_ENTRY_TYPE_NAME_ID_8_DATA_SIZE_8 && + entry->type() != DVAR_ENTRY_TYPE_NAME_ID_16_DATA_SIZE_8 && + entry->type() != DVAR_ENTRY_TYPE_NAME_ID_16_DATA_SIZE_16) { + // TODO: Add the rest as padding, as we encountered an unexpected entry and can't guarantee that the rest got parsed correctly + } + + UINT32 headerSize; + UINT32 bodySize; + UINT32 entrySize; + UINT32 nameId; + UINT8 subtype; + UString text; + + // TODO: find a Dell image with NameUtf8 entries + + // NamespaceGUID entry + if (entry->flags() == DVAR_ENTRY_FLAG_NAME_ID + DVAR_ENTRY_FLAG_NAMESPACE_GUID) { + // State of this variable only applies to the NameId part, not the NamespaceGuid part + // This kind of variables with deleted state till need to be shown as valid + subtype = Subtypes::NamespaceGuidDvarEntry; + EFI_GUID guid = *(const EFI_GUID*)(entry->namespace_guid().c_str()); + headerSize = sizeof(DVAR_ENTRY_HEADER) + sizeof(EFI_GUID); + if (entry->type() == DVAR_ENTRY_TYPE_NAME_ID_8_DATA_SIZE_8) { + nameId = entry->name_id_8(); + bodySize = entry->len_data_8(); + headerSize += sizeof(UINT8) + sizeof(UINT8); + } + else if (entry->type() == DVAR_ENTRY_TYPE_NAME_ID_16_DATA_SIZE_8) { + nameId = entry->name_id_16(); + bodySize = entry->len_data_8(); + headerSize += sizeof(UINT16) + sizeof(UINT8); + } + else if (entry->type() == DVAR_ENTRY_TYPE_NAME_ID_16_DATA_SIZE_16) { + nameId = entry->name_id_16(); + bodySize = entry->len_data_16(); + headerSize += sizeof(UINT16) + sizeof(UINT16); + } + + entrySize = headerSize + bodySize; + header = dvar.mid(entryOffset, headerSize); + body = dvar.mid(entryOffset + headerSize, bodySize); + + name = usprintf("%X:%X", entry->namespace_id(), nameId); + text = guidToUString(guid); + info = usprintf("Full size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nState: %02Xh\nFlags: %02Xh\nType: %02Xh\nNamespaceId: %Xh\nNameId: %Xh\n", + entrySize, entrySize, + (UINT32)header.size(), (UINT32)header.size(), + (UINT32)body.size(), (UINT32)body.size(), + entry->state(), + entry->flags(), + entry->type(), + entry->namespace_id(), + nameId) + + UString("NamespaceGuid: ") + guidToUString(guid, false); + } + // NameId entry + else { + subtype = Subtypes::NameIdDvarEntry; + headerSize = sizeof(DVAR_ENTRY_HEADER); + if (entry->type() == DVAR_ENTRY_TYPE_NAME_ID_8_DATA_SIZE_8) { + nameId = entry->name_id_8(); + bodySize = entry->len_data_8(); + headerSize += sizeof(UINT8) + sizeof(UINT8); + } + else if (entry->type() == DVAR_ENTRY_TYPE_NAME_ID_16_DATA_SIZE_8) { + nameId = entry->name_id_16(); + bodySize = entry->len_data_8(); + headerSize += sizeof(UINT16) + sizeof(UINT8); + } + else if (entry->type() == DVAR_ENTRY_TYPE_NAME_ID_16_DATA_SIZE_16) { + nameId = entry->name_id_16(); + bodySize = entry->len_data_16(); + headerSize += sizeof(UINT16) + sizeof(UINT16); + } + + entrySize = headerSize + bodySize; + header = dvar.mid(entryOffset, headerSize); + body = dvar.mid(entryOffset + headerSize, bodySize); + + name = usprintf("%X:%X", entry->namespace_id(), nameId); + info = usprintf("Full size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nState: %02Xh\nFlags: %02Xh\nType: %02Xh\nNamespaceId: %Xh\nNameId: %Xh\n", + entrySize, entrySize, + (UINT32)header.size(), (UINT32)header.size(), + (UINT32)body.size(), (UINT32)body.size(), + entry->state(), + entry->flags(), + entry->type(), + entry->namespace_id(), + nameId); + } - // Parse current volume's header - UModelIndex volumeIndex; - result = parseVolumeHeader(volume, headerSize + volumeOffset, index, volumeIndex); - if (result) - msg(UString("parseRawArea: volume header parsing failed with error ") + errorCodeToUString(result), index); + // Mark NameId entries that are not stored as Invalid + if (entry->flags() != DVAR_ENTRY_FLAG_NAME_ID + DVAR_ENTRY_FLAG_NAMESPACE_GUID && + (entry->state() == DVAR_ENTRY_STATE_STORING || + entry->state() == DVAR_ENTRY_STATE_DELETING || + entry->state() == DVAR_ENTRY_STATE_DELETED)) { + subtype = Subtypes::InvalidDvarEntry; + name = UString("Invalid"); + text.clear(); + } + + // Add tree item + model->addItem(entryOffset, Types::DellDvarEntry, subtype, name, text, info, header, body, UByteArray(), Fixed, headerIndex); + + entryOffset += entrySize; + } + } + catch (...) { + // Parsing failed, need to add the candidate as Padding + UByteArray padding = data.mid(itemOffset, itemSize); + + // Get info + name = UString("Padding"); + info = usprintf("Full size: %Xh (%u)", (UINT32)padding.size(), (UINT32)padding.size()); + + // Add tree item + model->addItem(headerSize + itemOffset, Types::Padding, getPaddingType(padding), name, UString(), info, UByteArray(), padding, UByteArray(), Fixed, index); + } + } +#endif else { - // Show messages - if (volumeSize != bmVolumeSize) - msg(usprintf("parseRawArea: volume size stored in header %Xh (%u) differs from calculated using block map %Xh (%u)", - volumeSize, volumeSize, - bmVolumeSize, bmVolumeSize), - volumeIndex); - } - - // Go to next volume - prevVolumeOffset = volumeOffset; - prevVolumeSize = volumeSize; - result = findNextVolume(index, data, offset, volumeOffset + prevVolumeSize, volumeOffset); - } - - // Padding at the end of RAW area - volumeOffset = prevVolumeOffset + prevVolumeSize; - if ((UINT32)data.size() > volumeOffset) { - UByteArray padding = data.mid(volumeOffset); - - // Get info - name = UString("Padding"); - info = usprintf("Full size: %Xh (%u)", padding.size(), padding.size()); - - // Construct parsing data - pdata.offset = offset + headerSize + volumeOffset; - - // Add tree item - model->addItem(Types::Padding, getPaddingType(padding), name, UString(), info, UByteArray(), padding, UByteArray(), true, parsingDataToUByteArray(pdata), index); - } - - // Parse bodies - for (int i = 0; i < model->rowCount(index); i++) { - UModelIndex current = index.child(i, 0); - switch (model->type(current)) { - case Types::Volume: - parseVolumeBody(current); - break; - case Types::Padding: - // No parsing required - break; - default: return U_UNKNOWN_ITEM_TYPE; } + + // Go to next item + prevItemOffset = itemOffset; + prevItemSize = itemSize; + prevItemType = itemType; + result = findNextRawAreaItem(index, itemOffset + prevItemSize, itemType, itemOffset, itemSize, itemAltSize); + + // Silence value not used after assignment warning + (void)prevItemType; } - + + // Padding at the end of raw area + itemOffset = prevItemOffset + prevItemSize; + if ((UINT32)data.size() > itemOffset) { + UByteArray padding = data.mid(itemOffset); + + // Get info + name = UString("Padding"); + info = usprintf("Full size: %Xh (%u)", (UINT32)padding.size(), (UINT32)padding.size()); + + // Add tree item + model->addItem(headerSize + itemOffset, Types::Padding, getPaddingType(padding), name, UString(), info, UByteArray(), padding, UByteArray(), Fixed, index); + } + + // Parse bodies + for (int i = 0; i < model->rowCount(index); i++) { + UModelIndex current = index.model()->index(i, 0, index); + + switch (model->type(current)) { + case Types::Volume: + parseVolumeBody(current); + break; + case Types::Microcode: + // Parsing already done + break; + case Types::BpdtStore: + // Parsing already done + break; + case Types::BpdtPartition: + // Parsing already done + break; + case Types::InsydeFlashDeviceMapStore: + // Parsing already done + break; + case Types::DellDvarStore: + // Parsing already done + break; + case Types::Padding: + // No parsing required + break; + default: + return U_UNKNOWN_ITEM_TYPE; + } + } + return U_SUCCESS; } -USTATUS FfsParser::parseVolumeHeader(const UByteArray & volume, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index) +USTATUS FfsParser::parseVolumeHeader(const UByteArray & volume, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index) { // Sanity check if (volume.isEmpty()) return U_INVALID_PARAMETER; - - // Get parent's parsing data - PARSING_DATA pdata = parsingDataFromUModelIndex(parent); - + // Check that there is space for the volume header - if ((UINT32)volume.size() < sizeof(EFI_FIRMWARE_VOLUME_HEADER)) { - msg(usprintf("parseVolumeHeader: input volume size %Xh (%u) is smaller than volume header size 40h (64)", volume.size(), volume.size())); + if ((UINT32)volume.size() < sizeof(EFI_FIRMWARE_VOLUME_HEADER)) { + msg(usprintf("%s: input volume size %Xh (%u) is smaller than volume header size 40h (64)", __FUNCTION__, (UINT32)volume.size(), (UINT32)volume.size())); return U_INVALID_VOLUME; } - + // Populate volume header const EFI_FIRMWARE_VOLUME_HEADER* volumeHeader = (const EFI_FIRMWARE_VOLUME_HEADER*)(volume.constData()); - + // Check sanity of HeaderLength value if ((UINT32)ALIGN8(volumeHeader->HeaderLength) > (UINT32)volume.size()) { - msg(UString("parseVolumeHeader: volume header overlaps the end of data")); + msg(usprintf("%s: volume header overlaps the end of data", __FUNCTION__)); return U_INVALID_VOLUME; } // Check sanity of ExtHeaderOffset value if (volumeHeader->Revision > 1 && volumeHeader->ExtHeaderOffset && (UINT32)ALIGN8(volumeHeader->ExtHeaderOffset + sizeof(EFI_FIRMWARE_VOLUME_EXT_HEADER)) > (UINT32)volume.size()) { - msg(UString("parseVolumeHeader: extended volume header overlaps the end of data")); + msg(usprintf("%s: extended volume header overlaps the end of data", __FUNCTION__)); return U_INVALID_VOLUME; } - + // Calculate volume header size UINT32 headerSize; - EFI_GUID extendedHeaderGuid = {{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }}; + EFI_GUID extendedHeaderGuid = {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0 }}; bool hasExtendedHeader = false; if (volumeHeader->Revision > 1 && volumeHeader->ExtHeaderOffset) { hasExtendedHeader = true; @@ -991,41 +1405,47 @@ USTATUS FfsParser::parseVolumeHeader(const UByteArray & volume, const UINT32 par headerSize = volumeHeader->ExtHeaderOffset + extendedHeader->ExtHeaderSize; extendedHeaderGuid = extendedHeader->FvName; } - else + else { headerSize = volumeHeader->HeaderLength; - + } + // Extended header end can be unaligned headerSize = ALIGN8(headerSize); - + // Check for volume structure to be known bool isUnknown = true; bool isNvramVolume = false; + bool isMicrocodeVolume = false; UINT8 ffsVersion = 0; - + // Check for FFS v2 volume - UByteArray guid = UByteArray((const char*)volumeHeader->FileSystemGuid.Data, sizeof(EFI_GUID)); + UByteArray guid = UByteArray((const char*)&volumeHeader->FileSystemGuid, sizeof(EFI_GUID)); if (std::find(FFSv2Volumes.begin(), FFSv2Volumes.end(), guid) != FFSv2Volumes.end()) { isUnknown = false; ffsVersion = 2; } - // Check for FFS v3 volume - if (std::find(FFSv3Volumes.begin(), FFSv3Volumes.end(), guid) != FFSv3Volumes.end()) { + else if (std::find(FFSv3Volumes.begin(), FFSv3Volumes.end(), guid) != FFSv3Volumes.end()) { isUnknown = false; ffsVersion = 3; } - // Check for VSS NVRAM volume - if (guid == NVRAM_MAIN_STORE_VOLUME_GUID || guid == NVRAM_ADDITIONAL_STORE_VOLUME_GUID) { + else if (guid == NVRAM_MAIN_STORE_VOLUME_GUID || guid == NVRAM_ADDITIONAL_STORE_VOLUME_GUID) { isUnknown = false; isNvramVolume = true; } - + // Check for Microcode volume + else if (guid == EFI_APPLE_MICROCODE_VOLUME_GUID) { + isUnknown = false; + isMicrocodeVolume = true; + headerSize = EFI_APPLE_MICROCODE_VOLUME_HEADER_SIZE; + } + // Check volume revision and alignment bool msgAlignmentBitsSet = false; bool msgUnaligned = false; bool msgUnknownRevision = false; - UINT32 alignment = 65536; // Default volume alignment is 64K + UINT32 alignment = 0x10000; // Default volume alignment is 64K if (volumeHeader->Revision == 1) { // Acquire alignment capability bit bool alignmentCap = (volumeHeader->Attributes & EFI_FVB_ALIGNMENT_CAP) != 0; @@ -1038,92 +1458,116 @@ USTATUS FfsParser::parseVolumeHeader(const UByteArray & volume, const UINT32 par } else if (volumeHeader->Revision == 2) { // Acquire alignment - alignment = (UINT32)pow(2.0, (int)(volumeHeader->Attributes & EFI_FVB2_ALIGNMENT) >> 16); + alignment = (UINT32)(1UL << ((volumeHeader->Attributes & EFI_FVB2_ALIGNMENT) >> 16)); // Check alignment - if (!isUnknown && !model->compressed(parent) && ((pdata.offset + parentOffset - capsuleOffsetFixup) % alignment)) + if (!isUnknown + && !model->compressed(parent) // Alignment checks don't really make sense for compressed volumes because they have to be extracted into memory, and by that point it's unlikely that the module doing such extraction will misalign them + && ((model->base(parent) + localOffset - imageBase) % alignment) != 0) // Explicit "is not zero" here for better code readability msgUnaligned = true; } - else + else { msgUnknownRevision = true; - + } + // Check attributes // Determine value of empty byte - UINT8 emptyByte = volumeHeader->Attributes & EFI_FVB_ERASE_POLARITY ? '\xFF' : '\x00'; - - // Check for AppleCRC32 and AppleFreeSpaceOffset in ZeroVector + UINT8 emptyByte = volumeHeader->Attributes & EFI_FVB_ERASE_POLARITY ? 0xFF : 0x00; + + // Check for AppleCRC32 and UsedSpace in ZeroVector bool hasAppleCrc32 = false; - bool hasAppleFSO = false; - UINT32 volumeSize = volume.size(); + UINT32 volumeSize = (UINT32)volume.size(); UINT32 appleCrc32 = *(UINT32*)(volume.constData() + 8); - UINT32 appleFSO = *(UINT32*)(volume.constData() + 12); + UINT32 usedSpace = *(UINT32*)(volume.constData() + 12); if (appleCrc32 != 0) { // Calculate CRC32 of the volume body - UINT32 crc = crc32(0, (const UINT8*)(volume.constData() + volumeHeader->HeaderLength), volumeSize - volumeHeader->HeaderLength); + UINT32 crc = (UINT32)crc32(0, (const UINT8*)(volume.constData() + volumeHeader->HeaderLength), volumeSize - volumeHeader->HeaderLength); if (crc == appleCrc32) { hasAppleCrc32 = true; } - - // Check if FreeSpaceOffset is non-zero - if (appleFSO != 0) { - hasAppleFSO = true; - } } - + // Check header checksum by recalculating it bool msgInvalidChecksum = false; + + if (volumeHeader->HeaderLength < sizeof(EFI_FIRMWARE_VOLUME_HEADER)) { + msg(usprintf("%s: input volume header length %04Xh (%hu) is smaller than volume header size", __FUNCTION__, volumeHeader->HeaderLength, volumeHeader->HeaderLength)); + return U_INVALID_VOLUME; + } UByteArray tempHeader((const char*)volumeHeader, volumeHeader->HeaderLength); ((EFI_FIRMWARE_VOLUME_HEADER*)tempHeader.data())->Checksum = 0; UINT16 calculated = calculateChecksum16((const UINT16*)tempHeader.constData(), volumeHeader->HeaderLength); if (volumeHeader->Checksum != calculated) msgInvalidChecksum = true; - + // Get info + if (headerSize >= (UINT32)volume.size()) { + return U_INVALID_VOLUME; + } UByteArray header = volume.left(headerSize); UByteArray body = volume.mid(headerSize); UString name = guidToUString(volumeHeader->FileSystemGuid); - UString info = usprintf("Signature: _FVH\nZeroVector:\n%02X %02X %02X %02X %02X %02X %02X %02X\n" - "%02X %02X %02X %02X %02X %02X %02X %02X\nFileSystem GUID: ", - volumeHeader->ZeroVector[0], volumeHeader->ZeroVector[1], volumeHeader->ZeroVector[2], volumeHeader->ZeroVector[3], - volumeHeader->ZeroVector[4], volumeHeader->ZeroVector[5], volumeHeader->ZeroVector[6], volumeHeader->ZeroVector[7], - volumeHeader->ZeroVector[8], volumeHeader->ZeroVector[9], volumeHeader->ZeroVector[10], volumeHeader->ZeroVector[11], - volumeHeader->ZeroVector[12], volumeHeader->ZeroVector[13], volumeHeader->ZeroVector[14], volumeHeader->ZeroVector[15]) - + guidToUString(volumeHeader->FileSystemGuid) \ - + usprintf("\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nRevision: %u\nAttributes: %08Xh\nErase polarity: %u\nChecksum: %04Xh", - volumeSize, volumeSize, - headerSize, headerSize, - volumeSize - headerSize, volumeSize - headerSize, - volumeHeader->Revision, - volumeHeader->Attributes, - (emptyByte ? 1 : 0), - volumeHeader->Checksum) + - (msgInvalidChecksum ? usprintf(", invalid, should be %04Xh", calculated) : UString(", valid")); - - // Extended header present + UString info = usprintf("ZeroVector:\n%02X %02X %02X %02X %02X %02X %02X %02X\n" + "%02X %02X %02X %02X %02X %02X %02X %02X\nSignature: _FVH\nFileSystem GUID: ", + volumeHeader->ZeroVector[0], volumeHeader->ZeroVector[1], volumeHeader->ZeroVector[2], volumeHeader->ZeroVector[3], + volumeHeader->ZeroVector[4], volumeHeader->ZeroVector[5], volumeHeader->ZeroVector[6], volumeHeader->ZeroVector[7], + volumeHeader->ZeroVector[8], volumeHeader->ZeroVector[9], volumeHeader->ZeroVector[10], volumeHeader->ZeroVector[11], + volumeHeader->ZeroVector[12], volumeHeader->ZeroVector[13], volumeHeader->ZeroVector[14], volumeHeader->ZeroVector[15]) + + guidToUString(volumeHeader->FileSystemGuid, false) \ + + usprintf("\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nRevision: %u\nAttributes: %08Xh\nErase polarity: %u\nChecksum: %04Xh", + volumeSize, volumeSize, + headerSize, headerSize, + volumeSize - headerSize, volumeSize - headerSize, + volumeHeader->Revision, + volumeHeader->Attributes, + (emptyByte ? 1 : 0), + volumeHeader->Checksum) + + (msgInvalidChecksum ? usprintf(", invalid, should be %04Xh", calculated) : UString(", valid")); + + // Block size and blocks number + const EFI_FV_BLOCK_MAP_ENTRY* entry = (const EFI_FV_BLOCK_MAP_ENTRY*)(volume.constData() + sizeof(EFI_FIRMWARE_VOLUME_HEADER)); + UString infoNumBlocks = usprintf("NumBlocks: %Xh (%u)", entry->NumBlocks, entry->NumBlocks); + UString infoLength = usprintf("Length: %Xh (%u)", entry->Length, entry->Length); + if (entry->NumBlocks == 0) { + infoNumBlocks += UString(", invalid, can not be zero"); + } + if (entry->Length == 0) { + infoLength += UString(", invalid, can not be zero"); + } + if (entry->NumBlocks != 0 && entry->Length != 0) { + UINT32 volumeAltSize = entry->NumBlocks * entry->Length; + if (volumeSize != volumeAltSize) { + if (volumeAltSize % entry->Length == 0 && volumeSize % entry->Length == 0) { + infoNumBlocks += usprintf(", invalid, should be %Xh", volumeSize / entry->Length); + infoLength += ", valid"; + } + else if (volumeAltSize % entry->NumBlocks == 0 && volumeSize % entry->NumBlocks == 0) { + infoNumBlocks += ", valid"; + infoLength += usprintf(", invalid, should be %Xh", volumeSize / entry->NumBlocks); + } + } + else { + infoNumBlocks += ", valid"; + infoLength += ", valid"; + } + } + info += "\n" + infoNumBlocks + "\n" + infoLength; + + // Extended header if (volumeHeader->Revision > 1 && volumeHeader->ExtHeaderOffset) { + if ((UINT32)volume.size() < volumeHeader->ExtHeaderOffset + sizeof(EFI_FIRMWARE_VOLUME_EXT_HEADER)) { + return U_INVALID_VOLUME; + } const EFI_FIRMWARE_VOLUME_EXT_HEADER* extendedHeader = (const EFI_FIRMWARE_VOLUME_EXT_HEADER*)(volume.constData() + volumeHeader->ExtHeaderOffset); info += usprintf("\nExtended header size: %Xh (%u)\nVolume GUID: ", - extendedHeader->ExtHeaderSize, extendedHeader->ExtHeaderSize) + guidToUString(extendedHeader->FvName); + extendedHeader->ExtHeaderSize, extendedHeader->ExtHeaderSize) + guidToUString(extendedHeader->FvName, false); + name = guidToUString(extendedHeader->FvName); // Replace FFS GUID with volume GUID } - - // Construct parsing data - pdata.offset += parentOffset; - pdata.emptyByte = emptyByte; - pdata.ffsVersion = ffsVersion; - pdata.volume.hasExtendedHeader = hasExtendedHeader ? TRUE : FALSE; - pdata.volume.extendedHeaderGuid = extendedHeaderGuid; - pdata.volume.alignment = alignment; - pdata.volume.revision = volumeHeader->Revision; - pdata.volume.hasAppleCrc32 = hasAppleCrc32; - pdata.volume.hasAppleFSO = hasAppleFSO; - pdata.volume.isWeakAligned = (volumeHeader->Revision > 1 && (volumeHeader->Attributes & EFI_FVB2_WEAK_ALIGNMENT)); - + // Add text UString text; if (hasAppleCrc32) text += UString("AppleCRC32 "); - if (hasAppleFSO) - text += UString("AppleFSO "); - + // Add tree item UINT8 subtype = Subtypes::UnknownVolume; if (!isUnknown) { @@ -1133,466 +1577,731 @@ USTATUS FfsParser::parseVolumeHeader(const UByteArray & volume, const UINT32 par subtype = Subtypes::Ffs3Volume; else if (isNvramVolume) subtype = Subtypes::NvramVolume; + else if (isMicrocodeVolume) + subtype = Subtypes::MicrocodeVolume; } - index = model->addItem(Types::Volume, subtype, name, text, info, header, body, UByteArray(), true, parsingDataToUByteArray(pdata), parent); - + index = model->addItem(localOffset, Types::Volume, subtype, name, text, info, header, body, UByteArray(), Movable, parent); + + // Set parsing data for created volume + VOLUME_PARSING_DATA pdata = {}; + pdata.emptyByte = emptyByte; + pdata.ffsVersion = ffsVersion; + pdata.hasExtendedHeader = hasExtendedHeader ? TRUE : FALSE; + pdata.extendedHeaderGuid = extendedHeaderGuid; + pdata.alignment = alignment; + pdata.revision = volumeHeader->Revision; + pdata.hasAppleCrc32 = hasAppleCrc32; + pdata.hasValidUsedSpace = FALSE; // Will be updated later, if needed + pdata.usedSpace = usedSpace; + pdata.isWeakAligned = (volumeHeader->Revision > 1 && (volumeHeader->Attributes & EFI_FVB2_WEAK_ALIGNMENT)); + model->setParsingData(index, UByteArray((const char*)&pdata, sizeof(pdata))); + // Show messages if (isUnknown) - msg(UString("parseVolumeHeader: unknown file system ") + guidToUString(volumeHeader->FileSystemGuid), index); + msg(usprintf("%s: unknown file system ", __FUNCTION__) + guidToUString(volumeHeader->FileSystemGuid), index); if (msgInvalidChecksum) - msg(UString("parseVolumeHeader: volume header checksum is invalid"), index); + msg(usprintf("%s: volume header checksum is invalid", __FUNCTION__), index); if (msgAlignmentBitsSet) - msg(UString("parseVolumeHeader: alignment bits set on volume without alignment capability"), index); + msg(usprintf("%s: alignment bits set on volume without alignment capability", __FUNCTION__), index); if (msgUnaligned) - msg(UString("parseVolumeHeader: unaligned volume"), index); + msg(usprintf("%s: unaligned volume", __FUNCTION__), index); if (msgUnknownRevision) - msg(usprintf("parseVolumeHeader: unknown volume revision %u", volumeHeader->Revision), index); - + msg(usprintf("%s: unknown volume revision %u", __FUNCTION__, volumeHeader->Revision), index); + return U_SUCCESS; } -USTATUS FfsParser::findNextVolume(const UModelIndex & index, const UByteArray & bios, const UINT32 parentOffset, const UINT32 volumeOffset, UINT32 & nextVolumeOffset) +bool FfsParser::microcodeHeaderValid(const INTEL_MICROCODE_HEADER* ucodeHeader) { - int nextIndex = bios.indexOf(EFI_FV_SIGNATURE, volumeOffset); - if (nextIndex < EFI_FV_SIGNATURE_OFFSET) - return U_VOLUMES_NOT_FOUND; - - // Check volume header to be sane - for (; nextIndex > 0; nextIndex = bios.indexOf(EFI_FV_SIGNATURE, nextIndex + 1)) { - const EFI_FIRMWARE_VOLUME_HEADER* volumeHeader = (const EFI_FIRMWARE_VOLUME_HEADER*)(bios.constData() + nextIndex - EFI_FV_SIGNATURE_OFFSET); - if (volumeHeader->FvLength < sizeof(EFI_FIRMWARE_VOLUME_HEADER) + 2 * sizeof(EFI_FV_BLOCK_MAP_ENTRY) || volumeHeader->FvLength >= 0xFFFFFFFFUL) { - msg(usprintf("findNextVolume: volume candidate at offset %Xh skipped, has invalid FvLength %" PRIX64 "h", - parentOffset + (nextIndex - EFI_FV_SIGNATURE_OFFSET), - volumeHeader->FvLength), index); - continue; - } - if (volumeHeader->Reserved != 0xFF && volumeHeader->Reserved != 0x00) { - msg(usprintf("findNextVolume: volume candidate at offset %Xh skipped, has invalid Reserved byte value %02Xh", - parentOffset + (nextIndex - EFI_FV_SIGNATURE_OFFSET), - volumeHeader->Reserved), index); - continue; - } - if (volumeHeader->Revision != 1 && volumeHeader->Revision != 2) { - msg(usprintf("findNextVolume: volume candidate at offset %Xh skipped, has invalid Revision byte value %02Xh", - parentOffset + (nextIndex - EFI_FV_SIGNATURE_OFFSET) - ,volumeHeader->Revision), index); - continue; - } - // All checks passed, volume found - break; + bool reservedBytesValid = true; + + // Check data size to be multiple of 4 and less than 0x1000000 + if (ucodeHeader->DataSize % 4 != 0 || + ucodeHeader->DataSize > 0xFFFFFF) { + return false; } - // No more volumes found - if (nextIndex < EFI_FV_SIGNATURE_OFFSET) - return U_VOLUMES_NOT_FOUND; - - nextVolumeOffset = nextIndex - EFI_FV_SIGNATURE_OFFSET; - return U_SUCCESS; + + // Check TotalSize to be greater or equal than DataSize and less than 0x1000000 + if (ucodeHeader->TotalSize < ucodeHeader->DataSize || + ucodeHeader->TotalSize > 0xFFFFFF) { + return false; + } + + // Check date to be sane + // Check day to be in 0x01-0x09, 0x10-0x19, 0x20-0x29, 0x30-0x31 + if (ucodeHeader->DateDay < 0x01 || + (ucodeHeader->DateDay > 0x09 && ucodeHeader->DateDay < 0x10) || + (ucodeHeader->DateDay > 0x19 && ucodeHeader->DateDay < 0x20) || + (ucodeHeader->DateDay > 0x29 && ucodeHeader->DateDay < 0x30) || + ucodeHeader->DateDay > 0x31) { + return false; + } + // Check month to be in 0x01-0x09, 0x10-0x12 + if (ucodeHeader->DateMonth < 0x01 || + (ucodeHeader->DateMonth > 0x09 && ucodeHeader->DateMonth < 0x10) || + ucodeHeader->DateMonth > 0x12) { + return FALSE; + } + // Check year to be in 0x1990-0x1999, 0x2000-0x2009, 0x2010-0x2019, 0x2020-0x2029, 0x2030-0x2030, 0x2040-0x2049 + if (ucodeHeader->DateYear < 0x1990 || + (ucodeHeader->DateYear > 0x1999 && ucodeHeader->DateYear < 0x2000) || + (ucodeHeader->DateYear > 0x2009 && ucodeHeader->DateYear < 0x2010) || + (ucodeHeader->DateYear > 0x2019 && ucodeHeader->DateYear < 0x2020) || + (ucodeHeader->DateYear > 0x2029 && ucodeHeader->DateYear < 0x2030) || + (ucodeHeader->DateYear > 0x2039 && ucodeHeader->DateYear < 0x2040) || + ucodeHeader->DateYear > 0x2049) { + return FALSE; + } + // Check HeaderType to be 1. + if (ucodeHeader->HeaderType != 1) { + return FALSE; + } + // Check LoaderRevision to be 1. + if (ucodeHeader->LoaderRevision != 1) { + return FALSE; + } + + return TRUE; } -USTATUS FfsParser::getVolumeSize(const UByteArray & bios, UINT32 volumeOffset, UINT32 & volumeSize, UINT32 & bmVolumeSize) +USTATUS FfsParser::findNextRawAreaItem(const UModelIndex & index, const UINT32 localOffset, UINT8 & nextItemType, UINT32 & nextItemOffset, UINT32 & nextItemSize, UINT32 & nextItemAlternativeSize) { - // Check that there is space for the volume header and at least two block map entries. - if ((UINT32)bios.size() < volumeOffset + sizeof(EFI_FIRMWARE_VOLUME_HEADER) + 2 * sizeof(EFI_FV_BLOCK_MAP_ENTRY)) - return U_INVALID_VOLUME; + UByteArray data = model->body(index); + UINT32 dataSize = (UINT32)data.size(); + + if (dataSize < sizeof(UINT32)) + return U_STORES_NOT_FOUND; + + UINT32 offset = localOffset; + for (; offset < dataSize - sizeof(UINT32); offset++) { + const UINT32* currentPos = (const UINT32*)(data.constData() + offset); + UINT32 restSize = dataSize - offset; + if (readUnaligned(currentPos) == INTEL_MICROCODE_HEADER_VERSION_1) { // Intel microcode + // Check data size + if (restSize < sizeof(INTEL_MICROCODE_HEADER)) { + continue; + } + + // Check microcode header candidate + const INTEL_MICROCODE_HEADER* ucodeHeader = (const INTEL_MICROCODE_HEADER*)currentPos; + if (FALSE == microcodeHeaderValid(ucodeHeader)) { + continue; + } + + // Check size candidate + if (ucodeHeader->TotalSize == 0) + continue; + + // All checks passed, microcode found + nextItemType = Types::Microcode; + nextItemSize = ucodeHeader->TotalSize; + nextItemAlternativeSize = ucodeHeader->TotalSize; + nextItemOffset = offset; + break; + } + else if (readUnaligned(currentPos) == EFI_FV_SIGNATURE) { + if (offset < EFI_FV_SIGNATURE_OFFSET) + continue; - // Populate volume header - const EFI_FIRMWARE_VOLUME_HEADER* volumeHeader = (const EFI_FIRMWARE_VOLUME_HEADER*)(bios.constData() + volumeOffset); + // Prevent OOB access + if (restSize + EFI_FV_SIGNATURE_OFFSET < sizeof(EFI_FIRMWARE_VOLUME_HEADER)) { + continue; + } + const EFI_FIRMWARE_VOLUME_HEADER* volumeHeader = (const EFI_FIRMWARE_VOLUME_HEADER*)(data.constData() + offset - EFI_FV_SIGNATURE_OFFSET); + restSize -= sizeof(EFI_FIRMWARE_VOLUME_HEADER); + if (volumeHeader->FvLength < sizeof(EFI_FIRMWARE_VOLUME_HEADER) + 2 * sizeof(EFI_FV_BLOCK_MAP_ENTRY) || volumeHeader->FvLength >= 0xFFFFFFFFUL) { + continue; + } + if (volumeHeader->Revision != 1 && volumeHeader->Revision != 2) { + continue; + } + + // Calculate alternative volume size using its BlockMap + nextItemAlternativeSize = 0; - // Check volume signature - if (UByteArray((const char*)&volumeHeader->Signature, sizeof(volumeHeader->Signature)) != EFI_FV_SIGNATURE) - return U_INVALID_VOLUME; - - // Calculate volume size using BlockMap - const EFI_FV_BLOCK_MAP_ENTRY* entry = (const EFI_FV_BLOCK_MAP_ENTRY*)(bios.constData() + volumeOffset + sizeof(EFI_FIRMWARE_VOLUME_HEADER)); - UINT32 calcVolumeSize = 0; - while (entry->NumBlocks != 0 && entry->Length != 0) { - if ((void*)entry > bios.constData() + bios.size()) - return U_INVALID_VOLUME; - - calcVolumeSize += entry->NumBlocks * entry->Length; - entry += 1; + // Prevent OOB access + if (restSize + EFI_FV_SIGNATURE_OFFSET < sizeof(EFI_FIRMWARE_VOLUME_HEADER)) { + continue; + } + const EFI_FV_BLOCK_MAP_ENTRY* entry = (const EFI_FV_BLOCK_MAP_ENTRY*)(data.constData() + offset - EFI_FV_SIGNATURE_OFFSET + sizeof(EFI_FIRMWARE_VOLUME_HEADER)); + restSize -= sizeof(EFI_FV_BLOCK_MAP_ENTRY); + while (entry->NumBlocks != 0 && entry->Length != 0) { + // Check if we are past the end of the volume + if (restSize + EFI_FV_SIGNATURE_OFFSET < sizeof(EFI_FV_BLOCK_MAP_ENTRY)) { + // This volume is broken, but we can't use continue here because we need to continue the outer loop + goto continue_searching; + } + + nextItemAlternativeSize += entry->NumBlocks * entry->Length; + restSize -= sizeof(EFI_FV_BLOCK_MAP_ENTRY); + entry += 1; + } + + // All checks passed, volume found + nextItemType = Types::Volume; + nextItemSize = (UINT32)volumeHeader->FvLength; + nextItemOffset = offset - EFI_FV_SIGNATURE_OFFSET; + break; +continue_searching: {} + } + else if (readUnaligned(currentPos) == BPDT_GREEN_SIGNATURE + || readUnaligned(currentPos) == BPDT_YELLOW_SIGNATURE) { + // Check data size + if (restSize < sizeof(BPDT_HEADER)) + continue; + + const BPDT_HEADER *bpdtHeader = (const BPDT_HEADER *)currentPos; + + // Check NumEntries to be sane + if (bpdtHeader->NumEntries > 0x100) + continue; + + // Check HeaderVersion to be 1 + if (bpdtHeader->HeaderVersion != BPDT_HEADER_VERSION_1) // Check only for IFWI 2.0 headers in raw areas + continue; + + // Check RedundancyFlag to be 0 or 1 + if (bpdtHeader->RedundancyFlag != 0 && bpdtHeader->RedundancyFlag != 1) // Check only for IFWI 2.0 headers in raw areas + continue; + + UINT32 ptBodySize = bpdtHeader->NumEntries * sizeof(BPDT_ENTRY); + UINT32 ptSize = sizeof(BPDT_HEADER) + ptBodySize; + // Check data size again + if (restSize < ptSize) + continue; + + UINT32 sizeCandidate = 0; + // Parse partition table + const BPDT_ENTRY* firstPtEntry = (const BPDT_ENTRY*)((const UINT8*)bpdtHeader + sizeof(BPDT_HEADER)); + for (UINT16 i = 0; i < bpdtHeader->NumEntries; i++) { + // Populate entry header + const BPDT_ENTRY* ptEntry = firstPtEntry + i; + // Check that entry is present in the image + if (ptEntry->Offset != 0 + && ptEntry->Offset != 0xFFFFFFFF + && ptEntry->Size != 0 + && sizeCandidate < ptEntry->Offset + ptEntry->Size) { + sizeCandidate = ptEntry->Offset + ptEntry->Size; + } + } + + // Check size candidate + if (sizeCandidate == 0 || sizeCandidate > restSize) { + msg(usprintf("%s: invalid BpdtStore size (sizeCandidate = %Xh, restSize = %Xh)", __FUNCTION__, sizeCandidate, restSize), index); + continue; + } + + // All checks passed, BPDT found + nextItemType = Types::BpdtStore; + nextItemSize = sizeCandidate; + nextItemAlternativeSize = sizeCandidate; + nextItemOffset = offset; + break; + } + else if (readUnaligned(currentPos) == INSYDE_FLASH_DEVICE_MAP_SIGNATURE) { + // Check data size + if (restSize < sizeof(INSYDE_FLASH_DEVICE_MAP_HEADER)) + continue; + + const INSYDE_FLASH_DEVICE_MAP_HEADER *fdmHeader = (const INSYDE_FLASH_DEVICE_MAP_HEADER *)currentPos; + + if (restSize < fdmHeader->Size) + continue; + + if (fdmHeader->Revision > 4) { + msg(usprintf("%s: Insyde Flash Device Map candidate with unknown revision %u", __FUNCTION__, fdmHeader->Revision), index); + continue; + } + + // All checks passed, FDM found + nextItemType = Types::InsydeFlashDeviceMapStore; + nextItemSize = fdmHeader->Size; + nextItemAlternativeSize = fdmHeader->Size; + nextItemOffset = offset; + break; + } +#ifdef U_ENABLE_NVRAM_PARSING_SUPPORT + else if (readUnaligned(currentPos) == DVAR_STORE_SIGNATURE) { + // Check data size + if (restSize < sizeof(DVAR_STORE_HEADER)) + continue; + + const DVAR_STORE_HEADER *dvarHeader = (const DVAR_STORE_HEADER *)currentPos; + UINT32 storeSize = 0xFFFFFFFF - dvarHeader->StoreSizeC; + if (restSize < storeSize) + continue; + + // All checks passed, FDM found + nextItemType = Types::DellDvarStore; + nextItemSize = storeSize; + nextItemAlternativeSize = storeSize; + nextItemOffset = offset; + break; + } +#endif } - - volumeSize = (UINT32)volumeHeader->FvLength; - bmVolumeSize = calcVolumeSize; - - if (volumeSize == 0) - return U_INVALID_VOLUME; - + + // No more stores found + if (offset >= dataSize - sizeof(UINT32)) { + return U_STORES_NOT_FOUND; + } + return U_SUCCESS; } -USTATUS FfsParser::parseVolumeNonUefiData(const UByteArray & data, const UINT32 parentOffset, const UModelIndex & index) +USTATUS FfsParser::parseVolumeNonUefiData(const UByteArray & data, const UINT32 localOffset, const UModelIndex & index) { // Sanity check if (!index.isValid()) return U_INVALID_PARAMETER; - - // Get parsing data - PARSING_DATA pdata = parsingDataFromUModelIndex(index); - - // Add parent offset - pdata.offset += parentOffset; - + // Get info - UString info = usprintf("Full size: %Xh (%u)", data.size(), data.size()); - + UString info = usprintf("Full size: %Xh (%u)", (UINT32)data.size(), (UINT32)data.size()); + // Add padding tree item - UModelIndex paddingIndex = model->addItem(Types::Padding, Subtypes::DataPadding, UString("Non-UEFI data"), UString(), info, UByteArray(), data, UByteArray(), true, parsingDataToUByteArray(pdata), index); - msg(UString("parseVolumeNonUefiData: non-UEFI data found in volume's free space"), paddingIndex); - - // Parse contents as RAW area + UModelIndex paddingIndex = model->addItem(localOffset, Types::Padding, Subtypes::DataPadding, UString("Non-UEFI data"), UString(), info, UByteArray(), data, UByteArray(), Fixed, index); + msg(usprintf("%s: non-UEFI data found in volume free space", __FUNCTION__), paddingIndex); + + // Parse contents as raw area return parseRawArea(paddingIndex); } USTATUS FfsParser::parseVolumeBody(const UModelIndex & index) { // Sanity check - if (!index.isValid()) + if (!index.isValid()) { return U_INVALID_PARAMETER; - + } + // Get volume header size and body UByteArray volumeBody = model->body(index); - UINT32 volumeHeaderSize = model->header(index).size(); - - // Get parsing data - PARSING_DATA pdata = parsingDataFromUModelIndex(index); - UINT32 offset = pdata.offset; - - // Parse VSS NVRAM volumes with a dedicated function - if (model->subtype(index) == Subtypes::NvramVolume) - return parseNvramVolumeBody(index); - - if (pdata.ffsVersion != 2 && pdata.ffsVersion != 3) // Don't parse unknown volumes + UINT32 volumeHeaderSize = (UINT32)model->header(index).size(); + + // Parse NVRAM volume with a dedicated function + if (model->subtype(index) == Subtypes::NvramVolume) { + return nvramParser->parseNvramVolumeBody(index); + } + + // Parse Microcode volume with a dedicated function + if (model->subtype(index) == Subtypes::MicrocodeVolume) { + return parseMicrocodeVolumeBody(index); + } + + // Get required values from parsing data + UINT8 emptyByte = 0xFF; + UINT8 ffsVersion = 2; + UINT32 usedSpace = 0; + UINT8 revision = 2; + if (model->hasEmptyParsingData(index) == false) { + UByteArray data = model->parsingData(index); + const VOLUME_PARSING_DATA* pdata = (const VOLUME_PARSING_DATA*)data.constData(); + emptyByte = pdata->emptyByte; + ffsVersion = pdata->ffsVersion; + usedSpace = pdata->usedSpace; + revision = pdata->revision; + } + + // Check for unknown FFS version + if (ffsVersion != 2 && ffsVersion != 3) { + msg(usprintf("%s: unknown FFS version %d", __FUNCTION__, ffsVersion), index); return U_SUCCESS; - + } + // Search for and parse all files - UINT32 volumeBodySize = volumeBody.size(); + UINT32 volumeBodySize = (UINT32)volumeBody.size(); UINT32 fileOffset = 0; while (fileOffset < volumeBodySize) { - UINT32 fileSize = getFileSize(volumeBody, fileOffset, pdata.ffsVersion); - // Check file size - if (fileSize < sizeof(EFI_FFS_FILE_HEADER) || fileSize > volumeBodySize - fileOffset) { - // Check that we are at the empty space - UByteArray header = volumeBody.mid(fileOffset, sizeof(EFI_FFS_FILE_HEADER)); - if (header.count(pdata.emptyByte) == header.size()) { //Empty space - // Check free space to be actually free - UByteArray freeSpace = volumeBody.mid(fileOffset); - if (freeSpace.count(pdata.emptyByte) != freeSpace.size()) { - // Search for the first non-empty byte - UINT32 i; - UINT32 size = freeSpace.size(); - const UINT8* current = (UINT8*)freeSpace.constData(); - for (i = 0; i < size; i++) { - if (*current++ != pdata.emptyByte) - break; - } - - // Align found index to file alignment - // It must be possible because minimum 16 bytes of empty were found before - if (i != ALIGN8(i)) - i = ALIGN8(i) - 8; - - // Construct parsing data - pdata.offset = offset + volumeHeaderSize + fileOffset; - - // Add all bytes before as free space - if (i > 0) { - UByteArray free = freeSpace.left(i); - - // Get info - UString info = usprintf("Full size: %Xh (%u)", free.size(), free.size()); - - // Add free space item - model->addItem(Types::FreeSpace, 0, UString("Volume free space"), UString(), info, UByteArray(), free, UByteArray(), false, parsingDataToUByteArray(pdata), index); - } - - // Parse non-UEFI data - parseVolumeNonUefiData(freeSpace.mid(i), volumeHeaderSize + fileOffset + i, index); + UINT32 fileSize = getFileSize(volumeBody, fileOffset, ffsVersion, revision); + + if (fileSize == 0) { + msg(usprintf("%s: file header parsing failed with invalid size", __FUNCTION__), index); + break; // Exit from parsing loop + } + + // Check that we are at the empty space + UByteArray header = volumeBody.mid(fileOffset, (int)std::min(sizeof(EFI_FFS_FILE_HEADER), (size_t)volumeBodySize - fileOffset)); + if (header.count(emptyByte) == header.size()) { //Empty space + // Check volume usedSpace entry to be valid + if (usedSpace > 0 && usedSpace == fileOffset + volumeHeaderSize) { + if (model->hasEmptyParsingData(index) == false) { + UByteArray data = model->parsingData(index); + VOLUME_PARSING_DATA* pdata = (VOLUME_PARSING_DATA*)data.data(); + pdata->hasValidUsedSpace = TRUE; + model->setParsingData(index, data); + model->setText(index, model->text(index) + "UsedSpace "); } - else { - // Construct parsing data - pdata.offset = offset + volumeHeaderSize + fileOffset; - + } + + // Check free space to be actually free + UByteArray freeSpace = volumeBody.mid(fileOffset); + if (freeSpace.count(emptyByte) != freeSpace.size()) { + // Search for the first non-empty byte + UINT32 i; + UINT32 size = (UINT32)freeSpace.size(); + const UINT8* current = (UINT8*)freeSpace.constData(); + for (i = 0; i < size; i++) { + if (*current++ != emptyByte) { + break; // Exit from parsing loop + } + } + + // Align found index to file alignment + // It must be possible because minimum 16 bytes of empty were found before + if (i != ALIGN8(i)) { + i = ALIGN8(i) - 8; + } + + // Add all bytes before as free space + if (i > 0) { + UByteArray free = freeSpace.left(i); + // Get info - UString info = usprintf("Full size: %Xh (%u)", freeSpace.size(), freeSpace.size()); - + UString info = usprintf("Full size: %Xh (%u)", (UINT32)free.size(), (UINT32)free.size()); + // Add free space item - model->addItem(Types::FreeSpace, 0, UString("Volume free space"), UString(), info, UByteArray(), freeSpace, UByteArray(), false, parsingDataToUByteArray(pdata), index); + model->addItem(volumeHeaderSize + fileOffset, Types::FreeSpace, 0, UString("Volume free space"), UString(), info, UByteArray(), free, UByteArray(), Movable, index); } - break; // Exit from parsing loop + + // Parse non-UEFI data + parseVolumeNonUefiData(freeSpace.mid(i), volumeHeaderSize + fileOffset + i, index); } - else { //File space - // Parse non-UEFI data - parseVolumeNonUefiData(volumeBody.mid(fileOffset), volumeHeaderSize + fileOffset, index); - break; // Exit from parsing loop + else { + // Get info + UString info = usprintf("Full size: %Xh (%u)", (UINT32)freeSpace.size(), (UINT32)freeSpace.size()); + + // Add free space item + model->addItem(volumeHeaderSize + fileOffset, Types::FreeSpace, 0, UString("Volume free space"), UString(), info, UByteArray(), freeSpace, UByteArray(), Movable, index); } + + break; // Exit from parsing loop } - - // Get file header - UByteArray file = volumeBody.mid(fileOffset, fileSize); - UByteArray header = file.left(sizeof(EFI_FFS_FILE_HEADER)); - const EFI_FFS_FILE_HEADER* fileHeader = (const EFI_FFS_FILE_HEADER*)header.constData(); - if (pdata.ffsVersion == 3 && (fileHeader->Attributes & FFS_ATTRIB_LARGE_FILE)) { - header = file.left(sizeof(EFI_FFS_FILE_HEADER2)); + + // We aren't at the end of empty space + // Check that the remaining space can still have a file in it + if (volumeBodySize - fileOffset < sizeof(EFI_FFS_FILE_HEADER) // Remaining space is smaller than the smallest possible file + || volumeBodySize - fileOffset < fileSize) { // Remaining space is smaller than non-empty file size + // Parse non-UEFI data + parseVolumeNonUefiData(volumeBody.mid(fileOffset), volumeHeaderSize + fileOffset, index); + + break; // Exit from parsing loop } - - //Parse current file's header + + // Parse current file's header UModelIndex fileIndex; - USTATUS result = parseFileHeader(file, volumeHeaderSize + fileOffset, index, fileIndex); - if (result) - msg(UString("parseVolumeBody: file header parsing failed with error ") + errorCodeToUString(result), index); - + USTATUS result = parseFileHeader(volumeBody.mid(fileOffset, fileSize), volumeHeaderSize + fileOffset, index, fileIndex); + if (result) { + msg(usprintf("%s: file header parsing failed with error ", __FUNCTION__) + errorCodeToUString(result), index); + } + // Move to next file fileOffset += fileSize; + // TODO: check that alignment bytes are all of erase polarity bit, warn if not so fileOffset = ALIGN8(fileOffset); } - + // Check for duplicate GUIDs for (int i = 0; i < model->rowCount(index); i++) { - UModelIndex current = index.child(i, 0); - // Skip non-file entries and pad files - if (model->type(current) != Types::File || model->subtype(current) == EFI_FV_FILETYPE_PAD) - continue; + UModelIndex current = index.model()->index(i, 0, index); + + // Skip non-file entries and padding files + if (model->type(current) != Types::File + || model->subtype(current) == EFI_FV_FILETYPE_PAD) { + continue; + } + + // Get current file GUID + UByteArray currentGuid(model->header(current).constData(), sizeof(EFI_GUID)); - // Get current file parsing data - PARSING_DATA currentPdata = parsingDataFromUModelIndex(current); - UByteArray currentGuid((const char*)¤tPdata.file.guid, sizeof(EFI_GUID)); - // Check files after current for having an equal GUID for (int j = i + 1; j < model->rowCount(index); j++) { - UModelIndex another = index.child(j, 0); - - // Skip non-file entries - if (model->type(another) != Types::File) - continue; + UModelIndex another = index.model()->index(j, 0, index); + + // Skip non-file entries + if (model->type(another) != Types::File) { + continue; + } + + // Get another file GUID + UByteArray anotherGuid(model->header(another).constData(), sizeof(EFI_GUID)); - // Get another file parsing data - PARSING_DATA anotherPdata = parsingDataFromUModelIndex(another); - UByteArray anotherGuid((const char*)&anotherPdata.file.guid, sizeof(EFI_GUID)); - // Check GUIDs for being equal if (currentGuid == anotherGuid) { - msg(UString("parseVolumeBody: file with duplicate GUID ") + guidToUString(anotherPdata.file.guid), another); + msg(usprintf("%s: file with duplicate GUID ", __FUNCTION__) + guidToUString(readUnaligned((EFI_GUID*)(anotherGuid.data()))), another); } } } - - //Parse bodies + + // Parse bodies for (int i = 0; i < model->rowCount(index); i++) { - UModelIndex current = index.child(i, 0); + UModelIndex current = index.model()->index(i, 0, index); + switch (model->type(current)) { - case Types::File: - parseFileBody(current); - break; - case Types::Padding: - case Types::FreeSpace: - // No parsing required - break; - default: - return U_UNKNOWN_ITEM_TYPE; + case Types::File: + parseFileBody(current); + break; + case Types::Padding: + case Types::FreeSpace: + // No parsing required + break; + default: + return U_UNKNOWN_ITEM_TYPE; } } - + return U_SUCCESS; } -UINT32 FfsParser::getFileSize(const UByteArray & volume, const UINT32 fileOffset, const UINT8 ffsVersion) +UINT32 FfsParser::getFileSize(const UByteArray & volume, const UINT32 fileOffset, const UINT8 ffsVersion, const UINT8 revision) { + if ((UINT32)volume.size() < fileOffset + sizeof(EFI_FFS_FILE_HEADER)) { + return 0; + } + + const EFI_FFS_FILE_HEADER* fileHeader = (const EFI_FFS_FILE_HEADER*)(volume.constData() + fileOffset); + if (ffsVersion == 2) { - if ((UINT32)volume.size() < fileOffset + sizeof(EFI_FFS_FILE_HEADER)) - return 0; - const EFI_FFS_FILE_HEADER* fileHeader = (const EFI_FFS_FILE_HEADER*)(volume.constData() + fileOffset); - return uint24ToUint32(fileHeader->Size); + UINT32 size = uint24ToUint32(fileHeader->Size); + // Special case of Lenovo large file insize FFSv2 Rev2 volume + if (revision == 2 && (fileHeader->Attributes & FFS_ATTRIB_LARGE_FILE)) { + if ((UINT32)volume.size() < fileOffset + sizeof(EFI_FFS_FILE_HEADER2_LENOVO)) { + return 0; + } + + const EFI_FFS_FILE_HEADER2_LENOVO* fileHeader2Lenovo = (const EFI_FFS_FILE_HEADER2_LENOVO*)(volume.constData() + fileOffset); + return (UINT32)fileHeader2Lenovo->ExtendedSize; + } + + return size; } else if (ffsVersion == 3) { - if ((UINT32)volume.size() < fileOffset + sizeof(EFI_FFS_FILE_HEADER2)) - return 0; - const EFI_FFS_FILE_HEADER2* fileHeader = (const EFI_FFS_FILE_HEADER2*)(volume.constData() + fileOffset); - if (fileHeader->Attributes & FFS_ATTRIB_LARGE_FILE) - return fileHeader->ExtendedSize; - else - return uint24ToUint32(fileHeader->Size); + if (fileHeader->Attributes & FFS_ATTRIB_LARGE_FILE) { + if ((UINT32)volume.size() < fileOffset + sizeof(EFI_FFS_FILE_HEADER2)) { + return 0; + } + + const EFI_FFS_FILE_HEADER2* fileHeader2 = (const EFI_FFS_FILE_HEADER2*)(volume.constData() + fileOffset); + return (UINT32)fileHeader2->ExtendedSize; + } + + return uint24ToUint32(fileHeader->Size); } - else - return 0; + + return 0; } -USTATUS FfsParser::parseFileHeader(const UByteArray & file, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index) +USTATUS FfsParser::parseFileHeader(const UByteArray & file, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index) { // Sanity check - if (file.isEmpty()) + if (file.isEmpty()) { return U_INVALID_PARAMETER; - - if ((UINT32)file.size() < sizeof(EFI_FFS_FILE_HEADER)) + } + if ((UINT32)file.size() < sizeof(EFI_FFS_FILE_HEADER)) { return U_INVALID_FILE; - - // Get parent's parsing data - PARSING_DATA pdata = parsingDataFromUModelIndex(parent); - + } + + // Obtain required information from parent volume + UINT8 ffsVersion = 2; + bool isWeakAligned = false; + UINT32 volumeAlignment = 0xFFFFFFFF; + UINT8 volumeRevision = 2; + UModelIndex parentVolumeIndex = model->type(parent) == Types::Volume ? parent : model->findParentOfType(parent, Types::Volume); + if (parentVolumeIndex.isValid() && model->hasEmptyParsingData(parentVolumeIndex) == false) { + UByteArray data = model->parsingData(parentVolumeIndex); + const VOLUME_PARSING_DATA* pdata = (const VOLUME_PARSING_DATA*)data.constData(); + ffsVersion = pdata->ffsVersion; + volumeAlignment = pdata->alignment; + volumeRevision = pdata->revision; + isWeakAligned = pdata->isWeakAligned; + } + // Get file header UByteArray header = file.left(sizeof(EFI_FFS_FILE_HEADER)); - const EFI_FFS_FILE_HEADER* fileHeader = (const EFI_FFS_FILE_HEADER*)header.constData(); - if (pdata.ffsVersion == 3 && (fileHeader->Attributes & FFS_ATTRIB_LARGE_FILE)) { - if ((UINT32)file.size() < sizeof(EFI_FFS_FILE_HEADER2)) - return U_INVALID_FILE; - header = file.left(sizeof(EFI_FFS_FILE_HEADER2)); + EFI_FFS_FILE_HEADER* tempFileHeader = (EFI_FFS_FILE_HEADER*)header.data(); + if (tempFileHeader->Attributes & FFS_ATTRIB_LARGE_FILE) { + if (ffsVersion == 2 && volumeRevision == 2) { + if ((UINT32)file.size() < sizeof(EFI_FFS_FILE_HEADER2_LENOVO)) + return U_INVALID_FILE; + header = file.left(sizeof(EFI_FFS_FILE_HEADER2_LENOVO)); + } + if (ffsVersion == 3) { + if ((UINT32)file.size() < sizeof(EFI_FFS_FILE_HEADER2)) + return U_INVALID_FILE; + header = file.left(sizeof(EFI_FFS_FILE_HEADER2)); + } } - + const EFI_FFS_FILE_HEADER* fileHeader = (const EFI_FFS_FILE_HEADER*)header.constData(); + // Check file alignment bool msgUnalignedFile = false; UINT8 alignmentPower = ffsAlignmentTable[(fileHeader->Attributes & FFS_ATTRIB_DATA_ALIGNMENT) >> 3]; - UINT32 alignment = (UINT32)pow(2.0, alignmentPower); - if ((parentOffset + header.size()) % alignment) + if (volumeRevision > 1 && (fileHeader->Attributes & FFS_ATTRIB_DATA_ALIGNMENT2)) { + alignmentPower = ffsAlignment2Table[(fileHeader->Attributes & FFS_ATTRIB_DATA_ALIGNMENT) >> 3]; + } + + UINT32 alignment = (UINT32)(1UL << alignmentPower); + if ((localOffset + header.size()) % alignment) { msgUnalignedFile = true; - - // Check file alignment agains volume alignment - bool msgFileAlignmentIsGreaterThanVolumes = false; - if (!pdata.volume.isWeakAligned && pdata.volume.alignment < alignment) - msgFileAlignmentIsGreaterThanVolumes = true; - + } + + // Check file alignment against volume alignment + bool msgFileAlignmentIsGreaterThanVolumeAlignment = false; + if (!isWeakAligned && volumeAlignment < alignment) { + msgFileAlignmentIsGreaterThanVolumeAlignment = true; + } + + // Get file body + UByteArray body = file.mid(header.size()); + + // Check for file tail presence + UByteArray tail; + bool msgInvalidTailValue = false; + if (volumeRevision == 1 && (fileHeader->Attributes & FFS_ATTRIB_TAIL_PRESENT)) { + //Check file tail; + UINT16 tailValue = *(UINT16*)body.right(sizeof(UINT16)).constData(); + if (fileHeader->IntegrityCheck.TailReference != (UINT16)~tailValue) + msgInvalidTailValue = true; + + // Get tail and remove it from file body + tail = body.right(sizeof(UINT16)); + body = body.left(body.size() - sizeof(UINT16)); + } + // Check header checksum - UByteArray tempHeader = header; - EFI_FFS_FILE_HEADER* tempFileHeader = (EFI_FFS_FILE_HEADER*)(tempHeader.data()); - tempFileHeader->IntegrityCheck.Checksum.Header = 0; - tempFileHeader->IntegrityCheck.Checksum.File = 0; - UINT8 calculatedHeader = calculateChecksum8((const UINT8*)tempFileHeader, header.size() - 1); + UINT8 calculatedHeader = 0x100 - (calculateSum8((const UINT8*)header.constData(), (UINT32)header.size()) - fileHeader->IntegrityCheck.Checksum.Header - fileHeader->IntegrityCheck.Checksum.File - fileHeader->State); bool msgInvalidHeaderChecksum = false; - if (fileHeader->IntegrityCheck.Checksum.Header != calculatedHeader) + if (fileHeader->IntegrityCheck.Checksum.Header != calculatedHeader) { msgInvalidHeaderChecksum = true; - + } + // Check data checksum // Data checksum must be calculated bool msgInvalidDataChecksum = false; UINT8 calculatedData = 0; if (fileHeader->Attributes & FFS_ATTRIB_CHECKSUM) { - UINT32 bufferSize = file.size() - header.size(); - // Exclude file tail from data checksum calculation - if (pdata.volume.revision == 1 && (fileHeader->Attributes & FFS_ATTRIB_TAIL_PRESENT)) - bufferSize -= sizeof(UINT16); - calculatedData = calculateChecksum8((const UINT8*)(file.constData() + header.size()), bufferSize); - if (fileHeader->IntegrityCheck.Checksum.File != calculatedData) - msgInvalidDataChecksum = true; + calculatedData = calculateChecksum8((const UINT8*)body.constData(), (UINT32)body.size()); } // Data checksum must be one of predefined values - else if (pdata.volume.revision == 1 && fileHeader->IntegrityCheck.Checksum.File != FFS_FIXED_CHECKSUM) { + else if (volumeRevision == 1) { calculatedData = FFS_FIXED_CHECKSUM; - msgInvalidDataChecksum = true; } - else if (pdata.volume.revision == 2 && fileHeader->IntegrityCheck.Checksum.File != FFS_FIXED_CHECKSUM2) { + else { calculatedData = FFS_FIXED_CHECKSUM2; + } + + if (fileHeader->IntegrityCheck.Checksum.File != calculatedData) { msgInvalidDataChecksum = true; } - + // Check file type bool msgUnknownType = false; - if (fileHeader->Type > EFI_FV_FILETYPE_SMM_CORE && fileHeader->Type != EFI_FV_FILETYPE_PAD) { + if (fileHeader->Type > EFI_FV_FILETYPE_MM_CORE_STANDALONE && fileHeader->Type != EFI_FV_FILETYPE_PAD) { msgUnknownType = true; }; - - // Get file body - UByteArray body = file.mid(header.size()); - - // Check for file tail presence - UByteArray tail; - bool msgInvalidTailValue = false; - if (pdata.volume.revision == 1 && (fileHeader->Attributes & FFS_ATTRIB_TAIL_PRESENT)) - { - //Check file tail; - UINT16 tailValue = *(UINT16*)body.right(sizeof(UINT16)).constData(); - if (fileHeader->IntegrityCheck.TailReference != (UINT16)~tailValue) - msgInvalidTailValue = true; - - // Get tail and remove it from file body - tail = body.right(sizeof(UINT16)); - body = body.left(body.size() - sizeof(UINT16)); - } - + // Get info UString name; UString info; - if (fileHeader->Type != EFI_FV_FILETYPE_PAD) + if (fileHeader->Type != EFI_FV_FILETYPE_PAD) { name = guidToUString(fileHeader->Name); - else - name = UString("Pad-file"); - - info = UString("File GUID: ") + guidToUString(fileHeader->Name) + - usprintf("\nType: %02Xh\nAttributes: %02Xh\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nTail size: %Xh (%u)\nState: %02Xh", - fileHeader->Type, - fileHeader->Attributes, - header.size() + body.size() + tail.size(), header.size() + body.size() + tail.size(), - header.size(), header.size(), - body.size(), body.size(), - tail.size(), tail.size(), - fileHeader->State) + - usprintf("\nHeader checksum: %02Xh", fileHeader->IntegrityCheck.Checksum.Header) + (msgInvalidHeaderChecksum ? usprintf(", invalid, should be %02Xh", calculatedHeader) : UString(", valid")) + - usprintf("\nData checksum: %02Xh", fileHeader->IntegrityCheck.Checksum.File) + (msgInvalidDataChecksum ? usprintf(", invalid, should be %02Xh", calculatedData) : UString(", valid")); - - // Add file GUID to parsing data - pdata.file.guid = fileHeader->Name; - + } else { + name = UString("Padding file"); + } + + info = UString("File GUID: ") + guidToUString(fileHeader->Name, false) + + usprintf("\nType: %02Xh\nAttributes: %02Xh\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nTail size: %Xh (%u)\nState: %02Xh", + fileHeader->Type, + fileHeader->Attributes, + (UINT32)(header.size() + body.size() + tail.size()), (UINT32)(header.size() + body.size() + tail.size()), + (UINT32)header.size(), (UINT32)header.size(), + (UINT32)body.size(), (UINT32)body.size(), + (UINT32)tail.size(), (UINT32)tail.size(), + fileHeader->State) + + usprintf("\nHeader checksum: %02Xh", fileHeader->IntegrityCheck.Checksum.Header) + (msgInvalidHeaderChecksum ? usprintf(", invalid, should be %02Xh", calculatedHeader) : UString(", valid")) + + usprintf("\nData checksum: %02Xh", fileHeader->IntegrityCheck.Checksum.File) + (msgInvalidDataChecksum ? usprintf(", invalid, should be %02Xh", calculatedData) : UString(", valid")); + UString text; bool isVtf = false; + bool isDxeCore = false; // Check if the file is a Volume Top File - if (UByteArray((const char*)&fileHeader->Name, sizeof(EFI_GUID)) == EFI_FFS_VOLUME_TOP_FILE_GUID) { + UByteArray fileGuid = UByteArray((const char*)&fileHeader->Name, sizeof(EFI_GUID)); + if (fileGuid == EFI_FFS_VOLUME_TOP_FILE_GUID) { // Mark it as the last VTF // This information will later be used to determine memory addresses of uncompressed image elements - // Because the last byte of the last VFT is mapped to 0xFFFFFFFF physical memory address + // Because the last byte of the last VFT is mapped to 0xFFFFFFFF physical memory address isVtf = true; text = UString("Volume Top File"); } - - // Construct parsing data - bool fixed = (fileHeader->Attributes & FFS_ATTRIB_FIXED) != 0; - pdata.offset += parentOffset; + // Check if the file is the first DXE Core + else if (fileGuid == EFI_DXE_CORE_GUID || fileGuid == AMI_CORE_DXE_GUID) { + // Mark is as first DXE core + // This information may be used to determine DXE volume offset for old AMI or post-IBB protected ranges + isDxeCore = true; + } + + // Construct fixed state + ItemFixedState fixed = (ItemFixedState)((fileHeader->Attributes & FFS_ATTRIB_FIXED) != 0); - // Add tree item - index = model->addItem(Types::File, fileHeader->Type, name, text, info, header, body, tail, fixed, parsingDataToUByteArray(pdata), parent); - - // Overwrite lastVtf, if needed + index = model->addItem(localOffset, Types::File, fileHeader->Type, name, text, info, header, body, tail, fixed, parent); + + // Set parsing data for created file + FILE_PARSING_DATA pdata = {}; + pdata.emptyByte = (fileHeader->State & EFI_FILE_ERASE_POLARITY) ? 0xFF : 0x00; + pdata.guid = fileHeader->Name; + model->setParsingData(index, UByteArray((const char*)&pdata, sizeof(pdata))); + + // Override lastVtf index, if needed if (isVtf) { lastVtf = index; } - + + // Override first DXE core index, if needed + if (isDxeCore && !dxeCore.isValid()) { + dxeCore = index; + } + // Show messages if (msgUnalignedFile) - msg(UString("parseFileHeader: unaligned file"), index); - if (msgFileAlignmentIsGreaterThanVolumes) - msg(usprintf("parseFileHeader: file alignment %Xh is greater than parent volume alignment %Xh", alignment, pdata.volume.alignment), index); + msg(usprintf("%s: unaligned file", __FUNCTION__), index); + if (msgFileAlignmentIsGreaterThanVolumeAlignment) + msg(usprintf("%s: file alignment %Xh is greater than parent volume alignment %Xh", __FUNCTION__, alignment, volumeAlignment), index); if (msgInvalidHeaderChecksum) - msg(UString("parseFileHeader: invalid header checksum"), index); + msg(usprintf("%s: invalid header checksum %02Xh, should be %02Xh", __FUNCTION__, fileHeader->IntegrityCheck.Checksum.Header, calculatedHeader), index); if (msgInvalidDataChecksum) - msg(UString("parseFileHeader: invalid data checksum"), index); + msg(usprintf("%s: invalid data checksum %02Xh, should be %02Xh", __FUNCTION__, fileHeader->IntegrityCheck.Checksum.File, calculatedData), index); if (msgInvalidTailValue) - msg(UString("parseFileHeader: invalid tail value"), index); + msg(usprintf("%s: invalid tail value %04Xh", __FUNCTION__, *(const UINT16*)tail.constData()), index); if (msgUnknownType) - msg(usprintf("parseFileHeader: unknown file type %02Xh", fileHeader->Type), index); - + msg(usprintf("%s: unknown file type %02Xh", __FUNCTION__, fileHeader->Type), index); + return U_SUCCESS; } UINT32 FfsParser::getSectionSize(const UByteArray & file, const UINT32 sectionOffset, const UINT8 ffsVersion) { + if ((UINT32)file.size() < sectionOffset + sizeof(EFI_COMMON_SECTION_HEADER)) { + return 0; + } + const EFI_COMMON_SECTION_HEADER* sectionHeader = (const EFI_COMMON_SECTION_HEADER*)(file.constData() + sectionOffset); + if (ffsVersion == 2) { - if ((UINT32)file.size() < sectionOffset + sizeof(EFI_COMMON_SECTION_HEADER)) - return 0; - const EFI_COMMON_SECTION_HEADER* sectionHeader = (const EFI_COMMON_SECTION_HEADER*)(file.constData() + sectionOffset); return uint24ToUint32(sectionHeader->Size); } else if (ffsVersion == 3) { - if ((UINT32)file.size() < sectionOffset + sizeof(EFI_COMMON_SECTION_HEADER2)) - return 0; - const EFI_COMMON_SECTION_HEADER2* sectionHeader = (const EFI_COMMON_SECTION_HEADER2*)(file.constData() + sectionOffset); UINT32 size = uint24ToUint32(sectionHeader->Size); - if (size == EFI_SECTION2_IS_USED) - return sectionHeader->ExtendedSize; - else - return size; + if (size == EFI_SECTION2_IS_USED) { + if ((UINT32)file.size() < sectionOffset + sizeof(EFI_COMMON_SECTION_HEADER2)) { + return 0; + } + const EFI_COMMON_SECTION_HEADER2* sectionHeader2 = (const EFI_COMMON_SECTION_HEADER2*)(file.constData() + sectionOffset); + return sectionHeader2->ExtendedSize; + } + + return size; } - else - return 0; + + return 0; } USTATUS FfsParser::parseFileBody(const UModelIndex & index) @@ -1600,27 +2309,63 @@ USTATUS FfsParser::parseFileBody(const UModelIndex & index) // Sanity check if (!index.isValid()) return U_INVALID_PARAMETER; - + // Do not parse non-file bodies if (model->type(index) != Types::File) return U_SUCCESS; - - // Parse pad-file body + + // Parse padding file body if (model->subtype(index) == EFI_FV_FILETYPE_PAD) return parsePadFileBody(index); - + // Parse raw files as raw areas if (model->subtype(index) == EFI_FV_FILETYPE_RAW || model->subtype(index) == EFI_FV_FILETYPE_ALL) { - // Get data from parsing data - PARSING_DATA pdata = parsingDataFromUModelIndex(index); - + UByteArray fileGuid = UByteArray(model->header(index).constData(), sizeof(EFI_GUID)); + // Parse NVAR store - if (UByteArray((const char*)&pdata.file.guid, sizeof(EFI_GUID)) == NVRAM_NVAR_STORE_FILE_GUID) - return parseNvarStore(index); - + if (fileGuid == NVRAM_NVAR_STORE_FILE_GUID) { + model->setText(index, UString("NVAR store")); + return nvramParser->parseNvarStore(index); + } + else if (fileGuid == NVRAM_NVAR_PEI_EXTERNAL_DEFAULTS_FILE_GUID) { + model->setText(index, UString("NVRAM external defaults")); + return nvramParser->parseNvarStore(index); + } + else if (fileGuid == NVRAM_NVAR_BB_DEFAULTS_FILE_GUID) { + model->setText(index, UString("NVAR BB defaults")); + return nvramParser->parseNvarStore(index); + } + // Parse vendor hash file + else if (fileGuid == PROTECTED_RANGE_VENDOR_HASH_FILE_GUID_PHOENIX) { + return parseVendorHashFile(fileGuid, index); + } + // Parse AMI ROM hole + else if (fileGuid == AMI_ROM_HOLE_FILE_GUID_0 + || fileGuid == AMI_ROM_HOLE_FILE_GUID_1 + || fileGuid == AMI_ROM_HOLE_FILE_GUID_2 + || fileGuid == AMI_ROM_HOLE_FILE_GUID_3 + || fileGuid == AMI_ROM_HOLE_FILE_GUID_4 + || fileGuid == AMI_ROM_HOLE_FILE_GUID_5 + || fileGuid == AMI_ROM_HOLE_FILE_GUID_6 + || fileGuid == AMI_ROM_HOLE_FILE_GUID_7 + || fileGuid == AMI_ROM_HOLE_FILE_GUID_8 + || fileGuid == AMI_ROM_HOLE_FILE_GUID_9 + || fileGuid == AMI_ROM_HOLE_FILE_GUID_10 + || fileGuid == AMI_ROM_HOLE_FILE_GUID_11 + || fileGuid == AMI_ROM_HOLE_FILE_GUID_12 + || fileGuid == AMI_ROM_HOLE_FILE_GUID_13 + || fileGuid == AMI_ROM_HOLE_FILE_GUID_14 + || fileGuid == AMI_ROM_HOLE_FILE_GUID_15) { + model->setText(index, UString("AMI ROM hole")); + // Mark ROM hole file as Fixed in the image + model->setFixed(index, Fixed); + // No need to parse further + return U_SUCCESS; + } + return parseRawArea(index); } - + // Parse sections return parseSections(model->body(index), index, true); } @@ -1630,62 +2375,86 @@ USTATUS FfsParser::parsePadFileBody(const UModelIndex & index) // Sanity check if (!index.isValid()) return U_INVALID_PARAMETER; - - // Get data from parsing data - PARSING_DATA pdata = parsingDataFromUModelIndex(index); - + // Check if all bytes of the file are empty UByteArray body = model->body(index); - if (body.size() == body.count(pdata.emptyByte)) + + // Obtain required information from parent file + UINT8 emptyByte = 0xFF; + UModelIndex parentFileIndex = model->findParentOfType(index, Types::File); + if (parentFileIndex.isValid() && model->hasEmptyParsingData(parentFileIndex) == false) { + UByteArray data = model->parsingData(index); + const FILE_PARSING_DATA* pdata = (const FILE_PARSING_DATA*)data.constData(); + emptyByte = pdata->emptyByte; + } + + // Check if the while padding file is empty + if (body.size() == body.count(emptyByte)) return U_SUCCESS; - + // Search for the first non-empty byte - UINT32 i; - UINT32 size = body.size(); + UINT32 nonEmptyByteOffset; + UINT32 size = (UINT32)body.size(); const UINT8* current = (const UINT8*)body.constData(); - for (i = 0; i < size; i++) { - if (*current++ != pdata.emptyByte) + for (nonEmptyByteOffset = 0; nonEmptyByteOffset < size; nonEmptyByteOffset++) { + if (*current++ != emptyByte) break; } - + // Add all bytes before as free space... - if (i >= 8) { + UINT32 headerSize = (UINT32)model->header(index).size(); + if (nonEmptyByteOffset >= 8) { // Align free space to 8 bytes boundary - if (i != ALIGN8(i)) - i = ALIGN8(i) - 8; - - UByteArray free = body.left(i); - + if (nonEmptyByteOffset != ALIGN8(nonEmptyByteOffset)) + nonEmptyByteOffset = ALIGN8(nonEmptyByteOffset) - 8; + + UByteArray free = body.left(nonEmptyByteOffset); + // Get info - UString info = usprintf("Full size: %Xh (%u)", free.size(), free.size()); - - // Constuct parsing data - pdata.offset += model->header(index).size(); - + UString info = usprintf("Full size: %Xh (%u)", (UINT32)free.size(), (UINT32)free.size()); + // Add tree item - model->addItem(Types::FreeSpace, 0, UString("Free space"), UString(), info, UByteArray(), free, UByteArray(), false, parsingDataToUByteArray(pdata), index); + model->addItem(headerSize, Types::FreeSpace, 0, UString("Free space"), UString(), info, UByteArray(), free, UByteArray(), Movable, index); } - else - i = 0; - + else { + nonEmptyByteOffset = 0; + } + // ... and all bytes after as a padding - UByteArray padding = body.mid(i); - - // Get info - UString info = usprintf("Full size: %Xh (%u)", padding.size(), padding.size()); - - // Constuct parsing data - pdata.offset += i; - - // Add tree item - UModelIndex dataIndex = model->addItem(Types::Padding, Subtypes::DataPadding, UString("Non-UEFI data"), UString(), info, UByteArray(), padding, UByteArray(), true, parsingDataToUByteArray(pdata), index); - - // Show message - msg(UString("parsePadFileBody: non-UEFI data found in pad-file"), dataIndex); - - // Rename the file - model->setName(index, UString("Non-empty pad-file")); - + UByteArray padding = body.mid(nonEmptyByteOffset); + + // Check for that data to be recovery startup AP data for x86 + // https://github.com/tianocore/edk2/blob/stable/202011/BaseTools/Source/C/GenFv/GenFvInternalLib.c#L106 + if (padding.left(RECOVERY_STARTUP_AP_DATA_X86_SIZE) == RECOVERY_STARTUP_AP_DATA_X86_128K) { + // Get info + UString info = usprintf("Full size: %Xh (%u)", (UINT32)padding.size(), (UINT32)padding.size()); + + // Add tree item + (void)model->addItem(headerSize + nonEmptyByteOffset, Types::StartupApDataEntry, Subtypes::x86128kStartupApDataEntry, UString("Startup AP data"), UString(), info, UByteArray(), padding, UByteArray(), Fixed, index); + + // Rename the file + model->setName(index, UString("Startup AP data padding file")); + + // Do not parse contents + return U_SUCCESS; + } + else { // Not a data array + // Get info + UString info = usprintf("Full size: %Xh (%u)", (UINT32)padding.size(), (UINT32)padding.size()); + + // Add tree item + UModelIndex dataIndex = model->addItem(headerSize + nonEmptyByteOffset, Types::Padding, Subtypes::DataPadding, UString("Non-UEFI data"), UString(), info, UByteArray(), padding, UByteArray(), Fixed, index); + + // Show message + msg(usprintf("%s: non-UEFI data found in padding file", __FUNCTION__), dataIndex); + + // Rename the file + model->setName(index, UString("Non-empty padding file")); + + // Do not parse contents + return U_SUCCESS; + } + return U_SUCCESS; } @@ -1694,187 +2463,215 @@ USTATUS FfsParser::parseSections(const UByteArray & sections, const UModelIndex // Sanity check if (!index.isValid()) return U_INVALID_PARAMETER; - - // Get data from parsing data - PARSING_DATA pdata = parsingDataFromUModelIndex(index); - + // Search for and parse all sections - UINT32 bodySize = sections.size(); - UINT32 headerSize = model->header(index).size(); + UINT32 bodySize = (UINT32)sections.size(); + UINT32 headerSize = (UINT32)model->header(index).size(); UINT32 sectionOffset = 0; - USTATUS result = U_SUCCESS; + + // Obtain required information from parent volume + UINT8 ffsVersion = 2; + UModelIndex parentVolumeIndex = model->findParentOfType(index, Types::Volume); + if (parentVolumeIndex.isValid() && model->hasEmptyParsingData(parentVolumeIndex) == false) { + UByteArray data = model->parsingData(parentVolumeIndex); + const VOLUME_PARSING_DATA* pdata = (const VOLUME_PARSING_DATA*)data.constData(); + ffsVersion = pdata->ffsVersion; + } + + // Iterate over sections + UINT32 sectionSize = 0; while (sectionOffset < bodySize) { // Get section size - UINT32 sectionSize = getSectionSize(sections, sectionOffset, pdata.ffsVersion); - - // Check section size - if (sectionSize < sizeof(EFI_COMMON_SECTION_HEADER) || sectionSize > (bodySize - sectionOffset)) { + sectionSize = getSectionSize(sections, sectionOffset, ffsVersion); + + // Check section size to be sane + if (sectionSize < sizeof(EFI_COMMON_SECTION_HEADER) + || sectionSize > (bodySize - sectionOffset)) { // Final parsing if (insertIntoTree) { // Add padding to fill the rest of sections UByteArray padding = sections.mid(sectionOffset); + // Get info - UString info = usprintf("Full size: %Xh (%u)", padding.size(), padding.size()); - - // Constuct parsing data - pdata.offset += headerSize + sectionOffset; - + UString info = usprintf("Full size: %Xh (%u)", (UINT32)padding.size(), (UINT32)padding.size()); + // Add tree item - UModelIndex dataIndex = model->addItem(Types::Padding, Subtypes::DataPadding, UString("Non-UEFI data"), UString(), info, UByteArray(), padding, UByteArray(), true, parsingDataToUByteArray(pdata), index); - + UModelIndex dataIndex = model->addItem(headerSize + sectionOffset, Types::Padding, Subtypes::DataPadding, UString("Non-UEFI data"), UString(), info, UByteArray(), padding, UByteArray(), Fixed, index); + // Show message - msg(UString("parseSections: non-UEFI data found in sections area"), dataIndex); - + msg(usprintf("%s: non-UEFI data found in sections area", __FUNCTION__), dataIndex); + // Exit from parsing loop - break; + break; } - // Preparsing - else + // Preliminary parsing + else { return U_INVALID_SECTION; + } } - + // Parse section header UModelIndex sectionIndex; result = parseSectionHeader(sections.mid(sectionOffset, sectionSize), headerSize + sectionOffset, index, sectionIndex, insertIntoTree); if (result) { if (insertIntoTree) - msg(UString("parseSections: section header parsing failed with error ") + errorCodeToUString(result), index); + msg(usprintf("%s: section header parsing failed with error ", __FUNCTION__) + errorCodeToUString(result), index); else return U_INVALID_SECTION; } + // Move to next section sectionOffset += sectionSize; + // TODO: verify that alignment bytes are actually zero as per PI spec sectionOffset = ALIGN4(sectionOffset); } - + +#if 0 // Do not enable this in production for now, as it needs further investigation. + // The PI spec requires sections to be aligned by 4 byte boundary with bytes that are all exactly zeroes + // Some images interpret "must be aligned by 4" as "every section needs to be padded for sectionSize to be divisible by 4". + // Detecting this case can be done by checking for the very last section to have sectionSize not divisible by 4, while the total bodySize is. + // However, such detection for a single file is unreliable because in 1/4 random cases the last section will be divisible by 4. + // We also know that either PEI core or DXE core is entity that does file and section parsing, + // so every single file in the volume should behave consistently. + // This makes the probability of unsuccessful detection here to be 1/(4^numFilesInVolume), + // which is low enough for real images out there. + // It should also be noted that enabling this section alignment quirk for an image that doesn't require it + // will not make the image unbootable, but will waste some space and possibly require to move some files around + if (sectionOffset == bodySize) { + // We are now at the very end of the file body, and sectionSize is the size of the last section + if ((sectionSize % 4 != 0) // sectionSize of the very last section is not divisible by 4 + && (bodySize % 4 == 0)) { // yet bodySize is, meaning that there are indeed some padding bytes added after the last section + msg(usprintf("%s: section alignment quirk found", __FUNCTION__), index); + } + } +#endif + // Parse bodies, will be skipped if insertIntoTree is not required for (int i = 0; i < model->rowCount(index); i++) { - UModelIndex current = index.child(i, 0); + UModelIndex current = index.model()->index(i, 0, index); + switch (model->type(current)) { - case Types::Section: - parseSectionBody(current); - break; - case Types::Padding: - // No parsing required - break; - default: - return U_UNKNOWN_ITEM_TYPE; + case Types::Section: + parseSectionBody(current); + break; + case Types::Padding: + // No parsing required + break; + default: + return U_UNKNOWN_ITEM_TYPE; } } return U_SUCCESS; } -USTATUS FfsParser::parseSectionHeader(const UByteArray & section, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree) +USTATUS FfsParser::parseSectionHeader(const UByteArray & section, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree) { // Check sanity - if ((UINT32)section.size() < sizeof(EFI_COMMON_SECTION_HEADER)) + if ((UINT32)section.size() < sizeof(EFI_COMMON_SECTION_HEADER)) { return U_INVALID_SECTION; - + } + const EFI_COMMON_SECTION_HEADER* sectionHeader = (const EFI_COMMON_SECTION_HEADER*)(section.constData()); switch (sectionHeader->Type) { - // Special - case EFI_SECTION_COMPRESSION: return parseCompressedSectionHeader(section, parentOffset, parent, index, insertIntoTree); - case EFI_SECTION_GUID_DEFINED: return parseGuidedSectionHeader(section, parentOffset, parent, index, insertIntoTree); - case EFI_SECTION_FREEFORM_SUBTYPE_GUID: return parseFreeformGuidedSectionHeader(section, parentOffset, parent, index, insertIntoTree); - case EFI_SECTION_VERSION: return parseVersionSectionHeader(section, parentOffset, parent, index, insertIntoTree); - case PHOENIX_SECTION_POSTCODE: - case INSYDE_SECTION_POSTCODE: return parsePostcodeSectionHeader(section, parentOffset, parent, index, insertIntoTree); - // Common - case EFI_SECTION_DISPOSABLE: - case EFI_SECTION_DXE_DEPEX: - case EFI_SECTION_PEI_DEPEX: - case EFI_SECTION_SMM_DEPEX: - case EFI_SECTION_PE32: - case EFI_SECTION_PIC: - case EFI_SECTION_TE: - case EFI_SECTION_COMPATIBILITY16: - case EFI_SECTION_USER_INTERFACE: - case EFI_SECTION_FIRMWARE_VOLUME_IMAGE: - case EFI_SECTION_RAW: return parseCommonSectionHeader(section, parentOffset, parent, index, insertIntoTree); - // Unknown - default: - USTATUS result = parseCommonSectionHeader(section, parentOffset, parent, index, insertIntoTree); - msg(usprintf("parseSectionHeader: section with unknown type %02Xh", sectionHeader->Type), index); - return result; + // Special + case EFI_SECTION_COMPRESSION: return parseCompressedSectionHeader(section, localOffset, parent, index, insertIntoTree); + case EFI_SECTION_GUID_DEFINED: return parseGuidedSectionHeader(section, localOffset, parent, index, insertIntoTree); + case EFI_SECTION_FREEFORM_SUBTYPE_GUID: return parseFreeformGuidedSectionHeader(section, localOffset, parent, index, insertIntoTree); + case EFI_SECTION_VERSION: return parseVersionSectionHeader(section, localOffset, parent, index, insertIntoTree); + case PHOENIX_SECTION_POSTCODE: + case INSYDE_SECTION_POSTCODE: return parsePostcodeSectionHeader(section, localOffset, parent, index, insertIntoTree); + // Common + case EFI_SECTION_DISPOSABLE: + case EFI_SECTION_DXE_DEPEX: + case EFI_SECTION_PEI_DEPEX: + case EFI_SECTION_MM_DEPEX: + case EFI_SECTION_PE32: + case EFI_SECTION_PIC: + case EFI_SECTION_TE: + case EFI_SECTION_COMPATIBILITY16: + case EFI_SECTION_USER_INTERFACE: + case EFI_SECTION_FIRMWARE_VOLUME_IMAGE: + case EFI_SECTION_RAW: return parseCommonSectionHeader(section, localOffset, parent, index, insertIntoTree); + // Unknown + default: + USTATUS result = parseCommonSectionHeader(section, localOffset, parent, index, insertIntoTree); + msg(usprintf("%s: section with unknown type %02Xh", __FUNCTION__, sectionHeader->Type), index); + return result; } } -USTATUS FfsParser::parseCommonSectionHeader(const UByteArray & section, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree) +USTATUS FfsParser::parseCommonSectionHeader(const UByteArray & section, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree) { // Check sanity - if ((UINT32)section.size() < sizeof(EFI_COMMON_SECTION_HEADER)) + if ((UINT32)section.size() < sizeof(EFI_COMMON_SECTION_HEADER)) { return U_INVALID_SECTION; + } + + // Obtain required information from parent volume + UINT8 ffsVersion = 2; + UModelIndex parentVolumeIndex = model->findParentOfType(parent, Types::Volume); + if (parentVolumeIndex.isValid() && model->hasEmptyParsingData(parentVolumeIndex) == false) { + UByteArray data = model->parsingData(parentVolumeIndex); + const VOLUME_PARSING_DATA* pdata = (const VOLUME_PARSING_DATA*)data.constData(); + ffsVersion = pdata->ffsVersion; + } - // Get data from parent's parsing data - PARSING_DATA pdata = parsingDataFromUModelIndex(parent); - // Obtain header fields - UINT32 headerSize; - UINT8 type; - const EFI_COMMON_SECTION_HEADER_APPLE* appleHeader = (const EFI_COMMON_SECTION_HEADER_APPLE*)(section.constData()); - if ((UINT32)section.size() >= sizeof(EFI_COMMON_SECTION_HEADER_APPLE) && appleHeader->Reserved == EFI_SECTION_APPLE_USED) { - headerSize = sizeof(EFI_COMMON_SECTION_HEADER_APPLE); - type = appleHeader->Type; - } - else { - const EFI_COMMON_SECTION_HEADER* sectionHeader = (const EFI_COMMON_SECTION_HEADER*)(section.constData()); - headerSize = sizeof(EFI_COMMON_SECTION_HEADER); - if (pdata.ffsVersion == 3 && uint24ToUint32(sectionHeader->Size) == EFI_SECTION2_IS_USED) - headerSize = sizeof(EFI_COMMON_SECTION_HEADER2); - type = sectionHeader->Type; - } - + const EFI_COMMON_SECTION_HEADER* sectionHeader = (const EFI_COMMON_SECTION_HEADER*)(section.constData()); + UINT32 headerSize = sizeof(EFI_COMMON_SECTION_HEADER); + if (ffsVersion == 3 && uint24ToUint32(sectionHeader->Size) == EFI_SECTION2_IS_USED) + headerSize = sizeof(EFI_COMMON_SECTION_HEADER2); + UINT8 type = sectionHeader->Type; + // Check sanity again - if ((UINT32)section.size() < headerSize) + if ((UINT32)section.size() < headerSize) { return U_INVALID_SECTION; + } UByteArray header = section.left(headerSize); UByteArray body = section.mid(headerSize); - + // Get info UString name = sectionTypeToUString(type) + UString(" section"); UString info = usprintf("Type: %02Xh\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)", - type, - section.size(), section.size(), - headerSize, headerSize, - body.size(), body.size()); - - // Construct parsing data - pdata.offset += parentOffset; - + type, + (UINT32)section.size(), (UINT32)section.size(), + headerSize, headerSize, + (UINT32)body.size(), (UINT32)body.size()); + // Add tree item if (insertIntoTree) { - index = model->addItem(Types::Section, type, name, UString(), info, header, body, UByteArray(), false, parsingDataToUByteArray(pdata), parent); - } + index = model->addItem(localOffset, Types::Section, type, name, UString(), info, header, body, UByteArray(), Movable, parent); + } + return U_SUCCESS; } -USTATUS FfsParser::parseCompressedSectionHeader(const UByteArray & section, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree) +USTATUS FfsParser::parseCompressedSectionHeader(const UByteArray & section, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree) { // Check sanity if ((UINT32)section.size() < sizeof(EFI_COMMON_SECTION_HEADER)) return U_INVALID_SECTION; - - // Get data from parent's parsing data - PARSING_DATA pdata = parsingDataFromUModelIndex(parent); - + + // Obtain required information from parent volume + UINT8 ffsVersion = 2; + UModelIndex parentVolumeIndex = model->findParentOfType(parent, Types::Volume); + if (parentVolumeIndex.isValid() && model->hasEmptyParsingData(parentVolumeIndex) == false) { + UByteArray data = model->parsingData(parentVolumeIndex); + const VOLUME_PARSING_DATA* pdata = (const VOLUME_PARSING_DATA*)data.constData(); + ffsVersion = pdata->ffsVersion; + } + // Obtain header fields UINT32 headerSize; UINT8 compressionType; UINT32 uncompressedLength; const EFI_COMMON_SECTION_HEADER* sectionHeader = (const EFI_COMMON_SECTION_HEADER*)(section.constData()); const EFI_COMMON_SECTION_HEADER2* section2Header = (const EFI_COMMON_SECTION_HEADER2*)(section.constData()); - const EFI_COMMON_SECTION_HEADER_APPLE* appleHeader = (const EFI_COMMON_SECTION_HEADER_APPLE*)(section.constData()); - - if ((UINT32)section.size() >= sizeof(EFI_COMMON_SECTION_HEADER_APPLE) && appleHeader->Reserved == EFI_SECTION_APPLE_USED) { // Check for apple section - const EFI_COMPRESSION_SECTION_APPLE* appleSectionHeader = (const EFI_COMPRESSION_SECTION_APPLE*)(appleHeader + 1); - headerSize = sizeof(EFI_COMMON_SECTION_HEADER_APPLE) + sizeof(EFI_COMPRESSION_SECTION_APPLE); - compressionType = (UINT8)appleSectionHeader->CompressionType; - uncompressedLength = appleSectionHeader->UncompressedLength; - } - else if (pdata.ffsVersion == 3 && uint24ToUint32(sectionHeader->Size) == EFI_SECTION2_IS_USED) { // Check for extended header section + + if (ffsVersion == 3 && uint24ToUint32(sectionHeader->Size) == EFI_SECTION2_IS_USED) { // Check for extended header section const EFI_COMPRESSION_SECTION* compressedSectionHeader = (const EFI_COMPRESSION_SECTION*)(section2Header + 1); if ((UINT32)section.size() < sizeof(EFI_COMMON_SECTION_HEADER2) + sizeof(EFI_COMPRESSION_SECTION)) return U_INVALID_SECTION; @@ -1888,45 +2685,54 @@ USTATUS FfsParser::parseCompressedSectionHeader(const UByteArray & section, cons compressionType = compressedSectionHeader->CompressionType; uncompressedLength = compressedSectionHeader->UncompressedLength; } - + // Check sanity again - if ((UINT32)section.size() < headerSize) + if ((UINT32)section.size() < headerSize) { return U_INVALID_SECTION; + } UByteArray header = section.left(headerSize); UByteArray body = section.mid(headerSize); - + // Get info UString name = sectionTypeToUString(sectionHeader->Type) + UString(" section"); UString info = usprintf("Type: %02Xh\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nCompression type: %02Xh\nDecompressed size: %Xh (%u)", - sectionHeader->Type, - section.size(), section.size(), - headerSize, headerSize, - body.size(), body.size(), - compressionType, - uncompressedLength, uncompressedLength); - - // Construct parsing data - pdata.offset += parentOffset; - pdata.section.compressed.compressionType = compressionType; - pdata.section.compressed.uncompressedSize = uncompressedLength; - + sectionHeader->Type, + (UINT32)section.size(), (UINT32)section.size(), + headerSize, headerSize, + (UINT32)body.size(), (UINT32)body.size(), + compressionType, + uncompressedLength, uncompressedLength); + // Add tree item if (insertIntoTree) { - index = model->addItem(Types::Section, sectionHeader->Type, name, UString(), info, header, body, UByteArray(), false, parsingDataToUByteArray(pdata), parent); + index = model->addItem(localOffset, Types::Section, sectionHeader->Type, name, UString(), info, header, body, UByteArray(), Movable, parent); + + // Set section parsing data + COMPRESSED_SECTION_PARSING_DATA pdata = {}; + pdata.compressionType = compressionType; + pdata.uncompressedSize = uncompressedLength; + model->setParsingData(index, UByteArray((const char*)&pdata, sizeof(pdata))); } + return U_SUCCESS; } -USTATUS FfsParser::parseGuidedSectionHeader(const UByteArray & section, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree) +USTATUS FfsParser::parseGuidedSectionHeader(const UByteArray & section, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree) { // Check sanity if ((UINT32)section.size() < sizeof(EFI_COMMON_SECTION_HEADER)) return U_INVALID_SECTION; - - // Get data from parent's parsing data - PARSING_DATA pdata = parsingDataFromUModelIndex(parent); - + + // Obtain required information from parent volume + UINT8 ffsVersion = 2; + UModelIndex parentVolumeIndex = model->findParentOfType(parent, Types::Volume); + if (parentVolumeIndex.isValid() && model->hasEmptyParsingData(parentVolumeIndex) == false) { + UByteArray data = model->parsingData(parentVolumeIndex); + const VOLUME_PARSING_DATA* pdata = (const VOLUME_PARSING_DATA*)data.constData(); + ffsVersion = pdata->ffsVersion; + } + // Obtain header fields UINT32 headerSize; EFI_GUID guid; @@ -1934,18 +2740,8 @@ USTATUS FfsParser::parseGuidedSectionHeader(const UByteArray & section, const UI UINT16 attributes; const EFI_COMMON_SECTION_HEADER* sectionHeader = (const EFI_COMMON_SECTION_HEADER*)(section.constData()); const EFI_COMMON_SECTION_HEADER2* section2Header = (const EFI_COMMON_SECTION_HEADER2*)(section.constData()); - const EFI_COMMON_SECTION_HEADER_APPLE* appleHeader = (const EFI_COMMON_SECTION_HEADER_APPLE*)(section.constData()); - - if ((UINT32)section.size() >= sizeof(EFI_COMMON_SECTION_HEADER_APPLE) && appleHeader->Reserved == EFI_SECTION_APPLE_USED) { // Check for apple section - const EFI_GUID_DEFINED_SECTION_APPLE* appleSectionHeader = (const EFI_GUID_DEFINED_SECTION_APPLE*)(appleHeader + 1); - headerSize = sizeof(EFI_COMMON_SECTION_HEADER_APPLE) + sizeof(EFI_GUID_DEFINED_SECTION_APPLE); - if ((UINT32)section.size() < headerSize) - return U_INVALID_SECTION; - guid = appleSectionHeader->SectionDefinitionGuid; - dataOffset = appleSectionHeader->DataOffset; - attributes = appleSectionHeader->Attributes; - } - else if (pdata.ffsVersion == 3 && uint24ToUint32(sectionHeader->Size) == EFI_SECTION2_IS_USED) { // Check for extended header section + + if (ffsVersion == 3 && uint24ToUint32(sectionHeader->Size) == EFI_SECTION2_IS_USED) { // Check for extended header section const EFI_GUID_DEFINED_SECTION* guidDefinedSectionHeader = (const EFI_GUID_DEFINED_SECTION*)(section2Header + 1); if ((UINT32)section.size() < sizeof(EFI_COMMON_SECTION_HEADER2) + sizeof(EFI_GUID_DEFINED_SECTION)) return U_INVALID_SECTION; @@ -1964,7 +2760,7 @@ USTATUS FfsParser::parseGuidedSectionHeader(const UByteArray & section, const UI // Check sanity again if ((UINT32)section.size() < headerSize) return U_INVALID_SECTION; - + // Check for special GUIDed sections UString additionalInfo; UByteArray baGuid((const char*)&guid, sizeof(EFI_GUID)); @@ -1975,18 +2771,20 @@ USTATUS FfsParser::parseGuidedSectionHeader(const UByteArray & section, const UI bool msgInvalidCrc = false; bool msgUnknownCertType = false; bool msgUnknownCertSubtype = false; + bool msgProcessingRequiredAttributeOnUnknownGuidedSection = false; + bool msgInvalidCompressedSize = false; if (baGuid == EFI_GUIDED_SECTION_CRC32) { if ((attributes & EFI_GUIDED_SECTION_AUTH_STATUS_VALID) == 0) { // Check that AuthStatusValid attribute is set on compressed GUIDed sections msgNoAuthStatusAttribute = true; } - + if ((UINT32)section.size() < headerSize + sizeof(UINT32)) return U_INVALID_SECTION; - + UINT32 crc = *(UINT32*)(section.constData() + headerSize); additionalInfo += UString("\nChecksum type: CRC32"); // Calculate CRC32 of section data - UINT32 calculated = crc32(0, (const UINT8*)section.constData() + dataOffset, section.size() - dataOffset); + UINT32 calculated = (UINT32)crc32(0, (const UINT8*)section.constData() + dataOffset, (uInt)(section.size() - dataOffset)); if (crc == calculated) { additionalInfo += usprintf("\nChecksum: %08Xh, valid", crc); } @@ -1996,40 +2794,77 @@ USTATUS FfsParser::parseGuidedSectionHeader(const UByteArray & section, const UI } // No need to change dataOffset here } - else if (baGuid == EFI_GUIDED_SECTION_LZMA || baGuid == EFI_GUIDED_SECTION_TIANO) { + else if (baGuid == EFI_GUIDED_SECTION_LZMA + || baGuid == EFI_GUIDED_SECTION_LZMA_HP + || baGuid == EFI_GUIDED_SECTION_LZMA_MS + || baGuid == EFI_GUIDED_SECTION_LZMAF86 + || baGuid == EFI_GUIDED_SECTION_TIANO + || baGuid == EFI_GUIDED_SECTION_GZIP) { if ((attributes & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) == 0) { // Check that ProcessingRequired attribute is set on compressed GUIDed sections msgNoProcessingRequiredAttributeCompressed = true; } // No need to change dataOffset here } + else if (baGuid == EFI_GUIDED_SECTION_ZLIB_AMD) { + if ((attributes & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) == 0) { // Check that ProcessingRequired attribute is set on compressed GUIDed sections + msgNoProcessingRequiredAttributeCompressed = true; + } + + if ((UINT32)section.size() < headerSize + sizeof(EFI_AMD_ZLIB_SECTION_HEADER)) + return U_INVALID_SECTION; + + const EFI_AMD_ZLIB_SECTION_HEADER* amdZlibSectionHeader = (const EFI_AMD_ZLIB_SECTION_HEADER*)(section.constData() + headerSize); + + // Check the compressed size to be sane + if ((UINT32)section.size() != headerSize + sizeof(EFI_AMD_ZLIB_SECTION_HEADER) + amdZlibSectionHeader->CompressedSize) { + msgInvalidCompressedSize = true; + } + + // Adjust dataOffset + dataOffset += sizeof(EFI_AMD_ZLIB_SECTION_HEADER); + } + else if (baGuid == EFI_CERT_TYPE_RSA2048_SHA256_GUID) { + if ((attributes & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) == 0) { // Check that ProcessingRequired attribute is set on signed GUIDed sections + msgNoProcessingRequiredAttributeSigned = true; + } + + // Get certificate type and length + if ((UINT32)section.size() < headerSize + sizeof(EFI_CERT_BLOCK_RSA2048_SHA256)) + return U_INVALID_SECTION; + + // Adjust dataOffset + dataOffset += sizeof(EFI_CERT_BLOCK_RSA2048_SHA256); + additionalInfo += UString("\nCertificate type: RSA2048/SHA256"); + msgSignedSectionFound = true; + } else if (baGuid == EFI_FIRMWARE_CONTENTS_SIGNED_GUID) { if ((attributes & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) == 0) { // Check that ProcessingRequired attribute is set on signed GUIDed sections msgNoProcessingRequiredAttributeSigned = true; } - + // Get certificate type and length if ((UINT32)section.size() < headerSize + sizeof(WIN_CERTIFICATE)) return U_INVALID_SECTION; - + const WIN_CERTIFICATE* winCertificate = (const WIN_CERTIFICATE*)(section.constData() + headerSize); UINT32 certLength = winCertificate->Length; UINT16 certType = winCertificate->CertificateType; - + // Adjust dataOffset dataOffset += certLength; - + // Check section size once again if ((UINT32)section.size() < dataOffset) return U_INVALID_SECTION; - + // Check certificate type if (certType == WIN_CERT_TYPE_EFI_GUID) { additionalInfo += UString("\nCertificate type: UEFI"); - + // Get certificate GUID const WIN_CERTIFICATE_UEFI_GUID* winCertificateUefiGuid = (const WIN_CERTIFICATE_UEFI_GUID*)(section.constData() + headerSize); UByteArray certTypeGuid((const char*)&winCertificateUefiGuid->CertType, sizeof(EFI_GUID)); - + if (certTypeGuid == EFI_CERT_TYPE_RSA2048_SHA256_GUID) { additionalInfo += UString("\nCertificate subtype: RSA2048/SHA256"); } @@ -2044,76 +2879,83 @@ USTATUS FfsParser::parseGuidedSectionHeader(const UByteArray & section, const UI } msgSignedSectionFound = true; } - + // Check that ProcessingRequired attribute is not set on GUIDed sections with unknown GUID + else if ((attributes & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) == EFI_GUIDED_SECTION_PROCESSING_REQUIRED) { + msgProcessingRequiredAttributeOnUnknownGuidedSection = true; + } + UByteArray header = section.left(dataOffset); UByteArray body = section.mid(dataOffset); - + // Get info UString name = guidToUString(guid); - UString info = UString("Section GUID: ") + name + - usprintf("\nType: %02Xh\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nData offset: %Xh\nAttributes: %04Xh", - sectionHeader->Type, - section.size(), section.size(), - header.size(), header.size(), - body.size(), body.size(), - dataOffset, - attributes); - + UString info = UString("Section GUID: ") + guidToUString(guid, false) + + usprintf("\nType: %02Xh\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nAttributes: %04Xh", + sectionHeader->Type, + (UINT32)section.size(), (UINT32)section.size(), + (UINT32)header.size(), (UINT32)header.size(), + (UINT32)body.size(), (UINT32)body.size(), + attributes); + // Append additional info info += additionalInfo; - - // Construct parsing data - pdata.offset += parentOffset; - pdata.section.guidDefined.guid = guid; - + // Add tree item if (insertIntoTree) { - index = model->addItem(Types::Section, sectionHeader->Type, name, UString(), info, header, body, UByteArray(), false, parsingDataToUByteArray(pdata), parent); - + index = model->addItem(localOffset, Types::Section, sectionHeader->Type, name, UString(), info, header, body, UByteArray(), Movable, parent); + + // Set parsing data + GUIDED_SECTION_PARSING_DATA pdata = {}; + pdata.guid = guid; + model->setParsingData(index, UByteArray((const char*)&pdata, sizeof(pdata))); + // Show messages if (msgSignedSectionFound) - msg(UString("parseGuidedSectionHeader: section signature may become invalid after any modification"), index); + msg(usprintf("%s: GUIDed section signature may become invalid after modification", __FUNCTION__), index); if (msgNoAuthStatusAttribute) - msg(UString("parseGuidedSectionHeader: CRC32 GUIDed section without AuthStatusValid attribute"), index); + msg(usprintf("%s: CRC32 GUIDed section without AuthStatusValid attribute", __FUNCTION__), index); if (msgNoProcessingRequiredAttributeCompressed) - msg(UString("parseGuidedSectionHeader: compressed GUIDed section without ProcessingRequired attribute"), index); + msg(usprintf("%s: compressed GUIDed section without ProcessingRequired attribute", __FUNCTION__), index); if (msgNoProcessingRequiredAttributeSigned) - msg(UString("parseGuidedSectionHeader: signed GUIDed section without ProcessingRequired attribute"), index); + msg(usprintf("%s: signed GUIDed section without ProcessingRequired attribute", __FUNCTION__), index); if (msgInvalidCrc) - msg(UString("parseGuidedSectionHeader: GUID defined section with invalid CRC32"), index); + msg(usprintf("%s: CRC32 GUIDed section with invalid checksum", __FUNCTION__), index); if (msgUnknownCertType) - msg(UString("parseGuidedSectionHeader: signed GUIDed section with unknown type"), index); + msg(usprintf("%s: signed GUIDed section with unknown certificate type", __FUNCTION__), index); if (msgUnknownCertSubtype) - msg(UString("parseGuidedSectionHeader: signed GUIDed section with unknown subtype"), index); + msg(usprintf("%s: signed GUIDed section with unknown certificate subtype", __FUNCTION__), index); + if (msgProcessingRequiredAttributeOnUnknownGuidedSection) + msg(usprintf("%s: processing required bit set for GUIDed section with unknown GUID", __FUNCTION__), index); + if (msgInvalidCompressedSize) + msg(usprintf("%s: AMD Zlib-compressed section with invalid compressed size", __FUNCTION__), index); } - + return U_SUCCESS; } -USTATUS FfsParser::parseFreeformGuidedSectionHeader(const UByteArray & section, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree) +USTATUS FfsParser::parseFreeformGuidedSectionHeader(const UByteArray & section, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree) { // Check sanity if ((UINT32)section.size() < sizeof(EFI_COMMON_SECTION_HEADER)) return U_INVALID_SECTION; - - // Get data from parent's parsing data - PARSING_DATA pdata = parsingDataFromUModelIndex(parent); - + + // Obtain required information from parent volume + UINT8 ffsVersion = 2; + UModelIndex parentVolumeIndex = model->findParentOfType(parent, Types::Volume); + if (parentVolumeIndex.isValid() && model->hasEmptyParsingData(parentVolumeIndex) == false) { + UByteArray data = model->parsingData(parentVolumeIndex); + const VOLUME_PARSING_DATA* pdata = (const VOLUME_PARSING_DATA*)data.constData(); + ffsVersion = pdata->ffsVersion; + } + // Obtain header fields UINT32 headerSize; EFI_GUID guid; UINT8 type; const EFI_COMMON_SECTION_HEADER* sectionHeader = (const EFI_COMMON_SECTION_HEADER*)(section.constData()); const EFI_COMMON_SECTION_HEADER2* section2Header = (const EFI_COMMON_SECTION_HEADER2*)(section.constData()); - const EFI_COMMON_SECTION_HEADER_APPLE* appleHeader = (const EFI_COMMON_SECTION_HEADER_APPLE*)(section.constData()); - - if ((UINT32)section.size() >= sizeof(EFI_COMMON_SECTION_HEADER_APPLE) && appleHeader->Reserved == EFI_SECTION_APPLE_USED) { // Check for apple section - const EFI_FREEFORM_SUBTYPE_GUID_SECTION* appleSectionHeader = (const EFI_FREEFORM_SUBTYPE_GUID_SECTION*)(appleHeader + 1); - headerSize = sizeof(EFI_COMMON_SECTION_HEADER_APPLE) + sizeof(EFI_FREEFORM_SUBTYPE_GUID_SECTION); - guid = appleSectionHeader->SubTypeGuid; - type = appleHeader->Type; - } - else if (pdata.ffsVersion == 3 && uint24ToUint32(sectionHeader->Size) == EFI_SECTION2_IS_USED) { // Check for extended header section + + if (ffsVersion == 3 && uint24ToUint32(sectionHeader->Size) == EFI_SECTION2_IS_USED) { // Check for extended header section const EFI_FREEFORM_SUBTYPE_GUID_SECTION* fsgSectionHeader = (const EFI_FREEFORM_SUBTYPE_GUID_SECTION*)(section2Header + 1); if ((UINT32)section.size() < sizeof(EFI_COMMON_SECTION_HEADER2) + sizeof(EFI_FREEFORM_SUBTYPE_GUID_SECTION)) return U_INVALID_SECTION; @@ -2127,61 +2969,62 @@ USTATUS FfsParser::parseFreeformGuidedSectionHeader(const UByteArray & section, guid = fsgSectionHeader->SubTypeGuid; type = sectionHeader->Type; } - + // Check sanity again if ((UINT32)section.size() < headerSize) return U_INVALID_SECTION; - + UByteArray header = section.left(headerSize); UByteArray body = section.mid(headerSize); - + // Get info UString name = sectionTypeToUString(type) + (" section"); UString info = usprintf("Type: %02Xh\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nSubtype GUID: ", - type, - section.size(), section.size(), - header.size(), header.size(), - body.size(), body.size()) - + guidToUString(guid); - - // Construct parsing data - pdata.offset += parentOffset; - pdata.section.freeformSubtypeGuid.guid = guid; - + type, + (UINT32)section.size(), (UINT32)section.size(), + (UINT32)header.size(), (UINT32)header.size(), + (UINT32)body.size(), (UINT32)body.size()) + + guidToUString(guid, false); + // Add tree item if (insertIntoTree) { - index = model->addItem(Types::Section, type, name, UString(), info, header, body, UByteArray(), false, parsingDataToUByteArray(pdata), parent); - + index = model->addItem(localOffset, Types::Section, type, name, UString(), info, header, body, UByteArray(), Movable, parent); + + // Set parsing data + FREEFORM_GUIDED_SECTION_PARSING_DATA pdata = {}; + pdata.guid = guid; + model->setParsingData(index, UByteArray((const char*)&pdata, sizeof(pdata))); + // Rename section model->setName(index, guidToUString(guid)); } + return U_SUCCESS; } -USTATUS FfsParser::parseVersionSectionHeader(const UByteArray & section, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree) +USTATUS FfsParser::parseVersionSectionHeader(const UByteArray & section, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree) { // Check sanity if ((UINT32)section.size() < sizeof(EFI_COMMON_SECTION_HEADER)) return U_INVALID_SECTION; - - // Get data from parent's parsing data - PARSING_DATA pdata = parsingDataFromUModelIndex(parent); - + + // Obtain required information from parent volume + UINT8 ffsVersion = 2; + UModelIndex parentVolumeIndex = model->findParentOfType(parent, Types::Volume); + if (parentVolumeIndex.isValid() && model->hasEmptyParsingData(parentVolumeIndex) == false) { + UByteArray data = model->parsingData(parentVolumeIndex); + const VOLUME_PARSING_DATA* pdata = (const VOLUME_PARSING_DATA*)data.constData(); + ffsVersion = pdata->ffsVersion; + } + // Obtain header fields UINT32 headerSize; UINT16 buildNumber; UINT8 type; const EFI_COMMON_SECTION_HEADER* sectionHeader = (const EFI_COMMON_SECTION_HEADER*)(section.constData()); const EFI_COMMON_SECTION_HEADER2* section2Header = (const EFI_COMMON_SECTION_HEADER2*)(section.constData()); - const EFI_COMMON_SECTION_HEADER_APPLE* appleHeader = (const EFI_COMMON_SECTION_HEADER_APPLE*)(section.constData()); - - if ((UINT32)section.size() >= sizeof(EFI_COMMON_SECTION_HEADER_APPLE) && appleHeader->Reserved == EFI_SECTION_APPLE_USED) { // Check for apple section - const EFI_VERSION_SECTION* versionHeader = (const EFI_VERSION_SECTION*)(appleHeader + 1); - headerSize = sizeof(EFI_COMMON_SECTION_HEADER_APPLE) + sizeof(EFI_VERSION_SECTION); - buildNumber = versionHeader->BuildNumber; - type = appleHeader->Type; - } - else if (pdata.ffsVersion == 3 && uint24ToUint32(sectionHeader->Size) == EFI_SECTION2_IS_USED) { // Check for extended header section + + if (ffsVersion == 3 && uint24ToUint32(sectionHeader->Size) == EFI_SECTION2_IS_USED) { // Check for extended header section const EFI_VERSION_SECTION* versionHeader = (const EFI_VERSION_SECTION*)(section2Header + 1); headerSize = sizeof(EFI_COMMON_SECTION_HEADER2) + sizeof(EFI_VERSION_SECTION); buildNumber = versionHeader->BuildNumber; @@ -2193,57 +3036,54 @@ USTATUS FfsParser::parseVersionSectionHeader(const UByteArray & section, const U buildNumber = versionHeader->BuildNumber; type = sectionHeader->Type; } - + // Check sanity again if ((UINT32)section.size() < headerSize) return U_INVALID_SECTION; - + UByteArray header = section.left(headerSize); UByteArray body = section.mid(headerSize); // Get info UString name = sectionTypeToUString(type) + (" section"); UString info = usprintf("Type: %02Xh\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nBuild number: %u", - type, - section.size(), section.size(), - header.size(), header.size(), - body.size(), body.size(), - buildNumber); - - // Construct parsing data - pdata.offset += parentOffset; - + type, + (UINT32)section.size(), (UINT32)section.size(), + (UINT32)header.size(), (UINT32)header.size(), + (UINT32)body.size(), (UINT32)body.size(), + buildNumber); + // Add tree item if (insertIntoTree) { - index = model->addItem(Types::Section, type, name, UString(), info, header, body, UByteArray(), false, parsingDataToUByteArray(pdata), parent); + index = model->addItem(localOffset, Types::Section, type, name, UString(), info, header, body, UByteArray(), Movable, parent); } + return U_SUCCESS; } -USTATUS FfsParser::parsePostcodeSectionHeader(const UByteArray & section, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree) +USTATUS FfsParser::parsePostcodeSectionHeader(const UByteArray & section, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree) { // Check sanity if ((UINT32)section.size() < sizeof(EFI_COMMON_SECTION_HEADER)) return U_INVALID_SECTION; - - // Get data from parent's parsing data - PARSING_DATA pdata = parsingDataFromUModelIndex(parent); - + + // Obtain required information from parent volume + UINT8 ffsVersion = 2; + UModelIndex parentVolumeIndex = model->findParentOfType(parent, Types::Volume); + if (parentVolumeIndex.isValid() && model->hasEmptyParsingData(parentVolumeIndex) == false) { + UByteArray data = model->parsingData(parentVolumeIndex); + const VOLUME_PARSING_DATA* pdata = (const VOLUME_PARSING_DATA*)data.constData(); + ffsVersion = pdata->ffsVersion; + } + // Obtain header fields UINT32 headerSize; UINT32 postCode; UINT8 type; const EFI_COMMON_SECTION_HEADER* sectionHeader = (const EFI_COMMON_SECTION_HEADER*)(section.constData()); const EFI_COMMON_SECTION_HEADER2* section2Header = (const EFI_COMMON_SECTION_HEADER2*)(section.constData()); - const EFI_COMMON_SECTION_HEADER_APPLE* appleHeader = (const EFI_COMMON_SECTION_HEADER_APPLE*)(section.constData()); - - if ((UINT32)section.size() >= sizeof(EFI_COMMON_SECTION_HEADER_APPLE) && appleHeader->Reserved == EFI_SECTION_APPLE_USED) { // Check for apple section - const POSTCODE_SECTION* postcodeHeader = (const POSTCODE_SECTION*)(appleHeader + 1); - headerSize = sizeof(EFI_COMMON_SECTION_HEADER_APPLE) + sizeof(POSTCODE_SECTION); - postCode = postcodeHeader->Postcode; - type = appleHeader->Type; - } - else if (pdata.ffsVersion == 3 && uint24ToUint32(sectionHeader->Size) == EFI_SECTION2_IS_USED) { // Check for extended header section + + if (ffsVersion == 3 && uint24ToUint32(sectionHeader->Size) == EFI_SECTION2_IS_USED) { // Check for extended header section const POSTCODE_SECTION* postcodeHeader = (const POSTCODE_SECTION*)(section2Header + 1); headerSize = sizeof(EFI_COMMON_SECTION_HEADER2) + sizeof(POSTCODE_SECTION); postCode = postcodeHeader->Postcode; @@ -2255,30 +3095,28 @@ USTATUS FfsParser::parsePostcodeSectionHeader(const UByteArray & section, const postCode = postcodeHeader->Postcode; type = sectionHeader->Type; } - + // Check sanity again if ((UINT32)section.size() < headerSize) return U_INVALID_SECTION; - + UByteArray header = section.left(headerSize); UByteArray body = section.mid(headerSize); - + // Get info UString name = sectionTypeToUString(type) + (" section"); UString info = usprintf("Type: %02Xh\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nPostcode: %Xh", - type, - section.size(), section.size(), - header.size(), header.size(), - body.size(), body.size(), - postCode); - - // Construct parsing data - pdata.offset += parentOffset; - + type, + (UINT32)section.size(), (UINT32)section.size(), + (UINT32)header.size(), (UINT32)header.size(), + (UINT32)body.size(), (UINT32)body.size(), + postCode); + // Add tree item if (insertIntoTree) { - index = model->addItem(Types::Section, sectionHeader->Type, name, UString(), info, header, body, UByteArray(), false, parsingDataToUByteArray(pdata), parent); + index = model->addItem(localOffset, Types::Section, sectionHeader->Type, name, UString(), info, header, body, UByteArray(), Movable, parent); } + return U_SUCCESS; } @@ -2292,30 +3130,30 @@ USTATUS FfsParser::parseSectionBody(const UModelIndex & index) return U_INVALID_SECTION; const EFI_COMMON_SECTION_HEADER* sectionHeader = (const EFI_COMMON_SECTION_HEADER*)(header.constData()); - + switch (sectionHeader->Type) { - // Encapsulation - case EFI_SECTION_COMPRESSION: return parseCompressedSectionBody(index); - case EFI_SECTION_GUID_DEFINED: return parseGuidedSectionBody(index); - case EFI_SECTION_DISPOSABLE: return parseSections(model->body(index), index, true); - // Leaf - case EFI_SECTION_FREEFORM_SUBTYPE_GUID: return parseRawArea(index); - case EFI_SECTION_VERSION: return parseVersionSectionBody(index); - case EFI_SECTION_DXE_DEPEX: - case EFI_SECTION_PEI_DEPEX: - case EFI_SECTION_SMM_DEPEX: return parseDepexSectionBody(index); - case EFI_SECTION_TE: return parseTeImageSectionBody(index); - case EFI_SECTION_PE32: - case EFI_SECTION_PIC: return parsePeImageSectionBody(index); - case EFI_SECTION_USER_INTERFACE: return parseUiSectionBody(index); - case EFI_SECTION_FIRMWARE_VOLUME_IMAGE: return parseRawArea(index); - case EFI_SECTION_RAW: return parseRawSectionBody(index); - // No parsing needed - case EFI_SECTION_COMPATIBILITY16: - case PHOENIX_SECTION_POSTCODE: - case INSYDE_SECTION_POSTCODE: - default: - return U_SUCCESS; + // Encapsulation + case EFI_SECTION_COMPRESSION: return parseCompressedSectionBody(index); + case EFI_SECTION_GUID_DEFINED: return parseGuidedSectionBody(index); + case EFI_SECTION_DISPOSABLE: return parseSections(model->body(index), index, true); + // Leaf + case EFI_SECTION_FREEFORM_SUBTYPE_GUID: return parseRawArea(index); + case EFI_SECTION_VERSION: return parseVersionSectionBody(index); + case EFI_SECTION_DXE_DEPEX: + case EFI_SECTION_PEI_DEPEX: + case EFI_SECTION_MM_DEPEX: return parseDepexSectionBody(index); + case EFI_SECTION_TE: return parseTeImageSectionBody(index); + case EFI_SECTION_PE32: + case EFI_SECTION_PIC: return parsePeImageSectionBody(index); + case EFI_SECTION_USER_INTERFACE: return parseUiSectionBody(index); + case EFI_SECTION_FIRMWARE_VOLUME_IMAGE: return parseRawArea(index); + case EFI_SECTION_RAW: return parseRawSectionBody(index); + // No parsing needed + case EFI_SECTION_COMPATIBILITY16: + case PHOENIX_SECTION_POSTCODE: + case INSYDE_SECTION_POSTCODE: + default: + return U_SUCCESS; } } @@ -2324,30 +3162,38 @@ USTATUS FfsParser::parseCompressedSectionBody(const UModelIndex & index) // Sanity check if (!index.isValid()) return U_INVALID_PARAMETER; - - // Get data from parsing data - PARSING_DATA pdata = parsingDataFromUModelIndex(index); - UINT8 algorithm = pdata.section.compressed.compressionType; - + + // Obtain required information from parsing data + UINT8 compressionType = EFI_NOT_COMPRESSED; + UINT32 uncompressedSize = (UINT32)model->body(index).size(); + if (model->hasEmptyParsingData(index) == false) { + UByteArray data = model->parsingData(index); + const COMPRESSED_SECTION_PARSING_DATA* pdata = (const COMPRESSED_SECTION_PARSING_DATA*)data.constData(); + compressionType = readUnaligned(pdata).compressionType; + uncompressedSize = readUnaligned(pdata).uncompressedSize; + } + // Decompress section + UINT8 algorithm = COMPRESSION_ALGORITHM_NONE; + UINT32 dictionarySize = 0; UByteArray decompressed; UByteArray efiDecompressed; - USTATUS result = decompress(model->body(index), algorithm, decompressed, efiDecompressed); + USTATUS result = decompress(model->body(index), compressionType, algorithm, dictionarySize, decompressed, efiDecompressed); if (result) { - msg(UString("parseCompressedSectionBody: decompression failed with error ") + errorCodeToUString(result), index); + msg(usprintf("%s: decompression failed with error ", __FUNCTION__) + errorCodeToUString(result), index); return U_SUCCESS; } // Check reported uncompressed size - if (pdata.section.compressed.uncompressedSize != (UINT32)decompressed.size()) { - msg(usprintf("parseCompressedSectionBody: decompressed size stored in header %Xh (%u) differs from actual %Xh (%u)", - pdata.section.compressed.uncompressedSize, - pdata.section.compressed.uncompressedSize, - decompressed.size(), - decompressed.size()), index); - model->addInfo(index, usprintf("\nActual decompressed size: %Xh (%u)", decompressed.size(), decompressed.size())); + if (uncompressedSize != (UINT32)decompressed.size()) { + msg(usprintf("%s: decompressed size stored in header %Xh (%u) differs from actual %Xh (%u)", + __FUNCTION__, + uncompressedSize, uncompressedSize, + (UINT32)decompressed.size(), (UINT32)decompressed.size()), + index); + model->addInfo(index, usprintf("\nActual decompressed size: %Xh (%u)", (UINT32)decompressed.size(), (UINT32)decompressed.size())); } - + // Check for undecided compression algorithm, this is a special case if (algorithm == COMPRESSION_ALGORITHM_UNDECIDED) { // Try preparse of sections decompressed with Tiano algorithm @@ -2360,18 +3206,29 @@ USTATUS FfsParser::parseCompressedSectionBody(const UModelIndex & index) decompressed = efiDecompressed; } else { - msg(UString("parseCompressedSectionBody: can't guess the correct decompression algorithm, both preparse steps are failed"), index); + msg(usprintf("%s: can't guess the correct decompression algorithm, both preparse steps are failed", __FUNCTION__), index); } } - + // Add info model->addInfo(index, UString("\nCompression algorithm: ") + compressionTypeToUString(algorithm)); - - // Update data - pdata.section.compressed.algorithm = algorithm; - if (algorithm != COMPRESSION_ALGORITHM_NONE) + if (algorithm == COMPRESSION_ALGORITHM_LZMA || algorithm == COMPRESSION_ALGORITHM_LZMA_INTEL_LEGACY) { + model->addInfo(index, usprintf("\nLZMA dictionary size: %Xh", dictionarySize)); + } + + // Set compression data + if (algorithm != COMPRESSION_ALGORITHM_NONE) { + model->setUncompressedData(index, decompressed); model->setCompressed(index, true); - model->setParsingData(index, parsingDataToUByteArray(pdata)); + } + + // Set parsing data + COMPRESSED_SECTION_PARSING_DATA pdata = {}; + pdata.algorithm = algorithm; + pdata.dictionarySize = dictionarySize; + pdata.compressionType = compressionType; + pdata.uncompressedSize = uncompressedSize; + model->setParsingData(index, UByteArray((const char*)&pdata, sizeof(pdata))); // Parse decompressed data return parseSections(decompressed, index, true); @@ -2382,27 +3239,31 @@ USTATUS FfsParser::parseGuidedSectionBody(const UModelIndex & index) // Sanity check if (!index.isValid()) return U_INVALID_PARAMETER; - - // Get data from parsing data - PARSING_DATA pdata = parsingDataFromUModelIndex(index); - EFI_GUID guid = pdata.section.guidDefined.guid; - + + // Obtain required information from parsing data + EFI_GUID guid = { 0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0 }}; + if (model->hasEmptyParsingData(index) == false) { + UByteArray data = model->parsingData(index); + const GUIDED_SECTION_PARSING_DATA* pdata = (const GUIDED_SECTION_PARSING_DATA*)data.constData(); + guid = readUnaligned(pdata).guid; + } + // Check if section requires processing UByteArray processed = model->body(index); UByteArray efiDecompressed; UString info; bool parseCurrentSection = true; UINT8 algorithm = COMPRESSION_ALGORITHM_NONE; + UINT32 dictionarySize = 0; + UByteArray baGuid = UByteArray((const char*)&guid, sizeof(EFI_GUID)); // Tiano compressed section - if (UByteArray((const char*)&guid, sizeof(EFI_GUID)) == EFI_GUIDED_SECTION_TIANO) { - algorithm = EFI_STANDARD_COMPRESSION; - USTATUS result = decompress(model->body(index), algorithm, processed, efiDecompressed); + if (baGuid == EFI_GUIDED_SECTION_TIANO) { + USTATUS result = decompress(model->body(index), EFI_STANDARD_COMPRESSION, algorithm, dictionarySize, processed, efiDecompressed); if (result) { - parseCurrentSection = false; - msg(UString("parseGuidedSectionBody: decompression failed with error ") + errorCodeToUString(result), index); + msg(usprintf("%s: decompression failed with error ", __FUNCTION__) + errorCodeToUString(result), index); return U_SUCCESS; } - + // Check for undecided compression algorithm, this is a special case if (algorithm == COMPRESSION_ALGORITHM_UNDECIDED) { // Try preparse of sections decompressed with Tiano algorithm @@ -2415,47 +3276,96 @@ USTATUS FfsParser::parseGuidedSectionBody(const UModelIndex & index) processed = efiDecompressed; } else { - msg(UString("parseGuidedSectionBody: can't guess the correct decompression algorithm, both preparse steps are failed"), index); - parseCurrentSection = false; + msg(usprintf("%s: can't guess the correct decompression algorithm, both preparse steps are failed", __FUNCTION__), index); + parseCurrentSection = false; } } info += UString("\nCompression algorithm: ") + compressionTypeToUString(algorithm); - info += usprintf("\nDecompressed size: %Xh (%u)", processed.size(), processed.size()); + info += usprintf("\nDecompressed size: %Xh (%u)", (UINT32)processed.size(), (UINT32)processed.size()); } // LZMA compressed section - else if (UByteArray((const char*)&guid, sizeof(EFI_GUID)) == EFI_GUIDED_SECTION_LZMA) { - algorithm = EFI_CUSTOMIZED_COMPRESSION; - USTATUS result = decompress(model->body(index), algorithm, processed, efiDecompressed); + else if (baGuid == EFI_GUIDED_SECTION_LZMA + || baGuid == EFI_GUIDED_SECTION_LZMA_HP + || baGuid == EFI_GUIDED_SECTION_LZMA_MS) { + USTATUS result = decompress(model->body(index), EFI_CUSTOMIZED_COMPRESSION, algorithm, dictionarySize, processed, efiDecompressed); if (result) { - parseCurrentSection = false; - msg(UString("parseGuidedSectionBody: decompression failed with error ") + errorCodeToUString(result), index); + msg(usprintf("%s: decompression failed with error ", __FUNCTION__) + errorCodeToUString(result), index); return U_SUCCESS; } - + if (algorithm == COMPRESSION_ALGORITHM_LZMA) { info += UString("\nCompression algorithm: LZMA"); - info += usprintf("\nDecompressed size: %Xh (%u)", processed.size(), processed.size()); + info += usprintf("\nDecompressed size: %Xh (%u)", (UINT32)processed.size(), (UINT32)processed.size()); + info += usprintf("\nLZMA dictionary size: %Xh", dictionarySize); } else { info += UString("\nCompression algorithm: unknown"); - parseCurrentSection = false; - } + parseCurrentSection = false; + } } + // LZMAF86 compressed section + else if (baGuid == EFI_GUIDED_SECTION_LZMAF86) { + USTATUS result = decompress(model->body(index), EFI_CUSTOMIZED_COMPRESSION_LZMAF86, algorithm, dictionarySize, processed, efiDecompressed); + if (result) { + msg(usprintf("%s: decompression failed with error ", __FUNCTION__) + errorCodeToUString(result), index); + return U_SUCCESS; + } + + if (algorithm == COMPRESSION_ALGORITHM_LZMAF86) { + info += UString("\nCompression algorithm: LZMAF86"); + info += usprintf("\nDecompressed size: %Xh (%u)", (UINT32)processed.size(), (UINT32)processed.size()); + info += usprintf("\nLZMA dictionary size: %Xh", dictionarySize); + } + else { + info += UString("\nCompression algorithm: unknown"); + parseCurrentSection = false; + } + } + // GZip compressed section + else if (baGuid == EFI_GUIDED_SECTION_GZIP) { + USTATUS result = gzipDecompress(model->body(index), processed); + if (result) { + msg(usprintf("%s: decompression failed with error ", __FUNCTION__) + errorCodeToUString(result), index); + return U_SUCCESS; + } + algorithm = COMPRESSION_ALGORITHM_GZIP; + info += UString("\nCompression algorithm: GZip"); + info += usprintf("\nDecompressed size: %Xh (%u)", (UINT32)processed.size(), (UINT32)processed.size()); + } + // Zlib compressed section + else if (baGuid == EFI_GUIDED_SECTION_ZLIB_AMD) { + USTATUS result = zlibDecompress(model->body(index), processed); + if (result) { + msg(usprintf("%s: decompression failed with error ", __FUNCTION__) + errorCodeToUString(result), index); + return U_SUCCESS; + } + + algorithm = COMPRESSION_ALGORITHM_ZLIB; + info += UString("\nCompression algorithm: Zlib"); + info += usprintf("\nDecompressed size: %Xh (%u)", (UINT32)processed.size(), (UINT32)processed.size()); + } + // Add info model->addInfo(index, info); - - // Update data - if (algorithm != COMPRESSION_ALGORITHM_NONE) + + // Set parsing data + GUIDED_SECTION_PARSING_DATA pdata = {}; + pdata.dictionarySize = dictionarySize; + model->setParsingData(index, UByteArray((const char*)&pdata, sizeof(pdata))); + + // Set compression data + if (algorithm != COMPRESSION_ALGORITHM_NONE) { + model->setUncompressedData(index, processed); model->setCompressed(index, true); - model->setParsingData(index, parsingDataToUByteArray(pdata)); - + } + if (!parseCurrentSection) { - msg(UString("parseGuidedSectionBody: GUID defined section can not be processed"), index); + msg(usprintf("%s: GUID defined section can not be processed", __FUNCTION__), index); return U_SUCCESS; } - + return parseSections(processed, index, true); } @@ -2464,10 +3374,10 @@ USTATUS FfsParser::parseVersionSectionBody(const UModelIndex & index) // Sanity check if (!index.isValid()) return U_INVALID_PARAMETER; - + // Add info - model->addInfo(index, UString("\nVersion string: ") + UString::fromUtf16((const CHAR16*)model->body(index).constData())); - + model->addInfo(index, UString("\nVersion string: ") + uFromUcs2(model->body(index).constData())); + return U_SUCCESS; } @@ -2476,122 +3386,124 @@ USTATUS FfsParser::parseDepexSectionBody(const UModelIndex & index) // Sanity check if (!index.isValid()) return U_INVALID_PARAMETER; - + UByteArray body = model->body(index); UString parsed; - + // Check data to be present if (body.size() < 2) { // 2 is a minimal sane value, i.e TRUE + END - msg(UString("parseDepexSectionBody: DEPEX section too short"), index); + msg(usprintf("%s: DEPEX section too short", __FUNCTION__), index); return U_DEPEX_PARSE_FAILED; } - + const EFI_GUID * guid; const UINT8* current = (const UINT8*)body.constData(); - + // Special cases of first opcode switch (*current) { - case EFI_DEP_BEFORE: - if (body.size() != 2 * EFI_DEP_OPCODE_SIZE + sizeof(EFI_GUID)) { - msg(UString("parseDepexSectionBody: DEPEX section too long for a section starting with BEFORE opcode"), index); - return U_SUCCESS; - } - guid = (const EFI_GUID*)(current + EFI_DEP_OPCODE_SIZE); - parsed += UString("\nBEFORE ") + guidToUString(*guid); - current += EFI_DEP_OPCODE_SIZE + sizeof(EFI_GUID); - if (*current != EFI_DEP_END){ - msg(UString("parseDepexSectionBody: DEPEX section ends with non-END opcode"), index); - return U_SUCCESS; - } - return U_SUCCESS; - case EFI_DEP_AFTER: - if (body.size() != 2 * EFI_DEP_OPCODE_SIZE + sizeof(EFI_GUID)){ - msg(UString("parseDepexSectionBody: DEPEX section too long for a section starting with AFTER opcode"), index); - return U_SUCCESS; - } - guid = (const EFI_GUID*)(current + EFI_DEP_OPCODE_SIZE); - parsed += UString("\nAFTER ") + guidToUString(*guid); - current += EFI_DEP_OPCODE_SIZE + sizeof(EFI_GUID); - if (*current != EFI_DEP_END) { - msg(UString("parseDepexSectionBody: DEPEX section ends with non-END opcode"), index); - return U_SUCCESS; - } - return U_SUCCESS; - case EFI_DEP_SOR: - if (body.size() <= 2 * EFI_DEP_OPCODE_SIZE) { - msg(UString("parseDepexSectionBody: DEPEX section too short for a section starting with SOR opcode"), index); - return U_SUCCESS; - } - parsed += UString("\nSOR"); - current += EFI_DEP_OPCODE_SIZE; - break; - } - - // Parse the rest of depex - while (current - (const UINT8*)body.constData() < body.size()) { - switch (*current) { - case EFI_DEP_BEFORE: { - msg(UString("parseDepexSectionBody: misplaced BEFORE opcode"), index); - return U_SUCCESS; - } - case EFI_DEP_AFTER: { - msg(UString("parseDepexSectionBody: misplaced AFTER opcode"), index); - return U_SUCCESS; - } - case EFI_DEP_SOR: { - msg(UString("parseDepexSectionBody: misplaced SOR opcode"), index); - return U_SUCCESS; - } - case EFI_DEP_PUSH: - // Check that the rest of depex has correct size - if ((UINT32)body.size() - (UINT32)(current - (const UINT8*)body.constData()) <= EFI_DEP_OPCODE_SIZE + sizeof(EFI_GUID)) { - parsed.clear(); - msg(UString("parseDepexSectionBody: remains of DEPEX section too short for PUSH opcode"), index); + case EFI_DEP_BEFORE: + if (body.size() != 2 * EFI_DEP_OPCODE_SIZE + sizeof(EFI_GUID)) { + msg(usprintf("%s: DEPEX section too long for a section starting with BEFORE opcode", __FUNCTION__), index); return U_SUCCESS; } guid = (const EFI_GUID*)(current + EFI_DEP_OPCODE_SIZE); - parsed += UString("\nPUSH ") + guidToUString(*guid); + parsed += UString("\nBEFORE ") + guidToUString(readUnaligned(guid)); current += EFI_DEP_OPCODE_SIZE + sizeof(EFI_GUID); - break; - case EFI_DEP_AND: - parsed += UString("\nAND"); - current += EFI_DEP_OPCODE_SIZE; - break; - case EFI_DEP_OR: - parsed += UString("\nOR"); - current += EFI_DEP_OPCODE_SIZE; - break; - case EFI_DEP_NOT: - parsed += UString("\nNOT"); - current += EFI_DEP_OPCODE_SIZE; - break; - case EFI_DEP_TRUE: - parsed += UString("\nTRUE"); - current += EFI_DEP_OPCODE_SIZE; - break; - case EFI_DEP_FALSE: - parsed += UString("\nFALSE"); - current += EFI_DEP_OPCODE_SIZE; - break; - case EFI_DEP_END: - parsed += UString("\nEND"); - current += EFI_DEP_OPCODE_SIZE; - // Check that END is the last opcode - if (current - (const UINT8*)body.constData() < body.size()) { - parsed.clear(); - msg(UString("parseDepexSectionBody: DEPEX section ends with non-END opcode"), index); + if (*current != EFI_DEP_END){ + msg(usprintf("%s: DEPEX section ends with non-END opcode", __FUNCTION__), index); + return U_SUCCESS; } - break; - default: - msg(UString("parseDepexSectionBody: unknown opcode"), index); + // No further parsing required return U_SUCCESS; + case EFI_DEP_AFTER: + if (body.size() != 2 * EFI_DEP_OPCODE_SIZE + sizeof(EFI_GUID)){ + msg(usprintf("%s: DEPEX section too long for a section starting with AFTER opcode", __FUNCTION__), index); + return U_SUCCESS; + } + guid = (const EFI_GUID*)(current + EFI_DEP_OPCODE_SIZE); + parsed += UString("\nAFTER ") + guidToUString(readUnaligned(guid)); + current += EFI_DEP_OPCODE_SIZE + sizeof(EFI_GUID); + if (*current != EFI_DEP_END) { + msg(usprintf("%s: DEPEX section ends with non-END opcode", __FUNCTION__), index); + return U_SUCCESS; + } + // No further parsing required + return U_SUCCESS; + case EFI_DEP_SOR: + if (body.size() <= 2 * EFI_DEP_OPCODE_SIZE) { + msg(usprintf("%s: DEPEX section too short for a section starting with SOR opcode", __FUNCTION__), index); + return U_SUCCESS; + } + parsed += UString("\nSOR"); + current += EFI_DEP_OPCODE_SIZE; break; + } + + // Parse the rest of depex + while (current - (const UINT8*)body.constData() < body.size()) { + switch (*current) { + case EFI_DEP_BEFORE: { + msg(usprintf("%s: misplaced BEFORE opcode", __FUNCTION__), index); + return U_SUCCESS; + } + case EFI_DEP_AFTER: { + msg(usprintf("%s: misplaced AFTER opcode", __FUNCTION__), index); + return U_SUCCESS; + } + case EFI_DEP_SOR: { + msg(usprintf("%s: misplaced SOR opcode", __FUNCTION__), index); + return U_SUCCESS; + } + case EFI_DEP_PUSH: + // Check that the rest of depex has correct size + if ((UINT32)body.size() - (UINT32)(current - (const UINT8*)body.constData()) <= EFI_DEP_OPCODE_SIZE + sizeof(EFI_GUID)) { + parsed.clear(); + msg(usprintf("%s: remains of DEPEX section too short for PUSH opcode", __FUNCTION__), index); + return U_SUCCESS; + } + guid = (const EFI_GUID*)(current + EFI_DEP_OPCODE_SIZE); + parsed += UString("\nPUSH ") + guidToUString(readUnaligned(guid)); + current += EFI_DEP_OPCODE_SIZE + sizeof(EFI_GUID); + break; + case EFI_DEP_AND: + parsed += UString("\nAND"); + current += EFI_DEP_OPCODE_SIZE; + break; + case EFI_DEP_OR: + parsed += UString("\nOR"); + current += EFI_DEP_OPCODE_SIZE; + break; + case EFI_DEP_NOT: + parsed += UString("\nNOT"); + current += EFI_DEP_OPCODE_SIZE; + break; + case EFI_DEP_TRUE: + parsed += UString("\nTRUE"); + current += EFI_DEP_OPCODE_SIZE; + break; + case EFI_DEP_FALSE: + parsed += UString("\nFALSE"); + current += EFI_DEP_OPCODE_SIZE; + break; + case EFI_DEP_END: + parsed += UString("\nEND"); + current += EFI_DEP_OPCODE_SIZE; + // Check that END is the last opcode + if (current - (const UINT8*)body.constData() < body.size()) { + parsed.clear(); + msg(usprintf("%s: DEPEX section ends with non-END opcode", __FUNCTION__), index); + } + break; + default: + msg(usprintf("%s: unknown opcode %02Xh", __FUNCTION__, *current), index); + // No further parsing required + return U_SUCCESS; } } // Add info model->addInfo(index, UString("\nParsed expression:") + parsed); - + return U_SUCCESS; } @@ -2600,15 +3512,15 @@ USTATUS FfsParser::parseUiSectionBody(const UModelIndex & index) // Sanity check if (!index.isValid()) return U_INVALID_PARAMETER; - - UString text = UString::fromUtf16((const CHAR16*)model->body(index).constData()); - + + UString text = uFromUcs2(model->body(index).constData()); + // Add info model->addInfo(index, UString("\nText: ") + text); - + // Rename parent file model->setText(model->findParentOfType(index, Types::File), text); - + return U_SUCCESS; } @@ -2616,17 +3528,17 @@ USTATUS FfsParser::parseAprioriRawSection(const UByteArray & body, UString & par { // Sanity check if (body.size() % sizeof(EFI_GUID)) { - msg(UString("parseAprioriRawSection: apriori file has size is not a multiple of 16")); + msg(usprintf("%s: apriori file has size is not a multiple of 16", __FUNCTION__)); } parsed.clear(); - UINT32 count = body.size() / sizeof(EFI_GUID); + UINT32 count = (UINT32)(body.size() / sizeof(EFI_GUID)); if (count > 0) { for (UINT32 i = 0; i < count; i++) { const EFI_GUID* guid = (const EFI_GUID*)body.constData() + i; - parsed += UString("\n") + guidToUString(*guid); + parsed += "\n" + guidToUString(readUnaligned(guid)); } } - + return U_SUCCESS; } @@ -2635,46 +3547,45 @@ USTATUS FfsParser::parseRawSectionBody(const UModelIndex & index) // Sanity check if (!index.isValid()) return U_INVALID_PARAMETER; - + // Check for apriori file UModelIndex parentFile = model->findParentOfType(index, Types::File); - + if (!parentFile.isValid()) + return U_INVALID_RAW_AREA; + // Get parent file parsing data - PARSING_DATA pdata = parsingDataFromUModelIndex(parentFile); - UByteArray parentFileGuid((const char*)&pdata.file.guid, sizeof(EFI_GUID)); - + UByteArray parentFileGuid(model->header(parentFile).constData(), sizeof(EFI_GUID)); if (parentFileGuid == EFI_PEI_APRIORI_FILE_GUID) { // PEI apriori file - // Parse apriori file list - UString str; - USTATUS result = parseAprioriRawSection(model->body(index), str); - if (!result && !str.isEmpty()) - model->addInfo(index, UString("\nFile list:") + str); - // Set parent file text model->setText(parentFile, UString("PEI apriori file")); - - return U_SUCCESS; - } - else if (parentFileGuid == EFI_DXE_APRIORI_FILE_GUID) { // DXE apriori file // Parse apriori file list UString str; USTATUS result = parseAprioriRawSection(model->body(index), str); if (!result && !str.isEmpty()) model->addInfo(index, UString("\nFile list:") + str); - - // Set parent file text + return result; + } + else if (parentFileGuid == EFI_DXE_APRIORI_FILE_GUID) { // DXE apriori file + // Rename parent file model->setText(parentFile, UString("DXE apriori file")); - - return U_SUCCESS; + // Parse apriori file list + UString str; + USTATUS result = parseAprioriRawSection(model->body(index), str); + if (!result && !str.isEmpty()) + model->addInfo(index, UString("\nFile list:") + str); + return result; } - else if (parentFileGuid == NVRAM_NVAR_EXTERNAL_DEFAULTS_FILE_GUID) { - // Parse NVAR area - parseNvarStore(index); - - // Set parent file text + else if (parentFileGuid == NVRAM_NVAR_EXTERNAL_DEFAULTS_FILE_GUID) { // AMI NVRAM external defaults + // Rename parent file model->setText(parentFile, UString("NVRAM external defaults")); + // Parse NVAR area + return nvramParser->parseNvarStore(index); } - + else if (parentFileGuid == PROTECTED_RANGE_VENDOR_HASH_FILE_GUID_AMI) { // AMI vendor hash file + // Parse AMI vendor hash file + return parseVendorHashFile(parentFileGuid, index); + } + // Parse as raw area return parseRawArea(index); } @@ -2685,84 +3596,84 @@ USTATUS FfsParser::parsePeImageSectionBody(const UModelIndex & index) // Sanity check if (!index.isValid()) return U_INVALID_PARAMETER; - + // Get section body UByteArray body = model->body(index); if ((UINT32)body.size() < sizeof(EFI_IMAGE_DOS_HEADER)) { - msg(UString("parsePeImageSectionBody: section body size is smaller than DOS header size"), index); + msg(usprintf("%s: section body size is smaller than DOS header size", __FUNCTION__), index); return U_SUCCESS; } - + UString info; const EFI_IMAGE_DOS_HEADER* dosHeader = (const EFI_IMAGE_DOS_HEADER*)body.constData(); if (dosHeader->e_magic != EFI_IMAGE_DOS_SIGNATURE) { info += usprintf("\nDOS signature: %04Xh, invalid", dosHeader->e_magic); - msg(UString("parsePeImageSectionBody: PE32 image with invalid DOS signature"), index); + msg(usprintf("%s: PE32 image with invalid DOS signature", __FUNCTION__), index); model->addInfo(index, info); return U_SUCCESS; } - + const EFI_IMAGE_PE_HEADER* peHeader = (EFI_IMAGE_PE_HEADER*)(body.constData() + dosHeader->e_lfanew); if (body.size() < (UINT8*)peHeader - (UINT8*)dosHeader) { info += UString("\nDOS header: invalid"); - msg(UString("parsePeImageSectionBody: PE32 image with invalid DOS header"), index); + msg(usprintf("%s: PE32 image with invalid DOS header", __FUNCTION__), index); model->addInfo(index, info); return U_SUCCESS; } - + if (peHeader->Signature != EFI_IMAGE_PE_SIGNATURE) { info += usprintf("\nPE signature: %08Xh, invalid", peHeader->Signature); - msg(UString("parsePeImageSectionBody: PE32 image with invalid PE signature"), index); + msg(usprintf("%s: PE32 image with invalid PE signature", __FUNCTION__), index); model->addInfo(index, info); return U_SUCCESS; } - + const EFI_IMAGE_FILE_HEADER* imageFileHeader = (const EFI_IMAGE_FILE_HEADER*)(peHeader + 1); if (body.size() < (UINT8*)imageFileHeader - (UINT8*)dosHeader) { info += UString("\nPE header: invalid"); - msg(UString("parsePeImageSectionBody: PE32 image with invalid PE header"), index); + msg(usprintf("%s: PE32 image with invalid PE header", __FUNCTION__), index); model->addInfo(index, info); return U_SUCCESS; } - + info += usprintf("\nDOS signature: %04Xh\nPE signature: %08Xh", - dosHeader->e_magic, - peHeader->Signature) + - UString("\nMachine type: ") + machineTypeToUString(imageFileHeader->Machine) + - usprintf("\nNumber of sections: %u\nCharacteristics: %04Xh", - imageFileHeader->NumberOfSections, - imageFileHeader->Characteristics); - - EFI_IMAGE_OPTIONAL_HEADER_POINTERS_UNION optionalHeader; + dosHeader->e_magic, + peHeader->Signature) + + UString("\nMachine type: ") + machineTypeToUString(imageFileHeader->Machine) + + usprintf("\nNumber of sections: %u\nCharacteristics: %04Xh", + imageFileHeader->NumberOfSections, + imageFileHeader->Characteristics); + + EFI_IMAGE_OPTIONAL_HEADER_POINTERS_UNION optionalHeader = {}; optionalHeader.H32 = (const EFI_IMAGE_OPTIONAL_HEADER32*)(imageFileHeader + 1); if (body.size() < (UINT8*)optionalHeader.H32 - (UINT8*)dosHeader) { info += UString("\nPE optional header: invalid"); - msg(UString("parsePeImageSectionBody: PE32 image with invalid PE optional header"), index); + msg(usprintf("%s: PE32 image with invalid PE optional header", __FUNCTION__), index); model->addInfo(index, info); return U_SUCCESS; } - + if (optionalHeader.H32->Magic == EFI_IMAGE_PE_OPTIONAL_HDR32_MAGIC) { info += usprintf("\nOptional header signature: %04Xh\nSubsystem: %04Xh\nAddress of entry point: %Xh\nBase of code: %Xh\nImage base: %Xh", - optionalHeader.H32->Magic, - optionalHeader.H32->Subsystem, - optionalHeader.H32->AddressOfEntryPoint, - optionalHeader.H32->BaseOfCode, - optionalHeader.H32->ImageBase); + optionalHeader.H32->Magic, + optionalHeader.H32->Subsystem, + optionalHeader.H32->AddressOfEntryPoint, + optionalHeader.H32->BaseOfCode, + optionalHeader.H32->ImageBase); } else if (optionalHeader.H32->Magic == EFI_IMAGE_PE_OPTIONAL_HDR64_MAGIC) { info += usprintf("\nOptional header signature: %04Xh\nSubsystem: %04Xh\nAddress of entry point: %Xh\nBase of code: %Xh\nImage base: %" PRIX64 "h", - optionalHeader.H64->Magic, - optionalHeader.H64->Subsystem, - optionalHeader.H64->AddressOfEntryPoint, - optionalHeader.H64->BaseOfCode, - optionalHeader.H64->ImageBase); + optionalHeader.H64->Magic, + optionalHeader.H64->Subsystem, + optionalHeader.H64->AddressOfEntryPoint, + optionalHeader.H64->BaseOfCode, + optionalHeader.H64->ImageBase); } else { info += usprintf("\nOptional header signature: %04Xh, unknown", optionalHeader.H32->Magic); - msg(UString("parsePeImageSectionBody: PE32 image with invalid optional PE header signature"), index); + msg(usprintf("%s: PE32 image with invalid optional PE header signature", __FUNCTION__), index); } - + model->addInfo(index, info); return U_SUCCESS; } @@ -2773,45 +3684,44 @@ USTATUS FfsParser::parseTeImageSectionBody(const UModelIndex & index) // Check sanity if (!index.isValid()) return U_INVALID_PARAMETER; - + // Get section body UByteArray body = model->body(index); if ((UINT32)body.size() < sizeof(EFI_IMAGE_TE_HEADER)) { - msg(("parsePeImageSectionBody: section body size is smaller than TE header size"), index); + msg(usprintf("%s: section body size is smaller than TE header size", __FUNCTION__), index); return U_SUCCESS; } - + UString info; const EFI_IMAGE_TE_HEADER* teHeader = (const EFI_IMAGE_TE_HEADER*)body.constData(); if (teHeader->Signature != EFI_IMAGE_TE_SIGNATURE) { info += usprintf("\nSignature: %04Xh, invalid", teHeader->Signature); - msg(UString("parseTeImageSectionBody: TE image with invalid TE signature"), index); + msg(usprintf("%s: TE image with invalid TE signature", __FUNCTION__), index); } else { info += usprintf("\nSignature: %04Xh", teHeader->Signature) + - UString("\nMachine type: ") + machineTypeToUString(teHeader->Machine) + - usprintf("\nNumber of sections: %u\nSubsystem: %02Xh\nStripped size: %Xh (%u)\n" - "Base of code: %Xh\nAddress of entry point: %Xh\nImage base: %" PRIX64 "h\nAdjusted image base: %" PRIX64 "h", - teHeader->NumberOfSections, - teHeader->Subsystem, - teHeader->StrippedSize, teHeader->StrippedSize, - teHeader->BaseOfCode, - teHeader->AddressOfEntryPoint, - teHeader->ImageBase, - teHeader->ImageBase + teHeader->StrippedSize - sizeof(EFI_IMAGE_TE_HEADER)); + UString("\nMachine type: ") + machineTypeToUString(teHeader->Machine) + + usprintf("\nNumber of sections: %u\nSubsystem: %02Xh\nStripped size: %Xh (%u)\n" + "Base of code: %Xh\nAddress of entry point: %Xh\nImage base: %" PRIX64 "h\nAdjusted image base: %" PRIX64 "h", + teHeader->NumberOfSections, + teHeader->Subsystem, + teHeader->StrippedSize, teHeader->StrippedSize, + teHeader->BaseOfCode, + teHeader->AddressOfEntryPoint, + teHeader->ImageBase, + teHeader->ImageBase + teHeader->StrippedSize - sizeof(EFI_IMAGE_TE_HEADER)); } - - // Get data from parsing data - PARSING_DATA pdata = parsingDataFromUModelIndex(index); - pdata.section.teImage.imageBase = (UINT32)teHeader->ImageBase; - pdata.section.teImage.adjustedImageBase = (UINT32)(teHeader->ImageBase + teHeader->StrippedSize - sizeof(EFI_IMAGE_TE_HEADER)); // Update parsing data - model->setParsingData(index, parsingDataToUByteArray(pdata)); - + TE_IMAGE_SECTION_PARSING_DATA pdata = {}; + pdata.imageBaseType = EFI_IMAGE_TE_BASE_OTHER; // Will be determined later + pdata.originalImageBase = (UINT32)teHeader->ImageBase; + pdata.adjustedImageBase = (UINT32)(teHeader->ImageBase + teHeader->StrippedSize - sizeof(EFI_IMAGE_TE_HEADER)); + model->setParsingData(index, UByteArray((const char*)&pdata, sizeof(pdata))); + // Add TE info model->addInfo(index, info); - + return U_SUCCESS; } @@ -2821,2154 +3731,1658 @@ USTATUS FfsParser::performSecondPass(const UModelIndex & index) // Sanity check if (!index.isValid() || !lastVtf.isValid()) return U_INVALID_PARAMETER; - + // Check for compressed lastVtf if (model->compressed(lastVtf)) { - msg(UString("performSecondPass: the last VTF appears inside compressed item, the image may be damaged"), lastVtf); + msg(usprintf("%s: the last VTF appears inside compressed item, the image may be damaged", __FUNCTION__), lastVtf); return U_SUCCESS; } - // Get parsing data for the last VTF - PARSING_DATA pdata = parsingDataFromUModelIndex(lastVtf); - // Calculate address difference - const UINT32 vtfSize = model->header(lastVtf).size() + model->body(lastVtf).size() + model->tail(lastVtf).size(); - const UINT32 diff = 0xFFFFFFFFUL - pdata.offset - vtfSize + 1; - - // Find and parse FIT - parseFit(index, diff); + const UINT32 vtfSize = (UINT32)(model->header(lastVtf).size() + model->body(lastVtf).size() + model->tail(lastVtf).size()); + addressDiff = 0xFFFFFFFFULL - model->base(lastVtf) - vtfSize + 1; + + // Parse reset vector data + parseResetVectorData(); + + // Find and parse FIT + fitParser->parseFit(index); + + // Check protected ranges + checkProtectedRanges(index); + + // Check TE files to have original or adjusted base + checkTeImageBase(index); - // Apply address information to index and all it's child items - addMemoryAddressesRecursive(index, diff); - - // Add fixed and compressed - addFixedAndCompressedRecursive(index); - return U_SUCCESS; } -USTATUS FfsParser::addFixedAndCompressedRecursive(const UModelIndex & index) { +USTATUS FfsParser::parseResetVectorData() +{ + // Sanity check + if (!lastVtf.isValid()) + return U_SUCCESS; + + // Check VTF to have enough space at the end to fit Reset Vector Data + UByteArray vtf = model->header(lastVtf) + model->body(lastVtf) + model->tail(lastVtf); + if ((UINT32)vtf.size() < sizeof(X86_RESET_VECTOR_DATA)) + return U_SUCCESS; + + const X86_RESET_VECTOR_DATA* resetVectorData = (const X86_RESET_VECTOR_DATA*)(vtf.constData() + vtf.size() - sizeof(X86_RESET_VECTOR_DATA)); + + // Add info + UString info = usprintf("\nAP entry vector: %02X %02X %02X %02X %02X %02X %02X %02X\n" + "Reset vector: %02X %02X %02X %02X %02X %02X %02X %02X\n" + "PEI core entry point: %08Xh\n" + "AP startup segment: %08Xh\n" + "BootFV base address: %08Xh\n", + resetVectorData->ApEntryVector[0], resetVectorData->ApEntryVector[1], resetVectorData->ApEntryVector[2], resetVectorData->ApEntryVector[3], + resetVectorData->ApEntryVector[4], resetVectorData->ApEntryVector[5], resetVectorData->ApEntryVector[6], resetVectorData->ApEntryVector[7], + resetVectorData->ResetVector[0], resetVectorData->ResetVector[1], resetVectorData->ResetVector[2], resetVectorData->ResetVector[3], + resetVectorData->ResetVector[4], resetVectorData->ResetVector[5], resetVectorData->ResetVector[6], resetVectorData->ResetVector[7], + resetVectorData->PeiCoreEntryPoint, + resetVectorData->ApStartupSegment, + resetVectorData->BootFvBaseAddress); + + model->addInfo(lastVtf, info); + return U_SUCCESS; +} + +USTATUS FfsParser::checkTeImageBase(const UModelIndex & index) +{ + // Sanity check + if (!index.isValid()) { + return U_INVALID_PARAMETER; + } + + // Determine relocation type of uncompressed TE image sections + if (model->compressed(index) == false + && model->type(index) == Types::Section + && model->subtype(index) == EFI_SECTION_TE) { + // Obtain required values from parsing data + UINT32 originalImageBase = 0; + UINT32 adjustedImageBase = 0; + UINT8 imageBaseType = EFI_IMAGE_TE_BASE_OTHER; + if (model->hasEmptyParsingData(index) == false) { + UByteArray data = model->parsingData(index); + const TE_IMAGE_SECTION_PARSING_DATA* pdata = (const TE_IMAGE_SECTION_PARSING_DATA*)data.constData(); + originalImageBase = readUnaligned(pdata).originalImageBase; + adjustedImageBase = readUnaligned(pdata).adjustedImageBase; + } + + if (originalImageBase != 0 || adjustedImageBase != 0) { + // Check data memory address to be equal to either OriginalImageBase or AdjustedImageBase + UINT64 address = addressDiff + model->base(index); + UINT32 base = (UINT32)(address + model->header(index).size()); + + if (originalImageBase == base) { + imageBaseType = EFI_IMAGE_TE_BASE_ORIGINAL; + } + else if (adjustedImageBase == base) { + imageBaseType = EFI_IMAGE_TE_BASE_ADJUSTED; + } + else { + // Check for one-bit difference + UINT32 xored = base ^ originalImageBase; // XOR result can't be zero + if ((xored & (xored - 1)) == 0) { // Check that XOR result is a power of 2, i.e. has exactly one bit set + imageBaseType = EFI_IMAGE_TE_BASE_ORIGINAL; + } + else { // The same check for adjustedImageBase + xored = base ^ adjustedImageBase; + if ((xored & (xored - 1)) == 0) { + imageBaseType = EFI_IMAGE_TE_BASE_ADJUSTED; + } + } + } + + // Show message if imageBaseType is still unknown + if (imageBaseType == EFI_IMAGE_TE_BASE_OTHER) { + msg(usprintf("%s: TE image base is neither zero, nor original, nor adjusted, nor top-swapped", __FUNCTION__), index); + } + + // Update parsing data + TE_IMAGE_SECTION_PARSING_DATA pdata = {}; + pdata.imageBaseType = imageBaseType; + pdata.originalImageBase = originalImageBase; + pdata.adjustedImageBase = adjustedImageBase; + model->setParsingData(index, UByteArray((const char*)&pdata, sizeof(pdata))); + } + } + + // Process child items + for (int i = 0; i < model->rowCount(index); i++) { + checkTeImageBase(index.model()->index(i, 0, index)); + } + + return U_SUCCESS; +} + +USTATUS FfsParser::addInfoRecursive(const UModelIndex & index) +{ // Sanity check if (!index.isValid()) return U_INVALID_PARAMETER; - - // Add fixed and compressed info - model->addInfo(index, usprintf("\nCompressed: %s", model->compressed(index) ? "Yes" : "No")); - model->addInfo(index, usprintf("\nFixed: %s", model->fixed(index) ? "Yes" : "No")); - - // Process child items - for (int i = 0; i < model->rowCount(index); i++) { - addFixedAndCompressedRecursive(index.child(i, 0)); - } - - return U_SUCCESS; -} - -USTATUS FfsParser::parseFit(const UModelIndex & index, const UINT32 diff) -{ - // Check sanity - if (!index.isValid()) - return EFI_INVALID_PARAMETER; - - // Search for FIT - UModelIndex fitIndex; - UINT32 fitOffset; - USTATUS result = findFitRecursive(index, diff, fitIndex, fitOffset); - if (result) - return result; - - // FIT not found - if (!fitIndex.isValid()) - return U_SUCCESS; - - // Explicitly set the item as fixed - model->setFixed(fitIndex, true); - - // Special case of FIT header - UByteArray fitBody = model->body(fitIndex); - const FIT_ENTRY* fitHeader = (const FIT_ENTRY*)(fitBody.constData() + fitOffset); - - // Check FIT checksum, if present - UINT32 fitSize = (fitHeader->Size & 0xFFFFFF) << 4; - if (fitHeader->Type & 0x80) { - // Calculate FIT entry checksum - UByteArray tempFIT = model->body(fitIndex).mid(fitOffset, fitSize); - FIT_ENTRY* tempFitHeader = (FIT_ENTRY*)tempFIT.data(); - tempFitHeader->Checksum = 0; - UINT8 calculated = calculateChecksum8((const UINT8*)tempFitHeader, fitSize); - if (calculated != fitHeader->Checksum) { - msg(usprintf("parseFit: invalid FIT table checksum %02Xh, should be %02Xh", fitHeader->Checksum, calculated), fitIndex); - } - } - - // Check fit header type - if ((fitHeader->Type & 0x7F) != FIT_TYPE_HEADER) - msg(("Invalid FIT header type"), fitIndex); - - // Add FIT header to fitTable - std::vector currentStrings; - currentStrings.push_back(UString("_FIT_ ")); - currentStrings.push_back(usprintf("%08Xh", fitSize)); - currentStrings.push_back(usprintf("%04Xh", fitHeader->Version)); - currentStrings.push_back(usprintf("%02Xh", fitHeader->Checksum)); - currentStrings.push_back(fitEntryTypeToUString(fitHeader->Type)); - fitTable.push_back(currentStrings); - - // Process all other entries - bool msgModifiedImageMayNotWork = false; - for (UINT32 i = 1; i < fitHeader->Size; i++) { - currentStrings.clear(); - const FIT_ENTRY* currentEntry = fitHeader + i; - - // Check entry type - switch (currentEntry->Type & 0x7F) { - case FIT_TYPE_HEADER: - msg(UString("parseFit: second FIT header found, the table is damaged"), fitIndex); - break; - - case FIT_TYPE_EMPTY: - case FIT_TYPE_MICROCODE: - break; - - case FIT_TYPE_BIOS_AC_MODULE: - case FIT_TYPE_BIOS_INIT_MODULE: - case FIT_TYPE_TPM_POLICY: - case FIT_TYPE_BIOS_POLICY_DATA: - case FIT_TYPE_TXT_CONF_POLICY: - case FIT_TYPE_AC_KEY_MANIFEST: - case FIT_TYPE_AC_BOOT_POLICY: - default: - msgModifiedImageMayNotWork = true; - break; - } - - // Add entry to fitTable - currentStrings.push_back(usprintf("%016" PRIX64, currentEntry->Address)); - currentStrings.push_back(usprintf("%08Xh", currentEntry->Size, currentEntry->Size)); - currentStrings.push_back(usprintf("%04Xh", currentEntry->Version)); - currentStrings.push_back(usprintf("%02Xh", currentEntry->Checksum)); - currentStrings.push_back(fitEntryTypeToUString(currentEntry->Type)); - fitTable.push_back(currentStrings); - } - - if (msgModifiedImageMayNotWork) - msg(UString("parseFit: opened image may not work after any modification"), fitIndex); - - return U_SUCCESS; -} - -USTATUS FfsParser::findFitRecursive(const UModelIndex & index, const UINT32 diff, UModelIndex & found, UINT32 & fitOffset) -{ - // Sanity check - if (!index.isValid()) - return U_SUCCESS; - - // Process child items - for (int i = 0; i < model->rowCount(index); i++) { - findFitRecursive(index.child(i, 0), diff, found, fitOffset); - if (found.isValid()) - return U_SUCCESS; - } - - // Get parsing data for the current item - PARSING_DATA pdata = parsingDataFromUModelIndex(index); - - // Check for all FIT signatures in item's body - UByteArray lastVtfBody = model->body(lastVtf); - UINT32 storedFitAddress = *(const UINT32*)(lastVtfBody.constData() + lastVtfBody.size() - FIT_POINTER_OFFSET); - for (INT32 offset = model->body(index).indexOf(FIT_SIGNATURE); - offset >= 0; - offset = model->body(index).indexOf(FIT_SIGNATURE, offset + 1)) { - // FIT candidate found, calculate it's physical address - UINT32 fitAddress = pdata.offset + diff + model->header(index).size() + (UINT32)offset; - - // Check FIT address to be stored in the last VTF - if (fitAddress == storedFitAddress) { - found = index; - fitOffset = offset; - msg(usprintf("findFitRecursive: real FIT table found at physical address %08Xh", fitAddress), found); - return U_SUCCESS; - } - else if (model->rowCount(index) == 0) // Show messages only to leaf items - msg(UString("findFitRecursive: FIT table candidate found, but not referenced from the last VTF"), index); - } - - return U_SUCCESS; -} - -USTATUS FfsParser::addMemoryAddressesRecursive(const UModelIndex & index, const UINT32 diff) -{ - // Sanity check - if (!index.isValid()) - return U_SUCCESS; + // Add offset + model->addInfo(index, usprintf("Offset: %Xh\n", model->offset(index)), false); - // Set address value for non-compressed data - if (!model->compressed(index)) { - // Get parsing data for the current item - PARSING_DATA pdata = parsingDataFromUModelIndex(index); - - // Check address sanity - if ((const UINT64)diff + pdata.offset <= 0xFFFFFFFFUL) { - // Update info - pdata.address = diff + pdata.offset; - UINT32 headerSize = model->header(index).size(); + // Add current base if the element is not compressed + // or it's compressed, but its parent isn't + if ((!model->compressed(index)) || (index.parent().isValid() && !model->compressed(index.parent()))) { + // Add physical address of the whole item or its header and data portions separately + UINT64 address = addressDiff + model->base(index); + if (address <= 0xFFFFFFFFUL) { + UINT32 headerSize = (UINT32)model->header(index).size(); if (headerSize) { - model->addInfo(index, usprintf("\nHeader memory address: %08Xh", pdata.address)); - model->addInfo(index, usprintf("\nData memory address: %08Xh", pdata.address + headerSize)); + model->addInfo(index, usprintf("Data address: %08Xh\n", (UINT32)address + headerSize),false); + model->addInfo(index, usprintf("Header address: %08Xh\n", (UINT32)address), false); } else { - model->addInfo(index, usprintf("\nMemory address: %08Xh", pdata.address)); + model->addInfo(index, usprintf("Address: %08Xh\n", (UINT32)address), false); } + } + // Add base + model->addInfo(index, usprintf("Base: %Xh\n", model->base(index)), false); + } + model->addInfo(index, usprintf("Fixed: %s\n", model->fixed(index) ? "Yes" : "No"), false); + + // Process child items + for (int i = 0; i < model->rowCount(index); i++) { + addInfoRecursive(index.model()->index(i, 0, index)); + } + + return U_SUCCESS; +} - // Special case of uncompressed TE image sections - if (model->type(index) == Types::Section && model->subtype(index) == EFI_SECTION_TE) { - // Check data memory address to be equal to either ImageBase or AdjustedImageBase - UINT32 base = pdata.address + headerSize; - pdata.section.teImage.imageBaseType = EFI_IMAGE_TE_BASE_OTHER; - - if (pdata.section.teImage.imageBase == base) { - pdata.section.teImage.imageBaseType = EFI_IMAGE_TE_BASE_ORIGINAL; +USTATUS FfsParser::checkProtectedRanges(const UModelIndex & index) +{ + // Sanity check + if (!index.isValid()) + return U_INVALID_PARAMETER; + + // QByteArray (Qt builds) supports obtaining data from invalid offsets in QByteArray, + // so mid() here doesn't throw anything for UEFITool, just returns ranges with all zeroes + // UByteArray (non-Qt builds) throws an exception that needs to be caught every time or the tools will crash. + + // Calculate digest for BG-protected ranges + UByteArray protectedParts; + bool bgProtectedRangeFound = false; + try { + for (UINT32 i = 0; i < (UINT32)protectedRanges.size(); i++) { + if (protectedRanges[i].Type == PROTECTED_RANGE_INTEL_BOOT_GUARD_IBB) { + bgProtectedRangeFound = true; + if ((UINT64)protectedRanges[i].Offset >= addressDiff) { + protectedRanges[i].Offset -= (UINT32)addressDiff; + } else { + msg(usprintf("%s: suspicious protected range offset", __FUNCTION__), index); } - else if (pdata.section.teImage.adjustedImageBase == base) { - pdata.section.teImage.imageBaseType = EFI_IMAGE_TE_BASE_ADJUSTED; + protectedParts += openedImage.mid(protectedRanges[i].Offset, protectedRanges[i].Size); + markProtectedRangeRecursive(index, protectedRanges[i]); + } + } + } catch (...) { + bgProtectedRangeFound = false; + } + + if (bgProtectedRangeFound) { + UINT8 digest[SHA512_HASH_SIZE] = {}; + UString digestString; + UString ibbDigests; + // SHA1 + digestString = ""; + sha1(protectedParts.constData(), protectedParts.size(), digest); + for (UINT8 i = 0; i < SHA1_HASH_SIZE; i++) { + digestString += usprintf("%02X", digest[i]); + } + ibbDigests += UString("Computed IBB Hash (SHA1): ") + digestString + "\n"; + // SHA256 + digestString = ""; + sha256(protectedParts.constData(), protectedParts.size(), digest); + for (UINT8 i = 0; i < SHA256_HASH_SIZE; i++) { + digestString += usprintf("%02X", digest[i]); + } + ibbDigests += UString("Computed IBB Hash (SHA256): ") + digestString + "\n"; + // SHA384 + digestString = ""; + sha384(protectedParts.constData(), protectedParts.size(), digest); + for (UINT8 i = 0; i < SHA384_HASH_SIZE; i++) { + digestString += usprintf("%02X", digest[i]); + } + ibbDigests += UString("Computed IBB Hash (SHA384): ") + digestString + "\n"; + // SHA512 + digestString = ""; + sha512(protectedParts.constData(), protectedParts.size(), digest); + for (UINT8 i = 0; i < SHA512_HASH_SIZE; i++) { + digestString += usprintf("%02X", digest[i]); + } + ibbDigests += UString("Computed IBB Hash (SHA512): ") + digestString + "\n"; + // SM3 + digestString = ""; + sm3(protectedParts.constData(), protectedParts.size(), digest); + for (UINT8 i = 0; i < SM3_HASH_SIZE; i++) { + digestString += usprintf("%02X", digest[i]); + } + ibbDigests += UString("Computed IBB Hash (SM3): ") + digestString + "\n"; + + securityInfo += ibbDigests + "\n"; + } + + // Calculate digests for vendor-protected ranges + for (UINT32 i = 0; i < (UINT32)protectedRanges.size(); i++) { + if (protectedRanges[i].Type == PROTECTED_RANGE_INTEL_BOOT_GUARD_POST_IBB) { + if (!dxeCore.isValid()) { + msg(usprintf("%s: can't determine DXE volume offset, post-IBB protected range hash can't be checked", __FUNCTION__), index); + } + else { + // Offset will be determined as the offset of root volume with first DXE core + UModelIndex dxeRootVolumeIndex = model->findLastParentOfType(dxeCore, Types::Volume); + if (!dxeRootVolumeIndex.isValid()) { + msg(usprintf("%s: can't determine DXE volume offset, post-IBB protected range hash can't be checked", __FUNCTION__), index); } - else { - // Check for one-bit difference - UINT32 xored = base ^ pdata.section.teImage.imageBase; // XOR result can't be zero - if ((xored & (xored - 1)) == 0) { // Check that XOR result is a power of 2, i.e. has exactly one bit set - pdata.section.teImage.imageBaseType = EFI_IMAGE_TE_BASE_ORIGINAL; + else { + try { + protectedRanges[i].Offset = model->base(dxeRootVolumeIndex); + protectedRanges[i].Size = (UINT32)(model->header(dxeRootVolumeIndex).size() + model->body(dxeRootVolumeIndex).size() + model->tail(dxeRootVolumeIndex).size()); + protectedParts = openedImage.mid(protectedRanges[i].Offset, protectedRanges[i].Size); + + // Calculate the hash + UByteArray digest(SHA512_HASH_SIZE, '\x00'); + if (protectedRanges[i].AlgorithmId == TCG_HASH_ALGORITHM_ID_SHA1) { + sha1(protectedParts.constData(), protectedParts.size(), digest.data()); + digest = digest.left(SHA1_HASH_SIZE); + } + else if (protectedRanges[i].AlgorithmId == TCG_HASH_ALGORITHM_ID_SHA256) { + sha256(protectedParts.constData(), protectedParts.size(), digest.data()); + digest = digest.left(SHA256_HASH_SIZE); + } + else if (protectedRanges[i].AlgorithmId == TCG_HASH_ALGORITHM_ID_SHA384) { + sha384(protectedParts.constData(), protectedParts.size(), digest.data()); + digest = digest.left(SHA384_HASH_SIZE); + } + else if (protectedRanges[i].AlgorithmId == TCG_HASH_ALGORITHM_ID_SHA512) { + sha512(protectedParts.constData(), protectedParts.size(), digest.data()); + digest = digest.left(SHA512_HASH_SIZE); + } + else if (protectedRanges[i].AlgorithmId == TCG_HASH_ALGORITHM_ID_SM3) { + sm3(protectedParts.constData(), protectedParts.size(), digest.data()); + digest = digest.left(SM3_HASH_SIZE); + } + else { + msg(usprintf("%s: post-IBB protected range [%Xh:%Xh] uses unknown hash algorithm %04Xh", __FUNCTION__, + protectedRanges[i].Offset, protectedRanges[i].Offset + protectedRanges[i].Size, protectedRanges[i].AlgorithmId), + model->findByBase(protectedRanges[i].Offset)); + } + + // Check the hash + if (digest != protectedRanges[i].Hash) { + msg(usprintf("%s: post-IBB protected range [%Xh:%Xh] hash mismatch, opened image may refuse to boot", __FUNCTION__, + protectedRanges[i].Offset, protectedRanges[i].Offset + protectedRanges[i].Size), + model->findByBase(protectedRanges[i].Offset)); + } + + markProtectedRangeRecursive(index, protectedRanges[i]); } - else { // The same check for adjustedImageBase - xored = base ^ pdata.section.teImage.adjustedImageBase; - if ((xored & (xored - 1)) == 0) { - pdata.section.teImage.imageBaseType = EFI_IMAGE_TE_BASE_ADJUSTED; + catch(...) { + // Do nothing, this range is likely not found in the image + } + } + } + } + else if (protectedRanges[i].Type == PROTECTED_RANGE_VENDOR_HASH_AMI_V1) { + if (!dxeCore.isValid()) { + msg(usprintf("%s: can't determine DXE volume offset, AMI v1 protected range hash can't be checked", __FUNCTION__), index); + } + else { + // Offset will be determined as the offset of root volume with first DXE core + UModelIndex dxeRootVolumeIndex = model->findLastParentOfType(dxeCore, Types::Volume); + if (!dxeRootVolumeIndex.isValid()) { + msg(usprintf("%s: can't determine DXE volume offset, AMI v1 protected range hash can't be checked", __FUNCTION__), index); + } + else { + try { + protectedRanges[i].Offset = model->base(dxeRootVolumeIndex); + protectedParts = openedImage.mid(protectedRanges[i].Offset, protectedRanges[i].Size); + + UByteArray digest(SHA256_HASH_SIZE, '\x00'); + sha256(protectedParts.constData(), protectedParts.size(), digest.data()); + + if (digest != protectedRanges[i].Hash) { + msg(usprintf("%s: AMI v1 protected range [%Xh:%Xh] hash mismatch, opened image may refuse to boot", __FUNCTION__, + protectedRanges[i].Offset, protectedRanges[i].Offset + protectedRanges[i].Size), + model->findByBase(protectedRanges[i].Offset)); + } + + markProtectedRangeRecursive(index, protectedRanges[i]); + } + catch (...) { + // Do nothing, this range is likely not found in the image + } + } + } + } + else if (protectedRanges[i].Type == PROTECTED_RANGE_VENDOR_HASH_AMI_V2) { + try { + protectedRanges[i].Offset -= (UINT32)addressDiff; + protectedParts = openedImage.mid(protectedRanges[i].Offset, protectedRanges[i].Size); + + UByteArray digest(SHA256_HASH_SIZE, '\x00'); + sha256(protectedParts.constData(), protectedParts.size(), digest.data()); + + if (digest != protectedRanges[i].Hash) { + msg(usprintf("%s: AMI v2 protected range [%Xh:%Xh] hash mismatch, opened image may refuse to boot", __FUNCTION__, + protectedRanges[i].Offset, protectedRanges[i].Offset + protectedRanges[i].Size), + model->findByBase(protectedRanges[i].Offset)); + } + + markProtectedRangeRecursive(index, protectedRanges[i]); + } + catch(...) { + // Do nothing, this range is likely not found in the image + } + } + else if (protectedRanges[i].Type == PROTECTED_RANGE_VENDOR_HASH_AMI_V3) { + try { + protectedRanges[i].Offset -= (UINT32)addressDiff; + protectedParts = openedImage.mid(protectedRanges[i].Offset, protectedRanges[i].Size); + markProtectedRangeRecursive(index, protectedRanges[i]); + + // Process second range + if (i + 1 < (UINT32)protectedRanges.size() && protectedRanges[i + 1].Type == PROTECTED_RANGE_VENDOR_HASH_AMI_V3) { + protectedRanges[i + 1].Offset -= (UINT32)addressDiff; + protectedParts += openedImage.mid(protectedRanges[i + 1].Offset, protectedRanges[i + 1].Size); + markProtectedRangeRecursive(index, protectedRanges[i + 1]); + + // Process third range + if (i + 2 < (UINT32)protectedRanges.size() && protectedRanges[i + 2].Type == PROTECTED_RANGE_VENDOR_HASH_AMI_V3) { + protectedRanges[i + 2].Offset -= (UINT32)addressDiff; + protectedParts += openedImage.mid(protectedRanges[i + 2].Offset, protectedRanges[i + 2].Size); + markProtectedRangeRecursive(index, protectedRanges[i + 2]); + + // Process fourth range + if (i + 3 < (UINT32)protectedRanges.size() && protectedRanges[i + 3].Type == PROTECTED_RANGE_VENDOR_HASH_AMI_V3) { + protectedRanges[i + 3].Offset -= (UINT32)addressDiff; + protectedParts += openedImage.mid(protectedRanges[i + 3].Offset, protectedRanges[i + 3].Size); + markProtectedRangeRecursive(index, protectedRanges[i + 3]); + i += 3; // Skip 3 already processed ranges + } + else { + i += 2; // Skip 2 already processed ranges + } + } + else { + i += 1; // Skip 1 already processed range + } + } + + UByteArray digest(SHA256_HASH_SIZE, '\x00'); + sha256(protectedParts.constData(), protectedParts.size(), digest.data()); + if (digest != protectedRanges[i].Hash) { + msg(usprintf("%s: AMI v3 protected ranges hash mismatch, opened image may refuse to boot", __FUNCTION__)); + } + } + catch (...) { + // Do nothing, this range is likely not found in the image + } + } + else if (protectedRanges[i].Type == PROTECTED_RANGE_VENDOR_HASH_PHOENIX) { + try { + protectedRanges[i].Offset += (UINT32)protectedRegionsBase; + protectedParts = openedImage.mid(protectedRanges[i].Offset, protectedRanges[i].Size); + + UByteArray digest(SHA256_HASH_SIZE, '\x00'); + sha256(protectedParts.constData(), protectedParts.size(), digest.data()); + + if (digest != protectedRanges[i].Hash) { + msg(usprintf("%s: Phoenix protected range [%Xh:%Xh] hash mismatch, opened image may refuse to boot", __FUNCTION__, + protectedRanges[i].Offset, protectedRanges[i].Offset + protectedRanges[i].Size), + model->findByBase(protectedRanges[i].Offset)); + } + + markProtectedRangeRecursive(index, protectedRanges[i]); + } + catch(...) { + // Do nothing, this range is likely not found in the image + } + } + else if (protectedRanges[i].Type == PROTECTED_RANGE_VENDOR_HASH_MICROSOFT_PMDA) { + try { + protectedRanges[i].Offset -= (UINT32)addressDiff; + protectedParts = openedImage.mid(protectedRanges[i].Offset, protectedRanges[i].Size); + + // Calculate the hash + UByteArray digest(SHA512_HASH_SIZE, '\x00'); + if (protectedRanges[i].AlgorithmId == TCG_HASH_ALGORITHM_ID_SHA1) { + sha1(protectedParts.constData(), protectedParts.size(), digest.data()); + digest = digest.left(SHA1_HASH_SIZE); + } + else if (protectedRanges[i].AlgorithmId == TCG_HASH_ALGORITHM_ID_SHA256) { + sha256(protectedParts.constData(), protectedParts.size(), digest.data()); + digest = digest.left(SHA256_HASH_SIZE); + } + else if (protectedRanges[i].AlgorithmId == TCG_HASH_ALGORITHM_ID_SHA384) { + sha384(protectedParts.constData(), protectedParts.size(), digest.data()); + digest = digest.left(SHA384_HASH_SIZE); + } + else if (protectedRanges[i].AlgorithmId == TCG_HASH_ALGORITHM_ID_SHA512) { + sha512(protectedParts.constData(), protectedParts.size(), digest.data()); + digest = digest.left(SHA512_HASH_SIZE); + } + else if (protectedRanges[i].AlgorithmId == TCG_HASH_ALGORITHM_ID_SM3) { + sm3(protectedParts.constData(), protectedParts.size(), digest.data()); + digest = digest.left(SM3_HASH_SIZE); + } + else { + msg(usprintf("%s: Microsoft PMDA protected range [%Xh:%Xh] uses unknown hash algorithm %04Xh", __FUNCTION__, + protectedRanges[i].Offset, protectedRanges[i].Offset + protectedRanges[i].Size, protectedRanges[i].AlgorithmId), + model->findByBase(protectedRanges[i].Offset)); + } + + // Check the hash + if (digest != protectedRanges[i].Hash) { + msg(usprintf("%s: Microsoft PMDA protected range [%Xh:%Xh] hash mismatch, opened image may refuse to boot", __FUNCTION__, + protectedRanges[i].Offset, protectedRanges[i].Offset + protectedRanges[i].Size), + model->findByBase(protectedRanges[i].Offset)); + } + + markProtectedRangeRecursive(index, protectedRanges[i]); + } + catch(...) { + // Do nothing, this range is likely not found in the image + } + } + else if (protectedRanges[i].Type == PROTECTED_RANGE_VENDOR_HASH_INSYDE) { + try { + protectedRanges[i].Offset -= (UINT32)addressDiff; + protectedParts = openedImage.mid(protectedRanges[i].Offset, protectedRanges[i].Size); + + UByteArray digest(SHA256_HASH_SIZE, '\x00'); + sha256(protectedParts.constData(), protectedParts.size(), digest.data()); + + if (digest != protectedRanges[i].Hash) { + msg(usprintf("%s: Insyde protected range [%Xh:%Xh] hash mismatch, opened image may refuse to boot", __FUNCTION__, + protectedRanges[i].Offset, protectedRanges[i].Offset + protectedRanges[i].Size), + model->findByBase(protectedRanges[i].Offset)); + } + + markProtectedRangeRecursive(index, protectedRanges[i]); + } + catch(...) { + // Do nothing, this range is likely not found in the image + } + } + } + + return U_SUCCESS; +} + +USTATUS FfsParser::markProtectedRangeRecursive(const UModelIndex & index, const PROTECTED_RANGE & range) +{ + if (!index.isValid()) + return U_SUCCESS; + + // Mark compressed items + UModelIndex parentIndex = model->parent(index); + if (parentIndex.isValid() && model->compressed(index) && model->compressed(parentIndex)) { + model->setMarking(index, model->marking(parentIndex)); + } + // Mark normal items + else { + UINT32 currentOffset = model->base(index); + UINT32 currentSize = (UINT32)(model->header(index).size() + model->body(index).size() + model->tail(index).size()); + + if (std::min(currentOffset + currentSize, range.Offset + range.Size) > std::max(currentOffset, range.Offset)) { + if (range.Offset <= currentOffset && currentOffset + currentSize <= range.Offset + range.Size) { // Mark as fully in range + if (range.Type == PROTECTED_RANGE_INTEL_BOOT_GUARD_IBB) { + model->setMarking(index, BootGuardMarking::BootGuardFullyInRange); + } + else { + model->setMarking(index, BootGuardMarking::VendorFullyInRange); + } + } + else { // Mark as partially in range + model->setMarking(index, BootGuardMarking::PartiallyInRange); + } + } + } + + for (int i = 0; i < model->rowCount(index); i++) { + markProtectedRangeRecursive(index.model()->index(i, 0, index), range); + } + + return U_SUCCESS; +} + +USTATUS FfsParser::parseVendorHashFile(const UByteArray & fileGuid, const UModelIndex & index) +{ + // Check sanity + if (!index.isValid()) { + return U_INVALID_PARAMETER; + } + + const UByteArray& body = model->body(index); + UINT32 size = (UINT32)body.size(); + if (fileGuid == PROTECTED_RANGE_VENDOR_HASH_FILE_GUID_PHOENIX) { + if (size < sizeof(PROTECTED_RANGE_VENDOR_HASH_FILE_HEADER_PHOENIX)) { + msg(usprintf("%s: unknown or corrupted Phoenix protected ranges hash file", __FUNCTION__), index); + } + else { + const PROTECTED_RANGE_VENDOR_HASH_FILE_HEADER_PHOENIX* header = (const PROTECTED_RANGE_VENDOR_HASH_FILE_HEADER_PHOENIX*)body.constData(); + if (header->Signature == BG_VENDOR_HASH_FILE_SIGNATURE_PHOENIX) { + if (size < sizeof(PROTECTED_RANGE_VENDOR_HASH_FILE_HEADER_PHOENIX) + header->NumEntries * sizeof(PROTECTED_RANGE_VENDOR_HASH_FILE_ENTRY)) { + msg(usprintf("%s: unknown or corrupted Phoenix protected ranges hash file", __FUNCTION__), index); + } + else { + if (header->NumEntries > 0) { + bool protectedRangesFound = false; + for (UINT32 i = 0; i < header->NumEntries; i++) { + const PROTECTED_RANGE_VENDOR_HASH_FILE_ENTRY* entry = (const PROTECTED_RANGE_VENDOR_HASH_FILE_ENTRY*)(header + 1) + i; + if (entry->Base != 0xFFFFFFFF && entry->Size != 0 && entry->Size != 0xFFFFFFFF) { + protectedRangesFound = true; + PROTECTED_RANGE range = {}; + range.Offset = entry->Base; + range.Size = entry->Size; + range.AlgorithmId = TCG_HASH_ALGORITHM_ID_SHA256; + range.Hash = UByteArray((const char*)entry->Hash, sizeof(entry->Hash)); + range.Type = PROTECTED_RANGE_VENDOR_HASH_PHOENIX; + protectedRanges.push_back(range); + } + } + + if (protectedRangesFound) { + securityInfo += usprintf("Phoenix hash file found at base %08Xh\nProtected ranges:\n", model->base(index)); + for (UINT32 i = 0; i < header->NumEntries; i++) { + const PROTECTED_RANGE_VENDOR_HASH_FILE_ENTRY* entry = (const PROTECTED_RANGE_VENDOR_HASH_FILE_ENTRY*)(header + 1) + i; + securityInfo += usprintf("RelativeOffset: %08Xh Size: %Xh\nHash: ", entry->Base, entry->Size); + for (UINT8 j = 0; j < sizeof(entry->Hash); j++) { + securityInfo += usprintf("%02X", entry->Hash[j]); + } + securityInfo += "\n"; + } } } } + } + } - // Show message if imageBaseType is still unknown - if (pdata.section.teImage.imageBase != 0 && pdata.section.teImage.imageBaseType == EFI_IMAGE_TE_BASE_OTHER) - msg(UString("addMemoryAddressesRecursive: TE image base is neither zero, nor original, nor adjusted, nor top-swapped"), index); + model->setText(index, UString("Phoenix protected ranges hash file")); + } + else if (fileGuid == PROTECTED_RANGE_VENDOR_HASH_FILE_GUID_AMI) { + UModelIndex fileIndex = model->parent(index); + if (size == sizeof(PROTECTED_RANGE_VENDOR_HASH_FILE_HEADER_AMI_V1)) { + securityInfo += usprintf("AMI protected ranges hash file v1 found at base %08Xh\nProtected range:\n", model->base(fileIndex)); + const PROTECTED_RANGE_VENDOR_HASH_FILE_HEADER_AMI_V1* entry = (const PROTECTED_RANGE_VENDOR_HASH_FILE_HEADER_AMI_V1*)(body.constData()); + securityInfo += usprintf("Size: %Xh\nHash (SHA256): ", entry->Size); + for (UINT8 i = 0; i < sizeof(entry->Hash); i++) { + securityInfo += usprintf("%02X", entry->Hash[i]); + } + securityInfo += "\n"; + + if (entry->Size != 0 && entry->Size != 0xFFFFFFFF) { + PROTECTED_RANGE range = {}; + range.Offset = 0; + range.Size = entry->Size; + range.AlgorithmId = TCG_HASH_ALGORITHM_ID_SHA256; + range.Hash = UByteArray((const char*)entry->Hash, sizeof(entry->Hash)); + range.Type = PROTECTED_RANGE_VENDOR_HASH_AMI_V1; + protectedRanges.push_back(range); } - // Set modified parsing data - model->setParsingData(index, parsingDataToUByteArray(pdata)); + model->setText(fileIndex, UString("AMI v1 protected ranges hash file")); + } + else if (size == sizeof(PROTECTED_RANGE_VENDOR_HASH_FILE_HEADER_AMI_V2)) { + const PROTECTED_RANGE_VENDOR_HASH_FILE_HEADER_AMI_V2* entry = (const PROTECTED_RANGE_VENDOR_HASH_FILE_HEADER_AMI_V2*)(body.constData()); + + securityInfo += usprintf("AMI v2 protected ranges hash file found at base %08Xh\nProtected ranges:", model->base(fileIndex)); + securityInfo += usprintf("\nAddress: %08Xh, Size: %Xh\nHash (SHA256): ", entry->Hash0.Base, entry->Hash0.Size); + for (UINT8 j = 0; j < sizeof(entry->Hash0.Hash); j++) { + securityInfo += usprintf("%02X", entry->Hash0.Hash[j]); + } + securityInfo += usprintf("\nAddress: %08Xh, Size: %Xh\nHash (SHA256): ", entry->Hash1.Base, entry->Hash1.Size); + for (UINT8 j = 0; j < sizeof(entry->Hash1.Hash); j++) { + securityInfo += usprintf("%02X", entry->Hash1.Hash[j]); + } + securityInfo += "\n"; + + if (entry->Hash0.Base != 0xFFFFFFFF && entry->Hash0.Size != 0 && entry->Hash0.Size != 0xFFFFFFFF) { + PROTECTED_RANGE range = {}; + range.Offset = entry->Hash0.Base; + range.Size = entry->Hash0.Size; + range.AlgorithmId = TCG_HASH_ALGORITHM_ID_SHA256; + range.Hash = UByteArray((const char*)entry->Hash0.Hash, sizeof(entry->Hash0.Hash)); + range.Type = PROTECTED_RANGE_VENDOR_HASH_AMI_V2; + protectedRanges.push_back(range); + } + + if (entry->Hash1.Base != 0xFFFFFFFF && entry->Hash1.Size != 0 && entry->Hash1.Size != 0xFFFFFFFF) { + PROTECTED_RANGE range = {}; + range.Offset = entry->Hash1.Base; + range.Size = entry->Hash1.Size; + range.AlgorithmId = TCG_HASH_ALGORITHM_ID_SHA256; + range.Hash = UByteArray((const char*)entry->Hash1.Hash, sizeof(entry->Hash1.Hash)); + range.Type = PROTECTED_RANGE_VENDOR_HASH_AMI_V2; + protectedRanges.push_back(range); + } + + model->setText(fileIndex, UString("AMI v2 protected ranges hash file")); + } + else if (size == sizeof(PROTECTED_RANGE_VENDOR_HASH_FILE_HEADER_AMI_V3)) { + const PROTECTED_RANGE_VENDOR_HASH_FILE_HEADER_AMI_V3* entry = (const PROTECTED_RANGE_VENDOR_HASH_FILE_HEADER_AMI_V3*)(body.constData()); + securityInfo += usprintf("AMI v3 protected ranges hash file found at base %08Xh\nProtected ranges:", model->base(fileIndex)); + securityInfo += usprintf("\nFvBaseSegment 0 Address: %08Xh, Size: %Xh", entry->FvMainSegmentBase[0], entry->FvMainSegmentSize[0]); + securityInfo += usprintf("\nFvBaseSegment 1 Address: %08Xh, Size: %Xh", entry->FvMainSegmentBase[1], entry->FvMainSegmentSize[1]); + securityInfo += usprintf("\nFvBaseSegment 2 Address: %08Xh, Size: %Xh", entry->FvMainSegmentBase[2], entry->FvMainSegmentSize[2]); + securityInfo += usprintf("\nNestedFvBase Address: %08Xh, Size: %Xh", entry->NestedFvBase, entry->NestedFvSize); + securityInfo += usprintf("\nHash (SHA256): "); + for (UINT8 j = 0; j < sizeof(entry->Hash); j++) { + securityInfo += usprintf("%02X", entry->Hash[j]); + } + securityInfo += "\n"; + + if (entry->FvMainSegmentBase[0] != 0xFFFFFFFF && entry->FvMainSegmentSize[0] != 0 && entry->FvMainSegmentSize[0] != 0xFFFFFFFF) { + PROTECTED_RANGE range = {}; + range.Offset = entry->FvMainSegmentBase[0]; + range.Size = entry->FvMainSegmentSize[0]; + range.AlgorithmId = TCG_HASH_ALGORITHM_ID_SHA256; + range.Hash = UByteArray((const char*)entry->Hash, sizeof(entry->Hash)); + range.Type = PROTECTED_RANGE_VENDOR_HASH_AMI_V3; + protectedRanges.push_back(range); + } + + if (entry->FvMainSegmentBase[1] != 0xFFFFFFFF && entry->FvMainSegmentSize[1] != 0 && entry->FvMainSegmentSize[1] != 0xFFFFFFFF) { + PROTECTED_RANGE range = {}; + range.Offset = entry->FvMainSegmentBase[1]; + range.Size = entry->FvMainSegmentSize[1]; + range.AlgorithmId = TCG_HASH_ALGORITHM_ID_SHA256; + range.Hash = UByteArray((const char*)entry->Hash, sizeof(entry->Hash)); + range.Type = PROTECTED_RANGE_VENDOR_HASH_AMI_V3; + protectedRanges.push_back(range); + } + + if (entry->FvMainSegmentBase[2] != 0xFFFFFFFF && entry->FvMainSegmentSize[2] != 0 && entry->FvMainSegmentSize[2] != 0xFFFFFFFF) { + PROTECTED_RANGE range = {}; + range.Offset = entry->FvMainSegmentBase[2]; + range.Size = entry->FvMainSegmentSize[2]; + range.AlgorithmId = TCG_HASH_ALGORITHM_ID_SHA256; + range.Hash = UByteArray((const char*)entry->Hash, sizeof(entry->Hash)); + range.Type = PROTECTED_RANGE_VENDOR_HASH_AMI_V3; + protectedRanges.push_back(range); + } + + if (entry->NestedFvBase != 0xFFFFFFFF && entry->NestedFvSize != 0 && entry->NestedFvSize != 0xFFFFFFFF) { + PROTECTED_RANGE range = {}; + range.Offset = entry->NestedFvBase; + range.Size = entry->NestedFvSize; + range.AlgorithmId = TCG_HASH_ALGORITHM_ID_SHA256; + range.Hash = UByteArray((const char*)entry->Hash, sizeof(entry->Hash)); + range.Type = PROTECTED_RANGE_VENDOR_HASH_AMI_V3; + protectedRanges.push_back(range); + } + + model->setText(fileIndex, UString("AMI v3 protected ranges hash file")); + } + else { + msg(usprintf("%s: unknown or corrupted AMI protected ranges hash file", __FUNCTION__), fileIndex); } } - // Process child items - for (int i = 0; i < model->rowCount(index); i++) { - addMemoryAddressesRecursive(index.child(i, 0), diff); - } - return U_SUCCESS; } -USTATUS FfsParser::addOffsetsRecursive(const UModelIndex & index) +USTATUS FfsParser::parseMicrocodeVolumeBody(const UModelIndex & index) { - // Sanity check - if (!index.isValid()) - return U_INVALID_PARAMETER; - - // Get parsing data for the current item - PARSING_DATA pdata = parsingDataFromUModelIndex(index); - - // Add current offset if the element is not compressed - // or it's compressed, but it's parent isn't - if ((!model->compressed(index)) || (index.parent().isValid() && !model->compressed(index.parent()))) { - model->addInfo(index, usprintf("Offset: %Xh\n", pdata.offset), false); - } - - // Process child items - for (int i = 0; i < model->rowCount(index); i++) { - addOffsetsRecursive(index.child(i, 0)); - } - - return U_SUCCESS; -} - -USTATUS FfsParser::parseNvarStore(const UModelIndex & index) -{ - // Sanity check - if (!index.isValid()) - return U_INVALID_PARAMETER; - - // Get parsing data for the current item - PARSING_DATA pdata = parsingDataFromUModelIndex(index); - UINT32 parentOffset = pdata.offset + model->header(index).size(); - - // Get item data - const UByteArray data = model->body(index); - - // Rename parent file - model->setText(model->findParentOfType(index, Types::File), UString("NVAR store")); - + const UINT32 headerSize = (UINT32)model->header(index).size(); + const UINT32 bodySize = (UINT32)model->body(index).size(); UINT32 offset = 0; - UINT32 guidsInStore = 0; - const UINT8 emptyByte = pdata.emptyByte; - // Parse all entries - while (1) { - bool msgUnknownExtDataFormat = false; - bool msgExtHeaderTooLong = false; - bool msgExtDataTooShort = false; - - bool isInvalid = false; - bool isInvalidLink = false; - //bool isDataOnly = false; - bool hasExtendedHeader = false; - bool hasChecksum = false; - bool hasTimestamp = false; - bool hasHash = false; - bool hasGuidIndex = false; - - UINT32 guidIndex = 0; - UINT8 storedChecksum = 0; - UINT8 calculatedChecksum = 0; - UINT32 extendedHeaderSize = 0; - UINT8 extendedAttributes = 0; - UINT64 timestamp = 0; - UByteArray hash; - - UINT8 subtype = Subtypes::FullNvarEntry; - UString name; - UString text; - UByteArray header; - UByteArray body; - UByteArray tail; + USTATUS result = U_SUCCESS; + + while(true) { + // Parse current microcode + UModelIndex currentMicrocode; + UByteArray ucode = model->body(index).mid(offset); - UINT32 guidAreaSize = guidsInStore * sizeof(EFI_GUID); - UINT32 unparsedSize = (UINT32)data.size() - offset - guidAreaSize; - - // Get entry header - const NVAR_ENTRY_HEADER* entryHeader = (const NVAR_ENTRY_HEADER*)(data.constData() + offset); + // Check for empty area + if (ucode.size() == ucode.count('\xFF') || ucode.size() == ucode.count('\x00')) { + result = U_INVALID_MICROCODE; + } + else { + result = parseIntelMicrocodeHeader(ucode, headerSize + offset, index, currentMicrocode); + } - // Check header size and signature - if (unparsedSize < sizeof(NVAR_ENTRY_HEADER) || - entryHeader->Signature != NVRAM_NVAR_ENTRY_SIGNATURE || - unparsedSize < entryHeader->Size) { - - // Check if the data left is a free space or a padding - UByteArray padding = data.mid(offset, unparsedSize); - UINT8 type; - - if ((UINT32)padding.count(emptyByte) == unparsedSize) { - // It's a free space - name = ("Free space"); - type = Types::FreeSpace; - subtype = 0; + // Add the rest as padding + if (result) { + if (offset < bodySize) { + // Get info + UString name = UString("Padding"); + UString info = usprintf("Full size: %Xh (%u)", (UINT32)ucode.size(), (UINT32)ucode.size()); + + // Add tree item + model->addItem(headerSize + offset, Types::Padding, getPaddingType(ucode), name, UString(), info, UByteArray(), ucode, UByteArray(), Fixed, index); } - else { - // Nothing is parsed yet, but the file is not empty - if (!offset) { - msg(UString("parseNvarStore: file can't be parsed as NVAR variables store"), index); - return U_SUCCESS; - } - - // It's a padding - name = UString("Padding"); - type = Types::Padding; - subtype = getPaddingType(padding); - } - // Get info - UString info = usprintf("Full size: %Xh (%u)", padding.size(), padding.size()); - // Construct parsing data - pdata.offset = parentOffset + offset; - // Add tree item - model->addItem(type, subtype, name, UString(), info, UByteArray(), padding, UByteArray(), false, parsingDataToUByteArray(pdata), index); - - // Add GUID store area - UByteArray guidArea = data.right(guidAreaSize); - // Get info - name = UString("GUID store area"); - info = usprintf("Full size: %Xh (%u)\nGUIDs in store: %u", - guidArea.size(), guidArea.size(), - guidsInStore); - // Construct parsing data - pdata.offset = parentOffset + offset + padding.size(); - // Add tree item - model->addItem(Types::Padding, getPaddingType(guidArea), name, UString(), info, UByteArray(), guidArea, UByteArray(), false, parsingDataToUByteArray(pdata), index); - return U_SUCCESS; } - // Contruct generic header and body - header = data.mid(offset, sizeof(NVAR_ENTRY_HEADER)); - body = data.mid(offset + sizeof(NVAR_ENTRY_HEADER), entryHeader->Size - sizeof(NVAR_ENTRY_HEADER)); - - UINT32 lastVariableFlag = pdata.emptyByte ? 0xFFFFFF : 0; - - // Set default next to predefined last value - pdata.nvar.next = lastVariableFlag; - - // Entry is marked as invalid - if ((entryHeader->Attributes & NVRAM_NVAR_ENTRY_VALID) == 0) { // Valid attribute is not set - isInvalid = true; - // Do not parse further - goto parsing_done; - } - - // Add next node information to parsing data - if (entryHeader->Next != lastVariableFlag) { - subtype = Subtypes::LinkNvarEntry; - pdata.nvar.next = entryHeader->Next; - } - - // Entry with extended header - if (entryHeader->Attributes & NVRAM_NVAR_ENTRY_EXT_HEADER) { - hasExtendedHeader = true; - msgUnknownExtDataFormat = true; - - extendedHeaderSize = *(UINT16*)(body.constData() + body.size() - sizeof(UINT16)); - if (extendedHeaderSize > (UINT32)body.size()) { - msgExtHeaderTooLong = true; - isInvalid = true; - // Do not parse further - goto parsing_done; - } - - extendedAttributes = *(UINT8*)(body.constData() + body.size() - extendedHeaderSize); - - // Variable with checksum - if (extendedAttributes & NVRAM_NVAR_ENTRY_EXT_CHECKSUM) { - // Get stored checksum - storedChecksum = *(UINT8*)(body.constData() + body.size() - sizeof(UINT16) - sizeof(UINT8)); - - // Recalculate checksum for the variable - calculatedChecksum = 0; - // Include entry data - UINT8* start = (UINT8*)(entryHeader + 1); - for (UINT8* p = start; p < start + entryHeader->Size - sizeof(NVAR_ENTRY_HEADER); p++) { - calculatedChecksum += *p; - } - // Include entry size and flags - start = (UINT8*)&entryHeader->Size; - for (UINT8*p = start; p < start + sizeof(UINT16); p++) { - calculatedChecksum += *p; - } - // Include entry attributes - calculatedChecksum += entryHeader->Attributes; - - hasChecksum = true; - msgUnknownExtDataFormat = false; - } - - tail = body.mid(body.size() - extendedHeaderSize); - body = body.left(body.size() - extendedHeaderSize); - - // Entry with authenticated write (for SecureBoot) - if (entryHeader->Attributes & NVRAM_NVAR_ENTRY_AUTH_WRITE) { - if ((entryHeader->Attributes & NVRAM_NVAR_ENTRY_DATA_ONLY)) {// Data only auth. variables has no hash - if ((UINT32)tail.size() < sizeof(UINT64)) { - msgExtDataTooShort = true; - isInvalid = true; - // Do not parse further - goto parsing_done; - } - - timestamp = *(UINT64*)(tail.constData() + sizeof(UINT8)); - hasTimestamp = true; - msgUnknownExtDataFormat = false; - } - else { // Full or link variable have hash - if ((UINT32)tail.size() < sizeof(UINT64) + SHA256_HASH_SIZE) { - msgExtDataTooShort = true; - isInvalid = true; - // Do not parse further - goto parsing_done; - } - - timestamp = *(UINT64*)(tail.constData() + sizeof(UINT8)); - hash = tail.mid(sizeof(UINT64) + sizeof(UINT8), SHA256_HASH_SIZE); - hasTimestamp = true; - hasHash = true; - msgUnknownExtDataFormat = false; - } - } - } - - // Entry is data-only (nameless and GUIDless entry or link) - if (entryHeader->Attributes & NVRAM_NVAR_ENTRY_DATA_ONLY) { // Data-only attribute is set - isInvalidLink = true; - UModelIndex nvarIndex; - // Search prevously added entries for a link to this variable - for (int i = 0; i < model->rowCount(index); i++) { - nvarIndex = index.child(i, 0); - PARSING_DATA nvarPdata = parsingDataFromUModelIndex(nvarIndex); - if (nvarPdata.nvar.isValid && nvarPdata.nvar.next + nvarPdata.offset - parentOffset == offset) { // Previous link is present and valid - isInvalidLink = false; - break; - } - } - // Check if the link is valid - if (!isInvalidLink) { - // Use the name and text of the previous link - name = model->name(nvarIndex); - text = model->text(nvarIndex); - - if (entryHeader->Next == lastVariableFlag) - subtype = Subtypes::DataNvarEntry; - } - - //isDataOnly = true; - // Do not parse further - goto parsing_done; - } - - // Get entry name - { - UINT32 nameOffset = (entryHeader->Attributes & NVRAM_NVAR_ENTRY_GUID) ? sizeof(EFI_GUID) : sizeof(UINT8); // GUID can be stored with the variable or in a separate store, so there will only be an index of it - CHAR8* namePtr = (CHAR8*)(entryHeader + 1) + nameOffset; - UINT32 nameSize = 0; - if (entryHeader->Attributes & NVRAM_NVAR_ENTRY_ASCII_NAME) { // Name is stored as ASCII string of CHAR8s - text = UString(namePtr); - nameSize = text.length() + 1; - } - else { // Name is stored as UCS2 string of CHAR16s - text = UString::fromUtf16((CHAR16*)namePtr); - nameSize = (text.length() + 1) * 2; - } - - // Get entry GUID - if (entryHeader->Attributes & NVRAM_NVAR_ENTRY_GUID) { // GUID is strored in the variable itself - name = guidToUString(*(EFI_GUID*)(entryHeader + 1)); - } - // GUID is stored in GUID list at the end of the store - else { - guidIndex = *(UINT8*)(entryHeader + 1); - if (guidsInStore < guidIndex + 1) - guidsInStore = guidIndex + 1; - - // The list begins at the end of the store and goes backwards - const EFI_GUID* guidPtr = (const EFI_GUID*)(data.constData() + data.size()) - 1 - guidIndex; - name = guidToUString(*guidPtr); - hasGuidIndex = true; - } - - // Include name and GUID into the header and remove them from body - header = data.mid(offset, sizeof(NVAR_ENTRY_HEADER) + nameOffset + nameSize); - body = body.mid(nameOffset + nameSize); - } -parsing_done: - UString info; - - // Rename invalid entries according to their types - pdata.nvar.isValid = TRUE; - if (isInvalid) { - name = UString("Invalid"); - subtype = Subtypes::InvalidNvarEntry; - pdata.nvar.isValid = FALSE; - } - else if (isInvalidLink) { - name = UString("Invalid link"); - subtype = Subtypes::InvalidLinkNvarEntry; - pdata.nvar.isValid = FALSE; - } - else // Add GUID info for valid entries - info += UString("Variable GUID: ") + name + UString("\n"); - - // Add GUID index information - if (hasGuidIndex) - info += usprintf("GUID index: %u\n", guidIndex); - - // Add header, body and extended data info - info += usprintf("Full size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)", - entryHeader->Size, entryHeader->Size, - header.size(), header.size(), - body.size(), body.size()); - - // Add attributes info - info += usprintf("\nAttributes: %02Xh", entryHeader->Attributes); - // Translate attributes to text - if (entryHeader->Attributes && entryHeader->Attributes != 0xFF) - info += UString(" (") + nvarAttributesToUString(entryHeader->Attributes) + UString(")"); - - // Add next node info - if (!isInvalid && entryHeader->Next != lastVariableFlag) - info += usprintf("\nNext node at offset: %Xh", parentOffset + offset + entryHeader->Next); - - // Add extended header info - if (hasExtendedHeader) { - info += usprintf("\nExtended header size: %Xh (%u)\nExtended attributes: %Xh (", - extendedHeaderSize, extendedHeaderSize, - extendedAttributes) + nvarExtendedAttributesToUString(extendedAttributes) + UString(")"); - - // Add checksum - if (hasChecksum) - info += usprintf("\nChecksum: %02Xh", storedChecksum) + - (calculatedChecksum ? usprintf(", invalid, should be %02Xh", 0x100 - calculatedChecksum) : UString(", valid")); - - // Add timestamp - if (hasTimestamp) - info += usprintf("\nTimestamp: %" PRIX64 "h", timestamp); - - // Add hash - if (hasHash) - info += UString("\nHash: ") + UString(hash.toHex().constData()); - } - - // Add correct offset to parsing data - pdata.offset = parentOffset + offset; - - // Add tree item - UModelIndex varIndex = model->addItem(Types::NvarEntry, subtype, name, text, info, header, body, tail, false, parsingDataToUByteArray(pdata), index); - - // Show messages - if (msgUnknownExtDataFormat) msg(UString("parseNvarStore: unknown extended data format"), varIndex); - if (msgExtHeaderTooLong) msg(usprintf("parseNvarStore: extended header size (%Xh) is greater than body size (%Xh)", - extendedHeaderSize, body.size()), varIndex); - if (msgExtDataTooShort) msg(usprintf("parseNvarStore: extended header size (%Xh) is too small for timestamp and hash", - tail.size()), varIndex); - - // Try parsing the entry data as NVAR storage if it begins with NVAR signature - if ((subtype == Subtypes::DataNvarEntry || subtype == Subtypes::FullNvarEntry) - && *(const UINT32*)body.constData() == NVRAM_NVAR_ENTRY_SIGNATURE) - parseNvarStore(varIndex); - - // Move to next exntry - offset += entryHeader->Size; + // Get to next candidate + offset += model->header(currentMicrocode).size() + model->body(currentMicrocode).size() + model->tail(currentMicrocode).size(); + if (offset >= bodySize) + break; } - return U_SUCCESS; } -USTATUS FfsParser::parseNvramVolumeBody(const UModelIndex & index) +USTATUS FfsParser::parseIntelMicrocodeHeader(const UByteArray & microcode, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index) { - // Sanity check - if (!index.isValid()) - return U_INVALID_PARAMETER; - - // Get parsing data - PARSING_DATA pdata = parsingDataFromUModelIndex(index); - UINT32 parentOffset = pdata.offset + model->header(index).size(); - - // Get item data - UByteArray data = model->body(index); - - // Search for first store - USTATUS result; - UINT32 prevStoreOffset; - result = findNextStore(index, data, parentOffset, 0, prevStoreOffset); - if (result) - return result; - - // First store is not at the beginning of volume body - UString name; - UString info; - if (prevStoreOffset > 0) { - // Get info - UByteArray padding = data.left(prevStoreOffset); - name = UString("Padding"); - info = usprintf("Full size: %Xh (%u)", padding.size(), padding.size()); - - // Construct parsing data - pdata.offset = parentOffset; - - // Add tree item - model->addItem(Types::Padding, getPaddingType(padding), name, UString(), info, UByteArray(), padding, UByteArray(), true, parsingDataToUByteArray(pdata), index); + // We have enough data to fit the header + if ((UINT32)microcode.size() < sizeof(INTEL_MICROCODE_HEADER)) { + return U_INVALID_MICROCODE; } - - // Search for and parse all stores - UINT32 storeOffset = prevStoreOffset; - UINT32 prevStoreSize = 0; - - while (!result) - { - // Padding between stores - if (storeOffset > prevStoreOffset + prevStoreSize) { - UINT32 paddingOffset = prevStoreOffset + prevStoreSize; - UINT32 paddingSize = storeOffset - paddingOffset; - UByteArray padding = data.mid(paddingOffset, paddingSize); - - // Get info - name = UString("Padding"); - info = usprintf("Full size: %Xh (%u)", padding.size(), padding.size()); - - // Construct parsing data - pdata.offset = parentOffset + paddingOffset; - - // Add tree item - model->addItem(Types::Padding, getPaddingType(padding), name, UString(), info, UByteArray(), padding, UByteArray(), true, parsingDataToUByteArray(pdata), index); - } - - // Get store size - UINT32 storeSize = 0; - result = getStoreSize(data, storeOffset, storeSize); - if (result) { - msg(UString("parseNvramVolumeBody: getStoreSize failed with error ") + errorCodeToUString(result), index); - return result; - } - - // Check that current store is fully present in input - if (storeSize > (UINT32)data.size() || storeOffset + storeSize > (UINT32)data.size()) { - // Mark the rest as padding and finish parsing - UByteArray padding = data.mid(storeOffset); - - // Get info - name = UString("Padding"); - info = usprintf("Full size: %Xh (%u)", padding.size(), padding.size()); - - // Construct parsing data - pdata.offset = parentOffset + storeOffset; - - // Add tree item - UModelIndex paddingIndex = model->addItem(Types::Padding, getPaddingType(padding), name, UString(), info, UByteArray(), padding, UByteArray(), true, parsingDataToUByteArray(pdata), index); - msg(UString("parseNvramVolumeBody: one of stores inside overlaps the end of data"), paddingIndex); - - // Update variables - prevStoreOffset = storeOffset; - prevStoreSize = padding.size(); - break; - } - - UByteArray store = data.mid(storeOffset, storeSize); - // Parse current store header - UModelIndex storeIndex; - result = parseStoreHeader(store, parentOffset + storeOffset, index, storeIndex); - if (result) - msg(UString("parseNvramVolumeBody: store header parsing failed with error ") + errorCodeToUString(result), index); - - // Go to next store - prevStoreOffset = storeOffset; - prevStoreSize = storeSize; - result = findNextStore(index, data, parentOffset, storeOffset + prevStoreSize, storeOffset); + + const INTEL_MICROCODE_HEADER* ucodeHeader = (const INTEL_MICROCODE_HEADER*)microcode.constData(); + + if (!microcodeHeaderValid(ucodeHeader)) { + return U_INVALID_MICROCODE; } - - // Padding/free space at the end - storeOffset = prevStoreOffset + prevStoreSize; - if ((UINT32)data.size() > storeOffset) { - UByteArray padding = data.mid(storeOffset); - UINT8 type; - UINT8 subtype; - if (padding.count(pdata.emptyByte) == padding.size()) { - // It's a free space - name = UString("Free space"); - type = Types::FreeSpace; - subtype = 0; + + // We have enough data to fit the whole TotalSize + if ((UINT32)microcode.size() < ucodeHeader->TotalSize) { + return U_INVALID_MICROCODE; + } + + // Valid microcode found + UINT32 dataSize = ucodeHeader->DataSize; + if (dataSize == 0) { + dataSize = INTEL_MICROCODE_REAL_DATA_SIZE_ON_ZERO; + } + + // Cross check DataSize and TotalSize + if (ucodeHeader->TotalSize < sizeof(INTEL_MICROCODE_HEADER) + dataSize) { + return U_INVALID_MICROCODE; + } + + // Recalculate the whole microcode checksum + UByteArray tempMicrocode = microcode; + INTEL_MICROCODE_HEADER* tempUcodeHeader = (INTEL_MICROCODE_HEADER*)(tempMicrocode.data()); + tempUcodeHeader->Checksum = 0; + UINT32 calculated = calculateChecksum32((const UINT32*)tempMicrocode.constData(), tempUcodeHeader->TotalSize); + bool msgInvalidChecksum = (ucodeHeader->Checksum != calculated); + + // Construct header, body and tail + UByteArray header = microcode.left(sizeof(INTEL_MICROCODE_HEADER)); + UByteArray body = microcode.mid(sizeof(INTEL_MICROCODE_HEADER), dataSize); + UByteArray tail; + + // Check if the tail is present + if (ucodeHeader->TotalSize > sizeof(INTEL_MICROCODE_HEADER) + dataSize) { + tail = microcode.mid(sizeof(INTEL_MICROCODE_HEADER) + dataSize, ucodeHeader->TotalSize - (sizeof(INTEL_MICROCODE_HEADER) + dataSize)); + } + + // Check if we have extended header in the tail + UString extendedHeaderInfo; + bool msgUnknownOrDamagedMicrocodeTail = false; + if ((UINT32)tail.size() >= sizeof(INTEL_MICROCODE_EXTENDED_HEADER)) { + const INTEL_MICROCODE_EXTENDED_HEADER* extendedHeader = (const INTEL_MICROCODE_EXTENDED_HEADER*)tail.constData(); + + // Reserved bytes are all zeroes + bool extendedReservedBytesValid = true; + for (UINT8 i = 0; i < sizeof(extendedHeader->Reserved); i++) { + if (extendedHeader->Reserved[i] != 0x00) { + extendedReservedBytesValid = false; + break; + } + } + + // We have more than 0 entries and they are all in the tail + if (extendedReservedBytesValid + && extendedHeader->EntryCount > 0 + && (UINT32)tail.size() == sizeof(INTEL_MICROCODE_EXTENDED_HEADER) + extendedHeader->EntryCount * sizeof(INTEL_MICROCODE_EXTENDED_HEADER_ENTRY)) { + // Recalculate extended header checksum + INTEL_MICROCODE_EXTENDED_HEADER* tempExtendedHeader = (INTEL_MICROCODE_EXTENDED_HEADER*)(tempMicrocode.data() + sizeof(INTEL_MICROCODE_HEADER) + dataSize); + tempExtendedHeader->Checksum = 0; + UINT32 extendedCalculated = calculateChecksum32((const UINT32*)tempExtendedHeader, sizeof(INTEL_MICROCODE_EXTENDED_HEADER) + extendedHeader->EntryCount * sizeof(INTEL_MICROCODE_EXTENDED_HEADER_ENTRY)); + + extendedHeaderInfo = usprintf("\nExtended header entries: %u\nExtended header checksum: %08Xh, ", + extendedHeader->EntryCount, + extendedHeader->Checksum) + + (extendedHeader->Checksum == extendedCalculated ? UString("valid") : usprintf("invalid, should be %08Xh", extendedCalculated)); + + const INTEL_MICROCODE_EXTENDED_HEADER_ENTRY* firstEntry = (const INTEL_MICROCODE_EXTENDED_HEADER_ENTRY*)(extendedHeader + 1); + for (UINT32 i = 0; i < extendedHeader->EntryCount; i++) { + const INTEL_MICROCODE_EXTENDED_HEADER_ENTRY* entry = (const INTEL_MICROCODE_EXTENDED_HEADER_ENTRY*)(firstEntry + i); + + // Recalculate checksum after patching + tempUcodeHeader->Checksum = 0; + tempUcodeHeader->PlatformIds = entry->PlatformIds; + tempUcodeHeader->ProcessorSignature = entry->ProcessorSignature; + UINT32 entryCalculated = calculateChecksum32((const UINT32*)tempMicrocode.constData(), sizeof(INTEL_MICROCODE_HEADER) + dataSize); + + extendedHeaderInfo += usprintf("\nCPU signature #%u: %08Xh\nCPU platform Id #%u: %08Xh\nChecksum #%u: %08Xh, ", + i + 1, entry->ProcessorSignature, + i + 1, entry->PlatformIds, + i + 1, entry->Checksum) + + (entry->Checksum == entryCalculated ? UString("valid") : usprintf("invalid, should be %08Xh", entryCalculated)); + } } else { - // Nothing is parsed yet, but the file is not empty - if (!storeOffset) { - msg(UString("parseNvramVolumeBody: can't be parsed as NVRAM volume"), index); - return U_SUCCESS; - } - - // It's a padding - name = UString("Padding"); - type = Types::Padding; - subtype = getPaddingType(padding); + msgUnknownOrDamagedMicrocodeTail = true; } - - // Add info - info = usprintf("Full size: %Xh (%u)", padding.size(), padding.size()); - - // Construct parsing data - pdata.offset = parentOffset + storeOffset; - - // Add tree item - model->addItem(type, subtype, name, UString(), info, UByteArray(), padding, UByteArray(), true, parsingDataToUByteArray(pdata), index); } - - // Parse bodies - for (int i = 0; i < model->rowCount(index); i++) { - UModelIndex current = index.child(i, 0); - switch (model->type(current)) { - case Types::VssStore: - case Types::FdcStore: parseVssStoreBody(current); break; - case Types::FsysStore: parseFsysStoreBody(current); break; - case Types::EvsaStore: parseEvsaStoreBody(current); break; - case Types::FlashMapStore: parseFlashMapBody(current); break; - } + else if (tail.size() != 0) { + msgUnknownOrDamagedMicrocodeTail = true; } - return U_SUCCESS; -} - -USTATUS FfsParser::findNextStore(const UModelIndex & index, const UByteArray & volume, const UINT32 parentOffset, const UINT32 storeOffset, UINT32 & nextStoreOffset) -{ - UINT32 dataSize = volume.size(); - - if (dataSize < sizeof(UINT32)) - return U_STORES_NOT_FOUND; - - UINT32 offset = storeOffset; - for (; offset < dataSize - sizeof(UINT32); offset++) { - const UINT32* currentPos = (const UINT32*)(volume.constData() + offset); - if (*currentPos == NVRAM_VSS_STORE_SIGNATURE || *currentPos == NVRAM_APPLE_SVS_STORE_SIGNATURE) { //$VSS or $SVS signatures found, perform checks - const VSS_VARIABLE_STORE_HEADER* vssHeader = (const VSS_VARIABLE_STORE_HEADER*)currentPos; - if (vssHeader->Format != NVRAM_VSS_VARIABLE_STORE_FORMATTED) { - msg(usprintf("findNextStore: VSS store candidate at offset %Xh skipped, has invalid format %02Xh", parentOffset + offset, vssHeader->Format), index); - continue; - } - if (vssHeader->Size == 0 || vssHeader->Size == 0xFFFFFFFF) { - msg(usprintf("findNextStore: VSS store candidate at offset %Xh skipped, has invalid size %Xh", parentOffset + offset, vssHeader->Size), index); - continue; - } - // All checks passed, store found - break; - } - else if (*currentPos == NVRAM_FDC_VOLUME_SIGNATURE) { //FDC signature found - const FDC_VOLUME_HEADER* fdcHeader = (const FDC_VOLUME_HEADER*)currentPos; - if (fdcHeader->Size == 0 || fdcHeader->Size == 0xFFFFFFFF) { - msg(usprintf("findNextStore: FDC store candidate at offset %Xh skipped, has invalid size %Xh", parentOffset + offset, fdcHeader->Size), index); - continue; - } - // All checks passed, store found - break; - } - else if (*currentPos == NVRAM_APPLE_FSYS_STORE_SIGNATURE || *currentPos == NVRAM_APPLE_GAID_STORE_SIGNATURE) { //Fsys or Gaid signature found - const APPLE_FSYS_STORE_HEADER* fsysHeader = (const APPLE_FSYS_STORE_HEADER*)currentPos; - if (fsysHeader->Size == 0 || fsysHeader->Size == 0xFFFF) { - msg(usprintf("findNextStore: Fsys store candidate at offset %Xh skipped, has invalid size %Xh", parentOffset + offset, fsysHeader->Size), index); - continue; - } - // All checks passed, store found - break; - } - else if (*currentPos == NVRAM_EVSA_STORE_SIGNATURE) { //EVSA signature found - if (offset < sizeof(UINT32)) - continue; - - const EVSA_STORE_ENTRY* evsaHeader = (const EVSA_STORE_ENTRY*)(currentPos - 1); - if (evsaHeader->Header.Type != NVRAM_EVSA_ENTRY_TYPE_STORE) { - msg(usprintf("findNextStore: EVSA store candidate at offset %Xh skipped, has invalid type %02Xh", parentOffset + offset - 4, evsaHeader->Header.Type), index); - continue; - } - if (evsaHeader->StoreSize == 0 || evsaHeader->StoreSize == 0xFFFFFFFF) { - msg(usprintf("findNextStore: EVSA store candidate at offset %Xh skipped, has invalid size %Xh", parentOffset + offset, evsaHeader->StoreSize), index); - continue; - } - // All checks passed, store found - offset -= sizeof(UINT32); - break; - } - else if (*currentPos == NVRAM_MAIN_STORE_VOLUME_GUID_DATA1 || *currentPos == EDKII_WORKING_BLOCK_SIGNATURE_GUID_DATA1) { //Possible FTW block signature found - UByteArray guid = UByteArray(volume.constData() + offset, sizeof(EFI_GUID)); - if (guid != NVRAM_MAIN_STORE_VOLUME_GUID && guid != EDKII_WORKING_BLOCK_SIGNATURE_GUID) // Check the whole signature - continue; - - // Detect header variant based on WriteQueueSize - const EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER32* ftwHeader = (const EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER32*)currentPos; - if (ftwHeader->WriteQueueSize % 0x10 == 0x04) { // Header with 32 bit WriteQueueSize - if (ftwHeader->WriteQueueSize == 0 || ftwHeader->WriteQueueSize == 0xFFFFFFFF) { - msg(usprintf("findNextStore: FTW block candidate at offset %Xh skipped, has invalid body size %Xh", parentOffset + offset, ftwHeader->WriteQueueSize), index); - continue; - } - } - else if (ftwHeader->WriteQueueSize % 0x10 == 0x00) { // Header with 64 bit WriteQueueSize - const EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER64* ftw64Header = (const EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER64*)currentPos; - if (ftw64Header->WriteQueueSize == 0 || ftw64Header->WriteQueueSize >= 0xFFFFFFFF) { - msg(usprintf("findNextStore: FTW block candidate at offset %Xh skipped, has invalid body size %Xh", parentOffset + offset, ftw64Header->WriteQueueSize), index); - continue; - } - } - else // Unknown header - continue; - - // All checks passed, store found - break; - } - else if (*currentPos == NVRAM_PHOENIX_FLASH_MAP_SIGNATURE_PART1) {// Phoenix SCT flash map - UByteArray signature = UByteArray(volume.constData() + offset, NVRAM_PHOENIX_FLASH_MAP_SIGNATURE_LENGTH); - if (signature != NVRAM_PHOENIX_FLASH_MAP_SIGNATURE) // Check the whole signature - continue; - - // All checks passed, store found - break; - } - else if (*currentPos == NVRAM_PHOENIX_CMDB_HEADER_SIGNATURE) { // Phoenix SCT CMDB store - const PHOENIX_CMDB_HEADER* cmdbHeader = (const PHOENIX_CMDB_HEADER*)currentPos; - - // Check size - if (cmdbHeader->HeaderSize != sizeof(PHOENIX_CMDB_HEADER)) - continue; - - // All checks passed, store found - break; - } - else if (*currentPos == INTEL_MICROCODE_HEADER_VERSION) {// Intel microcode - if (!INTEL_MICROCODE_HEADER_SIZES_VALID(currentPos)) // Check header sizes - continue; - - // Check reserved bytes - const INTEL_MICROCODE_HEADER* ucodeHeader = (const INTEL_MICROCODE_HEADER*)currentPos; - bool reservedBytesValid = true; - for (UINT32 i = 0; i < sizeof(ucodeHeader->Reserved); i++) - if (ucodeHeader->Reserved[i] != INTEL_MICROCODE_HEADER_RESERVED_BYTE) { - reservedBytesValid = false; - break; - } - if (!reservedBytesValid) - continue; - - // All checks passed, store found - break; - } - else if (*currentPos == OEM_ACTIVATION_PUBKEY_MAGIC) { // SLIC pubkey - if (offset < 4 * sizeof(UINT32)) - continue; - - const OEM_ACTIVATION_PUBKEY* pubkeyHeader = (const OEM_ACTIVATION_PUBKEY*)(currentPos - 4); - // Check type - if (pubkeyHeader->Type != OEM_ACTIVATION_PUBKEY_TYPE) - continue; - - // All checks passed, store found - offset -= 4 * sizeof(UINT32); - break; - } - else if (*currentPos == OEM_ACTIVATION_MARKER_WINDOWS_FLAG_PART1) { // SLIC marker - if (offset >= dataSize - sizeof(UINT64) || - *(const UINT64*)currentPos != OEM_ACTIVATION_MARKER_WINDOWS_FLAG || - offset < 26) // Check full windows flag and structure size - continue; - - const OEM_ACTIVATION_MARKER* markerHeader = (const OEM_ACTIVATION_MARKER*)(volume.constData() + offset - 26); - // Check reserved bytes - bool reservedBytesValid = true; - for (UINT32 i = 0; i < sizeof(markerHeader->Reserved); i++) - if (markerHeader->Reserved[i] != OEM_ACTIVATION_MARKER_RESERVED_BYTE) { - reservedBytesValid = false; - break; - } - if (!reservedBytesValid) - continue; - - // All checks passed, store found - offset -= 26; - break; - } - } - // No more stores found - if (offset >= dataSize - sizeof(UINT32)) - return U_STORES_NOT_FOUND; - - nextStoreOffset = offset; - - return U_SUCCESS; -} - -USTATUS FfsParser::getStoreSize(const UByteArray & data, const UINT32 storeOffset, UINT32 & storeSize) -{ - const UINT32* signature = (const UINT32*)(data.constData() + storeOffset); - if (*signature == NVRAM_VSS_STORE_SIGNATURE || *signature == NVRAM_APPLE_SVS_STORE_SIGNATURE) { - const VSS_VARIABLE_STORE_HEADER* vssHeader = (const VSS_VARIABLE_STORE_HEADER*)signature; - storeSize = vssHeader->Size; - } - else if (*signature == NVRAM_FDC_VOLUME_SIGNATURE) { - const FDC_VOLUME_HEADER* fdcHeader = (const FDC_VOLUME_HEADER*)signature; - storeSize = fdcHeader->Size; - } - else if (*signature == NVRAM_APPLE_FSYS_STORE_SIGNATURE || *signature == NVRAM_APPLE_GAID_STORE_SIGNATURE) { - const APPLE_FSYS_STORE_HEADER* fsysHeader = (const APPLE_FSYS_STORE_HEADER*)signature; - storeSize = fsysHeader->Size; - } - else if (*(signature + 1) == NVRAM_EVSA_STORE_SIGNATURE) { - const EVSA_STORE_ENTRY* evsaHeader = (const EVSA_STORE_ENTRY*)signature; - storeSize = evsaHeader->StoreSize; - } - else if (*signature == NVRAM_MAIN_STORE_VOLUME_GUID_DATA1 || *signature == EDKII_WORKING_BLOCK_SIGNATURE_GUID_DATA1) { - const EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER32* ftwHeader = (const EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER32*)signature; - if (ftwHeader->WriteQueueSize % 0x10 == 0x04) { // Header with 32 bit WriteQueueSize - storeSize = sizeof(EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER32) + ftwHeader->WriteQueueSize; - } - else { // Header with 64 bit WriteQueueSize - const EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER64* ftw64Header = (const EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER64*)signature; - storeSize = sizeof(EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER64) + (UINT32)ftw64Header->WriteQueueSize; - } - } - else if (*signature == NVRAM_PHOENIX_FLASH_MAP_SIGNATURE_PART1) { // Phoenix SCT flash map - const PHOENIX_FLASH_MAP_HEADER* flashMapHeader = (const PHOENIX_FLASH_MAP_HEADER*)signature; - storeSize = sizeof(PHOENIX_FLASH_MAP_HEADER) + sizeof(PHOENIX_FLASH_MAP_ENTRY) * flashMapHeader->NumEntries; - } - else if (*signature == NVRAM_PHOENIX_CMDB_HEADER_SIGNATURE) { // Phoenix SCT CMDB store - storeSize = NVRAM_PHOENIX_CMDB_SIZE; // It's a predefined max size, no need to calculate - } - else if (*(signature + 4) == OEM_ACTIVATION_PUBKEY_MAGIC) { // SLIC pubkey - const OEM_ACTIVATION_PUBKEY* pubkeyHeader = (const OEM_ACTIVATION_PUBKEY*)signature; - storeSize = pubkeyHeader->Size; - } - else if (*(const UINT64*)(data.constData() + storeOffset + 26) == OEM_ACTIVATION_MARKER_WINDOWS_FLAG) { // SLIC marker - const OEM_ACTIVATION_MARKER* markerHeader = (const OEM_ACTIVATION_MARKER*)signature; - storeSize = markerHeader->Size; - } - else if (*signature == INTEL_MICROCODE_HEADER_VERSION) { // Intel microcode, must be checked after SLIC marker because of the same *signature values - const INTEL_MICROCODE_HEADER* ucodeHeader = (const INTEL_MICROCODE_HEADER*)signature; - storeSize = ucodeHeader->TotalSize; - } - return U_SUCCESS; -} - -USTATUS FfsParser::parseVssStoreHeader(const UByteArray & store, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index) -{ - const UINT32 dataSize = (const UINT32)store.size(); + // Get microcode binary + UByteArray microcodeBinary = microcode.left(ucodeHeader->TotalSize); - // Check store size - if (dataSize < sizeof(VSS_VARIABLE_STORE_HEADER)) { - msg(UString("parseVssStoreHeader: volume body is too small even for VSS store header"), parent); - return U_SUCCESS; - } - - // Get VSS store header - const VSS_VARIABLE_STORE_HEADER* vssStoreHeader = (const VSS_VARIABLE_STORE_HEADER*)store.constData(); - - // Check store size - if (dataSize < vssStoreHeader->Size) { - msg(usprintf("parseVssStoreHeader: VSS store size %Xh (%u) is greater than volume body size %Xh (%u)", - vssStoreHeader->Size, vssStoreHeader->Size, - dataSize, dataSize), parent); - return U_SUCCESS; - } - - // Get parsing data - PARSING_DATA pdata = parsingDataFromUModelIndex(parent); - - // Construct header and body - UByteArray header = store.left(sizeof(VSS_VARIABLE_STORE_HEADER)); - UByteArray body = store.mid(sizeof(VSS_VARIABLE_STORE_HEADER), vssStoreHeader->Size - sizeof(VSS_VARIABLE_STORE_HEADER)); - - // Add info - bool isSvsStore = (vssStoreHeader->Signature == NVRAM_APPLE_SVS_STORE_SIGNATURE); - UString name = isSvsStore ? UString("SVS store") : UString("VSS store"); - UString info = usprintf("Signature: %s\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nFormat: %02Xh\nState: %02Xh\nUnknown: %04Xh", - isSvsStore ? "$SVS" : "$VSS", - vssStoreHeader->Size, vssStoreHeader->Size, - header.size(), header.size(), - body.size(), body.size(), - vssStoreHeader->Format, - vssStoreHeader->State, - vssStoreHeader->Unknown); - - // Add correct offset - pdata.offset = parentOffset; - - // Add tree item - index = model->addItem(Types::VssStore, 0, name, UString(), info, header, body, UByteArray(), true, parsingDataToUByteArray(pdata), parent); - - return U_SUCCESS; -} - -USTATUS FfsParser::parseFtwStoreHeader(const UByteArray & store, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index) -{ - const UINT32 dataSize = (const UINT32)store.size(); - - // Check store size - if (dataSize < sizeof(EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER64)) { - msg(UString("parseFtwStoreHeader: volume body is too small even for FTW store header"), parent); - return U_SUCCESS; - } - - // Get FTW block headers - const EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER32* ftw32BlockHeader = (const EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER32*)store.constData(); - const EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER64* ftw64BlockHeader = (const EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER64*)store.constData(); - - // Check store size - UINT32 ftwBlockSize; - bool has32bitHeader; - if (ftw32BlockHeader->WriteQueueSize % 0x10 == 0x04) { // Header with 32 bit WriteQueueSize - ftwBlockSize = sizeof(EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER32) + ftw32BlockHeader->WriteQueueSize; - has32bitHeader = true; - } - else { // Header with 64 bit WriteQueueSize - ftwBlockSize = sizeof(EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER64) + (UINT32)ftw64BlockHeader->WriteQueueSize; - has32bitHeader = false; - } - if (dataSize < ftwBlockSize) { - msg(usprintf("parseFtwStoreHeader: FTW store size %Xh (%u) is greater than volume body size %Xh (%u)", - ftwBlockSize, ftwBlockSize, - dataSize, dataSize), parent); - return U_SUCCESS; - } - - // Get parsing data - PARSING_DATA pdata = parsingDataFromUModelIndex(parent); - - // Construct header and body - UINT32 headerSize = has32bitHeader ? sizeof(EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER32) : sizeof(EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER64); - UByteArray header = store.left(headerSize); - UByteArray body = store.mid(headerSize, ftwBlockSize - headerSize); - - // Check block header checksum - UByteArray crcHeader = header; - EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER32* crcFtwBlockHeader = (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER32*)header.data(); - crcFtwBlockHeader->Crc = pdata.emptyByte ? 0xFFFFFFFF : 0; - crcFtwBlockHeader->State = pdata.emptyByte ? 0xFF : 0; - UINT32 calculatedCrc = crc32(0, (const UINT8*)crcFtwBlockHeader, headerSize); - - // Add info - UString name("FTW store"); - UString info = UString("Signature: ") + guidToUString(ftw32BlockHeader->Signature) + - usprintf("\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nState: %02Xh\nHeader CRC32: %08Xh", - ftwBlockSize, ftwBlockSize, - headerSize, headerSize, - body.size(), body.size(), - ftw32BlockHeader->State, - ftw32BlockHeader->Crc) + - (ftw32BlockHeader->Crc != calculatedCrc ? usprintf(", invalid, should be %08Xh", calculatedCrc) : UString(", valid")); - - // Add correct offset - pdata.offset = parentOffset; - - // Add tree item - index = model->addItem(Types::FtwStore, 0, name, UString(), info, header, body, UByteArray(), true, parsingDataToUByteArray(pdata), parent); - - return U_SUCCESS; -} - -USTATUS FfsParser::parseFdcStoreHeader(const UByteArray & store, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index) -{ - const UINT32 dataSize = (const UINT32)store.size(); - - // Check store size - if (dataSize < sizeof(FDC_VOLUME_HEADER)) { - msg(UString("parseFdcStoreHeader: volume body is too small even for FDC store header"), parent); - return U_SUCCESS; - } - - // Get Fdc store header - const FDC_VOLUME_HEADER* fdcStoreHeader = (const FDC_VOLUME_HEADER*)store.constData(); - - // Check store size - if (dataSize < fdcStoreHeader->Size) { - msg(usprintf("parseFdcStoreHeader: FDC store size %Xh (%u) is greater than volume body size %Xh (%u)", - fdcStoreHeader->Size, fdcStoreHeader->Size, - dataSize, dataSize), parent); - return U_SUCCESS; - } - - // Determine internal volume header size - const EFI_FIRMWARE_VOLUME_HEADER* volumeHeader = (const EFI_FIRMWARE_VOLUME_HEADER*)(fdcStoreHeader + 1); - UINT32 headerSize; - if (volumeHeader->Revision > 1 && volumeHeader->ExtHeaderOffset) { - const EFI_FIRMWARE_VOLUME_EXT_HEADER* extendedHeader = (const EFI_FIRMWARE_VOLUME_EXT_HEADER*)((const UINT8*)volumeHeader + volumeHeader->ExtHeaderOffset); - headerSize = volumeHeader->ExtHeaderOffset + extendedHeader->ExtHeaderSize; - } - else - headerSize = volumeHeader->HeaderLength; - - // Extended header end can be unaligned - headerSize = ALIGN8(headerSize); - - // Add VSS store header - headerSize += sizeof(VSS_VARIABLE_STORE_HEADER); - - // Add FDC header - headerSize += sizeof(FDC_VOLUME_HEADER); - - // Check sanity of combined header size - if (dataSize < headerSize) { - msg(usprintf("parseFdcStoreHeader: FDC store header size %Xh (%u) is greater than volume body size %Xh (%u)", - fdcStoreHeader->Size,fdcStoreHeader->Size, - dataSize, dataSize), parent); - return U_SUCCESS; - } - - // Get parsing data - PARSING_DATA pdata = parsingDataFromUModelIndex(parent); - - // Construct header and body - UByteArray header = store.left(headerSize); - UByteArray body = store.mid(headerSize, fdcStoreHeader->Size - headerSize); - - // Add info - UString name("FDC store"); - UString info = usprintf("Signature: _FDC\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)", - fdcStoreHeader->Size, fdcStoreHeader->Size, - header.size(), header.size(), - body.size(), body.size()); - - // TODO: add internal headers info - - // Add correct offset - pdata.offset = parentOffset; - - // Add tree item - index = model->addItem(Types::FdcStore, 0, name, UString(), info, header, body, UByteArray(), true, parsingDataToUByteArray(pdata), parent); - - return U_SUCCESS; -} - -USTATUS FfsParser::parseFsysStoreHeader(const UByteArray & store, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index) -{ - const UINT32 dataSize = (const UINT32)store.size(); - - // Check store size - if (dataSize < sizeof(APPLE_FSYS_STORE_HEADER)) { - msg(UString("parseFsysStoreHeader: volume body is too small even for Fsys store header"), parent); - return U_SUCCESS; - } - - // Get Fsys store header - const APPLE_FSYS_STORE_HEADER* fsysStoreHeader = (const APPLE_FSYS_STORE_HEADER*)store.constData(); - - // Check store size - if (dataSize < fsysStoreHeader->Size) { - msg(usprintf("parseFsysStoreHeader: Fsys store size %Xh (%u) is greater than volume body size %Xh (%u)", - fsysStoreHeader->Size, fsysStoreHeader->Size, - dataSize, dataSize), parent); - return U_SUCCESS; - } - - // Get parsing data - PARSING_DATA pdata = parsingDataFromUModelIndex(parent); - - // Construct header and body - UByteArray header = store.left(sizeof(APPLE_FSYS_STORE_HEADER)); - UByteArray body = store.mid(sizeof(APPLE_FSYS_STORE_HEADER), fsysStoreHeader->Size - sizeof(APPLE_FSYS_STORE_HEADER) - sizeof(UINT32)); - - // Check store checksum - UINT32 storedCrc = *(UINT32*)store.right(sizeof(UINT32)).constData(); - UINT32 calculatedCrc = crc32(0, (const UINT8*)store.constData(), (const UINT32)store.size() - sizeof(UINT32)); - - // Add info - bool isGaidStore = (fsysStoreHeader->Signature == NVRAM_APPLE_GAID_STORE_SIGNATURE); - UString name = isGaidStore ? UString("Gaid store") : UString("Fsys store"); - UString info = usprintf("Signature: %s\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nUnknown0: %02Xh\nUnknown1: %08Xh\nCRC32: %08Xh", - isGaidStore ? "Gaid" : "Fsys", - fsysStoreHeader->Size, fsysStoreHeader->Size, - header.size(), header.size(), - body.size(), body.size(), - fsysStoreHeader->Unknown0, - fsysStoreHeader->Unknown1) - + (storedCrc != calculatedCrc ? usprintf(", invalid, should be %08Xh", calculatedCrc) : UString(", valid")); - - // Add correct offset - pdata.offset = parentOffset; - - // Add tree item - index = model->addItem(Types::FsysStore, 0, name, UString(), info, header, body, UByteArray(), true, parsingDataToUByteArray(pdata), parent); - - return U_SUCCESS; -} - -USTATUS FfsParser::parseEvsaStoreHeader(const UByteArray & store, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index) -{ - const UINT32 dataSize = (const UINT32)store.size(); - - // Check dataSize - if (dataSize < sizeof(EVSA_STORE_ENTRY)) { - msg(UString("parseEvsaStoreHeader: volume body is too small even for EVSA store header"), parent); - return U_SUCCESS; - } - - // Get EVSA store header - const EVSA_STORE_ENTRY* evsaStoreHeader = (const EVSA_STORE_ENTRY*)store.constData(); - - // Check store size - if (dataSize < evsaStoreHeader->StoreSize) { - msg(usprintf("parseEvsaStoreHeader: EVSA store size %Xh (%u) is greater than volume body size %Xh (%u)", - evsaStoreHeader->StoreSize, evsaStoreHeader->StoreSize, - dataSize, dataSize), parent); - return U_SUCCESS; - } - - // Get parsing data - PARSING_DATA pdata = parsingDataFromUModelIndex(parent); - - // Construct header and body - UByteArray header = store.left(evsaStoreHeader->Header.Size); - UByteArray body = store.mid(evsaStoreHeader->Header.Size, evsaStoreHeader->StoreSize - evsaStoreHeader->Header.Size); - - // Recalculate checksum - UINT8 calculated = calculateChecksum8(((const UINT8*)evsaStoreHeader) + 2, evsaStoreHeader->Header.Size - 2); - - // Add info - UString name("EVSA store"); - UString info = usprintf("Signature: EVSA\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nType: %02Xh\nAttributes: %08Xh\nChecksum: %02Xh", - evsaStoreHeader->StoreSize, evsaStoreHeader->StoreSize, - header.size(), header.size(), - body.size(), body.size(), - evsaStoreHeader->Header.Type, - evsaStoreHeader->Attributes, - evsaStoreHeader->Header.Checksum) + - (evsaStoreHeader->Header.Checksum != calculated ? usprintf("%, invalid, should be %02Xh", calculated) : UString(", valid")); - - // Add correct offset - pdata.offset = parentOffset; - - // Add tree item - index = model->addItem(Types::EvsaStore, 0, name, UString(), info, header, body, UByteArray(), true, parsingDataToUByteArray(pdata), parent); - - return U_SUCCESS; -} - -USTATUS FfsParser::parseFlashMapStoreHeader(const UByteArray & store, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index) -{ - const UINT32 dataSize = (const UINT32)store.size(); - - // Check data size - if (dataSize < sizeof(PHOENIX_FLASH_MAP_HEADER)) { - msg(UString("parseFlashMapStoreHeader: volume body is too small even for FlashMap block header"), parent); - return U_SUCCESS; - } - - // Get FlashMap block header - const PHOENIX_FLASH_MAP_HEADER* flashMapHeader = (const PHOENIX_FLASH_MAP_HEADER*)store.constData(); - - // Check store size - UINT32 flashMapSize = sizeof(PHOENIX_FLASH_MAP_HEADER) + flashMapHeader->NumEntries * sizeof(PHOENIX_FLASH_MAP_ENTRY); - if (dataSize < flashMapSize) { - msg(usprintf("parseFlashMapStoreHeader: FlashMap block size %Xh (%u) is greater than volume body size %Xh (%u)", - flashMapSize, flashMapSize, - dataSize, dataSize), parent); - return U_SUCCESS; - } - - // Get parsing data - PARSING_DATA pdata = parsingDataFromUModelIndex(parent); - - // Construct header and body - UByteArray header = store.left(sizeof(PHOENIX_FLASH_MAP_HEADER)); - UByteArray body = store.mid(sizeof(PHOENIX_FLASH_MAP_HEADER), flashMapSize - sizeof(PHOENIX_FLASH_MAP_HEADER)); - - // Add info - UString name("Phoenix SCT flash map"); - UString info = usprintf("Signature: _FLASH_MAP\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nNumber of entries: %u", - flashMapSize, flashMapSize, - header.size(), header.size(), - body.size(), body.size(), - flashMapHeader->NumEntries); - - // Add correct offset - pdata.offset = parentOffset; - - // Add tree item - index = model->addItem(Types::FlashMapStore, 0, name, UString(), info, header, body, UByteArray(), true, parsingDataToUByteArray(pdata), parent); - - return U_SUCCESS; -} - -USTATUS FfsParser::parseCmdbStoreHeader(const UByteArray & store, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index) -{ - const UINT32 dataSize = (const UINT32)store.size(); - - // Check store size - if (dataSize < sizeof(PHOENIX_CMDB_HEADER)) { - msg(UString("parseCmdbStoreHeader: volume body is too small even for CMDB store header"), parent); - return U_SUCCESS; - } - - UINT32 cmdbSize = NVRAM_PHOENIX_CMDB_SIZE; - if (dataSize < cmdbSize) { - msg(usprintf("parseCmdbStoreHeader: CMDB store size %Xh (%u) is greater than volume body size %Xh (%u)", - cmdbSize, cmdbSize, - dataSize, dataSize), parent); - return U_SUCCESS; - } - - // Get store header - const PHOENIX_CMDB_HEADER* cmdbHeader = (const PHOENIX_CMDB_HEADER*)store.constData(); - - // Get parsing data - PARSING_DATA pdata = parsingDataFromUModelIndex(parent); - - // Construct header and body - UByteArray header = store.left(cmdbHeader->TotalSize); - UByteArray body = store.mid(cmdbHeader->TotalSize, cmdbSize - cmdbHeader->TotalSize); - - // Add info - UString name("CMDB store"); - UString info = usprintf("Signature: CMDB\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)", - cmdbSize, cmdbSize, - header.size(), header.size(), - body.size(), body.size()); - - // Add correct offset - pdata.offset = parentOffset; - - // Add tree item - index = model->addItem(Types::CmdbStore, 0, name, UString(), info, header, body, UByteArray(), true, parsingDataToUByteArray(pdata), parent); - - return U_SUCCESS; -} - -USTATUS FfsParser::parseSlicPubkeyHeader(const UByteArray & store, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index) -{ - const UINT32 dataSize = (const UINT32)store.size(); - - // Check data size - if (dataSize < sizeof(OEM_ACTIVATION_PUBKEY)) { - msg(UString("parseSlicPubkeyHeader: volume body is too small even for SLIC pubkey header"), parent); - return U_SUCCESS; - } - - // Get SLIC pubkey header - const OEM_ACTIVATION_PUBKEY* pubkeyHeader = (const OEM_ACTIVATION_PUBKEY*)store.constData(); - - // Check store size - if (dataSize < pubkeyHeader->Size) { - msg(usprintf("parseSlicPubkeyHeader: SLIC pubkey size %Xh (%u) is greater than volume body size %Xh (%u)", - pubkeyHeader->Size, pubkeyHeader->Size, - dataSize, dataSize), parent); - return U_SUCCESS; - } - - // Get parsing data - PARSING_DATA pdata = parsingDataFromUModelIndex(parent); - - // Construct header and body - UByteArray header = store.left(sizeof(OEM_ACTIVATION_PUBKEY)); - - // Add info - UString name("SLIC pubkey"); - UString info = usprintf("Type: 0h\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: 0h (0)\n" - "Key type: %02Xh\nVersion: %02Xh\nAlgorithm: %08Xh\nMagic: RSA1\nBit length: %08Xh\nExponent: %08Xh", - pubkeyHeader->Size, pubkeyHeader->Size, - header.size(), header.size(), - pubkeyHeader->KeyType, - pubkeyHeader->Version, - pubkeyHeader->Algorithm, - pubkeyHeader->BitLength, - pubkeyHeader->Exponent); - - // Add correct offset - pdata.offset = parentOffset; - - // Add tree item - index = model->addItem(Types::SlicData, Subtypes::PubkeySlicData, name, UString(), info, header, UByteArray(), UByteArray(), true, parsingDataToUByteArray(pdata), parent); - - return U_SUCCESS; -} - -USTATUS FfsParser::parseSlicMarkerHeader(const UByteArray & store, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index) -{ - const UINT32 dataSize = (const UINT32)store.size(); - - // Check data size - if (dataSize < sizeof(OEM_ACTIVATION_MARKER)) { - msg(UString("parseSlicMarkerHeader: volume body is too small even for SLIC marker header"), parent); - return U_SUCCESS; - } - - // Get SLIC marker header - const OEM_ACTIVATION_MARKER* markerHeader = (const OEM_ACTIVATION_MARKER*)store.constData(); - - // Check store size - if (dataSize < markerHeader->Size) { - msg(usprintf("parseSlicMarkerHeader: SLIC marker size %Xh (%u) is greater than volume body size %Xh (%u)", - markerHeader->Size, markerHeader->Size, - dataSize, dataSize), parent); - return U_SUCCESS; - } - - // Get parsing data - PARSING_DATA pdata = parsingDataFromUModelIndex(parent); - - // Construct header and body - UByteArray header = store.left(sizeof(OEM_ACTIVATION_MARKER)); - - // Add info - UString name("SLIC marker"); - UString info = usprintf("Type: 1h\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: 0h (0)\n" - "Version: %08Xh\nOEM ID: %s\nOEM table ID: %s\nWindows flag: WINDOWS\nSLIC version: %08Xh", - markerHeader->Size, markerHeader->Size, - header.size(), header.size(), - markerHeader->Version, - (const char*)UString((const char*)&(markerHeader->OemId)).left(6).toLocal8Bit(), - (const char*)UString((const char*)&(markerHeader->OemTableId)).left(8).toLocal8Bit(), - markerHeader->SlicVersion); - - // Add correct offset - pdata.offset = parentOffset; - - // Add tree item - index = model->addItem(Types::SlicData, Subtypes::MarkerSlicData, name, UString(), info, header, UByteArray(), UByteArray(), true, parsingDataToUByteArray(pdata), parent); - - return U_SUCCESS; -} - -USTATUS FfsParser::parseIntelMicrocodeHeader(const UByteArray & store, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index) -{ - const UINT32 dataSize = (const UINT32)store.size(); - - // Check data size - if (dataSize < sizeof(INTEL_MICROCODE_HEADER)) { - msg(UString("parseIntelMicrocodeHeader: volume body is too small even for Intel microcode header"), parent); - return U_SUCCESS; - } - - // Get Intel microcode header - const INTEL_MICROCODE_HEADER* ucodeHeader = (const INTEL_MICROCODE_HEADER*)store.constData(); - - // Check store size - if (dataSize < ucodeHeader->TotalSize) { - msg(usprintf("parseIntelMicrocodeHeader: Intel microcode size %Xh (%u) is greater than volume body size %Xh (%u)", - ucodeHeader->TotalSize, ucodeHeader->TotalSize, - dataSize, dataSize), parent); - return U_SUCCESS; - } - - // Get parsing data - PARSING_DATA pdata = parsingDataFromUModelIndex(parent); - - // Construct header and body - UByteArray header = store.left(sizeof(INTEL_MICROCODE_HEADER)); - UByteArray body = store.mid(sizeof(INTEL_MICROCODE_HEADER), ucodeHeader->DataSize); - - //TODO: recalculate checksum - // Add info UString name("Intel microcode"); - UString info = usprintf("Revision: 1h\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\n" - "Date: %08Xh\nCPU signature: %08Xh\nChecksum: %08Xh\nLoader revision: %08Xh\nCPU flags: %08Xh", - ucodeHeader->TotalSize, ucodeHeader->TotalSize, - header.size(), header.size(), - body.size(), body.size(), - ucodeHeader->Date, - ucodeHeader->CpuSignature, - ucodeHeader->Checksum, - ucodeHeader->LoaderRevision, - ucodeHeader->CpuFlags); - - // Add correct offset - pdata.offset = parentOffset; - + UString info = usprintf("Full size: %Xh (%u)\nHeader size: 0h (0u)\nBody size: %Xh (%u)\nTail size: 0h (0u)\n" + "Date: %02X.%02X.%04x\nCPU signature: %08Xh\nRevision: %08Xh\nMinimal update revision: %08Xh\nCPU platform Id: %08Xh\nChecksum: %08Xh, ", + (UINT32)microcodeBinary.size(), (UINT32)microcodeBinary.size(), + (UINT32)microcodeBinary.size(), (UINT32)microcodeBinary.size(), + ucodeHeader->DateDay, + ucodeHeader->DateMonth, + ucodeHeader->DateYear, + ucodeHeader->ProcessorSignature, + ucodeHeader->UpdateRevision, + ucodeHeader->UpdateRevisionMin, + ucodeHeader->PlatformIds, + ucodeHeader->Checksum) + + (ucodeHeader->Checksum == calculated ? UString("valid") : usprintf("invalid, should be %08Xh", calculated)) + + extendedHeaderInfo; + // Add tree item - index = model->addItem(Types::Microcode, Subtypes::IntelMicrocode, name, UString(), info, header, body, UByteArray(), true, parsingDataToUByteArray(pdata), parent); - + index = model->addItem(localOffset, Types::Microcode, Subtypes::IntelMicrocode, name, UString(), info, UByteArray(), microcodeBinary, UByteArray(), Fixed, parent); + if (msgInvalidChecksum) + msg(usprintf("%s: invalid microcode checksum %08Xh, should be %08Xh", __FUNCTION__, ucodeHeader->Checksum, calculated), index); + if (msgUnknownOrDamagedMicrocodeTail) + msg(usprintf("%s: extended header of size %Xh (%u) found, but it's damaged or has unknown format", __FUNCTION__, (UINT32)tail.size(), (UINT32)tail.size()), index); + + // No need to parse the body further for now return U_SUCCESS; } -USTATUS FfsParser::parseStoreHeader(const UByteArray & store, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index) +USTATUS FfsParser::parseBpdtRegion(const UByteArray & region, const UINT32 localOffset, const UINT32 sbpdtOffsetFixup, const UModelIndex & parent, UModelIndex & index) { - const UINT32 dataSize = (const UINT32)store.size(); - const UINT32* signature = (const UINT32*)store.constData(); - // Check store size - if (dataSize < sizeof(UINT32)) { - msg(UString("parseStoreHeader: volume body is too small even for store signature"), parent); - return U_SUCCESS; - } - - // Check signature and run parser function needed - // VSS/SVS store - if (*signature == NVRAM_VSS_STORE_SIGNATURE || *signature == NVRAM_APPLE_SVS_STORE_SIGNATURE) - return parseVssStoreHeader(store, parentOffset, parent, index); - // FTW store - else if (*signature == NVRAM_MAIN_STORE_VOLUME_GUID_DATA1 || *signature == EDKII_WORKING_BLOCK_SIGNATURE_GUID_DATA1) - return parseFtwStoreHeader(store, parentOffset, parent, index); - // FDC store - else if (*signature == NVRAM_FDC_VOLUME_SIGNATURE) - return parseFdcStoreHeader(store, parentOffset, parent, index); - // Apple Fsys/Gaid store - else if (*signature == NVRAM_APPLE_FSYS_STORE_SIGNATURE || *signature == NVRAM_APPLE_GAID_STORE_SIGNATURE) - return parseFsysStoreHeader(store, parentOffset, parent, index); - // EVSA store - else if (*(signature + 1) == NVRAM_EVSA_STORE_SIGNATURE) - return parseEvsaStoreHeader(store, parentOffset, parent, index); - // Phoenix SCT flash map - else if (*signature == NVRAM_PHOENIX_FLASH_MAP_SIGNATURE_PART1) - return parseFlashMapStoreHeader(store, parentOffset, parent, index); - // Phoenix CMDB store - else if (*signature == NVRAM_PHOENIX_CMDB_HEADER_SIGNATURE) - return parseCmdbStoreHeader(store, parentOffset, parent, index); - // SLIC pubkey - else if (*(signature + 4) == OEM_ACTIVATION_PUBKEY_MAGIC) - return parseSlicPubkeyHeader(store, parentOffset, parent, index); - // SLIC marker - else if (*(const UINT64*)(store.constData() + 26) == OEM_ACTIVATION_MARKER_WINDOWS_FLAG) - return parseSlicMarkerHeader(store, parentOffset, parent, index); - // Intel microcode - // Must be checked after SLIC marker because of the same *signature values - else if (*signature == INTEL_MICROCODE_HEADER_VERSION) - return parseIntelMicrocodeHeader(store, parentOffset, parent, index); - - msg(usprintf("parseStoreHeader: don't know how to parse a header with signature %08Xh", *signature), parent); - return U_SUCCESS; -} - -USTATUS FfsParser::parseVssStoreBody(const UModelIndex & index) -{ - // Sanity check - if (!index.isValid()) - return U_INVALID_PARAMETER; - - // Get parsing data for the current item - PARSING_DATA pdata = parsingDataFromUModelIndex(index); - UINT32 parentOffset = pdata.offset + model->header(index).size(); - const UByteArray data = model->body(index); - - // Check that the is enough space for variable header - const UINT32 dataSize = (UINT32)data.size(); - if (dataSize < sizeof(VSS_VARIABLE_HEADER)) { - msg(UString("parseVssStoreBody: store body is too small even for VSS variable header"), index); - return U_SUCCESS; + UINT32 regionSize = (UINT32)region.size(); + + // Check region size + if (regionSize < sizeof(BPDT_HEADER)) { + msg(usprintf("%s: BPDT region too small to fit BPDT partition table header", __FUNCTION__), parent); + return U_INVALID_ME_PARTITION_TABLE; } - UINT32 offset = 0; - - // Parse all variables - while (1) { - bool isInvalid = false; - bool isAuthenticated = false; - bool isAppleCrc32 = false; + // Populate partition table header + const BPDT_HEADER* ptHeader = (const BPDT_HEADER*)(region.constData()); + + // Check region size again + UINT32 ptBodySize = ptHeader->NumEntries * sizeof(BPDT_ENTRY); + UINT32 ptSize = sizeof(BPDT_HEADER) + ptBodySize; + if (regionSize < ptSize) { + msg(usprintf("%s: BPDT region too small to fit BPDT partition table", __FUNCTION__), parent); + return U_INVALID_ME_PARTITION_TABLE; + } + + // Get info + UByteArray header = region.left(sizeof(BPDT_HEADER)); + UByteArray body = region.mid(sizeof(BPDT_HEADER), ptBodySize); + + UString name = UString("BPDT partition table"); + UString info = usprintf("Full size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\n" + "Number of entries: %u\nVersion: %02Xh\nRedundancyFlag: %Xh\n" + "IFWI version: %Xh\nFITC version: %u.%u.%u.%u", + ptSize, ptSize, + (UINT32)header.size(), (UINT32)header.size(), + ptBodySize, ptBodySize, + ptHeader->NumEntries, + ptHeader->HeaderVersion, + ptHeader->RedundancyFlag, + ptHeader->IfwiVersion, + ptHeader->FitcMajor, ptHeader->FitcMinor, ptHeader->FitcHotfix, ptHeader->FitcBuild); + + // Add tree item + index = model->addItem(localOffset, Types::BpdtStore, 0, name, UString(), info, header, body, UByteArray(), Fixed, parent); + + // Adjust offset + UINT32 offset = sizeof(BPDT_HEADER); + + // Add partition table entries + std::vector partitions; + const BPDT_ENTRY* firstPtEntry = (const BPDT_ENTRY*)((const UINT8*)ptHeader + sizeof(BPDT_HEADER)); + UINT16 numEntries = ptHeader->NumEntries; + for (UINT16 i = 0; i < numEntries; i++) { + // Populate entry header + const BPDT_ENTRY* ptEntry = firstPtEntry + i; - UINT32 storedCrc32 = 0; - UINT32 calculatedCrc32 = 0; - UINT64 monotonicCounter = 0; - EFI_TIME timestamp = { 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - UINT32 pubKeyIndex = 0; - - UINT8 subtype = 0; - UString name; - UString text; - EFI_GUID* variableGuid; - CHAR16* variableName = (CHAR16*)L""; - UByteArray header; - UByteArray body; - - UINT32 unparsedSize = dataSize - offset; - - // Get variable header - const VSS_VARIABLE_HEADER* variableHeader = (const VSS_VARIABLE_HEADER*)(data.constData() + offset); - - // Check variable header to fit in still unparsed data - UINT32 variableSize = 0; - if (unparsedSize >= sizeof(VSS_VARIABLE_HEADER) - && variableHeader->StartId == NVRAM_VSS_VARIABLE_START_ID) { - - // Apple VSS variable with CRC32 of the data - if (variableHeader->Attributes & NVRAM_VSS_VARIABLE_APPLE_DATA_CHECKSUM) { - isAppleCrc32 = true; - if (unparsedSize < sizeof(VSS_APPLE_VARIABLE_HEADER)) { - variableSize = 0; - } - else { - const VSS_APPLE_VARIABLE_HEADER* appleVariableHeader = (const VSS_APPLE_VARIABLE_HEADER*)variableHeader; - variableSize = sizeof(VSS_APPLE_VARIABLE_HEADER) + appleVariableHeader->NameSize + appleVariableHeader->DataSize; - variableGuid = (EFI_GUID*)&appleVariableHeader->VendorGuid; - variableName = (CHAR16*)(appleVariableHeader + 1); - - header = data.mid(offset, sizeof(VSS_APPLE_VARIABLE_HEADER) + appleVariableHeader->NameSize); - body = data.mid(offset + header.size(), appleVariableHeader->DataSize); - - // Calculate CRC32 of the variable data - storedCrc32 = appleVariableHeader->DataCrc32; - calculatedCrc32 = crc32(0, (const UINT8*)body.constData(), body.size()); - } - } - - // Authenticated variable - else if ((variableHeader->Attributes & NVRAM_VSS_VARIABLE_AUTHENTICATED_WRITE_ACCESS) - || (variableHeader->Attributes & NVRAM_VSS_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) - || (variableHeader->Attributes & NVRAM_VSS_VARIABLE_APPEND_WRITE) - || (variableHeader->NameSize == 0 && variableHeader->DataSize == 0)) { // If both NameSize and DataSize are zeros, it's auth variable with zero montonic counter - isAuthenticated = true; - if (unparsedSize < sizeof(VSS_AUTH_VARIABLE_HEADER)) { - variableSize = 0; - } - else { - const VSS_AUTH_VARIABLE_HEADER* authVariableHeader = (const VSS_AUTH_VARIABLE_HEADER*)variableHeader; - variableSize = sizeof(VSS_AUTH_VARIABLE_HEADER) + authVariableHeader->NameSize + authVariableHeader->DataSize; - variableGuid = (EFI_GUID*)&authVariableHeader->VendorGuid; - variableName = (CHAR16*)(authVariableHeader + 1); - - header = data.mid(offset, sizeof(VSS_AUTH_VARIABLE_HEADER) + authVariableHeader->NameSize); - body = data.mid(offset + header.size(), authVariableHeader->DataSize); - - monotonicCounter = authVariableHeader->MonotonicCounter; - timestamp = authVariableHeader->Timestamp; - pubKeyIndex = authVariableHeader->PubKeyIndex; - } - } - - // Normal VSS variable - if (!isAuthenticated && !isAppleCrc32) { - variableSize = sizeof(VSS_VARIABLE_HEADER) + variableHeader->NameSize + variableHeader->DataSize; - variableGuid = (EFI_GUID*)&variableHeader->VendorGuid; - variableName = (CHAR16*)(variableHeader + 1); - - header = data.mid(offset, sizeof(VSS_VARIABLE_HEADER) + variableHeader->NameSize); - body = data.mid(offset + header.size(), variableHeader->DataSize); - } - - // There is also a case of authenticated Apple variables, but I haven't seen one yet - - // Check variable state - if (variableHeader->State != NVRAM_VSS_VARIABLE_ADDED && variableHeader->State != NVRAM_VSS_VARIABLE_HEADER_VALID) { - isInvalid = true; - } + // Get info + name = bpdtEntryTypeToUString(ptEntry->Type); + info = usprintf("Full size: %Xh (%u)\nType: %Xh\nPartition offset: %Xh\nPartition length: %Xh", + (UINT32)sizeof(BPDT_ENTRY), (UINT32)sizeof(BPDT_ENTRY), + ptEntry->Type, + ptEntry->Offset, + ptEntry->Size) + + UString("\nSplit sub-partition first part: ") + (ptEntry->SplitSubPartitionFirstPart ? "Yes" : "No") + + UString("\nSplit sub-partition second part: ") + (ptEntry->SplitSubPartitionSecondPart ? "Yes" : "No") + + UString("\nCode sub-partition: ") + (ptEntry->CodeSubPartition ? "Yes" : "No") + + UString("\nUMA cacheable: ") + (ptEntry->UmaCacheable ? "Yes" : "No"); + + // Add tree item + UModelIndex entryIndex = model->addItem(localOffset + offset, Types::BpdtEntry, 0, name, UString(), info, UByteArray(), UByteArray((const char*)ptEntry, sizeof(BPDT_ENTRY)), UByteArray(), Fixed, index); + + // Adjust offset + offset += sizeof(BPDT_ENTRY); + + if (ptEntry->Offset != 0 && ptEntry->Offset != 0xFFFFFFFF && ptEntry->Size != 0) { + // Add to partitions vector + BPDT_PARTITION_INFO partition = {}; + partition.type = Types::BpdtPartition; + partition.ptEntry = *ptEntry; + partition.ptEntry.Offset -= sbpdtOffsetFixup; + partition.index = entryIndex; + partitions.push_back(partition); } - - // Can't parse further, add the last element and break the loop - if (!variableSize) { - // Check if the data left is a free space or a padding - UByteArray padding = data.mid(offset, unparsedSize); - UINT8 type; - - if (padding.count(pdata.emptyByte) == padding.size()) { - // It's a free space - name = UString("Free space"); - type = Types::FreeSpace; - subtype = 0; + } + + // Check for empty set of partitions + if (partitions.empty()) { + // Add a single padding partition in this case + BPDT_PARTITION_INFO padding = {}; + padding.ptEntry.Offset = offset; + padding.ptEntry.Size = (UINT32)(region.size() - padding.ptEntry.Offset); + padding.type = Types::Padding; + partitions.push_back(padding); + } + +make_partition_table_consistent: + if (partitions.empty()) { + return U_INVALID_ME_PARTITION_TABLE; + } + // Sort partitions by offset + std::sort(partitions.begin(), partitions.end()); + + // Check for intersections and paddings between partitions + BPDT_PARTITION_INFO padding = {}; + + // Check intersection with the partition table header + if (partitions.front().ptEntry.Offset < ptSize) { + msg(usprintf("%s: BPDT partition has intersection with BPDT partition table, skipped", __FUNCTION__), + partitions.front().index); + partitions.erase(partitions.begin()); + goto make_partition_table_consistent; + } + // Check for padding between partition table and the first partition + else if (partitions.front().ptEntry.Offset > ptSize) { + padding.ptEntry.Offset = ptSize; + padding.ptEntry.Size = partitions.front().ptEntry.Offset - padding.ptEntry.Offset; + padding.type = Types::Padding; + partitions.insert(partitions.begin(), padding); + } + // Check for intersections/paddings between partitions + for (size_t i = 1; i < partitions.size(); i++) { + UINT32 previousPartitionEnd = partitions[i - 1].ptEntry.Offset + partitions[i - 1].ptEntry.Size; + + // Check that partition is fully present in the image + if ((UINT64)partitions[i].ptEntry.Offset + (UINT64)partitions[i].ptEntry.Size > regionSize) { + if ((UINT64)partitions[i].ptEntry.Offset >= (UINT64)region.size()) { + msg(usprintf("%s: BPDT partition is located outside of the opened image, skipped", __FUNCTION__), partitions[i].index); + partitions.erase(partitions.begin() + i); + goto make_partition_table_consistent; } else { - // Nothing is parsed yet, but the store is not empty - if (!offset) { - msg(UString("parseVssStoreBody: store can't be parsed as VSS store"), index); - return U_SUCCESS; - } - - // It's a padding - name = UString("Padding"); - type = Types::Padding; - subtype = getPaddingType(padding); + msg(usprintf("%s: BPDT partition can't fit into its region, truncated", __FUNCTION__), partitions[i].index); + partitions[i].ptEntry.Size = regionSize - (UINT32)partitions[i].ptEntry.Offset; } - + } + + // Check for intersection with previous partition + if (partitions[i].ptEntry.Offset < previousPartitionEnd) { + // Check if current partition is located inside previous one + if (partitions[i].ptEntry.Offset + partitions[i].ptEntry.Size <= previousPartitionEnd) { + msg(usprintf("%s: BPDT partition is located inside another BPDT partition, skipped", __FUNCTION__), + partitions[i].index); + partitions.erase(partitions.begin() + i); + goto make_partition_table_consistent; + } + else { + msg(usprintf("%s: BPDT partition intersects with previous one, skipped", __FUNCTION__), + partitions[i].index); + partitions.erase(partitions.begin() + i); + goto make_partition_table_consistent; + } + } + + // Check for padding between current and previous partitions + else if (partitions[i].ptEntry.Offset > previousPartitionEnd) { + padding.ptEntry.Offset = previousPartitionEnd; + padding.ptEntry.Size = partitions[i].ptEntry.Offset - previousPartitionEnd; + padding.type = Types::Padding; + std::vector::iterator iter = partitions.begin(); + std::advance(iter, i); + partitions.insert(iter, padding); + } + } + + // Partition map is consistent + for (size_t i = 0; i < partitions.size(); i++) { + if (partitions[i].type == Types::BpdtPartition) { // Get info - UString info = usprintf("Full size: %Xh (%u)", padding.size(), padding.size()); + UString name = bpdtEntryTypeToUString(partitions[i].ptEntry.Type); + UByteArray partition = region.mid(partitions[i].ptEntry.Offset, partitions[i].ptEntry.Size); + UByteArray signature = partition.left(sizeof(UINT32)); - // Construct parsing data - pdata.offset = parentOffset + offset; + UString info = usprintf("Full size: %Xh (%u)\nType: %Xh", + (UINT32)partition.size(), (UINT32)partition.size(), + partitions[i].ptEntry.Type) + + UString("\nSplit sub-partition first part: ") + (partitions[i].ptEntry.SplitSubPartitionFirstPart ? "Yes" : "No") + + UString("\nSplit sub-partition second part: ") + (partitions[i].ptEntry.SplitSubPartitionSecondPart ? "Yes" : "No") + + UString("\nCode sub-partition: ") + (partitions[i].ptEntry.CodeSubPartition ? "Yes" : "No") + + UString("\nUMA cacheable: ") + (partitions[i].ptEntry.UmaCacheable ? "Yes" : "No"); + + UString text = bpdtEntryTypeToUString(partitions[i].ptEntry.Type); // Add tree item - model->addItem(type, subtype, name, UString(), info, UByteArray(), padding, UByteArray(), false, parsingDataToUByteArray(pdata), index); - - return U_SUCCESS; - } - - UString info; - - // Rename invalid variables - if (isInvalid) { - name = UString("Invalid"); - } - else { // Add GUID and text for valid variables - name = guidToUString(*variableGuid); - info += UString("Variable GUID: ") + name + UString("\n"); - text = UString::fromUtf16(variableName); - } - - // Add info - info += usprintf("Full size: %Xh (%u)\nHeader size %Xh (%u)\nBody size: %Xh (%u)\nState: %02Xh\nAttributes: %08Xh (", - variableSize, variableSize, - header.size(), header.size(), - body.size(), body.size(), - variableHeader->State, - variableHeader->Attributes) + vssAttributesToUString(variableHeader->Attributes) + UString(")"); - - // Set subtype and add related info - if (isInvalid) - subtype = Subtypes::InvalidVssEntry; - else if (isAuthenticated) { - subtype = Subtypes::AuthVssEntry; - info += usprintf("\nMonotonic counter: %" PRIX64 "h\nTimestamp: ", monotonicCounter) + efiTimeToUString(timestamp) - + usprintf("\nPubKey index: %u", pubKeyIndex); - } - else if (isAppleCrc32) { - subtype = Subtypes::AppleVssEntry; - info += usprintf("\nData checksum: %08Xh", storedCrc32) + - (storedCrc32 != calculatedCrc32 ? usprintf(", invalid, should be %08Xh", calculatedCrc32) : UString(", valid")); - } - else - subtype = Subtypes::StandardVssEntry; - - // Add correct offset to parsing data - pdata.offset = parentOffset + offset; - - // Add tree item - model->addItem(Types::VssEntry, subtype, name, text, info, header, body, UByteArray(), false, parsingDataToUByteArray(pdata), index); - - // Move to next variable - offset += variableSize; - } - - return U_SUCCESS; -} - -USTATUS FfsParser::parseFsysStoreBody(const UModelIndex & index) -{ - // Sanity check - if (!index.isValid()) - return U_INVALID_PARAMETER; - - // Get parsing data for the current item - PARSING_DATA pdata = parsingDataFromUModelIndex(index); - UINT32 parentOffset = pdata.offset + model->header(index).size(); - const UByteArray data = model->body(index); - - // Check that the is enough space for variable header - const UINT32 dataSize = (UINT32)data.size(); - UINT32 offset = 0; - - // Parse all variables - while (1) { - UINT32 unparsedSize = dataSize - offset; - UINT32 variableSize = 0; - - // Get nameSize and name of the variable - const UINT8 nameSize = *(UINT8*)(data.constData() + offset); - // Check sanity - if (unparsedSize >= nameSize + sizeof(UINT8)) { - variableSize = nameSize + sizeof(UINT8); - } - - UByteArray name; - if (variableSize) { - name = data.mid(offset + sizeof(UINT8), nameSize); - // Check for EOF variable - if (nameSize == 3 && name[0] == 'E' && name[1] == 'O' && name[2] == 'F') { - // There is no data afterward, add EOF variable and free space and return - UByteArray header = data.mid(offset, sizeof(UINT8) + nameSize); - UString info = usprintf("Full size: %Xh (%u)", header.size(), header.size()); - - // Add correct offset to parsing data - pdata.offset = parentOffset + offset; - - // Add EOF tree item - model->addItem(Types::FsysEntry, 0, UString("EOF"), UString(), info, header, UByteArray(), UByteArray(), false, parsingDataToUByteArray(pdata), index); - - // Add free space - offset += header.size(); - unparsedSize = dataSize - offset; - UByteArray body = data.mid(offset); - info = usprintf("Full size: %Xh (%u)", body.size(), body.size()); - - // Add correct offset to parsing data - pdata.offset = parentOffset + offset; - - // Add free space tree item - model->addItem(Types::FreeSpace, 0, UString("Free space"), UString(), info, UByteArray(), body, UByteArray(), false, parsingDataToUByteArray(pdata), index); - - return U_SUCCESS; + UModelIndex partitionIndex = model->addItem(localOffset + partitions[i].ptEntry.Offset, Types::BpdtPartition, 0, name, text, info, UByteArray(), partition, UByteArray(), Fixed, parent); + + // Special case of S-BPDT + if (partitions[i].ptEntry.Type == BPDT_ENTRY_TYPE_S_BPDT) { + UModelIndex sbpdtIndex; + parseBpdtRegion(partition, 0, partitions[i].ptEntry.Offset, partitionIndex, sbpdtIndex); // Third parameter is a fixup for S-BPDT offset entries, because they are calculated from the start of BIOS region + } + + // Parse code partitions + if (readUnaligned((const UINT32*)partition.constData()) == CPD_SIGNATURE) { + // Parse code partition contents + UModelIndex cpdIndex; + parseCpdRegion(partition, 0, partitionIndex, cpdIndex); + } + + // Check for entry type to be known + if (partitions[i].ptEntry.Type > BPDT_ENTRY_TYPE_PSEP) { + msg(usprintf("%s: BPDT entry of unknown type found", __FUNCTION__), partitionIndex); } } - - // Get dataSize and data of the variable - const UINT16 dataSize = *(UINT16*)(data.constData() + offset + sizeof(UINT8) + nameSize); - if (unparsedSize >= sizeof(UINT8) + nameSize + sizeof(UINT16) + dataSize) { - variableSize = sizeof(UINT8) + nameSize + sizeof(UINT16) + dataSize; - } - else { - // Last variable is bad, add the rest as padding and return - UByteArray body = data.mid(offset); - UString info = usprintf("Full size: %Xh (%u)", body.size(), body.size()); - - // Add correct offset to parsing data - pdata.offset = parentOffset + offset; - - // Add free space tree item - model->addItem(Types::Padding, getPaddingType(body), UString("Padding"), UString(), info, UByteArray(), body, UByteArray(), false, parsingDataToUByteArray(pdata), index); + else if (partitions[i].type == Types::Padding) { + UByteArray padding = region.mid(partitions[i].ptEntry.Offset, partitions[i].ptEntry.Size); - // Show message - msg(UString("parseFsysStoreBody: next variable appears too big, added as padding"), index); - - return U_SUCCESS; + // Get info + name = UString("Padding"); + info = usprintf("Full size: %Xh (%u)", + (UINT32)padding.size(), (UINT32)padding.size()); + + // Add tree item + model->addItem(localOffset + partitions[i].ptEntry.Offset, Types::Padding, getPaddingType(padding), name, UString(), info, UByteArray(), padding, UByteArray(), Fixed, parent); } - - // Construct header and body - UByteArray header = data.mid(offset, sizeof(UINT8) + nameSize + sizeof(UINT16)); - UByteArray body = data.mid(offset + sizeof(UINT8) + nameSize + sizeof(UINT16), dataSize); - - // Add info - UString info = usprintf("Full size: %Xh (%u)\nHeader size %Xh (%u)\nBody size: %Xh (%u)", - variableSize, variableSize, - header.size(), header.size(), - body.size(), body.size()); - - // Add correct offset to parsing data - pdata.offset = parentOffset + offset; - + } + + // Add padding after the last region + if ((UINT64)partitions.back().ptEntry.Offset + (UINT64)partitions.back().ptEntry.Size < regionSize) { + UINT64 usedSize = (UINT64)partitions.back().ptEntry.Offset + (UINT64)partitions.back().ptEntry.Size; + UByteArray padding = region.mid(partitions.back().ptEntry.Offset + partitions.back().ptEntry.Size, (int)(regionSize - usedSize)); + + // Get info + name = UString("Padding"); + info = usprintf("Full size: %Xh (%u)", + (UINT32)padding.size(), (UINT32)padding.size()); + // Add tree item - model->addItem(Types::FsysEntry, 0, UString(name.constData()), UString(), info, header, body, UByteArray(), false, parsingDataToUByteArray(pdata), index); - - // Move to next variable - offset += variableSize; + model->addItem(localOffset + partitions.back().ptEntry.Offset + partitions.back().ptEntry.Size, Types::Padding, getPaddingType(padding), name, UString(), info, UByteArray(), padding, UByteArray(), Fixed, parent); } return U_SUCCESS; } -USTATUS FfsParser::parseEvsaStoreBody(const UModelIndex & index) +USTATUS FfsParser::parseCpdRegion(const UByteArray & region, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index) { - // Sanity check - if (!index.isValid()) - return U_INVALID_PARAMETER; - - // Get parsing data for the current item - PARSING_DATA pdata = parsingDataFromUModelIndex(index); - UINT32 parentOffset = pdata.offset + model->header(index).size(); - const UByteArray data = model->body(index); - - // Check that the is enough space for entry header - const UINT32 dataSize = (UINT32)data.size(); - UINT32 offset = 0; - - std::map guidMap; - std::map nameMap; - - // Parse all entries - UINT32 unparsedSize = dataSize; - while (unparsedSize) { - UINT32 variableSize = 0; - UString name; - UString info; - UByteArray header; - UByteArray body; - UINT8 subtype; - UINT8 calculated; - - const EVSA_ENTRY_HEADER* entryHeader = (const EVSA_ENTRY_HEADER*)(data.constData() + offset); - - // Check entry size - variableSize = sizeof(EVSA_ENTRY_HEADER); - if (unparsedSize < variableSize || unparsedSize < entryHeader->Size) { - UByteArray body = data.mid(offset); - UString info = usprintf("Full size: %Xh (%u)", body.size(), body.size()); - - // Checke type - UString name("Free space"); - UINT8 type = Types::FreeSpace; - UINT8 subtype = 0; - if (getPaddingType(body) == Subtypes::DataPadding) { - name = UString("Padding"); - type = Types::Padding; - subtype = Subtypes::DataPadding; - } - - // Add correct offset to parsing data - pdata.offset = parentOffset + offset; - - // Add free space tree item - UModelIndex itemIndex = model->addItem(type, subtype, name, UString(), info, UByteArray(), body, UByteArray(), false, parsingDataToUByteArray(pdata), index); - - // Show message - if (type == Types::Padding) - msg(UString("parseEvsaStoreBody: variable parsing failed, rest of unparsed store added as padding"), itemIndex); - - break; - } - variableSize = entryHeader->Size; - - // Recalculate entry checksum - calculated = calculateChecksum8(((const UINT8*)entryHeader) + 2, entryHeader->Size - 2); - - // GUID entry - if (entryHeader->Type == NVRAM_EVSA_ENTRY_TYPE_GUID1 || - entryHeader->Type == NVRAM_EVSA_ENTRY_TYPE_GUID2) { - const EVSA_GUID_ENTRY* guidHeader = (const EVSA_GUID_ENTRY*)entryHeader; - header = data.mid(offset, sizeof(EVSA_GUID_ENTRY)); - body = data.mid(offset + sizeof(EVSA_GUID_ENTRY), guidHeader->Header.Size - sizeof(EVSA_GUID_ENTRY)); - EFI_GUID guid = *(EFI_GUID*)body.constData(); - name = guidToUString(guid); - info = UString("GUID: ") + name + usprintf("\nFull size: %Xh (%u)\nHeader size %Xh (%u)\nBody size: %Xh (%u)\nType: %02Xh\nChecksum: %02Xh", - variableSize, variableSize, - header.size(), header.size(), - body.size(), body.size(), - guidHeader->Header.Type, - guidHeader->Header.Checksum) - + (guidHeader->Header.Checksum != calculated ? usprintf(", invalid, should be %02Xh", calculated) : UString(", valid")) - + usprintf("\nGuidId: %04Xh", guidHeader->GuidId); - subtype = Subtypes::GuidEvsaEntry; - guidMap.insert(std::pair(guidHeader->GuidId, guid)); - } - // Name entry - else if (entryHeader->Type == NVRAM_EVSA_ENTRY_TYPE_NAME1 || - entryHeader->Type == NVRAM_EVSA_ENTRY_TYPE_NAME2) { - const EVSA_NAME_ENTRY* nameHeader = (const EVSA_NAME_ENTRY*)entryHeader; - header = data.mid(offset, sizeof(EVSA_NAME_ENTRY)); - body = data.mid(offset + sizeof(EVSA_NAME_ENTRY), nameHeader->Header.Size - sizeof(EVSA_NAME_ENTRY)); - name = UString::fromUtf16((const CHAR16*)body.constData()); - info = UString("GUID: ") + name + usprintf("\nFull size: %Xh (%u)\nHeader size %Xh (%u)\nBody size: %Xh (%u)\nType: %02Xh\nChecksum: %02Xh", - variableSize, variableSize, - header.size(), header.size(), - body.size(), body.size(), - nameHeader->Header.Type, - nameHeader->Header.Checksum) - + (nameHeader->Header.Checksum != calculated ? usprintf(", invalid, should be %02Xh", calculated) : UString(", valid")) - + usprintf("\nVarId: %04Xh", nameHeader->VarId); - subtype = Subtypes::NameEvsaEntry; - nameMap.insert(std::pair(nameHeader->VarId, name)); - } - // Data entry - else if (entryHeader->Type == NVRAM_EVSA_ENTRY_TYPE_DATA1 || - entryHeader->Type == NVRAM_EVSA_ENTRY_TYPE_DATA2 || - entryHeader->Type == NVRAM_EVSA_ENTRY_TYPE_DATA_INVALID) { - const EVSA_DATA_ENTRY* dataHeader = (const EVSA_DATA_ENTRY*)entryHeader; - // Check for extended header - UINT32 headerSize = sizeof(EVSA_DATA_ENTRY); - UINT32 dataSize = dataHeader->Header.Size - sizeof(EVSA_DATA_ENTRY); - if (dataHeader->Attributes & NVRAM_EVSA_DATA_EXTENDED_HEADER) { - const EVSA_DATA_ENTRY_EXTENDED* dataHeaderExtended = (const EVSA_DATA_ENTRY_EXTENDED*)entryHeader; - headerSize = sizeof(EVSA_DATA_ENTRY_EXTENDED); - dataSize = dataHeaderExtended->DataSize; - variableSize = headerSize + dataSize; - } - - header = data.mid(offset, headerSize); - body = data.mid(offset + headerSize, dataSize); - name = UString("Data"); - info = usprintf("Full size: %Xh (%u)\nHeader size %Xh (%u)\nBody size: %Xh (%u)\nType: %02Xh\nChecksum: %02Xh", - variableSize, variableSize, - headerSize, headerSize, - dataSize, dataSize, - dataHeader->Header.Type, - dataHeader->Header.Checksum) - + (dataHeader->Header.Checksum != calculated ? usprintf(", invalid, should be %02Xh", calculated) : UString(", valid")) - + usprintf("\nVarId: %04Xh\nGuidId: %04Xh\nAttributes: %08Xh (", - dataHeader->VarId, - dataHeader->GuidId, - dataHeader->Attributes) - + evsaAttributesToUString(dataHeader->Attributes) + UString(")"); - subtype = Subtypes::DataEvsaEntry; - } - // Unknown entry or free space - else { - UByteArray body = data.mid(offset); - UString info = usprintf("Full size: %Xh (%u)", body.size(), body.size()); - - // Check type - UString name("Free space"); - UINT8 type = Types::FreeSpace; - UINT8 subtype = 0; - if (getPaddingType(body) == Subtypes::DataPadding) { - name = UString("Padding"); - type = Types::Padding; - subtype = Subtypes::DataPadding; - } - - // Add correct offset to parsing data - pdata.offset = parentOffset + offset; - - // Add free space tree item - UModelIndex itemIndex = model->addItem(type, subtype, name, UString(), info, UByteArray(), body, UByteArray(), false, parsingDataToUByteArray(pdata), index); - - // Show message - if (type == Types::Padding) - msg(usprintf("parseEvsaStoreBody: unknown variable of type %02Xh found at offset %Xh, the rest of unparsed store added as padding",entryHeader->Type, offset), itemIndex); - break; - } - - // Add correct offset to parsing data - pdata.offset = parentOffset + offset; - - // Add tree item - model->addItem(Types::EvsaEntry, subtype, name, UString(), info, header, body, UByteArray(), false, parsingDataToUByteArray(pdata), index); - - // Move to next variable - offset += variableSize; - unparsedSize = dataSize - offset; + // Check directory size + if ((UINT32)region.size() < sizeof(CPD_REV1_HEADER)) { + msg(usprintf("%s: CPD too small to fit rev1 partition table header", __FUNCTION__), parent); + return U_INVALID_ME_PARTITION_TABLE; } - - // Reparse all data variables to detect invalid ones and assign name and test to valid ones - for (int i = 0; i < model->rowCount(index); i++) { - UModelIndex current = index.child(i, 0); - if (model->subtype(current) == Subtypes::DataEvsaEntry) { - UByteArray header = model->header(current); - const EVSA_DATA_ENTRY* dataHeader = (const EVSA_DATA_ENTRY*)header.constData(); - UString guid; - if (guidMap.count(dataHeader->GuidId)) - guid = guidToUString(guidMap[dataHeader->GuidId]); - UString name; - if (nameMap.count(dataHeader->VarId)) - name = nameMap[dataHeader->VarId]; + + // Populate partition table header + const CPD_REV1_HEADER* cpdHeader = (const CPD_REV1_HEADER*)region.constData(); + + // Check header version to be known + UINT32 ptHeaderSize = 0; + if (cpdHeader->HeaderVersion == 2) { + if ((UINT32)region.size() < sizeof(CPD_REV2_HEADER)) { + msg(usprintf("%s: CPD too small to fit rev2 partition table header", __FUNCTION__), parent); + return U_INVALID_ME_PARTITION_TABLE; + } + + ptHeaderSize = sizeof(CPD_REV2_HEADER); + } + else if (cpdHeader->HeaderVersion == 1) { + ptHeaderSize = sizeof(CPD_REV1_HEADER); + } + + // Check directory size again + UINT32 ptBodySize = cpdHeader->NumEntries * sizeof(CPD_ENTRY); + UINT32 ptSize = ptHeaderSize + ptBodySize; + if ((UINT32)region.size() < ptSize) { + msg(usprintf("%s: CPD too small to fit the whole partition table", __FUNCTION__), parent); + return U_INVALID_ME_PARTITION_TABLE; + } + + // Get info + UByteArray header = region.left(ptHeaderSize); + UByteArray body = region.mid(ptHeaderSize, ptBodySize); + UString name = usprintf("CPD partition table"); + UString info = usprintf("Full size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nNumber of entries: %u\n" + "Header version: %u\nEntry version: %u", + ptSize, ptSize, + (UINT32)header.size(), (UINT32)header.size(), + (UINT32)body.size(), (UINT32)body.size(), + cpdHeader->NumEntries, + cpdHeader->HeaderVersion, + cpdHeader->EntryVersion); + + // Add tree item + index = model->addItem(localOffset, Types::CpdStore, 0, name, UString(), info, header, body, UByteArray(), Fixed, parent); + + // Add partition table entries + std::vector partitions; + UINT32 offset = ptHeaderSize; + const CPD_ENTRY* firstCpdEntry = (const CPD_ENTRY*)(body.constData()); + for (UINT32 i = 0; i < cpdHeader->NumEntries; i++) { + // Populate entry header + const CPD_ENTRY* cpdEntry = firstCpdEntry + i; + UByteArray entry((const char*)cpdEntry, sizeof(CPD_ENTRY)); + + // Get info + name = usprintf("%.12s", cpdEntry->EntryName); + info = usprintf("Full size: %Xh (%u)\nEntry offset: %Xh\nEntry length: %Xh\nHuffman compressed: ", + (UINT32)entry.size(), (UINT32)entry.size(), + cpdEntry->Offset.Offset, + cpdEntry->Length) + + (cpdEntry->Offset.HuffmanCompressed ? "Yes" : "No"); + + // Add tree item + UModelIndex entryIndex = model->addItem(offset, Types::CpdEntry, 0, name, UString(), info, UByteArray(), entry, UByteArray(), Fixed, index); + + // Adjust offset + offset += sizeof(CPD_ENTRY); + + if (cpdEntry->Offset.Offset != 0 && cpdEntry->Length != 0) { + // Add to partitions vector + CPD_PARTITION_INFO partition; + partition.type = Types::CpdPartition; + partition.ptEntry = *cpdEntry; + partition.index = entryIndex; + partition.hasMetaData = false; + partitions.push_back(partition); + } + } + + // Add padding if there's no partions to add + if (partitions.size() == 0) { + UByteArray partition = region.mid(ptSize); + + // Get info + name = UString("Padding"); + info = usprintf("Full size: %Xh (%u)", + (UINT32)partition.size(), (UINT32)partition.size()); + + // Add tree item + model->addItem(localOffset + ptSize, Types::Padding, getPaddingType(partition), name, UString(), info, UByteArray(), partition, UByteArray(), Fixed, parent); + + return U_SUCCESS; + } + + // Sort partitions by offset + std::sort(partitions.begin(), partitions.end()); + + // Because lenghts for all Huffmann-compressed partitions mean nothing at all, we need to split all partitions into 2 classes: + // 1. CPD manifest + // 2. Metadata entries + UINT32 i = 1; // manifest is index 0, .met partitions start at index 1 + while (i < partitions.size()) { + name = usprintf("%.12s", partitions[i].ptEntry.EntryName); + + // Check if the current entry is metadata entry + if (!name.endsWith(".met")) { + // No need to parse further, all metadata partitions are parsed + break; + } + + // Parse into data block, find Module Attributes extension, and get compressed size from there + UINT32 offset = 0; + UINT32 length = 0xFFFFFFFF; // Special guardian value + UByteArray partition = region.mid(partitions[i].ptEntry.Offset.Offset, partitions[i].ptEntry.Length); + while (offset < (UINT32)partition.size()) { + const CPD_EXTENTION_HEADER* extHeader = (const CPD_EXTENTION_HEADER*) (partition.constData() + offset); + if (extHeader->Length <= ((UINT32)partition.size() - offset)) { + if (extHeader->Type == CPD_EXT_TYPE_MODULE_ATTRIBUTES) { + const CPD_EXT_MODULE_ATTRIBUTES* attrHeader = (const CPD_EXT_MODULE_ATTRIBUTES*)(partition.constData() + offset); + length = attrHeader->CompressedSize; + } + offset += extHeader->Length; + } + else break; + } + + // Search down for corresponding code partition + // Construct its name by removing the .met suffix + name.chop(4); + + // Search + bool found = false; + UINT32 j = 1; + while (j < partitions.size()) { + UString namej = usprintf("%.12s", partitions[j].ptEntry.EntryName); - // Check for variable validity - if (guid.isEmpty() && name.isEmpty()) { // Both name and guid aren't found - model->setSubtype(current, Subtypes::InvalidEvsaEntry); - model->setName(current, UString("Invalid")); - msg(UString("parseEvsaStoreBody: data variable with invalid GuidId and invalid VarId"), current); + if (name == namej) { + found = true; + // Found it, update its Length if needed + if (partitions[j].ptEntry.Offset.HuffmanCompressed) { + partitions[j].ptEntry.Length = length; + } + else if (length != 0xFFFFFFFF && partitions[j].ptEntry.Length != length) { + msg(usprintf("%s: partition size mismatch between partition table (%Xh) and partition metadata (%Xh)", __FUNCTION__, + partitions[j].ptEntry.Length, length), partitions[j].index); + partitions[j].ptEntry.Length = length; // Believe metadata + } + partitions[j].hasMetaData = true; + // No need to search further + break; } - else if (guid.isEmpty()) { // Guid not found - model->setSubtype(current, Subtypes::InvalidEvsaEntry); - model->setName(current, UString("Invalid")); - msg(UString("parseEvsaStoreBody: data variable with invalid GuidId"), current); + // Check the next partition + j++; + } + if (!found) { + msg(usprintf("%s: no code partition", __FUNCTION__), partitions[i].index); + } + + // Check the next partition + i++; + } + +make_partition_table_consistent: + if (partitions.empty()) { + return U_INVALID_ME_PARTITION_TABLE; + } + // Sort partitions by offset + std::sort(partitions.begin(), partitions.end()); + + // Check for intersections and paddings between partitions + CPD_PARTITION_INFO padding = {}; + + // Check intersection with the partition table header + if (partitions.front().ptEntry.Offset.Offset < ptSize) { + msg(usprintf("%s: CPD partition has intersection with CPD partition table, skipped", __FUNCTION__), + partitions.front().index); + partitions.erase(partitions.begin()); + goto make_partition_table_consistent; + } + // Check for padding between partition table and the first partition + else if (partitions.front().ptEntry.Offset.Offset > ptSize) { + padding.ptEntry.Offset.Offset = ptSize; + padding.ptEntry.Length = partitions.front().ptEntry.Offset.Offset - padding.ptEntry.Offset.Offset; + padding.type = Types::Padding; + partitions.insert(partitions.begin(), padding); + } + // Check for intersections/paddings between partitions + for (size_t i = 1; i < partitions.size(); i++) { + UINT32 previousPartitionEnd = partitions[i - 1].ptEntry.Offset.Offset + partitions[i - 1].ptEntry.Length; + + // Check that current region is fully present in the image + if ((UINT64)partitions[i].ptEntry.Offset.Offset + (UINT64)partitions[i].ptEntry.Length > (UINT64)region.size()) { + if ((UINT64)partitions[i].ptEntry.Offset.Offset >= (UINT64)region.size()) { + msg(usprintf("%s: CPD partition is located outside of the opened image, skipped", __FUNCTION__), partitions[i].index); + partitions.erase(partitions.begin() + i); + goto make_partition_table_consistent; } - else if (name.isEmpty()) { // Name not found - model->setSubtype(current, Subtypes::InvalidEvsaEntry); - model->setName(current, UString("Invalid")); - msg(UString("parseEvsaStoreBody: data variable with invalid VarId"), current); - } - else { // Variable is OK, rename it - if (dataHeader->Header.Type == NVRAM_EVSA_ENTRY_TYPE_DATA_INVALID) { - model->setSubtype(current, Subtypes::InvalidEvsaEntry); - model->setName(current, UString("Invalid")); + else { + if (!partitions[i].hasMetaData && partitions[i].ptEntry.Offset.HuffmanCompressed) { + msg(usprintf("%s: CPD partition is compressed but doesn't have metadata and can't fit into its region, length adjusted", __FUNCTION__), + partitions[i].index); } else { - model->setName(current, guid); + msg(usprintf("%s: CPD partition can't fit into its region, truncated", __FUNCTION__), partitions[i].index); } - model->setText(current, name); - model->addInfo(current, UString("GUID: ") + guid + UString("\nName: ") + name + UString("\n"), false); + partitions[i].ptEntry.Length = (UINT32)region.size() - (UINT32)partitions[i].ptEntry.Offset.Offset; } } - } - - return U_SUCCESS; -} - - -USTATUS FfsParser::parseFlashMapBody(const UModelIndex & index) -{ - // Sanity check - if (!index.isValid()) - return U_INVALID_PARAMETER; - - // Get parsing data for the current item - PARSING_DATA pdata = parsingDataFromUModelIndex(index); - UINT32 parentOffset = pdata.offset + model->header(index).size(); - const UByteArray data = model->body(index); - - - const UINT32 dataSize = (UINT32)data.size(); - UINT32 offset = 0; - UINT32 unparsedSize = dataSize; - // Parse all entries - while (unparsedSize) { - const PHOENIX_FLASH_MAP_ENTRY* entryHeader = (const PHOENIX_FLASH_MAP_ENTRY*)(data.constData() + offset); - - // Check entry size - if (unparsedSize < sizeof(PHOENIX_FLASH_MAP_ENTRY)) { - // Last variable is bad, add the rest as padding and return - UByteArray body = data.mid(offset); - UString info = usprintf("Full size: %Xh (%u)", body.size(), body.size()); - - // Add correct offset to parsing data - pdata.offset = parentOffset + offset; - - // Add free space tree item - model->addItem(Types::Padding, getPaddingType(body), UString("Padding"), UString(), info, UByteArray(), body, UByteArray(), false, parsingDataToUByteArray(pdata), index); - - // Show message - if (unparsedSize < entryHeader->Size) - msg(UString("parseFlashMapBody: next entry appears too big, added as padding"), index); - - break; - } - - UString name = guidToUString(entryHeader->Guid); - // Construct header - UByteArray header = data.mid(offset, sizeof(PHOENIX_FLASH_MAP_ENTRY)); - - // Add info - UString info = UString("Entry GUID: ") + name + usprintf("\nFull size: 24h (36)\nHeader size: 24h (36)\nBody size: 0h (0)\n" - "Entry type: %04Xh\nData type: %04Xh\nMemory address: %08Xh\nSize: %08Xh\nOffset: %08Xh", - entryHeader->EntryType, - entryHeader->DataType, - entryHeader->PhysicalAddress, - entryHeader->Size, - entryHeader->Offset); - - // Add correct offset to parsing data - pdata.offset = parentOffset + offset; - - // Determine subtype - UINT8 subtype = 0; - switch (entryHeader->DataType) { - case NVRAM_PHOENIX_FLASH_MAP_ENTRY_TYPE_VOLUME: - subtype = Subtypes::VolumeFlashMapEntry; - break; - case NVRAM_PHOENIX_FLASH_MAP_ENTRY_TYPE_DATA_BLOCK: - subtype = Subtypes::DataFlashMapEntry; - break; + // Check for intersection with previous partition + if (partitions[i].ptEntry.Offset.Offset < previousPartitionEnd) { + // Check if previous partition was compressed but did not have metadata + if (!partitions[i - 1].hasMetaData && partitions[i - 1].ptEntry.Offset.HuffmanCompressed) { + msg(usprintf("%s: CPD partition is compressed but doesn't have metadata, length adjusted", __FUNCTION__), + partitions[i - 1].index); + partitions[i - 1].ptEntry.Length = (UINT32)partitions[i].ptEntry.Offset.Offset - (UINT32)partitions[i - 1].ptEntry.Offset.Offset; + goto make_partition_table_consistent; + } + + // Check if current partition is located inside previous one + if (partitions[i].ptEntry.Offset.Offset + partitions[i].ptEntry.Length <= previousPartitionEnd) { + msg(usprintf("%s: CPD partition is located inside another CPD partition, skipped", __FUNCTION__), + partitions[i].index); + partitions.erase(partitions.begin() + i); + goto make_partition_table_consistent; + } + else { + msg(usprintf("%s: CPD partition intersects with previous one, skipped", __FUNCTION__), + partitions[i].index); + partitions.erase(partitions.begin() + i); + goto make_partition_table_consistent; + } + } + // Check for padding between current and previous partitions + else if (partitions[i].ptEntry.Offset.Offset > previousPartitionEnd) { + padding.ptEntry.Offset.Offset = previousPartitionEnd; + padding.ptEntry.Length = partitions[i].ptEntry.Offset.Offset - previousPartitionEnd; + padding.type = Types::Padding; + std::vector::iterator iter = partitions.begin(); + std::advance(iter, i); + partitions.insert(iter, padding); } - - // Add tree item - model->addItem(Types::FlashMapEntry, subtype, name, flashMapGuidToUString(entryHeader->Guid), info, header, UByteArray(), UByteArray(), true, parsingDataToUByteArray(pdata), index); - - // Move to next variable - offset += sizeof(PHOENIX_FLASH_MAP_ENTRY); - unparsedSize = dataSize - offset; } - + // Check for padding after the last region + if ((UINT64)partitions.back().ptEntry.Offset.Offset + (UINT64)partitions.back().ptEntry.Length < (UINT64)region.size()) { + padding.ptEntry.Offset.Offset = partitions.back().ptEntry.Offset.Offset + partitions.back().ptEntry.Length; + padding.ptEntry.Length = (UINT32)region.size() - padding.ptEntry.Offset.Offset; + padding.type = Types::Padding; + partitions.push_back(padding); + } + + // Partition map is consistent + for (size_t i = 0; i < partitions.size(); i++) { + if (partitions[i].type == Types::CpdPartition) { + UByteArray partition = region.mid(partitions[i].ptEntry.Offset.Offset, partitions[i].ptEntry.Length); + + // Get info + name = usprintf("%.12s", partitions[i].ptEntry.EntryName); + + // It's a manifest + if (name.endsWith(".man")) { + if (!partitions[i].ptEntry.Offset.HuffmanCompressed + && partitions[i].ptEntry.Length >= sizeof(CPD_MANIFEST_HEADER)) { + const CPD_MANIFEST_HEADER* manifestHeader = (const CPD_MANIFEST_HEADER*) partition.constData(); + if (manifestHeader->HeaderId == ME_MANIFEST_HEADER_ID) { + UByteArray header = partition.left(manifestHeader->HeaderLength * sizeof(UINT32)); + UByteArray body = partition.mid(manifestHeader->HeaderLength * sizeof(UINT32)); + + info = usprintf("Full size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)" + "\nHeader type: %u\nHeader length: %Xh (%u)\nHeader version: %Xh\nFlags: %08Xh\nVendor: %Xh\n" + "Date: %Xh\nSize: %Xh (%u)\nVersion: %u.%u.%u.%u\nSecurity version number: %u\nModulus size: %Xh (%u)\nExponent size: %Xh (%u)", + (UINT32)partition.size(), (UINT32)partition.size(), + (UINT32)header.size(), (UINT32)header.size(), + (UINT32)body.size(), (UINT32)body.size(), + manifestHeader->HeaderType, + manifestHeader->HeaderLength * (UINT32)sizeof(UINT32), manifestHeader->HeaderLength * (UINT32)sizeof(UINT32), + manifestHeader->HeaderVersion, + manifestHeader->Flags, + manifestHeader->Vendor, + manifestHeader->Date, + manifestHeader->Size * (UINT32)sizeof(UINT32), manifestHeader->Size * (UINT32)sizeof(UINT32), + manifestHeader->VersionMajor, manifestHeader->VersionMinor, manifestHeader->VersionBugfix, manifestHeader->VersionBuild, + manifestHeader->SecurityVersion, + manifestHeader->ModulusSize * (UINT32)sizeof(UINT32), manifestHeader->ModulusSize * (UINT32)sizeof(UINT32), + manifestHeader->ExponentSize * (UINT32)sizeof(UINT32), manifestHeader->ExponentSize * (UINT32)sizeof(UINT32)); + + // Add tree item + UModelIndex partitionIndex = model->addItem(localOffset + partitions[i].ptEntry.Offset.Offset, Types::CpdPartition, Subtypes::ManifestCpdPartition, name, UString(), info, header, body, UByteArray(), Fixed, parent); + + // Parse data as extensions area + // Add the header size as a local offset + // Since the body starts after the header length + parseCpdExtensionsArea(partitionIndex, (UINT32)header.size()); + } + } + } + // It's a metadata + else if (name.endsWith(".met")) { + info = usprintf("Full size: %Xh (%u)\nHuffman compressed: ", + (UINT32)partition.size(), (UINT32)partition.size()) + + (partitions[i].ptEntry.Offset.HuffmanCompressed ? "Yes" : "No"); + + // Calculate SHA256 hash over the metadata and add it to its info + UByteArray hash(SHA256_HASH_SIZE, '\x00'); + sha256(partition.constData(), partition.size(), hash.data()); + info += UString("\nMetadata hash: ") + UString(hash.toHex().constData()); + + // Add three item + UModelIndex partitionIndex = model->addItem(localOffset + partitions[i].ptEntry.Offset.Offset, Types::CpdPartition, Subtypes::MetadataCpdPartition, name, UString(), info, UByteArray(), partition, UByteArray(), Fixed, parent); + + // Parse data as extensions area + parseCpdExtensionsArea(partitionIndex, 0); + } + // It's a code + else { + info = usprintf("Full size: %Xh (%u)\nHuffman compressed: ", + (UINT32)partition.size(), (UINT32)partition.size()) + + (partitions[i].ptEntry.Offset.HuffmanCompressed ? "Yes" : "No"); + + // Calculate SHA256 hash over the code and add it to its info + UByteArray hash(SHA256_HASH_SIZE, '\x00'); + sha256(partition.constData(), partition.size(), hash.data()); + info += UString("\nHash: ") + UString(hash.toHex().constData()); + + UModelIndex codeIndex = model->addItem(localOffset + partitions[i].ptEntry.Offset.Offset, Types::CpdPartition, Subtypes::CodeCpdPartition, name, UString(), info, UByteArray(), partition, UByteArray(), Fixed, parent); + (void)parseRawArea(codeIndex); + } + } + else if (partitions[i].type == Types::Padding) { + UByteArray partition = region.mid(partitions[i].ptEntry.Offset.Offset, partitions[i].ptEntry.Length); + + // Get info + name = UString("Padding"); + info = usprintf("Full size: %Xh (%u)", (UINT32)partition.size(), (UINT32)partition.size()); + + // Add tree item + model->addItem(localOffset + partitions[i].ptEntry.Offset.Offset, Types::Padding, getPaddingType(partition), name, UString(), info, UByteArray(), partition, UByteArray(), Fixed, parent); + } + else { + msg(usprintf("%s: CPD partition of unknown type found", __FUNCTION__), parent); + return U_INVALID_ME_PARTITION_TABLE; + } + } + return U_SUCCESS; } + +USTATUS FfsParser::parseCpdExtensionsArea(const UModelIndex & index, const UINT32 localOffset) +{ + if (!index.isValid()) { + return U_INVALID_PARAMETER; + } + + UByteArray body = model->body(index); + UINT32 offset = 0; + while (offset < (UINT32)body.size()) { + const CPD_EXTENTION_HEADER* extHeader = (const CPD_EXTENTION_HEADER*) (body.constData() + offset); + if (extHeader->Length > 0 + && extHeader->Length <= ((UINT32)body.size() - offset)) { + UByteArray partition = body.mid(offset, extHeader->Length); + + UString name = cpdExtensionTypeToUstring(extHeader->Type); + UString info = usprintf("Full size: %Xh (%u)\nType: %Xh", (UINT32)partition.size(), (UINT32)partition.size(), extHeader->Type); + + // Parse Signed Package Info a bit further + UModelIndex extIndex; + if (extHeader->Type == CPD_EXT_TYPE_SIGNED_PACKAGE_INFO) { + UByteArray header = partition.left(sizeof(CPD_EXT_SIGNED_PACKAGE_INFO)); + UByteArray data = partition.mid(header.size()); + + const CPD_EXT_SIGNED_PACKAGE_INFO* infoHeader = (const CPD_EXT_SIGNED_PACKAGE_INFO*)header.constData(); + + info = usprintf("Full size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nType: %Xh\n" + "Package name: %.4s\nVersion control number: %Xh\nSecurity version number: %Xh\n" + "Usage bitmap: %02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X", + (UINT32)partition.size(), (UINT32)partition.size(), + (UINT32)header.size(), (UINT32)header.size(), + (UINT32)body.size(), (UINT32)body.size(), + infoHeader->ExtensionType, + infoHeader->PackageName, + infoHeader->Vcn, + infoHeader->Svn, + infoHeader->UsageBitmap[0], infoHeader->UsageBitmap[1], infoHeader->UsageBitmap[2], infoHeader->UsageBitmap[3], + infoHeader->UsageBitmap[4], infoHeader->UsageBitmap[5], infoHeader->UsageBitmap[6], infoHeader->UsageBitmap[7], + infoHeader->UsageBitmap[8], infoHeader->UsageBitmap[9], infoHeader->UsageBitmap[10], infoHeader->UsageBitmap[11], + infoHeader->UsageBitmap[12], infoHeader->UsageBitmap[13], infoHeader->UsageBitmap[14], infoHeader->UsageBitmap[15]); + + // Add tree item + extIndex = model->addItem(offset + localOffset, Types::CpdExtension, 0, name, UString(), info, header, data, UByteArray(), Fixed, index); + parseSignedPackageInfoData(extIndex); + } + // Parse IFWI Partition Manifest a bit further + else if (extHeader->Type == CPD_EXT_TYPE_IFWI_PARTITION_MANIFEST) { + const CPD_EXT_IFWI_PARTITION_MANIFEST* attrHeader = (const CPD_EXT_IFWI_PARTITION_MANIFEST*)partition.constData(); + + // Check HashSize to be sane. + UINT32 hashSize = attrHeader->HashSize; + bool msgHashSizeMismatch = false; + if (hashSize > sizeof(attrHeader->CompletePartitionHash)) { + hashSize = sizeof(attrHeader->CompletePartitionHash); + msgHashSizeMismatch = true; + } + + // This hash is stored reversed + // Need to reverse it back to normal + UByteArray hash((const char*)&attrHeader->CompletePartitionHash, hashSize); + std::reverse(hash.begin(), hash.end()); + + info = usprintf("Full size: %Xh (%u)\nType: %Xh\n" + "Partition name: %.4s\nPartition length: %Xh\nPartition version major: %Xh\nPartition version minor: %Xh\n" + "Data format version: %Xh\nInstance ID: %Xh\nHash algorithm: %Xh\nHash size: %Xh\nAction on update: %Xh", + (UINT32)partition.size(), (UINT32)partition.size(), + attrHeader->ExtensionType, + attrHeader->PartitionName, + attrHeader->CompletePartitionLength, + attrHeader->PartitionVersionMajor, attrHeader->PartitionVersionMinor, + attrHeader->DataFormatVersion, + attrHeader->InstanceId, + attrHeader->HashAlgorithm, + attrHeader->HashSize, + attrHeader->ActionOnUpdate) + + UString("\nSupport multiple instances: ") + (attrHeader->SupportMultipleInstances ? "Yes" : "No") + + UString("\nSupport API version based update: ") + (attrHeader->SupportApiVersionBasedUpdate ? "Yes" : "No") + + UString("\nObey full update rules: ") + (attrHeader->ObeyFullUpdateRules ? "Yes" : "No") + + UString("\nIFR enable only: ") + (attrHeader->IfrEnableOnly ? "Yes" : "No") + + UString("\nAllow cross point update: ") + (attrHeader->AllowCrossPointUpdate ? "Yes" : "No") + + UString("\nAllow cross hotfix update: ") + (attrHeader->AllowCrossHotfixUpdate ? "Yes" : "No") + + UString("\nPartial update only: ") + (attrHeader->PartialUpdateOnly ? "Yes" : "No") + + UString("\nPartition hash: ") + UString(hash.toHex().constData()); + + // Add tree item + extIndex = model->addItem(offset + localOffset, Types::CpdExtension, 0, name, UString(), info, UByteArray(), partition, UByteArray(), Fixed, index); + if (msgHashSizeMismatch) { + msg(usprintf("%s: IFWI Partition Manifest hash size is %u, maximum allowed is %u, truncated", __FUNCTION__, attrHeader->HashSize, (UINT32)sizeof(attrHeader->CompletePartitionHash)), extIndex); + } + } + // Parse Module Attributes a bit further + else if (extHeader->Type == CPD_EXT_TYPE_MODULE_ATTRIBUTES) { + const CPD_EXT_MODULE_ATTRIBUTES* attrHeader = (const CPD_EXT_MODULE_ATTRIBUTES*)partition.constData(); + int hashSize = (UINT32)partition.size() - CpdExtModuleImageHashOffset; + + // This hash is stored reversed + // Need to reverse it back to normal + UByteArray hash((const char*)attrHeader + CpdExtModuleImageHashOffset, hashSize); + std::reverse(hash.begin(), hash.end()); + + info = usprintf("Full size: %Xh (%u)\nType: %Xh\n" + "Compression type: %Xh\nUncompressed size: %Xh (%u)\nCompressed size: %Xh (%u)\nGlobal module ID: %Xh\nImage hash: ", + (UINT32)partition.size(), (UINT32)partition.size(), + attrHeader->ExtensionType, + attrHeader->CompressionType, + attrHeader->UncompressedSize, attrHeader->UncompressedSize, + attrHeader->CompressedSize, attrHeader->CompressedSize, + attrHeader->GlobalModuleId) + UString(hash.toHex().constData()); + + // Add tree item + extIndex = model->addItem(offset + localOffset, Types::CpdExtension, 0, name, UString(), info, UByteArray(), partition, UByteArray(), Fixed, index); + } + // Parse everything else + else { + // Add tree item, if needed + extIndex = model->addItem(offset + localOffset, Types::CpdExtension, 0, name, UString(), info, UByteArray(), partition, UByteArray(), Fixed, index); + } + + // There needs to be a more generic way to do it, but it is fine for now + if (extHeader->Type > CPD_EXT_TYPE_TBT_METADATA + && extHeader->Type != CPD_EXT_TYPE_GMF_CERTIFICATE + && extHeader->Type != CPD_EXT_TYPE_GMF_BODY + && extHeader->Type != CPD_EXT_TYPE_KEY_MANIFEST_EXT + && extHeader->Type != CPD_EXT_TYPE_SIGNED_PACKAGE_INFO_EXT + && extHeader->Type != CPD_EXT_TYPE_SPS_PLATFORM_ID) { + msg(usprintf("%s: CPD extension of unknown type found", __FUNCTION__), extIndex); + } + + offset += extHeader->Length; + } + else break; + // TODO: add padding at the end + } + + return U_SUCCESS; +} + +USTATUS FfsParser::parseSignedPackageInfoData(const UModelIndex & index) +{ + if (!index.isValid()) { + return U_INVALID_PARAMETER; + } + + UByteArray body = model->body(index); + UINT32 offset = 0; + while (offset < (UINT32)body.size()) { + const CPD_EXT_SIGNED_PACKAGE_INFO_MODULE* moduleHeader = (const CPD_EXT_SIGNED_PACKAGE_INFO_MODULE*)(body.constData() + offset); + if (sizeof(CPD_EXT_SIGNED_PACKAGE_INFO_MODULE) <= ((UINT32)body.size() - offset)) { + // TODO: check sanity of moduleHeader->HashSize + UByteArray module((const char*)moduleHeader, CpdExtSignedPkgMetadataHashOffset + moduleHeader->HashSize); + UString name = usprintf("%.12s", moduleHeader->Name); + + // This hash is stored reversed + // Need to reverse it back to normal + UByteArray hash((const char*)moduleHeader + CpdExtSignedPkgMetadataHashOffset, moduleHeader->HashSize); + std::reverse(hash.begin(), hash.end()); + + UString info = usprintf("Full size: %Xh (%u)\nType: %Xh\nHash algorithm: %Xh\nHash size: %Xh (%u)\nMetadata size: %Xh (%u)\nMetadata hash: ", + (UINT32)module.size(), (UINT32)module.size(), + moduleHeader->Type, + moduleHeader->HashAlgorithm, + moduleHeader->HashSize, moduleHeader->HashSize, + moduleHeader->MetadataSize, moduleHeader->MetadataSize) + UString(hash.toHex().constData()); + // Add tree otem + model->addItem(offset, Types::CpdSpiEntry, 0, name, UString(), info, UByteArray(), module, UByteArray(), Fixed, index); + offset += module.size(); + } + else break; + // TODO: add padding at the end + } + + return U_SUCCESS; +} + +void FfsParser::outputInfo(void) { + // Show ffsParser's messages + std::vector > messages = getMessages(); + for (size_t i = 0; i < messages.size(); i++) { + std::cout << (const char *)messages[i].first.toLocal8Bit() << std::endl; + } + + // Get last VTF + std::vector, UModelIndex > > fitTable = getFitTable(); + if (fitTable.size()) { + std::cout << "---------------------------------------------------------------------------" << std::endl; + std::cout << " Address | Size | Ver | CS | Type / Info " << std::endl; + std::cout << "---------------------------------------------------------------------------" << std::endl; + for (size_t i = 0; i < fitTable.size(); i++) { + std::cout + << (const char *)fitTable[i].first[0].toLocal8Bit() << " | " + << (const char *)fitTable[i].first[1].toLocal8Bit() << " | " + << (const char *)fitTable[i].first[2].toLocal8Bit() << " | " + << (const char *)fitTable[i].first[3].toLocal8Bit() << " | " + << (const char *)fitTable[i].first[4].toLocal8Bit() << " | " + << (const char *)fitTable[i].first[5].toLocal8Bit() << std::endl; + } + } + + // Get security info + UString secInfo = getSecurityInfo(); + if (!secInfo.isEmpty()) { + std::cout << "---------------------------------------------------------------------------" << std::endl; + std::cout << "Security Info" << std::endl; + std::cout << "---------------------------------------------------------------------------" << std::endl; + std::cout << (const char *)secInfo.toLocal8Bit() << std::endl; + } +} diff --git a/common/ffsparser.h b/common/ffsparser.h index 258cb53..ef7ccc4 100644 --- a/common/ffsparser.h +++ b/common/ffsparser.h @@ -1,6 +1,6 @@ /* ffsparser.h -Copyright (c) 2016, Nikolaj Schlej. All rights reserved. +Copyright (c) 2017, LongSoft. All rights reserved. This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -15,81 +15,151 @@ WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include +#include "basetypes.h" #include "ustring.h" #include "ubytearray.h" -#include "basetypes.h" #include "treemodel.h" -#include "utility.h" -#include "peimage.h" -#include "parsingdata.h" -#include "types.h" -#include "treemodel.h" -#include "descriptor.h" +#include "intel_microcode.h" #include "ffs.h" -#include "gbe.h" -#include "me.h" -#include "fit.h" -#include "nvram.h" +#include "fitparser.h" -class TreeModel; +// Region info +typedef struct REGION_INFO_ { + UINT32 offset = 0; + UINT32 length = 0; + UINT8 type = 0; + UByteArray data; + friend bool operator< (const struct REGION_INFO_ & lhs, const struct REGION_INFO_ & rhs) { return lhs.offset < rhs.offset; } +} REGION_INFO; + +// BPDT partition info +typedef struct BPDT_PARTITION_INFO_ { + BPDT_ENTRY ptEntry = {}; + UINT8 type = 0; + UModelIndex index; + friend bool operator< (const struct BPDT_PARTITION_INFO_ & lhs, const struct BPDT_PARTITION_INFO_ & rhs) { return lhs.ptEntry.Offset < rhs.ptEntry.Offset; } +} BPDT_PARTITION_INFO; + +// CPD partition info +typedef struct CPD_PARTITION_INFO_ { + CPD_ENTRY ptEntry = {}; + UINT8 type = 0; + bool hasMetaData = false; + UModelIndex index; + friend bool operator< (const struct CPD_PARTITION_INFO_ & lhs, const struct CPD_PARTITION_INFO_ & rhs) { return lhs.ptEntry.Offset.Offset < rhs.ptEntry.Offset.Offset; } +} CPD_PARTITION_INFO; + +// Protected range +typedef struct PROTECTED_RANGE_ { + UINT32 Offset; + UINT32 Size; + UINT16 AlgorithmId; + UINT8 Type; + UINT8 : 8; + UByteArray Hash; +} PROTECTED_RANGE; + +#define PROTECTED_RANGE_INTEL_BOOT_GUARD_IBB 0x01 +#define PROTECTED_RANGE_INTEL_BOOT_GUARD_POST_IBB 0x02 +#define PROTECTED_RANGE_INTEL_BOOT_GUARD_OBB 0x03 +#define PROTECTED_RANGE_VENDOR_HASH_PHOENIX 0x04 +#define PROTECTED_RANGE_VENDOR_HASH_AMI_V1 0x05 +#define PROTECTED_RANGE_VENDOR_HASH_AMI_V2 0x06 +#define PROTECTED_RANGE_VENDOR_HASH_AMI_V3 0x07 +#define PROTECTED_RANGE_VENDOR_HASH_MICROSOFT_PMDA 0x08 +#define PROTECTED_RANGE_VENDOR_HASH_INSYDE 0x09 + +class FitParser; +class NvramParser; +class MeParser; class FfsParser { public: - // Default constructor and destructor - FfsParser(TreeModel* treeModel) : model(treeModel), capsuleOffsetFixup(0) {} - ~FfsParser() {} + // Constructor and destructor + FfsParser(TreeModel* treeModel); + ~FfsParser(); - // Returns messages - std::vector > getMessages() const { return messagesVector; } - // Clears messages + // Obtain parser messages + std::vector > getMessages() const; + // Clear messages void clearMessages() { messagesVector.clear(); } - // Firmware image parsing + // Parse firmware image USTATUS parse(const UByteArray &buffer); // Obtain parsed FIT table - std::vector > getFitTable() const { return fitTable; } + std::vector, UModelIndex> > getFitTable() const; + + // Obtain Security Info + UString getSecurityInfo() const; + + // Obtain offset/address difference + UINT64 getAddressDiff() { return addressDiff; } + + // Output some info to stdout + void outputInfo(void); private: TreeModel *model; std::vector > messagesVector; - void msg(const UString message, const UModelIndex index = UModelIndex()) { + void msg(const UString & message, const UModelIndex & index = UModelIndex()) { messagesVector.push_back(std::pair(message, index)); }; + FitParser* fitParser; + NvramParser* nvramParser; + MeParser* meParser; + + UByteArray openedImage; UModelIndex lastVtf; - UINT32 capsuleOffsetFixup; - std::vector > fitTable; + UINT32 imageBase; + UINT64 addressDiff; + + UString securityInfo; + + std::vector protectedRanges; + UINT64 protectedRegionsBase; + UModelIndex dxeCore; // First pass USTATUS performFirstPass(const UByteArray & imageFile, UModelIndex & index); + USTATUS parseCapsule(const UByteArray & capsule, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index); + USTATUS parseIntelImage(const UByteArray & intelImage, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index); + USTATUS parseGenericImage(const UByteArray & intelImage, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index); + + USTATUS parseBpdtRegion(const UByteArray & region, const UINT32 localOffset, const UINT32 sbpdtOffsetFixup, const UModelIndex & parent, UModelIndex & index); + USTATUS parseCpdRegion(const UByteArray & region, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index); + USTATUS parseCpdExtensionsArea(const UModelIndex & index, const UINT32 localOffset); + USTATUS parseSignedPackageInfoData(const UModelIndex & index); + USTATUS parseRawArea(const UModelIndex & index); - USTATUS parseVolumeHeader(const UByteArray & volume, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index); + USTATUS parseVolumeHeader(const UByteArray & volume, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index); USTATUS parseVolumeBody(const UModelIndex & index); - USTATUS parseFileHeader(const UByteArray & file, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index); + USTATUS parseMicrocodeVolumeBody(const UModelIndex & index); + USTATUS parseFileHeader(const UByteArray & file, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index); USTATUS parseFileBody(const UModelIndex & index); - USTATUS parseSectionHeader(const UByteArray & section, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree); + USTATUS parseSectionHeader(const UByteArray & section, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree); USTATUS parseSectionBody(const UModelIndex & index); - USTATUS parseIntelImage(const UByteArray & intelImage, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & root); - USTATUS parseGbeRegion(const UByteArray & gbe, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index); - USTATUS parseMeRegion(const UByteArray & me, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index); - USTATUS parseBiosRegion(const UByteArray & bios, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index); - USTATUS parsePdrRegion(const UByteArray & pdr, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index); - USTATUS parseGeneralRegion(const UINT8 subtype, const UByteArray & region, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index); + USTATUS parseGbeRegion(const UByteArray & gbe, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index); + USTATUS parseMeRegion(const UByteArray & me, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index); + USTATUS parseBiosRegion(const UByteArray & bios, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index); + USTATUS parsePdrRegion(const UByteArray & pdr, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index); + USTATUS parseDevExp1Region(const UByteArray & devExp1, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index); + USTATUS parseGenericRegion(const UINT8 subtype, const UByteArray & region, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index); USTATUS parsePadFileBody(const UModelIndex & index); - USTATUS parseVolumeNonUefiData(const UByteArray & data, const UINT32 parentOffset, const UModelIndex & index); + USTATUS parseVolumeNonUefiData(const UByteArray & data, const UINT32 localOffset, const UModelIndex & index); USTATUS parseSections(const UByteArray & sections, const UModelIndex & index, const bool insertIntoTree); - USTATUS parseCommonSectionHeader(const UByteArray & section, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree); - USTATUS parseCompressedSectionHeader(const UByteArray & section, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree); - USTATUS parseGuidedSectionHeader(const UByteArray & section, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree); - USTATUS parseFreeformGuidedSectionHeader(const UByteArray & section, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree); - USTATUS parseVersionSectionHeader(const UByteArray & section, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree); - USTATUS parsePostcodeSectionHeader(const UByteArray & section, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree); + USTATUS parseCommonSectionHeader(const UByteArray & section, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree); + USTATUS parseCompressedSectionHeader(const UByteArray & section, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree); + USTATUS parseGuidedSectionHeader(const UByteArray & section, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree); + USTATUS parseFreeformGuidedSectionHeader(const UByteArray & section, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree); + USTATUS parseVersionSectionHeader(const UByteArray & section, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree); + USTATUS parsePostcodeSectionHeader(const UByteArray & section, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree); USTATUS parseCompressedSectionBody(const UModelIndex & index); USTATUS parseGuidedSectionBody(const UModelIndex & index); @@ -100,43 +170,37 @@ private: USTATUS parsePeImageSectionBody(const UModelIndex & index); USTATUS parseTeImageSectionBody(const UModelIndex & index); - UINT8 getPaddingType(const UByteArray & padding); USTATUS parseAprioriRawSection(const UByteArray & body, UString & parsed); - USTATUS findNextVolume(const UModelIndex & index, const UByteArray & bios, const UINT32 parentOffset, const UINT32 volumeOffset, UINT32 & nextVolumeOffset); - USTATUS getVolumeSize(const UByteArray & bios, const UINT32 volumeOffset, UINT32 & volumeSize, UINT32 & bmVolumeSize); - UINT32 getFileSize(const UByteArray & volume, const UINT32 fileOffset, const UINT8 ffsVersion); + USTATUS findNextRawAreaItem(const UModelIndex & index, const UINT32 localOffset, UINT8 & nextItemType, UINT32 & nextItemOffset, UINT32 & nextItemSize, UINT32 & nextItemAlternativeSize); + UINT32 getFileSize(const UByteArray & volume, const UINT32 fileOffset, const UINT8 ffsVersion, const UINT8 revision); UINT32 getSectionSize(const UByteArray & file, const UINT32 sectionOffset, const UINT8 ffsVersion); + + USTATUS parseIntelMicrocodeHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index); + bool microcodeHeaderValid(const INTEL_MICROCODE_HEADER* ucodeHeader); - // NVRAM parsing - USTATUS parseNvramVolumeBody(const UModelIndex & index); - USTATUS findNextStore(const UModelIndex & index, const UByteArray & volume, const UINT32 parentOffset, const UINT32 storeOffset, UINT32 & nextStoreOffset); - USTATUS getStoreSize(const UByteArray & data, const UINT32 storeOffset, UINT32 & storeSize); - USTATUS parseStoreHeader(const UByteArray & store, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index); - - USTATUS parseNvarStore(const UModelIndex & index); - USTATUS parseVssStoreHeader(const UByteArray & store, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index); - USTATUS parseFtwStoreHeader(const UByteArray & store, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index); - USTATUS parseFdcStoreHeader(const UByteArray & store, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index); - USTATUS parseFsysStoreHeader(const UByteArray & store, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index); - USTATUS parseEvsaStoreHeader(const UByteArray & store, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index); - USTATUS parseFlashMapStoreHeader(const UByteArray & store, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index); - USTATUS parseCmdbStoreHeader(const UByteArray & store, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index); - USTATUS parseSlicPubkeyHeader(const UByteArray & store, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index); - USTATUS parseSlicMarkerHeader(const UByteArray & store, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index); - USTATUS parseIntelMicrocodeHeader(const UByteArray & store, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index); - - USTATUS parseVssStoreBody(const UModelIndex & index); - USTATUS parseFsysStoreBody(const UModelIndex & index); - USTATUS parseEvsaStoreBody(const UModelIndex & index); - USTATUS parseFlashMapBody(const UModelIndex & index); + USTATUS parseVendorHashFile(const UByteArray & fileGuid, const UModelIndex & index); // Second pass USTATUS performSecondPass(const UModelIndex & index); - USTATUS addOffsetsRecursive(const UModelIndex & index); - USTATUS addMemoryAddressesRecursive(const UModelIndex & index, const UINT32 diff); - USTATUS addFixedAndCompressedRecursive(const UModelIndex & index); - USTATUS parseFit(const UModelIndex & index, const UINT32 diff); - USTATUS findFitRecursive(const UModelIndex & index, const UINT32 diff, UModelIndex & found, UINT32 & fitOffset); + USTATUS addInfoRecursive(const UModelIndex & index); + USTATUS checkTeImageBase(const UModelIndex & index); + + USTATUS checkProtectedRanges(const UModelIndex & index); + USTATUS markProtectedRangeRecursive(const UModelIndex & index, const PROTECTED_RANGE & range); + + USTATUS parseResetVectorData(); + +#ifdef U_ENABLE_FIT_PARSING_SUPPORT + friend class FitParser; // Make FFS parsing routines accessible to FitParser +#endif + +#ifdef U_ENABLE_NVRAM_PARSING_SUPPORT + friend class NvramParser; // Make FFS parsing routines accessible to NvramParser +#endif + +#ifdef U_ENABLE_ME_PARSING_SUPPORT + friend class MeParser; // Make FFS parsing routines accessible to MeParser +#endif }; #endif // FFSPARSER_H diff --git a/common/ffsreport.cpp b/common/ffsreport.cpp index 58f9775..901fe35 100644 --- a/common/ffsreport.cpp +++ b/common/ffsreport.cpp @@ -1,17 +1,19 @@ /* fssreport.cpp - -Copyright (c) 2016, Nikolaj Schlej. All rights reserved. -This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -*/ + + Copyright (c) 2016, Nikolaj Schlej. All rights reserved. + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + */ #include "ffsreport.h" +#include "ffs.h" +#include "utility.h" std::vector FfsReport::generate() { @@ -19,49 +21,56 @@ std::vector FfsReport::generate() // Check model pointer if (!model) { - report.push_back(UString("ERROR: Invalid model pointer provided")); + report.push_back(usprintf("%s: invalid model pointer provided", __FUNCTION__)); return report; } // Check root index to be valid UModelIndex root = model->index(0,0); if (!root.isValid()) { - report.push_back(UString("ERROR: Model root index is invalid")); + report.push_back(usprintf("%s: model root index is invalid", __FUNCTION__)); return report; } - + // Generate report recursive - report.push_back(UString(" Type | Subtype | Size | CRC32 | Name ")); + report.push_back(UString(" Type | Subtype | Base | Size | CRC32 | Name ")); USTATUS result = generateRecursive(report, root); if (result) { - report.push_back(UString("ERROR: generateRecursive returned ") + errorCodeToUString(result)); + report.push_back(usprintf("%s: generateRecursive returned ", __FUNCTION__) + errorCodeToUString(result)); } - + return report; } -USTATUS FfsReport::generateRecursive(std::vector & report, UModelIndex index, UINT32 level) +USTATUS FfsReport::generateRecursive(std::vector & report, const UModelIndex & index, const UINT32 level) { if (!index.isValid()) - return U_SUCCESS; //Nothing to report for invalid index + return U_SUCCESS; // Nothing to report for invalid index // Calculate item CRC32 UByteArray data = model->header(index) + model->body(index) + model->tail(index); - UINT32 crc = crc32(0, (const UINT8*)data.constData(), data.size()); - + UINT32 crc = (UINT32)crc32(0, (const UINT8*)data.constData(), (uInt)data.size()); + // Information on current item UString text = model->text(index); + UString offset = "| N/A "; + if ((!model->compressed(index)) || (index.parent().isValid() && !model->compressed(index.parent()))) { + offset = usprintf("| %08X ", model->base(index)); + } + report.push_back( - UString(" ") + itemTypeToUString(model->type(index)).leftJustified(16) - + UString("| ") + itemSubtypeToUString(model->type(index), model->subtype(index)).leftJustified(22) - + usprintf("| %08X | %08X | ", data.size(), crc) - + urepeated('-', level) + UString(" ") + model->name(index) + (text.isEmpty() ? UString("") : UString(" | ") + text) - ); + UString(" ") + itemTypeToUString(model->type(index)).leftJustified(20) + + UString("| ") + itemSubtypeToUString(model->type(index), model->subtype(index)).leftJustified(22) + + offset + + usprintf("| %08X | %08X | ", (UINT32)data.size(), crc) + + urepeated('-', level) + UString(" ") + model->name(index) + (text.isEmpty() ? UString() : UString(" | ") + text) + ); // Information on child items for (int i = 0; i < model->rowCount(index); i++) { - generateRecursive(report, index.child(i,0), level + 1); + generateRecursive(report, index.model()->index(i,0,index), level + 1); } return U_SUCCESS; } + diff --git a/common/ffsreport.h b/common/ffsreport.h index c7415f9..65d1662 100644 --- a/common/ffsreport.h +++ b/common/ffsreport.h @@ -16,12 +16,11 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include -#include "../common/ubytearray.h" -#include "../common/ustring.h" #include "basetypes.h" +#include "ubytearray.h" +#include "ustring.h" #include "treemodel.h" -#include "ffs.h" -#include "utility.h" + class FfsReport { @@ -35,8 +34,8 @@ public: private: TreeModel* model; - USTATUS generateRecursive(std::vector & report, UModelIndex index, UINT32 level = 0); - + USTATUS generateRecursive(std::vector & report, const UModelIndex & index, const UINT32 level = 0); }; #endif // FFSREPORT_H + diff --git a/common/filesystem.cpp b/common/filesystem.cpp new file mode 100644 index 0000000..766ee5c --- /dev/null +++ b/common/filesystem.cpp @@ -0,0 +1,113 @@ +/* filesystem.c + +Copyright (c) 2023, Nikolaj Schlej. All rights reserved. +This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +*/ + +#include "filesystem.h" +#include +#include + +bool readFileIntoBuffer(const UString& inPath, UByteArray& buf) +{ + if (!isExistOnFs(inPath)) + return false; + + std::ifstream inputFile(inPath.toLocal8Bit(), std::ios::in | std::ios::binary); + if (!inputFile) + return false; + std::vector buffer(std::istreambuf_iterator(inputFile), + (std::istreambuf_iterator())); + inputFile.close(); + + buf = buffer; + + return true; +} + +#if defined(_WIN32) || defined(__MINGW32__) +#include +#include +bool isExistOnFs(const UString & path) +{ + struct _stat buf; + return (_stat(path.toLocal8Bit(), &buf) == 0); +} + +bool makeDirectory(const UString & dir) +{ + return (_mkdir(dir.toLocal8Bit()) == 0); +} + +bool changeDirectory(const UString & dir) +{ + return (_chdir(dir.toLocal8Bit()) == 0); +} + +bool removeDirectory(const UString & dir) +{ + int r = _rmdir(dir.toLocal8Bit()); + // Hack: unlike *nix, Windows does not permit deleting current directories + if (r < 0 && errno == EACCES && changeDirectory(dir + UString("/../"))) { + return (_rmdir(dir.toLocal8Bit()) == 0); + } + return (r == 0); +} + +UString getAbsPath(const UString & path) +{ + char * abs = (char*)calloc(0x8000, 1); + UString new_path; + if (_fullpath(abs, path.toLocal8Bit(), 0x8000)) + new_path = UString(abs); + else + new_path = path; + free(abs); + return new_path; +} +#else +#include +#include +#if !defined(ACCESSPERMS) +#define ACCESSPERMS (S_IRWXU|S_IRWXG|S_IRWXO) +#endif +bool isExistOnFs(const UString & path) +{ + struct stat buf; + return (stat(path.toLocal8Bit(), &buf) == 0); +} + +bool makeDirectory(const UString & dir) +{ + return (mkdir(dir.toLocal8Bit(), ACCESSPERMS) == 0); +} + +bool removeDirectory(const UString & dir) +{ + return (rmdir(dir.toLocal8Bit()) == 0); +} + +bool changeDirectory(const UString & dir) +{ + return (chdir(dir.toLocal8Bit()) == 0); +} + +UString getAbsPath(const UString & path) { + char * abs = realpath(path.toLocal8Bit(), nullptr); + // Last is a non-standard extension for non-existent files + UString new_path; + if (abs) + new_path = UString(abs); + else + new_path = path; + free(abs); + return new_path; +} +#endif diff --git a/common/filesystem.h b/common/filesystem.h new file mode 100644 index 0000000..fbad5f3 --- /dev/null +++ b/common/filesystem.h @@ -0,0 +1,27 @@ +/* filesystem.h + +Copyright (c) 2023, Nikolaj Schlej. All rights reserved. +This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +*/ + +#ifndef FILESYSTEM_H +#define FILESYSTEM_H + +#include "ustring.h" +#include "ubytearray.h" + +bool isExistOnFs(const UString& path); +bool makeDirectory(const UString& dir); +bool changeDirectory(const UString& dir); +bool removeDirectory(const UString& dir); +bool readFileIntoBuffer(const UString& inPath, UByteArray& buf); +UString getAbsPath(const UString& path); + +#endif diff --git a/common/fit.h b/common/fit.h deleted file mode 100644 index 81d73de..0000000 --- a/common/fit.h +++ /dev/null @@ -1,70 +0,0 @@ -/* fit.h - -Copyright (c) 2015, Nikolaj Schlej. All rights reserved. -This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -*/ - -#ifndef FIT_H -#define FIT_H - -#include "basetypes.h" -#include "ubytearray.h" - -// Make sure we use right packing rules -#pragma pack(push, 1) - -// Memory address of a pointer to FIT, 40h back from the end of flash chip -#define FIT_POINTER_OFFSET 0x40 - -// Entry types -#define FIT_TYPE_HEADER 0x00 -#define FIT_TYPE_MICROCODE 0x01 -#define FIT_TYPE_BIOS_AC_MODULE 0x02 -#define FIT_TYPE_BIOS_INIT_MODULE 0x07 -#define FIT_TYPE_TPM_POLICY 0x08 -#define FIT_TYPE_BIOS_POLICY_DATA 0x09 -#define FIT_TYPE_TXT_CONF_POLICY 0x0A -#define FIT_TYPE_AC_KEY_MANIFEST 0x0B -#define FIT_TYPE_AC_BOOT_POLICY 0x0C -#define FIT_TYPE_EMPTY 0x7F - -#define FIT_HEADER_VERSION 0x0100 -#define FIT_MICROCODE_VERSION 0x0100 - -const UByteArray FIT_SIGNATURE -("\x5F\x46\x49\x54\x5F\x20\x20\x20", 8); - -typedef struct FIT_ENTRY_ { - UINT64 Address; - UINT32 Size; - UINT16 Version; - UINT8 Type; - UINT8 Checksum; -} FIT_ENTRY; - -typedef struct INTEL_MICROCODE_HEADER_ { - UINT32 Version; - UINT32 Revision; - UINT32 Date; - UINT32 CpuSignature; - UINT32 Checksum; - UINT32 LoaderRevision; - UINT32 CpuFlags; - UINT32 DataSize; - UINT32 TotalSize; - UINT8 Reserved[12]; -} INTEL_MICROCODE_HEADER; - -#define INTEL_MICROCODE_HEADER_VERSION 0x00000001 -#define INTEL_MICROCODE_HEADER_RESERVED_BYTE 0x00 -#define INTEL_MICROCODE_HEADER_SIZES_VALID(ptr) (((INTEL_MICROCODE_HEADER*)ptr)->TotalSize - ((INTEL_MICROCODE_HEADER*)ptr)->DataSize == sizeof(INTEL_MICROCODE_HEADER)) - -#pragma pack(pop) - -#endif // FIT_H diff --git a/common/fitparser.cpp b/common/fitparser.cpp new file mode 100644 index 0000000..641d07f --- /dev/null +++ b/common/fitparser.cpp @@ -0,0 +1,1189 @@ +/* fitparser.cpp + + Copyright (c) 2022, Nikolaj Schlej. All rights reserved. + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + */ +#include "fitparser.h" + +#ifdef U_ENABLE_FIT_PARSING_SUPPORT + +#include "intel_fit.h" +#include "ffs.h" +#include "parsingdata.h" +#include "types.h" +#include "utility.h" +#include "digest/sha2.h" + +#include "umemstream.h" +#include "kaitai/kaitaistream.h" +#include "generated/intel_acbp_v1.h" +#include "generated/intel_acbp_v2.h" +#include "generated/intel_keym_v1.h" +#include "generated/intel_keym_v2.h" +#include "generated/intel_acm.h" + +USTATUS FitParser::parseFit(const UModelIndex & index) +{ + // Reset parser state + fitTable.clear(); + securityInfo = ""; + bgAcmFound = false; + bgKeyManifestFound = false; + bgBootPolicyFound = false; + bgKmHash = UByteArray(); + bgBpHashSha256 = UByteArray(); + bgBpHashSha384 = UByteArray(); + + // Check sanity + if (!index.isValid()) { + return U_INVALID_PARAMETER; + } + + // Search for FIT + UModelIndex fitIndex; + UINT32 fitOffset; + findFitRecursive(index, fitIndex, fitOffset); + + // FIT not found + if (!fitIndex.isValid()) { + // Nothing to parse further + return U_SUCCESS; + } + // Explicitly set the item containing FIT as fixed + model->setFixed(fitIndex, true); + + // Special case of FIT header + UByteArray fitBody = model->body(fitIndex); + // This is safe, as we checked the size in findFitRecursive already + const INTEL_FIT_ENTRY* fitHeader = (const INTEL_FIT_ENTRY*)(fitBody.constData() + fitOffset); + + // Sanity check + UINT32 fitSize = fitHeader->Size * sizeof(INTEL_FIT_ENTRY); + if ((UINT32)fitBody.size() - fitOffset < fitSize) { + msg(usprintf("%s: not enough space to contain the whole FIT table", __FUNCTION__), fitIndex); + return U_INVALID_FIT; + } + + // Check FIT checksum, if present + if (fitHeader->ChecksumValid) { + // Calculate FIT entry checksum + UByteArray tempFIT = model->body(fitIndex).mid(fitOffset, fitSize); + INTEL_FIT_ENTRY* tempFitHeader = (INTEL_FIT_ENTRY*)tempFIT.data(); + tempFitHeader->Checksum = 0; + UINT8 calculated = calculateChecksum8((const UINT8*)tempFitHeader, fitSize); + if (calculated != fitHeader->Checksum) { + msg(usprintf("%s: invalid FIT table checksum %02Xh, should be %02Xh", __FUNCTION__, fitHeader->Checksum, calculated), fitIndex); + } + } + + // Check fit header type + if (fitHeader->Type != INTEL_FIT_TYPE_HEADER) { + msg(usprintf("%s: invalid FIT header type", __FUNCTION__), fitIndex); + return U_INVALID_FIT; + } + + // Add FIT header + std::vector currentStrings; + currentStrings.push_back(UString("_FIT_ ")); + currentStrings.push_back(usprintf("%08Xh", fitSize)); + currentStrings.push_back(usprintf("%04Xh", fitHeader->Version)); + currentStrings.push_back(usprintf("%02Xh", fitHeader->Checksum)); + currentStrings.push_back(fitEntryTypeToUString(fitHeader->Type)); + currentStrings.push_back(UString()); // Empty info for FIT header + fitTable.push_back(std::pair, UModelIndex>(currentStrings, fitIndex)); + + // Process all other entries + UModelIndex acmIndex; + UModelIndex kmIndex; + UModelIndex bpIndex; + for (UINT32 i = 1; i < fitHeader->Size; i++) { + currentStrings.clear(); + UString info; + UModelIndex itemIndex; + const INTEL_FIT_ENTRY* currentEntry = fitHeader + i; + UINT32 currentEntrySize = currentEntry->Size; + + // Check sanity + if (currentEntry->Type == INTEL_FIT_TYPE_HEADER) { + msg(usprintf("%s: second FIT header found, the table is damaged", __FUNCTION__), fitIndex); + return U_INVALID_FIT; + } + + // Special case of version 0 entries for TXT and TPM policies + if ((currentEntry->Type == INTEL_FIT_TYPE_TXT_POLICY || currentEntry->Type == INTEL_FIT_TYPE_TPM_POLICY) + && currentEntry->Version == 0) { + const INTEL_FIT_INDEX_IO_ADDRESS* policy = (const INTEL_FIT_INDEX_IO_ADDRESS*)currentEntry; + info += usprintf("Index: %04Xh, BitPosition: %02Xh, AccessWidth: %02Xh, DataRegAddr: %04Xh, IndexRegAddr: %04Xh", + policy->Index, + policy->BitPosition, + policy->AccessWidthInBytes, + policy->DataRegisterAddress, + policy->IndexRegisterAddress); + } + else if (currentEntry->Address > ffsParser->addressDiff && currentEntry->Address < 0xFFFFFFFFUL) { // Only elements in the image need to be parsed + UINT32 currentEntryBase = (UINT32)(currentEntry->Address - ffsParser->addressDiff); + itemIndex = model->findByBase(currentEntryBase); + if (itemIndex.isValid()) { + UByteArray item = model->header(itemIndex) + model->body(itemIndex) + model->tail(itemIndex); + UINT32 localOffset = currentEntryBase - model->base(itemIndex); + + switch (currentEntry->Type) { + case INTEL_FIT_TYPE_MICROCODE: + (void)parseFitEntryMicrocode(item, localOffset, itemIndex, info, currentEntrySize); + break; + + case INTEL_FIT_TYPE_STARTUP_AC_MODULE: + (void)parseFitEntryAcm(item, localOffset, itemIndex, info, currentEntrySize); + acmIndex = itemIndex; + break; + + case INTEL_FIT_TYPE_BOOT_GUARD_KEY_MANIFEST: + (void)parseFitEntryBootGuardKeyManifest(item, localOffset, itemIndex, info, currentEntrySize); + kmIndex = itemIndex; + break; + + case INTEL_FIT_TYPE_BOOT_GUARD_BOOT_POLICY: + (void)parseFitEntryBootGuardBootPolicy(item, localOffset, itemIndex, info, currentEntrySize); + bpIndex = itemIndex; + break; + + default: + // Do nothing + break; + } + } + else { + msg(usprintf("%s: FIT entry #%u not found in the image", __FUNCTION__, i), fitIndex); + } + } + + // Explicitly set the item referenced by FIT as fixed + if (itemIndex.isValid()) { + model->setFixed(itemIndex, true); + } + + // Add entry to fitTable + currentStrings.push_back(usprintf("%016" PRIX64 "h", currentEntry->Address)); + currentStrings.push_back(usprintf("%08Xh", currentEntrySize)); + currentStrings.push_back(usprintf("%04Xh", currentEntry->Version)); + currentStrings.push_back(usprintf("%02Xh", currentEntry->Checksum)); + currentStrings.push_back(fitEntryTypeToUString(currentEntry->Type)); + currentStrings.push_back(info); + fitTable.push_back(std::pair, UModelIndex>(currentStrings, itemIndex)); + } + + // Perform validation of BootGuard components + if (bgAcmFound) { + if (!bgKeyManifestFound) { + msg(usprintf("%s: startup ACM found, but KeyManifest is not", __FUNCTION__), acmIndex); + } + else if (!bgBootPolicyFound) { + msg(usprintf("%s: startup ACM and Key Manifest found, Boot Policy is not", __FUNCTION__), kmIndex); + } + else { + // Check key hashes + if (!bgKmHash.isEmpty() + && !(bgKmHash == bgBpHashSha256 || bgKmHash == bgBpHashSha384)) { + msg(usprintf("%s: Boot Policy key hash stored in Key Manifest differs from the hash of the public key stored in Boot Policy", __FUNCTION__), bpIndex); + return U_SUCCESS; + } + } + } + + return U_SUCCESS; +} + +void FitParser::findFitRecursive(const UModelIndex & index, UModelIndex & found, UINT32 & fitOffset) +{ + // Sanity check + if (!index.isValid()) { + return; + } + + // Process child items + for (int i = 0; i < model->rowCount(index); i++) { + findFitRecursive(index.model()->index(i, 0, index), found, fitOffset); + + if (found.isValid()) { + // Found it, no need to process further + return; + } + } + + // Check for all FIT signatures in item body + UByteArray lastVtfBody = model->body(ffsParser->lastVtf); + UINT64 fitSignatureValue = INTEL_FIT_SIGNATURE; + UByteArray fitSignature((const char*)&fitSignatureValue, sizeof(fitSignatureValue)); + UINT32 storedFitAddress = *(const UINT32*)(lastVtfBody.constData() + lastVtfBody.size() - INTEL_FIT_POINTER_OFFSET); + for (INT32 offset = (INT32)model->body(index).indexOf(fitSignature); + offset >= 0; + offset = (INT32)model->body(index).indexOf(fitSignature, offset + 1)) { + // FIT candidate found, calculate its physical address + UINT32 fitAddress = (UINT32)(model->base(index) + (UINT32)ffsParser->addressDiff + model->header(index).size() + (UINT32)offset); + + // Check FIT address to be stored in the last VTF + if (fitAddress == storedFitAddress) { + // Valid FIT table must have at least two entries + if ((UINT32)model->body(index).size() < offset + 2*sizeof(INTEL_FIT_ENTRY)) { + msg(usprintf("%s: FIT table candidate found, too small to contain real FIT", __FUNCTION__), index); + } + else { + // Real FIT found + found = index; + fitOffset = offset; + msg(usprintf("%s: real FIT table found at physical address %08Xh", __FUNCTION__, fitAddress), found); + break; + } + } + else if (model->rowCount(index) == 0) { // Show messages only to leaf items + msg(usprintf("%s: FIT table candidate found, but not referenced from the last VTF", __FUNCTION__), index); + } + } +} + +USTATUS FitParser::parseFitEntryMicrocode(const UByteArray & microcode, const UINT32 localOffset, const UModelIndex & parent, UString & info, UINT32 &realSize) +{ + U_UNUSED_PARAMETER(parent); + if ((UINT32)microcode.size() - localOffset < sizeof(INTEL_MICROCODE_HEADER)) { + return U_INVALID_MICROCODE; + } + + const INTEL_MICROCODE_HEADER* ucodeHeader = (const INTEL_MICROCODE_HEADER*)(microcode.constData() + localOffset); + if (!ffsParser->microcodeHeaderValid(ucodeHeader)) { + return U_INVALID_MICROCODE; + } + + if ((UINT32)microcode.size() - localOffset < ucodeHeader->TotalSize) { + return U_INVALID_MICROCODE; + } + + // Valid microcode found + info = usprintf("CpuSignature: %08Xh, Revision: %08Xh, Date: %02X.%02X.%04X", + ucodeHeader->ProcessorSignature, + ucodeHeader->UpdateRevision, + ucodeHeader->DateDay, + ucodeHeader->DateMonth, + ucodeHeader->DateYear); + realSize = ucodeHeader->TotalSize; + + return U_SUCCESS; +} + +USTATUS FitParser::parseFitEntryAcm(const UByteArray & acm, const UINT32 localOffset, const UModelIndex & parent, UString & info, UINT32 &realSize) +{ + try { + umemstream is(acm.constData(), acm.size()); + is.seekg(localOffset, is.beg); + kaitai::kstream ks(&is); + intel_acm_t parsed(&ks); + intel_acm_t::header_t* header = parsed.header(); + + realSize = header->module_size(); + + // Check header version to be of a known value + if (header->header_version() != intel_acm_t::KNOWN_HEADER_VERSION_V0_0 + && header->header_version() != intel_acm_t::KNOWN_HEADER_VERSION_V3_0) { + msg(usprintf("%s: Intel ACM with unknown header version %08Xh found", __FUNCTION__, header->header_version()), parent); + } + + // Valid ACM found + info = usprintf("LocalOffset: %08Xh, EntryPoint: %08Xh, ACM SVN: %04Xh, Date: %02X.%02X.%04X", + localOffset, + header->entry_point(), + header->acm_svn(), + header->date_day(), + header->date_month(), + header->date_year()); + + // Populate ACM info + UString acmInfo; + if (header->module_subtype() == intel_acm_t::MODULE_SUBTYPE_TXT) { + acmInfo = "TXT ACM "; + } + else if(header->module_subtype() == intel_acm_t::MODULE_SUBTYPE_STARTUP) { + acmInfo = "Startup ACM "; + } + else if (header->module_subtype() == intel_acm_t::MODULE_SUBTYPE_BOOT_GUARD) { + acmInfo = "BootGuard ACM "; + } + else { + acmInfo = usprintf("Unknown ACM (%04Xh)", header->module_subtype()); + msg(usprintf("%s: Intel ACM with unknown subtype %04Xh found", __FUNCTION__, header->module_subtype()), parent); + } + + acmInfo += usprintf("found at base %Xh\n" + "ModuleType: %04Xh\n" + "ModuleSubtype: %04Xh\n" + "HeaderSize: %08Xh\n" + "HeaderVersion: %08Xh\n" + "ChipsetId: %04Xh\n" + "Flags: %04Xh\n" + "ModuleVendor: %04Xh\n" + "Date: %02X.%02X.%04X\n" + "ModuleSize: %08Xh\n" + "AcmSvn: %04Xh\n" + "SeSvn: %04Xh\n" + "CodeControlFlags: %08Xh\n" + "ErrorEntryPoint: %08Xh\n" + "GdtMax: %08Xh\n" + "GdtBase: %08Xh\n" + "SegmentSel: %08Xh\n" + "EntryPoint: %08Xh\n" + "KeySize: %08Xh\n" + "ScratchSpaceSize: %08Xh\n", + model->base(parent) + localOffset, + header->module_type(), + header->module_subtype(), + header->header_size() * (UINT32)sizeof(UINT32), + header->header_version(), + header->chipset_id(), + header->flags(), + header->module_vendor(), + header->date_day(), header->date_month(), header->date_year(), + header->module_size() * (UINT32)sizeof(UINT32), + header->acm_svn(), + header->se_svn(), + header->code_control_flags(), + header->error_entry_point(), + header->gdt_max(), + header->gdt_base(), + header->segment_sel(), + header->entry_point(), + header->key_size() * (UINT32)sizeof(UINT32), + header->scratch_space_size() * (UINT32)sizeof(UINT32)); + + // Add RsaPublicKey + if (header->_is_null_rsa_exponent() == false) { + acmInfo += usprintf("ACM RSA Public Key Exponent: %Xh\n", header->rsa_exponent()); + } + else { + acmInfo += usprintf("ACM RSA Public Key Exponent: %Xh\n", INTEL_ACM_HARDCODED_RSA_EXPONENT); + } + acmInfo += usprintf("ACM RSA Public Key:"); + for (UINT32 i = 0; i < header->rsa_public_key().size(); i++) { + if (i % 32 == 0) acmInfo += "\n"; + acmInfo += usprintf("%02X", (UINT8)header->rsa_public_key().at(i)); + } + acmInfo += "\n"; + + // Add RsaSignature + acmInfo += UString("ACM RSA Signature:"); + for (UINT32 i = 0; i < header->rsa_signature().size(); i++) { + if (i % 32 == 0) acmInfo +="\n"; + acmInfo += usprintf("%02X", (UINT8)header->rsa_signature().at(i)); + } + acmInfo += "\n"; + + securityInfo += acmInfo + "\n"; + bgAcmFound = true; + return U_SUCCESS; + } + catch (...) { + msg(usprintf("%s: unable to parse ACM", __FUNCTION__), parent); + return U_INVALID_ACM; + } +} + +USTATUS FitParser::parseFitEntryBootGuardKeyManifest(const UByteArray & keyManifest, const UINT32 localOffset, const UModelIndex & parent, UString & info, UINT32 &realSize) +{ + U_UNUSED_PARAMETER(realSize); + + // v1 + try { + umemstream is(keyManifest.constData(), keyManifest.size()); + is.seekg(localOffset, is.beg); + kaitai::kstream ks(&is); + intel_keym_v1_t parsed(&ks); + + // Valid KM found + info = usprintf("LocalOffset: %08Xh, Version: %02Xh, KM Version: %02Xh, KM SVN: %02Xh", + localOffset, + parsed.version(), + parsed.km_version(), + parsed.km_svn()); + + // Populate KM info + UString kmInfo + = usprintf("Intel BootGuard Key manifest found at base %Xh\n" + "Tag: '__KEYM__'\n" + "Version: %02Xh\n" + "KmVersion: %02Xh\n" + "KmSvn: %02Xh\n" + "KmId: %02Xh\n", + model->base(parent) + localOffset, + parsed.version(), + parsed.km_version(), + parsed.km_svn(), + parsed.km_id()); + + // Add KM hash + kmInfo += UString("KM Hash (") + hashTypeToUString(parsed.km_hash()->hash_algorithm_id()) + "): "; + for (UINT16 j = 0; j < parsed.km_hash()->len_hash(); j++) { + kmInfo += usprintf("%02X", (UINT8) parsed.km_hash()->hash().data()[j]); + } + kmInfo += "\n"; + + // Add Key Signature + const intel_keym_v1_t::key_signature_t* key_signature = parsed.key_signature(); + kmInfo += usprintf("Key Manifest Key Signature:\n" + "Version: %02Xh\n" + "KeyId: %04Xh\n" + "SigScheme: %04Xh\n", + key_signature->version(), + key_signature->key_id(), + key_signature->sig_scheme()); + + // Add PubKey + kmInfo += usprintf("Key Manifest Public Key Exponent: %Xh\n", key_signature->public_key()->exponent()); + kmInfo += usprintf("Key Manifest Public Key:"); + for (UINT16 i = 0; i < (UINT16)key_signature->public_key()->modulus().length(); i++) { + if (i % 32 == 0) kmInfo += UString("\n"); + kmInfo += usprintf("%02X", (UINT8)key_signature->public_key()->modulus().at(i)); + } + kmInfo += "\n"; + + // One of those hashes is what's getting written into Field Programmable Fuses + // Calculate the hashes of public key modulus only + UINT8 hash[SHA384_HASH_SIZE] = {}; + sha256(key_signature->public_key()->modulus().data(), key_signature->public_key()->modulus().length(), hash); + kmInfo += usprintf("Key Manifest Public Key Hash (Modulus Only, SHA256): "); + for (UINT8 i = 0; i < SHA256_HASH_SIZE; i++) { + kmInfo += usprintf("%02X", hash[i]); + } + kmInfo += "\n"; + sha384(key_signature->public_key()->modulus().data(), key_signature->public_key()->modulus().length(), hash); + kmInfo += usprintf("Key Manifest Public Key Hash (Modulus Only, SHA384): "); + for (UINT8 i = 0; i < SHA384_HASH_SIZE; i++) { + kmInfo += usprintf("%02X", hash[i]); + } + kmInfo += "\n"; + // Calculate the hashes of public key modulus + exponent + UByteArray dataToHash; + dataToHash += UByteArray(key_signature->public_key()->modulus().data(), key_signature->public_key()->modulus().length()); + UINT32 exponent = key_signature->public_key()->exponent(); + dataToHash += UByteArray((const char*)&exponent, sizeof(exponent)); + sha256(dataToHash.constData(), dataToHash.size(), hash); + kmInfo += usprintf("Key Manifest Public Key Hash (Modulus+Exponent, SHA256): "); + for (UINT8 i = 0; i < SHA256_HASH_SIZE; i++) { + kmInfo += usprintf("%02X", hash[i]); + } + kmInfo += "\n"; + sha384(dataToHash.constData(), dataToHash.size(), hash); + kmInfo += usprintf("Key Manifest Public Key Hash (Modulus+Exponent, SHA384): "); + for (UINT8 i = 0; i < SHA384_HASH_SIZE; i++) { + kmInfo += usprintf("%02X", hash[i]); + } + kmInfo += "\n"; + + // Add Signature + kmInfo += UString("Key Manifest Signature: "); + for (UINT16 i = 0; i < (UINT16)key_signature->signature()->signature().length(); i++) { + if (i % 32 == 0) kmInfo += UString("\n"); + kmInfo += usprintf("%02X", (UINT8)key_signature->signature()->signature().at(i)); + } + kmInfo += "\n"; + + securityInfo += kmInfo + "\n"; + bgKeyManifestFound = true; + return U_SUCCESS; + } + catch (...) { + // Do nothing here, will try parsing as v2 next + } + + // v2 + try { + umemstream is(keyManifest.constData(), keyManifest.size()); + is.seekg(localOffset, is.beg); + kaitai::kstream ks(&is); + intel_keym_v2_t parsed(&ks); + intel_keym_v2_t::header_t* header = parsed.header(); + + // Valid KM found + info = usprintf("LocalOffset: %08Xh, Version: %02Xh, KM Version: %02Xh, KM SVN: %02Xh", + localOffset, + header->version(), + parsed.km_version(), + parsed.km_svn()); + + // Populate KM info + UString kmInfo + = usprintf("Intel BootGuard Key manifest found at base %Xh\n" + "Tag: '__KEYM__'\n" + "Version: %02Xh\n" + "KmVersion: %02Xh\n" + "KmSvn: %02Xh\n" + "KmId: %02Xh\n" + "KeySignatureOffset: %04Xh\n" + "FPFHashAlgorithmId: %04Xh\n" + "HashCount: %04Xh\n", + model->base(parent) + localOffset, + header->version(), + parsed.km_version(), + parsed.km_svn(), + parsed.km_id(), + parsed.key_signature_offset(), + parsed.fpf_hash_algorithm_id(), + parsed.num_km_hashes()); + + // Add KM hashes + if (parsed.num_km_hashes() == 0) { + kmInfo += UString("KM Hashes: N/A\n"); + msg(usprintf("%s: Key Manifest without KM hashes", __FUNCTION__), parent); + } + else { + kmInfo += UString("KM Hashes:\n"); + for (UINT16 i = 0; i < parsed.num_km_hashes(); i++) { + const auto & current_km_hash = parsed.km_hashes()->at(i); + + // Add KM hash + kmInfo += usprintf("UsageFlags: %016" PRIX64 "h, ", current_km_hash->usage_flags()) + hashTypeToUString(current_km_hash->hash_algorithm_id()) + ": "; + for (UINT16 j = 0; j < current_km_hash->len_hash(); j++) { + kmInfo += usprintf("%02X", (UINT8)current_km_hash->hash().data()[j]); + } + kmInfo += "\n"; + + if (current_km_hash->usage_flags() == intel_keym_v2_t::KM_USAGE_FLAGS_BOOT_POLICY_MANIFEST) { + bgKmHash = UByteArray((const char*)current_km_hash->hash().data(), current_km_hash->hash().size()); + } + } + } + + // Add Key Signature + const intel_keym_v2_t::key_signature_t* key_signature = parsed.key_signature(); + kmInfo += usprintf("Key Manifest Key Signature:\n" + "Version: %02Xh\n" + "KeyId: %04Xh\n" + "SigScheme: %04Xh\n", + key_signature->version(), + key_signature->key_id(), + key_signature->sig_scheme()); + + // Add PubKey + kmInfo += usprintf("Key Manifest Public Key Exponent: %Xh\n", key_signature->public_key()->exponent()); + kmInfo += usprintf("Key Manifest Public Key:"); + for (UINT16 i = 0; i < (UINT16)key_signature->public_key()->modulus().length(); i++) { + if (i % 32 == 0) kmInfo += UString("\n"); + kmInfo += usprintf("%02X", (UINT8)key_signature->public_key()->modulus().at(i)); + } + kmInfo += "\n"; + + // One of those hashes is what's getting written into Field Programmable Fuses + // Calculate the hashes of public key modulus only + UINT8 hash[SHA384_HASH_SIZE] = {}; + sha256(key_signature->public_key()->modulus().data(), key_signature->public_key()->modulus().length(), hash); + kmInfo += usprintf("Key Manifest Public Key Hash (Modulus Only, SHA256): "); + for (UINT8 i = 0; i < SHA256_HASH_SIZE; i++) { + kmInfo += usprintf("%02X", hash[i]); + } + kmInfo += "\n"; + sha384(key_signature->public_key()->modulus().data(), key_signature->public_key()->modulus().length(), hash); + kmInfo += usprintf("Key Manifest Public Key Hash (Modulus Only, SHA384): "); + for (UINT8 i = 0; i < SHA384_HASH_SIZE; i++) { + kmInfo += usprintf("%02X", hash[i]); + } + kmInfo += "\n"; + // Calculate the hashes of public key modulus + exponent + UByteArray dataToHash; + dataToHash += UByteArray(key_signature->public_key()->modulus().data(), key_signature->public_key()->modulus().length()); + UINT32 exponent = key_signature->public_key()->exponent(); + dataToHash += UByteArray((const char*)&exponent, sizeof(exponent)); + sha256(dataToHash.constData(), dataToHash.size(), hash); + kmInfo += usprintf("Key Manifest Public Key Hash (Modulus+Exponent, SHA256): "); + for (UINT8 i = 0; i < SHA256_HASH_SIZE; i++) { + kmInfo += usprintf("%02X", hash[i]); + } + kmInfo += "\n"; + sha384(dataToHash.constData(), dataToHash.size(), hash); + kmInfo += usprintf("Key Manifest Public Key Hash (Modulus+Exponent, SHA384): "); + for (UINT8 i = 0; i < SHA384_HASH_SIZE; i++) { + kmInfo += usprintf("%02X", hash[i]); + } + kmInfo += "\n"; + + // Add Signature + kmInfo += UString("Key Manifest Signature: "); + for (UINT16 i = 0; i < (UINT16)key_signature->signature()->signature().length(); i++) { + if (i % 32 == 0) kmInfo += UString("\n"); + kmInfo += usprintf("%02X", (UINT8)key_signature->signature()->signature().at(i)); + } + kmInfo += "\n"; + + securityInfo += kmInfo + "\n"; + bgKeyManifestFound = true; + return U_SUCCESS; + } + catch (...) { + msg(usprintf("%s: unable to parse Key Manifest", __FUNCTION__), parent); + return U_INVALID_BOOT_GUARD_KEY_MANIFEST; + } +} + +USTATUS FitParser::parseFitEntryBootGuardBootPolicy(const UByteArray & bootPolicy, const UINT32 localOffset, const UModelIndex & parent, UString & info, UINT32 &realSize) +{ + U_UNUSED_PARAMETER(realSize); + + // v1 + try { + umemstream is(bootPolicy.constData(), bootPolicy.size()); + is.seekg(localOffset, is.beg); + kaitai::kstream ks(&is); + intel_acbp_v1_t parsed(&ks); + + // Valid BPM found + info = usprintf("LocalOffset: %08Xh, Version: %02Xh, BP SVN: %02Xh, ACM SVN: %02Xh", + localOffset, + parsed.version(), + parsed.bp_svn(), + parsed.acm_svn()); + + UString bpInfo + = usprintf("Intel BootGuard Boot Policy Manifest found at base %Xh\n" + "StructureId: '__ACBP__'\n" + "Version: %02Xh\n" + "BPMRevision: %02Xh\n" + "BPSVN: %02Xh\n" + "ACMSVN: %02Xh\n" + "NEMDataSize: %04Xh\n", + model->base(parent) + localOffset, + parsed.version(), + parsed.bpm_revision(), + parsed.bp_svn(), + parsed.acm_svn(), + parsed.nem_data_size()); + + bpInfo += UString("Boot Policy Elements:\n"); + for (const auto & element : *parsed.elements()) { + const auto & element_header = element->header(); + + UINT64 structure_id = (UINT64) element_header->structure_id(); + const char* structure_id_bytes = (const char*)&structure_id; + + bpInfo += usprintf("StructureId: '%c%c%c%c%c%c%c%c'\n" + "Version: %02Xh\n", + structure_id_bytes[0], + structure_id_bytes[1], + structure_id_bytes[2], + structure_id_bytes[3], + structure_id_bytes[4], + structure_id_bytes[5], + structure_id_bytes[6], + structure_id_bytes[7], + element_header->version()); + + // IBBS + if (element->_is_null_ibbs_body() == false) { + const intel_acbp_v1_t::ibbs_body_t* ibbs_body = element->ibbs_body(); + + // Valid IBBS element found + bpInfo += usprintf("Flags: %08Xh\n" + "MchBar: %016" PRIX64 "h\n" + "VtdBar: %016" PRIX64 "h\n" + "DmaProtectionBase0: %08Xh\n" + "DmaProtectionLimit0: %08Xh\n" + "DmaProtectionBase1: %016" PRIX64 "h\n" + "DmaProtectionLimit1: %016" PRIX64 "h\n" + "IbbEntryPoint: %08Xh\n" + "IbbSegmentsCount: %02Xh\n", + ibbs_body->flags(), + ibbs_body->mch_bar(), + ibbs_body->vtd_bar(), + ibbs_body->dma_protection_base0(), + ibbs_body->dma_protection_limit0(), + ibbs_body->dma_protection_base1(), + ibbs_body->dma_protection_limit1(), + ibbs_body->ibb_entry_point(), + ibbs_body->num_ibb_segments()); + + // Check for non-empty PostIbbHash + if (ibbs_body->post_ibb_hash()->len_hash() == 0) { + bpInfo += UString("PostIBB Hash: N/A\n"); + } + else { + // Add postIbbHash protected range + UByteArray postIbbHash(ibbs_body->post_ibb_hash()->hash().data(), ibbs_body->post_ibb_hash()->len_hash()); + if (postIbbHash.count('\x00') != postIbbHash.size() + && postIbbHash.count('\xFF') != postIbbHash.size()) { + PROTECTED_RANGE range = {}; + range.Type = PROTECTED_RANGE_INTEL_BOOT_GUARD_POST_IBB; + range.AlgorithmId = ibbs_body->post_ibb_hash()->hash_algorithm_id(); + range.Hash = postIbbHash; + ffsParser->protectedRanges.push_back(range); + } + + // Add PostIbbHash + bpInfo += UString("PostIBB Hash (") + hashTypeToUString(ibbs_body->post_ibb_hash()->hash_algorithm_id()) + "): "; + for (UINT16 i = 0; i < ibbs_body->post_ibb_hash()->len_hash(); i++) { + bpInfo += usprintf("%02X", (UINT8)ibbs_body->post_ibb_hash()->hash().data()[i]); + } + bpInfo += "\n"; + } + + // Add IbbHash + bpInfo += UString("IBB Hash (") + hashTypeToUString(ibbs_body->ibb_hash()->hash_algorithm_id()) + "): "; + for (UINT16 j = 0; j < ibbs_body->ibb_hash()->len_hash(); j++) { + bpInfo += usprintf("%02X", (UINT8)ibbs_body->ibb_hash()->hash().data()[j]); + } + bpInfo += "\n"; + + // Check for non-empty IbbSegments + if (ibbs_body->num_ibb_segments() == 0) { + bpInfo += UString("IBB Segments: N/A\n"); + msg(usprintf("%s: Boot Policy without IBB segments", __FUNCTION__), parent); + } + else { + bpInfo += UString("IBB Segments:\n"); + for (UINT8 i = 0; i < ibbs_body->num_ibb_segments(); i++) { + const auto & current_segment = ibbs_body->ibb_segments()->at(i); + + bpInfo += usprintf("Flags: %04Xh, Address: %08Xh, Size: %08Xh\n", + current_segment->flags(), + current_segment->base(), + current_segment->size()); + + if (current_segment->flags() == intel_acbp_v1_t::IBB_SEGMENT_TYPE_IBB + && current_segment->base() != 0xFFFFFFFF && current_segment->size() != 0 && current_segment->size() != 0xFFFFFFFF) { + PROTECTED_RANGE range = {}; + range.Offset = current_segment->base(); + range.Size = current_segment->size(); + range.AlgorithmId = TCG_HASH_ALGORITHM_ID_SHA256; + range.Type = PROTECTED_RANGE_INTEL_BOOT_GUARD_IBB; + ffsParser->protectedRanges.push_back(range); + } + } + } + } + // PMDA + else if (element->_is_null_pmda_body() == false) { + intel_acbp_v1_t::pmda_body_t* pmda_body = element->pmda_body(); + + // Valid Microsoft PMDA element found + bpInfo += usprintf("TotalSize: %04Xh\n" + "Version: %08Xh\n" + "NumEntries: %08Xh\n", + pmda_body->total_size(), + pmda_body->version(), + pmda_body->num_entries()); + if (pmda_body->num_entries() == 0) { + bpInfo += UString("PMDA Entries: N/A\n"); + } + else { + bpInfo += UString("PMDA Entries:\n"); + // v1 entries + if (pmda_body->_is_null_entries_v1() == false) { + for (UINT32 i = 0; i < pmda_body->num_entries(); i++) { + const auto & current_element = pmda_body->entries_v1()->at(i); + + // Add element + bpInfo += usprintf("Address: %08Xh, Size: %08Xh\n", + current_element->base(), + current_element->size()); + + // Add hash + bpInfo += "SHA256: "; + for (UINT16 j = 0; j < (UINT16)current_element->hash().size(); j++) { + bpInfo += usprintf("%02X", (UINT8)current_element->hash().data()[j]); + } + bpInfo += "\n"; + + // Add protected range + if (current_element->base() != 0xFFFFFFFF && current_element->size() != 0 && current_element->size() != 0xFFFFFFFF) { + PROTECTED_RANGE range = {}; + range.Offset = current_element->base(); + range.Size = current_element->size(); + range.Type = PROTECTED_RANGE_VENDOR_HASH_MICROSOFT_PMDA; + range.AlgorithmId = TCG_HASH_ALGORITHM_ID_SHA256; + range.Hash = UByteArray(current_element->hash().data(), current_element->hash().size()); + ffsParser->protectedRanges.push_back(range); + } + } + } + // v2 entries + else if (pmda_body->_is_null_entries_v2() == false) { + for (UINT32 i = 0; i < pmda_body->num_entries(); i++) { + const auto & current_element = pmda_body->entries_v2()->at(i); + + // Add element + bpInfo += usprintf("Address: %08Xh, Size: %08Xh\n", + current_element->base(), + current_element->size()); + + // Add hash + bpInfo += hashTypeToUString(current_element->hash()->hash_algorithm_id()) + ": "; + for (UINT16 j = 0; j < (UINT16)current_element->hash()->hash().size(); j++) { + bpInfo += usprintf("%02X", (UINT8)current_element->hash()->hash().data()[j]); + } + bpInfo += "\n"; + + // Add protected range + if (current_element->base() != 0xFFFFFFFF && current_element->size() != 0 && current_element->size() != 0xFFFFFFFF) { + PROTECTED_RANGE range = {}; + range.Offset = current_element->base(); + range.Size = current_element->size(); + range.Type = PROTECTED_RANGE_VENDOR_HASH_MICROSOFT_PMDA; + range.AlgorithmId = current_element->hash()->hash_algorithm_id(); + range.Hash = UByteArray(current_element->hash()->hash().data(), current_element->hash()->hash().size()); + ffsParser->protectedRanges.push_back(range); + } + } + } + } + } + // PMSG + else if (element->_is_null_pmsg_body() == false) { + const intel_acbp_v1_t::pmsg_body_t* key_signature = element->pmsg_body(); + bpInfo += usprintf("Boot Policy Key Signature:\n" + "Version: %02Xh\n" + "KeyId: %04Xh\n" + "SigScheme: %04Xh\n", + key_signature->version(), + key_signature->key_id(), + key_signature->sig_scheme()); + + // Add PubKey + bpInfo += usprintf("Boot Policy Public Key Exponent: %Xh\n", key_signature->public_key()->exponent()); + bpInfo += usprintf("Boot Policy Public Key:"); + for (UINT16 i = 0; i < (UINT16)key_signature->public_key()->modulus().length(); i++) { + if (i % 32 == 0) bpInfo += UString("\n"); + bpInfo += usprintf("%02X", (UINT8)key_signature->public_key()->modulus().at(i)); + } + bpInfo += "\n"; + + // Calculate and add PubKey hashes + UINT8 hash[SHA384_HASH_SIZE]; + // SHA256 + sha256(key_signature->public_key()->modulus().data(), key_signature->public_key()->modulus().length() , hash); + bpInfo += UString("Boot Policy Public Key Hash (SHA256): "); + for (UINT8 i = 0; i < SHA256_HASH_SIZE; i++) { + bpInfo += usprintf("%02X", hash[i]); + } + bpInfo += "\n"; + bgBpHashSha256 = UByteArray((const char*)hash, SHA256_HASH_SIZE); + // SHA384 + sha384(key_signature->public_key()->modulus().data(), key_signature->public_key()->modulus().length() , hash); + bpInfo += UString("Boot Policy Public Key Hash (SHA384): "); + for (UINT8 i = 0; i < SHA384_HASH_SIZE; i++) { + bpInfo += usprintf("%02X", hash[i]); + } + bpInfo += "\n"; + bgBpHashSha384 = UByteArray((const char*)hash, SHA384_HASH_SIZE); + + // Add Signature + bpInfo += UString("Boot Policy Signature: "); + for (UINT16 i = 0; i < (UINT16)key_signature->signature()->signature().length(); i++) { + if (i % 32 == 0) bpInfo += UString("\n"); + bpInfo += usprintf("%02X", (UINT8)key_signature->signature()->signature().at(i)); + } + bpInfo += "\n"; + } + } + + securityInfo += bpInfo + "\n"; + bgBootPolicyFound = true; + return U_SUCCESS; + } + catch (...) { + // Do nothing here, will try parsing as v2 next + } + + // v2 + try { + umemstream is(bootPolicy.constData(), bootPolicy.size()); + is.seekg(localOffset, is.beg); + kaitai::kstream ks(&is); + intel_acbp_v2_t parsed(&ks); // This already verified the version to be >= 0x20 + // Valid BPM found + info = usprintf("LocalOffset: %08Xh, Version: %02Xh, BP SVN: %02Xh, ACM SVN: %02Xh", + localOffset, + parsed.version(), + parsed.bp_svn(), + parsed.acm_svn()); + + // Add BP header and body info + UString bpInfo + = usprintf("Intel BootGuard Boot Policy Manifest found at base %Xh\n" + "StructureId: '__ACBP__'\n" + "Version: %02Xh\n" + "HeaderSpecific: %02Xh\n" + "TotalSize: %04Xh\n" + "KeySignatureOffset: %04Xh\n" + "BPMRevision: %02Xh\n" + "BPSVN: %02Xh\n" + "ACMSVN: %02Xh\n" + "NEMDataSize: %04Xh\n", + model->base(parent) + localOffset, + parsed.version(), + parsed.header_specific(), + parsed.total_size(), + parsed.key_signature_offset(), + parsed.bpm_revision(), + parsed.bp_svn(), + parsed.acm_svn(), + parsed.nem_data_size()); + + bpInfo += UString("Boot Policy Elements:\n"); + for (const auto & element : *parsed.elements()) { + const intel_acbp_v2_t::header_t* element_header = element->header(); + + UINT64 structure_id = element_header->structure_id(); + const char* structure_id_bytes = (const char*)&structure_id; + + bpInfo += usprintf("StructureId: '%c%c%c%c%c%c%c%c'\n" + "Version: %02Xh\n" + "HeaderSpecific: %02Xh\n" + "TotalSize: %04Xh\n", + structure_id_bytes[0], + structure_id_bytes[1], + structure_id_bytes[2], + structure_id_bytes[3], + structure_id_bytes[4], + structure_id_bytes[5], + structure_id_bytes[6], + structure_id_bytes[7], + element_header->version(), + element_header->header_specific(), + element_header->total_size()); + + // IBBS + if (element->_is_null_ibbs_body() == false) { + const intel_acbp_v2_t::ibbs_body_t* ibbs_body = element->ibbs_body(); + + // Valid IBBS element found + bpInfo += usprintf("SetNumber: %02Xh\n" + "PBETValue: %02Xh\n" + "Flags: %08Xh\n" + "MchBar: %016" PRIX64 "h\n" + "VtdBar: %016" PRIX64 "h\n" + "DmaProtectionBase0: %08Xh\n" + "DmaProtectionLimit0: %08Xh\n" + "DmaProtectionBase1: %016" PRIX64 "h\n" + "DmaProtectionLimit1: %016" PRIX64 "h\n" + "IbbEntryPoint: %08Xh\n" + "IbbDigestsSize: %02Xh\n" + "IbbDigestsCount: %02Xh\n" + "IbbSegmentsCount: %02Xh\n", + ibbs_body->set_number(), + ibbs_body->pbet_value(), + ibbs_body->flags(), + ibbs_body->mch_bar(), + ibbs_body->vtd_bar(), + ibbs_body->dma_protection_base0(), + ibbs_body->dma_protection_limit0(), + ibbs_body->dma_protection_base1(), + ibbs_body->dma_protection_limit1(), + ibbs_body->ibb_entry_point(), + ibbs_body->ibb_digests_size(), + ibbs_body->num_ibb_digests(), + ibbs_body->num_ibb_segments()); + + // Check for non-empty PostIbbHash + if (ibbs_body->post_ibb_digest()->len_hash() == 0) { + bpInfo += UString("PostIBB Hash: N/A\n"); + } + else { + // Add postIbbHash protected range + UByteArray postIbbHash(ibbs_body->post_ibb_digest()->hash().data(), ibbs_body->post_ibb_digest()->len_hash()); + if (postIbbHash.count('\x00') != postIbbHash.size() + && postIbbHash.count('\xFF') != postIbbHash.size()) { + PROTECTED_RANGE range = {}; + range.Type = PROTECTED_RANGE_INTEL_BOOT_GUARD_POST_IBB; + range.AlgorithmId = ibbs_body->post_ibb_digest()->hash_algorithm_id(); + range.Hash = postIbbHash; + ffsParser->protectedRanges.push_back(range); + } + + // Add PostIbbDigest + bpInfo += UString("PostIBB Hash (") + hashTypeToUString(ibbs_body->post_ibb_digest()->hash_algorithm_id()) + "): "; + for (UINT16 i = 0; i < ibbs_body->post_ibb_digest()->len_hash(); i++) { + bpInfo += usprintf("%02X", (UINT8)ibbs_body->post_ibb_digest()->hash().data()[i]); + } + bpInfo += "\n"; + } + + // Check for non-empty ObbHash + if (ibbs_body->obb_digest() == 0) { + bpInfo += UString("OBB Hash: N/A\n"); + } + else { + // Add ObbHash + bpInfo += UString("OBB Hash (") + hashTypeToUString(ibbs_body->obb_digest()->hash_algorithm_id()) + "): "; + for (UINT16 i = 0; i < ibbs_body->obb_digest()->len_hash(); i++) { + bpInfo += usprintf("%02X", (UINT8)ibbs_body->obb_digest()->hash().data()[i]); + } + bpInfo += "\n"; + + // Add ObbHash protected range + UByteArray obbHash(ibbs_body->obb_digest()->hash().data(), ibbs_body->obb_digest()->len_hash()); + if (obbHash.count('\x00') != obbHash.size() + && obbHash.count('\xFF') != obbHash.size()) { + PROTECTED_RANGE range = {}; + range.Type = PROTECTED_RANGE_INTEL_BOOT_GUARD_OBB; + range.AlgorithmId = ibbs_body->obb_digest()->hash_algorithm_id(); + range.Hash = obbHash; + ffsParser->protectedRanges.push_back(range); + } + } + + // Check for non-empty IbbDigests + if (ibbs_body->num_ibb_digests() == 0) { + bpInfo += UString("IBB Hashes: N/A\n"); + msg(usprintf("%s: Boot Policy without IBB digests", __FUNCTION__), parent); + } + else { + bpInfo += UString("IBB Hashes:\n"); + for (UINT16 i = 0; i < ibbs_body->num_ibb_digests(); i++) { + const auto & current_hash = ibbs_body->ibb_digests()->at(i); + bpInfo += hashTypeToUString(current_hash->hash_algorithm_id()) + ": "; + for (UINT16 j = 0; j < current_hash->len_hash(); j++) { + bpInfo += usprintf("%02X", (UINT8)current_hash->hash().data()[j]); + } + bpInfo += "\n"; + } + } + + // Check for non-empty IbbSegments + if (ibbs_body->num_ibb_segments() == 0) { + bpInfo += UString("IBB Segments: N/A\n"); + msg(usprintf("%s: Boot Policy without IBB segments", __FUNCTION__), parent); + } + else { + bpInfo += UString("IBB Segments:\n"); + for (UINT8 i = 0; i < ibbs_body->num_ibb_segments(); i++) { + const auto & current_segment = ibbs_body->ibb_segments()->at(i); + + bpInfo += usprintf("Flags: %04Xh, Address: %08Xh, Size: %08Xh\n", + current_segment->flags(), + current_segment->base(), + current_segment->size()); + + if (current_segment->flags() == intel_acbp_v2_t::IBB_SEGMENT_TYPE_IBB + && current_segment->base() != 0xFFFFFFFF && current_segment->size() != 0 && current_segment->size() != 0xFFFFFFFF) { + PROTECTED_RANGE range = {}; + range.Offset = current_segment->base(); + range.Size =current_segment->size(); + range.Type = PROTECTED_RANGE_INTEL_BOOT_GUARD_IBB; + range.AlgorithmId = TCG_HASH_ALGORITHM_ID_SHA256; + ffsParser->protectedRanges.push_back(range); + } + } + } + } + // PMDA + else if (element->_is_null_pmda_body() == false) { + const intel_acbp_v2_t::pmda_body_t* pmda_body = element->pmda_body(); + + // Valid Microsoft PMDA element found + bpInfo += usprintf("TotalSize: %04Xh\n" + "Version: %08Xh\n" + "NumEntries: %08Xh\n", + pmda_body->total_size(), + pmda_body->version(), + pmda_body->num_entries()); + + if (pmda_body->num_entries() == 0) { + bpInfo += UString("PMDA Entries: N/A\n"); + } + else { + bpInfo += UString("PMDA Entries:\n"); + for (UINT32 i = 0; i < pmda_body->num_entries(); i++) { + const auto & current_entry = pmda_body->entries()->at(i); + + UINT64 entry_id = current_entry->entry_id(); + const char* entry_id_bytes = (const char*)&entry_id; + + // Add element + bpInfo += usprintf("EntryId: '%c%c%c%c', Version: %04Xh, Address: %08Xh, Size: %08Xh\n", + entry_id_bytes[0], + entry_id_bytes[1], + entry_id_bytes[2], + entry_id_bytes[3], + current_entry->version(), + current_entry->base(), + current_entry->size()); + + // Add hash + bpInfo += hashTypeToUString(current_entry->hash()->hash_algorithm_id()) + ": "; + for (UINT16 j = 0; j < current_entry->hash()->len_hash(); j++) { + bpInfo += usprintf("%02X", (UINT8)current_entry->hash()->hash().data()[j]); + } + bpInfo += "\n"; + + // Add protected range + if (current_entry->base() != 0xFFFFFFFF && current_entry->size() != 0 && current_entry->size() != 0xFFFFFFFF) { + PROTECTED_RANGE range = {}; + range.Offset = current_entry->base(); + range.Size = current_entry->size(); + range.Type = PROTECTED_RANGE_VENDOR_HASH_MICROSOFT_PMDA; + range.AlgorithmId = current_entry->hash()->hash_algorithm_id(); + range.Hash = UByteArray(current_entry->hash()->hash().data(), current_entry->hash()->hash().size()); + ffsParser->protectedRanges.push_back(range); + } + } + } + } + bpInfo += "\n"; + } + + // Add Key Signature + const intel_acbp_v2_t::key_signature_t* key_signature = parsed.key_signature(); + bpInfo += usprintf("Boot Policy Key Signature:\n" + "Version: %02Xh\n" + "KeyId: %04Xh\n" + "SigScheme: %04Xh\n", + key_signature->version(), + key_signature->key_id(), + key_signature->sig_scheme()); + + // Add PubKey + bpInfo += usprintf("Boot Policy Public Key Exponent: %Xh\n", key_signature->public_key()->exponent()); + bpInfo += usprintf("Boot Policy Public Key:"); + for (UINT16 i = 0; i < (UINT16)key_signature->public_key()->modulus().length(); i++) { + if (i % 32 == 0) bpInfo += UString("\n"); + bpInfo += usprintf("%02X", (UINT8)key_signature->public_key()->modulus().at(i)); + } + bpInfo += "\n"; + + // Calculate and add PubKey hashes + UINT8 hash[SHA384_HASH_SIZE]; + // SHA256 + sha256(key_signature->public_key()->modulus().data(), key_signature->public_key()->modulus().length() , hash); + bpInfo += UString("Boot Policy Public Key Hash (SHA256): "); + for (UINT8 i = 0; i < SHA256_HASH_SIZE; i++) { + bpInfo += usprintf("%02X", hash[i]); + } + bpInfo += "\n"; + bgBpHashSha256 = UByteArray((const char*)hash, SHA256_HASH_SIZE); + // SHA384 + sha384(key_signature->public_key()->modulus().data(), key_signature->public_key()->modulus().length() , hash); + bpInfo += UString("Boot Policy Public Key Hash (SHA384): "); + for (UINT8 i = 0; i < SHA384_HASH_SIZE; i++) { + bpInfo += usprintf("%02X", hash[i]); + } + bpInfo += "\n"; + bgBpHashSha384 = UByteArray((const char*)hash, SHA384_HASH_SIZE); + + // Add Signature + bpInfo += UString("Boot Policy Signature: "); + for (UINT16 i = 0; i < (UINT16)key_signature->signature()->signature().length(); i++) { + if (i % 32 == 0) bpInfo += UString("\n"); + bpInfo += usprintf("%02X", (UINT8)key_signature->signature()->signature().at(i)); + } + bpInfo += "\n"; + + securityInfo += bpInfo + "\n"; + bgBootPolicyFound = true; + return U_SUCCESS; + } + catch (...) { + msg(usprintf("%s: unable to parse Boot Policy", __FUNCTION__), parent); + return U_INVALID_BOOT_GUARD_BOOT_POLICY; + } +} +#endif // U_ENABLE_ME_PARSING_SUPPORT diff --git a/common/fitparser.h b/common/fitparser.h new file mode 100644 index 0000000..d0d3553 --- /dev/null +++ b/common/fitparser.h @@ -0,0 +1,100 @@ +/* fitparser.h + +Copyright (c) 2022, Nikolaj Schlej. All rights reserved. + +This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php. + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +*/ + +#ifndef FITPARSER_H +#define FITPARSER_H + +#include + +#include "basetypes.h" +#include "ustring.h" +#include "ubytearray.h" +#include "treemodel.h" +#include "intel_fit.h" +#include "intel_microcode.h" +#include "ffsparser.h" + +class FfsParser; + +#ifdef U_ENABLE_FIT_PARSING_SUPPORT +class FitParser +{ +public: + // Default constructor and destructor + FitParser(TreeModel* treeModel, FfsParser* parser) : model(treeModel), ffsParser(parser), + bgAcmFound(false), bgKeyManifestFound(false), bgBootPolicyFound(false) {} + ~FitParser() {} + + // Returns messages + std::vector > getMessages() const { return messagesVector; } + // Clears messages + void clearMessages() { messagesVector.clear(); } + + // Obtain parsed FIT table + std::vector, UModelIndex> > getFitTable() const { return fitTable; } + + // Obtain security info + UString getSecurityInfo() const { return securityInfo; } + + // FIT parsing + USTATUS parseFit(const UModelIndex & index); + +private: + TreeModel *model; + FfsParser *ffsParser; + std::vector > messagesVector; + + std::vector, UModelIndex> > fitTable; + bool bgAcmFound; + bool bgKeyManifestFound; + bool bgBootPolicyFound; + UByteArray bgKmHash; + UByteArray bgBpHashSha256; + UByteArray bgBpHashSha384; + UString securityInfo; + + void msg(const UString message, const UModelIndex index = UModelIndex()) { + messagesVector.push_back(std::pair(message, index)); + } + + void findFitRecursive(const UModelIndex & index, UModelIndex & found, UINT32 & fitOffset); + USTATUS parseFitEntryMicrocode(const UByteArray & microcode, const UINT32 localOffset, const UModelIndex & parent, UString & info, UINT32 &realSize); + USTATUS parseFitEntryAcm(const UByteArray & acm, const UINT32 localOffset, const UModelIndex & parent, UString & info, UINT32 &realSize); + USTATUS parseFitEntryBootGuardKeyManifest(const UByteArray & keyManifest, const UINT32 localOffset, const UModelIndex & parent, UString & info, UINT32 &realSize); + USTATUS parseFitEntryBootGuardBootPolicy(const UByteArray & bootPolicy, const UINT32 localOffset, const UModelIndex & parent, UString & info, UINT32 &realSize); +}; +#else // U_ENABLE_FIT_PARSING_SUPPORT +class FitParser +{ +public: + // Default constructor and destructor + FitParser(TreeModel* treeModel, FfsParser* parser) { U_UNUSED_PARAMETER(treeModel); U_UNUSED_PARAMETER(parser); } + ~FitParser() {} + + // Returns messages + std::vector > getMessages() const { return std::vector >(); } + // Clears messages + void clearMessages() {} + + // Obtain parsed FIT table + std::vector, UModelIndex> > getFitTable() const { return std::vector, UModelIndex> >(); } + + // Obtain security info + UString getSecurityInfo() const { return UString(); } + + // FIT parsing + USTATUS parseFit(const UModelIndex & index) { U_UNUSED_PARAMETER(index); return U_SUCCESS; } +}; +#endif // U_ENABLE_FIT_PARSING_SUPPORT +#endif // FITPARSER_H diff --git a/common/gbe.h b/common/gbe.h index d11230d..0130d83 100644 --- a/common/gbe.h +++ b/common/gbe.h @@ -26,7 +26,7 @@ typedef struct GBE_MAC_ADDRESS_ { #define GBE_VERSION_OFFSET 10 typedef struct GBE_VERSION_ { - UINT8 id : 4; + UINT8 id : 4; UINT8 minor : 4; UINT8 major; } GBE_VERSION; diff --git a/common/generated/ami_nvar.cpp b/common/generated/ami_nvar.cpp new file mode 100644 index 0000000..c41427c --- /dev/null +++ b/common/generated/ami_nvar.cpp @@ -0,0 +1,382 @@ +// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild + +#include "ami_nvar.h" +#include "../kaitai/exceptions.h" + +ami_nvar_t::ami_nvar_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, ami_nvar_t* p__root) : kaitai::kstruct(p__io) { + m__parent = p__parent; + m__root = this; (void)p__root; + m_entries = nullptr; + _read(); +} + +void ami_nvar_t::_read() { + m_entries = std::unique_ptr>>(new std::vector>()); + { + int i = 0; + nvar_entry_t* _; + do { + _ = new nvar_entry_t(m__io, this, m__root); + m_entries->push_back(std::move(std::unique_ptr(_))); + i++; + } while (!( ((_->signature_first() != 78) || (_io()->is_eof())) )); + } +} + +ami_nvar_t::~ami_nvar_t() { + _clean_up(); +} + +void ami_nvar_t::_clean_up() { +} + +ami_nvar_t::nvar_attributes_t::nvar_attributes_t(kaitai::kstream* p__io, ami_nvar_t::nvar_entry_t* p__parent, ami_nvar_t* p__root) : kaitai::kstruct(p__io) { + m__parent = p__parent; + m__root = p__root; + _read(); +} + +void ami_nvar_t::nvar_attributes_t::_read() { + m_valid = m__io->read_bits_int_be(1); + m_auth_write = m__io->read_bits_int_be(1); + m_hw_error_record = m__io->read_bits_int_be(1); + m_extended_header = m__io->read_bits_int_be(1); + m_data_only = m__io->read_bits_int_be(1); + m_local_guid = m__io->read_bits_int_be(1); + m_ascii_name = m__io->read_bits_int_be(1); + m_runtime = m__io->read_bits_int_be(1); +} + +ami_nvar_t::nvar_attributes_t::~nvar_attributes_t() { + _clean_up(); +} + +void ami_nvar_t::nvar_attributes_t::_clean_up() { +} + +ami_nvar_t::ucs2_string_t::ucs2_string_t(kaitai::kstream* p__io, ami_nvar_t::nvar_entry_body_t* p__parent, ami_nvar_t* p__root) : kaitai::kstruct(p__io) { + m__parent = p__parent; + m__root = p__root; + m_ucs2_chars = nullptr; + _read(); +} + +void ami_nvar_t::ucs2_string_t::_read() { + m_ucs2_chars = std::unique_ptr>(new std::vector()); + { + int i = 0; + uint16_t _; + do { + _ = m__io->read_u2le(); + m_ucs2_chars->push_back(_); + i++; + } while (!(_ == 0)); + } +} + +ami_nvar_t::ucs2_string_t::~ucs2_string_t() { + _clean_up(); +} + +void ami_nvar_t::ucs2_string_t::_clean_up() { +} + +ami_nvar_t::nvar_extended_attributes_t::nvar_extended_attributes_t(kaitai::kstream* p__io, ami_nvar_t::nvar_entry_body_t* p__parent, ami_nvar_t* p__root) : kaitai::kstruct(p__io) { + m__parent = p__parent; + m__root = p__root; + _read(); +} + +void ami_nvar_t::nvar_extended_attributes_t::_read() { + m_reserved_high = m__io->read_bits_int_be(2); + m_time_based_auth = m__io->read_bits_int_be(1); + m_auth_write = m__io->read_bits_int_be(1); + m_reserved_low = m__io->read_bits_int_be(3); + m_checksum = m__io->read_bits_int_be(1); +} + +ami_nvar_t::nvar_extended_attributes_t::~nvar_extended_attributes_t() { + _clean_up(); +} + +void ami_nvar_t::nvar_extended_attributes_t::_clean_up() { +} + +ami_nvar_t::nvar_entry_t::nvar_entry_t(kaitai::kstream* p__io, ami_nvar_t* p__parent, ami_nvar_t* p__root) : kaitai::kstruct(p__io) { + m__parent = p__parent; + m__root = p__root; + m_attributes = nullptr; + m_body = nullptr; + m__io__raw_body = nullptr; + f_offset = false; + f_end_offset = false; + _read(); +} + +void ami_nvar_t::nvar_entry_t::_read() { + n_invoke_offset = true; + if (offset() >= 0) { + n_invoke_offset = false; + m_invoke_offset = m__io->read_bytes(0); + } + m_signature_first = m__io->read_u1(); + n_signature_rest = true; + if (signature_first() == 78) { + n_signature_rest = false; + m_signature_rest = m__io->read_bytes(3); + if (!(signature_rest() == std::string("\x56\x41\x52", 3))) { + throw kaitai::validation_not_equal_error(std::string("\x56\x41\x52", 3), signature_rest(), _io(), std::string("/types/nvar_entry/seq/2")); + } + } + n_size = true; + if (signature_first() == 78) { + n_size = false; + m_size = m__io->read_u2le(); + { + uint16_t _ = size(); + if (!(_ > ((4 + 2) + 4))) { + throw kaitai::validation_expr_error(size(), _io(), std::string("/types/nvar_entry/seq/3")); + } + } + } + n_next = true; + if (signature_first() == 78) { + n_next = false; + m_next = m__io->read_bits_int_le(24); + } + m__io->align_to_byte(); + n_attributes = true; + if (signature_first() == 78) { + n_attributes = false; + m_attributes = std::unique_ptr(new nvar_attributes_t(m__io, this, m__root)); + } + n_body = true; + if (signature_first() == 78) { + n_body = false; + m__raw_body = m__io->read_bytes((size() - ((4 + 2) + 4))); + m__io__raw_body = std::unique_ptr(new kaitai::kstream(m__raw_body)); + m_body = std::unique_ptr(new nvar_entry_body_t(m__io__raw_body.get(), this, m__root)); + } + n_invoke_end_offset = true; + if ( ((signature_first() == 78) && (end_offset() >= 0)) ) { + n_invoke_end_offset = false; + m_invoke_end_offset = m__io->read_bytes(0); + } +} + +ami_nvar_t::nvar_entry_t::~nvar_entry_t() { + _clean_up(); +} + +void ami_nvar_t::nvar_entry_t::_clean_up() { + if (!n_invoke_offset) { + } + if (!n_signature_rest) { + } + if (!n_size) { + } + if (!n_next) { + } + if (!n_attributes) { + } + if (!n_body) { + } + if (!n_invoke_end_offset) { + } +} + +int32_t ami_nvar_t::nvar_entry_t::offset() { + if (f_offset) + return m_offset; + m_offset = (int32_t)_io()->pos(); + f_offset = true; + return m_offset; +} + +int32_t ami_nvar_t::nvar_entry_t::end_offset() { + if (f_end_offset) + return m_end_offset; + m_end_offset = (int32_t)_io()->pos(); + f_end_offset = true; + return m_end_offset; +} + +ami_nvar_t::nvar_entry_body_t::nvar_entry_body_t(kaitai::kstream* p__io, ami_nvar_t::nvar_entry_t* p__parent, ami_nvar_t* p__root) : kaitai::kstruct(p__io) { + m__parent = p__parent; + m__root = p__root; + m_ucs2_name = nullptr; + m_extended_header_attributes = nullptr; + f_extended_header_attributes = false; + f_data_start_offset = false; + f_extended_header_size_field = false; + f_extended_header_timestamp = false; + f_data_size = false; + f_extended_header_checksum = false; + f_data_end_offset = false; + f_extended_header_size = false; + f_extended_header_hash = false; + _read(); +} + +void ami_nvar_t::nvar_entry_body_t::_read() { + n_guid_index = true; + if ( ((!(_parent()->attributes()->local_guid())) && (!(_parent()->attributes()->data_only())) && (_parent()->attributes()->valid())) ) { + n_guid_index = false; + m_guid_index = m__io->read_u1(); + } + n_guid = true; + if ( ((_parent()->attributes()->local_guid()) && (!(_parent()->attributes()->data_only())) && (_parent()->attributes()->valid())) ) { + n_guid = false; + m_guid = m__io->read_bytes(16); + } + n_ascii_name = true; + if ( ((_parent()->attributes()->ascii_name()) && (!(_parent()->attributes()->data_only())) && (_parent()->attributes()->valid())) ) { + n_ascii_name = false; + m_ascii_name = kaitai::kstream::bytes_to_str(m__io->read_bytes_term(0, false, true, true), std::string("ASCII")); + } + n_ucs2_name = true; + if ( ((!(_parent()->attributes()->ascii_name())) && (!(_parent()->attributes()->data_only())) && (_parent()->attributes()->valid())) ) { + n_ucs2_name = false; + m_ucs2_name = std::unique_ptr(new ucs2_string_t(m__io, this, m__root)); + } + n_invoke_data_start = true; + if (data_start_offset() >= 0) { + n_invoke_data_start = false; + m_invoke_data_start = m__io->read_bytes(0); + } + m_data = m__io->read_bytes_full(); +} + +ami_nvar_t::nvar_entry_body_t::~nvar_entry_body_t() { + _clean_up(); +} + +void ami_nvar_t::nvar_entry_body_t::_clean_up() { + if (!n_guid_index) { + } + if (!n_guid) { + } + if (!n_ascii_name) { + } + if (!n_ucs2_name) { + } + if (!n_invoke_data_start) { + } + if (f_extended_header_attributes && !n_extended_header_attributes) { + } + if (f_extended_header_size_field && !n_extended_header_size_field) { + } + if (f_extended_header_timestamp && !n_extended_header_timestamp) { + } + if (f_extended_header_checksum && !n_extended_header_checksum) { + } + if (f_extended_header_hash && !n_extended_header_hash) { + } +} + +ami_nvar_t::nvar_extended_attributes_t* ami_nvar_t::nvar_entry_body_t::extended_header_attributes() { + if (f_extended_header_attributes) + return m_extended_header_attributes.get(); + n_extended_header_attributes = true; + if ( ((_parent()->attributes()->valid()) && (_parent()->attributes()->extended_header()) && (extended_header_size() >= (1 + 2))) ) { + n_extended_header_attributes = false; + std::streampos _pos = m__io->pos(); + m__io->seek((_io()->pos() - extended_header_size())); + m_extended_header_attributes = std::unique_ptr(new nvar_extended_attributes_t(m__io, this, m__root)); + m__io->seek(_pos); + f_extended_header_attributes = true; + } + return m_extended_header_attributes.get(); +} + +int32_t ami_nvar_t::nvar_entry_body_t::data_start_offset() { + if (f_data_start_offset) + return m_data_start_offset; + m_data_start_offset = (int32_t)_io()->pos(); + f_data_start_offset = true; + return m_data_start_offset; +} + +uint16_t ami_nvar_t::nvar_entry_body_t::extended_header_size_field() { + if (f_extended_header_size_field) + return m_extended_header_size_field; + n_extended_header_size_field = true; + if ( ((_parent()->attributes()->valid()) && (_parent()->attributes()->extended_header()) && (_parent()->size() > (((4 + 2) + 4) + 2))) ) { + n_extended_header_size_field = false; + std::streampos _pos = m__io->pos(); + m__io->seek((_io()->pos() - 2)); + m_extended_header_size_field = m__io->read_u2le(); + m__io->seek(_pos); + f_extended_header_size_field = true; + } + return m_extended_header_size_field; +} + +uint64_t ami_nvar_t::nvar_entry_body_t::extended_header_timestamp() { + if (f_extended_header_timestamp) + return m_extended_header_timestamp; + n_extended_header_timestamp = true; + if ( ((_parent()->attributes()->valid()) && (_parent()->attributes()->extended_header()) && (extended_header_size() >= ((1 + 8) + 2)) && (extended_header_attributes()->time_based_auth())) ) { + n_extended_header_timestamp = false; + std::streampos _pos = m__io->pos(); + m__io->seek(((_io()->pos() - extended_header_size()) + 1)); + m_extended_header_timestamp = m__io->read_u8le(); + m__io->seek(_pos); + f_extended_header_timestamp = true; + } + return m_extended_header_timestamp; +} + +int32_t ami_nvar_t::nvar_entry_body_t::data_size() { + if (f_data_size) + return m_data_size; + m_data_size = ((data_end_offset() - data_start_offset()) - extended_header_size()); + f_data_size = true; + return m_data_size; +} + +uint8_t ami_nvar_t::nvar_entry_body_t::extended_header_checksum() { + if (f_extended_header_checksum) + return m_extended_header_checksum; + n_extended_header_checksum = true; + if ( ((_parent()->attributes()->valid()) && (_parent()->attributes()->extended_header()) && (extended_header_size() >= ((1 + 1) + 2)) && (extended_header_attributes()->checksum())) ) { + n_extended_header_checksum = false; + std::streampos _pos = m__io->pos(); + m__io->seek(((_io()->pos() - 2) - 1)); + m_extended_header_checksum = m__io->read_u1(); + m__io->seek(_pos); + f_extended_header_checksum = true; + } + return m_extended_header_checksum; +} + +int32_t ami_nvar_t::nvar_entry_body_t::data_end_offset() { + if (f_data_end_offset) + return m_data_end_offset; + m_data_end_offset = (int32_t)_io()->pos(); + f_data_end_offset = true; + return m_data_end_offset; +} + +uint16_t ami_nvar_t::nvar_entry_body_t::extended_header_size() { + if (f_extended_header_size) + return m_extended_header_size; + m_extended_header_size = (( ((_parent()->attributes()->extended_header()) && (_parent()->attributes()->valid()) && (_parent()->size() > (((4 + 2) + 4) + 2))) ) ? (((extended_header_size_field() >= (1 + 2)) ? (extended_header_size_field()) : (0))) : (0)); + f_extended_header_size = true; + return m_extended_header_size; +} + +std::string ami_nvar_t::nvar_entry_body_t::extended_header_hash() { + if (f_extended_header_hash) + return m_extended_header_hash; + n_extended_header_hash = true; + if ( ((_parent()->attributes()->valid()) && (_parent()->attributes()->extended_header()) && (extended_header_size() >= (((1 + 8) + 32) + 2)) && (extended_header_attributes()->time_based_auth()) && (!(_parent()->attributes()->data_only()))) ) { + n_extended_header_hash = false; + std::streampos _pos = m__io->pos(); + m__io->seek((((_io()->pos() - extended_header_size()) + 1) + 8)); + m_extended_header_hash = m__io->read_bytes(32); + m__io->seek(_pos); + f_extended_header_hash = true; + } + return m_extended_header_hash; +} diff --git a/common/generated/ami_nvar.h b/common/generated/ami_nvar.h new file mode 100644 index 0000000..9469bec --- /dev/null +++ b/common/generated/ami_nvar.h @@ -0,0 +1,396 @@ +#pragma once + +// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild + +#include "../kaitai/kaitaistruct.h" +#include +#include +#include + +#if KAITAI_STRUCT_VERSION < 9000L +#error "Incompatible Kaitai Struct C++/STL API: version 0.9 or later is required" +#endif + +class ami_nvar_t : public kaitai::kstruct { + +public: + class nvar_attributes_t; + class ucs2_string_t; + class nvar_extended_attributes_t; + class nvar_entry_t; + class nvar_entry_body_t; + + ami_nvar_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = nullptr, ami_nvar_t* p__root = nullptr); + +private: + void _read(); + void _clean_up(); + +public: + ~ami_nvar_t(); + + class nvar_attributes_t : public kaitai::kstruct { + + public: + + nvar_attributes_t(kaitai::kstream* p__io, ami_nvar_t::nvar_entry_t* p__parent = nullptr, ami_nvar_t* p__root = nullptr); + + private: + void _read(); + void _clean_up(); + + public: + ~nvar_attributes_t(); + + private: + bool m_valid; + bool m_auth_write; + bool m_hw_error_record; + bool m_extended_header; + bool m_data_only; + bool m_local_guid; + bool m_ascii_name; + bool m_runtime; + ami_nvar_t* m__root; + ami_nvar_t::nvar_entry_t* m__parent; + + public: + bool valid() const { return m_valid; } + bool auth_write() const { return m_auth_write; } + bool hw_error_record() const { return m_hw_error_record; } + bool extended_header() const { return m_extended_header; } + bool data_only() const { return m_data_only; } + bool local_guid() const { return m_local_guid; } + bool ascii_name() const { return m_ascii_name; } + bool runtime() const { return m_runtime; } + ami_nvar_t* _root() const { return m__root; } + ami_nvar_t::nvar_entry_t* _parent() const { return m__parent; } + }; + + class ucs2_string_t : public kaitai::kstruct { + + public: + + ucs2_string_t(kaitai::kstream* p__io, ami_nvar_t::nvar_entry_body_t* p__parent = nullptr, ami_nvar_t* p__root = nullptr); + + private: + void _read(); + void _clean_up(); + + public: + ~ucs2_string_t(); + + private: + std::unique_ptr> m_ucs2_chars; + ami_nvar_t* m__root; + ami_nvar_t::nvar_entry_body_t* m__parent; + + public: + std::vector* ucs2_chars() const { return m_ucs2_chars.get(); } + ami_nvar_t* _root() const { return m__root; } + ami_nvar_t::nvar_entry_body_t* _parent() const { return m__parent; } + }; + + class nvar_extended_attributes_t : public kaitai::kstruct { + + public: + + nvar_extended_attributes_t(kaitai::kstream* p__io, ami_nvar_t::nvar_entry_body_t* p__parent = nullptr, ami_nvar_t* p__root = nullptr); + + private: + void _read(); + void _clean_up(); + + public: + ~nvar_extended_attributes_t(); + + private: + uint64_t m_reserved_high; + bool m_time_based_auth; + bool m_auth_write; + uint64_t m_reserved_low; + bool m_checksum; + ami_nvar_t* m__root; + ami_nvar_t::nvar_entry_body_t* m__parent; + + public: + uint64_t reserved_high() const { return m_reserved_high; } + bool time_based_auth() const { return m_time_based_auth; } + bool auth_write() const { return m_auth_write; } + uint64_t reserved_low() const { return m_reserved_low; } + bool checksum() const { return m_checksum; } + ami_nvar_t* _root() const { return m__root; } + ami_nvar_t::nvar_entry_body_t* _parent() const { return m__parent; } + }; + + class nvar_entry_t : public kaitai::kstruct { + + public: + + nvar_entry_t(kaitai::kstream* p__io, ami_nvar_t* p__parent = nullptr, ami_nvar_t* p__root = nullptr); + + private: + void _read(); + void _clean_up(); + + public: + ~nvar_entry_t(); + + private: + bool f_offset; + int32_t m_offset; + + public: + int32_t offset(); + + private: + bool f_end_offset; + int32_t m_end_offset; + + public: + int32_t end_offset(); + + private: + std::string m_invoke_offset; + bool n_invoke_offset; + + public: + bool _is_null_invoke_offset() { invoke_offset(); return n_invoke_offset; }; + + private: + uint8_t m_signature_first; + std::string m_signature_rest; + bool n_signature_rest; + + public: + bool _is_null_signature_rest() { signature_rest(); return n_signature_rest; }; + + private: + uint16_t m_size; + bool n_size; + + public: + bool _is_null_size() { size(); return n_size; }; + + private: + uint64_t m_next; + bool n_next; + + public: + bool _is_null_next() { next(); return n_next; }; + + private: + std::unique_ptr m_attributes; + bool n_attributes; + + public: + bool _is_null_attributes() { attributes(); return n_attributes; }; + + private: + std::unique_ptr m_body; + bool n_body; + + public: + bool _is_null_body() { body(); return n_body; }; + + private: + std::string m_invoke_end_offset; + bool n_invoke_end_offset; + + public: + bool _is_null_invoke_end_offset() { invoke_end_offset(); return n_invoke_end_offset; }; + + private: + ami_nvar_t* m__root; + ami_nvar_t* m__parent; + std::string m__raw_body; + bool n__raw_body; + + public: + bool _is_null__raw_body() { _raw_body(); return n__raw_body; }; + + private: + std::unique_ptr m__io__raw_body; + + public: + std::string invoke_offset() const { return m_invoke_offset; } + uint8_t signature_first() const { return m_signature_first; } + std::string signature_rest() const { return m_signature_rest; } + uint16_t size() const { return m_size; } + uint64_t next() const { return m_next; } + nvar_attributes_t* attributes() const { return m_attributes.get(); } + nvar_entry_body_t* body() const { return m_body.get(); } + std::string invoke_end_offset() const { return m_invoke_end_offset; } + ami_nvar_t* _root() const { return m__root; } + ami_nvar_t* _parent() const { return m__parent; } + std::string _raw_body() const { return m__raw_body; } + kaitai::kstream* _io__raw_body() const { return m__io__raw_body.get(); } + }; + + class nvar_entry_body_t : public kaitai::kstruct { + + public: + + nvar_entry_body_t(kaitai::kstream* p__io, ami_nvar_t::nvar_entry_t* p__parent = nullptr, ami_nvar_t* p__root = nullptr); + + private: + void _read(); + void _clean_up(); + + public: + ~nvar_entry_body_t(); + + private: + bool f_extended_header_attributes; + std::unique_ptr m_extended_header_attributes; + bool n_extended_header_attributes; + + public: + bool _is_null_extended_header_attributes() { extended_header_attributes(); return n_extended_header_attributes; }; + + private: + + public: + nvar_extended_attributes_t* extended_header_attributes(); + + private: + bool f_data_start_offset; + int32_t m_data_start_offset; + + public: + int32_t data_start_offset(); + + private: + bool f_extended_header_size_field; + uint16_t m_extended_header_size_field; + bool n_extended_header_size_field; + + public: + bool _is_null_extended_header_size_field() { extended_header_size_field(); return n_extended_header_size_field; }; + + private: + + public: + uint16_t extended_header_size_field(); + + private: + bool f_extended_header_timestamp; + uint64_t m_extended_header_timestamp; + bool n_extended_header_timestamp; + + public: + bool _is_null_extended_header_timestamp() { extended_header_timestamp(); return n_extended_header_timestamp; }; + + private: + + public: + uint64_t extended_header_timestamp(); + + private: + bool f_data_size; + int32_t m_data_size; + + public: + int32_t data_size(); + + private: + bool f_extended_header_checksum; + uint8_t m_extended_header_checksum; + bool n_extended_header_checksum; + + public: + bool _is_null_extended_header_checksum() { extended_header_checksum(); return n_extended_header_checksum; }; + + private: + + public: + uint8_t extended_header_checksum(); + + private: + bool f_data_end_offset; + int32_t m_data_end_offset; + + public: + int32_t data_end_offset(); + + private: + bool f_extended_header_size; + uint16_t m_extended_header_size; + + public: + uint16_t extended_header_size(); + + private: + bool f_extended_header_hash; + std::string m_extended_header_hash; + bool n_extended_header_hash; + + public: + bool _is_null_extended_header_hash() { extended_header_hash(); return n_extended_header_hash; }; + + private: + + public: + std::string extended_header_hash(); + + private: + uint8_t m_guid_index; + bool n_guid_index; + + public: + bool _is_null_guid_index() { guid_index(); return n_guid_index; }; + + private: + std::string m_guid; + bool n_guid; + + public: + bool _is_null_guid() { guid(); return n_guid; }; + + private: + std::string m_ascii_name; + bool n_ascii_name; + + public: + bool _is_null_ascii_name() { ascii_name(); return n_ascii_name; }; + + private: + std::unique_ptr m_ucs2_name; + bool n_ucs2_name; + + public: + bool _is_null_ucs2_name() { ucs2_name(); return n_ucs2_name; }; + + private: + std::string m_invoke_data_start; + bool n_invoke_data_start; + + public: + bool _is_null_invoke_data_start() { invoke_data_start(); return n_invoke_data_start; }; + + private: + std::string m_data; + ami_nvar_t* m__root; + ami_nvar_t::nvar_entry_t* m__parent; + + public: + uint8_t guid_index() const { return m_guid_index; } + std::string guid() const { return m_guid; } + std::string ascii_name() const { return m_ascii_name; } + ucs2_string_t* ucs2_name() const { return m_ucs2_name.get(); } + std::string invoke_data_start() const { return m_invoke_data_start; } + std::string data() const { return m_data; } + ami_nvar_t* _root() const { return m__root; } + ami_nvar_t::nvar_entry_t* _parent() const { return m__parent; } + }; + +private: + std::unique_ptr>> m_entries; + ami_nvar_t* m__root; + kaitai::kstruct* m__parent; + +public: + std::vector>* entries() const { return m_entries.get(); } + ami_nvar_t* _root() const { return m__root; } + kaitai::kstruct* _parent() const { return m__parent; } +}; diff --git a/common/generated/apple_sysf.cpp b/common/generated/apple_sysf.cpp new file mode 100644 index 0000000..580d84e --- /dev/null +++ b/common/generated/apple_sysf.cpp @@ -0,0 +1,108 @@ +// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild + +#include "apple_sysf.h" + +apple_sysf_t::apple_sysf_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, apple_sysf_t* p__root) : kaitai::kstruct(p__io) { + m__parent = p__parent; + m__root = this; (void)p__root; + m_body = nullptr; + m__io__raw_body = nullptr; + f_len_sysf_store_header = false; + _read(); +} + +void apple_sysf_t::_read() { + m_signature = m__io->read_u4le(); + m_unknown = m__io->read_u1(); + m_unknown1 = m__io->read_u4le(); + m_sysf_size = m__io->read_u2le(); + m__raw_body = m__io->read_bytes(((sysf_size() - len_sysf_store_header()) - 4)); + m__io__raw_body = std::unique_ptr(new kaitai::kstream(m__raw_body)); + m_body = std::unique_ptr(new sysf_store_body_t(m__io__raw_body.get(), this, m__root)); + m_crc = m__io->read_u4le(); +} + +apple_sysf_t::~apple_sysf_t() { + _clean_up(); +} + +void apple_sysf_t::_clean_up() { +} + +apple_sysf_t::sysf_store_body_t::sysf_store_body_t(kaitai::kstream* p__io, apple_sysf_t* p__parent, apple_sysf_t* p__root) : kaitai::kstruct(p__io) { + m__parent = p__parent; + m__root = p__root; + m_variables = nullptr; + m_zeroes = nullptr; + _read(); +} + +void apple_sysf_t::sysf_store_body_t::_read() { + m_variables = std::unique_ptr>>(new std::vector>()); + { + int i = 0; + sysf_variable_t* _; + do { + _ = new sysf_variable_t(m__io, this, m__root); + m_variables->push_back(std::move(std::unique_ptr(_))); + i++; + } while (!( (( ((_->len_name() == 3) && (_->name() == (std::string("EOF")))) ) || (_io()->is_eof())) )); + } + m_zeroes = std::unique_ptr>(new std::vector()); + { + int i = 0; + while (!m__io->is_eof()) { + m_zeroes->push_back(std::move(m__io->read_u1())); + i++; + } + } +} + +apple_sysf_t::sysf_store_body_t::~sysf_store_body_t() { + _clean_up(); +} + +void apple_sysf_t::sysf_store_body_t::_clean_up() { +} + +apple_sysf_t::sysf_variable_t::sysf_variable_t(kaitai::kstream* p__io, apple_sysf_t::sysf_store_body_t* p__parent, apple_sysf_t* p__root) : kaitai::kstruct(p__io) { + m__parent = p__parent; + m__root = p__root; + _read(); +} + +void apple_sysf_t::sysf_variable_t::_read() { + m_len_name = m__io->read_bits_int_le(7); + m_invalid_flag = m__io->read_bits_int_le(1); + m__io->align_to_byte(); + m_name = kaitai::kstream::bytes_to_str(kaitai::kstream::bytes_terminate(m__io->read_bytes(len_name()), 0, false), std::string("ascii")); + n_len_data = true; + if (name() != std::string("EOF")) { + n_len_data = false; + m_len_data = m__io->read_u2le(); + } + n_data = true; + if (name() != std::string("EOF")) { + n_data = false; + m_data = m__io->read_bytes(len_data()); + } +} + +apple_sysf_t::sysf_variable_t::~sysf_variable_t() { + _clean_up(); +} + +void apple_sysf_t::sysf_variable_t::_clean_up() { + if (!n_len_data) { + } + if (!n_data) { + } +} + +int8_t apple_sysf_t::len_sysf_store_header() { + if (f_len_sysf_store_header) + return m_len_sysf_store_header; + m_len_sysf_store_header = 11; + f_len_sysf_store_header = true; + return m_len_sysf_store_header; +} diff --git a/common/generated/apple_sysf.h b/common/generated/apple_sysf.h new file mode 100644 index 0000000..8de0be8 --- /dev/null +++ b/common/generated/apple_sysf.h @@ -0,0 +1,129 @@ +#pragma once + +// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild + +#include "../kaitai/kaitaistruct.h" +#include +#include +#include + +#if KAITAI_STRUCT_VERSION < 9000L +#error "Incompatible Kaitai Struct C++/STL API: version 0.9 or later is required" +#endif + +class apple_sysf_t : public kaitai::kstruct { + +public: + class sysf_store_body_t; + class sysf_variable_t; + + apple_sysf_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = nullptr, apple_sysf_t* p__root = nullptr); + +private: + void _read(); + void _clean_up(); + +public: + ~apple_sysf_t(); + + class sysf_store_body_t : public kaitai::kstruct { + + public: + + sysf_store_body_t(kaitai::kstream* p__io, apple_sysf_t* p__parent = nullptr, apple_sysf_t* p__root = nullptr); + + private: + void _read(); + void _clean_up(); + + public: + ~sysf_store_body_t(); + + private: + std::unique_ptr>> m_variables; + std::unique_ptr> m_zeroes; + apple_sysf_t* m__root; + apple_sysf_t* m__parent; + + public: + std::vector>* variables() const { return m_variables.get(); } + std::vector* zeroes() const { return m_zeroes.get(); } + apple_sysf_t* _root() const { return m__root; } + apple_sysf_t* _parent() const { return m__parent; } + }; + + class sysf_variable_t : public kaitai::kstruct { + + public: + + sysf_variable_t(kaitai::kstream* p__io, apple_sysf_t::sysf_store_body_t* p__parent = nullptr, apple_sysf_t* p__root = nullptr); + + private: + void _read(); + void _clean_up(); + + public: + ~sysf_variable_t(); + + private: + uint64_t m_len_name; + bool m_invalid_flag; + std::string m_name; + uint16_t m_len_data; + bool n_len_data; + + public: + bool _is_null_len_data() { len_data(); return n_len_data; }; + + private: + std::string m_data; + bool n_data; + + public: + bool _is_null_data() { data(); return n_data; }; + + private: + apple_sysf_t* m__root; + apple_sysf_t::sysf_store_body_t* m__parent; + + public: + uint64_t len_name() const { return m_len_name; } + bool invalid_flag() const { return m_invalid_flag; } + std::string name() const { return m_name; } + uint16_t len_data() const { return m_len_data; } + std::string data() const { return m_data; } + apple_sysf_t* _root() const { return m__root; } + apple_sysf_t::sysf_store_body_t* _parent() const { return m__parent; } + }; + +private: + bool f_len_sysf_store_header; + int8_t m_len_sysf_store_header; + +public: + int8_t len_sysf_store_header(); + +private: + uint32_t m_signature; + uint8_t m_unknown; + uint32_t m_unknown1; + uint16_t m_sysf_size; + std::unique_ptr m_body; + uint32_t m_crc; + apple_sysf_t* m__root; + kaitai::kstruct* m__parent; + std::string m__raw_body; + std::unique_ptr m__io__raw_body; + +public: + uint32_t signature() const { return m_signature; } + uint8_t unknown() const { return m_unknown; } + uint32_t unknown1() const { return m_unknown1; } + uint16_t sysf_size() const { return m_sysf_size; } + sysf_store_body_t* body() const { return m_body.get(); } + uint32_t crc() const { return m_crc; } + apple_sysf_t* _root() const { return m__root; } + kaitai::kstruct* _parent() const { return m__parent; } + std::string _raw_body() const { return m__raw_body; } + kaitai::kstream* _io__raw_body() const { return m__io__raw_body.get(); } +}; diff --git a/common/generated/dell_dvar.cpp b/common/generated/dell_dvar.cpp new file mode 100644 index 0000000..cc35e93 --- /dev/null +++ b/common/generated/dell_dvar.cpp @@ -0,0 +1,235 @@ +// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild + +#include "dell_dvar.h" + +dell_dvar_t::dell_dvar_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, dell_dvar_t* p__root) : kaitai::kstruct(p__io) { + m__parent = p__parent; + m__root = this; (void)p__root; + m_entries = nullptr; + f_len_store = false; + f_flags = false; + f_data_offset = false; + _read(); +} + +void dell_dvar_t::_read() { + m_signature = m__io->read_bytes(4); + m_len_store_c = m__io->read_u4le(); + m_flags_c = m__io->read_u1(); + m_entries = std::unique_ptr>>(new std::vector>()); + { + int i = 0; + dvar_entry_t* _; + do { + _ = new dvar_entry_t(m__io, this, m__root); + m_entries->push_back(std::move(std::unique_ptr(_))); + i++; + } while (!(_->state_c() == 255)); + } +} + +dell_dvar_t::~dell_dvar_t() { + _clean_up(); +} + +void dell_dvar_t::_clean_up() { +} + +dell_dvar_t::dvar_entry_t::dvar_entry_t(kaitai::kstream* p__io, dell_dvar_t* p__parent, dell_dvar_t* p__root) : kaitai::kstruct(p__io) { + m__parent = p__parent; + m__root = p__root; + f_namespace_id = false; + f_len_data_8 = false; + f_state = false; + f_len_data_16 = false; + f_attributes = false; + f_flags = false; + f_name_id_8 = false; + f_name_id_16 = false; + f_type = false; + _read(); +} + +void dell_dvar_t::dvar_entry_t::_read() { + m_state_c = m__io->read_u1(); + n_flags_c = true; + if (state_c() != 255) { + n_flags_c = false; + m_flags_c = m__io->read_u1(); + } + n_type_c = true; + if (state_c() != 255) { + n_type_c = false; + m_type_c = m__io->read_u1(); + } + n_attributes_c = true; + if (state_c() != 255) { + n_attributes_c = false; + m_attributes_c = m__io->read_u1(); + } + n_namespace_id_c = true; + if ( ((state_c() != 255) && ( ((flags() == 2) || (flags() == 6)) )) ) { + n_namespace_id_c = false; + m_namespace_id_c = m__io->read_u1(); + } + n_namespace_guid = true; + if ( ((state_c() != 255) && (flags() == 6)) ) { + n_namespace_guid = false; + m_namespace_guid = m__io->read_bytes(16); + } + n_name_id_8_c = true; + if ( ((state_c() != 255) && (type() == 0)) ) { + n_name_id_8_c = false; + m_name_id_8_c = m__io->read_u1(); + } + n_name_id_16_c = true; + if ( ((state_c() != 255) && ( ((type() == 4) || (type() == 5)) )) ) { + n_name_id_16_c = false; + m_name_id_16_c = m__io->read_u2le(); + } + n_len_data_8_c = true; + if ( ((state_c() != 255) && ( ((type() == 0) || (type() == 4)) )) ) { + n_len_data_8_c = false; + m_len_data_8_c = m__io->read_u1(); + } + n_len_data_16_c = true; + if ( ((state_c() != 255) && (type() == 5)) ) { + n_len_data_16_c = false; + m_len_data_16_c = m__io->read_u2le(); + } + n_data_8 = true; + if ( ((state_c() != 255) && ( ((type() == 0) || (type() == 4)) )) ) { + n_data_8 = false; + m_data_8 = m__io->read_bytes(len_data_8()); + } + n_data_16 = true; + if ( ((state_c() != 255) && (type() == 5)) ) { + n_data_16 = false; + m_data_16 = m__io->read_bytes(len_data_16()); + } +} + +dell_dvar_t::dvar_entry_t::~dvar_entry_t() { + _clean_up(); +} + +void dell_dvar_t::dvar_entry_t::_clean_up() { + if (!n_flags_c) { + } + if (!n_type_c) { + } + if (!n_attributes_c) { + } + if (!n_namespace_id_c) { + } + if (!n_namespace_guid) { + } + if (!n_name_id_8_c) { + } + if (!n_name_id_16_c) { + } + if (!n_len_data_8_c) { + } + if (!n_len_data_16_c) { + } + if (!n_data_8) { + } + if (!n_data_16) { + } +} + +int32_t dell_dvar_t::dvar_entry_t::namespace_id() { + if (f_namespace_id) + return m_namespace_id; + m_namespace_id = (255 - namespace_id_c()); + f_namespace_id = true; + return m_namespace_id; +} + +int32_t dell_dvar_t::dvar_entry_t::len_data_8() { + if (f_len_data_8) + return m_len_data_8; + m_len_data_8 = (255 - len_data_8_c()); + f_len_data_8 = true; + return m_len_data_8; +} + +int32_t dell_dvar_t::dvar_entry_t::state() { + if (f_state) + return m_state; + m_state = (255 - state_c()); + f_state = true; + return m_state; +} + +int32_t dell_dvar_t::dvar_entry_t::len_data_16() { + if (f_len_data_16) + return m_len_data_16; + m_len_data_16 = (65535 - len_data_16_c()); + f_len_data_16 = true; + return m_len_data_16; +} + +int32_t dell_dvar_t::dvar_entry_t::attributes() { + if (f_attributes) + return m_attributes; + m_attributes = (255 - attributes_c()); + f_attributes = true; + return m_attributes; +} + +int32_t dell_dvar_t::dvar_entry_t::flags() { + if (f_flags) + return m_flags; + m_flags = (255 - flags_c()); + f_flags = true; + return m_flags; +} + +int32_t dell_dvar_t::dvar_entry_t::name_id_8() { + if (f_name_id_8) + return m_name_id_8; + m_name_id_8 = (255 - name_id_8_c()); + f_name_id_8 = true; + return m_name_id_8; +} + +int32_t dell_dvar_t::dvar_entry_t::name_id_16() { + if (f_name_id_16) + return m_name_id_16; + m_name_id_16 = (65535 - name_id_16_c()); + f_name_id_16 = true; + return m_name_id_16; +} + +int32_t dell_dvar_t::dvar_entry_t::type() { + if (f_type) + return m_type; + m_type = (255 - type_c()); + f_type = true; + return m_type; +} + +int32_t dell_dvar_t::len_store() { + if (f_len_store) + return m_len_store; + m_len_store = (4294967295UL - len_store_c()); + f_len_store = true; + return m_len_store; +} + +int32_t dell_dvar_t::flags() { + if (f_flags) + return m_flags; + m_flags = (255 - flags_c()); + f_flags = true; + return m_flags; +} + +int8_t dell_dvar_t::data_offset() { + if (f_data_offset) + return m_data_offset; + m_data_offset = 9; + f_data_offset = true; + return m_data_offset; +} diff --git a/common/generated/dell_dvar.h b/common/generated/dell_dvar.h new file mode 100644 index 0000000..e50af45 --- /dev/null +++ b/common/generated/dell_dvar.h @@ -0,0 +1,239 @@ +#pragma once + +// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild + +#include "../kaitai/kaitaistruct.h" +#include +#include +#include + +#if KAITAI_STRUCT_VERSION < 9000L +#error "Incompatible Kaitai Struct C++/STL API: version 0.9 or later is required" +#endif + +class dell_dvar_t : public kaitai::kstruct { + +public: + class dvar_entry_t; + + dell_dvar_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = nullptr, dell_dvar_t* p__root = nullptr); + +private: + void _read(); + void _clean_up(); + +public: + ~dell_dvar_t(); + + class dvar_entry_t : public kaitai::kstruct { + + public: + + dvar_entry_t(kaitai::kstream* p__io, dell_dvar_t* p__parent = nullptr, dell_dvar_t* p__root = nullptr); + + private: + void _read(); + void _clean_up(); + + public: + ~dvar_entry_t(); + + private: + bool f_namespace_id; + int32_t m_namespace_id; + + public: + int32_t namespace_id(); + + private: + bool f_len_data_8; + int32_t m_len_data_8; + + public: + int32_t len_data_8(); + + private: + bool f_state; + int32_t m_state; + + public: + int32_t state(); + + private: + bool f_len_data_16; + int32_t m_len_data_16; + + public: + int32_t len_data_16(); + + private: + bool f_attributes; + int32_t m_attributes; + + public: + int32_t attributes(); + + private: + bool f_flags; + int32_t m_flags; + + public: + int32_t flags(); + + private: + bool f_name_id_8; + int32_t m_name_id_8; + + public: + int32_t name_id_8(); + + private: + bool f_name_id_16; + int32_t m_name_id_16; + + public: + int32_t name_id_16(); + + private: + bool f_type; + int32_t m_type; + + public: + int32_t type(); + + private: + uint8_t m_state_c; + uint8_t m_flags_c; + bool n_flags_c; + + public: + bool _is_null_flags_c() { flags_c(); return n_flags_c; }; + + private: + uint8_t m_type_c; + bool n_type_c; + + public: + bool _is_null_type_c() { type_c(); return n_type_c; }; + + private: + uint8_t m_attributes_c; + bool n_attributes_c; + + public: + bool _is_null_attributes_c() { attributes_c(); return n_attributes_c; }; + + private: + uint8_t m_namespace_id_c; + bool n_namespace_id_c; + + public: + bool _is_null_namespace_id_c() { namespace_id_c(); return n_namespace_id_c; }; + + private: + std::string m_namespace_guid; + bool n_namespace_guid; + + public: + bool _is_null_namespace_guid() { namespace_guid(); return n_namespace_guid; }; + + private: + uint8_t m_name_id_8_c; + bool n_name_id_8_c; + + public: + bool _is_null_name_id_8_c() { name_id_8_c(); return n_name_id_8_c; }; + + private: + uint16_t m_name_id_16_c; + bool n_name_id_16_c; + + public: + bool _is_null_name_id_16_c() { name_id_16_c(); return n_name_id_16_c; }; + + private: + uint8_t m_len_data_8_c; + bool n_len_data_8_c; + + public: + bool _is_null_len_data_8_c() { len_data_8_c(); return n_len_data_8_c; }; + + private: + uint16_t m_len_data_16_c; + bool n_len_data_16_c; + + public: + bool _is_null_len_data_16_c() { len_data_16_c(); return n_len_data_16_c; }; + + private: + std::string m_data_8; + bool n_data_8; + + public: + bool _is_null_data_8() { data_8(); return n_data_8; }; + + private: + std::string m_data_16; + bool n_data_16; + + public: + bool _is_null_data_16() { data_16(); return n_data_16; }; + + private: + dell_dvar_t* m__root; + dell_dvar_t* m__parent; + + public: + uint8_t state_c() const { return m_state_c; } + uint8_t flags_c() const { return m_flags_c; } + uint8_t type_c() const { return m_type_c; } + uint8_t attributes_c() const { return m_attributes_c; } + uint8_t namespace_id_c() const { return m_namespace_id_c; } + std::string namespace_guid() const { return m_namespace_guid; } + uint8_t name_id_8_c() const { return m_name_id_8_c; } + uint16_t name_id_16_c() const { return m_name_id_16_c; } + uint8_t len_data_8_c() const { return m_len_data_8_c; } + uint16_t len_data_16_c() const { return m_len_data_16_c; } + std::string data_8() const { return m_data_8; } + std::string data_16() const { return m_data_16; } + dell_dvar_t* _root() const { return m__root; } + dell_dvar_t* _parent() const { return m__parent; } + }; + +private: + bool f_len_store; + int32_t m_len_store; + +public: + int32_t len_store(); + +private: + bool f_flags; + int32_t m_flags; + +public: + int32_t flags(); + +private: + bool f_data_offset; + int8_t m_data_offset; + +public: + int8_t data_offset(); + +private: + std::string m_signature; + uint32_t m_len_store_c; + uint8_t m_flags_c; + std::unique_ptr>> m_entries; + dell_dvar_t* m__root; + kaitai::kstruct* m__parent; + +public: + std::string signature() const { return m_signature; } + uint32_t len_store_c() const { return m_len_store_c; } + uint8_t flags_c() const { return m_flags_c; } + std::vector>* entries() const { return m_entries.get(); } + dell_dvar_t* _root() const { return m__root; } + kaitai::kstruct* _parent() const { return m__parent; } +}; diff --git a/common/generated/edk2_ftw.cpp b/common/generated/edk2_ftw.cpp new file mode 100644 index 0000000..60aa199 --- /dev/null +++ b/common/generated/edk2_ftw.cpp @@ -0,0 +1,63 @@ +// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild + +#include "edk2_ftw.h" + +edk2_ftw_t::edk2_ftw_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, edk2_ftw_t* p__root) : kaitai::kstruct(p__io) { + m__parent = p__parent; + m__root = this; (void)p__root; + f_len_ftw_store_header_32 = false; + f_len_ftw_store_header_64 = false; + _read(); +} + +void edk2_ftw_t::_read() { + m_signature = m__io->read_bytes(16); + m_crc = m__io->read_u4le(); + m_state = m__io->read_u1(); + m_reserved = m__io->read_bytes(3); + m_len_write_queue_32 = m__io->read_u4le(); + n_len_write_queue_64 = true; + if (kaitai::kstream::mod(len_write_queue_32(), 16) == 0) { + n_len_write_queue_64 = false; + m_len_write_queue_64 = m__io->read_u4le(); + } + n_write_queue_32 = true; + if (kaitai::kstream::mod(len_write_queue_32(), 16) == 4) { + n_write_queue_32 = false; + m_write_queue_32 = m__io->read_bytes(len_write_queue_32()); + } + n_write_queue_64 = true; + if (kaitai::kstream::mod(len_write_queue_32(), 16) == 0) { + n_write_queue_64 = false; + m_write_queue_64 = m__io->read_bytes(((static_cast(len_write_queue_64()) << 32) + len_write_queue_32())); + } +} + +edk2_ftw_t::~edk2_ftw_t() { + _clean_up(); +} + +void edk2_ftw_t::_clean_up() { + if (!n_len_write_queue_64) { + } + if (!n_write_queue_32) { + } + if (!n_write_queue_64) { + } +} + +int8_t edk2_ftw_t::len_ftw_store_header_32() { + if (f_len_ftw_store_header_32) + return m_len_ftw_store_header_32; + m_len_ftw_store_header_32 = 28; + f_len_ftw_store_header_32 = true; + return m_len_ftw_store_header_32; +} + +int8_t edk2_ftw_t::len_ftw_store_header_64() { + if (f_len_ftw_store_header_64) + return m_len_ftw_store_header_64; + m_len_ftw_store_header_64 = 32; + f_len_ftw_store_header_64 = true; + return m_len_ftw_store_header_64; +} diff --git a/common/generated/edk2_ftw.h b/common/generated/edk2_ftw.h new file mode 100644 index 0000000..dc03753 --- /dev/null +++ b/common/generated/edk2_ftw.h @@ -0,0 +1,81 @@ +#pragma once + +// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild + +#include "../kaitai/kaitaistruct.h" +#include +#include + +#if KAITAI_STRUCT_VERSION < 9000L +#error "Incompatible Kaitai Struct C++/STL API: version 0.9 or later is required" +#endif + +class edk2_ftw_t : public kaitai::kstruct { + +public: + + edk2_ftw_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = nullptr, edk2_ftw_t* p__root = nullptr); + +private: + void _read(); + void _clean_up(); + +public: + ~edk2_ftw_t(); + +private: + bool f_len_ftw_store_header_32; + int8_t m_len_ftw_store_header_32; + +public: + int8_t len_ftw_store_header_32(); + +private: + bool f_len_ftw_store_header_64; + int8_t m_len_ftw_store_header_64; + +public: + int8_t len_ftw_store_header_64(); + +private: + std::string m_signature; + uint32_t m_crc; + uint8_t m_state; + std::string m_reserved; + uint32_t m_len_write_queue_32; + uint32_t m_len_write_queue_64; + bool n_len_write_queue_64; + +public: + bool _is_null_len_write_queue_64() { len_write_queue_64(); return n_len_write_queue_64; }; + +private: + std::string m_write_queue_32; + bool n_write_queue_32; + +public: + bool _is_null_write_queue_32() { write_queue_32(); return n_write_queue_32; }; + +private: + std::string m_write_queue_64; + bool n_write_queue_64; + +public: + bool _is_null_write_queue_64() { write_queue_64(); return n_write_queue_64; }; + +private: + edk2_ftw_t* m__root; + kaitai::kstruct* m__parent; + +public: + std::string signature() const { return m_signature; } + uint32_t crc() const { return m_crc; } + uint8_t state() const { return m_state; } + std::string reserved() const { return m_reserved; } + uint32_t len_write_queue_32() const { return m_len_write_queue_32; } + uint32_t len_write_queue_64() const { return m_len_write_queue_64; } + std::string write_queue_32() const { return m_write_queue_32; } + std::string write_queue_64() const { return m_write_queue_64; } + edk2_ftw_t* _root() const { return m__root; } + kaitai::kstruct* _parent() const { return m__parent; } +}; diff --git a/common/generated/edk2_vss.cpp b/common/generated/edk2_vss.cpp new file mode 100644 index 0000000..6a5eced --- /dev/null +++ b/common/generated/edk2_vss.cpp @@ -0,0 +1,341 @@ +// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild + +#include "edk2_vss.h" +#include "../kaitai/exceptions.h" + +edk2_vss_t::edk2_vss_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, edk2_vss_t* p__root) : kaitai::kstruct(p__io) { + m__parent = p__parent; + m__root = this; (void)p__root; + m_body = nullptr; + m__io__raw_body = nullptr; + f_len_vss_store_header = false; + _read(); +} + +void edk2_vss_t::_read() { + m_signature = m__io->read_u4le(); + m_vss_size = m__io->read_u4le(); + { + uint32_t _ = vss_size(); + if (!( ((_ > static_cast(len_vss_store_header())) && (_ < 4294967295UL)) )) { + throw kaitai::validation_expr_error(vss_size(), _io(), std::string("/seq/1")); + } + } + m_format = m__io->read_u1(); + m_state = m__io->read_u1(); + m_reserved = m__io->read_u2le(); + m_reserved1 = m__io->read_u4le(); + m__raw_body = m__io->read_bytes((vss_size() - len_vss_store_header())); + m__io__raw_body = std::unique_ptr(new kaitai::kstream(m__raw_body)); + m_body = std::unique_ptr(new vss_store_body_t(m__io__raw_body.get(), this, m__root)); +} + +edk2_vss_t::~edk2_vss_t() { + _clean_up(); +} + +void edk2_vss_t::_clean_up() { +} + +edk2_vss_t::vss_store_body_t::vss_store_body_t(kaitai::kstream* p__io, edk2_vss_t* p__parent, edk2_vss_t* p__root) : kaitai::kstruct(p__io) { + m__parent = p__parent; + m__root = p__root; + m_variables = nullptr; + _read(); +} + +void edk2_vss_t::vss_store_body_t::_read() { + m_variables = std::unique_ptr>>(new std::vector>()); + { + int i = 0; + vss_variable_t* _; + do { + _ = new vss_variable_t(m__io, this, m__root); + m_variables->push_back(std::move(std::unique_ptr(_))); + i++; + } while (!( ((_->signature_first() != 170) || (_io()->is_eof())) )); + } +} + +edk2_vss_t::vss_store_body_t::~vss_store_body_t() { + _clean_up(); +} + +void edk2_vss_t::vss_store_body_t::_clean_up() { +} + +edk2_vss_t::vss_variable_attributes_t::vss_variable_attributes_t(kaitai::kstream* p__io, edk2_vss_t::vss_variable_t* p__parent, edk2_vss_t* p__root) : kaitai::kstruct(p__io) { + m__parent = p__parent; + m__root = p__root; + _read(); +} + +void edk2_vss_t::vss_variable_attributes_t::_read() { + m_non_volatile = m__io->read_bits_int_le(1); + m_boot_service = m__io->read_bits_int_le(1); + m_runtime = m__io->read_bits_int_le(1); + m_hw_error_record = m__io->read_bits_int_le(1); + m_auth_write = m__io->read_bits_int_le(1); + m_time_based_auth = m__io->read_bits_int_le(1); + m_append_write = m__io->read_bits_int_le(1); + m_reserved = m__io->read_bits_int_le(24); + m_apple_data_checksum = m__io->read_bits_int_le(1); +} + +edk2_vss_t::vss_variable_attributes_t::~vss_variable_attributes_t() { + _clean_up(); +} + +void edk2_vss_t::vss_variable_attributes_t::_clean_up() { +} + +edk2_vss_t::vss_variable_t::vss_variable_t(kaitai::kstream* p__io, edk2_vss_t::vss_store_body_t* p__parent, edk2_vss_t* p__root) : kaitai::kstruct(p__io) { + m__parent = p__parent; + m__root = p__root; + m_attributes = nullptr; + f_is_auth = false; + f_len_standard_header = false; + f_is_intel_legacy = false; + f_len_auth_header = false; + f_len_apple_header = false; + f_len_intel_legacy_header = false; + f_is_valid = false; + _read(); +} + +void edk2_vss_t::vss_variable_t::_read() { + m_signature_first = m__io->read_u1(); + n_signature_last = true; + if (signature_first() == 170) { + n_signature_last = false; + m_signature_last = m__io->read_u1(); + { + uint8_t _ = signature_last(); + if (!(_ == 85)) { + throw kaitai::validation_expr_error(signature_last(), _io(), std::string("/types/vss_variable/seq/1")); + } + } + } + n_state = true; + if (signature_first() == 170) { + n_state = false; + m_state = m__io->read_u1(); + } + n_reserved = true; + if (signature_first() == 170) { + n_reserved = false; + m_reserved = m__io->read_u1(); + } + n_attributes = true; + if (signature_first() == 170) { + n_attributes = false; + m_attributes = std::unique_ptr(new vss_variable_attributes_t(m__io, this, m__root)); + } + n_len_total = true; + if ( ((signature_first() == 170) && (is_intel_legacy())) ) { + n_len_total = false; + m_len_total = m__io->read_u4le(); + { + uint32_t _ = len_total(); + if (!(_ >= ((static_cast(len_intel_legacy_header()) + 4) + 1))) { + throw kaitai::validation_expr_error(len_total(), _io(), std::string("/types/vss_variable/seq/5")); + } + } + } + n_len_name = true; + if ( ((signature_first() == 170) && (!(is_intel_legacy()))) ) { + n_len_name = false; + m_len_name = m__io->read_u4le(); + } + n_len_data = true; + if ( ((signature_first() == 170) && (!(is_intel_legacy()))) ) { + n_len_data = false; + m_len_data = m__io->read_u4le(); + } + n_timestamp = true; + if ( ((signature_first() == 170) && (is_auth())) ) { + n_timestamp = false; + m_timestamp = m__io->read_bytes(16); + } + n_pubkey_index = true; + if ( ((signature_first() == 170) && (is_auth())) ) { + n_pubkey_index = false; + m_pubkey_index = m__io->read_u4le(); + } + n_len_name_auth = true; + if ( ((signature_first() == 170) && (is_auth())) ) { + n_len_name_auth = false; + m_len_name_auth = m__io->read_u4le(); + { + uint32_t _ = len_name_auth(); + if (!( ((_ >= 4) && (kaitai::kstream::mod(_, 2) == 0)) )) { + throw kaitai::validation_expr_error(len_name_auth(), _io(), std::string("/types/vss_variable/seq/10")); + } + } + } + n_len_data_auth = true; + if ( ((signature_first() == 170) && (is_auth())) ) { + n_len_data_auth = false; + m_len_data_auth = m__io->read_u4le(); + { + uint32_t _ = len_data_auth(); + if (!(_ > 0)) { + throw kaitai::validation_expr_error(len_data_auth(), _io(), std::string("/types/vss_variable/seq/11")); + } + } + } + n_vendor_guid = true; + if (signature_first() == 170) { + n_vendor_guid = false; + m_vendor_guid = m__io->read_bytes(16); + } + n_name_auth = true; + if ( ((signature_first() == 170) && (is_auth())) ) { + n_name_auth = false; + m_name_auth = m__io->read_bytes(len_name_auth()); + } + n_data_auth = true; + if ( ((signature_first() == 170) && (is_auth())) ) { + n_data_auth = false; + m_data_auth = m__io->read_bytes(len_data_auth()); + } + n_apple_data_crc32 = true; + if ( ((signature_first() == 170) && (!(is_intel_legacy())) && (!(is_auth())) && (attributes()->apple_data_checksum())) ) { + n_apple_data_crc32 = false; + m_apple_data_crc32 = m__io->read_u4le(); + } + n_intel_legacy_data = true; + if ( ((signature_first() == 170) && (is_intel_legacy())) ) { + n_intel_legacy_data = false; + m_intel_legacy_data = m__io->read_bytes((len_total() - len_intel_legacy_header())); + } + n_name = true; + if ( ((signature_first() == 170) && (!(is_intel_legacy())) && (!(is_auth()))) ) { + n_name = false; + m_name = m__io->read_bytes(len_name()); + { + std::string _ = name(); + if (!( ((len_name() >= 4) && (kaitai::kstream::mod(len_name(), 2) == 0)) )) { + throw kaitai::validation_expr_error(name(), _io(), std::string("/types/vss_variable/seq/17")); + } + } + } + n_data = true; + if ( ((signature_first() == 170) && (!(is_intel_legacy())) && (!(is_auth()))) ) { + n_data = false; + m_data = m__io->read_bytes(len_data()); + { + std::string _ = data(); + if (!(len_name() > 0)) { + throw kaitai::validation_expr_error(data(), _io(), std::string("/types/vss_variable/seq/18")); + } + } + } +} + +edk2_vss_t::vss_variable_t::~vss_variable_t() { + _clean_up(); +} + +void edk2_vss_t::vss_variable_t::_clean_up() { + if (!n_signature_last) { + } + if (!n_state) { + } + if (!n_reserved) { + } + if (!n_attributes) { + } + if (!n_len_total) { + } + if (!n_len_name) { + } + if (!n_len_data) { + } + if (!n_timestamp) { + } + if (!n_pubkey_index) { + } + if (!n_len_name_auth) { + } + if (!n_len_data_auth) { + } + if (!n_vendor_guid) { + } + if (!n_name_auth) { + } + if (!n_data_auth) { + } + if (!n_apple_data_crc32) { + } + if (!n_intel_legacy_data) { + } + if (!n_name) { + } + if (!n_data) { + } +} + +bool edk2_vss_t::vss_variable_t::is_auth() { + if (f_is_auth) + return m_is_auth; + m_is_auth = ((state() != 248) && (state() != 252) && ( (( ((attributes()->auth_write()) || (attributes()->time_based_auth()) || (attributes()->append_write())) ) || ( ((len_name() == 0) || (len_data() == 0)) )) )) ; + f_is_auth = true; + return m_is_auth; +} + +int8_t edk2_vss_t::vss_variable_t::len_standard_header() { + if (f_len_standard_header) + return m_len_standard_header; + m_len_standard_header = 32; + f_len_standard_header = true; + return m_len_standard_header; +} + +bool edk2_vss_t::vss_variable_t::is_intel_legacy() { + if (f_is_intel_legacy) + return m_is_intel_legacy; + m_is_intel_legacy = ((state() == 248) || (state() == 252)) ; + f_is_intel_legacy = true; + return m_is_intel_legacy; +} + +int8_t edk2_vss_t::vss_variable_t::len_auth_header() { + if (f_len_auth_header) + return m_len_auth_header; + m_len_auth_header = 60; + f_len_auth_header = true; + return m_len_auth_header; +} + +int8_t edk2_vss_t::vss_variable_t::len_apple_header() { + if (f_len_apple_header) + return m_len_apple_header; + m_len_apple_header = 36; + f_len_apple_header = true; + return m_len_apple_header; +} + +int8_t edk2_vss_t::vss_variable_t::len_intel_legacy_header() { + if (f_len_intel_legacy_header) + return m_len_intel_legacy_header; + m_len_intel_legacy_header = 28; + f_len_intel_legacy_header = true; + return m_len_intel_legacy_header; +} + +bool edk2_vss_t::vss_variable_t::is_valid() { + if (f_is_valid) + return m_is_valid; + m_is_valid = ((state() == 252) || (state() == 127) || (state() == 63)) ; + f_is_valid = true; + return m_is_valid; +} + +int8_t edk2_vss_t::len_vss_store_header() { + if (f_len_vss_store_header) + return m_len_vss_store_header; + m_len_vss_store_header = 16; + f_len_vss_store_header = true; + return m_len_vss_store_header; +} diff --git a/common/generated/edk2_vss.h b/common/generated/edk2_vss.h new file mode 100644 index 0000000..22b9162 --- /dev/null +++ b/common/generated/edk2_vss.h @@ -0,0 +1,343 @@ +#pragma once + +// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild + +#include "../kaitai/kaitaistruct.h" +#include +#include +#include + +#if KAITAI_STRUCT_VERSION < 9000L +#error "Incompatible Kaitai Struct C++/STL API: version 0.9 or later is required" +#endif + +class edk2_vss_t : public kaitai::kstruct { + +public: + class vss_store_body_t; + class vss_variable_attributes_t; + class vss_variable_t; + + edk2_vss_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = nullptr, edk2_vss_t* p__root = nullptr); + +private: + void _read(); + void _clean_up(); + +public: + ~edk2_vss_t(); + + class vss_store_body_t : public kaitai::kstruct { + + public: + + vss_store_body_t(kaitai::kstream* p__io, edk2_vss_t* p__parent = nullptr, edk2_vss_t* p__root = nullptr); + + private: + void _read(); + void _clean_up(); + + public: + ~vss_store_body_t(); + + private: + std::unique_ptr>> m_variables; + edk2_vss_t* m__root; + edk2_vss_t* m__parent; + + public: + std::vector>* variables() const { return m_variables.get(); } + edk2_vss_t* _root() const { return m__root; } + edk2_vss_t* _parent() const { return m__parent; } + }; + + class vss_variable_attributes_t : public kaitai::kstruct { + + public: + + vss_variable_attributes_t(kaitai::kstream* p__io, edk2_vss_t::vss_variable_t* p__parent = nullptr, edk2_vss_t* p__root = nullptr); + + private: + void _read(); + void _clean_up(); + + public: + ~vss_variable_attributes_t(); + + private: + bool m_non_volatile; + bool m_boot_service; + bool m_runtime; + bool m_hw_error_record; + bool m_auth_write; + bool m_time_based_auth; + bool m_append_write; + uint64_t m_reserved; + bool m_apple_data_checksum; + edk2_vss_t* m__root; + edk2_vss_t::vss_variable_t* m__parent; + + public: + bool non_volatile() const { return m_non_volatile; } + bool boot_service() const { return m_boot_service; } + bool runtime() const { return m_runtime; } + bool hw_error_record() const { return m_hw_error_record; } + bool auth_write() const { return m_auth_write; } + bool time_based_auth() const { return m_time_based_auth; } + bool append_write() const { return m_append_write; } + uint64_t reserved() const { return m_reserved; } + bool apple_data_checksum() const { return m_apple_data_checksum; } + edk2_vss_t* _root() const { return m__root; } + edk2_vss_t::vss_variable_t* _parent() const { return m__parent; } + }; + + class vss_variable_t : public kaitai::kstruct { + + public: + + vss_variable_t(kaitai::kstream* p__io, edk2_vss_t::vss_store_body_t* p__parent = nullptr, edk2_vss_t* p__root = nullptr); + + private: + void _read(); + void _clean_up(); + + public: + ~vss_variable_t(); + + private: + bool f_is_auth; + bool m_is_auth; + + public: + bool is_auth(); + + private: + bool f_len_standard_header; + int8_t m_len_standard_header; + + public: + int8_t len_standard_header(); + + private: + bool f_is_intel_legacy; + bool m_is_intel_legacy; + + public: + bool is_intel_legacy(); + + private: + bool f_len_auth_header; + int8_t m_len_auth_header; + + public: + int8_t len_auth_header(); + + private: + bool f_len_apple_header; + int8_t m_len_apple_header; + + public: + int8_t len_apple_header(); + + private: + bool f_len_intel_legacy_header; + int8_t m_len_intel_legacy_header; + + public: + int8_t len_intel_legacy_header(); + + private: + bool f_is_valid; + bool m_is_valid; + + public: + bool is_valid(); + + private: + uint8_t m_signature_first; + uint8_t m_signature_last; + bool n_signature_last; + + public: + bool _is_null_signature_last() { signature_last(); return n_signature_last; }; + + private: + uint8_t m_state; + bool n_state; + + public: + bool _is_null_state() { state(); return n_state; }; + + private: + uint8_t m_reserved; + bool n_reserved; + + public: + bool _is_null_reserved() { reserved(); return n_reserved; }; + + private: + std::unique_ptr m_attributes; + bool n_attributes; + + public: + bool _is_null_attributes() { attributes(); return n_attributes; }; + + private: + uint32_t m_len_total; + bool n_len_total; + + public: + bool _is_null_len_total() { len_total(); return n_len_total; }; + + private: + uint32_t m_len_name; + bool n_len_name; + + public: + bool _is_null_len_name() { len_name(); return n_len_name; }; + + private: + uint32_t m_len_data; + bool n_len_data; + + public: + bool _is_null_len_data() { len_data(); return n_len_data; }; + + private: + std::string m_timestamp; + bool n_timestamp; + + public: + bool _is_null_timestamp() { timestamp(); return n_timestamp; }; + + private: + uint32_t m_pubkey_index; + bool n_pubkey_index; + + public: + bool _is_null_pubkey_index() { pubkey_index(); return n_pubkey_index; }; + + private: + uint32_t m_len_name_auth; + bool n_len_name_auth; + + public: + bool _is_null_len_name_auth() { len_name_auth(); return n_len_name_auth; }; + + private: + uint32_t m_len_data_auth; + bool n_len_data_auth; + + public: + bool _is_null_len_data_auth() { len_data_auth(); return n_len_data_auth; }; + + private: + std::string m_vendor_guid; + bool n_vendor_guid; + + public: + bool _is_null_vendor_guid() { vendor_guid(); return n_vendor_guid; }; + + private: + std::string m_name_auth; + bool n_name_auth; + + public: + bool _is_null_name_auth() { name_auth(); return n_name_auth; }; + + private: + std::string m_data_auth; + bool n_data_auth; + + public: + bool _is_null_data_auth() { data_auth(); return n_data_auth; }; + + private: + uint32_t m_apple_data_crc32; + bool n_apple_data_crc32; + + public: + bool _is_null_apple_data_crc32() { apple_data_crc32(); return n_apple_data_crc32; }; + + private: + std::string m_intel_legacy_data; + bool n_intel_legacy_data; + + public: + bool _is_null_intel_legacy_data() { intel_legacy_data(); return n_intel_legacy_data; }; + + private: + std::string m_name; + bool n_name; + + public: + bool _is_null_name() { name(); return n_name; }; + + private: + std::string m_data; + bool n_data; + + public: + bool _is_null_data() { data(); return n_data; }; + + private: + edk2_vss_t* m__root; + edk2_vss_t::vss_store_body_t* m__parent; + + public: + uint8_t signature_first() const { return m_signature_first; } + uint8_t signature_last() const { return m_signature_last; } + uint8_t state() const { return m_state; } + uint8_t reserved() const { return m_reserved; } + vss_variable_attributes_t* attributes() const { return m_attributes.get(); } + uint32_t len_total() const { return m_len_total; } + uint32_t len_name() const { return m_len_name; } + uint32_t len_data() const { return m_len_data; } + std::string timestamp() const { return m_timestamp; } + uint32_t pubkey_index() const { return m_pubkey_index; } + uint32_t len_name_auth() const { return m_len_name_auth; } + uint32_t len_data_auth() const { return m_len_data_auth; } + std::string vendor_guid() const { return m_vendor_guid; } + std::string name_auth() const { return m_name_auth; } + std::string data_auth() const { return m_data_auth; } + uint32_t apple_data_crc32() const { return m_apple_data_crc32; } + std::string intel_legacy_data() const { return m_intel_legacy_data; } + std::string name() const { return m_name; } + std::string data() const { return m_data; } + edk2_vss_t* _root() const { return m__root; } + edk2_vss_t::vss_store_body_t* _parent() const { return m__parent; } + }; + +private: + bool f_len_vss_store_header; + int8_t m_len_vss_store_header; + +public: + int8_t len_vss_store_header(); + +private: + uint32_t m_signature; + uint32_t m_vss_size; + uint8_t m_format; + uint8_t m_state; + uint16_t m_reserved; + uint32_t m_reserved1; + std::unique_ptr m_body; + edk2_vss_t* m__root; + kaitai::kstruct* m__parent; + std::string m__raw_body; + std::unique_ptr m__io__raw_body; + +public: + uint32_t signature() const { return m_signature; } + uint32_t vss_size() const { return m_vss_size; } + uint8_t format() const { return m_format; } + uint8_t state() const { return m_state; } + uint16_t reserved() const { return m_reserved; } + uint32_t reserved1() const { return m_reserved1; } + vss_store_body_t* body() const { return m_body.get(); } + edk2_vss_t* _root() const { return m__root; } + kaitai::kstruct* _parent() const { return m__parent; } + std::string _raw_body() const { return m__raw_body; } + kaitai::kstream* _io__raw_body() const { return m__io__raw_body.get(); } +}; diff --git a/common/generated/edk2_vss2.cpp b/common/generated/edk2_vss2.cpp new file mode 100644 index 0000000..7e2e3f5 --- /dev/null +++ b/common/generated/edk2_vss2.cpp @@ -0,0 +1,342 @@ +// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild + +#include "edk2_vss2.h" +#include "../kaitai/exceptions.h" + +edk2_vss2_t::edk2_vss2_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, edk2_vss2_t* p__root) : kaitai::kstruct(p__io) { + m__parent = p__parent; + m__root = this; (void)p__root; + m_body = nullptr; + m__io__raw_body = nullptr; + f_len_vss2_store_header = false; + _read(); +} + +void edk2_vss2_t::_read() { + m_signature = m__io->read_bytes(16); + m_vss2_size = m__io->read_u4le(); + { + uint32_t _ = vss2_size(); + if (!( ((_ > static_cast(len_vss2_store_header())) && (_ < 4294967295UL)) )) { + throw kaitai::validation_expr_error(vss2_size(), _io(), std::string("/seq/1")); + } + } + m_format = m__io->read_u1(); + m_state = m__io->read_u1(); + m_reserved = m__io->read_u2le(); + m_reserved1 = m__io->read_u4le(); + m__raw_body = m__io->read_bytes((vss2_size() - len_vss2_store_header())); + m__io__raw_body = std::unique_ptr(new kaitai::kstream(m__raw_body)); + m_body = std::unique_ptr(new vss2_store_body_t(m__io__raw_body.get(), this, m__root)); +} + +edk2_vss2_t::~edk2_vss2_t() { + _clean_up(); +} + +void edk2_vss2_t::_clean_up() { +} + +edk2_vss2_t::vss2_store_body_t::vss2_store_body_t(kaitai::kstream* p__io, edk2_vss2_t* p__parent, edk2_vss2_t* p__root) : kaitai::kstruct(p__io) { + m__parent = p__parent; + m__root = p__root; + m_variables = nullptr; + _read(); +} + +void edk2_vss2_t::vss2_store_body_t::_read() { + m_variables = std::unique_ptr>>(new std::vector>()); + { + int i = 0; + vss2_variable_t* _; + do { + _ = new vss2_variable_t(m__io, this, m__root); + m_variables->push_back(std::move(std::unique_ptr(_))); + i++; + } while (!( ((_->signature_first() != 170) || (_io()->is_eof())) )); + } +} + +edk2_vss2_t::vss2_store_body_t::~vss2_store_body_t() { + _clean_up(); +} + +void edk2_vss2_t::vss2_store_body_t::_clean_up() { +} + +edk2_vss2_t::vss2_variable_attributes_t::vss2_variable_attributes_t(kaitai::kstream* p__io, edk2_vss2_t::vss2_variable_t* p__parent, edk2_vss2_t* p__root) : kaitai::kstruct(p__io) { + m__parent = p__parent; + m__root = p__root; + _read(); +} + +void edk2_vss2_t::vss2_variable_attributes_t::_read() { + m_non_volatile = m__io->read_bits_int_le(1); + m_boot_service = m__io->read_bits_int_le(1); + m_runtime = m__io->read_bits_int_le(1); + m_hw_error_record = m__io->read_bits_int_le(1); + m_auth_write = m__io->read_bits_int_le(1); + m_time_based_auth = m__io->read_bits_int_le(1); + m_append_write = m__io->read_bits_int_le(1); + m_reserved = m__io->read_bits_int_le(25); +} + +edk2_vss2_t::vss2_variable_attributes_t::~vss2_variable_attributes_t() { + _clean_up(); +} + +void edk2_vss2_t::vss2_variable_attributes_t::_clean_up() { +} + +edk2_vss2_t::vss2_variable_t::vss2_variable_t(kaitai::kstream* p__io, edk2_vss2_t::vss2_store_body_t* p__parent, edk2_vss2_t* p__root) : kaitai::kstruct(p__io) { + m__parent = p__parent; + m__root = p__root; + m_attributes = nullptr; + f_is_auth = false; + f_len_standard_header = false; + f_end_offset_auth = false; + f_len_alignment_padding = false; + f_len_auth_header = false; + f_end_offset = false; + f_len_alignment_padding_auth = false; + f_is_valid = false; + f_offset = false; + _read(); +} + +void edk2_vss2_t::vss2_variable_t::_read() { + n_invoke_offset = true; + if (offset() >= 0) { + n_invoke_offset = false; + m_invoke_offset = m__io->read_bytes(0); + } + m_signature_first = m__io->read_u1(); + n_signature_last = true; + if (signature_first() == 170) { + n_signature_last = false; + m_signature_last = m__io->read_u1(); + { + uint8_t _ = signature_last(); + if (!(_ == 85)) { + throw kaitai::validation_expr_error(signature_last(), _io(), std::string("/types/vss2_variable/seq/2")); + } + } + } + n_state = true; + if (signature_first() == 170) { + n_state = false; + m_state = m__io->read_u1(); + } + n_reserved = true; + if (signature_first() == 170) { + n_reserved = false; + m_reserved = m__io->read_u1(); + } + n_attributes = true; + if (signature_first() == 170) { + n_attributes = false; + m_attributes = std::unique_ptr(new vss2_variable_attributes_t(m__io, this, m__root)); + } + n_len_name = true; + if (signature_first() == 170) { + n_len_name = false; + m_len_name = m__io->read_u4le(); + } + n_len_data = true; + if (signature_first() == 170) { + n_len_data = false; + m_len_data = m__io->read_u4le(); + } + n_timestamp = true; + if ( ((signature_first() == 170) && (is_auth())) ) { + n_timestamp = false; + m_timestamp = m__io->read_bytes(16); + } + n_pubkey_index = true; + if ( ((signature_first() == 170) && (is_auth())) ) { + n_pubkey_index = false; + m_pubkey_index = m__io->read_u4le(); + } + n_len_name_auth = true; + if ( ((signature_first() == 170) && (is_auth())) ) { + n_len_name_auth = false; + m_len_name_auth = m__io->read_u4le(); + } + n_len_data_auth = true; + if ( ((signature_first() == 170) && (is_auth())) ) { + n_len_data_auth = false; + m_len_data_auth = m__io->read_u4le(); + } + n_vendor_guid = true; + if (signature_first() == 170) { + n_vendor_guid = false; + m_vendor_guid = m__io->read_bytes(16); + } + n_name_auth = true; + if ( ((signature_first() == 170) && (is_auth())) ) { + n_name_auth = false; + m_name_auth = m__io->read_bytes(len_name_auth()); + } + n_data_auth = true; + if ( ((signature_first() == 170) && (is_auth())) ) { + n_data_auth = false; + m_data_auth = m__io->read_bytes(len_data_auth()); + } + n_invoke_end_offset_auth = true; + if ( ((signature_first() == 170) && (is_auth()) && (end_offset_auth() >= 0)) ) { + n_invoke_end_offset_auth = false; + m_invoke_end_offset_auth = m__io->read_bytes(0); + } + n_alignment_padding_auth = true; + if ( ((signature_first() == 170) && (is_auth())) ) { + n_alignment_padding_auth = false; + m_alignment_padding_auth = m__io->read_bytes(len_alignment_padding_auth()); + } + n_name = true; + if ( ((signature_first() == 170) && (!(is_auth()))) ) { + n_name = false; + m_name = m__io->read_bytes(len_name()); + } + n_data = true; + if ( ((signature_first() == 170) && (!(is_auth()))) ) { + n_data = false; + m_data = m__io->read_bytes(len_data()); + } + n_invoke_end_offset = true; + if ( ((signature_first() == 170) && (!(is_auth())) && (end_offset() >= 0)) ) { + n_invoke_end_offset = false; + m_invoke_end_offset = m__io->read_bytes(0); + } + n_alignment_padding = true; + if ( ((signature_first() == 170) && (!(is_auth()))) ) { + n_alignment_padding = false; + m_alignment_padding = m__io->read_bytes(len_alignment_padding()); + } +} + +edk2_vss2_t::vss2_variable_t::~vss2_variable_t() { + _clean_up(); +} + +void edk2_vss2_t::vss2_variable_t::_clean_up() { + if (!n_invoke_offset) { + } + if (!n_signature_last) { + } + if (!n_state) { + } + if (!n_reserved) { + } + if (!n_attributes) { + } + if (!n_len_name) { + } + if (!n_len_data) { + } + if (!n_timestamp) { + } + if (!n_pubkey_index) { + } + if (!n_len_name_auth) { + } + if (!n_len_data_auth) { + } + if (!n_vendor_guid) { + } + if (!n_name_auth) { + } + if (!n_data_auth) { + } + if (!n_invoke_end_offset_auth) { + } + if (!n_alignment_padding_auth) { + } + if (!n_name) { + } + if (!n_data) { + } + if (!n_invoke_end_offset) { + } + if (!n_alignment_padding) { + } +} + +bool edk2_vss2_t::vss2_variable_t::is_auth() { + if (f_is_auth) + return m_is_auth; + m_is_auth = (( ((attributes()->auth_write()) || (attributes()->time_based_auth()) || (attributes()->append_write())) ) || ( ((len_name() == 0) || (len_data() == 0)) )) ; + f_is_auth = true; + return m_is_auth; +} + +int8_t edk2_vss2_t::vss2_variable_t::len_standard_header() { + if (f_len_standard_header) + return m_len_standard_header; + m_len_standard_header = 32; + f_len_standard_header = true; + return m_len_standard_header; +} + +int32_t edk2_vss2_t::vss2_variable_t::end_offset_auth() { + if (f_end_offset_auth) + return m_end_offset_auth; + m_end_offset_auth = (int32_t)_io()->pos(); + f_end_offset_auth = true; + return m_end_offset_auth; +} + +int32_t edk2_vss2_t::vss2_variable_t::len_alignment_padding() { + if (f_len_alignment_padding) + return m_len_alignment_padding; + m_len_alignment_padding = ((((end_offset() - offset()) + 3) & ~3) - (end_offset() - offset())); + f_len_alignment_padding = true; + return m_len_alignment_padding; +} + +int8_t edk2_vss2_t::vss2_variable_t::len_auth_header() { + if (f_len_auth_header) + return m_len_auth_header; + m_len_auth_header = 60; + f_len_auth_header = true; + return m_len_auth_header; +} + +int32_t edk2_vss2_t::vss2_variable_t::end_offset() { + if (f_end_offset) + return m_end_offset; + m_end_offset = (int32_t)_io()->pos(); + f_end_offset = true; + return m_end_offset; +} + +int32_t edk2_vss2_t::vss2_variable_t::len_alignment_padding_auth() { + if (f_len_alignment_padding_auth) + return m_len_alignment_padding_auth; + m_len_alignment_padding_auth = ((((end_offset_auth() - offset()) + 3) & ~3) - (end_offset_auth() - offset())); + f_len_alignment_padding_auth = true; + return m_len_alignment_padding_auth; +} + +bool edk2_vss2_t::vss2_variable_t::is_valid() { + if (f_is_valid) + return m_is_valid; + m_is_valid = ((state() == 127) || (state() == 63)) ; + f_is_valid = true; + return m_is_valid; +} + +int32_t edk2_vss2_t::vss2_variable_t::offset() { + if (f_offset) + return m_offset; + m_offset = (int32_t)_io()->pos(); + f_offset = true; + return m_offset; +} + +int32_t edk2_vss2_t::len_vss2_store_header() { + if (f_len_vss2_store_header) + return m_len_vss2_store_header; + m_len_vss2_store_header = (7 * 4); + f_len_vss2_store_header = true; + return m_len_vss2_store_header; +} diff --git a/common/generated/edk2_vss2.h b/common/generated/edk2_vss2.h new file mode 100644 index 0000000..3053a8e --- /dev/null +++ b/common/generated/edk2_vss2.h @@ -0,0 +1,371 @@ +#pragma once + +// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild + +#include "../kaitai/kaitaistruct.h" +#include +#include +#include + +#if KAITAI_STRUCT_VERSION < 9000L +#error "Incompatible Kaitai Struct C++/STL API: version 0.9 or later is required" +#endif + +class edk2_vss2_t : public kaitai::kstruct { + +public: + class vss2_store_body_t; + class vss2_variable_attributes_t; + class vss2_variable_t; + + edk2_vss2_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = nullptr, edk2_vss2_t* p__root = nullptr); + +private: + void _read(); + void _clean_up(); + +public: + ~edk2_vss2_t(); + + class vss2_store_body_t : public kaitai::kstruct { + + public: + + vss2_store_body_t(kaitai::kstream* p__io, edk2_vss2_t* p__parent = nullptr, edk2_vss2_t* p__root = nullptr); + + private: + void _read(); + void _clean_up(); + + public: + ~vss2_store_body_t(); + + private: + std::unique_ptr>> m_variables; + edk2_vss2_t* m__root; + edk2_vss2_t* m__parent; + + public: + std::vector>* variables() const { return m_variables.get(); } + edk2_vss2_t* _root() const { return m__root; } + edk2_vss2_t* _parent() const { return m__parent; } + }; + + class vss2_variable_attributes_t : public kaitai::kstruct { + + public: + + vss2_variable_attributes_t(kaitai::kstream* p__io, edk2_vss2_t::vss2_variable_t* p__parent = nullptr, edk2_vss2_t* p__root = nullptr); + + private: + void _read(); + void _clean_up(); + + public: + ~vss2_variable_attributes_t(); + + private: + bool m_non_volatile; + bool m_boot_service; + bool m_runtime; + bool m_hw_error_record; + bool m_auth_write; + bool m_time_based_auth; + bool m_append_write; + uint64_t m_reserved; + edk2_vss2_t* m__root; + edk2_vss2_t::vss2_variable_t* m__parent; + + public: + bool non_volatile() const { return m_non_volatile; } + bool boot_service() const { return m_boot_service; } + bool runtime() const { return m_runtime; } + bool hw_error_record() const { return m_hw_error_record; } + bool auth_write() const { return m_auth_write; } + bool time_based_auth() const { return m_time_based_auth; } + bool append_write() const { return m_append_write; } + uint64_t reserved() const { return m_reserved; } + edk2_vss2_t* _root() const { return m__root; } + edk2_vss2_t::vss2_variable_t* _parent() const { return m__parent; } + }; + + class vss2_variable_t : public kaitai::kstruct { + + public: + + vss2_variable_t(kaitai::kstream* p__io, edk2_vss2_t::vss2_store_body_t* p__parent = nullptr, edk2_vss2_t* p__root = nullptr); + + private: + void _read(); + void _clean_up(); + + public: + ~vss2_variable_t(); + + private: + bool f_is_auth; + bool m_is_auth; + + public: + bool is_auth(); + + private: + bool f_len_standard_header; + int8_t m_len_standard_header; + + public: + int8_t len_standard_header(); + + private: + bool f_end_offset_auth; + int32_t m_end_offset_auth; + + public: + int32_t end_offset_auth(); + + private: + bool f_len_alignment_padding; + int32_t m_len_alignment_padding; + + public: + int32_t len_alignment_padding(); + + private: + bool f_len_auth_header; + int8_t m_len_auth_header; + + public: + int8_t len_auth_header(); + + private: + bool f_end_offset; + int32_t m_end_offset; + + public: + int32_t end_offset(); + + private: + bool f_len_alignment_padding_auth; + int32_t m_len_alignment_padding_auth; + + public: + int32_t len_alignment_padding_auth(); + + private: + bool f_is_valid; + bool m_is_valid; + + public: + bool is_valid(); + + private: + bool f_offset; + int32_t m_offset; + + public: + int32_t offset(); + + private: + std::string m_invoke_offset; + bool n_invoke_offset; + + public: + bool _is_null_invoke_offset() { invoke_offset(); return n_invoke_offset; }; + + private: + uint8_t m_signature_first; + uint8_t m_signature_last; + bool n_signature_last; + + public: + bool _is_null_signature_last() { signature_last(); return n_signature_last; }; + + private: + uint8_t m_state; + bool n_state; + + public: + bool _is_null_state() { state(); return n_state; }; + + private: + uint8_t m_reserved; + bool n_reserved; + + public: + bool _is_null_reserved() { reserved(); return n_reserved; }; + + private: + std::unique_ptr m_attributes; + bool n_attributes; + + public: + bool _is_null_attributes() { attributes(); return n_attributes; }; + + private: + uint32_t m_len_name; + bool n_len_name; + + public: + bool _is_null_len_name() { len_name(); return n_len_name; }; + + private: + uint32_t m_len_data; + bool n_len_data; + + public: + bool _is_null_len_data() { len_data(); return n_len_data; }; + + private: + std::string m_timestamp; + bool n_timestamp; + + public: + bool _is_null_timestamp() { timestamp(); return n_timestamp; }; + + private: + uint32_t m_pubkey_index; + bool n_pubkey_index; + + public: + bool _is_null_pubkey_index() { pubkey_index(); return n_pubkey_index; }; + + private: + uint32_t m_len_name_auth; + bool n_len_name_auth; + + public: + bool _is_null_len_name_auth() { len_name_auth(); return n_len_name_auth; }; + + private: + uint32_t m_len_data_auth; + bool n_len_data_auth; + + public: + bool _is_null_len_data_auth() { len_data_auth(); return n_len_data_auth; }; + + private: + std::string m_vendor_guid; + bool n_vendor_guid; + + public: + bool _is_null_vendor_guid() { vendor_guid(); return n_vendor_guid; }; + + private: + std::string m_name_auth; + bool n_name_auth; + + public: + bool _is_null_name_auth() { name_auth(); return n_name_auth; }; + + private: + std::string m_data_auth; + bool n_data_auth; + + public: + bool _is_null_data_auth() { data_auth(); return n_data_auth; }; + + private: + std::string m_invoke_end_offset_auth; + bool n_invoke_end_offset_auth; + + public: + bool _is_null_invoke_end_offset_auth() { invoke_end_offset_auth(); return n_invoke_end_offset_auth; }; + + private: + std::string m_alignment_padding_auth; + bool n_alignment_padding_auth; + + public: + bool _is_null_alignment_padding_auth() { alignment_padding_auth(); return n_alignment_padding_auth; }; + + private: + std::string m_name; + bool n_name; + + public: + bool _is_null_name() { name(); return n_name; }; + + private: + std::string m_data; + bool n_data; + + public: + bool _is_null_data() { data(); return n_data; }; + + private: + std::string m_invoke_end_offset; + bool n_invoke_end_offset; + + public: + bool _is_null_invoke_end_offset() { invoke_end_offset(); return n_invoke_end_offset; }; + + private: + std::string m_alignment_padding; + bool n_alignment_padding; + + public: + bool _is_null_alignment_padding() { alignment_padding(); return n_alignment_padding; }; + + private: + edk2_vss2_t* m__root; + edk2_vss2_t::vss2_store_body_t* m__parent; + + public: + std::string invoke_offset() const { return m_invoke_offset; } + uint8_t signature_first() const { return m_signature_first; } + uint8_t signature_last() const { return m_signature_last; } + uint8_t state() const { return m_state; } + uint8_t reserved() const { return m_reserved; } + vss2_variable_attributes_t* attributes() const { return m_attributes.get(); } + uint32_t len_name() const { return m_len_name; } + uint32_t len_data() const { return m_len_data; } + std::string timestamp() const { return m_timestamp; } + uint32_t pubkey_index() const { return m_pubkey_index; } + uint32_t len_name_auth() const { return m_len_name_auth; } + uint32_t len_data_auth() const { return m_len_data_auth; } + std::string vendor_guid() const { return m_vendor_guid; } + std::string name_auth() const { return m_name_auth; } + std::string data_auth() const { return m_data_auth; } + std::string invoke_end_offset_auth() const { return m_invoke_end_offset_auth; } + std::string alignment_padding_auth() const { return m_alignment_padding_auth; } + std::string name() const { return m_name; } + std::string data() const { return m_data; } + std::string invoke_end_offset() const { return m_invoke_end_offset; } + std::string alignment_padding() const { return m_alignment_padding; } + edk2_vss2_t* _root() const { return m__root; } + edk2_vss2_t::vss2_store_body_t* _parent() const { return m__parent; } + }; + +private: + bool f_len_vss2_store_header; + int32_t m_len_vss2_store_header; + +public: + int32_t len_vss2_store_header(); + +private: + std::string m_signature; + uint32_t m_vss2_size; + uint8_t m_format; + uint8_t m_state; + uint16_t m_reserved; + uint32_t m_reserved1; + std::unique_ptr m_body; + edk2_vss2_t* m__root; + kaitai::kstruct* m__parent; + std::string m__raw_body; + std::unique_ptr m__io__raw_body; + +public: + std::string signature() const { return m_signature; } + uint32_t vss2_size() const { return m_vss2_size; } + uint8_t format() const { return m_format; } + uint8_t state() const { return m_state; } + uint16_t reserved() const { return m_reserved; } + uint32_t reserved1() const { return m_reserved1; } + vss2_store_body_t* body() const { return m_body.get(); } + edk2_vss2_t* _root() const { return m__root; } + kaitai::kstruct* _parent() const { return m__parent; } + std::string _raw_body() const { return m__raw_body; } + kaitai::kstream* _io__raw_body() const { return m__io__raw_body.get(); } +}; diff --git a/common/generated/insyde_fdc.cpp b/common/generated/insyde_fdc.cpp new file mode 100644 index 0000000..7a3080e --- /dev/null +++ b/common/generated/insyde_fdc.cpp @@ -0,0 +1,38 @@ +// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild + +#include "insyde_fdc.h" +#include "../kaitai/exceptions.h" + +insyde_fdc_t::insyde_fdc_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, insyde_fdc_t* p__root) : kaitai::kstruct(p__io) { + m__parent = p__parent; + m__root = this; (void)p__root; + f_len_fdc_store_header = false; + _read(); +} + +void insyde_fdc_t::_read() { + m_signature = m__io->read_u4le(); + m_fdc_size = m__io->read_u4le(); + { + uint32_t _ = fdc_size(); + if (!( ((_ > static_cast(len_fdc_store_header())) && (_ < 4294967295UL)) )) { + throw kaitai::validation_expr_error(fdc_size(), _io(), std::string("/seq/1")); + } + } + m_body = m__io->read_bytes((fdc_size() - len_fdc_store_header())); +} + +insyde_fdc_t::~insyde_fdc_t() { + _clean_up(); +} + +void insyde_fdc_t::_clean_up() { +} + +int8_t insyde_fdc_t::len_fdc_store_header() { + if (f_len_fdc_store_header) + return m_len_fdc_store_header; + m_len_fdc_store_header = 80; + f_len_fdc_store_header = true; + return m_len_fdc_store_header; +} diff --git a/common/generated/insyde_fdc.h b/common/generated/insyde_fdc.h new file mode 100644 index 0000000..3e8d8a7 --- /dev/null +++ b/common/generated/insyde_fdc.h @@ -0,0 +1,46 @@ +#pragma once + +// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild + +#include "../kaitai/kaitaistruct.h" +#include +#include + +#if KAITAI_STRUCT_VERSION < 9000L +#error "Incompatible Kaitai Struct C++/STL API: version 0.9 or later is required" +#endif + +class insyde_fdc_t : public kaitai::kstruct { + +public: + + insyde_fdc_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = nullptr, insyde_fdc_t* p__root = nullptr); + +private: + void _read(); + void _clean_up(); + +public: + ~insyde_fdc_t(); + +private: + bool f_len_fdc_store_header; + int8_t m_len_fdc_store_header; + +public: + int8_t len_fdc_store_header(); + +private: + uint32_t m_signature; + uint32_t m_fdc_size; + std::string m_body; + insyde_fdc_t* m__root; + kaitai::kstruct* m__parent; + +public: + uint32_t signature() const { return m_signature; } + uint32_t fdc_size() const { return m_fdc_size; } + std::string body() const { return m_body; } + insyde_fdc_t* _root() const { return m__root; } + kaitai::kstruct* _parent() const { return m__parent; } +}; diff --git a/common/generated/insyde_fdm.cpp b/common/generated/insyde_fdm.cpp new file mode 100644 index 0000000..e5942d0 --- /dev/null +++ b/common/generated/insyde_fdm.cpp @@ -0,0 +1,175 @@ +// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild + +#include "insyde_fdm.h" + +insyde_fdm_t::insyde_fdm_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, insyde_fdm_t* p__root) : kaitai::kstruct(p__io) { + m__parent = p__parent; + m__root = this; (void)p__root; + m_extensions = nullptr; + m__io__raw_extensions = nullptr; + m_board_ids = nullptr; + m_entries = nullptr; + m__io__raw_entries = nullptr; + _read(); +} + +void insyde_fdm_t::_read() { + m_signature = m__io->read_u4le(); + m_store_size = m__io->read_u4le(); + m_data_offset = m__io->read_u4le(); + m_entry_size = m__io->read_u4le(); + m_entry_format = m__io->read_u1(); + m_revision = m__io->read_u1(); + m_num_extensions = m__io->read_u1(); + m_checksum = m__io->read_u1(); + m_fd_base_address = m__io->read_u8le(); + n_extensions = true; + if (revision() > 2) { + n_extensions = false; + m__raw_extensions = m__io->read_bytes((num_extensions() * 4)); + m__io__raw_extensions = std::unique_ptr(new kaitai::kstream(m__raw_extensions)); + m_extensions = std::unique_ptr(new fdm_extensions_t(m__io__raw_extensions.get(), this, m__root)); + } + n_board_ids = true; + if ( ((revision() > 2) && (extensions()->extensions()->at(1)->count() > 0)) ) { + n_board_ids = false; + m_board_ids = std::unique_ptr(new fdm_board_ids_t(m__io, this, m__root)); + } + m__raw_entries = m__io->read_bytes((store_size() - data_offset())); + m__io__raw_entries = std::unique_ptr(new kaitai::kstream(m__raw_entries)); + m_entries = std::unique_ptr(new fdm_entries_t(m__io__raw_entries.get(), this, m__root)); +} + +insyde_fdm_t::~insyde_fdm_t() { + _clean_up(); +} + +void insyde_fdm_t::_clean_up() { + if (!n_extensions) { + } + if (!n_board_ids) { + } +} + +insyde_fdm_t::fdm_entries_t::fdm_entries_t(kaitai::kstream* p__io, insyde_fdm_t* p__parent, insyde_fdm_t* p__root) : kaitai::kstruct(p__io) { + m__parent = p__parent; + m__root = p__root; + m_entries = nullptr; + _read(); +} + +void insyde_fdm_t::fdm_entries_t::_read() { + m_entries = std::unique_ptr>>(new std::vector>()); + { + int i = 0; + while (!m__io->is_eof()) { + m_entries->push_back(std::move(std::unique_ptr(new fdm_entry_t(m__io, this, m__root)))); + i++; + } + } +} + +insyde_fdm_t::fdm_entries_t::~fdm_entries_t() { + _clean_up(); +} + +void insyde_fdm_t::fdm_entries_t::_clean_up() { +} + +insyde_fdm_t::fdm_extension_t::fdm_extension_t(kaitai::kstream* p__io, insyde_fdm_t::fdm_extensions_t* p__parent, insyde_fdm_t* p__root) : kaitai::kstruct(p__io) { + m__parent = p__parent; + m__root = p__root; + _read(); +} + +void insyde_fdm_t::fdm_extension_t::_read() { + m_offset = m__io->read_u2le(); + m_count = m__io->read_u2le(); +} + +insyde_fdm_t::fdm_extension_t::~fdm_extension_t() { + _clean_up(); +} + +void insyde_fdm_t::fdm_extension_t::_clean_up() { +} + +insyde_fdm_t::fdm_board_ids_t::fdm_board_ids_t(kaitai::kstream* p__io, insyde_fdm_t* p__parent, insyde_fdm_t* p__root) : kaitai::kstruct(p__io) { + m__parent = p__parent; + m__root = p__root; + m_board_ids = nullptr; + _read(); +} + +void insyde_fdm_t::fdm_board_ids_t::_read() { + m_region_index = m__io->read_u4le(); + m_num_board_ids = m__io->read_u4le(); + m_board_ids = std::unique_ptr>(new std::vector()); + const int l_board_ids = num_board_ids(); + for (int i = 0; i < l_board_ids; i++) { + m_board_ids->push_back(std::move(m__io->read_u8le())); + } +} + +insyde_fdm_t::fdm_board_ids_t::~fdm_board_ids_t() { + _clean_up(); +} + +void insyde_fdm_t::fdm_board_ids_t::_clean_up() { +} + +insyde_fdm_t::fdm_extensions_t::fdm_extensions_t(kaitai::kstream* p__io, insyde_fdm_t* p__parent, insyde_fdm_t* p__root) : kaitai::kstruct(p__io) { + m__parent = p__parent; + m__root = p__root; + m_extensions = nullptr; + _read(); +} + +void insyde_fdm_t::fdm_extensions_t::_read() { + m_extensions = std::unique_ptr>>(new std::vector>()); + { + int i = 0; + while (!m__io->is_eof()) { + m_extensions->push_back(std::move(std::unique_ptr(new fdm_extension_t(m__io, this, m__root)))); + i++; + } + } +} + +insyde_fdm_t::fdm_extensions_t::~fdm_extensions_t() { + _clean_up(); +} + +void insyde_fdm_t::fdm_extensions_t::_clean_up() { +} + +insyde_fdm_t::fdm_entry_t::fdm_entry_t(kaitai::kstream* p__io, insyde_fdm_t::fdm_entries_t* p__parent, insyde_fdm_t* p__root) : kaitai::kstruct(p__io) { + m__parent = p__parent; + m__root = p__root; + f_region_base = false; + _read(); +} + +void insyde_fdm_t::fdm_entry_t::_read() { + m_guid = m__io->read_bytes(16); + m_region_id = m__io->read_bytes(16); + m_region_offset = m__io->read_u8le(); + m_region_size = m__io->read_u8le(); + m_attributes = m__io->read_u4le(); + m_hash = m__io->read_bytes((((((_parent()->_parent()->entry_size() - 16) - 16) - 8) - 8) - 4)); +} + +insyde_fdm_t::fdm_entry_t::~fdm_entry_t() { + _clean_up(); +} + +void insyde_fdm_t::fdm_entry_t::_clean_up() { +} + +int32_t insyde_fdm_t::fdm_entry_t::region_base() { + if (f_region_base) + return m_region_base; + m_region_base = (static_cast(_root()->fd_base_address()) + static_cast(region_offset())); + f_region_base = true; + return m_region_base; +} diff --git a/common/generated/insyde_fdm.h b/common/generated/insyde_fdm.h new file mode 100644 index 0000000..7bbd056 --- /dev/null +++ b/common/generated/insyde_fdm.h @@ -0,0 +1,232 @@ +#pragma once + +// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild + +#include "../kaitai/kaitaistruct.h" +#include +#include +#include + +#if KAITAI_STRUCT_VERSION < 9000L +#error "Incompatible Kaitai Struct C++/STL API: version 0.9 or later is required" +#endif + +class insyde_fdm_t : public kaitai::kstruct { + +public: + class fdm_entries_t; + class fdm_extension_t; + class fdm_board_ids_t; + class fdm_extensions_t; + class fdm_entry_t; + + insyde_fdm_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = nullptr, insyde_fdm_t* p__root = nullptr); + +private: + void _read(); + void _clean_up(); + +public: + ~insyde_fdm_t(); + + class fdm_entries_t : public kaitai::kstruct { + + public: + + fdm_entries_t(kaitai::kstream* p__io, insyde_fdm_t* p__parent = nullptr, insyde_fdm_t* p__root = nullptr); + + private: + void _read(); + void _clean_up(); + + public: + ~fdm_entries_t(); + + private: + std::unique_ptr>> m_entries; + insyde_fdm_t* m__root; + insyde_fdm_t* m__parent; + + public: + std::vector>* entries() const { return m_entries.get(); } + insyde_fdm_t* _root() const { return m__root; } + insyde_fdm_t* _parent() const { return m__parent; } + }; + + class fdm_extension_t : public kaitai::kstruct { + + public: + + fdm_extension_t(kaitai::kstream* p__io, insyde_fdm_t::fdm_extensions_t* p__parent = nullptr, insyde_fdm_t* p__root = nullptr); + + private: + void _read(); + void _clean_up(); + + public: + ~fdm_extension_t(); + + private: + uint16_t m_offset; + uint16_t m_count; + insyde_fdm_t* m__root; + insyde_fdm_t::fdm_extensions_t* m__parent; + + public: + uint16_t offset() const { return m_offset; } + uint16_t count() const { return m_count; } + insyde_fdm_t* _root() const { return m__root; } + insyde_fdm_t::fdm_extensions_t* _parent() const { return m__parent; } + }; + + class fdm_board_ids_t : public kaitai::kstruct { + + public: + + fdm_board_ids_t(kaitai::kstream* p__io, insyde_fdm_t* p__parent = nullptr, insyde_fdm_t* p__root = nullptr); + + private: + void _read(); + void _clean_up(); + + public: + ~fdm_board_ids_t(); + + private: + uint32_t m_region_index; + uint32_t m_num_board_ids; + std::unique_ptr> m_board_ids; + insyde_fdm_t* m__root; + insyde_fdm_t* m__parent; + + public: + uint32_t region_index() const { return m_region_index; } + uint32_t num_board_ids() const { return m_num_board_ids; } + std::vector* board_ids() const { return m_board_ids.get(); } + insyde_fdm_t* _root() const { return m__root; } + insyde_fdm_t* _parent() const { return m__parent; } + }; + + class fdm_extensions_t : public kaitai::kstruct { + + public: + + fdm_extensions_t(kaitai::kstream* p__io, insyde_fdm_t* p__parent = nullptr, insyde_fdm_t* p__root = nullptr); + + private: + void _read(); + void _clean_up(); + + public: + ~fdm_extensions_t(); + + private: + std::unique_ptr>> m_extensions; + insyde_fdm_t* m__root; + insyde_fdm_t* m__parent; + + public: + std::vector>* extensions() const { return m_extensions.get(); } + insyde_fdm_t* _root() const { return m__root; } + insyde_fdm_t* _parent() const { return m__parent; } + }; + + class fdm_entry_t : public kaitai::kstruct { + + public: + + fdm_entry_t(kaitai::kstream* p__io, insyde_fdm_t::fdm_entries_t* p__parent = nullptr, insyde_fdm_t* p__root = nullptr); + + private: + void _read(); + void _clean_up(); + + public: + ~fdm_entry_t(); + + private: + bool f_region_base; + int32_t m_region_base; + + public: + int32_t region_base(); + + private: + std::string m_guid; + std::string m_region_id; + uint64_t m_region_offset; + uint64_t m_region_size; + uint32_t m_attributes; + std::string m_hash; + insyde_fdm_t* m__root; + insyde_fdm_t::fdm_entries_t* m__parent; + + public: + std::string guid() const { return m_guid; } + std::string region_id() const { return m_region_id; } + uint64_t region_offset() const { return m_region_offset; } + uint64_t region_size() const { return m_region_size; } + uint32_t attributes() const { return m_attributes; } + std::string hash() const { return m_hash; } + insyde_fdm_t* _root() const { return m__root; } + insyde_fdm_t::fdm_entries_t* _parent() const { return m__parent; } + }; + +private: + uint32_t m_signature; + uint32_t m_store_size; + uint32_t m_data_offset; + uint32_t m_entry_size; + uint8_t m_entry_format; + uint8_t m_revision; + uint8_t m_num_extensions; + uint8_t m_checksum; + uint64_t m_fd_base_address; + std::unique_ptr m_extensions; + bool n_extensions; + +public: + bool _is_null_extensions() { extensions(); return n_extensions; }; + +private: + std::unique_ptr m_board_ids; + bool n_board_ids; + +public: + bool _is_null_board_ids() { board_ids(); return n_board_ids; }; + +private: + std::unique_ptr m_entries; + insyde_fdm_t* m__root; + kaitai::kstruct* m__parent; + std::string m__raw_extensions; + bool n__raw_extensions; + +public: + bool _is_null__raw_extensions() { _raw_extensions(); return n__raw_extensions; }; + +private: + std::unique_ptr m__io__raw_extensions; + std::string m__raw_entries; + std::unique_ptr m__io__raw_entries; + +public: + uint32_t signature() const { return m_signature; } + uint32_t store_size() const { return m_store_size; } + uint32_t data_offset() const { return m_data_offset; } + uint32_t entry_size() const { return m_entry_size; } + uint8_t entry_format() const { return m_entry_format; } + uint8_t revision() const { return m_revision; } + uint8_t num_extensions() const { return m_num_extensions; } + uint8_t checksum() const { return m_checksum; } + uint64_t fd_base_address() const { return m_fd_base_address; } + fdm_extensions_t* extensions() const { return m_extensions.get(); } + fdm_board_ids_t* board_ids() const { return m_board_ids.get(); } + fdm_entries_t* entries() const { return m_entries.get(); } + insyde_fdm_t* _root() const { return m__root; } + kaitai::kstruct* _parent() const { return m__parent; } + std::string _raw_extensions() const { return m__raw_extensions; } + kaitai::kstream* _io__raw_extensions() const { return m__io__raw_extensions.get(); } + std::string _raw_entries() const { return m__raw_entries; } + kaitai::kstream* _io__raw_entries() const { return m__io__raw_entries.get(); } +}; diff --git a/common/generated/intel_acbp_v1.cpp b/common/generated/intel_acbp_v1.cpp new file mode 100644 index 0000000..92e540e --- /dev/null +++ b/common/generated/intel_acbp_v1.cpp @@ -0,0 +1,346 @@ +// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild + +#include "intel_acbp_v1.h" +#include "../kaitai/exceptions.h" + +intel_acbp_v1_t::intel_acbp_v1_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, intel_acbp_v1_t* p__root) : kaitai::kstruct(p__io) { + m__parent = p__parent; + m__root = this; (void)p__root; + m_elements = nullptr; + _read(); +} + +void intel_acbp_v1_t::_read() { + m_structure_id = static_cast(m__io->read_u8le()); + if (!(structure_id() == intel_acbp_v1_t::STRUCTURE_IDS_ACBP)) { + throw kaitai::validation_not_equal_error(intel_acbp_v1_t::STRUCTURE_IDS_ACBP, structure_id(), _io(), std::string("/seq/0")); + } + m_version = m__io->read_u1(); + { + uint8_t _ = version(); + if (!(_ < 32)) { + throw kaitai::validation_expr_error(version(), _io(), std::string("/seq/1")); + } + } + m_reserved0 = m__io->read_u1(); + m_bpm_revision = m__io->read_u1(); + m_bp_svn = m__io->read_u1(); + m_acm_svn = m__io->read_u1(); + m_reserved1 = m__io->read_u1(); + m_nem_data_size = m__io->read_u2le(); + m_elements = std::unique_ptr>>(new std::vector>()); + { + int i = 0; + acbp_element_t* _; + do { + _ = new acbp_element_t(m__io, this, m__root); + m_elements->push_back(std::move(std::unique_ptr(_))); + i++; + } while (!( ((_->header()->structure_id() == intel_acbp_v1_t::STRUCTURE_IDS_PMSG) || (_io()->is_eof())) )); + } +} + +intel_acbp_v1_t::~intel_acbp_v1_t() { + _clean_up(); +} + +void intel_acbp_v1_t::_clean_up() { +} + +intel_acbp_v1_t::pmsg_body_t::pmsg_body_t(kaitai::kstream* p__io, intel_acbp_v1_t::acbp_element_t* p__parent, intel_acbp_v1_t* p__root) : kaitai::kstruct(p__io) { + m__parent = p__parent; + m__root = p__root; + m_public_key = nullptr; + m_signature = nullptr; + _read(); +} + +void intel_acbp_v1_t::pmsg_body_t::_read() { + m_version = m__io->read_u1(); + m_key_id = m__io->read_u2le(); + m_public_key = std::unique_ptr(new public_key_t(m__io, this, m__root)); + m_sig_scheme = m__io->read_u2le(); + m_signature = std::unique_ptr(new signature_t(m__io, this, m__root)); +} + +intel_acbp_v1_t::pmsg_body_t::~pmsg_body_t() { + _clean_up(); +} + +void intel_acbp_v1_t::pmsg_body_t::_clean_up() { +} + +intel_acbp_v1_t::acbp_element_t::acbp_element_t(kaitai::kstream* p__io, intel_acbp_v1_t* p__parent, intel_acbp_v1_t* p__root) : kaitai::kstruct(p__io) { + m__parent = p__parent; + m__root = p__root; + m_header = nullptr; + m_ibbs_body = nullptr; + m_pmda_body = nullptr; + m_pmsg_body = nullptr; + _read(); +} + +void intel_acbp_v1_t::acbp_element_t::_read() { + m_header = std::unique_ptr(new common_header_t(m__io, this, m__root)); + n_ibbs_body = true; + if (header()->structure_id() == intel_acbp_v1_t::STRUCTURE_IDS_IBBS) { + n_ibbs_body = false; + m_ibbs_body = std::unique_ptr(new ibbs_body_t(m__io, this, m__root)); + } + n_pmda_body = true; + if (header()->structure_id() == intel_acbp_v1_t::STRUCTURE_IDS_PMDA) { + n_pmda_body = false; + m_pmda_body = std::unique_ptr(new pmda_body_t(m__io, this, m__root)); + } + n_pmsg_body = true; + if (header()->structure_id() == intel_acbp_v1_t::STRUCTURE_IDS_PMSG) { + n_pmsg_body = false; + m_pmsg_body = std::unique_ptr(new pmsg_body_t(m__io, this, m__root)); + } + n_invalid_body = true; + if ( ((header()->structure_id() != intel_acbp_v1_t::STRUCTURE_IDS_PMSG) && (header()->structure_id() != intel_acbp_v1_t::STRUCTURE_IDS_PMDA) && (header()->structure_id() != intel_acbp_v1_t::STRUCTURE_IDS_IBBS)) ) { + n_invalid_body = false; + m_invalid_body = m__io->read_bytes(0); + { + std::string _ = invalid_body(); + if (!(false)) { + throw kaitai::validation_expr_error(invalid_body(), _io(), std::string("/types/acbp_element/seq/4")); + } + } + } +} + +intel_acbp_v1_t::acbp_element_t::~acbp_element_t() { + _clean_up(); +} + +void intel_acbp_v1_t::acbp_element_t::_clean_up() { + if (!n_ibbs_body) { + } + if (!n_pmda_body) { + } + if (!n_pmsg_body) { + } + if (!n_invalid_body) { + } +} + +intel_acbp_v1_t::common_header_t::common_header_t(kaitai::kstream* p__io, intel_acbp_v1_t::acbp_element_t* p__parent, intel_acbp_v1_t* p__root) : kaitai::kstruct(p__io) { + m__parent = p__parent; + m__root = p__root; + _read(); +} + +void intel_acbp_v1_t::common_header_t::_read() { + m_structure_id = static_cast(m__io->read_u8le()); + m_version = m__io->read_u1(); +} + +intel_acbp_v1_t::common_header_t::~common_header_t() { + _clean_up(); +} + +void intel_acbp_v1_t::common_header_t::_clean_up() { +} + +intel_acbp_v1_t::signature_t::signature_t(kaitai::kstream* p__io, intel_acbp_v1_t::pmsg_body_t* p__parent, intel_acbp_v1_t* p__root) : kaitai::kstruct(p__io) { + m__parent = p__parent; + m__root = p__root; + _read(); +} + +void intel_acbp_v1_t::signature_t::_read() { + m_version = m__io->read_u1(); + m_size_bits = m__io->read_u2le(); + m_hash_algorithm_id = m__io->read_u2le(); + m_signature = m__io->read_bytes((size_bits() / 8)); +} + +intel_acbp_v1_t::signature_t::~signature_t() { + _clean_up(); +} + +void intel_acbp_v1_t::signature_t::_clean_up() { +} + +intel_acbp_v1_t::pmda_entry_v1_t::pmda_entry_v1_t(kaitai::kstream* p__io, intel_acbp_v1_t::pmda_body_t* p__parent, intel_acbp_v1_t* p__root) : kaitai::kstruct(p__io) { + m__parent = p__parent; + m__root = p__root; + _read(); +} + +void intel_acbp_v1_t::pmda_entry_v1_t::_read() { + m_base = m__io->read_u4le(); + m_size = m__io->read_u4le(); + m_hash = m__io->read_bytes(32); +} + +intel_acbp_v1_t::pmda_entry_v1_t::~pmda_entry_v1_t() { + _clean_up(); +} + +void intel_acbp_v1_t::pmda_entry_v1_t::_clean_up() { +} + +intel_acbp_v1_t::ibb_segment_t::ibb_segment_t(kaitai::kstream* p__io, intel_acbp_v1_t::ibbs_body_t* p__parent, intel_acbp_v1_t* p__root) : kaitai::kstruct(p__io) { + m__parent = p__parent; + m__root = p__root; + _read(); +} + +void intel_acbp_v1_t::ibb_segment_t::_read() { + m_reserved = m__io->read_u2le(); + m_flags = m__io->read_u2le(); + m_base = m__io->read_u4le(); + m_size = m__io->read_u4le(); +} + +intel_acbp_v1_t::ibb_segment_t::~ibb_segment_t() { + _clean_up(); +} + +void intel_acbp_v1_t::ibb_segment_t::_clean_up() { +} + +intel_acbp_v1_t::public_key_t::public_key_t(kaitai::kstream* p__io, intel_acbp_v1_t::pmsg_body_t* p__parent, intel_acbp_v1_t* p__root) : kaitai::kstruct(p__io) { + m__parent = p__parent; + m__root = p__root; + _read(); +} + +void intel_acbp_v1_t::public_key_t::_read() { + m_version = m__io->read_u1(); + m_size_bits = m__io->read_u2le(); + m_exponent = m__io->read_u4le(); + m_modulus = m__io->read_bytes((size_bits() / 8)); +} + +intel_acbp_v1_t::public_key_t::~public_key_t() { + _clean_up(); +} + +void intel_acbp_v1_t::public_key_t::_clean_up() { +} + +intel_acbp_v1_t::hash_t::hash_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, intel_acbp_v1_t* p__root) : kaitai::kstruct(p__io) { + m__parent = p__parent; + m__root = p__root; + _read(); +} + +void intel_acbp_v1_t::hash_t::_read() { + m_hash_algorithm_id = m__io->read_u2le(); + m_len_hash = m__io->read_u2le(); + m_hash = m__io->read_bytes(32); +} + +intel_acbp_v1_t::hash_t::~hash_t() { + _clean_up(); +} + +void intel_acbp_v1_t::hash_t::_clean_up() { +} + +intel_acbp_v1_t::pmda_entry_v2_t::pmda_entry_v2_t(kaitai::kstream* p__io, intel_acbp_v1_t::pmda_body_t* p__parent, intel_acbp_v1_t* p__root) : kaitai::kstruct(p__io) { + m__parent = p__parent; + m__root = p__root; + m_hash = nullptr; + _read(); +} + +void intel_acbp_v1_t::pmda_entry_v2_t::_read() { + m_base = m__io->read_u4le(); + m_size = m__io->read_u4le(); + m_hash = std::unique_ptr(new hash_t(m__io, this, m__root)); +} + +intel_acbp_v1_t::pmda_entry_v2_t::~pmda_entry_v2_t() { + _clean_up(); +} + +void intel_acbp_v1_t::pmda_entry_v2_t::_clean_up() { +} + +intel_acbp_v1_t::ibbs_body_t::ibbs_body_t(kaitai::kstream* p__io, intel_acbp_v1_t::acbp_element_t* p__parent, intel_acbp_v1_t* p__root) : kaitai::kstruct(p__io) { + m__parent = p__parent; + m__root = p__root; + m_reserved = nullptr; + m_post_ibb_hash = nullptr; + m_ibb_hash = nullptr; + m_ibb_segments = nullptr; + _read(); +} + +void intel_acbp_v1_t::ibbs_body_t::_read() { + m_reserved = std::unique_ptr>(new std::vector()); + const int l_reserved = 3; + for (int i = 0; i < l_reserved; i++) { + m_reserved->push_back(std::move(m__io->read_u1())); + } + m_flags = m__io->read_u4le(); + m_mch_bar = m__io->read_u8le(); + m_vtd_bar = m__io->read_u8le(); + m_dma_protection_base0 = m__io->read_u4le(); + m_dma_protection_limit0 = m__io->read_u4le(); + m_dma_protection_base1 = m__io->read_u8le(); + m_dma_protection_limit1 = m__io->read_u8le(); + m_post_ibb_hash = std::unique_ptr(new hash_t(m__io, this, m__root)); + m_ibb_entry_point = m__io->read_u4le(); + m_ibb_hash = std::unique_ptr(new hash_t(m__io, this, m__root)); + m_num_ibb_segments = m__io->read_u1(); + m_ibb_segments = std::unique_ptr>>(new std::vector>()); + const int l_ibb_segments = num_ibb_segments(); + for (int i = 0; i < l_ibb_segments; i++) { + m_ibb_segments->push_back(std::move(std::unique_ptr(new ibb_segment_t(m__io, this, m__root)))); + } +} + +intel_acbp_v1_t::ibbs_body_t::~ibbs_body_t() { + _clean_up(); +} + +void intel_acbp_v1_t::ibbs_body_t::_clean_up() { +} + +intel_acbp_v1_t::pmda_body_t::pmda_body_t(kaitai::kstream* p__io, intel_acbp_v1_t::acbp_element_t* p__parent, intel_acbp_v1_t* p__root) : kaitai::kstruct(p__io) { + m__parent = p__parent; + m__root = p__root; + m_entries_v1 = nullptr; + m_entries_v2 = nullptr; + _read(); +} + +void intel_acbp_v1_t::pmda_body_t::_read() { + m_total_size = m__io->read_u2le(); + m_version = m__io->read_u4le(); + m_num_entries = m__io->read_u4le(); + n_entries_v1 = true; + if (version() == 1) { + n_entries_v1 = false; + m_entries_v1 = std::unique_ptr>>(new std::vector>()); + const int l_entries_v1 = num_entries(); + for (int i = 0; i < l_entries_v1; i++) { + m_entries_v1->push_back(std::move(std::unique_ptr(new pmda_entry_v1_t(m__io, this, m__root)))); + } + } + n_entries_v2 = true; + if (version() == 2) { + n_entries_v2 = false; + m_entries_v2 = std::unique_ptr>>(new std::vector>()); + const int l_entries_v2 = num_entries(); + for (int i = 0; i < l_entries_v2; i++) { + m_entries_v2->push_back(std::move(std::unique_ptr(new pmda_entry_v2_t(m__io, this, m__root)))); + } + } +} + +intel_acbp_v1_t::pmda_body_t::~pmda_body_t() { + _clean_up(); +} + +void intel_acbp_v1_t::pmda_body_t::_clean_up() { + if (!n_entries_v1) { + } + if (!n_entries_v2) { + } +} diff --git a/common/generated/intel_acbp_v1.h b/common/generated/intel_acbp_v1.h new file mode 100644 index 0000000..2296ab6 --- /dev/null +++ b/common/generated/intel_acbp_v1.h @@ -0,0 +1,455 @@ +#pragma once + +// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild + +#include "../kaitai/kaitaistruct.h" +#include +#include +#include + +#if KAITAI_STRUCT_VERSION < 9000L +#error "Incompatible Kaitai Struct C++/STL API: version 0.9 or later is required" +#endif + +class intel_acbp_v1_t : public kaitai::kstruct { + +public: + class pmsg_body_t; + class acbp_element_t; + class common_header_t; + class signature_t; + class pmda_entry_v1_t; + class ibb_segment_t; + class public_key_t; + class hash_t; + class pmda_entry_v2_t; + class ibbs_body_t; + class pmda_body_t; + + enum ibb_segment_type_t { + IBB_SEGMENT_TYPE_IBB = 0, + IBB_SEGMENT_TYPE_NON_IBB = 1 + }; + + enum structure_ids_t : uint64_t { + STRUCTURE_IDS_PMDA = 6872283318001360735LL, + STRUCTURE_IDS_PMSG = 6872289979495636831LL, + STRUCTURE_IDS_ACBP = 6872299801917087583LL, + STRUCTURE_IDS_IBBS = 6872303100435717983LL + }; + + intel_acbp_v1_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = nullptr, intel_acbp_v1_t* p__root = nullptr); + +private: + void _read(); + void _clean_up(); + +public: + ~intel_acbp_v1_t(); + + class pmsg_body_t : public kaitai::kstruct { + + public: + + pmsg_body_t(kaitai::kstream* p__io, intel_acbp_v1_t::acbp_element_t* p__parent = nullptr, intel_acbp_v1_t* p__root = nullptr); + + private: + void _read(); + void _clean_up(); + + public: + ~pmsg_body_t(); + + private: + uint8_t m_version; + uint16_t m_key_id; + std::unique_ptr m_public_key; + uint16_t m_sig_scheme; + std::unique_ptr m_signature; + intel_acbp_v1_t* m__root; + intel_acbp_v1_t::acbp_element_t* m__parent; + + public: + uint8_t version() const { return m_version; } + uint16_t key_id() const { return m_key_id; } + public_key_t* public_key() const { return m_public_key.get(); } + uint16_t sig_scheme() const { return m_sig_scheme; } + signature_t* signature() const { return m_signature.get(); } + intel_acbp_v1_t* _root() const { return m__root; } + intel_acbp_v1_t::acbp_element_t* _parent() const { return m__parent; } + }; + + class acbp_element_t : public kaitai::kstruct { + + public: + + acbp_element_t(kaitai::kstream* p__io, intel_acbp_v1_t* p__parent = nullptr, intel_acbp_v1_t* p__root = nullptr); + + private: + void _read(); + void _clean_up(); + + public: + ~acbp_element_t(); + + private: + std::unique_ptr m_header; + std::unique_ptr m_ibbs_body; + bool n_ibbs_body; + + public: + bool _is_null_ibbs_body() { ibbs_body(); return n_ibbs_body; }; + + private: + std::unique_ptr m_pmda_body; + bool n_pmda_body; + + public: + bool _is_null_pmda_body() { pmda_body(); return n_pmda_body; }; + + private: + std::unique_ptr m_pmsg_body; + bool n_pmsg_body; + + public: + bool _is_null_pmsg_body() { pmsg_body(); return n_pmsg_body; }; + + private: + std::string m_invalid_body; + bool n_invalid_body; + + public: + bool _is_null_invalid_body() { invalid_body(); return n_invalid_body; }; + + private: + intel_acbp_v1_t* m__root; + intel_acbp_v1_t* m__parent; + + public: + common_header_t* header() const { return m_header.get(); } + ibbs_body_t* ibbs_body() const { return m_ibbs_body.get(); } + pmda_body_t* pmda_body() const { return m_pmda_body.get(); } + pmsg_body_t* pmsg_body() const { return m_pmsg_body.get(); } + std::string invalid_body() const { return m_invalid_body; } + intel_acbp_v1_t* _root() const { return m__root; } + intel_acbp_v1_t* _parent() const { return m__parent; } + }; + + class common_header_t : public kaitai::kstruct { + + public: + + common_header_t(kaitai::kstream* p__io, intel_acbp_v1_t::acbp_element_t* p__parent = nullptr, intel_acbp_v1_t* p__root = nullptr); + + private: + void _read(); + void _clean_up(); + + public: + ~common_header_t(); + + private: + structure_ids_t m_structure_id; + uint8_t m_version; + intel_acbp_v1_t* m__root; + intel_acbp_v1_t::acbp_element_t* m__parent; + + public: + structure_ids_t structure_id() const { return m_structure_id; } + uint8_t version() const { return m_version; } + intel_acbp_v1_t* _root() const { return m__root; } + intel_acbp_v1_t::acbp_element_t* _parent() const { return m__parent; } + }; + + class signature_t : public kaitai::kstruct { + + public: + + signature_t(kaitai::kstream* p__io, intel_acbp_v1_t::pmsg_body_t* p__parent = nullptr, intel_acbp_v1_t* p__root = nullptr); + + private: + void _read(); + void _clean_up(); + + public: + ~signature_t(); + + private: + uint8_t m_version; + uint16_t m_size_bits; + uint16_t m_hash_algorithm_id; + std::string m_signature; + intel_acbp_v1_t* m__root; + intel_acbp_v1_t::pmsg_body_t* m__parent; + + public: + uint8_t version() const { return m_version; } + uint16_t size_bits() const { return m_size_bits; } + uint16_t hash_algorithm_id() const { return m_hash_algorithm_id; } + std::string signature() const { return m_signature; } + intel_acbp_v1_t* _root() const { return m__root; } + intel_acbp_v1_t::pmsg_body_t* _parent() const { return m__parent; } + }; + + class pmda_entry_v1_t : public kaitai::kstruct { + + public: + + pmda_entry_v1_t(kaitai::kstream* p__io, intel_acbp_v1_t::pmda_body_t* p__parent = nullptr, intel_acbp_v1_t* p__root = nullptr); + + private: + void _read(); + void _clean_up(); + + public: + ~pmda_entry_v1_t(); + + private: + uint32_t m_base; + uint32_t m_size; + std::string m_hash; + intel_acbp_v1_t* m__root; + intel_acbp_v1_t::pmda_body_t* m__parent; + + public: + uint32_t base() const { return m_base; } + uint32_t size() const { return m_size; } + std::string hash() const { return m_hash; } + intel_acbp_v1_t* _root() const { return m__root; } + intel_acbp_v1_t::pmda_body_t* _parent() const { return m__parent; } + }; + + class ibb_segment_t : public kaitai::kstruct { + + public: + + ibb_segment_t(kaitai::kstream* p__io, intel_acbp_v1_t::ibbs_body_t* p__parent = nullptr, intel_acbp_v1_t* p__root = nullptr); + + private: + void _read(); + void _clean_up(); + + public: + ~ibb_segment_t(); + + private: + uint16_t m_reserved; + uint16_t m_flags; + uint32_t m_base; + uint32_t m_size; + intel_acbp_v1_t* m__root; + intel_acbp_v1_t::ibbs_body_t* m__parent; + + public: + uint16_t reserved() const { return m_reserved; } + uint16_t flags() const { return m_flags; } + uint32_t base() const { return m_base; } + uint32_t size() const { return m_size; } + intel_acbp_v1_t* _root() const { return m__root; } + intel_acbp_v1_t::ibbs_body_t* _parent() const { return m__parent; } + }; + + class public_key_t : public kaitai::kstruct { + + public: + + public_key_t(kaitai::kstream* p__io, intel_acbp_v1_t::pmsg_body_t* p__parent = nullptr, intel_acbp_v1_t* p__root = nullptr); + + private: + void _read(); + void _clean_up(); + + public: + ~public_key_t(); + + private: + uint8_t m_version; + uint16_t m_size_bits; + uint32_t m_exponent; + std::string m_modulus; + intel_acbp_v1_t* m__root; + intel_acbp_v1_t::pmsg_body_t* m__parent; + + public: + uint8_t version() const { return m_version; } + uint16_t size_bits() const { return m_size_bits; } + uint32_t exponent() const { return m_exponent; } + std::string modulus() const { return m_modulus; } + intel_acbp_v1_t* _root() const { return m__root; } + intel_acbp_v1_t::pmsg_body_t* _parent() const { return m__parent; } + }; + + class hash_t : public kaitai::kstruct { + + public: + + hash_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = nullptr, intel_acbp_v1_t* p__root = nullptr); + + private: + void _read(); + void _clean_up(); + + public: + ~hash_t(); + + private: + uint16_t m_hash_algorithm_id; + uint16_t m_len_hash; + std::string m_hash; + intel_acbp_v1_t* m__root; + kaitai::kstruct* m__parent; + + public: + uint16_t hash_algorithm_id() const { return m_hash_algorithm_id; } + uint16_t len_hash() const { return m_len_hash; } + std::string hash() const { return m_hash; } + intel_acbp_v1_t* _root() const { return m__root; } + kaitai::kstruct* _parent() const { return m__parent; } + }; + + class pmda_entry_v2_t : public kaitai::kstruct { + + public: + + pmda_entry_v2_t(kaitai::kstream* p__io, intel_acbp_v1_t::pmda_body_t* p__parent = nullptr, intel_acbp_v1_t* p__root = nullptr); + + private: + void _read(); + void _clean_up(); + + public: + ~pmda_entry_v2_t(); + + private: + uint32_t m_base; + uint32_t m_size; + std::unique_ptr m_hash; + intel_acbp_v1_t* m__root; + intel_acbp_v1_t::pmda_body_t* m__parent; + + public: + uint32_t base() const { return m_base; } + uint32_t size() const { return m_size; } + hash_t* hash() const { return m_hash.get(); } + intel_acbp_v1_t* _root() const { return m__root; } + intel_acbp_v1_t::pmda_body_t* _parent() const { return m__parent; } + }; + + class ibbs_body_t : public kaitai::kstruct { + + public: + + ibbs_body_t(kaitai::kstream* p__io, intel_acbp_v1_t::acbp_element_t* p__parent = nullptr, intel_acbp_v1_t* p__root = nullptr); + + private: + void _read(); + void _clean_up(); + + public: + ~ibbs_body_t(); + + private: + std::unique_ptr> m_reserved; + uint32_t m_flags; + uint64_t m_mch_bar; + uint64_t m_vtd_bar; + uint32_t m_dma_protection_base0; + uint32_t m_dma_protection_limit0; + uint64_t m_dma_protection_base1; + uint64_t m_dma_protection_limit1; + std::unique_ptr m_post_ibb_hash; + uint32_t m_ibb_entry_point; + std::unique_ptr m_ibb_hash; + uint8_t m_num_ibb_segments; + std::unique_ptr>> m_ibb_segments; + intel_acbp_v1_t* m__root; + intel_acbp_v1_t::acbp_element_t* m__parent; + + public: + std::vector* reserved() const { return m_reserved.get(); } + uint32_t flags() const { return m_flags; } + uint64_t mch_bar() const { return m_mch_bar; } + uint64_t vtd_bar() const { return m_vtd_bar; } + uint32_t dma_protection_base0() const { return m_dma_protection_base0; } + uint32_t dma_protection_limit0() const { return m_dma_protection_limit0; } + uint64_t dma_protection_base1() const { return m_dma_protection_base1; } + uint64_t dma_protection_limit1() const { return m_dma_protection_limit1; } + hash_t* post_ibb_hash() const { return m_post_ibb_hash.get(); } + uint32_t ibb_entry_point() const { return m_ibb_entry_point; } + hash_t* ibb_hash() const { return m_ibb_hash.get(); } + uint8_t num_ibb_segments() const { return m_num_ibb_segments; } + std::vector>* ibb_segments() const { return m_ibb_segments.get(); } + intel_acbp_v1_t* _root() const { return m__root; } + intel_acbp_v1_t::acbp_element_t* _parent() const { return m__parent; } + }; + + class pmda_body_t : public kaitai::kstruct { + + public: + + pmda_body_t(kaitai::kstream* p__io, intel_acbp_v1_t::acbp_element_t* p__parent = nullptr, intel_acbp_v1_t* p__root = nullptr); + + private: + void _read(); + void _clean_up(); + + public: + ~pmda_body_t(); + + private: + uint16_t m_total_size; + uint32_t m_version; + uint32_t m_num_entries; + std::unique_ptr>> m_entries_v1; + bool n_entries_v1; + + public: + bool _is_null_entries_v1() { entries_v1(); return n_entries_v1; }; + + private: + std::unique_ptr>> m_entries_v2; + bool n_entries_v2; + + public: + bool _is_null_entries_v2() { entries_v2(); return n_entries_v2; }; + + private: + intel_acbp_v1_t* m__root; + intel_acbp_v1_t::acbp_element_t* m__parent; + + public: + uint16_t total_size() const { return m_total_size; } + uint32_t version() const { return m_version; } + uint32_t num_entries() const { return m_num_entries; } + std::vector>* entries_v1() const { return m_entries_v1.get(); } + std::vector>* entries_v2() const { return m_entries_v2.get(); } + intel_acbp_v1_t* _root() const { return m__root; } + intel_acbp_v1_t::acbp_element_t* _parent() const { return m__parent; } + }; + +private: + structure_ids_t m_structure_id; + uint8_t m_version; + uint8_t m_reserved0; + uint8_t m_bpm_revision; + uint8_t m_bp_svn; + uint8_t m_acm_svn; + uint8_t m_reserved1; + uint16_t m_nem_data_size; + std::unique_ptr>> m_elements; + intel_acbp_v1_t* m__root; + kaitai::kstruct* m__parent; + +public: + structure_ids_t structure_id() const { return m_structure_id; } + uint8_t version() const { return m_version; } + uint8_t reserved0() const { return m_reserved0; } + uint8_t bpm_revision() const { return m_bpm_revision; } + uint8_t bp_svn() const { return m_bp_svn; } + uint8_t acm_svn() const { return m_acm_svn; } + uint8_t reserved1() const { return m_reserved1; } + uint16_t nem_data_size() const { return m_nem_data_size; } + std::vector>* elements() const { return m_elements.get(); } + intel_acbp_v1_t* _root() const { return m__root; } + kaitai::kstruct* _parent() const { return m__parent; } +}; diff --git a/common/generated/intel_acbp_v2.cpp b/common/generated/intel_acbp_v2.cpp new file mode 100644 index 0000000..e6f4e29 --- /dev/null +++ b/common/generated/intel_acbp_v2.cpp @@ -0,0 +1,323 @@ +// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild + +#include "intel_acbp_v2.h" +#include "../kaitai/exceptions.h" + +intel_acbp_v2_t::intel_acbp_v2_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, intel_acbp_v2_t* p__root) : kaitai::kstruct(p__io) { + m__parent = p__parent; + m__root = this; (void)p__root; + m_elements = nullptr; + m_key_signature = nullptr; + _read(); +} + +void intel_acbp_v2_t::_read() { + m_structure_id = static_cast(m__io->read_u8le()); + if (!(structure_id() == intel_acbp_v2_t::STRUCTURE_IDS_ACBP)) { + throw kaitai::validation_not_equal_error(intel_acbp_v2_t::STRUCTURE_IDS_ACBP, structure_id(), _io(), std::string("/seq/0")); + } + m_version = m__io->read_u1(); + { + uint8_t _ = version(); + if (!(_ >= 32)) { + throw kaitai::validation_expr_error(version(), _io(), std::string("/seq/1")); + } + } + m_header_specific = m__io->read_u1(); + m_total_size = m__io->read_u2le(); + if (!(total_size() == 20)) { + throw kaitai::validation_not_equal_error(20, total_size(), _io(), std::string("/seq/3")); + } + m_key_signature_offset = m__io->read_u2le(); + m_bpm_revision = m__io->read_u1(); + m_bp_svn = m__io->read_u1(); + m_acm_svn = m__io->read_u1(); + m_reserved = m__io->read_u1(); + m_nem_data_size = m__io->read_u2le(); + m_elements = std::unique_ptr>>(new std::vector>()); + { + int i = 0; + acbp_element_t* _; + do { + _ = new acbp_element_t(m__io, this, m__root); + m_elements->push_back(std::move(std::unique_ptr(_))); + i++; + } while (!( ((_->header()->total_size() == 0) || (_->header()->structure_id() == intel_acbp_v2_t::STRUCTURE_IDS_PMSG)) )); + } + m_key_signature = std::unique_ptr(new key_signature_t(m__io, this, m__root)); +} + +intel_acbp_v2_t::~intel_acbp_v2_t() { + _clean_up(); +} + +void intel_acbp_v2_t::_clean_up() { +} + +intel_acbp_v2_t::acbp_element_t::acbp_element_t(kaitai::kstream* p__io, intel_acbp_v2_t* p__parent, intel_acbp_v2_t* p__root) : kaitai::kstruct(p__io) { + m__parent = p__parent; + m__root = p__root; + m_header = nullptr; + m_ibbs_body = nullptr; + m_pmda_body = nullptr; + _read(); +} + +void intel_acbp_v2_t::acbp_element_t::_read() { + m_header = std::unique_ptr(new header_t(m__io, this, m__root)); + n_ibbs_body = true; + if ( ((header()->structure_id() == intel_acbp_v2_t::STRUCTURE_IDS_IBBS) && (header()->total_size() >= 12)) ) { + n_ibbs_body = false; + m_ibbs_body = std::unique_ptr(new ibbs_body_t(m__io, this, m__root)); + } + n_pmda_body = true; + if ( ((header()->structure_id() == intel_acbp_v2_t::STRUCTURE_IDS_PMDA) && (header()->total_size() >= 12)) ) { + n_pmda_body = false; + m_pmda_body = std::unique_ptr(new pmda_body_t(m__io, this, m__root)); + } + n_generic_body = true; + if ( ((header()->structure_id() != intel_acbp_v2_t::STRUCTURE_IDS_IBBS) && (header()->structure_id() != intel_acbp_v2_t::STRUCTURE_IDS_PMDA) && (header()->total_size() >= 12)) ) { + n_generic_body = false; + m_generic_body = m__io->read_bytes((header()->total_size() - 12)); + } +} + +intel_acbp_v2_t::acbp_element_t::~acbp_element_t() { + _clean_up(); +} + +void intel_acbp_v2_t::acbp_element_t::_clean_up() { + if (!n_ibbs_body) { + } + if (!n_pmda_body) { + } + if (!n_generic_body) { + } +} + +intel_acbp_v2_t::key_signature_t::key_signature_t(kaitai::kstream* p__io, intel_acbp_v2_t* p__parent, intel_acbp_v2_t* p__root) : kaitai::kstruct(p__io) { + m__parent = p__parent; + m__root = p__root; + m_public_key = nullptr; + m_signature = nullptr; + _read(); +} + +void intel_acbp_v2_t::key_signature_t::_read() { + m_version = m__io->read_u1(); + m_key_id = m__io->read_u2le(); + m_public_key = std::unique_ptr(new public_key_t(m__io, this, m__root)); + m_sig_scheme = m__io->read_u2le(); + m_signature = std::unique_ptr(new signature_t(m__io, this, m__root)); +} + +intel_acbp_v2_t::key_signature_t::~key_signature_t() { + _clean_up(); +} + +void intel_acbp_v2_t::key_signature_t::_clean_up() { +} + +intel_acbp_v2_t::signature_t::signature_t(kaitai::kstream* p__io, intel_acbp_v2_t::key_signature_t* p__parent, intel_acbp_v2_t* p__root) : kaitai::kstruct(p__io) { + m__parent = p__parent; + m__root = p__root; + _read(); +} + +void intel_acbp_v2_t::signature_t::_read() { + m_version = m__io->read_u1(); + m_size_bits = m__io->read_u2le(); + m_hash_algorithm_id = m__io->read_u2le(); + m_signature = m__io->read_bytes((size_bits() / 8)); +} + +intel_acbp_v2_t::signature_t::~signature_t() { + _clean_up(); +} + +void intel_acbp_v2_t::signature_t::_clean_up() { +} + +intel_acbp_v2_t::ibb_segment_t::ibb_segment_t(kaitai::kstream* p__io, intel_acbp_v2_t::ibbs_body_t* p__parent, intel_acbp_v2_t* p__root) : kaitai::kstruct(p__io) { + m__parent = p__parent; + m__root = p__root; + _read(); +} + +void intel_acbp_v2_t::ibb_segment_t::_read() { + m_reserved = m__io->read_u2le(); + m_flags = m__io->read_u2le(); + m_base = m__io->read_u4le(); + m_size = m__io->read_u4le(); +} + +intel_acbp_v2_t::ibb_segment_t::~ibb_segment_t() { + _clean_up(); +} + +void intel_acbp_v2_t::ibb_segment_t::_clean_up() { +} + +intel_acbp_v2_t::public_key_t::public_key_t(kaitai::kstream* p__io, intel_acbp_v2_t::key_signature_t* p__parent, intel_acbp_v2_t* p__root) : kaitai::kstruct(p__io) { + m__parent = p__parent; + m__root = p__root; + _read(); +} + +void intel_acbp_v2_t::public_key_t::_read() { + m_version = m__io->read_u1(); + m_size_bits = m__io->read_u2le(); + m_exponent = m__io->read_u4le(); + m_modulus = m__io->read_bytes((size_bits() / 8)); +} + +intel_acbp_v2_t::public_key_t::~public_key_t() { + _clean_up(); +} + +void intel_acbp_v2_t::public_key_t::_clean_up() { +} + +intel_acbp_v2_t::hash_t::hash_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, intel_acbp_v2_t* p__root) : kaitai::kstruct(p__io) { + m__parent = p__parent; + m__root = p__root; + _read(); +} + +void intel_acbp_v2_t::hash_t::_read() { + m_hash_algorithm_id = m__io->read_u2le(); + m_len_hash = m__io->read_u2le(); + m_hash = m__io->read_bytes(len_hash()); +} + +intel_acbp_v2_t::hash_t::~hash_t() { + _clean_up(); +} + +void intel_acbp_v2_t::hash_t::_clean_up() { +} + +intel_acbp_v2_t::header_t::header_t(kaitai::kstream* p__io, intel_acbp_v2_t::acbp_element_t* p__parent, intel_acbp_v2_t* p__root) : kaitai::kstruct(p__io) { + m__parent = p__parent; + m__root = p__root; + _read(); +} + +void intel_acbp_v2_t::header_t::_read() { + m_structure_id = static_cast(m__io->read_u8le()); + m_version = m__io->read_u1(); + m_header_specific = m__io->read_u1(); + m_total_size = m__io->read_u2le(); +} + +intel_acbp_v2_t::header_t::~header_t() { + _clean_up(); +} + +void intel_acbp_v2_t::header_t::_clean_up() { +} + +intel_acbp_v2_t::pmda_entry_v3_t::pmda_entry_v3_t(kaitai::kstream* p__io, intel_acbp_v2_t::pmda_body_t* p__parent, intel_acbp_v2_t* p__root) : kaitai::kstruct(p__io) { + m__parent = p__parent; + m__root = p__root; + m_hash = nullptr; + _read(); +} + +void intel_acbp_v2_t::pmda_entry_v3_t::_read() { + m_entry_id = m__io->read_u4le(); + m_base = m__io->read_u4le(); + m_size = m__io->read_u4le(); + m_total_entry_size = m__io->read_u2le(); + m_version = m__io->read_u2le(); + m_hash = std::unique_ptr(new hash_t(m__io, this, m__root)); +} + +intel_acbp_v2_t::pmda_entry_v3_t::~pmda_entry_v3_t() { + _clean_up(); +} + +void intel_acbp_v2_t::pmda_entry_v3_t::_clean_up() { +} + +intel_acbp_v2_t::ibbs_body_t::ibbs_body_t(kaitai::kstream* p__io, intel_acbp_v2_t::acbp_element_t* p__parent, intel_acbp_v2_t* p__root) : kaitai::kstruct(p__io) { + m__parent = p__parent; + m__root = p__root; + m_post_ibb_digest = nullptr; + m_ibb_digests = nullptr; + m_obb_digest = nullptr; + m_reserved2 = nullptr; + m_ibb_segments = nullptr; + _read(); +} + +void intel_acbp_v2_t::ibbs_body_t::_read() { + m_reserved0 = m__io->read_u1(); + m_set_number = m__io->read_u1(); + m_reserved1 = m__io->read_u1(); + m_pbet_value = m__io->read_u1(); + m_flags = m__io->read_u4le(); + m_mch_bar = m__io->read_u8le(); + m_vtd_bar = m__io->read_u8le(); + m_dma_protection_base0 = m__io->read_u4le(); + m_dma_protection_limit0 = m__io->read_u4le(); + m_dma_protection_base1 = m__io->read_u8le(); + m_dma_protection_limit1 = m__io->read_u8le(); + m_post_ibb_digest = std::unique_ptr(new hash_t(m__io, this, m__root)); + m_ibb_entry_point = m__io->read_u4le(); + m_ibb_digests_size = m__io->read_u2le(); + m_num_ibb_digests = m__io->read_u2le(); + m_ibb_digests = std::unique_ptr>>(new std::vector>()); + const int l_ibb_digests = num_ibb_digests(); + for (int i = 0; i < l_ibb_digests; i++) { + m_ibb_digests->push_back(std::move(std::unique_ptr(new hash_t(m__io, this, m__root)))); + } + m_obb_digest = std::unique_ptr(new hash_t(m__io, this, m__root)); + m_reserved2 = std::unique_ptr>(new std::vector()); + const int l_reserved2 = 3; + for (int i = 0; i < l_reserved2; i++) { + m_reserved2->push_back(std::move(m__io->read_u1())); + } + m_num_ibb_segments = m__io->read_u1(); + m_ibb_segments = std::unique_ptr>>(new std::vector>()); + const int l_ibb_segments = num_ibb_segments(); + for (int i = 0; i < l_ibb_segments; i++) { + m_ibb_segments->push_back(std::move(std::unique_ptr(new ibb_segment_t(m__io, this, m__root)))); + } +} + +intel_acbp_v2_t::ibbs_body_t::~ibbs_body_t() { + _clean_up(); +} + +void intel_acbp_v2_t::ibbs_body_t::_clean_up() { +} + +intel_acbp_v2_t::pmda_body_t::pmda_body_t(kaitai::kstream* p__io, intel_acbp_v2_t::acbp_element_t* p__parent, intel_acbp_v2_t* p__root) : kaitai::kstruct(p__io) { + m__parent = p__parent; + m__root = p__root; + m_entries = nullptr; + _read(); +} + +void intel_acbp_v2_t::pmda_body_t::_read() { + m_reserved = m__io->read_u2le(); + m_total_size = m__io->read_u2le(); + m_version = m__io->read_u4le(); + if (!(version() == 3)) { + throw kaitai::validation_not_equal_error(3, version(), _io(), std::string("/types/pmda_body/seq/2")); + } + m_num_entries = m__io->read_u4le(); + m_entries = std::unique_ptr>>(new std::vector>()); + const int l_entries = num_entries(); + for (int i = 0; i < l_entries; i++) { + m_entries->push_back(std::move(std::unique_ptr(new pmda_entry_v3_t(m__io, this, m__root)))); + } +} + +intel_acbp_v2_t::pmda_body_t::~pmda_body_t() { + _clean_up(); +} + +void intel_acbp_v2_t::pmda_body_t::_clean_up() { +} diff --git a/common/generated/intel_acbp_v2.h b/common/generated/intel_acbp_v2.h new file mode 100644 index 0000000..24a601e --- /dev/null +++ b/common/generated/intel_acbp_v2.h @@ -0,0 +1,439 @@ +#pragma once + +// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild + +#include "../kaitai/kaitaistruct.h" +#include +#include +#include + +#if KAITAI_STRUCT_VERSION < 9000L +#error "Incompatible Kaitai Struct C++/STL API: version 0.9 or later is required" +#endif + +class intel_acbp_v2_t : public kaitai::kstruct { + +public: + class acbp_element_t; + class key_signature_t; + class signature_t; + class ibb_segment_t; + class public_key_t; + class hash_t; + class header_t; + class pmda_entry_v3_t; + class ibbs_body_t; + class pmda_body_t; + + enum ibb_segment_type_t { + IBB_SEGMENT_TYPE_IBB = 0, + IBB_SEGMENT_TYPE_NON_IBB = 1 + }; + + enum structure_ids_t : uint64_t { + STRUCTURE_IDS_PMDA = 6872283318001360735LL, + STRUCTURE_IDS_PMSG = 6872289979495636831LL, + STRUCTURE_IDS_ACBP = 6872299801917087583LL, + STRUCTURE_IDS_IBBS = 6872303100435717983LL, + STRUCTURE_IDS_PCDS = 6872303109042888543LL, + STRUCTURE_IDS_PFRS = 6872303169222762335LL, + STRUCTURE_IDS_TXTS = 6872303178114948959LL + }; + + intel_acbp_v2_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = nullptr, intel_acbp_v2_t* p__root = nullptr); + +private: + void _read(); + void _clean_up(); + +public: + ~intel_acbp_v2_t(); + + class acbp_element_t : public kaitai::kstruct { + + public: + + acbp_element_t(kaitai::kstream* p__io, intel_acbp_v2_t* p__parent = nullptr, intel_acbp_v2_t* p__root = nullptr); + + private: + void _read(); + void _clean_up(); + + public: + ~acbp_element_t(); + + private: + std::unique_ptr m_header; + std::unique_ptr m_ibbs_body; + bool n_ibbs_body; + + public: + bool _is_null_ibbs_body() { ibbs_body(); return n_ibbs_body; }; + + private: + std::unique_ptr m_pmda_body; + bool n_pmda_body; + + public: + bool _is_null_pmda_body() { pmda_body(); return n_pmda_body; }; + + private: + std::string m_generic_body; + bool n_generic_body; + + public: + bool _is_null_generic_body() { generic_body(); return n_generic_body; }; + + private: + intel_acbp_v2_t* m__root; + intel_acbp_v2_t* m__parent; + + public: + header_t* header() const { return m_header.get(); } + ibbs_body_t* ibbs_body() const { return m_ibbs_body.get(); } + pmda_body_t* pmda_body() const { return m_pmda_body.get(); } + std::string generic_body() const { return m_generic_body; } + intel_acbp_v2_t* _root() const { return m__root; } + intel_acbp_v2_t* _parent() const { return m__parent; } + }; + + class key_signature_t : public kaitai::kstruct { + + public: + + key_signature_t(kaitai::kstream* p__io, intel_acbp_v2_t* p__parent = nullptr, intel_acbp_v2_t* p__root = nullptr); + + private: + void _read(); + void _clean_up(); + + public: + ~key_signature_t(); + + private: + uint8_t m_version; + uint16_t m_key_id; + std::unique_ptr m_public_key; + uint16_t m_sig_scheme; + std::unique_ptr m_signature; + intel_acbp_v2_t* m__root; + intel_acbp_v2_t* m__parent; + + public: + uint8_t version() const { return m_version; } + uint16_t key_id() const { return m_key_id; } + public_key_t* public_key() const { return m_public_key.get(); } + uint16_t sig_scheme() const { return m_sig_scheme; } + signature_t* signature() const { return m_signature.get(); } + intel_acbp_v2_t* _root() const { return m__root; } + intel_acbp_v2_t* _parent() const { return m__parent; } + }; + + class signature_t : public kaitai::kstruct { + + public: + + signature_t(kaitai::kstream* p__io, intel_acbp_v2_t::key_signature_t* p__parent = nullptr, intel_acbp_v2_t* p__root = nullptr); + + private: + void _read(); + void _clean_up(); + + public: + ~signature_t(); + + private: + uint8_t m_version; + uint16_t m_size_bits; + uint16_t m_hash_algorithm_id; + std::string m_signature; + intel_acbp_v2_t* m__root; + intel_acbp_v2_t::key_signature_t* m__parent; + + public: + uint8_t version() const { return m_version; } + uint16_t size_bits() const { return m_size_bits; } + uint16_t hash_algorithm_id() const { return m_hash_algorithm_id; } + std::string signature() const { return m_signature; } + intel_acbp_v2_t* _root() const { return m__root; } + intel_acbp_v2_t::key_signature_t* _parent() const { return m__parent; } + }; + + class ibb_segment_t : public kaitai::kstruct { + + public: + + ibb_segment_t(kaitai::kstream* p__io, intel_acbp_v2_t::ibbs_body_t* p__parent = nullptr, intel_acbp_v2_t* p__root = nullptr); + + private: + void _read(); + void _clean_up(); + + public: + ~ibb_segment_t(); + + private: + uint16_t m_reserved; + uint16_t m_flags; + uint32_t m_base; + uint32_t m_size; + intel_acbp_v2_t* m__root; + intel_acbp_v2_t::ibbs_body_t* m__parent; + + public: + uint16_t reserved() const { return m_reserved; } + uint16_t flags() const { return m_flags; } + uint32_t base() const { return m_base; } + uint32_t size() const { return m_size; } + intel_acbp_v2_t* _root() const { return m__root; } + intel_acbp_v2_t::ibbs_body_t* _parent() const { return m__parent; } + }; + + class public_key_t : public kaitai::kstruct { + + public: + + public_key_t(kaitai::kstream* p__io, intel_acbp_v2_t::key_signature_t* p__parent = nullptr, intel_acbp_v2_t* p__root = nullptr); + + private: + void _read(); + void _clean_up(); + + public: + ~public_key_t(); + + private: + uint8_t m_version; + uint16_t m_size_bits; + uint32_t m_exponent; + std::string m_modulus; + intel_acbp_v2_t* m__root; + intel_acbp_v2_t::key_signature_t* m__parent; + + public: + uint8_t version() const { return m_version; } + uint16_t size_bits() const { return m_size_bits; } + uint32_t exponent() const { return m_exponent; } + std::string modulus() const { return m_modulus; } + intel_acbp_v2_t* _root() const { return m__root; } + intel_acbp_v2_t::key_signature_t* _parent() const { return m__parent; } + }; + + class hash_t : public kaitai::kstruct { + + public: + + hash_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = nullptr, intel_acbp_v2_t* p__root = nullptr); + + private: + void _read(); + void _clean_up(); + + public: + ~hash_t(); + + private: + uint16_t m_hash_algorithm_id; + uint16_t m_len_hash; + std::string m_hash; + intel_acbp_v2_t* m__root; + kaitai::kstruct* m__parent; + + public: + uint16_t hash_algorithm_id() const { return m_hash_algorithm_id; } + uint16_t len_hash() const { return m_len_hash; } + std::string hash() const { return m_hash; } + intel_acbp_v2_t* _root() const { return m__root; } + kaitai::kstruct* _parent() const { return m__parent; } + }; + + class header_t : public kaitai::kstruct { + + public: + + header_t(kaitai::kstream* p__io, intel_acbp_v2_t::acbp_element_t* p__parent = nullptr, intel_acbp_v2_t* p__root = nullptr); + + private: + void _read(); + void _clean_up(); + + public: + ~header_t(); + + private: + structure_ids_t m_structure_id; + uint8_t m_version; + uint8_t m_header_specific; + uint16_t m_total_size; + intel_acbp_v2_t* m__root; + intel_acbp_v2_t::acbp_element_t* m__parent; + + public: + structure_ids_t structure_id() const { return m_structure_id; } + uint8_t version() const { return m_version; } + uint8_t header_specific() const { return m_header_specific; } + uint16_t total_size() const { return m_total_size; } + intel_acbp_v2_t* _root() const { return m__root; } + intel_acbp_v2_t::acbp_element_t* _parent() const { return m__parent; } + }; + + class pmda_entry_v3_t : public kaitai::kstruct { + + public: + + pmda_entry_v3_t(kaitai::kstream* p__io, intel_acbp_v2_t::pmda_body_t* p__parent = nullptr, intel_acbp_v2_t* p__root = nullptr); + + private: + void _read(); + void _clean_up(); + + public: + ~pmda_entry_v3_t(); + + private: + uint32_t m_entry_id; + uint32_t m_base; + uint32_t m_size; + uint16_t m_total_entry_size; + uint16_t m_version; + std::unique_ptr m_hash; + intel_acbp_v2_t* m__root; + intel_acbp_v2_t::pmda_body_t* m__parent; + + public: + uint32_t entry_id() const { return m_entry_id; } + uint32_t base() const { return m_base; } + uint32_t size() const { return m_size; } + uint16_t total_entry_size() const { return m_total_entry_size; } + uint16_t version() const { return m_version; } + hash_t* hash() const { return m_hash.get(); } + intel_acbp_v2_t* _root() const { return m__root; } + intel_acbp_v2_t::pmda_body_t* _parent() const { return m__parent; } + }; + + class ibbs_body_t : public kaitai::kstruct { + + public: + + ibbs_body_t(kaitai::kstream* p__io, intel_acbp_v2_t::acbp_element_t* p__parent = nullptr, intel_acbp_v2_t* p__root = nullptr); + + private: + void _read(); + void _clean_up(); + + public: + ~ibbs_body_t(); + + private: + uint8_t m_reserved0; + uint8_t m_set_number; + uint8_t m_reserved1; + uint8_t m_pbet_value; + uint32_t m_flags; + uint64_t m_mch_bar; + uint64_t m_vtd_bar; + uint32_t m_dma_protection_base0; + uint32_t m_dma_protection_limit0; + uint64_t m_dma_protection_base1; + uint64_t m_dma_protection_limit1; + std::unique_ptr m_post_ibb_digest; + uint32_t m_ibb_entry_point; + uint16_t m_ibb_digests_size; + uint16_t m_num_ibb_digests; + std::unique_ptr>> m_ibb_digests; + std::unique_ptr m_obb_digest; + std::unique_ptr> m_reserved2; + uint8_t m_num_ibb_segments; + std::unique_ptr>> m_ibb_segments; + intel_acbp_v2_t* m__root; + intel_acbp_v2_t::acbp_element_t* m__parent; + + public: + uint8_t reserved0() const { return m_reserved0; } + uint8_t set_number() const { return m_set_number; } + uint8_t reserved1() const { return m_reserved1; } + uint8_t pbet_value() const { return m_pbet_value; } + uint32_t flags() const { return m_flags; } + uint64_t mch_bar() const { return m_mch_bar; } + uint64_t vtd_bar() const { return m_vtd_bar; } + uint32_t dma_protection_base0() const { return m_dma_protection_base0; } + uint32_t dma_protection_limit0() const { return m_dma_protection_limit0; } + uint64_t dma_protection_base1() const { return m_dma_protection_base1; } + uint64_t dma_protection_limit1() const { return m_dma_protection_limit1; } + hash_t* post_ibb_digest() const { return m_post_ibb_digest.get(); } + uint32_t ibb_entry_point() const { return m_ibb_entry_point; } + uint16_t ibb_digests_size() const { return m_ibb_digests_size; } + uint16_t num_ibb_digests() const { return m_num_ibb_digests; } + std::vector>* ibb_digests() const { return m_ibb_digests.get(); } + hash_t* obb_digest() const { return m_obb_digest.get(); } + std::vector* reserved2() const { return m_reserved2.get(); } + uint8_t num_ibb_segments() const { return m_num_ibb_segments; } + std::vector>* ibb_segments() const { return m_ibb_segments.get(); } + intel_acbp_v2_t* _root() const { return m__root; } + intel_acbp_v2_t::acbp_element_t* _parent() const { return m__parent; } + }; + + class pmda_body_t : public kaitai::kstruct { + + public: + + pmda_body_t(kaitai::kstream* p__io, intel_acbp_v2_t::acbp_element_t* p__parent = nullptr, intel_acbp_v2_t* p__root = nullptr); + + private: + void _read(); + void _clean_up(); + + public: + ~pmda_body_t(); + + private: + uint16_t m_reserved; + uint16_t m_total_size; + uint32_t m_version; + uint32_t m_num_entries; + std::unique_ptr>> m_entries; + intel_acbp_v2_t* m__root; + intel_acbp_v2_t::acbp_element_t* m__parent; + + public: + uint16_t reserved() const { return m_reserved; } + uint16_t total_size() const { return m_total_size; } + uint32_t version() const { return m_version; } + uint32_t num_entries() const { return m_num_entries; } + std::vector>* entries() const { return m_entries.get(); } + intel_acbp_v2_t* _root() const { return m__root; } + intel_acbp_v2_t::acbp_element_t* _parent() const { return m__parent; } + }; + +private: + structure_ids_t m_structure_id; + uint8_t m_version; + uint8_t m_header_specific; + uint16_t m_total_size; + uint16_t m_key_signature_offset; + uint8_t m_bpm_revision; + uint8_t m_bp_svn; + uint8_t m_acm_svn; + uint8_t m_reserved; + uint16_t m_nem_data_size; + std::unique_ptr>> m_elements; + std::unique_ptr m_key_signature; + intel_acbp_v2_t* m__root; + kaitai::kstruct* m__parent; + +public: + structure_ids_t structure_id() const { return m_structure_id; } + uint8_t version() const { return m_version; } + uint8_t header_specific() const { return m_header_specific; } + uint16_t total_size() const { return m_total_size; } + uint16_t key_signature_offset() const { return m_key_signature_offset; } + uint8_t bpm_revision() const { return m_bpm_revision; } + uint8_t bp_svn() const { return m_bp_svn; } + uint8_t acm_svn() const { return m_acm_svn; } + uint8_t reserved() const { return m_reserved; } + uint16_t nem_data_size() const { return m_nem_data_size; } + std::vector>* elements() const { return m_elements.get(); } + key_signature_t* key_signature() const { return m_key_signature.get(); } + intel_acbp_v2_t* _root() const { return m__root; } + kaitai::kstruct* _parent() const { return m__parent; } +}; diff --git a/common/generated/intel_acm.cpp b/common/generated/intel_acm.cpp new file mode 100644 index 0000000..8f60062 --- /dev/null +++ b/common/generated/intel_acm.cpp @@ -0,0 +1,77 @@ +// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild + +#include "intel_acm.h" +#include "../kaitai/exceptions.h" + +intel_acm_t::intel_acm_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, intel_acm_t* p__root) : kaitai::kstruct(p__io) { + m__parent = p__parent; + m__root = this; (void)p__root; + m_header = nullptr; + _read(); +} + +void intel_acm_t::_read() { + m_header = std::unique_ptr(new header_t(m__io, this, m__root)); + m_body = m__io->read_bytes((4 * ((header()->module_size() - header()->header_size()) - header()->scratch_space_size()))); +} + +intel_acm_t::~intel_acm_t() { + _clean_up(); +} + +void intel_acm_t::_clean_up() { +} + +intel_acm_t::header_t::header_t(kaitai::kstream* p__io, intel_acm_t* p__parent, intel_acm_t* p__root) : kaitai::kstruct(p__io) { + m__parent = p__parent; + m__root = p__root; + _read(); +} + +void intel_acm_t::header_t::_read() { + m_module_type = m__io->read_u2le(); + if (!(module_type() == 2)) { + throw kaitai::validation_not_equal_error(2, module_type(), _io(), std::string("/types/header/seq/0")); + } + m_module_subtype = static_cast(m__io->read_u2le()); + m_header_size = m__io->read_u4le(); + m_header_version = m__io->read_u4le(); + m_chipset_id = m__io->read_u2le(); + m_flags = m__io->read_u2le(); + m_module_vendor = m__io->read_u4le(); + if (!(module_vendor() == 32902)) { + throw kaitai::validation_not_equal_error(32902, module_vendor(), _io(), std::string("/types/header/seq/6")); + } + m_date_day = m__io->read_u1(); + m_date_month = m__io->read_u1(); + m_date_year = m__io->read_u2le(); + m_module_size = m__io->read_u4le(); + m_acm_svn = m__io->read_u2le(); + m_se_svn = m__io->read_u2le(); + m_code_control_flags = m__io->read_u4le(); + m_error_entry_point = m__io->read_u4le(); + m_gdt_max = m__io->read_u4le(); + m_gdt_base = m__io->read_u4le(); + m_segment_sel = m__io->read_u4le(); + m_entry_point = m__io->read_u4le(); + m_reserved = m__io->read_bytes(64); + m_key_size = m__io->read_u4le(); + m_scratch_space_size = m__io->read_u4le(); + m_rsa_public_key = m__io->read_bytes((4 * key_size())); + n_rsa_exponent = true; + if (header_version() == 0) { + n_rsa_exponent = false; + m_rsa_exponent = m__io->read_u4le(); + } + m_rsa_signature = m__io->read_bytes((4 * key_size())); + m_scratch_space = m__io->read_bytes((4 * scratch_space_size())); +} + +intel_acm_t::header_t::~header_t() { + _clean_up(); +} + +void intel_acm_t::header_t::_clean_up() { + if (!n_rsa_exponent) { + } +} diff --git a/common/generated/intel_acm.h b/common/generated/intel_acm.h new file mode 100644 index 0000000..942070f --- /dev/null +++ b/common/generated/intel_acm.h @@ -0,0 +1,157 @@ +#pragma once + +// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild + +#include "../kaitai/kaitaistruct.h" +#include +#include + +#if KAITAI_STRUCT_VERSION < 9000L +#error "Incompatible Kaitai Struct C++/STL API: version 0.9 or later is required" +#endif + +class intel_acm_t : public kaitai::kstruct { + +public: + class header_t; + + enum module_subtype_t { + MODULE_SUBTYPE_TXT = 0, + MODULE_SUBTYPE_STARTUP = 1, + MODULE_SUBTYPE_BOOT_GUARD = 3 + }; + + enum known_header_version_t { + KNOWN_HEADER_VERSION_V0_0 = 0, + KNOWN_HEADER_VERSION_V3_0 = 196608 + }; + + intel_acm_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = nullptr, intel_acm_t* p__root = nullptr); + +private: + void _read(); + void _clean_up(); + +public: + ~intel_acm_t(); + + class header_t : public kaitai::kstruct { + + public: + + header_t(kaitai::kstream* p__io, intel_acm_t* p__parent = nullptr, intel_acm_t* p__root = nullptr); + + private: + void _read(); + void _clean_up(); + + public: + ~header_t(); + + private: + uint16_t m_module_type; + module_subtype_t m_module_subtype; + uint32_t m_header_size; + uint32_t m_header_version; + uint16_t m_chipset_id; + uint16_t m_flags; + uint32_t m_module_vendor; + uint8_t m_date_day; + uint8_t m_date_month; + uint16_t m_date_year; + uint32_t m_module_size; + uint16_t m_acm_svn; + uint16_t m_se_svn; + uint32_t m_code_control_flags; + uint32_t m_error_entry_point; + uint32_t m_gdt_max; + uint32_t m_gdt_base; + uint32_t m_segment_sel; + uint32_t m_entry_point; + std::string m_reserved; + uint32_t m_key_size; + uint32_t m_scratch_space_size; + std::string m_rsa_public_key; + uint32_t m_rsa_exponent; + bool n_rsa_exponent; + + public: + bool _is_null_rsa_exponent() { rsa_exponent(); return n_rsa_exponent; }; + + private: + std::string m_rsa_signature; + std::string m_scratch_space; + intel_acm_t* m__root; + intel_acm_t* m__parent; + + public: + uint16_t module_type() const { return m_module_type; } + module_subtype_t module_subtype() const { return m_module_subtype; } + + /** + * counted in 4 byte increments + */ + uint32_t header_size() const { return m_header_size; } + uint32_t header_version() const { return m_header_version; } + uint16_t chipset_id() const { return m_chipset_id; } + uint16_t flags() const { return m_flags; } + uint32_t module_vendor() const { return m_module_vendor; } + + /** + * BCD + */ + uint8_t date_day() const { return m_date_day; } + + /** + * BCD + */ + uint8_t date_month() const { return m_date_month; } + + /** + * BCD + */ + uint16_t date_year() const { return m_date_year; } + + /** + * counted in 4 byte increments + */ + uint32_t module_size() const { return m_module_size; } + uint16_t acm_svn() const { return m_acm_svn; } + uint16_t se_svn() const { return m_se_svn; } + uint32_t code_control_flags() const { return m_code_control_flags; } + uint32_t error_entry_point() const { return m_error_entry_point; } + uint32_t gdt_max() const { return m_gdt_max; } + uint32_t gdt_base() const { return m_gdt_base; } + uint32_t segment_sel() const { return m_segment_sel; } + uint32_t entry_point() const { return m_entry_point; } + std::string reserved() const { return m_reserved; } + + /** + * counted in 4 byte increments + */ + uint32_t key_size() const { return m_key_size; } + + /** + * counted in 4 byte increments + */ + uint32_t scratch_space_size() const { return m_scratch_space_size; } + std::string rsa_public_key() const { return m_rsa_public_key; } + uint32_t rsa_exponent() const { return m_rsa_exponent; } + std::string rsa_signature() const { return m_rsa_signature; } + std::string scratch_space() const { return m_scratch_space; } + intel_acm_t* _root() const { return m__root; } + intel_acm_t* _parent() const { return m__parent; } + }; + +private: + std::unique_ptr m_header; + std::string m_body; + intel_acm_t* m__root; + kaitai::kstruct* m__parent; + +public: + header_t* header() const { return m_header.get(); } + std::string body() const { return m_body; } + intel_acm_t* _root() const { return m__root; } + kaitai::kstruct* _parent() const { return m__parent; } +}; diff --git a/common/generated/intel_keym_v1.cpp b/common/generated/intel_keym_v1.cpp new file mode 100644 index 0000000..81f4b0a --- /dev/null +++ b/common/generated/intel_keym_v1.cpp @@ -0,0 +1,120 @@ +// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild + +#include "intel_keym_v1.h" +#include "../kaitai/exceptions.h" + +intel_keym_v1_t::intel_keym_v1_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, intel_keym_v1_t* p__root) : kaitai::kstruct(p__io) { + m__parent = p__parent; + m__root = this; (void)p__root; + m_km_hash = nullptr; + m_key_signature = nullptr; + _read(); +} + +void intel_keym_v1_t::_read() { + m_structure_id = static_cast(m__io->read_u8le()); + if (!(structure_id() == intel_keym_v1_t::STRUCTURE_IDS_KEYM)) { + throw kaitai::validation_not_equal_error(intel_keym_v1_t::STRUCTURE_IDS_KEYM, structure_id(), _io(), std::string("/seq/0")); + } + m_version = m__io->read_u1(); + { + uint8_t _ = version(); + if (!(_ < 32)) { + throw kaitai::validation_expr_error(version(), _io(), std::string("/seq/1")); + } + } + m_km_version = m__io->read_u1(); + m_km_svn = m__io->read_u1(); + m_km_id = m__io->read_u1(); + m_km_hash = std::unique_ptr(new km_hash_t(m__io, this, m__root)); + m_key_signature = std::unique_ptr(new key_signature_t(m__io, this, m__root)); +} + +intel_keym_v1_t::~intel_keym_v1_t() { + _clean_up(); +} + +void intel_keym_v1_t::_clean_up() { +} + +intel_keym_v1_t::km_hash_t::km_hash_t(kaitai::kstream* p__io, intel_keym_v1_t* p__parent, intel_keym_v1_t* p__root) : kaitai::kstruct(p__io) { + m__parent = p__parent; + m__root = p__root; + _read(); +} + +void intel_keym_v1_t::km_hash_t::_read() { + m_hash_algorithm_id = m__io->read_u2le(); + m_len_hash = m__io->read_u2le(); + m_hash = m__io->read_bytes(len_hash()); +} + +intel_keym_v1_t::km_hash_t::~km_hash_t() { + _clean_up(); +} + +void intel_keym_v1_t::km_hash_t::_clean_up() { +} + +intel_keym_v1_t::public_key_t::public_key_t(kaitai::kstream* p__io, intel_keym_v1_t::key_signature_t* p__parent, intel_keym_v1_t* p__root) : kaitai::kstruct(p__io) { + m__parent = p__parent; + m__root = p__root; + _read(); +} + +void intel_keym_v1_t::public_key_t::_read() { + m_version = m__io->read_u1(); + m_size_bits = m__io->read_u2le(); + m_exponent = m__io->read_u4le(); + m_modulus = m__io->read_bytes((size_bits() / 8)); +} + +intel_keym_v1_t::public_key_t::~public_key_t() { + _clean_up(); +} + +void intel_keym_v1_t::public_key_t::_clean_up() { +} + +intel_keym_v1_t::signature_t::signature_t(kaitai::kstream* p__io, intel_keym_v1_t::key_signature_t* p__parent, intel_keym_v1_t* p__root) : kaitai::kstruct(p__io) { + m__parent = p__parent; + m__root = p__root; + _read(); +} + +void intel_keym_v1_t::signature_t::_read() { + m_version = m__io->read_u1(); + m_size_bits = m__io->read_u2le(); + m_hash_algorithm_id = m__io->read_u2le(); + m_signature = m__io->read_bytes((size_bits() / 8)); +} + +intel_keym_v1_t::signature_t::~signature_t() { + _clean_up(); +} + +void intel_keym_v1_t::signature_t::_clean_up() { +} + +intel_keym_v1_t::key_signature_t::key_signature_t(kaitai::kstream* p__io, intel_keym_v1_t* p__parent, intel_keym_v1_t* p__root) : kaitai::kstruct(p__io) { + m__parent = p__parent; + m__root = p__root; + m_public_key = nullptr; + m_signature = nullptr; + _read(); +} + +void intel_keym_v1_t::key_signature_t::_read() { + m_version = m__io->read_u1(); + m_key_id = m__io->read_u2le(); + m_public_key = std::unique_ptr(new public_key_t(m__io, this, m__root)); + m_sig_scheme = m__io->read_u2le(); + m_signature = std::unique_ptr(new signature_t(m__io, this, m__root)); +} + +intel_keym_v1_t::key_signature_t::~key_signature_t() { + _clean_up(); +} + +void intel_keym_v1_t::key_signature_t::_clean_up() { +} diff --git a/common/generated/intel_keym_v1.h b/common/generated/intel_keym_v1.h new file mode 100644 index 0000000..c1c2ec8 --- /dev/null +++ b/common/generated/intel_keym_v1.h @@ -0,0 +1,175 @@ +#pragma once + +// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild + +#include "../kaitai/kaitaistruct.h" +#include +#include + +#if KAITAI_STRUCT_VERSION < 9000L +#error "Incompatible Kaitai Struct C++/STL API: version 0.9 or later is required" +#endif + +class intel_keym_v1_t : public kaitai::kstruct { + +public: + class km_hash_t; + class public_key_t; + class signature_t; + class key_signature_t; + + enum structure_ids_t : uint64_t { + STRUCTURE_IDS_KEYM = 6872296602200661855LL + }; + + intel_keym_v1_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = nullptr, intel_keym_v1_t* p__root = nullptr); + +private: + void _read(); + void _clean_up(); + +public: + ~intel_keym_v1_t(); + + class km_hash_t : public kaitai::kstruct { + + public: + + km_hash_t(kaitai::kstream* p__io, intel_keym_v1_t* p__parent = nullptr, intel_keym_v1_t* p__root = nullptr); + + private: + void _read(); + void _clean_up(); + + public: + ~km_hash_t(); + + private: + uint16_t m_hash_algorithm_id; + uint16_t m_len_hash; + std::string m_hash; + intel_keym_v1_t* m__root; + intel_keym_v1_t* m__parent; + + public: + uint16_t hash_algorithm_id() const { return m_hash_algorithm_id; } + uint16_t len_hash() const { return m_len_hash; } + std::string hash() const { return m_hash; } + intel_keym_v1_t* _root() const { return m__root; } + intel_keym_v1_t* _parent() const { return m__parent; } + }; + + class public_key_t : public kaitai::kstruct { + + public: + + public_key_t(kaitai::kstream* p__io, intel_keym_v1_t::key_signature_t* p__parent = nullptr, intel_keym_v1_t* p__root = nullptr); + + private: + void _read(); + void _clean_up(); + + public: + ~public_key_t(); + + private: + uint8_t m_version; + uint16_t m_size_bits; + uint32_t m_exponent; + std::string m_modulus; + intel_keym_v1_t* m__root; + intel_keym_v1_t::key_signature_t* m__parent; + + public: + uint8_t version() const { return m_version; } + uint16_t size_bits() const { return m_size_bits; } + uint32_t exponent() const { return m_exponent; } + std::string modulus() const { return m_modulus; } + intel_keym_v1_t* _root() const { return m__root; } + intel_keym_v1_t::key_signature_t* _parent() const { return m__parent; } + }; + + class signature_t : public kaitai::kstruct { + + public: + + signature_t(kaitai::kstream* p__io, intel_keym_v1_t::key_signature_t* p__parent = nullptr, intel_keym_v1_t* p__root = nullptr); + + private: + void _read(); + void _clean_up(); + + public: + ~signature_t(); + + private: + uint8_t m_version; + uint16_t m_size_bits; + uint16_t m_hash_algorithm_id; + std::string m_signature; + intel_keym_v1_t* m__root; + intel_keym_v1_t::key_signature_t* m__parent; + + public: + uint8_t version() const { return m_version; } + uint16_t size_bits() const { return m_size_bits; } + uint16_t hash_algorithm_id() const { return m_hash_algorithm_id; } + std::string signature() const { return m_signature; } + intel_keym_v1_t* _root() const { return m__root; } + intel_keym_v1_t::key_signature_t* _parent() const { return m__parent; } + }; + + class key_signature_t : public kaitai::kstruct { + + public: + + key_signature_t(kaitai::kstream* p__io, intel_keym_v1_t* p__parent = nullptr, intel_keym_v1_t* p__root = nullptr); + + private: + void _read(); + void _clean_up(); + + public: + ~key_signature_t(); + + private: + uint8_t m_version; + uint16_t m_key_id; + std::unique_ptr m_public_key; + uint16_t m_sig_scheme; + std::unique_ptr m_signature; + intel_keym_v1_t* m__root; + intel_keym_v1_t* m__parent; + + public: + uint8_t version() const { return m_version; } + uint16_t key_id() const { return m_key_id; } + public_key_t* public_key() const { return m_public_key.get(); } + uint16_t sig_scheme() const { return m_sig_scheme; } + signature_t* signature() const { return m_signature.get(); } + intel_keym_v1_t* _root() const { return m__root; } + intel_keym_v1_t* _parent() const { return m__parent; } + }; + +private: + structure_ids_t m_structure_id; + uint8_t m_version; + uint8_t m_km_version; + uint8_t m_km_svn; + uint8_t m_km_id; + std::unique_ptr m_km_hash; + std::unique_ptr m_key_signature; + intel_keym_v1_t* m__root; + kaitai::kstruct* m__parent; + +public: + structure_ids_t structure_id() const { return m_structure_id; } + uint8_t version() const { return m_version; } + uint8_t km_version() const { return m_km_version; } + uint8_t km_svn() const { return m_km_svn; } + uint8_t km_id() const { return m_km_id; } + km_hash_t* km_hash() const { return m_km_hash.get(); } + key_signature_t* key_signature() const { return m_key_signature.get(); } + intel_keym_v1_t* _root() const { return m__root; } + kaitai::kstruct* _parent() const { return m__parent; } +}; diff --git a/common/generated/intel_keym_v2.cpp b/common/generated/intel_keym_v2.cpp new file mode 100644 index 0000000..f9fd523 --- /dev/null +++ b/common/generated/intel_keym_v2.cpp @@ -0,0 +1,157 @@ +// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild + +#include "intel_keym_v2.h" +#include "../kaitai/exceptions.h" + +intel_keym_v2_t::intel_keym_v2_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, intel_keym_v2_t* p__root) : kaitai::kstruct(p__io) { + m__parent = p__parent; + m__root = this; (void)p__root; + m_header = nullptr; + m_reserved = nullptr; + m_km_hashes = nullptr; + m_key_signature = nullptr; + _read(); +} + +void intel_keym_v2_t::_read() { + m_header = std::unique_ptr(new header_t(m__io, this, m__root)); + m_key_signature_offset = m__io->read_u2le(); + m_reserved = std::unique_ptr>(new std::vector()); + const int l_reserved = 3; + for (int i = 0; i < l_reserved; i++) { + m_reserved->push_back(std::move(m__io->read_u1())); + } + m_km_version = m__io->read_u1(); + m_km_svn = m__io->read_u1(); + m_km_id = m__io->read_u1(); + m_fpf_hash_algorithm_id = m__io->read_u2le(); + m_num_km_hashes = m__io->read_u2le(); + m_km_hashes = std::unique_ptr>>(new std::vector>()); + const int l_km_hashes = num_km_hashes(); + for (int i = 0; i < l_km_hashes; i++) { + m_km_hashes->push_back(std::move(std::unique_ptr(new km_hash_t(m__io, this, m__root)))); + } + m_key_signature = std::unique_ptr(new key_signature_t(m__io, this, m__root)); +} + +intel_keym_v2_t::~intel_keym_v2_t() { + _clean_up(); +} + +void intel_keym_v2_t::_clean_up() { +} + +intel_keym_v2_t::key_signature_t::key_signature_t(kaitai::kstream* p__io, intel_keym_v2_t* p__parent, intel_keym_v2_t* p__root) : kaitai::kstruct(p__io) { + m__parent = p__parent; + m__root = p__root; + m_public_key = nullptr; + m_signature = nullptr; + _read(); +} + +void intel_keym_v2_t::key_signature_t::_read() { + m_version = m__io->read_u1(); + m_key_id = m__io->read_u2le(); + m_public_key = std::unique_ptr(new public_key_t(m__io, this, m__root)); + m_sig_scheme = m__io->read_u2le(); + m_signature = std::unique_ptr(new signature_t(m__io, this, m__root)); +} + +intel_keym_v2_t::key_signature_t::~key_signature_t() { + _clean_up(); +} + +void intel_keym_v2_t::key_signature_t::_clean_up() { +} + +intel_keym_v2_t::km_hash_t::km_hash_t(kaitai::kstream* p__io, intel_keym_v2_t* p__parent, intel_keym_v2_t* p__root) : kaitai::kstruct(p__io) { + m__parent = p__parent; + m__root = p__root; + _read(); +} + +void intel_keym_v2_t::km_hash_t::_read() { + m_usage_flags = m__io->read_u8le(); + m_hash_algorithm_id = m__io->read_u2le(); + m_len_hash = m__io->read_u2le(); + m_hash = m__io->read_bytes(len_hash()); +} + +intel_keym_v2_t::km_hash_t::~km_hash_t() { + _clean_up(); +} + +void intel_keym_v2_t::km_hash_t::_clean_up() { +} + +intel_keym_v2_t::signature_t::signature_t(kaitai::kstream* p__io, intel_keym_v2_t::key_signature_t* p__parent, intel_keym_v2_t* p__root) : kaitai::kstruct(p__io) { + m__parent = p__parent; + m__root = p__root; + _read(); +} + +void intel_keym_v2_t::signature_t::_read() { + m_version = m__io->read_u1(); + m_size_bits = m__io->read_u2le(); + m_hash_algorithm_id = m__io->read_u2le(); + m_signature = m__io->read_bytes((size_bits() / 8)); +} + +intel_keym_v2_t::signature_t::~signature_t() { + _clean_up(); +} + +void intel_keym_v2_t::signature_t::_clean_up() { +} + +intel_keym_v2_t::public_key_t::public_key_t(kaitai::kstream* p__io, intel_keym_v2_t::key_signature_t* p__parent, intel_keym_v2_t* p__root) : kaitai::kstruct(p__io) { + m__parent = p__parent; + m__root = p__root; + _read(); +} + +void intel_keym_v2_t::public_key_t::_read() { + m_version = m__io->read_u1(); + m_size_bits = m__io->read_u2le(); + m_exponent = m__io->read_u4le(); + m_modulus = m__io->read_bytes((size_bits() / 8)); +} + +intel_keym_v2_t::public_key_t::~public_key_t() { + _clean_up(); +} + +void intel_keym_v2_t::public_key_t::_clean_up() { +} + +intel_keym_v2_t::header_t::header_t(kaitai::kstream* p__io, intel_keym_v2_t* p__parent, intel_keym_v2_t* p__root) : kaitai::kstruct(p__io) { + m__parent = p__parent; + m__root = p__root; + _read(); +} + +void intel_keym_v2_t::header_t::_read() { + m_structure_id = static_cast(m__io->read_u8le()); + if (!(structure_id() == intel_keym_v2_t::STRUCTURE_IDS_KEYM)) { + throw kaitai::validation_not_equal_error(intel_keym_v2_t::STRUCTURE_IDS_KEYM, structure_id(), _io(), std::string("/types/header/seq/0")); + } + m_version = m__io->read_u1(); + { + uint8_t _ = version(); + if (!(_ >= 32)) { + throw kaitai::validation_expr_error(version(), _io(), std::string("/types/header/seq/1")); + } + } + m_header_specific = m__io->read_u1(); + m_total_size = m__io->read_u2le(); + if (!(total_size() == 0)) { + throw kaitai::validation_not_equal_error(0, total_size(), _io(), std::string("/types/header/seq/3")); + } +} + +intel_keym_v2_t::header_t::~header_t() { + _clean_up(); +} + +void intel_keym_v2_t::header_t::_clean_up() { +} diff --git a/common/generated/intel_keym_v2.h b/common/generated/intel_keym_v2.h new file mode 100644 index 0000000..1512652 --- /dev/null +++ b/common/generated/intel_keym_v2.h @@ -0,0 +1,222 @@ +#pragma once + +// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild + +#include "../kaitai/kaitaistruct.h" +#include +#include +#include + +#if KAITAI_STRUCT_VERSION < 9000L +#error "Incompatible Kaitai Struct C++/STL API: version 0.9 or later is required" +#endif + +class intel_keym_v2_t : public kaitai::kstruct { + +public: + class key_signature_t; + class km_hash_t; + class signature_t; + class public_key_t; + class header_t; + + enum structure_ids_t : uint64_t { + STRUCTURE_IDS_KEYM = 6872296602200661855LL + }; + + enum km_usage_flags_t { + KM_USAGE_FLAGS_BOOT_POLICY_MANIFEST = 1, + KM_USAGE_FLAGS_FIT_PATCH_MANIFEST = 2, + KM_USAGE_FLAGS_ACM_MANIFEST = 4, + KM_USAGE_FLAGS_SDEV = 8 + }; + + intel_keym_v2_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = nullptr, intel_keym_v2_t* p__root = nullptr); + +private: + void _read(); + void _clean_up(); + +public: + ~intel_keym_v2_t(); + + class key_signature_t : public kaitai::kstruct { + + public: + + key_signature_t(kaitai::kstream* p__io, intel_keym_v2_t* p__parent = nullptr, intel_keym_v2_t* p__root = nullptr); + + private: + void _read(); + void _clean_up(); + + public: + ~key_signature_t(); + + private: + uint8_t m_version; + uint16_t m_key_id; + std::unique_ptr m_public_key; + uint16_t m_sig_scheme; + std::unique_ptr m_signature; + intel_keym_v2_t* m__root; + intel_keym_v2_t* m__parent; + + public: + uint8_t version() const { return m_version; } + uint16_t key_id() const { return m_key_id; } + public_key_t* public_key() const { return m_public_key.get(); } + uint16_t sig_scheme() const { return m_sig_scheme; } + signature_t* signature() const { return m_signature.get(); } + intel_keym_v2_t* _root() const { return m__root; } + intel_keym_v2_t* _parent() const { return m__parent; } + }; + + class km_hash_t : public kaitai::kstruct { + + public: + + km_hash_t(kaitai::kstream* p__io, intel_keym_v2_t* p__parent = nullptr, intel_keym_v2_t* p__root = nullptr); + + private: + void _read(); + void _clean_up(); + + public: + ~km_hash_t(); + + private: + uint64_t m_usage_flags; + uint16_t m_hash_algorithm_id; + uint16_t m_len_hash; + std::string m_hash; + intel_keym_v2_t* m__root; + intel_keym_v2_t* m__parent; + + public: + uint64_t usage_flags() const { return m_usage_flags; } + uint16_t hash_algorithm_id() const { return m_hash_algorithm_id; } + uint16_t len_hash() const { return m_len_hash; } + std::string hash() const { return m_hash; } + intel_keym_v2_t* _root() const { return m__root; } + intel_keym_v2_t* _parent() const { return m__parent; } + }; + + class signature_t : public kaitai::kstruct { + + public: + + signature_t(kaitai::kstream* p__io, intel_keym_v2_t::key_signature_t* p__parent = nullptr, intel_keym_v2_t* p__root = nullptr); + + private: + void _read(); + void _clean_up(); + + public: + ~signature_t(); + + private: + uint8_t m_version; + uint16_t m_size_bits; + uint16_t m_hash_algorithm_id; + std::string m_signature; + intel_keym_v2_t* m__root; + intel_keym_v2_t::key_signature_t* m__parent; + + public: + uint8_t version() const { return m_version; } + uint16_t size_bits() const { return m_size_bits; } + uint16_t hash_algorithm_id() const { return m_hash_algorithm_id; } + std::string signature() const { return m_signature; } + intel_keym_v2_t* _root() const { return m__root; } + intel_keym_v2_t::key_signature_t* _parent() const { return m__parent; } + }; + + class public_key_t : public kaitai::kstruct { + + public: + + public_key_t(kaitai::kstream* p__io, intel_keym_v2_t::key_signature_t* p__parent = nullptr, intel_keym_v2_t* p__root = nullptr); + + private: + void _read(); + void _clean_up(); + + public: + ~public_key_t(); + + private: + uint8_t m_version; + uint16_t m_size_bits; + uint32_t m_exponent; + std::string m_modulus; + intel_keym_v2_t* m__root; + intel_keym_v2_t::key_signature_t* m__parent; + + public: + uint8_t version() const { return m_version; } + uint16_t size_bits() const { return m_size_bits; } + uint32_t exponent() const { return m_exponent; } + std::string modulus() const { return m_modulus; } + intel_keym_v2_t* _root() const { return m__root; } + intel_keym_v2_t::key_signature_t* _parent() const { return m__parent; } + }; + + class header_t : public kaitai::kstruct { + + public: + + header_t(kaitai::kstream* p__io, intel_keym_v2_t* p__parent = nullptr, intel_keym_v2_t* p__root = nullptr); + + private: + void _read(); + void _clean_up(); + + public: + ~header_t(); + + private: + structure_ids_t m_structure_id; + uint8_t m_version; + uint8_t m_header_specific; + uint16_t m_total_size; + intel_keym_v2_t* m__root; + intel_keym_v2_t* m__parent; + + public: + structure_ids_t structure_id() const { return m_structure_id; } + uint8_t version() const { return m_version; } + uint8_t header_specific() const { return m_header_specific; } + uint16_t total_size() const { return m_total_size; } + intel_keym_v2_t* _root() const { return m__root; } + intel_keym_v2_t* _parent() const { return m__parent; } + }; + +private: + std::unique_ptr m_header; + uint16_t m_key_signature_offset; + std::unique_ptr> m_reserved; + uint8_t m_km_version; + uint8_t m_km_svn; + uint8_t m_km_id; + uint16_t m_fpf_hash_algorithm_id; + uint16_t m_num_km_hashes; + std::unique_ptr>> m_km_hashes; + std::unique_ptr m_key_signature; + intel_keym_v2_t* m__root; + kaitai::kstruct* m__parent; + +public: + header_t* header() const { return m_header.get(); } + uint16_t key_signature_offset() const { return m_key_signature_offset; } + std::vector* reserved() const { return m_reserved.get(); } + uint8_t km_version() const { return m_km_version; } + uint8_t km_svn() const { return m_km_svn; } + uint8_t km_id() const { return m_km_id; } + uint16_t fpf_hash_algorithm_id() const { return m_fpf_hash_algorithm_id; } + uint16_t num_km_hashes() const { return m_num_km_hashes; } + std::vector>* km_hashes() const { return m_km_hashes.get(); } + key_signature_t* key_signature() const { return m_key_signature.get(); } + intel_keym_v2_t* _root() const { return m__root; } + kaitai::kstruct* _parent() const { return m__parent; } +}; diff --git a/common/generated/ms_slic_marker.cpp b/common/generated/ms_slic_marker.cpp new file mode 100644 index 0000000..ad7aa00 --- /dev/null +++ b/common/generated/ms_slic_marker.cpp @@ -0,0 +1,28 @@ +// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild + +#include "ms_slic_marker.h" + +ms_slic_marker_t::ms_slic_marker_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, ms_slic_marker_t* p__root) : kaitai::kstruct(p__io) { + m__parent = p__parent; + m__root = this; (void)p__root; + _read(); +} + +void ms_slic_marker_t::_read() { + m_type = m__io->read_u4le(); + m_len_marker = m__io->read_u4le(); + m_version = m__io->read_u4le(); + m_oem_id = m__io->read_bytes(6); + m_oem_table_id = m__io->read_bytes(8); + m_windows_flag = m__io->read_u8le(); + m_slic_version = m__io->read_u4le(); + m_reserved = m__io->read_bytes(16); + m_signature = m__io->read_bytes(128); +} + +ms_slic_marker_t::~ms_slic_marker_t() { + _clean_up(); +} + +void ms_slic_marker_t::_clean_up() { +} diff --git a/common/generated/ms_slic_marker.h b/common/generated/ms_slic_marker.h new file mode 100644 index 0000000..a5935dc --- /dev/null +++ b/common/generated/ms_slic_marker.h @@ -0,0 +1,51 @@ +#pragma once + +// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild + +#include "../kaitai/kaitaistruct.h" +#include +#include + +#if KAITAI_STRUCT_VERSION < 9000L +#error "Incompatible Kaitai Struct C++/STL API: version 0.9 or later is required" +#endif + +class ms_slic_marker_t : public kaitai::kstruct { + +public: + + ms_slic_marker_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = nullptr, ms_slic_marker_t* p__root = nullptr); + +private: + void _read(); + void _clean_up(); + +public: + ~ms_slic_marker_t(); + +private: + uint32_t m_type; + uint32_t m_len_marker; + uint32_t m_version; + std::string m_oem_id; + std::string m_oem_table_id; + uint64_t m_windows_flag; + uint32_t m_slic_version; + std::string m_reserved; + std::string m_signature; + ms_slic_marker_t* m__root; + kaitai::kstruct* m__parent; + +public: + uint32_t type() const { return m_type; } + uint32_t len_marker() const { return m_len_marker; } + uint32_t version() const { return m_version; } + std::string oem_id() const { return m_oem_id; } + std::string oem_table_id() const { return m_oem_table_id; } + uint64_t windows_flag() const { return m_windows_flag; } + uint32_t slic_version() const { return m_slic_version; } + std::string reserved() const { return m_reserved; } + std::string signature() const { return m_signature; } + ms_slic_marker_t* _root() const { return m__root; } + kaitai::kstruct* _parent() const { return m__parent; } +}; diff --git a/common/generated/ms_slic_pubkey.cpp b/common/generated/ms_slic_pubkey.cpp new file mode 100644 index 0000000..bfe2fb9 --- /dev/null +++ b/common/generated/ms_slic_pubkey.cpp @@ -0,0 +1,29 @@ +// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild + +#include "ms_slic_pubkey.h" + +ms_slic_pubkey_t::ms_slic_pubkey_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, ms_slic_pubkey_t* p__root) : kaitai::kstruct(p__io) { + m__parent = p__parent; + m__root = this; (void)p__root; + _read(); +} + +void ms_slic_pubkey_t::_read() { + m_type = m__io->read_u4le(); + m_len_pubkey = m__io->read_u4le(); + m_key_type = m__io->read_u1(); + m_version = m__io->read_u1(); + m_reserved = m__io->read_u2le(); + m_algorithm = m__io->read_u4le(); + m_magic = m__io->read_u4le(); + m_bit_length = m__io->read_u4le(); + m_exponent = m__io->read_u4le(); + m_modulus = m__io->read_bytes(128); +} + +ms_slic_pubkey_t::~ms_slic_pubkey_t() { + _clean_up(); +} + +void ms_slic_pubkey_t::_clean_up() { +} diff --git a/common/generated/ms_slic_pubkey.h b/common/generated/ms_slic_pubkey.h new file mode 100644 index 0000000..75e7361 --- /dev/null +++ b/common/generated/ms_slic_pubkey.h @@ -0,0 +1,53 @@ +#pragma once + +// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild + +#include "../kaitai/kaitaistruct.h" +#include +#include + +#if KAITAI_STRUCT_VERSION < 9000L +#error "Incompatible Kaitai Struct C++/STL API: version 0.9 or later is required" +#endif + +class ms_slic_pubkey_t : public kaitai::kstruct { + +public: + + ms_slic_pubkey_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = nullptr, ms_slic_pubkey_t* p__root = nullptr); + +private: + void _read(); + void _clean_up(); + +public: + ~ms_slic_pubkey_t(); + +private: + uint32_t m_type; + uint32_t m_len_pubkey; + uint8_t m_key_type; + uint8_t m_version; + uint16_t m_reserved; + uint32_t m_algorithm; + uint32_t m_magic; + uint32_t m_bit_length; + uint32_t m_exponent; + std::string m_modulus; + ms_slic_pubkey_t* m__root; + kaitai::kstruct* m__parent; + +public: + uint32_t type() const { return m_type; } + uint32_t len_pubkey() const { return m_len_pubkey; } + uint8_t key_type() const { return m_key_type; } + uint8_t version() const { return m_version; } + uint16_t reserved() const { return m_reserved; } + uint32_t algorithm() const { return m_algorithm; } + uint32_t magic() const { return m_magic; } + uint32_t bit_length() const { return m_bit_length; } + uint32_t exponent() const { return m_exponent; } + std::string modulus() const { return m_modulus; } + ms_slic_pubkey_t* _root() const { return m__root; } + kaitai::kstruct* _parent() const { return m__parent; } +}; diff --git a/common/generated/phoenix_evsa.cpp b/common/generated/phoenix_evsa.cpp new file mode 100644 index 0000000..c586711 --- /dev/null +++ b/common/generated/phoenix_evsa.cpp @@ -0,0 +1,259 @@ +// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild + +#include "phoenix_evsa.h" +#include "../kaitai/exceptions.h" + +phoenix_evsa_t::phoenix_evsa_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, phoenix_evsa_t* p__root) : kaitai::kstruct(p__io) { + m__parent = p__parent; + m__root = this; (void)p__root; + m_body = nullptr; + m__io__raw_body = nullptr; + _read(); +} + +void phoenix_evsa_t::_read() { + m_type = m__io->read_u1(); + m_checksum = m__io->read_u1(); + m_len_evsa_store_header = m__io->read_u2le(); + m_signature = m__io->read_u4le(); + m_attributes = m__io->read_u4le(); + m_len_evsa_store = m__io->read_u4le(); + m_reserved = m__io->read_u4le(); + m__raw_body = m__io->read_bytes((len_evsa_store() - len_evsa_store_header())); + m__io__raw_body = std::unique_ptr(new kaitai::kstream(m__raw_body)); + m_body = std::unique_ptr(new evsa_body_t(m__io__raw_body.get(), this, m__root)); +} + +phoenix_evsa_t::~phoenix_evsa_t() { + _clean_up(); +} + +void phoenix_evsa_t::_clean_up() { +} + +phoenix_evsa_t::evsa_entry_t::evsa_entry_t(kaitai::kstream* p__io, phoenix_evsa_t::evsa_body_t* p__parent, phoenix_evsa_t* p__root) : kaitai::kstruct(p__io) { + m__parent = p__parent; + m__root = p__root; + _read(); +} + +void phoenix_evsa_t::evsa_entry_t::_read() { + m_entry_type = m__io->read_u1(); + n_checksum = true; + if ( ((entry_type() == 225) || (entry_type() == 226) || (entry_type() == 227) || (entry_type() == 237) || (entry_type() == 238) || (entry_type() == 239) || (entry_type() == 131)) ) { + n_checksum = false; + m_checksum = m__io->read_u1(); + } + n_len_evsa_entry = true; + if ( ((entry_type() == 225) || (entry_type() == 226) || (entry_type() == 227) || (entry_type() == 237) || (entry_type() == 238) || (entry_type() == 239) || (entry_type() == 131)) ) { + n_len_evsa_entry = false; + m_len_evsa_entry = m__io->read_u2le(); + } + switch (entry_type()) { + case 239: { + m_body = std::unique_ptr(new evsa_data_t(m__io, this, m__root)); + break; + } + case 131: { + m_body = std::unique_ptr(new evsa_data_t(m__io, this, m__root)); + break; + } + case 227: { + m_body = std::unique_ptr(new evsa_data_t(m__io, this, m__root)); + break; + } + case 237: { + m_body = std::unique_ptr(new evsa_guid_t(m__io, this, m__root)); + break; + } + case 226: { + m_body = std::unique_ptr(new evsa_name_t(m__io, this, m__root)); + break; + } + case 225: { + m_body = std::unique_ptr(new evsa_guid_t(m__io, this, m__root)); + break; + } + case 238: { + m_body = std::unique_ptr(new evsa_name_t(m__io, this, m__root)); + break; + } + default: { + m_body = std::unique_ptr(new evsa_unknown_t(m__io, this, m__root)); + break; + } + } +} + +phoenix_evsa_t::evsa_entry_t::~evsa_entry_t() { + _clean_up(); +} + +void phoenix_evsa_t::evsa_entry_t::_clean_up() { + if (!n_checksum) { + } + if (!n_len_evsa_entry) { + } +} + +phoenix_evsa_t::evsa_unknown_t::evsa_unknown_t(kaitai::kstream* p__io, phoenix_evsa_t::evsa_entry_t* p__parent, phoenix_evsa_t* p__root) : kaitai::kstruct(p__io) { + m__parent = p__parent; + m__root = p__root; + _read(); +} + +void phoenix_evsa_t::evsa_unknown_t::_read() { + m_unknown = m__io->read_bytes(0); +} + +phoenix_evsa_t::evsa_unknown_t::~evsa_unknown_t() { + _clean_up(); +} + +void phoenix_evsa_t::evsa_unknown_t::_clean_up() { +} + +phoenix_evsa_t::evsa_body_t::evsa_body_t(kaitai::kstream* p__io, phoenix_evsa_t* p__parent, phoenix_evsa_t* p__root) : kaitai::kstruct(p__io) { + m__parent = p__parent; + m__root = p__root; + m_entries = nullptr; + m_free_space = nullptr; + _read(); +} + +void phoenix_evsa_t::evsa_body_t::_read() { + m_entries = std::unique_ptr>>(new std::vector>()); + { + int i = 0; + evsa_entry_t* _; + do { + _ = new evsa_entry_t(m__io, this, m__root); + m_entries->push_back(std::move(std::unique_ptr(_))); + i++; + } while (!( (( ((_->entry_type() != 237) && (_->entry_type() != 238) && (_->entry_type() != 239) && (_->entry_type() != 225) && (_->entry_type() != 226) && (_->entry_type() != 227) && (_->entry_type() != 131)) ) || (_io()->is_eof())) )); + } + m_free_space = std::unique_ptr>(new std::vector()); + { + int i = 0; + while (!m__io->is_eof()) { + m_free_space->push_back(std::move(m__io->read_u1())); + i++; + } + } +} + +phoenix_evsa_t::evsa_body_t::~evsa_body_t() { + _clean_up(); +} + +void phoenix_evsa_t::evsa_body_t::_clean_up() { +} + +phoenix_evsa_t::evsa_name_t::evsa_name_t(kaitai::kstream* p__io, phoenix_evsa_t::evsa_entry_t* p__parent, phoenix_evsa_t* p__root) : kaitai::kstruct(p__io) { + m__parent = p__parent; + m__root = p__root; + _read(); +} + +void phoenix_evsa_t::evsa_name_t::_read() { + m_var_id = m__io->read_u2le(); + m_name = m__io->read_bytes((_parent()->len_evsa_entry() - 6)); +} + +phoenix_evsa_t::evsa_name_t::~evsa_name_t() { + _clean_up(); +} + +void phoenix_evsa_t::evsa_name_t::_clean_up() { +} + +phoenix_evsa_t::evsa_guid_t::evsa_guid_t(kaitai::kstream* p__io, phoenix_evsa_t::evsa_entry_t* p__parent, phoenix_evsa_t* p__root) : kaitai::kstruct(p__io) { + m__parent = p__parent; + m__root = p__root; + _read(); +} + +void phoenix_evsa_t::evsa_guid_t::_read() { + m_guid_id = m__io->read_u2le(); + m_guid = m__io->read_bytes(16); + { + std::string _ = guid(); + if (!(_parent()->len_evsa_entry() == 22)) { + throw kaitai::validation_expr_error(guid(), _io(), std::string("/types/evsa_guid/seq/1")); + } + } +} + +phoenix_evsa_t::evsa_guid_t::~evsa_guid_t() { + _clean_up(); +} + +void phoenix_evsa_t::evsa_guid_t::_clean_up() { +} + +phoenix_evsa_t::evsa_variable_attributes_t::evsa_variable_attributes_t(kaitai::kstream* p__io, phoenix_evsa_t::evsa_data_t* p__parent, phoenix_evsa_t* p__root) : kaitai::kstruct(p__io) { + m__parent = p__parent; + m__root = p__root; + _read(); +} + +void phoenix_evsa_t::evsa_variable_attributes_t::_read() { + m_non_volatile = m__io->read_bits_int_le(1); + m_boot_service = m__io->read_bits_int_le(1); + m_runtime = m__io->read_bits_int_le(1); + m_hw_error_record = m__io->read_bits_int_le(1); + m_auth_write = m__io->read_bits_int_le(1); + m_time_based_auth = m__io->read_bits_int_le(1); + m_append_write = m__io->read_bits_int_le(1); + m_reserved = m__io->read_bits_int_le(21); + m_extended_header = m__io->read_bits_int_le(1); + m_reserved1 = m__io->read_bits_int_le(3); +} + +phoenix_evsa_t::evsa_variable_attributes_t::~evsa_variable_attributes_t() { + _clean_up(); +} + +void phoenix_evsa_t::evsa_variable_attributes_t::_clean_up() { +} + +phoenix_evsa_t::evsa_data_t::evsa_data_t(kaitai::kstream* p__io, phoenix_evsa_t::evsa_entry_t* p__parent, phoenix_evsa_t* p__root) : kaitai::kstruct(p__io) { + m__parent = p__parent; + m__root = p__root; + m_attributes = nullptr; + _read(); +} + +void phoenix_evsa_t::evsa_data_t::_read() { + m_guid_id = m__io->read_u2le(); + m_var_id = m__io->read_u2le(); + m_attributes = std::unique_ptr(new evsa_variable_attributes_t(m__io, this, m__root)); + n_len_data_ext = true; + if (attributes()->extended_header()) { + n_len_data_ext = false; + m_len_data_ext = m__io->read_u4le(); + } + n_data = true; + if (!(attributes()->extended_header())) { + n_data = false; + m_data = m__io->read_bytes((_parent()->len_evsa_entry() - 12)); + } + n_data_ext = true; + if (attributes()->extended_header()) { + n_data_ext = false; + m_data_ext = m__io->read_bytes(len_data_ext()); + } +} + +phoenix_evsa_t::evsa_data_t::~evsa_data_t() { + _clean_up(); +} + +void phoenix_evsa_t::evsa_data_t::_clean_up() { + if (!n_len_data_ext) { + } + if (!n_data) { + } + if (!n_data_ext) { + } +} diff --git a/common/generated/phoenix_evsa.h b/common/generated/phoenix_evsa.h new file mode 100644 index 0000000..694b39b --- /dev/null +++ b/common/generated/phoenix_evsa.h @@ -0,0 +1,299 @@ +#pragma once + +// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild + +#include "../kaitai/kaitaistruct.h" +#include +#include +#include + +#if KAITAI_STRUCT_VERSION < 9000L +#error "Incompatible Kaitai Struct C++/STL API: version 0.9 or later is required" +#endif + +class phoenix_evsa_t : public kaitai::kstruct { + +public: + class evsa_entry_t; + class evsa_unknown_t; + class evsa_body_t; + class evsa_name_t; + class evsa_guid_t; + class evsa_variable_attributes_t; + class evsa_data_t; + + phoenix_evsa_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = nullptr, phoenix_evsa_t* p__root = nullptr); + +private: + void _read(); + void _clean_up(); + +public: + ~phoenix_evsa_t(); + + class evsa_entry_t : public kaitai::kstruct { + + public: + + evsa_entry_t(kaitai::kstream* p__io, phoenix_evsa_t::evsa_body_t* p__parent = nullptr, phoenix_evsa_t* p__root = nullptr); + + private: + void _read(); + void _clean_up(); + + public: + ~evsa_entry_t(); + + private: + uint8_t m_entry_type; + uint8_t m_checksum; + bool n_checksum; + + public: + bool _is_null_checksum() { checksum(); return n_checksum; }; + + private: + uint16_t m_len_evsa_entry; + bool n_len_evsa_entry; + + public: + bool _is_null_len_evsa_entry() { len_evsa_entry(); return n_len_evsa_entry; }; + + private: + std::unique_ptr m_body; + phoenix_evsa_t* m__root; + phoenix_evsa_t::evsa_body_t* m__parent; + + public: + uint8_t entry_type() const { return m_entry_type; } + uint8_t checksum() const { return m_checksum; } + uint16_t len_evsa_entry() const { return m_len_evsa_entry; } + kaitai::kstruct* body() const { return m_body.get(); } + phoenix_evsa_t* _root() const { return m__root; } + phoenix_evsa_t::evsa_body_t* _parent() const { return m__parent; } + }; + + class evsa_unknown_t : public kaitai::kstruct { + + public: + + evsa_unknown_t(kaitai::kstream* p__io, phoenix_evsa_t::evsa_entry_t* p__parent = nullptr, phoenix_evsa_t* p__root = nullptr); + + private: + void _read(); + void _clean_up(); + + public: + ~evsa_unknown_t(); + + private: + std::string m_unknown; + phoenix_evsa_t* m__root; + phoenix_evsa_t::evsa_entry_t* m__parent; + + public: + std::string unknown() const { return m_unknown; } + phoenix_evsa_t* _root() const { return m__root; } + phoenix_evsa_t::evsa_entry_t* _parent() const { return m__parent; } + }; + + class evsa_body_t : public kaitai::kstruct { + + public: + + evsa_body_t(kaitai::kstream* p__io, phoenix_evsa_t* p__parent = nullptr, phoenix_evsa_t* p__root = nullptr); + + private: + void _read(); + void _clean_up(); + + public: + ~evsa_body_t(); + + private: + std::unique_ptr>> m_entries; + std::unique_ptr> m_free_space; + phoenix_evsa_t* m__root; + phoenix_evsa_t* m__parent; + + public: + std::vector>* entries() const { return m_entries.get(); } + std::vector* free_space() const { return m_free_space.get(); } + phoenix_evsa_t* _root() const { return m__root; } + phoenix_evsa_t* _parent() const { return m__parent; } + }; + + class evsa_name_t : public kaitai::kstruct { + + public: + + evsa_name_t(kaitai::kstream* p__io, phoenix_evsa_t::evsa_entry_t* p__parent = nullptr, phoenix_evsa_t* p__root = nullptr); + + private: + void _read(); + void _clean_up(); + + public: + ~evsa_name_t(); + + private: + uint16_t m_var_id; + std::string m_name; + phoenix_evsa_t* m__root; + phoenix_evsa_t::evsa_entry_t* m__parent; + + public: + uint16_t var_id() const { return m_var_id; } + std::string name() const { return m_name; } + phoenix_evsa_t* _root() const { return m__root; } + phoenix_evsa_t::evsa_entry_t* _parent() const { return m__parent; } + }; + + class evsa_guid_t : public kaitai::kstruct { + + public: + + evsa_guid_t(kaitai::kstream* p__io, phoenix_evsa_t::evsa_entry_t* p__parent = nullptr, phoenix_evsa_t* p__root = nullptr); + + private: + void _read(); + void _clean_up(); + + public: + ~evsa_guid_t(); + + private: + uint16_t m_guid_id; + std::string m_guid; + phoenix_evsa_t* m__root; + phoenix_evsa_t::evsa_entry_t* m__parent; + + public: + uint16_t guid_id() const { return m_guid_id; } + std::string guid() const { return m_guid; } + phoenix_evsa_t* _root() const { return m__root; } + phoenix_evsa_t::evsa_entry_t* _parent() const { return m__parent; } + }; + + class evsa_variable_attributes_t : public kaitai::kstruct { + + public: + + evsa_variable_attributes_t(kaitai::kstream* p__io, phoenix_evsa_t::evsa_data_t* p__parent = nullptr, phoenix_evsa_t* p__root = nullptr); + + private: + void _read(); + void _clean_up(); + + public: + ~evsa_variable_attributes_t(); + + private: + bool m_non_volatile; + bool m_boot_service; + bool m_runtime; + bool m_hw_error_record; + bool m_auth_write; + bool m_time_based_auth; + bool m_append_write; + uint64_t m_reserved; + bool m_extended_header; + uint64_t m_reserved1; + phoenix_evsa_t* m__root; + phoenix_evsa_t::evsa_data_t* m__parent; + + public: + bool non_volatile() const { return m_non_volatile; } + bool boot_service() const { return m_boot_service; } + bool runtime() const { return m_runtime; } + bool hw_error_record() const { return m_hw_error_record; } + bool auth_write() const { return m_auth_write; } + bool time_based_auth() const { return m_time_based_auth; } + bool append_write() const { return m_append_write; } + uint64_t reserved() const { return m_reserved; } + bool extended_header() const { return m_extended_header; } + uint64_t reserved1() const { return m_reserved1; } + phoenix_evsa_t* _root() const { return m__root; } + phoenix_evsa_t::evsa_data_t* _parent() const { return m__parent; } + }; + + class evsa_data_t : public kaitai::kstruct { + + public: + + evsa_data_t(kaitai::kstream* p__io, phoenix_evsa_t::evsa_entry_t* p__parent = nullptr, phoenix_evsa_t* p__root = nullptr); + + private: + void _read(); + void _clean_up(); + + public: + ~evsa_data_t(); + + private: + uint16_t m_guid_id; + uint16_t m_var_id; + std::unique_ptr m_attributes; + uint32_t m_len_data_ext; + bool n_len_data_ext; + + public: + bool _is_null_len_data_ext() { len_data_ext(); return n_len_data_ext; }; + + private: + std::string m_data; + bool n_data; + + public: + bool _is_null_data() { data(); return n_data; }; + + private: + std::string m_data_ext; + bool n_data_ext; + + public: + bool _is_null_data_ext() { data_ext(); return n_data_ext; }; + + private: + phoenix_evsa_t* m__root; + phoenix_evsa_t::evsa_entry_t* m__parent; + + public: + uint16_t guid_id() const { return m_guid_id; } + uint16_t var_id() const { return m_var_id; } + evsa_variable_attributes_t* attributes() const { return m_attributes.get(); } + uint32_t len_data_ext() const { return m_len_data_ext; } + std::string data() const { return m_data; } + std::string data_ext() const { return m_data_ext; } + phoenix_evsa_t* _root() const { return m__root; } + phoenix_evsa_t::evsa_entry_t* _parent() const { return m__parent; } + }; + +private: + uint8_t m_type; + uint8_t m_checksum; + uint16_t m_len_evsa_store_header; + uint32_t m_signature; + uint32_t m_attributes; + uint32_t m_len_evsa_store; + uint32_t m_reserved; + std::unique_ptr m_body; + phoenix_evsa_t* m__root; + kaitai::kstruct* m__parent; + std::string m__raw_body; + std::unique_ptr m__io__raw_body; + +public: + uint8_t type() const { return m_type; } + uint8_t checksum() const { return m_checksum; } + uint16_t len_evsa_store_header() const { return m_len_evsa_store_header; } + uint32_t signature() const { return m_signature; } + uint32_t attributes() const { return m_attributes; } + uint32_t len_evsa_store() const { return m_len_evsa_store; } + uint32_t reserved() const { return m_reserved; } + evsa_body_t* body() const { return m_body.get(); } + phoenix_evsa_t* _root() const { return m__root; } + kaitai::kstruct* _parent() const { return m__parent; } + std::string _raw_body() const { return m__raw_body; } + kaitai::kstream* _io__raw_body() const { return m__io__raw_body.get(); } +}; diff --git a/common/generated/phoenix_flm.cpp b/common/generated/phoenix_flm.cpp new file mode 100644 index 0000000..babbbb3 --- /dev/null +++ b/common/generated/phoenix_flm.cpp @@ -0,0 +1,68 @@ +// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild + +#include "phoenix_flm.h" + +phoenix_flm_t::phoenix_flm_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, phoenix_flm_t* p__root) : kaitai::kstruct(p__io) { + m__parent = p__parent; + m__root = this; (void)p__root; + m_entries = nullptr; + f_len_flm_store_header = false; + f_len_flm_entry = false; + _read(); +} + +void phoenix_flm_t::_read() { + m_signature = m__io->read_bytes(10); + m_num_entries = m__io->read_u2le(); + m_reserved = m__io->read_u4le(); + m_entries = std::unique_ptr>>(new std::vector>()); + const int l_entries = num_entries(); + for (int i = 0; i < l_entries; i++) { + m_entries->push_back(std::move(std::unique_ptr(new flm_entry_t(m__io, this, m__root)))); + } +} + +phoenix_flm_t::~phoenix_flm_t() { + _clean_up(); +} + +void phoenix_flm_t::_clean_up() { +} + +phoenix_flm_t::flm_entry_t::flm_entry_t(kaitai::kstream* p__io, phoenix_flm_t* p__parent, phoenix_flm_t* p__root) : kaitai::kstruct(p__io) { + m__parent = p__parent; + m__root = p__root; + _read(); +} + +void phoenix_flm_t::flm_entry_t::_read() { + m_guid = m__io->read_bytes(16); + m_data_type = m__io->read_u2le(); + m_entry_type = m__io->read_u2le(); + m_physical_address = m__io->read_u8le(); + m_size = m__io->read_u4le(); + m_offset = m__io->read_u4le(); +} + +phoenix_flm_t::flm_entry_t::~flm_entry_t() { + _clean_up(); +} + +void phoenix_flm_t::flm_entry_t::_clean_up() { +} + +int8_t phoenix_flm_t::len_flm_store_header() { + if (f_len_flm_store_header) + return m_len_flm_store_header; + m_len_flm_store_header = 16; + f_len_flm_store_header = true; + return m_len_flm_store_header; +} + +int8_t phoenix_flm_t::len_flm_entry() { + if (f_len_flm_entry) + return m_len_flm_entry; + m_len_flm_entry = 36; + f_len_flm_entry = true; + return m_len_flm_entry; +} diff --git a/common/generated/phoenix_flm.h b/common/generated/phoenix_flm.h new file mode 100644 index 0000000..2faeba3 --- /dev/null +++ b/common/generated/phoenix_flm.h @@ -0,0 +1,91 @@ +#pragma once + +// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild + +#include "../kaitai/kaitaistruct.h" +#include +#include +#include + +#if KAITAI_STRUCT_VERSION < 9000L +#error "Incompatible Kaitai Struct C++/STL API: version 0.9 or later is required" +#endif + +class phoenix_flm_t : public kaitai::kstruct { + +public: + class flm_entry_t; + + phoenix_flm_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = nullptr, phoenix_flm_t* p__root = nullptr); + +private: + void _read(); + void _clean_up(); + +public: + ~phoenix_flm_t(); + + class flm_entry_t : public kaitai::kstruct { + + public: + + flm_entry_t(kaitai::kstream* p__io, phoenix_flm_t* p__parent = nullptr, phoenix_flm_t* p__root = nullptr); + + private: + void _read(); + void _clean_up(); + + public: + ~flm_entry_t(); + + private: + std::string m_guid; + uint16_t m_data_type; + uint16_t m_entry_type; + uint64_t m_physical_address; + uint32_t m_size; + uint32_t m_offset; + phoenix_flm_t* m__root; + phoenix_flm_t* m__parent; + + public: + std::string guid() const { return m_guid; } + uint16_t data_type() const { return m_data_type; } + uint16_t entry_type() const { return m_entry_type; } + uint64_t physical_address() const { return m_physical_address; } + uint32_t size() const { return m_size; } + uint32_t offset() const { return m_offset; } + phoenix_flm_t* _root() const { return m__root; } + phoenix_flm_t* _parent() const { return m__parent; } + }; + +private: + bool f_len_flm_store_header; + int8_t m_len_flm_store_header; + +public: + int8_t len_flm_store_header(); + +private: + bool f_len_flm_entry; + int8_t m_len_flm_entry; + +public: + int8_t len_flm_entry(); + +private: + std::string m_signature; + uint16_t m_num_entries; + uint32_t m_reserved; + std::unique_ptr>> m_entries; + phoenix_flm_t* m__root; + kaitai::kstruct* m__parent; + +public: + std::string signature() const { return m_signature; } + uint16_t num_entries() const { return m_num_entries; } + uint32_t reserved() const { return m_reserved; } + std::vector>* entries() const { return m_entries.get(); } + phoenix_flm_t* _root() const { return m__root; } + kaitai::kstruct* _parent() const { return m__parent; } +}; diff --git a/common/guiddatabase.cpp b/common/guiddatabase.cpp new file mode 100644 index 0000000..c8aa89d --- /dev/null +++ b/common/guiddatabase.cpp @@ -0,0 +1,142 @@ +/* guiddatabase.cpp + + Copyright (c) 2017, LongSoft. All rights reserved. + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + */ + +#include "guiddatabase.h" +#include "ubytearray.h" +#include "ffs.h" + +#include +#include + +#if defined(U_ENABLE_GUID_DATABASE_SUPPORT) +#include +#include +#include + +static GuidDatabase gLocalGuidDatabase; + +#ifdef QT_CORE_LIB + +#include +#include + +// This is required to be able to read Qt-embedded paths + +static std::string readGuidDatabase(const UString &path) { + QFile guids(path); + if (guids.open(QFile::ReadOnly | QFile::Text)) + return QTextStream(&guids).readAll().toStdString(); + return std::string {}; +} + +#else + +static std::string readGuidDatabase(const UString &path) { + std::ifstream guids(path.toLocal8Bit()); + std::stringstream ret; + if (ret) + ret << guids.rdbuf(); + return ret.str(); +} + +#endif + +void initGuidDatabase(const UString & path, UINT32* numEntries) +{ + gLocalGuidDatabase.clear(); + + std::stringstream file(readGuidDatabase(path)); + + while (!file.eof()) { + std::string line; + std::getline(file, line); + + // Use sharp symbol as commentary + if (line.size() == 0 || line[0] == '#') + continue; + + // GUID and name are comma-separated + std::vector lineParts; + std::string::size_type prev = 0, curr = 0; + while ((curr = line.find(',', curr)) != std::string::npos) { + std::string substring( line.substr(prev, curr-prev) ); + lineParts.push_back(UString(substring.c_str())); + prev = ++curr; + } + lineParts.push_back(UString(line.substr(prev, curr-prev).c_str())); + + if (lineParts.size() < 2) + continue; + + EFI_GUID guid; + if (!ustringToGuid(lineParts[0], guid)) + continue; + + gLocalGuidDatabase[guid] = lineParts[1]; + } + + if (numEntries) + *numEntries = (UINT32)gLocalGuidDatabase.size(); +} + +UString guidDatabaseLookup(const EFI_GUID & guid) +{ + return gLocalGuidDatabase[guid]; +} + +#else +void initGuidDatabase(const UString & path, UINT32* numEntries) +{ + U_UNUSED_PARAMETER(path); + if (numEntries) + *numEntries = 0; +} + +UString guidDatabaseLookup(const EFI_GUID & guid) +{ + U_UNUSED_PARAMETER(guid); + return UString(); +} +#endif + +GuidDatabase guidDatabaseFromTreeRecursive(TreeModel * model, const UModelIndex index) +{ + GuidDatabase db; + + if (!index.isValid()) + return db; + + for (int i = 0; i < model->rowCount(index); i++) { + GuidDatabase tmpDb = guidDatabaseFromTreeRecursive(model, index.model()->index(i, index.column(), index)); + + db.insert(tmpDb.begin(), tmpDb.end()); + } + + if (model->type(index) == Types::File && !model->text(index).isEmpty()) + db[readUnaligned((const EFI_GUID*)model->header(index).left(16).constData())] = model->text(index); + + return db; +} + +USTATUS guidDatabaseExportToFile(const UString & outPath, GuidDatabase & db) +{ + std::ofstream outputFile(outPath.toLocal8Bit(), std::ios::out | std::ios::trunc); + if (!outputFile) + return U_FILE_OPEN; + for (GuidDatabase::iterator it = db.begin(); it != db.end(); it++) { + std::string guid(guidToUString (it->first, false).toLocal8Bit()); + std::string name(it->second.toLocal8Bit()); + outputFile << guid << ',' << name << '\n'; + } + + return U_SUCCESS; +} diff --git a/common/guiddatabase.h b/common/guiddatabase.h new file mode 100644 index 0000000..e4c574a --- /dev/null +++ b/common/guiddatabase.h @@ -0,0 +1,40 @@ +/* guiddatabase.h + +Copyright (c) 2017, LongSoft. All rights reserved. +This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +*/ + +#ifndef GUID_DATABASE_H +#define GUID_DATABASE_H + +#include +#include + +#include "basetypes.h" +#include "ustring.h" +#include "ffsparser.h" +#include "ffs.h" +#include "utility.h" + +struct OperatorLessForGuids +{ + bool operator()(const EFI_GUID& lhs, const EFI_GUID& rhs) const + { + return (memcmp(&lhs, &rhs, sizeof(EFI_GUID)) < 0); + } +}; + +typedef std::map GuidDatabase; + +UString guidDatabaseLookup(const EFI_GUID & guid); +void initGuidDatabase(const UString & path = "", UINT32* numEntries = NULL); +GuidDatabase guidDatabaseFromTreeRecursive(TreeModel * model, const UModelIndex index); +USTATUS guidDatabaseExportToFile(const UString & outPath, GuidDatabase & db); + +#endif // GUID_DATABASE_H diff --git a/common/guids.csv b/common/guids.csv new file mode 100644 index 0000000..db963e1 --- /dev/null +++ b/common/guids.csv @@ -0,0 +1,11593 @@ +00000000-0000-0000-0000-000000000000,ZeroGuid +00000000-0ED6-4E09-BBF9-28325DB6BA30,BSODDxeRuntime +00026AEB-F334-4C15-A7F0-E1E897E9FE91,NvmeRecovery +000AC7B6-F44D-4220-BD8B-521D30DEA80F,HpGraphicsDetectDxe +000F42D0-283C-46AB-9287-ACB6C9941FCD,SmmSupvErrorReport +0013BE6B-2198-43F1-93BA-2A7ED7B1E1CC,SystemUsbSwitchDxe +00160F8D-2B35-4DF2-BBE0-B272A8D631F0,FirmwarePerformanceDxe +001D24D1-4AB1-B202-42D1-0FB9F4E4AD36,BiosPowerOnPortingSmm +0029231B-72EF-4FA5-BD37-7018A046FB0D,LenovoMultipleKeyboardService +0029DE6A-E024-4EB8-A91D-9F23AA1F4E92,NetworkStackSetupScreen +003443BE-0997-42D9-BB92-FCDF6926DCEE,FchSmbusDxe +00364A4C-6A0A-4F08-8FFD-0937F3DBB13E,IdeBusBoard +0049858F-8CA7-4CCD-918B-D952CBF32975,VirtioFdtDxe +004E6CC2-D60F-4726-BE22-D3D8020C4687,AsusSmartHsioDxe +00504624-8A59-4EEB-BD0F-6B36E96128E0,FpNvStorage +0053D9D6-2659-4599-A26B-EF4536E631A9,ShellAliasGuid +0062F7D1-F7DB-44FA-ABEE-F7A3CC636E0B,PhStallPpi +0065B106-EB27-4A3C-851C-EC77D51EDCD6,AbsoluteActivateDxe +0065D394-9951-4144-82A3-0AFC8579C251,EfiPeiRscHandlerPpiGuid +0067835F-9A50-433A-8CBB-852078197814,EfiCpuCsrAccess +00720665-67EB-4A99-BAF7-D3C33A1C7CC9,EfiTcp4ServiceBindingProtocolGuid +0072F4B5-74D5-4CC8-AFF6-CC9469D33F7B,UsbMediaCardReaderConfigDxe +00781CA1-5DE3-405F-ABB8-379C3C076984,AmiRomLayoutGuid +007A2B20-8383-4CD2-AF81-2994473434D8,UsbOcUpdateDxeBigPineKey +007AF6DC-BB4A-4D2A-8B57-A96A307275B5,FJFP_PBA_64 +0086AF89-AE1A-4435-A698-0815E850A004,AsusSetupReserveVariableItem +0090F816-86A1-4638-97C8-4D1BD79E7E5F,SmcPeiReportStatusConOut +00A2B266-B5CF-43A8-8547-CBEBFDEC894C,SmmSvcCallback +00A480CE-D751-4B11-89FB-7DCEBBB22F4D,DellPmPolicyProtocol +00B46EC9-2712-486B-A6A4-E2933581C28B,HstiPlatformDxe +00B8E6B5-83CE-448A-8AC6-CCBC9D5F3BE3,FchTaishanSmmInit +00C86DB8-013B-4FF4-B8E9-208F4FCF1C00,LibSignal +00CA959F-6CFA-4DB1-95BC-E46C47514390,EfiTlsProtocolGuid +00D6B14B-7DD0-4062-8821-E5F96A2A1B00,FspReservedMemoryResourceHobMiscGuid +00D6E846-49C7-4517-AC79-A70E8BC0553C,AmdMemChanXLatSspPei +00DBD91D-55E9-420F-9639-5E9F8437B44F,EfiExtendedSalStatusCodeServicesProtocolGuid +00DC20A3-66A2-4D14-BBD7-5BA938E556DE,LenovoSmbios +00E98021-F4FE-46CC-AB2D-894C373AFA01,DxeEnhancedSpeedstepProtocol +00EEAB3B-4719-432D-A2DC-C97A2C62BFDD,DellPermDevConfigPei +00F02769-AE45-41CF-AA58-6377B87BA99A,DeviceLayoutLoadPei +010216CD-9C09-4EB5-B7DA-D0A2865092D4,ProjectDXE +0102ADD8-037F-46FC-A9F2-41D352D2F695,TouchPad_Elan_2nd +010574D3-9CA7-4265-A536-D10E7A8CDCB0,OemSolPei +011A7546-DB4E-4119-A216-9A3167B6AF56,ComputraceDxe +01237498-4E20-42E5-BF75-1CD3B20F7CE3,PlatformStatusCodeHandlerPei +01239999-FC0E-4B6E-9E79-D54D5DB6CD20,EfiServerMgmtSetupVariable +0127B951-E840-480A-A083-087A9AE17353,LEMSetVariableCtlSmm +013295AB-6680-4C41-9C98-C41AA6F5188B,FlabLoadUadmDxe +013464B6-AC20-4E86-A2F9-23CC4650DDC2,MemoryDiagnostic +0135229A-EBB5-4A21-957D-1D20057CF751,TCMPEI +0135229A-EBB5-4A21-957D-1D20057CF752,TCMDXE +01359D99-9446-456D-ADA4-50A711C03ADA,CpuPei +01359D99-9446-456D-ADA4-50A711C03ADB,CpuPeim +01368881-C4AD-4B1D-B631-D57A8EC8DB6B,AmiGlobalVariableGuid +013A1234-DB4E-3123-CEA6-9A31982CAE96,DiskSanitizer +013A65AC-DB4E-3123-CEA6-9A31982CAE96,HddDiagnostic +013A65AC-DB4E-4119-CEA6-9A31982CAE96,ABCTDxe +013A65AC-DEAC-3123-CEA6-9A3198223E96,MemTest +0154DD51-9079-4A10-895C-9C0772815788,PlatformBootManagerStringPackGuid +0155DB6A-3C05-46F6-9341-FEFA4085E61E,FjPostScreenMfgErrorCheckDxe +01631791-F34E-4C0A-B15D-0B6CE22B27A8,TcgPeiAfterMem +01637772-B022-4047-BD52-35454C1C6B9F,Armani_EcCommunicationSmm +0167CCC4-D0F7-4F21-A3EF-9E64B7CDCE8B,ScsiBus +0167CCC4-D0F7-4F21-A3EF-9E64B7CDCE8C,SystemAhciBusDxe +0170F60C-1D40-4651-956D-F0BD9879D527,Virtio10 +0174B2B5-F505-4B12-AA60-59DFF8D6EA37,ShellNetwork2HiiGuid +017CB4B7-B80C-4040-B6C8-EA982BBB25B7,AmiSmbusHob +017EA01C-4988-4CD9-8A6C-3480E386A325,LegacyStr +017F2629-2D3E-4EA9-9E59-88DA4D98C027,SpiProtectionPei +01806607-245B-47A8-952A-DC8C5C6A5316,OemDeviceDetect +0182244E-F95D-43FC-91EC-60594EF47599,Lpc47m18xDxe +01882424-63B1-4E30-90E8-4C2C344E89C0,RecoveryCpuInitPei +018A5C7A-12EB-429D-9DEF-6FCC410B04E8,IioCfgUpdateDxeLightningRidgeEXECB4 +018AA4F0-773E-46F3-B62D-2C70EA32E0D0,EfiSystemPartCapsuleStorage +018E1925-D6A2-4A2A-8958-817610A15ADF,PeiS3LibNull +018E4D93-E8CF-4F51-9170-2658ECA4C9E3,AmdMiniRasStxKrkServiceDxe +018F3936-3A40-459D-9C82-3F1F78A90164,DellControlVaultDxe +019FB1CA-D411-4948-B73C-4C054ABA9E8E,FastBootFunctionEnabledHob +01AB1829-CECD-4CFA-A18C-EA75D66F3E74,IntelMebxProtocol +01AFCA2F-5089-4559-BEF3-6163AE15AE90,FRUSelfRepair +01B95206-CD66-4C0D-A867-ED42960E07DC,SystemFirmwareDeviceSmmProtocol +01C827C2-7765-42E9-B31C-E03E89A09113,AmdSocFp5RvPei +01CF676F-6F01-4FA3-9789-B6322D890394,AmdCcxZen4Pei +01D127EA-F6F1-4EF6-9415-8A000093F89D,UEfiCorebootPayloadPkgTokenSpaceGuid +01D6940E-06A2-455C-A0CA-DD380B3CEA31,SDSecureFlash +01D8F749-FD74-4F70-A393-6FED1D2C8D32,AsusWmiToProtocol +01ED6C55-0D2E-4859-BB57-3044737A3679,PhConSplitterDxe +01F34D25-4DE2-23AD-3FF3-36353FF323F1,EfiPeiPcdPpiGuid +01F7EC2A-8F6E-4C51-94C2-DE0E1C223F73,RasAcpi +01FB5D53-4FF9-4AD9-ADF5-7DC63659A1B2,PeiPciEnumeration +02005ACC-AD91-42B9-8636-403B4F5799C2,LenovoFlashDeviceInterfaceSmm +02049744-32D9-4338-A64B-FDC42C836F9A,FchDxe +02049744-32D9-4338-CCCB-FDC42C836F9C,FchPromontoryPlusDxe +02061E01-BEBD-4DF5-81B6-DFC4F23D1D00,SensorI2C +020BC7C9-80E5-476D-B187-0FB754850CAB,PvnvramDxe +020BCB33-7EA7-4E48-9AF8-1B6AC52CE83F,MeBackDoorSMI +021722D8-522B-4079-852A-FE44C2C13F49,SataController +021BD2CA-51D2-11E3-8E56-B75417C70B44,UsbDeviceProtocolGuid +021D723A-501C-4D1E-B792-0D3C4651B848,OemWwanSmm +022218B8-FE5E-4EBC-BC96-74058A4E7E83,ErrorGlobeBorder +02281CDA-5AE2-4A27-93DA-18ED4A545FBF,MRCErrorHandler +02337E07-2CF2-46BE-BCF7-834945FCCEB9,EfiUnbootablePartitionGuid +023B3AA9-098F-4027-B83F-B6407DA06569,AmdPspFtpmDxe +0246E0B3-E8EA-4E03-B2A5-39FA937FD122,SsidPei +024DEE41-33E7-11D3-9D69-0008C781F39F,EfiPartTypeLegacyMbrGuid +02509C17-DD0B-4915-81F6-1DE4BA954B14,FanTableSmm +0250B201-273B-4A64-9CAC-4FE9FB56F65E,AmdRAIDCoreDxe +0250D7AB-AADE-4691-8909-8DC184822D1D,SmbiosTpmDeviceInfo +0253F9FA-129A-4A8D-B12E-7DC2B6376302,dpDynamicCommand +0255DED3-BF9C-4155-8DDB-6E8609EE0482,AmdGopPlatformToDriver +025BBFC7-E6A9-4B8B-82AD-6815A1AEAF4A,MnpDxe +025F738B-4EBD-4D55-B728-5F421B601F1F,PlatformInfoDxe +025F738B-4EBD-4D55-B728-5F421B601F20,PlatformCpuInfoDxe +0273146C-96C4-45A1-A7AF-78E0524A0AE2,AmiBoardInfoProtocol +02814228-57C8-405C-8A67-C928E4B50992,EepromInterfaceCoreSmm +0284F846-2CB7-4960-8DB2-47AA71513AD5,menu_selection +02955B8D-DF90-4ACB-B242-78D06B3FA6CA,TrackPointJYT +029D4C32-51E8-4866-BF51-FD0ED9A2DC55,DellBiosDimmLocation +02A6DE33-3EA9-4C17-8EA2-5681CC7AFDED,VMDDxeEfi +02AC0805-155F-473A-A302-0D89D6E1E6CC,AsusSLP2 +02B01AD5-7E59-43E8-A6D8-238180613A5A,EmuVariableRuntimeDxe +02B2E27A-E8B5-4A42-82C3-55B43222EB9B,HpGFIStrsSubComp +02B3D5F2-AC28-11D3-9A2D-0090273FC14D,EfiTcpProtocol +02B92D47-5227-4C18-9FF5-888550C395B9,MktmeLateInit +02BA5CFC-D092-4404-9E52-A1B018525056,SiliconDataInitSmm +02BD55C2-AB1D-4B75-B0FD-9A63AE09B31D,BaseMemoryLibOptDxe +02C0AB0D-D5F0-4CAD-A4BF-0CC40A554BBD,HpInitNVSWksSmm +02C38DE3-FB92-4B29-9430-ECE6D0C0F3B0,FjMfgServicesDxe +02C40333-CED5-45BA-8836-B47E4C36489E,PlatformFanControl +02C5A102-58EA-4E53-8BE1-6ED1ACAA708A,AmdMemoryHobInfoPeim +02CE967A-DD7E-4FFC-9EE7-810CF0470880,EfiEndOfDxeEventGroupGuid +02D46AF0-78A0-43FD-A9D6-25B094E0BA93,LEN0130Driver +02D7DFE6-CB36-4FF9-9ED9-31806B797251,FchSmmDiagDispatcher +02E800BE-8F01-4AA6-946B-D71388E1833F,EFI_MTFTP4_SERVICE_BINDING_PROTOCOL_GUID +02EEA107-98DB-400E-9830-460A1542D799,Ip6ConfigNvDataGuid +02EEC6CF-FDF5-4FF0-A6AF-DF569BCD6828,HpDimmIdDxe +02EEC6CF-FDF5-4FF0-A6AF-DF569BCD6829,HpDimmIdSmm +02F04694-2C0A-4F1E-B0CE-64BE25890B03,DebugAgentTimerLibNull +0301BE48-7D25-443C-AA77-D5E753DB416A,EfiRsaBmcCommandsProtocol +0302DCB7-A6A3-467C-B85E-F21DB7E8533B,SmmDispatchEngine +03068297-DDA5-4CCD-BBFA-7E09AE025177,I2cTouchPanelDxe +0317F4CE-AD43-4461-8D14-B9F2543FD839,SataDriveInfoDxe +0325A554-05BE-466B-BC8C-70BE3C9DAFB1,AmiTcg2InfoProtocolGuid +0325B5A1-0937-4A4F-B8AF-EC3F80EE6B35,SataControllerLite +032DE3F1-1362-45A5-A5C2-44A0E63CC263,FjGabiSystemTableSmm +03327D04-C807-4B76-965F-B30046F15391,VtioSetup +033FF0BE-ABFB-40AC-87E3-C22A69BD7FA7,TransparentUnlockDXE +03417BF3-6D95-41DF-88EF-0DDA6E86DC34,AsfPei +0347E9D2-3778-46DC-B8B5-F1687C703973,FjWwanRfSettingUIDxe +034AA642-91B0-4160-A0F7-D31A28E013CB,H19DisplayControl +03583FF6-CB36-4940-947E-B9B39F4AFAF7,EfiSmbiosProtocolGuid +0365E9E2-A03E-49BE-8B2B-02B7E3AE953C,KeyMonFilter +0369593A-BA9B-457D-B46F-31D83A96D6FE,DehSmmProtocolVer3 +036B6292-2793-4DC0-9A7F-D6B5F034558C,FjSystemHooks +036F84E1-7F37-428C-A79E-575FDFAA84EC,EfiIommuDMArErrorSectionGuid +03721EF2-1801-4C91-A213-147323F75132,AsfTableAsl +0379BE4E-D706-437D-B037-EDB82FB772A4,EfiDevicePathUtilitiesProtocolGuid +037B547A-97E8-4FF2-8CD1-DCB7A1B4915A,SetupConfigUpdateDxeArcherCityModular +0387F555-20A8-4FC2-BB94-CD30DA1B4008,EfiWindowsInt10Workaround +038CE287-B806-45B6-A819-514DAF4B91B9,DellErrorLogConfig +038EF9A9-5969-4793-964F-FF12FA18393E,AmdCpmOemInitPeim +0393D0C4-6B0C-4B96-B4C3-8C7EB718F348,CsrPseudoOffsetInitSmm +0397B0C9-22E8-459E-A4FF-99BC65270929,Tpm2StartupLocalityHobGuid +03A8E402-2AB7-46B3-B591-740383796B82,AmdMemChanXLatDummyPei +03ADF4A1-A27A-45E3-B211-3177C6C2E7ED,SmbiosBasic +03AF477A-8336-0142-8A65-B4BD93B1A1A9,FirmwareExtension +03BF5679-5749-4BC5-A53F-47471DA767C8,IsscSmm +03C1F5C8-48F1-416E-A6B6-992DF3BBACA6,A01SmmServiceBody +03C4E603-AC28-11D3-9A2D-0090273FC14D,EfiPxeBaseCodeProtocolGuid +03C4E624-AC28-11D3-9A2D-0090293FC14D,EfiPxeDhcp4Protocol +03C70B0D-67E6-5C16-8E57-312DF246A961,BootChimeAudio +03D56EEC-E196-4815-B91A-C4885A839043,CompalGlobalNvsDxe +03D73468-3D39-4C9E-97F1-1FA925BD7D9E,SystemSecureVariableStorageDxe +03DA99B3-DDF4-4C7E-8CCA-216FC3F1F311,BaseFspSecPlatformLibNull +03DBB540-E186-4615-8A7F-A427863B4E56,PoofAnimationState1 +03E0A38B-3FBE-49CB-B311-726611213182,EgsFhfPolicyOverrideDxe +03EBDB4B-96BA-4F40-8329-7F3AA8865707,EcIoSmm +03FA15BF-A5C8-4006-81B5-B836E7A70030,GnbSummitRouting +03FDF171-1D67-4ACE-A904-3E36D338FA74,SeCPlatformReadyToBootGuid +04062BAD-2117-46DF-AEB9-8E468D8326E5,OemCheckRtcBattery +0412A7A1-C050-42C2-877A-77C379F9F5F1,FirewireOhciDxe +0419E4C6-4E8E-4436-8509-38B7AE50BFFD,ReadyBootSMI +0419F582-0625-4531-8A33-85A9965C95BC,WinNtBusDriverGuid +041CE993-6677-4720-A665-375B80FFE012,DellFpThunk +041FD986-B016-47CE-AFC5-2269EDD4AD64,ACPIS4Dxe +04356799-81B7-4E08-A38D-D978FA47BA42,EfiExtendedSalSmComLayerServicesProtocol +04398FAF-B8D6-4C35-99C9-037911233DD9,H19QRCodeCreater +043A3340-7CD0-4338-B7FE-7A6AEB790A28,HidKeyboardDxe +043DF38F-32E1-4893-911F-37A7FE91F723,CapsuleProcessorDxe +044310AB-77FD-402A-AF1A-87D4120E7329,FirmwarePerformanceSmm +044D9982-AA57-45D7-BB7D-62966AF7356B,DellStatusCodeHandlerPei +0455CEAF-FE5C-442F-BA23-34DFDC77505A,NewRsmSampleDriver +045B6F49-9102-4590-A0A5-35311B0AEFC3,EfiDpsdRSA1024AndSHA256SignatureVerificationProtocolGuid +045E78D8-3D5D-4EE5-90AA-42121E1EEE49,CbsBasePeiRV +04609BF5-E1C3-44FC-E4DE-7F9489362184,BiosConnectDaInterfaceSmm +04624E48-D24E-4670-BDFD-124DD92F3DAD,PxeDriverI225 +04627B9B-385E-4744-9021-E66319F20394,AmiPbKeyRsa2048 +04688D96-3468-4D52-9727-357B9AED6727,FchPromontoryPlusCbsPei +0468A601-C535-46FD-A95D-BBAB991B178C,EfiPowerOnHobGuid +0469CF6E-1A81-4FFF-AC00-1608472EA307,MsdmUpdateSmm +046C44DB-59DF-41B3-AF53-EF707B930E9A,FtRecovery +0471BC5B-64BE-43BF-8FA1-435AF1161384,CrystalRidgeMeasurement +0477CC85-F610-47B9-B322-42E1A93D9EE7,FjGpioAbstractionReferenceSmm +047CA5C8-EFA6-64CA-98EC-A01DF3BCC6A8,A01BootDeviceServiceSmm +048520E2-46BC-829D-5683-329BF1162CD2,BiosPowerOnSmm +04877BE8-FAC0-448E-801D-F0F895CCB012,SmbiosDmiEditSsi +04970E59-FCCC-47CC-B945-7976EE7DBB7A,OKRConfig +04A0D644-5599-430A-A4E1-C8FEE8CBF46A,SmbiosType142 +04A76C80-06B9-445E-B73E-CB8C61A6A964,SIO791 +04AFC94A-73AF-432F-BECB-B794568AC985,DellOnboardNicSmm +04B37FE8-F6AE-480B-BDD5-37D98C5E89AA,EdkiiVarErrorFlagGuid +04C332FD-14D3-411C-A1EF-6512E260339E,FjNvsAreaSmm +04DD0ECD-4844-426D-AE59-1EF632C5EA4C,SystemDxeToSmmEventDxe +04DD1EE1-4C38-41C7-83C6-4ED6BB692CFD,AaeonDioDxe +04E86DFA-6FA9-4749-A069-5A708F416AF7,OemPDAutoFlash +04EAAAA1-29A1-11D7-8838-00500473D4EB,UsbRtSmm +04F5B0F1-73E2-4CC4-9741-662DBC3AB78B,ErrorCodeHandlerSmm +04F75442-A593-4281-BD4B-095935B7D2F8,wifi_1bar +04F7F9B7-1248-497C-B0EB-8F748ABFCAF0,DellVideoProtocol +05041A6B-4DEE-47BB-9E58-5944D1870EE5,UsbConfigGuid +050EB8C6-C12E-4B86-892B-40985E8B3137,UefiDevicePathLibDevicePathProtocol +05105279-DCE6-4D27-BA3C-0C6F3E8DE66D,SetBoardIdVar +051274F4-A724-4732-BE00-82793A3D499A,AmdUsb4Dxe +0515BC05-2959-4E91-89C6-6B3A3F1FCB65,TCG_MPDriver +05161583-2AB3-43D1-8087-E890997B0F80,DellPlatformFlexBay +051A0B77-C066-4610-9904-BF25C296D6E6,LenovoEn25Qh32FlashPartDxe +052E6EB0-F240-42C5-8309-45874545C6B4,BootNowCount +05302B01-E898-494E-9FB1-9E02DC5D7CCC,EcMudPei +0535C332-6D4D-4D89-9468-F3627BB386CE,H19MpmRuntimeDxe +0541150C-E33B-4DAF-A263-02E4BB4BF1CF,SecurityErrorHandlingDxe +054F2504-E2BC-4641-83FC-502588FE1F28,CpuInitDxe +0559E886-AC78-4BCC-899A-E7830B5D6462,SystemSmbiosBcpSmm +0565365C-2FE1-4F88-B3BE-624C04623A20,MicrocodeUpdateDxe +0565963B-3DFD-4712-9CFD-614C5EDBE592,MsiBoardPei +056623DC-1285-4EAF-9446-75C3B00F78C6,FchMultiFchDxe +05687F4A-3CA7-4D19-9BC5-E180CEA3569F,AmiPlatformSecurityChipGuid +056BCA18-2F19-41EE-84EA-83746CB5069A,CrystalRidgeSMM +056E7324-A718-465B-9A84-228F06642B4F,DxePlatform +0571DC0C-D3B8-422C-A9EF-AC446483BDFE,VisualCSM +057A449A-1FDC-4C06-BFC9-F53F6A99BB92,EfiPciCfg2PpiGuid +05839AAC-361D-47D8-B2BA-50D5F4B09AD8,AsusRecoveryFailedPei +0583D694-AF8B-4BAA-9583-813CEDF40843,CsmInt10Block +0584FC67-72B9-4D46-AE3E-AD330452D9B4,InputDeviceAggregatorDxe +05885D44-9588-428E-9EB0-1CA7E54CA96B,TdxPostMem +0589E077-93C8-470E-9B90-958B4E2FE686,DevUpdateProgress +05913B1B-DB0C-4679-94B1-F8AA09B4A971,FjPcieCardReaderRTS5250 +05984E1A-D8BB-5D8A-A8E6-90E6FB2AB7DA,AlertUI +05ABE46F-BFA5-4C68-B305-3D545C58D805,Vby1PeiPreGop +05ABE46F-BFA5-4C68-B305-3D545C58D806,Vby1PeiPostBuffer +05AD34BA-6F02-4214-952E-4DA0398E2BB9,EfiDxeServicesTableGuid +05B0A258-308A-445E-B669-A854549D225C,SmmCpuProtocol +05B17EF3-26CB-444A-82F7-92705CFB6B1E,DellSetupFormSets +05C99A21-C70F-4AD2-8A5F-35DF3343F51E,EfiDevicePathFromTextProtocolGuid +05CA01FC-0FC1-11DC-9011-00173153EBA8,OemRomHole_0 +05CA01FD-0FC1-11DC-9011-00173153EBA8,OemRomHole_1 +05CDF411-F3C1-4B12-AA64-21416E18A13C,AmdCpmSharedBSmm +05DB6CC9-E9E4-4209-9D46-AA52C4052937,CNVISetupSmm +05DDA141-2DFA-48BB-B09D-D922344947FE,ApobZpRvPei +05DFCA46-141F-11DF-8508-E38C0891C4E2,HfsPlusDxe +05E9CF0F-4BE3-87F4-7265-B796A76959C3,S5MaxPowerSavingsSmm +05F7AA70-A64A-432C-8CEE-4CDECB8671D7,A01ODMDxeDriver +05FC0C8E-276A-422D-BAE1-645CFD7B786B,Cf9Reset +05FE1BB1-41D3-43DD-ABB0-91860B4AB185,AsusBackupSync +05FFB44D-EE01-40E1-9866-FD27FD4FBE92,ThunderboltDeviceDxe +060644B6-6A7F-4A97-900C-49645DA956D7,FchYuntaiDxe +060CC026-4C0D-4DDA-8F41-595FEF00A502,MemoryStatusCodeRecordGuid +0619F5C2-4858-4CAA-A86A-73A21A18DF6B,GenericWatchdogDxe +0625FEA6-F95F-498D-8789-3EA053A06D7E,Cf9Reset +062A6204-8C80-4A27-9D09-96654C965894,AsusHwmSensorPortingDxe +062ACC82-1D1E-4F61-AA94-8B0C47236A3D,BootScriptSaveOnS3SaveStateThunk +062FDFE6-2C0F-462C-9572-92018E6E52E3,HpIcicleRepSet +0633A0F1-78FE-4139-B878-0045E81CB8AB,EfiVolatileMemModeVariable +06384570-1680-4620-9D00-6AD9E3CCB19F,LenovoMtmFormatSmm +0639408B-19A6-4B5D-BAFB-12A2F5114032,Acoustic +0650F140-439A-2D4F-9807-C92669339399,AppleEvent +0653586A-9ED4-400C-A342-9EFAF99CE54E,SecuredCorePCDeviceIdentifier +067B1F5F-CF26-44C5-8554-93D777912D42,ConfidentialComputingSevSnpBlob +067E2381-7234-4798-B49C-D5FECBFF6D07,VariableAuthSmmRuntimeDxe +06818C78-1C8A-4591-9833-DC0E4B9566E4,TdtAm +06830AC0-75D7-4933-B6AF-4D3AA317D2AF,FJPhysicalPresencePage +0683FB88-664C-4BA6-9ED4-1C0916EE43A4,UserAuthenticationDxe +0684C591-19E8-499D-978A-D715636F1DAB,AmdRasRvDxe +0693BAA5-35D0-4360-83F6-1DF26D3C53CE,SiCpuInitPei +06968B6E-F620-4E8D-A6A6-52552354DD75,LenovoDxeRicohInit +069887DE-145C-404C-9B23-E262A88789AF,RfVlan +06B5947E-FF53-457D-98BC-C5ABC777FD5A,SetupMouseDxe +06BE9C49-717C-46C8-9848-E626B79FAA36,FchYuntaiSmmInit +06D1F4F5-B131-4F7C-A983-20E4BE9E8A3D,DellPSBFuseDxe +06D20D84-A032-4E25-969A-346D255E46D1,CpuCsrAccess +06DE824A-A4E2-4295-A3F6-03B3FEF5B109,LenovoSecurityVariableDxe +06E81C58-4AD7-44BC-8390-F10265F72480,PcdPpiGuid +06ECAF57-1A95-44DD-AE09-AB9B9BD681E9,MpmAsfDxe +06F00EDE-198C-0217-2416-4299BCE072CA,OemMfgdoneDcfg +06F73F04-36C0-4CBC-A3B0-9F16FB603350,OemPxeLoader +07013588-C789-4E12-A7C3-88FAFAE79F7C,EfiSocketProcessorCoreVar +0702269D-380C-4873-BFEB-32F5BC44DD16,AmtLockI2cConInDxe +0703F912-BF8D-4E2A-BE07-AB272525C592,EfiSmmPeiMmramMemoryReserve +0718AD81-F26A-4850-A6EC-F268E309D707,Tpm20PlatformDxe +071A3DBE-CFF4-4B73-83F0-598C13DCFDD5,Slp21Markers +0723F88B-810F-4E44-92A0-A5C83B433698,PchFlashControllerDxe +07261C8F-9F27-4409-BD78-2BB0B691F331,DetectWlan +072A957A-2A7A-4DB1-A35D-21C9795ACD6E,SetupUtilitySilicon1 +07309A59-462F-4251-BF5F-324E80CD5B05,WtTimestamp +0732BD39-D6B0-4039-B6C2-9654466DE525,MeudError +0736595D-88AB-483E-9886-8132018980FE,SioChip1InitDxe +0738958D-A35A-4175-ACE9-D32445501D34,FjTpmPhysicalPresenceLockSkip +0739CE30-2E1A-449A-B575-FD64F1B4321D,SystemSetupCapsuleFromInternetDxe +073E2576-F6C1-4B91-92A9-D4675DDA34B1,PttPassThruProtocolGuid +073E7E01-2611-4E85-B896-A3B6767CBA00,AmiTsePasswordPromptEnterGuid +074993A4-19A1-4E0D-B892-8FBCC6D79F35,SaveMemoryConfig +074E1E48-8132-47A1-8C2C-3F14AD9A66DC,EfiGlobalNvsAreaProtocolGuid +07525079-2616-4599-93FA-5EE9E3F0295C,CsmPolicy +0755BB58-3362-4E3C-8D4C-8E0F28366E21,EcGbeSmm +0764AAD8-9D82-441F-80F3-21AFA56F807C,Afu32MOfbd +07683700-036B-440B-8EBA-637F9ECB3DEB,SioSmbusAccessSmm +076E4FF4-AFB4-4B74-8D94-0517BEC86361,FchSmbusPei +076FBF50-EF83-4B77-912C-D5BB77075AE3,CompalThermalDxe +07709C98-414A-4039-B7D0-29C21F105E92,AcpiPlatformFeatures +0770E7A0-9C3A-499C-A311-2F8385080556,BoardInfoSmm +07755871-CA72-42D1-AF0E-5BEB971F7E4C,RtcAlarmSmi +077700FC-1F81-4FD2-8EA8-BE9258884D45,PostScreenInfo +077A3100-1667-45FA-B98C-37651B5073EE,TpmSmbiosDxe +077F6FC5-2D7C-4F58-B12C-F5287E5F5843,DellTagsDxe +0780F2B5-EEA8-4A94-97B8-59C8275D5692,Ccg4ControllerDetectPortingSmm +078485F1-0C1F-4B1B-AFB3-4A09C0EF87A1,It8728SmmFeatures +0784924F-E296-11D4-9A49-0090273FC14D,EfiDriverDiagnosticsProtocolGuid +0787C598-F9C6-4B7F-8C85-0C96C4E1E531,FjHookFormBrowserDxe +07893DFB-115C-4C5E-B54E-9A4E83EE2E70,InstallSLICTable +078F54D4-CC22-4048-9E94-879C214D562F,DefaultFvPadFileNameGuid +079C90B0-1B9C-4C3C-9316-EFC7F680A67B,PlatformSmbiosDxe +079E8E98-AE93-4B9A-8A71-1DC869F23E09,ShellSortTestApp +07A50B13-7539-41CB-B924-9E72B870C6D3,UsbVhcDxe +07A9330A-F347-11D4-9A49-0090273FC14D,LegacyMetronome +07AD733A-0DDB-4244-BD82-071F39E2A420,PlatformSmm +07B348F3-2187-4035-AEAF-F07A85D9754B,AmdEdidOverrideDxe +07B37006-9302-408E-B416-B524D110DD7F,AppleHidInterface +07B58AD3-EB7B-4233-9044-9C9E65A4973B,RZ616_MtkSuppDex +07BDE155-616C-4291-BD0B-24411F3BB908,AmdRAIDCoreDxe +07BEF20E-5E47-4A69-B228-27C6C870EAE1,AmdSocFp7r2PhxDxe +07D1E0C7-1262-481F-95C0-3E05DA38F766,FchTacomaSmmInit +07D279A1-34E4-4168-993B-178B3ACC68EF,AodSetupDxe +07D75280-27D4-4D69-90D0-5643E238B341,EfiPciPlatformProtocolGuid +07DCCAE1-A9AE-4EF4-AA10-468B1C37BECC,OemDxeShp +07DFA0D2-2AC5-4CAB-AC14-305C624887E4,PlatformTokenSpace +07EDEF55-24EC-43F3-8E3E-8C0831E21E68,EzTpmUpdStTpmFwUpdDrv +07F1B357-4270-4122-A32A-7EAB3C013BAC,DfciManager +07F6A3D8-9320-4BCB-BA8B-4FA6055D909D,AmdPspP2CmboxV2Ssp +08018188-42CD-BB48-100F-5387D53DED3D,EfiPersistentVirtualCdGuid +081603B4-0F1D-4022-B6FD-4CE35E09A1A6,EfiUnixNetwork +081C9A43-431F-475D-B84C-93AD6714B80C,DiskIdm +081CCA80-AE21-AFC8-1AC8-3091A8F1CBC5,SmcOobPlatformPolicySmm +082198EB-1731-478A-901C-5A86A9C64910,DellPermDevConfigDxe +08226C3F-BBF8-431B-875E-7361444A23F9,AmdMemSmbiosV2RnPei +0823A088-1248-4285-9616-0111CC76D3C5,SmbusRecovery +0831AB36-D5D0-4280-BED2-A7E27E9FEFC9,HpSioInitPei +0833A84D-8A39-431F-BD1C-30965AAE71DD,ProcessorStartup +0840FF86-F690-4FD8-A891-8BF944B0F324,DellSmmKeyboardBacklightProtocol +08448B41-7F83-49BE-82A7-0E84790AB133,LePassKeyDeviceManager +08464531-4C99-4C4C-A887-8D8BA4BBB063,Ps2MouseDxe +08497E75-0BF6-40E2-8ABF-B98DFB464C93,SpiFlashPeiLibNull +084A92B2-036A-414C-ADEA-620ACF547664,RasMiscDxe +0859BA18-7DD7-4ED7-A88E-109C63917BDD,EfiPlatformMemtestProtocol +085A786C-5CFF-4762-81CF-D7CBFECA77D4,AmdPlatformRasBrhSmm +085DDD80-CE41-4FA8-B298-6071E8F62BC5,SmcOobPlatformPolicyDxe +085E8CC2-8EC9-4666-BD2A-49D481E95FA7,FjEvteLaunch +086147FA-4C0D-4781-AD27-0A3725F03F2B,DxeDg2OpregionInit +0872E0A5-6D38-4567-964C-7A3B48053A4F,FdmInitDxe +08747359-BA88-42F8-9D25-F71D93B6CD26,EcFlashSmm +087568D7-5A70-4DDC-84FD-92E358E7BF2C,NvmePciHcPei +087E9760-1FB5-49F7-879A-853D2B214CC7,LenovoSlp2Dxe +08804377-AF7A-4496-8A7B-175900E9AB46,EdkIIRedfishCredentialProtocol +0885F288-418C-4BE1-A6AF-8BAD61DA08FE,AmiTseDriverHealthEnb +08A2CA63-3B65-472C-874E-5E138E947324,AsusEcDxeRt +08A92691-926C-414F-A0B5-E785D90B9853,Memory_OK_DXE +08ABE065-C359-4B95-8D59-C1B58EB657B5,IntelLomSmm +08B2E586-35A8-4A3F-A9ED-E48134891601,SmcInBandSmm +08B97689-86AF-4A36-9E35-117B4D2EF26A,AfscDxe +08BB308D-C7D8-4D7B-B4D4-BC4BB53768A6,OemVariableInit +08BF43A1-CD5F-44E4-8275-7D3B79228FA3,Lpit +08C8BAE1-92A6-49D5-FFFF-FFFFBA9D8DC2,SplashDxe +08CB0301-F702-4F88-A1A2-B51C2D99E80C,SioCashDrawerPei +08DD466B-69FB-4C41-90B2-551161C5ECAC,AmiAgesaChipsetDxe +08EFD15D-EC55-4023-B648-7BA40DF7D05D,PeiRamBootPei +08F2C63B-08DE-4CCD-8670-ACFE644A1C48,PchS3Support +08F74BAA-EA36-41D9-9521-21A70F8780BC,EfiDiskInfoScsiInterfaceGuid +08FA7EC9-60D4-47C8-B299-9F83B4A9DAC3,AcpiOverride +08FBD32F-867F-452B-B134-705161F73333,LenovoCryptServiceSmm +0903DD14-2CA0-458A-B5EB-0C0CA30D785C,AmiSmbiosBoardProtocolGuid +0914DE08-434D-4F9F-93B3-6FA48AEAF7E0,DellSpiPartMicron +0916E322-3740-31CE-AD62-BD172CECCA36,AsrockRaidSetup +091AAEA3-09A9-40F6-9864-0139388A9F8C,XhciPei +0922E604-F5EC-42EF-980D-A35E9A2B1844,IpSecConfig +09286371-5FF2-4065-B3D2-B81C882898AB,HpIcicleSmm +0939A4CC-DC2B-48A0-909B-30994D39D82C,ReportStatusCodeRouterSmm +093E0245-BDA6-48C7-A0B4-C3C9BFB87C79,WLANDxe +093E0FAE-A6C4-4F50-9F1B-D41E2B89C19A,EfiCertSha512Guid +094325E0-4DA2-4912-990B-D6DB19077573,HeciAccessDxe +094788DA-6FFA-4031-B435-FF9623656034,PspDxe +0948381E-0B3D-43A9-8E03-F2489F2B9E2E,FchSmmDispatcher +09576E91-6D3F-11D2-8E39-00A0C969723B,EfiDevicePathProtocolGuid +09576E92-6D3F-11D2-8E39-00A0C969723B,EfiFileInfoGuid +09576E93-6D3F-11D2-8E39-00A0C969723B,EfiFileSystemInfoGuid +095E3853-2F3D-4061-BBDF-0EC0D478FD16,OemServiceDxe +096111BF-B355-4180-BA39-737153339F0E,ServiceBatteryRemoval +09633AD2-2A5E-4562-90A8-24C673C4097C,AmdMemFp8Pei +09767DB6-412A-45BA-8026-F087CAE210E3,DTSPolicy +097CEE1C-A7F0-40CB-AB0D-F0774AE90E2B,FjSetupPower +09813137-B2A5-4462-8A2A-48F77ECA31BF,SmbiosDataUpdateDxeExpertWorkStationRP +09831032-6FA3-4484-AF4F-0A000A8D3A82,PL180MciDxe +098515FC-9F73-4BE4-B542-D38BE9E91E96,FlashUtilitySmm +098ED901-C6BF-4D20-91E2-A39F0C084A8D,QuickSpi +0996199F-2CE2-4D97-830B-077A7B28588A,WpbtDxe +0997E770-756E-4139-BF3F-7FC2A308177E,DellSmmS3 +099CFA27-134F-449A-AF4A-D29C441CB521,AsusAmlBuffDxe +099E1F39-0102-43C3-8CEC-8E897B6562F7,EventLogSmm +099FD87F-4B39-43F6-AB47-F801F99209F7,DellDcpRegister +09A9D5AC-5204-4214-96E5-94992E752BCD,EfiEventNotificationTypePei +09B5D8DA-9A25-47AF-A810-45A6D549E3F7,FjI2CPpi +09B8BA84-3DD3-49A6-A05A-3134A5F07BAD,ArmScmiPerformanceProtocol +09B98059-2D74-43C5-9709-AD0A0051867D,DellAhciDxe +09BD2ED8-C485-4D9C-B9A1-7B064C0309D2,UsbSxCallback +09C960B3-DA83-47BE-BBC4-81267BA9B002,FlashBootFlag +09CE2C2D-4D83-44B8-97D0-1085EB5490B8,AsrockRaidLoader +09D13410-2718-463A-8B15-DA93C3CA0A64,UsbCdcEcm +09D445BE-3C89-4E4F-ABE0-51FA84C2E4FF,ScGeneralConfigGuid +09D5B53F-F4B0-4F59-A0B1-7B57D35C0E05,NicIp4ConfigNvDataGuid +09DF88E2-0E05-4F28-A55F-0D62BFBCF59F,AmdFabricRvPei +09EA8911-BE0D-4230-A003-EDC693B48E11,VlvPeiInitPpiGuid +09EA894A-BE0D-4230-A003-EDC693B48E95,PchInitPpiGuid +09EB7679-2152-47F3-B832-EE9B947B29F5,SmartUsbProtection +09FDCB1E-E08B-4B64-890C-70E3174BE07A,FpgaErrorRecord +0A056E30-B2C9-44F3-FFFF-FFFF94A524A6,XnotePowerButtonSmiHandler +0A18976F-6CA6-405B-AF4B-27B8F7F6DB98,AmiUsbIadProtocol +0A1C30D2-7821-4FD2-B3C1-D24FA4C84B6A,DellCfgChangeReport +0A1D4FD8-4704-4501-85EB-93399492CBED,DevShell +0A249BB5-5918-45F5-B220-76A3B6C89529,FjLvdsFwDownPei +0A24A50A-C148-42B6-9302-8ED31D334E73,ASRockNetFtp +0A2FBD15-1C25-407E-8915-60C5652BC2AA,SystemFirmwareUpdateDxe +0A32A803-ACDF-4C89-8293-91011548CD91,MicrocodeMeasurementDxe +0A457A6C-178E-438C-AC96-D9C0EC52BE66,DellTcgPeiPolicy +0A496AAC-8C56-4DA0-A960-E417247A6183,BroadcomLomSmm +0A4D622D-01F4-4974-B3F5-2BFE9888EF92,SLP20OEMPublicKeyVariableGuid +0A4FB373-359F-4A34-B354-AB7B2EB72552,AmdSocAm4SmPei +0A58B5C0-0E01-429C-A8AD-EB7349A5CFA5,DellPlatformVTdPolicyDxe +0A5EA2E1-BE0B-44A0-A775-F429C9A018A0,PlatformInit +0A602C5B-05A0-40C4-9181-EDCD891D0001,OememDxeBin +0A602C5B-05A0-40C4-9181-EDCD891D0002,OememSmiBin +0A602C5B-05A0-40C4-9181-EDCD891D0003,OememPeiBin +0A66E322-3740-4CCE-AD62-BD172CECCA35,ScsiDisk +0A7521E1-09F1-44AE-9B5F-2781B78971D6,SimpleBootFlag +0A77E089-1590-4442-BBEA-115E19E6358A,EfiOsWdtPolicyProtocol +0A7A6FC0-AD10-445F-BCB0-704AD17CDB23,Ucsi +0A814161-DE67-46E7-A813-B7F8F489AFCD,UpdateSmbios +0A845224-8675-4241-8AE9-4D94C93DEB90,PauseKey +0A8BADD5-03B8-4D19-B128-7B8F0EDAA596,EfiConfigKeywordHandlerProtocolGuid +0A9DB95A-0E4A-4816-8639-5BE4FFA9C909,AmdFabricPhxSmm +0A9EAFB0-FAF9-48AA-91F9-6CCA33061276,BctBaseSmmMDN +0A9F795E-B9FC-4117-BC4E-138695D16562,AmdSocFp5RvDxe +0AA10093-E97A-4E28-8E77-7CB37041B291,DeviceBlacklistWmi +0AA31BC6-3379-41E8-825A-53F82CC0F254,AmiTpm32Bin +0AB697CE-B920-48AC-A265-EC5624EDCDD7,DellDevPasswordProtocol +0ABD8284-6DA3-4616-971A-83A5148067BA,IsaFloppyDxe +0AC12AB3-DD33-4460-87F5-82694D3D7402,SmcOFBDNull +0AC2D35D-1C77-1033-A6F8-7CA55DF7D0AA,CpuPolicyPei +0AC742BF-07C6-4C87-A87D-A3B2918AFD00,TileDxe +0AC7D82C-9BAD-419F-B8FF-B39BA18737FD,Rtk8852CEWifiSupDriver +0AD3D31B-B3D8-4506-AE71-2EF11006D90F,UefiAcpiBoardInfoGuid +0AD4F13B-D197-44EC-FFFF-FFFF62C8C689,XnoteVariableDxe +0ADFB62D-FF74-484C-8944-F85C4BEA87A8,AmiEfiKeycodeProtocolGuid +0AE01967-8B3B-4572-85BD-EFD5C0F251EB,AmdPspRomArmor3Smm +0AE8CE5D-E448-4437-A8D7-EBF5F194F731,EfiDxeIplPpiGuid +0AEF5579-3700-41D2-A53E-DABD55E22432,DellUsbBusSmm +0AF0B742-63EC-45BD-8DB6-71AD7F2FE8E8,ShellDriver1HiiGuid +0AF7C79C-65B5-4319-B0AE-44EC484E4AD7,EfiHashAlgorithmMD5Guid +0AFD2FA7-5EF2-4B3B-A65E-B6F276D082A1,AdvBootOptionPolicyDxe +0B04B2ED-861C-42CD-A22F-C3AAFACCB896,BiosVideoDxe +0B0D3C7E-473A-22E2-8428-3DAE5CCEAC64,CableDetectDxe +0B1E645F-5E5C-48A1-FFFF-FFFF5804E747,XnotePlatformResetRuntimeDxe +0B227B84-9466-46BD-8ABA-8EEA99FAD22C,AsusEcNvramDxe +0B234DF1-0080-412B-8716-8A81A3A11FAA,DellEdiagsDxe +0B24790B-6C79-4CE4-8E09-3864C49BE256,SioWdtSmi +0B280816-52E7-4E51-AA57-11BD41CBEFC3,EfiPciHotplugDevice +0B2B4F68-3566-40FC-B7E6-FA819993840A,OemUniWillVariableDxe +0B2CFBF2-3E08-4C4E-A74D-59748A9F930F,LegacyRegionDxe +0B2E406A-ED5B-4668-BCD1-2B1DB01841FC,DellAcpiOemConfig +0B3AFDEC-F177-4548-9C7E-4D09EDF4A2FA,EcdSmartPowerOn +0B4AE6BE-6DA6-4908-8A71-7E6A8A33B11C,MeFwVersion +0B4BDCFF-74B2-45AD-91E1-8F6634C8A1DC,SIOBasicIOPei +0B590774-BC67-49F4-A7DB-E82E89E6B5D6,EfiPeiMpInitLibUpDepPpi +0B64AAB0-5429-11D4-9816-00A0C91FADCF,EfiBisProtocolGuid +0B6A8DE0-6281-40A2-8E9A-09F1A18A6D40,SystemUsbSwitchSmm +0B6E5233-A65C-44C9-9407-D9AB83BFC8BD,EfiCertSha224Guid +0B6F5CA7-4F53-445A-B76E-2E365B806366,ArmVirtTokenSpaceGuid +0B74F980-2325-4AF3-9664-0C3ABE237D52,BootPerformanceLogSmm +0B7BF76C-721A-44FB-A758-52E13CA457F1,DellSpiPartMxic +0B7C6357-A4F5-48B9-AA30-0CE7F9E66A72,RestoreVariablesSmi +0B7E694D-B909-4097-9C03-5E728489F709,HybridGraphicsConfigGuid +0B81B13E-E595-4D35-9E7B-A3C85E01A23F,HhmDxe +0B9303A2-5BF6-4725-8414-7EDCD343D27D,RZ616_MtkWiFiDex +0BA38E92-154A-4BE2-A5E0-BE80571CDB71,DellDtwlanSmm +0BA8263C-A8BD-4AAD-B402-6A6AF2F7E77D,BlockDeviceCapsuleGuid +0BA8630D-B1F9-4CED-887D-DD013A0C6B4A,UsbTypeCChargingPei +0BAED1B4-B14B-40F1-9D67-B8CD96F923E4,AsusTCONDxe +0BB12CAC-CFA9-4839-A4C2-1797248109D0,DellLegacy16Rom +0BB51CDD-A750-442F-A15E-7DEADFBA30FF,Mtftp4Dxe +0BB60340-8865-4584-A32D-7F839903DF4E,MmioSerialUart1 +0BBC6CAB-F228-4F20-8C6A-847CDEE3FF24,OFCDxe +0BBC88DE-17D1-4DBA-BA54-734B01DE421F,OEMPlatformGopPolicy +0BC22608-ECC5-47B9-A038-4F0A68372E44,DellDeviceNameConfig +0BC7E05C-C88A-4254-BCBB-D42638D28AAD,PlatformMilestoneSmm +0BCAF6F4-5A78-4818-82BC-5594D175943C,FchSmbusPei +0BCB2808-FEA5-6047-9A60-8767A46A72A1,AppleUdp4Dxe +0BD7EBBF-F1A9-4C0B-9941-636D102AA48A,FchBixbyDxe +0BE3D6AE-6D2C-41AD-9869-A97364E7C1F1,FjIbvSfuSecFlashAbstractionSmmProtocol +0BE98320-5634-4AAB-B2B7-FCBC9777151E,FjTerraSmm +0BF06027-29A4-447D-8FA4-D8A289F1DDDC,CxlManager +0BF13AFB-98B6-4B77-96E3-0868917C2D2E,I2cBusConfigurationManagement +0BF70067-D53B-42DF-B770-E92C91C61411,EfiTdtProtocolGuid +0BF89093-3E5E-457A-8CA6-62352915A3B4,PHashDPei +0C008B0D-596A-42D1-809C-D2E7B649177E,HwErrorHandler +0C04B0FF-227D-479A-935A-F6E5A8B5198C,EfiPeiPlatformTypeLightningRidgeExecB2Ppi +0C070BA5-3F07-4E9D-883F-057C505FE3B8,BiosAuditLogWmiReporter +0C0F3B43-44DE-4907-B478-225F6F6289DC,UsbKeyboardLayoutPackageGuid +0C0FA9B6-F3AF-49BD-89C5-6C2D43969072,MmioSerialUart +0C109319-C149-450E-A3E3-B9BADD9DC3A4,EfiPeiMmConfigurationPpi +0C1F6580-9C57-4A32-8499-227C2EA27E7D,DellSmmServicesProtocol +0C215B39-425D-42E0-A1B4-367D574956EC,FjDmiSystemData +0C2C4003-6551-4EEA-B006-0FECB4BB300B,RTL8111E +0C34B372-2622-4A13-A46E-BFD0DEB48BFF,I2cBusDxe +0C375A90-4C4C-4428-8EA0-531BE8959BF7,FlashDriverSmm +0C3798AA-D22E-4DD6-8CB4-3C9CFB1D86D3,NCT6126DSmm +0C396FCA-6BDA-4A15-B6A3-A6FA4544BDB7,EcFwUpdateDxe +0C3B7B59-28E5-4C99-85E5-D0116DBFAAF2,IsctWakeReason +0C4F81C5-309F-4941-85A2-8C6A44B4F4F6,AmdVariableProtectionSmm +0C556BFF-B16A-439D-A3EC-1164378E2C2A,AmdPspPeiV2 +0C5FCE90-1C03-4ED2-9EFE-B1D02E72B3B0,menu_bottom_mid +0C8050B7-D2F0-42F8-852B-D1DEB2F2E9B0,SetupIoDetect +0C80C256-3428-4D1C-BBEB-79FCC812AFF6,RestorePasswordSMI +0C81D263-7CE3-4F61-A175-FDA4FD240985,HpAltModePei +0C85DF8A-4212-4CC1-A4AA-1A7A36E8DA97,FpgaPlatformEarlyInit +0C8823D5-93FB-485C-AAFA-FA7B6BF0A27F,CompalEepromSmm +0C88B3B5-6A1D-4657-AA88-1B7D92FF3699,CompalCMFCCommonSwSmi +0C88F1B7-DD08-4E29-BE2D-D04688A42C74,OemKbLightDxe +0C95A916-A006-11D4-BCFA-0080C73C8881,WinNtThunkDxe +0C95A928-A006-11D4-BCFA-0080C73C8881,EfiWinNtVirtualDisksGuid +0C95A92F-A006-11D4-BCFA-0080C73C8881,EfiWinNtPhysicalDisksGuid +0C95A935-A006-11D4-BCFA-0080C73C8881,EfiWinNtFileSystemGuid +0C95A93D-A006-11D4-BCFA-0080C73C8881,EfiWinNtSerialPortGuid +0C95A940-A006-11D4-BCFA-0080C73C8881,WinNtBusDriverDxe +0C989D41-F4B4-4244-9D7F-E9FFB4163273,FastBootOption +0C9C3169-6F39-409E-990B-5B8B48B9D2B9,SyncUpNvramToPostFlag +0CABB327-11FE-416B-AE80-2DE5DF60F77D,IioPolicyHob +0CACEC37-B79B-4A78-B3C5-EA61EAF6980D,BiosInitToFactorySupport +0CC252D2-C106-4661-B5BD-3147A4F81F92,EfiPrint_2sProtocol +0CC2C3FC-41F0-4830-ACF7-0BA8EC78045A,SpiAccessPei +0CCA1898-D936-4386-872B-734FE850DC49,FjIbvSfuOverrideAbstractionDxeProtocol +0CCF27CF-E68D-4279-96B0-8A4E1CDFF10C,SettingsManagerDxe +0CD3D2FA-B21D-47B5-BA95-D8C00B38F324,DellAi13Rom +0CD80A60-46D9-48B3-A8B9-61E5598AB054,MultiPdtDxe +0CD9632B-A19C-4488-8917-4E1C8E75DC1A,ncm865x64 +0CDA5D94-951A-4C61-8DD5-E5BF34BA69EC,SlotDataUpdateDxeLightningRidgeEXECB1 +0CE47609-0E04-4EE5-A192-F410A1995E0A,b57undix64 +0CE5EA44-BED3-49CA-AECC-B50AB9C5B0E9,DellRecoverySiDxe +0CEFD645-588E-4ED7-9943-054808CD7572,SiFirmwareVersionDxe +0CF7AEE6-3BD4-48A3-97E2-E7E5B83F67FD,CbsBasePeiRS +0D024887-B489-4E9F-884B-A4B6BB8A576B,ODMCompuTraceDxe +0D05D4DB-4A1D-4DCD-89B5-87B36C6DD180,SDEmmcInfoDxe +0D1B9C8E-F77B-4632-8343-91F43D9A8560,EfiCpuHtCapable +0D1CE46B-72D9-4BA7-95DA-23511865E661,CryptoPei +0D1ED2F7-E92B-4562-92DD-5C82EC917EAE,CrbPei +0D1ED2F7-E92B-4562-92DD-5C82EC917EBF,EcsPlatformPei +0D22D223-E9A7-00C5-BE84-3FCAF25EC1A7,InstallMadtDxe +0D244DF9-6CE3-4133-A1CF-53200AB663AC,FspsWrapperPeim +0D24A235-9C12-446C-8ECB-EFC1F5280209,DellJpegDecoder +0D275C72-10C6-4D8C-8B2C-6610E69E3403,Uart16550SerialDxe +0D28C529-87D4-4298-8A54-40F22A9FE24A,DellDaHddProtection +0D2B85C0-D468-4ADB-93BF-E53AE203C034,OemErpPolicy +0D3FB176-9569-4D51-A3EF-7D61C64FEABA,EfiSecurityPkgTokenSpaceGuid +0D42E9AB-5DDE-4CAC-A485-0215C252717F,AmdSmmControl +0D4BBF18-C2CC-4C23-BD63-BFDAD4C710D0,Tcg2Acpi +0D51905B-B77E-452A-A2C0-ECA0CC8D514A,EdkiiNonDiscoverableDeviceProtocolGuid +0D57B171-A6D2-49C9-95AD-ABC02546E605,DellSystemUsbPortConfigDxe +0D58AE36-31AF-4CF3-A74D-74891A1597F2,AssetIDDxe +0D648466-36BD-42C6-B287-7C3BAA2575C0,LenovoSetupUnderOsDxe +0D759F81-43B0-4E0A-B613-61550C6157C2,SystemGraphicsOutputBltPipeDxe +0D79A645-1D91-40A6-A81F-61E6982B32B4,EfiNt32PkgTokenSpaceGuid +0D8039FF-49E9-4CC9-A806-BB7C31B0BCB0,AmiTpm20PlatformPei +0D81FDC5-CB98-4B9F-B93B-70A9C0663ABE,DellDccsSmmDriver +0D82A9EC-1289-4FD4-AC0B-4C6B1A25ABC6,SwitchableGraphicsDxe +0D8E6E4E-B029-475F-9122-60A3FEDBA8C0,DxeIoLibEsal +0D8FA117-1239-4CD6-AD0A-331663824B13,DellOnboardNicPei +0D966D65-8F25-4574-8EAF-6C0463F38742,UsbPortConfigSmm +0D98D4C6-59B2-44CC-8E28-4540130E347D,LaunchPadDrv +0D9A1427-E02A-437D-926B-AA521FD722BA,EfiPciLanInfoGuid +0D9E8DB6-5A5A-4A5B-8621-85FFC9AE4583,DellStealthModePolicy +0DA55BC9-45F8-4BB4-8719-5224F18A4D45,EfiWiFiProtocolGuid +0DB48A36-4E54-EA9C-9B09-1EA5BE3A660B,EfiRestProtocolGuid +0DBCEC22-0ABE-4BF4-BFEE-A04D1CA6F643,PlatformInitDxeHedt +0DBF0B49-604C-40D4-9121-77AC41942626,FixedBootOrder +0DC02196-CEC8-4A0E-9DCD-B0DE59D86204,Wcn685xLauncher +0DC65ADC-A973-4130-8DF0-2ADBEB9E4A31,FirmwarePerformanceS3PointerGuid +0DC73AED-CBF6-4A25-A68D-59C80F44C7C3,EfiDFUVerGuid +0DCA3D4D-12DA-4728-BF7E-86CEB928D067,EfiNicIp4ConfigProtocol +0DCA793A-EA96-42D8-BD7B-DC7F684E38C1,LegacyRomLayout +0DCE384D-007C-4BA5-94BD-0F6EB64D2AA9,PeiNtAutoScanPpiGuid +0DCF3594-318C-4596-B00F-BE61842DE3E2,SystemBootTypePeiPei +0DDE9636-8321-4EDF-9F14-0BFCA3B473F5,DellIntrusionDetectSmm +0DDF623A-9F60-4AF2-B5C7-EFE4A637290E,FjDtDiagnosticsDxe +0DE19141-7AEB-46CA-9F87-2D19FEBC99C3,OemBootMiscDxe +0DE2CE25-446A-45A7-BFC9-37DA26344B37,EfiPeiDeviceRecoveryModulePpiGuid +0DE8BACF-E00A-4538-BE0D-81AF9374FCC9,EmulatedEepromSmmProtocol +0DED86EE-6E79-4764-AA83-37A472F48123,ChkrecoveryFile +0E00B084-2D16-4A27-B172-B1F68C2CC55D,MicrocodeUpdates +0E06A80E-D726-4BAF-A0CF-211260FE69D8,OemSSIDUpdate +0E0885B3-07A2-41AA-82E7-806A47A9215E,Parade_Retimer_FmpDxe_FwUpd +0E109C7B-8790-4B9D-981C-9D4B079E98D4,MsiSGSmm +0E135E4D-E63E-45C6-A9A2-E9363477DDFC,AmdNbioBaseMdnDxe +0E1B2F3C-DD5F-44CE-8D37-5AEC2B339B5C,BiosConnectSOSLauncher +0E1D2972-65AF-4AC1-BFA3-CEF4AB0C38FE,EfiCapsuleCrashGuid +0E2D6BB1-C624-446D-9982-693CD181A607,EfiSmmTcoDispatchProtocol +0E2DAF63-8A4F-4026-A899-DE2D7F46E5EC,TpvPei +0E2EDA9F-4BB6-4140-AED6-7DBCEB63C829,MtkWifiSupDriver +0E359F52-C6DE-4EA4-9A05-857DE1B7D320,FjWifi6eSupport +0E3606D2-1DC3-4E6F-BE65-394982A26547,PlatformVirtualKeyboardProtocol +0E3FEFDE-4A6C-4E4F-B77F-4B456150430F,PegaSetKeyboardSetting +0E3FEFDE-4A6C-4E4F-B77F-4B46C950430F,PegaSMBIOS +0E4D805D-746C-4EBC-8795-31A286CCA620,TcgPeiPolicyHobGuid +0E511F9D-5B86-4389-9325-9F8217220FBB,CpuInstallEfiMemoryPei +0E51393A-E865-4C3E-8C5F-442FE09146A5,DellSmmVariableProtocol +0E5870E4-0525-40AD-95A8-0FFF155B8FC0,AmiSmbiosElogSupport +0E714B8D-EEAA-4FBA-83AB-2B8005D417C3,EnableM2PCIeCardDxe +0E7383B1-83EE-41A4-939E-24C886F03AD6,DellVirtRtcSmm +0E78D1D6-5691-4793-8FF7-465CB7F9124E,DellNvmePwDxe +0E84FC69-29CC-4C6D-92AC-6D476921850F,UpdateDriverDxe +0E8C545B-A2EE-470D-8E26-BDA1A13C0AA3,LastEnumLangGuid +0E93C52B-4B73-5C32-86D5-69250A0BA723,AppleThemeFileNames +0EA3D651-49B4-47D9-BDC3-E4A379F3DE76,HwmInitSmm +0EA4E9CB-819D-4B37-9362-AE1783481AC0,FjDtPowerFailureRecoveryPlatformSmm +0EA50C2B-4C0D-4CA3-97C1-0014DB754473,UefiLegacyBootMarker +0EAB05C1-766A-4805-A039-3081DE0210C7,FmpDxe +0EB4819C-D878-4C8D-913B-404947AEB89F,PlatformStorageInformationDxe +0EB4FAC0-A3EC-4FED-9783-A8D0FFD1AE33,DellSmBiosStrucDb +0EB84DA1-267A-40B4-8347-1F48694C8B47,PeCoffExtraActionLibNull +0EC1C157-DD5E-426B-8764-68C1DA088C49,OSDSMIFunctionPei +0EC2019D-BC70-4A4E-A239-501EF5D6F742,InstallPlatformSsdt +0ECC666B-4662-47F9-9DD5-D096FF7DA49E,PeiSecPerformancePpiGuid +0ECE530F-7BDD-4405-9EB9-61C9868D8ABD,AaeonSmbiosDxe +0ECEDD30-67EC-4570-9EFB-308DE53EE93D,AmiTseOemPortingVar23 +0EDC9494-2743-4BA5-8818-0AEF5213F188,EfiExtendedSalCacheServicesProtocolGuid +0EDEF0B3-EF91-4935-859E-2338DFFAC099,MpdtUpdateDxe +0EEC96BC-0B82-4573-9791-C414E4DCEE64,IhisiService +0EECB4A5-7B9F-4707-81D7-9C045E98CA95,AmiPlatformInfoUncompressedFfsSection +0EF3C867-459B-41D8-8541-DD7DC277EBC0,PdHostInterfaceRtkPei +0EF53039-3A38-42D1-BCEC-CE966E87061A,PeiFrb +0EF84C20-D178-490B-9FCD-122739FAAEFC,FchSmmDiagDispatcher +0EF8A3B1-388A-4B62-8BE6-C7877D50AEDF,UefiPxeBcDxe +0EF98D3A-3E33-497A-A401-77BE3EB74F38,EfiAcpiS3ContextGuid +0EFC6282-F1E5-469A-8A70-194A8761F9AA,XenAcpiPlatformDxe +0F03D285-6614-4DDC-86DC-DAE5E375443A,EndOfFirstPowerOn +0F0B1735-87A0-4193-B266-538C38AF48CE,EfiIfrTianoGuid +0F0DA838-E678-432E-9AEE-CB606E89B3DA,FchSmbusPei +0F17CECC-653A-C343-9CFA-FAA27A07EFE5,AppleCrypto +0F23C1F8-4BAC-470C-B6B8-B392D544290A,FmpCapsuleUpdate +0F2FADAB-E401-63ED-7E29-69F215C60511,OemUSBGetSetupData +0F411BE5-B10C-4DDA-B28C-868FC24789F8,AmdVariableProtection +0F492340-21B3-4E23-9140-8C14476292CD,SetupRepSetSmm +0F500BE6-ECE4-4ED8-9081-9AA9A523FB7B,HstiPublishCompleteProtocolGuid +0F5DD251-6C8B-4752-8110-FCDF57EEDFB2,DxeReportStatusConOut +0F5EF786-17A0-40C6-BC18-1B3272A00987,IccInit +0F647B12-5FA2-4B5E-9D61-2AB3C51F224E,BctBaseSmmSSP +0F6499B1-E9AD-493D-B9C2-2F90815C6CBC,EfiPhysicalPresenceGuid +0F69F6D7-0E4B-43A6-BFC2-6871694369B0,WdtAppPei +0F729F33-25C1-41A7-86B2-23A737A91823,IntelSnbGopVbt +0F7BDE7C-AAF3-48D0-931F-475750DDE209,OemPei +0F7BDE7C-AAF3-48D0-931F-475750DDE210,OemWwanPei +0F7EC77A-1EE1-400F-A99D-7CBD1FEB181E,PcatPciRootBridge +0F886E75-3029-4ECF-B694-22894D3F2143,PLEDDXE +0F8E91FD-9964-4A65-B052-C4639C5A9EF0,SioRfTestWmiSmm +0F92508B-F17C-4EFB-8722-BCA5531F8B53,CpuDeviceInfoDxe +0F99E33C-CA0C-4AA2-887D-B57EC9050278,SaveMemoryConfig +0F9D89E8-9259-4F76-A5AF-0C89E34023DF,EfiFirmwareContentsSignedGuid +0F9DD4B0-599E-4D66-8565-22FBEA1E028C,AmdFabricPhxPei +0FA00C23-CACA-5515-6AD3-B7D87540DFA3,BLSeedTest +0FA79B12-719A-41EC-8C57-7C24F4771162,VerifyHpRomSignature +0FAAECB1-226E-4782-AACE-7DB9BCBF4DAF,EfiFtp4ServiceBindingProtocolGuid +0FAD5644-7BDF-4A75-B568-287AE2EBD3A6,SmcSwSmiFlashSmm +0FAF9D33-E3B7-49DE-9B04-3A8B1E732AFD,Armani_BatteryInfoSmm +0FB3BCF9-0A1D-4598-A521-E5C84E95D97A,EfiTraceHubStatusCodeHandlePei +0FB7C852-ADCA-4853-8D0F-FBA71B1CE11A,EfiFormBrowserCompatibilityProtocolGuid +0FBA43B8-ACDB-4EE2-AB31-0FA4D5B6C3C5,FastBootTseProtocol +0FBEE984-33BF-4AC0-A871-B352AD59E337,DisableLTEB +0FC38C56-500A-4654-89A7-F43C1A3843F5,AmiPlatformInfoFfsFile +0FC50878-1633-432A-BDE4-841357FC15E9,AmiScsiPassThruInitProtocolGuid +0FC9013A-0568-4BA9-9B7E-C9C390A6609B,EfiLegacyRegionProtocolGuid +0FD41E0B-C4DF-4B4B-863D-17C0DBD6EF56,SbSmi +0FD57366-4708-3EE0-392B-14A873782A25,PciePowerManagementSmm +0FD60162-A235-47D3-BF7E-735E027D48B2,AmdFabricRmbSmm +0FD96974-23AA-4CDC-B9CB-98D17750322A,EfiHiiStringProtocolGuid +0FDB6F0B-5581-4999-AF7D-A571E3131BD2,FjGabiDeviceFirmwareApiSmm +0FDB764B-E669-4C69-83AC-5EDD99A2711E,ReadOnlyVariableOnReadOnlyVariable2Thunk +0FE159B5-076F-4C36-BF26-D724F2831252,BdsCtrl +0FE9DA53-043D-4265-A94D-FD77FEDE2EB4,TcgPlatformSetupPeiPolicy +0FEBE434-A6AF-4166-BC2F-DE2C5952C87D,DellAbsoluteDxe +0FFBCE19-324C-4690-A009-98C6AE2EB186,RecoveryOnFatUsbDiskGuid +0FFC90BD-B0B8-4538-9D8A-23AB12345678,SctPdmCustomFileDialogDxe +10064AEC-4E12-440D-8126-D71D07837423,PeiCallback +1009A840-C625-42B3-A94B-B90F991B1B1A,NhltInstallTable +100C2CFA-B586-4198-9B4C-1683D195B1DA,MMC +100CB8AA-7BFC-4D2B-90BE-0A48C9ED5316,BoardMilestoneHookDxe +1011B5D2-261A-424F-977C-C8A4B39353B8,StaticSkuDataDxeArcherCityModular +10149626-5583-4364-822F-A459B8121302,SystemFirmwareDeviceDxe +1015EA63-7421-417D-BB51-E5193061C551,DxeIpmiUsb +10164673-D365-4BE2-8513-1497CC07611D,ScPolicyPpiGuid +101DF54A-10FF-4E0D-94C0-A89D5546DD6C,AmdFabricStxhPei +102287B4-6B12-4D41-91E1-EBEE1F3AA614,UefiDebugLibDebugPortProtocol +1034183F-AF0A-4716-BE0E-4CB5319D6193,PciHotPlugNonRpDxe +103D3C97-CE0F-4DF0-97B0-194C61BD540C,FchEspiCmdDxe +1051EC65-F6FC-41EA-BA51-344C37F60CDF,BoardConfigInitPreMem +1054B2FA-3DF0-41FC-A7CE-D59379F3988E,AsusSIBoardPei +105884E1-57DA-4F36-9104-8D092339D234,DellThermInfoConfigDxe +105FF0EA-A0C0-48A8-B8F7-E8B4D62A1019,FmpAuthenticationLibRsa2048Sha256 +1062CB92-72A9-4FDC-9694-B1FE817EFAAF,DustFilterAlertDxe +1065E739-23C2-493F-B1AD-DC6D8DF77CF4,HpGenSwSmi +106A2FD5-11FF-42EA-AFBA-B4969A702616,BaseOobLibrary +106C877F-C2BA-4C46-876C-BDFE6171CD7E,DebugCommunicationLibUsb3Pei +106F3545-B788-4CB5-9D2A-CE0CDB208DF5,EfiHiiThunkProducerGuid +107A772B-D5E1-11D4-9A46-0090273FC14D,EfiDriverConfigurationProtocolGuid +107A772C-D5E1-11D4-9A46-0090273FC14D,EfiComponentNameProtocolGuid +10811F41-037E-4EBE-9872-771D7646FFFA,LEMSAPAMLock +108343B1-3F5B-4908-9525-E25E62D5729A,LegacyPciUcrDxe +10921D66-281D-496E-A3B4-A8D47FD6DE9E,HpVpinSelectionSmm +1093A6F0-37ED-49BA-9DCC-4F6999807315,MmioSerialUart2 +10952220-AA32-11DF-A438-0002A5D5C51B,PL35xSmc +10B12ADD-F5E2-CC78-5CA0-B77F76223ACD,AmiCpuFeaturesDxe +10B7F979-741C-467E-8764-8DD50D8AD6C5,SdioInt13 +10B91E23-11BA-4CB5-9012-AF5016005DD3,SelfHealingDetectCorruptionDxe +10BA6BBE-A97E-41C3-9A07-607AD9BD60E5,EfiVlv2VariableGuid +10C22623-DB6F-4721-AA30-4C12AF4230A7,IdeRecovery +10C22623-DB6F-4721-AA30-9C12AF4230F8,ExtRecovery +10D72AD4-F4D5-4F35-A5A3-001F6ED81E1E,DxeSerialTextOut +10D93A56-2D64-47D3-828D-7A5066915292,AmdRasBrApeiDxe +10DB0A54-F6F9-4CA2-A75E-F9AACAE70970,BiosGuardConfigGuid +10E26DF1-8775-4EE1-B50A-3AE82893703A,SeCfTPMPpiGuid +10E88749-28D1-49A0-AC9E-0324E40211A8,WMISwSmi +10EE5462-B207-4A4F-ABD8-CB522ECAA3A4,Udp4Dxe +10EE54AE-B207-4A4F-ABD8-CB522ECAA3A4,Udp6Dxe +10F312D4-4A25-4D75-A1F3-1A264ADCDBCF,DellSoftTAALoadDefault +10F432DE-DEEC-4631-80CD-47F65D8F80BB,EfiPeiPerformanceHob +10FB6E0F-537F-41D2-9214-7D00EEBFD6A9,LnvSyncMFGDone2BiosGuard +11052D8B-C1AC-4244-A564-B5A71FF7822A,BiosGuardStoreStatusDxe +11148D39-5926-4022-91AC-CB252AF74530,Usb_Lan_RT8152B +1118396E-54CC-4389-BFD1-97D2AE13E12C,FjGabiCoreSmm +1126215D-B99C-4B09-9CA8-60C611ACE29D,OemEcFeature +11335C60-2618-4AF4-AF9F-15BD35D0577B,FjLidSmm +11354A0C-781E-44A1-A787-C0178C8D570F,P2sbConfigGuid +1136D4DD-D9B7-4801-8352-E7582D32A05A,IntelDRS +1137C217-B5BC-4E9A-B328-1E7BCD530520,DellThermalDebugSmmDriver +11399A01-0423-49CC-8368-85291533C35D,FprSynapticsMetallicaDriver +113B2126-FC8A-11E3-BD6C-B8E8562CBAFA,EfiBootManagerPolicyConnectAllGuid +113FD31A-BE8B-418B-B034-7EAFE5C60C99,EsaInterfacesForTseProtocolGuid +1144265E-F049-45B9-8778-752F12A1365A,IntelTechSetup +11472071-A5CA-4281-9779-DF2C839A455A,DxeSndwBeep +114B7105-6CC9-453C-BADC-16DF227BB4EF,TrEESmm +114BA15A-6189-180D-BFC0-2053B3480949,EfiBoardSelectGuid +114CA60C-D965-4C13-BEF7-C4062248E1FA,EcIoDxe +114DA5EF-2CF1-4E12-9BBB-C470B55205D9,EfiAdapterInfoSanMacAddressGuid +11527125-78B2-4D3E-A0DF-41E75C221F5A,CpuS3 +1156EFC6-EA32-4396-B5D5-26932E83C313,EfiSpiProtocolGuid +115F8F4F-7899-4154-9C1D-B6E12B320BE1,EcCommunicationSmm +11650C26-915A-40AC-829C-A1E1B6333D79,PwrButtonCtrlPei +11668FCA-73BA-4B58-85A2-98AC4DF59A2C,SystemSmmCommunicationBufferManagerDxe +11681F03-6B8B-4CAD-83E7-588A64BC64EA,FjPowerOverEthernetD2927 +116E1ACF-2533-4CC2-820A-BBC10A2AB07C,CpuSpSmi +116ED1E8-F9C6-4112-A49C-87ADA570DEC1,AudioPlayback +11726D68-F147-48DF-AB16-0489818BD570,AmiHpetTimer +117342B2-9824-4170-8AFB-E568E62C0694,AmdSsdtPpcvOverride +11777581-2B67-4075-8EB4-F691A47ECEC7,ProcMemInit +1177B5A8-7BA6-4C20-A3B4-7D6519D8670A,ECHeartbeatPei +11793215-CD3A-422A-A229-249417282DFA,FchDxeMmio +11799AA2-1C5D-4E5B-8A5D-32D20C39B9D3,AfuCapsuleOnDiskPostFlag +1181E16D-AF11-4C52-847E-516DD09BD376,DellCenturyRolloverSmm +11822C42-79E4-48C9-9F73-700D3556B0C0,MyAsusAutoInstallItem +1183FB2D-DFBD-40CD-945B-3FA630879BCD,FjEvteServicesDxe +1188F1FC-06E9-49B8-A615-F5A0886FCF89,UhciInitPei +118FE494-0699-42AA-AACA-62E849359B17,FspRsc2PostCodeMapServicePei +1191BBF5-DCB9-44F4-827E-95359744C987,PlatformStage2Pei +119BFA16-911B-4F1F-B1B2-69F43B759448,DellPcdUpdatePei +119F3764-A7C2-4329-B25C-E6305E743049,DellSmmSecurityVault +11A03A8E-A9C5-4DB9-90CF-4434B01586C4,BootPerformanceLog +11A51DAF-6834-4BA1-AD5E-4A58633B343E,AmdPspDxeV2Rmb +11A687C0-EDBF-4ACF-8FD5-32A0BD5D76AA,RZ6xxLauncher +11A6EDF6-A9BE-426D-A6CC-B22FE51D9224,PciHotPlugInitDxe +11ADE65F-956B-4D0E-B368-86DBC92F01AA,VariableSmiInt15Dxe +11AF0D83-0784-4C1E-9A1B-9CF43127555E,CrbModernStandby +11B1E470-255E-40E3-9517-30513E3F14D3,GsensorExtendModeDXE +11B34006-D85B-4D0A-A290-D5A571310EF7,PcdProtocolGuid +11BFBEB0-FE77-4362-84FB-4F961E7BB2ED,H2OFormDialogDxe +11C4D07D-B44F-4630-BCD8-EFF786E24A74,CypressCCGxSmm +11CAA2F5-4552-4AC3-95D0-8B5DB1FF6D4F,OemDxe +11CDB71A-AA09-4B1B-BC58-F99838A4980D,fTPMTisPei +11D1EC21-E568-4EB0-8E1D-A0809772B606,DellEnhancedVersionProtocol +11D8AC35-FB8A-44D1-8D09-0B5606D321B9,DSDT +11D92DFB-3CA9-4F93-BA2E-4780ED3E03B5,VirtioBlkDxe +11DD0F6C-209B-47CE-8A98-418C9B7CC756,DxeSwSmi +11E32C34-60B5-4991-8DEA-63D3E8C876DE,UsbRndisDriverSrc +11EE12F3-4B62-172F-37A6-A6BEDAB1FF62,Pca9545aPei +11F6C2EA-E21F-5ACF-A5DF-32C12E5E0E70,PlatformPreInit +11FBFDFB-10D2-43E6-B5B1-B4386EDCCB9A,EfiSeCRcInfoProtocolGuid +12025686-3984-466C-980B-8B5E89DA0319,AmiReadyToLoadDxeCorePpiGuid +12067096-18AF-41DD-B4F1-D29592283062,SystemDeviceModePrivateWmiSmm +1206F7CA-A475-4624-A83E-E6FC9BB38E49,SmmControl2Dxe +120992F2-0339-402C-BAB6-16122DB2EC7E,PeiMemoryDiagnosticTest +120D28AA-6630-46F0-8157-C0ADC2383BF5,AmiLegacyBootProtocolGuid +1216BD2A-C05E-4C6D-91E7-EB8E37AD3B7A,aDefaultDXE +12199730-7D13-4C92-97D5-1562515A1E48,OemThermalPolicy +121D5264-990F-4716-8061-C2144A7D4D0D,DxeDgOpregionInit +12345678-930A-4A95-AB04-2E6CFDFF6631,TcgPeiAftermem +12345678-AABB-CCDD-EEFF-112233445566,My +123AC7B6-F44D-4220-BD8B-521D30DEA80F,M2CarrierSupportDxe +124A2E7A-1949-483E-899F-6032904CA0A7,SystemSmmAhciAspiLegacyRt +124ED7DA-3DBE-49DB-8AA8-CA584CC063E4,DirtyShutdown +1259F60D-B754-468E-A789-4DB85D55E87E,EfiSwapAddressRangeProtocolGuid +125F2DE1-FB85-440C-A54C-4D99358A8D38,EfiAcpiS3SaveProtocolGuid +126A762D-5758-4FCA-8531-201A7F57F850,LenovoSetupStartupDxe +126F424E-F45B-4406-801E-2AACF404167F,AmiSetPhysicalPresenceGuid +127C1C4E-9135-46E3-B006-F9808B0559A5,Slp20Markers +127D145B-410D-4DD7-BFAF-15A3D3B60B94,SetupRepSetDxe +127D4E48-85C0-4FBA-B678-B14E9492AADF,FchKernPei +12826089-D1EC-4505-B3AE-8E4CF3A4A78B,SetBoardId +128FB770-5E79-4176-9E51-9BB268A17DD1,PciHostBridgeDxe +12900E5E-B88B-446C-AE19-18A0856B717F,SioSmbusAccessDxe +12963E55-5826-469E-A934-A3CBB3076EC5,DellSmmSbAcpi +129F6AA7-AB69-4CB8-AED1-40985001115E,SerialMuxControl +12A5DC4A-88AA-89DA-89D0-D4547191E3F4,RstUefiDriverSupport +12A5DC4B-88AA-89DA-89D0-D4547191E3F4,SdMmcOverride +12A9420E-546A-484B-85E7-6F6B27BF9B40,FjCapsuleResetHookSmm +12A94570-A22F-4069-B52E-B71EAEE4E06F,FjOemGlobalNVSDxe +12AEDBEA-392D-4E2A-8789-5F6DC6B23661,OemBadgingSupportDxe +12B0AA24-AC37-43F2-A84E-3CCA6437BF6D,AmdLegacyInterrupt +12B6C042-7C62-4666-A472-89ED5133A98C,FjIbvInterexchangeDataStorageProtocolSmm +12BFCA88-7A2F-4AB5-9A5D-C40CA68BF75F,BootOrderSection +12C293C3-3745-4726-8FA2-2A9EF18679AD,AaeonBfpiDxe +12C67BE1-AD2E-4F13-A95F-6EDC2C4392DE,MePolicyInitPei +12CADD30-6007-4C83-89D7-FF237F7B947A,SetupCompleteRedrawGuid +12CD8A4D-93FD-E81C-72FC-D931EBBC04D4,DellTouchScreen +12D1D3A2-99F7-420B-BC69-8BB1D492A355,Logoid +12D43AAE-DDC1-4615-B0BC-E115F9D17FC1,FjPowerButtonSmm +12E082F4-0DCE-444B-B89A-EF3328428D64,ArmaniSmm +12E1529B-B6A0-4D7F-8B15-5036C9BC2DE3,Fji210LanControl +12E2306C-1EBD-3140-B92E-EFA9099E82D2,CacheManager +12E5A97F-98D1-4C1F-87DA-FB67CFFBD9DA,EfiLanDriverDxe +12E7691F-1EEE-4ED4-8793-69E2801D602A,LenovoFpPba +12E7691F-1EEE-4ED4-8793-69E2801D6123,AsixPxe +12F38E73-B34D-4559-99E5-AE2DCD002156,BaseFspWrapperPlatformLibSample +12F70DB2-8585-49A6-A1E5-20F0363B05B0,WCN7850 +12F75401-5415-4FF3-A981-A39BEE9F369E,SerialRecovery +12FF2998-429F-400B-B9EE-FEA8287A1DFE,FjAbtDxe +130B8BA5-E63E-44A0-85DB-4D4E571C526A,IioCfgUpdateDxeNeonCityEPECB +1310BA34-D7B4-4A80-A645-8C0417C6AA55,AmiMemoryInfoConfig +1310BA66-D7B4-77B0-A645-8C8887C6AA29,AmiSvrMemoryInfoConfig +1314216C-CB8D-421C-B854-06231386E642,PlatformInfoDxe +1314B450-E856-438E-8131-CF823CAB3550,ExpansionSlotConfigPortingPei +1317F0D5-7842-475C-B1CA-6EDC20DCBE7D,HashLibTpm2 +1318FED0-2765-42B5-803E-3215A3C093C5,AmiTseOemPortingVar27 +131AAC21-2145-49E6-A3E1-A97BCE090020,AcpiSpcr +13222252-931B-4552-9577-68556113AFD0,FjSmmPcieCardReaderRTS5250 +1323C7F8-DAD5-4126-A54B-7A05FBF41515,SmmAccess +132EC73B-3025-4FBF-B193-8ACB50EFBD89,QFlash +132EC73B-BD26-4FBF-B193-8ACB50EFBD89,UserDefSetupDxe +132FD006-2915-40EA-B779-0F0DDD01465F,PxeDriverRtk +133EAD80-FB48-11E5-939D-6431503B939A,TransparentUnlockDrv +134BEDBA-7ACF-4295-A4B4-66565E3E97D1,OemAcpiNvs +13524551-5600-43B4-A5DF-F4B1942F339A,MeResiliencyPei +1353DE63-B74A-4BEF-80FD-2C5CFA83040B,GifDecoderDxe +135902E7-9709-4B41-8FD2-4069DAF0546A,TcEfiGlobalVariableGuid +1361DEC9-A270-4013-9701-A540F56C58C9,MctpSmbusDxe +136A3048-752A-4BF6-A757-0936119538ED,UiStringPackGuid +1374882C-B994-48DB-8D1B-93E817541FBD,CertificateStorageDxe +137B3044-F6D7-473E-A625-9FB92505C180,EfiSpiBusProtocolGuid +13863F79-D94B-4205-BB0F-E4E06AAA5A4E,DelayUefiRaidOprom +1388066E-3A57-4EFA-98F3-C12F3A958A29,EfiPeiSecurityPpiGuid +138F81C1-0A5F-4F5B-BFF9-F9B5BCBA6ABF,HpSecureBootModeDxe +138F9CF4-F0E7-4721-8F49-F5FFECF42D40,EfiPeiMpInitLibMpDepPpi +1390954D-DA95-4227-9328-7282C217DAA8,EfiSmmBaseProtocolGuid +1398661B-1EB6-417B-848E-CCC388526099,IntelUndiDxe +139AA2A0-311F-42CC-911A-579A2447B37D,XhciDxe +13A3F0F6-264A-3EF0-F2E0-DEC512342F34,EfiPcdProtocolGuid +13AC6DD0-73D0-11D4-B06B-00AA00BD6DE7,EbcDxe +13AC6DD1-73D0-11D4-B06B-00AA00BD6DE7,EfiEbcProtocolGuid +13B00AAE-4FD2-964E-B30F-94627017370A,BmpConvert +13B03F00-18B8-48DA-8B1C-B290C69BAAFE,EzFileBrowser +13BEAD28-488D-9112-5B0E-40B67EDD800C,AmdRasSmm +13C4BBE0-422C-4CAC-804F-FACDBA6F1A28,SuperIoExPei +13C5506E-8231-415E-9EBC-88DD115E3818,SmbiosElog +13D3B72A-8047-47B8-A4C4-4E814F6B25A1,DnxDxe +13E58E55-E1E1-4CA7-BE88-2D8FE72664DC,DashManagementPei +13E828E8-41A9-4D36-98DE-FD3968E2C18E,LnvPdrSmm +13ECD928-87AB-4460-BBE0-B520F9EB1D32,IconNetBoot +13F37218-70DF-45DD-8883-D4E6F5BE4255,NvidiaGpuAcpitables +13F40F6E-50C1-4B73-B1E2-6E72D21CB04A,EfiUsbLegacyPlatformProtocolGuid +13F4EA8E-BFF1-43BF-8F44-80BCC96040F1,FpgaDxe +13F74CE7-CFED-4E97-9EE6-042B3D2D977F,FjCryptoDESSmm +13FA7698-C831-49C7-87EA-8F43FCC25196,EfiEventVirtualAddressChangeGuid +1400F9E6-4BAB-4B68-A53F-58FD240818E6,Reset_Modify +14045170-CA65-47BC-9C15-2DE36D44AEE9,SmcInBandDxe +1405AD5E-5BED-11E3-866A-047D7B99E097,Slp20ServiceDxe +140E8004-16E1-4DE1-A352-C6EF51110ECF,ArmSmcLibNull +1410C6AC-9F4B-495B-9C23-8A5AEB0165E9,SmmSwDispatch2OnSmmSwDispatchThunk +1410C6AD-9F4B-495B-9C23-8A5AEB0165E9,SmmUsbDispatch2OnSmmUsbDispatchThunk +14186114-B990-4734-898E-5F86FAE49784,DellHwmIoDxe +141B0F7F-E241-4659-91BF-4505D79A7714,FjCpuInfo +1421D662-67BF-4A23-8B32-607E1C9E3AEE,MacAddressPassThroughDxe +142204E2-C7B1-4AF9-A729-923758D96D03,AmiLegx16Bin +14257B56-BDA2-4FAF-8E4F-C885DF75583C,IccPlatformDxe +1428F772-B64A-441E-B8C3-9EBDD7F893C7,QemuKernelLoaderFsMedia +143B7632-B81B-4CB7-ABD3-B625A5B9BFFE,EfiExtScsiPassThruProtocolGuid +143C715E-E903-4667-BF15-03F5A542F58E,ClientronShowSystemInfoDxe +1440F976-2332-4DF3-B77F-62F8C6C1EFFA,AmdNbioBaseRmbDxe +1448C340-0202-4711-9C4B-2D063AA6475B,ProgressBarEmptyLeftEndcap +144C3319-5F75-4A9F-A939-882A7AB29979,FjM2WlanEnableDisableDxe +1450464F-EB36-4AC6-ACEB-DAACC8FC3218,BoardSelectPei +145372BC-66B9-476D-81BC-2127C376BB66,FFS_pad +14575E7C-03D7-4A62-9C01-4EBFBD48BA48,SmbiosTypeAdd +145971E9-AD52-4094-A8C8-BE5B3FECC82D,CpuPeim +145E152B-3DDE-4EB4-99A7-77083C2BCBEC,DellFmpMcu +14610837-4E97-4427-96E0-21D9B2956996,EsalVariableDxeSal +14702E6F-73FB-46D5-BF5B-F0AD781A17B7,AuthenticationPromptProtocol +1471B886-A01F-4835-903C-5C7E792075C2,OememPei +1478454A-4584-4CCA-B0D2-120ACE129DBB,DellMfgModeSmmDriver +147B4839-5DBE-413F-917F-DFEB687C6312,PchResetPeim +14814579-D905-4A3B-8874-410B518674E7,RstNvmExpressSmm +1484EBE8-2681-45F1-A2E5-12ECAD893B62,ArmJunoDxe +14862240-96E5-4986-AB8E-9CEC8BC2AB57,ShowBmcIp +148C8945-F4A2-4586-A508-42F5470B2D47,DellSpdSmbusAccessDxe +14982A4F-B0ED-45B8-A811-5A7A9BC232DF,EfiHiiKeyBoardLayoutGuid +149A6B53-FAFA-44F9-8BAF-F50C68A05236,ScInitDxe +149E1CBD-A263-46DB-895C-4B0201D242B1,CrServiceDxe +14A7C46F-BC02-4047-9F18-A5D725D8BD19,EfiDFUResultGuid +14BAE438-5C05-483E-AFDB-D88325CC0E93,DellKeyManagementServiceSmm +14BB6DA5-0C47-4F2C-9348-8DC272619998,VmwSvgaDxe +14BD268F-76FC-4EDB-87F0-F0D4EBB256B4,VfsFingerPrintDevice +14D159A2-52ED-465D-9353-F239C5464BF5,DellSmmLomProtocol +14E7D9BE-7834-477E-A942-FF5F823EE249,DellSpiPartAtmel +14E9734F-3644-4F3F-ADFE-AB80BF5B48BC,SMBGlobalAcpiNvs +14F95E01-D562-432E-844A-95A43905107E,GuidBase +14FC52BE-01DC-426C-91AE-A23C3E220AE8,EfiSmmSxDispatchProtocolGuid +14FF38A8-ACBA-4228-A7D7-A73260C7559B,PiSmmStatusCodeOnFrameworkSmmStatusCodeThunk +1501F737-C56D-4721-988F-7437F3D22FD9,H19SmmReadyToLockHook +1504BA7B-58F8-4D12-9638-B494A7044376,LenovoSystemSmmServicesSmm +150CE416-EE63-46B6-8BA3-7322BBE04637,SaPlatformPolicyPpi +150EC16F-0BB6-42A8-B605-79794B89D15B,DellEdiagsConfig +151252AC-F77D-4C44-9977-A48CBEEC9CCA,SmmHooks +151664D4-6001-478F-8C97-C51420FC2B75,FchI2cMasterDxe +151C8EAE-7F2C-472C-9E54-9828194F6A88,EfiDiskIo2ProtocolGuid +152656B6-564B-4C8C-877E-B67FB70DFDDC,FjHobFlexIOPresence +15344673-D365-4BE2-8513-1497CC07611D,PchPlatformPolicyPpiGuid +15380DE9-1D51-407F-BE3E-CA71EC05C60D,AsusSetupDxeVariableItem +15446019-9170-436A-A981-CC7521E9D7F9,Usb4PlatformPei +154774EC-4350-40D4-AF66-7D1837BCD559,EfiHeciTrustedChannelSmmProtocolGuid +1547B4F3-3E8A-4FEF-81C8-328ED647AB1A,Csm16 +15488FA6-2391-4C9B-6FB7-6FE0E0F410BC,DellPeiPolicyInit +154CAB4A-52B5-46CD-99C3-4368ABBACFFD,MetronomeDxe +15510D47-FADC-41F4-8B9D-FC323C821FE2,VerboseDisableCursor +1551A247-BB31-4393-8BB4-10509AE2F18F,ChargeLedDebugPei +15551AF8-56A3-43DF-B0BD-22422AD2F08D,DeviceStatusDxe +1555ACF3-BD07-4685-B668-A86945A4124D,CpuPeiBeforeMem +15721C79-5720-4838-A544-052563708E24,AlderLakeSmm +157C666C-7C74-4E4A-B639-7BBA21487CE1,QFanDXE +15853D7C-3DDF-43E0-A1CB-EBF85B8F872C,EfiDeferredImageLoadProtocolGuid +158B59E5-DE4B-4964-8306-40C03F5B5D57,FjMeDataRecoveryEventLogDxe +158DC712-F15A-44DC-93BB-1675045BE066,HashLibBaseCryptoRouterDxe +158DEF5A-F656-419C-B027-7A3192C079D2,ShellVariableGuid +158E2079-23F3-4E83-8A35-657A76408C0A,ApobSspPei +1597AB4F-D542-4EFE-9AF7-B244EC544C0B,EdkiiPeiPciDevicePpi +15A02416-DC90-4F8C-B687-093FFA8BB966,AMIProjectDxePriori +15A450BE-5D20-47E9-8B3B-856058CCD408,AsusNct6796DHwmPei +15A5BAF6-1C91-467D-9DFB-319D178D4BB4,UniversalPayloadExtraData +15AF363B-7C41-4D1A-800D-8BCEE473FF3B,AdlMiscellaneous +15AFBE86-E7F9-42F9-A02D-E95043E62F98,AdlSmbios +15B985C5-7103-4F35-B59D-2235FC5F3FFE,UsbTypeCDxe +15B9B6DA-00A9-4DE7-B8E8-ED7AFB88F16E,CpuPolicyInitDxe +15C5E761-58D8-461A-9173-CAB020916264,VAminiPort +15C75527-302A-4872-BBED-4730A0ABFFCA,LegacyBootEvent +15C80344-F980-4BF5-AAA0-BFBE027AEF16,LenovoEcService +15CCACBE-2A4A-45ED-9EC2-53135F98AB24,BmcAcpi +15CF24A9-F9AB-46D0-8DCF-83664C632FD8,MemDetect +15D101A9-60C5-4577-9672-DE91842D01D5,FjRTS52500S +15DD5676-2679-4E24-9CAA-85B22DD893EB,LenovoSecureFlashVerifySmm +15E4C005-52C0-444C-8C94-56FFA04C7B36,SmuV12Dxe +15EB6248-FB67-4690-B368-270B73B6ED2C,OemUniversalDxe +15EF0BF5-B7ED-4FB6-93D5-08BB4DE87ABB,HbmMemMap +15FE2940-B426-479A-A002-5454A34C7A6E,FlashMapBin +1601E050-BE0C-41B7-8F96-9F48F72B7E26,OnboardControllerCtrl +16036A73-E8EF-46D0-953C-9B8E96527D13,Reset +160D11D8-93D8-40A2-B1F8-7F7E80E0C8C7,DellSecureBootDxe +1612CCDF-2549-466A-BF6F-D06DAAE60958,AppleKeyMapAggregator +161BE597-E9C5-49DB-AE50-C462AB54EEDA,PowerManagementAcpiTables2 +161F757E-ED55-4A75-A6F0-ED2DF16E0842,LanguageDefaultsAndWmi +16259EDB-3A84-4FC1-34BA-BA5AC23256DC,OemWwanDxe +16271FCA-55D9-4A33-93FC-5A3EB128DE21,MiscSubclassDxe +16271FCA-55D9-4A33-93FC-5A3EB128DEB6,CrbDxe +16271FCA-55D9-4A33-93FC-5A3EB128DEC7,EcsPlatformDxe +16271FCA-55D9-4A33-93FC-5A3EB128DEE6,OemDxe +162793AA-0FE7-4010-9818-45F55C5CCC3E,AmdCpmInitDxe +16287BA4-5B9D-4D98-919F-7B7B78CB2BE0,AmiLoadCsm +162CCA7D-DB17-4CD4-99C4-15F16282206E,GoodixTouchpadUpdate +163699CA-FFD9-4EFA-9901-A7B2DF3DE7D1,Class3Smm +163BA792-F811-4FBA-AE8C-101732F0328F,AdlSemaThermalControl +16449EDB-3A84-4FC1-88BA-BA5AC23256DC,OemWwanPei +164B86BF-B265-4033-92F9-BCB6D4ADC0C9,OobProvisionDxe +164CE56B-5EBC-4984-B0DA-C12B4F21D2EC,AmdRasRvSmm +164E5590-FB7A-47B9-8687-3E91DA499D97,AmiAmdUefiRaid +165E05F4-CCD6-418C-9BD9-6D6FF9B1B996,HpCommonDxe +16639ADE-3D0E-45F2-B158-9186FC416A1E,EfiFileSystemCapsuleStorage +166C533A-8F1E-4D34-A60E-0F68D8D61308,OemKey +166CAE80-98DE-45B9-BB47-85307145D874,AmdNbioGfxRMBPei +166CD554-8AAE-4617-8FDD-A2E3A5AFD89E,SystemSetupSecurityDxe +166D1713-23A0-4F6A-9821-ACD94F77BDE3,SbSocBixbyPei +166FD043-EA13-4848-BB3C-6FA295B94627,DellVariable2Smm +16791C86-47BA-BFC7-468F-D9B50D509487,AmdPsppControlPei +167CC1F7-F4AB-46CC-8773-6278056C14EB,BootMaintDxe +1682FE44-BD7A-4407-B7C7-DCA37CA3922D,EfiTlsConfigurationProtocolGuid +168D1A6E-F4A5-448A-9E95-795661BB3067,ArmPciCpuIo2Dxe +168E8FFC-B8DE-48E4-9CFC-D8A667ABEF11,GnbSocRenoirPei +168E8FFC-B8DE-48E4-9CFC-D8A667ABEF65,GnbSocRavenPei +16958446-19B7-480B-B047-7485AD3F716D,FdtHobGuid +16A4ADD0-EF11-4C86-B159-88A2A8C4501C,wifi_3bars +16A66E14-40A3-4A0C-B569-1C6822373345,AmdSocFp7r2PhxPei +16AD4FE0-B5B1-11DF-8CBF-0002A5D5C51B,PL310L2Cache +16B14E2B-DAD9-4618-ACE2-7D324A26F9A0,FjGpioResetPDPei +16B45DA2-7D70-4AEA-A58D-760E9ECB841D,FD_Drv_X86 +16B6109E-194C-440F-94F8-C7CCCCC32DEB,EfiCseEndofPostProtocolGuid +16C368FE-F174-4881-92CE-388699D34D95,SmmGpioPolicy +16C58600-554B-4587-8C62-A40997CFE206,ASRockNetSmtpBin +16C8A6D0-FE8A-4082-A208-CF89C4290433,UefiSystemTableInfoGuid +16D0A23E-C09C-407D-A14A-AD058FDD0CA1,ACPI +16D11030-71BA-4E5E-A9F9-B475A549048A,EfiRedirElogProtocol +16DBCD0A-ED77-442C-A4AB-3DCADE378A1C,ThunderboltNhi +16E9BA4E-9EE9-48A8-A9A0-8E5F529911DA,Pca6107Pei +1705E39E-C353-11E2-A187-047D7B99E097,SetupMenuService +17088572-377F-44EF-8F4E-B09FFF46A070,Microcode +170D9568-C969-4FA1-A533-DB6779BFBE62,LenovoEn25Qh128FlashPartSmm +170E13C0-BF1B-4218-871D-2ABDC6F887BC,EfiOEMBadgingProtocolGuid +171148F3-6CF6-4C58-85D6-73013E19D90E,DriveEraseInterfaceCoreDxe +17119241-1153-970D-6509-75DCDFA41774,SbSocRavenDxe +171272DD-45CF-45E8-BCD9-F3891BF22975,BiosAuditLogDefaultsAndWmi +171E9188-31D3-40F5-B10C-539B2DB940CD,EfiShellPkgTokenSpaceGuid +171E9398-269C-4081-9099-3844E260466C,EfiPlatformTypeProtocol +171F43DC-C4D9-47A6-9641-65DDCDD5AA30,UsbRtDxe +1722EFD4-B7F0-41E8-AD21-0DA8FD6297A3,AmtLockUsbConInDxe +172B4EDF-DF64-48E5-ACAE-BDB51878FDAB,AsfPei +173220DA-F287-4D34-84C4-12EA968B927E,FjGabiEntrySmiDispatcherSmm +17390333-4CE6-48A8-AFB9-0EF55B666B74,RunTimeAcpiDxe +174005F5-3663-4305-9062-904B2BE2D07A,ApobPhxPei +174A8F8A-7B53-48B4-ACA9-D955AB1B5E90,SrSetupPure +174CF46D-B167-4E6A-B1CD-D41E24EFA0F9,AsusBackupSmm +1755E35E-3B29-4F3A-AD20-80788159DA1F,LEMPasswordStoreProtocolSmm +17565311-4B71-4340-88AA-DC9F4422E53A,SmmBiosGuardProtocol +175A5BB0-1508-4714-A1CF-34BD56C825DF,FjHobFlexIOSave +176652EE-2B20-4CE8-A61B-1C152726FEC4,HeciLegacyDxe +1767CEED-DB82-47CD-BF2B-68458A8CCFFF,EfiMemorySubclassDriver +17689034-F11B-468B-8CC4-E114C77F41B1,AsusPTTDxe +17706D27-83FE-4770-875F-4CEF4CB8F63D,AmiAhciPlatformPolicyProtocolGuid +17772369-D262-4B90-9F31-BDC41F2663A5,mebx_main +177B2C74-9674-45F4-AAEB-43F5506AE0FE,AsusPostMessageDxe +177D39D2-43B8-40C8-9AE1-3C5198D6941E,PeiTcgPpiGuid +177E63C1-AED6-4D88-917E-9B4FB9FE4092,PhoenixSmmCoreServicesProtocolGuid +17851FBF-45C4-4FF7-A2A0-C3B12D63C27E,SdBlockIoPei +17985E6F-E778-4D94-AEFA-C5DD2B77E186,QemuFwCfgAcpiPlatform +17A0A3D7-C0A5-4635-BBD5-072187DFE2EE,EmbeddedGpioProtocolGuid +17A269DE-7C35-4132-9EA0-A3EB5AB87F1E,PowerLostNotifyDxe +17A8A22C-8365-4540-9866-DAF6DABEABEF,McBankErrorInjection +17AAF4D7-0E18-4B99-87C6-94C8B5F25FB4,FchShastaSmmInit +17AE8AF9-6644-4342-A786-4CA69645D137,HspFtpmAcpi +17AF0060-A98C-4A03-90AD-6ABED75045BD,CbsBaseDxeRV +17BF72A7-BA65-4837-866D-979B2F2C075E,RasClvPatrolScrubProtocol +17CCF600-3AA4-4FF7-82D0-19CBEB78F443,MePolicyHelper +17D09362-326C-4920-A50C-76F8A116A093,SeCPolicyInitDxe +17D290E7-49BE-41FC-BF62-912C17152FA8,DellSimulatedECDxe +17E9EC9E-4036-4237-B074-D1F29464599C,OemDataRegionFlashSmm +17ED0DA9-EAC5-4613-BDE7-C3A506917676,LoadPartialDefault +17EE496A-D8E4-4B9A-94D1-CE8272300850,EfiPeiBootInRecoveryModePpiGuid +17F76387-DE12-4E59-A107-485BB133B4D6,SecureBioDxe +17FE14B6-9ABA-43C3-BEB0-D12F81AAA883,AmdCpmDiscreteUSB4Smm +180636A5-871B-496D-B8F3-E83EF196D100,menu_top_right +1807040D-5934-41A2-A088-8E0F777F71AB,NvramDxe +180D765F-C489-4F7A-8A3F-596018499EAF,DTbtDxe +1810AB4A-2314-4DF6-81EB-67C6EC058591,BootScriptTableBaseGuid +1812EFD5-0DFB-44D7-9AD6-74FCBB33B192,UiAppWrapper +181E874D-C089-4C99-8EC2-6D6761348220,AmiPllOverVotageFlagHob +18231874-2933-4A4C-AAF1-65B4A752A409,FwHealthReporterDxe +1826B10E-ECE1-4BD1-B351-BC469D17FC59,DellPlatformSwSmi +182F61F3-A6B7-4B56-AB1C-6EF6DDE09798,FjGabiFlashBiosRegionCtrlSmm +1830A6DD-E03D-4BC0-B115-94D91950FE4A,SioDynamicSetup +1834A306-0D70-470E-901F-2370FF30DDAB,DxeSpiNorFlash +1834C334-6F84-4147-B72E-16A1AF7BEF02,AsusPEFirmwareBiosGuardVS2015Bin +18355EC0-EF43-4CD5-9132-D2B33C5E5897,FjUsbTypecPwrLimitCtrlPei +183BB3E1-A1E5-4445-8AC9-0E83B6547E0E,CpuFeaturesPei +18435CD7-8003-4CED-AFA4-ECBC440C0F30,FwBlockServiceDxe +1849BDA2-6952-4E86-A1DB-559A3C479DF1,EdkiiFirmwareManagementProgressProtocol +18578E75-D073-4203-90D2-8788A871E44D,LenovoComputraceSmiServices +1859044F-C25A-4AA8-965A-2410D06A603F,ApobBrhPei +18633BFC-1735-4217-8AC9-17239282D3F8,EfiBttAbstractionGuid +1879BFDD-47FF-485B-88FB-4FCD206E49F4,AmdSocFp7r2RmbDxe +188DAED4-939D-4FAA-9F47-F01D5C16DD82,H19ErrorLog +189641F9-4F75-423F-9427-6457E8ED095D,DashSmm +18968E73-3C45-4333-B97F-8764C23923AC,FjAutoBiosUpdateInterfaceProtocol +18A031AB-B443-4D1A-A5C0-0C09261E9F71,EfiDriverBindingProtocolGuid +18A3B667-14AF-4AE7-840F-CD6317EA0CBD,NbRsRouting +18A3C6DC-5EEA-48C8-A1C1-B53389F98999,EfiSmmSwDispatch2ProtocolGuid +18AF0E1A-CDB4-48C2-B111-14CB070417BF,SyncCBSconfigPei +18BD198C-ECF5-40F2-98ED-C388C3FD9136,DRAMPei +18C040D4-15E4-4148-B7B3-582764710BBC,FprValidityRaptorDriver +18CB2CF0-40CD-11E5-B970-0800200C9A66,DellDptfChipsetDxe +18CC225E-8799-4945-9F92-EBB96423D6C1,FjGabiFlashCommonGbeRegionCtrlSmm +18CC325E-2799-4545-9F92-EBB9E423D6C1,FjGabiFlashCommonEcRegionCtrlSmm +18D543E8-C59A-40DC-AA28-50B832C67D02,CutOffStrToLimitedLength +18D5FF31-7A47-424D-B500-7D792D3E33AC,DellDtDiagSmm +18D6FC7E-D862-48DE-B56D-FA311421BF29,EfiTpmCallBackProtocol +18DA03A8-FAE4-410A-A8C2-34C91913F515,AmdPspIntrusionDetectionSmm +18EBDB3E-95C2-4725-AB63-74B478C475DE,AmdCpmSocAm4RvDxe +18EF8946-68F5-49E6-B202-CE90C3EEF1C9,IchSmmDispatcherDxe +18FE7632-F5C8-4E63-8DE8-17A55C5913BD,StandaloneSmmPkgTokenSpace +1905FCF3-DDB6-49BB-A785-1E50C807160D,SystemSlotInfoDxe +19123709-F770-4FAA-858E-3BD5FB18464D,OemSmi +1916F73E-C824-4F91-AC9C-BF1FD28E4431,DellServiceMenu +1925903D-3FAA-4A91-A257-448F4513B309,AmdNbioPciePei +192AFAB3-55F8-44B8-B49E-275A9DFDD03F,SetupFunction +19342D99-FF4E-4798-A3E0-FA36C961CCFE,PdtCapsuleDxe +1944F611-FBCC-40BC-88C8-850D0FE514E3,WCN6855 +194D473A-01F6-48AE-9429-FD395813BE47,AdlinkNxpPei +194EE52B-02FE-418D-AA10-2E61E51CB894,DellMonotonicCounter +19618BCE-55AE-09C6-37E9-4CE04084C7A1,httpDynamicCommand +1964A5A5-91DF-4B2A-B3C4-8B4BF238D0BF,SystemVirtualKeyboardDxe +1967167B-A13D-4E45-801B-A605D11946D5,AmiTseOemPortingVar15 +1967DD9B-B72C-4328-8C80-D4ACFC83FDF8,PciHotPlugDxe +196BFE1F-51FC-43E6-8E14-D421552BF0C7,FjFlashMapRt +196CA3D8-9A5A-4735-B328-8FFC1D93D188,TcgPlatformSetupPolicy +197DB236-F856-4924-90F8-CDF12FB875F3,Microcode +197E8644-1C26-7644-B5B4-978ED7301AD7,PlanarSelfRepair +198251A4-DE06-442A-AAB7-B0EE1E6DB8FF,GenericVar +1983E991-5033-43DA-8EA1-16D03AE895C8,MemoryMarginToolHookSmmShp +1988A1D8-04FC-4D68-B58D-636F36F30D82,SoftStrapsPeim +19984B85-18A1-468C-AF3E-C3D93F18C9FA,AsusSetupRestorePei +199C1EF0-6400-41C5-B0A4-FFBF219DCBAE,QuarkPlatformTokenSpaceGuid +199FD111-0785-4132-A9B3-1F66573F0060,GenericComponentsSmm +19A84692-4AAD-C04B-90E9-E017360A9860,DiskImage +19AD5244-FD6B-4E5C-826A-414646D6DA6A,EfiGlkVariableGuid +19AFD36B-F501-4446-9C9E-0457DB6E7888,SetupItemLinkageDxe +19B058DF-F97E-475F-92C7-BB26E0594FC8,DashManagerDxe +19B23409-85BD-44B0-897F-ECFE8AA7A145,SmbiosElogType15 +19B4BEAE-54DA-4AA9-98B0-41ED75D805BA,EcRotTpmRecoveryDxe +19B6F165-7855-42E8-AA6F-2361CA87E024,LenovoSmmVideoInt10 +19C2A1DC-73CB-46BF-A420-4C5558F958E8,DmiEditorDxe +19C4B49D-28DA-4232-996A-D175BBF6AFF7,SystemBiosSelfHealingPremiumDxe +19CB87AB-2CB9-4665-8360-DDCF6054F79D,EfiPciHotPlugRequestProtocolGuid +19CE57CC-628E-4F96-93D4-3C21F823C343,LEMPhyPresenceSet20 +19D17940-BA8D-4FA7-A704-F33D9FAFAB9D,LibStringlist +19D92C2D-F089-4B7C-ABE6-333A1205ED89,AmiSmmMultiPlatformProtocol +19D96D3F-6A6A-47D2-B195-7B2432DA3BE2,AddBootOption +19DBBDC1-DEDF-4DED-8684-2476B99FAC91,AST2500DxeInit +19DF145A-B1D4-453F-8507-38816676D7F6,AtaBusDxe +19E3BBBA-BEB1-43E8-B32D-9ACBB22C7639,BasePostCodeLibDebug +19FE2FE9-470E-4C7E-8D55-6C7A08DA855A,SetupDefault +1A10742F-FA80-4B79-9DA6-357058CC397B,ArrowCursor +1A1241E6-8F19-41A9-BC0E-E8EF39E06546,EfiHiiImageExProtocolGuid +1A1D1204-E385-4943-A892-5334CE3809AC,DellCsmOemRom +1A1E4886-9517-440E-9FDE-3BE44CEE2136,CpuDxe +1A20B273-2CBF-4E64-A4A0-16A2AF252C27,AmdFchWheaSmm +1A2614A0-89E7-11E3-2990-31D281FEB1DC,NgnRasProtocol +1A3113D2-91A2-41FD-A83F-AD5E6B90D43D,AmdDashSmm +1A345BC0-CC35-9ABC-1CEA-1CAD7D33ADDF,SmcLsiRaidOOBSetup +1A3558EC-13BB-4451-A589-74DFBD9A27AD,LidPoller +1A36E4E7-FAB6-476A-8E75-695A0576FDD7,EfiPeiDecompressPpiGuid +1A481E8E-342F-40AA-AF31-F4FB7C99D428,AmtInt16 +1A4D88C8-015E-42C2-9D4A-C4212BD881AC,MfgDoneSyncItem +1A57C46D-B93E-4036-8F33-1174CA091857,SystemDefaultVariableManagerPei +1A682DA2-3EE3-4793-8521-4DB8A69939FC,AmdNbioAlibMDNDxe +1A6853C8-F362-4F68-A77E-0B304A194C05,UseSocketDxe +1A6F63F1-AEAD-45FC-882C-03885004A6D6,DellAdvSysMgmtSmm +1A763B74-1400-4245-BF89-56910FA7BE48,FjSystemInfo +1A7BEAE8-0587-4EB5-B35D-D0D262201800,DellAcpiResetProtocol +1A7E4468-2F55-4A56-903C-01265EB7622B,TcpDxe +1A819E49-D8EE-48CB-9A9C-0AA0D2810A38,DxePchPolicyUpdateProtocolGuid +1A8DC70E-1D6D-4E33-BF0A-7FE6CD38744E,SiInitPch +1A8E9D96-66E6-461B-95D6-882C984D0B00,TbtPei +1A926325-2764-47C8-9E1C-4F83B1723336,VirtualEcDxe +1A931FB8-C466-454A-B684-73ADA2CB050B,AsusPostMessagePei +1AA34862-C1D3-49D1-9281-9F261545C09C,FjSystemDataFvDriverSmm +1AA6D900-89D1-4C21-9C50-EDC7390A67C3,SlotDataUpdateDxeNeonCityFPGA +1AA719F3-10A8-47BB-983F-3A03BABBB1EB,JGPIOCtrlPei +1AAF6A9B-CB1B-469E-9420-0D3912B8E376,MrcHooksChipServicesPpi +1AB9B2FC-7A50-4FA2-A190-EEB35797571D,OpromUpdateDxeSierra +1ABCB349-299B-46E8-99D1-582D91B3AB54,RstEraseDxe +1ACED566-76ED-4218-BC81-767F1F977A89,EfiNetworkInterfaceIdentifierProtocolGuid_31 +1AD5B195-44D9-4917-9BAE-E14784979306,Fji210LanDriver +1AE42876-008F-4161-B2B7-1C0D15C5EF43,DefaultDataFile +1AE856C8-1C5A-45F0-8FC2-0093292DB915,IteOnlySmm +1AEA4E7D-D6F8-491E-BB5C-4BEC10C98C99,FchSmmDispatcher +1AEC7EDF-3287-4669-B114-33A1198A60C0,OemAcpiDriver +1AEC89FC-DB8D-48EF-A6CC-C87A0B63E934,XnoteSwSmiServiceSmm +1AFE6BD0-C9C5-44D4-B7BD-8F5E7D0F2560,DellDiagsSbControlSmm +1B037083-5F15-4437-BE09-6C68AC675B85,MtkWiFiDxeGen2 +1B04374D-FA9C-420F-AC62-FEE6D45E8443,FspDebugServicePei +1B05DE41-C93B-4BB4-AD47-2A78AC0FC9E4,HstiProtocolGuid +1B06C65D-466E-35C9-154D-4D91BC4B9F8F,AmdPspDtpmPei +1B06FA46-E65B-4257-8855-5828B7591E61,FingerPrintHDDPasswordChecking +1B08A1DB-F91A-4FA1-A911-255C417F1CF7,ServerMgmtSetup +1B0FB9BF-699D-4FDD-A7C3-2546681BF63B,EfiWiFi2ProtocolGuid +1B1183FA-1823-46A7-8872-9C578755409D,EfiSmmPowerButtonDispatch2ProtocolGuid +1B1924C3-6321-484F-83EF-8894B21DE258,AmiPeiCrbInfoPpiGuid +1B2042F7-5CE0-4360-B98F-2973CAE22B97,FjSysmanTeutatesSmmBin +1B26C724-C7D4-4DE6-B0B1-C622BC2937FF,SmartCoverPortingDxe +1B2C4952-D778-4B64-BDA1-15A36F5FA545,Slp20PubKey +1B31A273-217E-3377-23D1-AB0CF19B9D47,ChgbootDxe +1B346098-AB0B-4AE7-DDBE-88AB3CD6220D,BatteryIdm +1B417388-B6B7-4026-B849-30060477A2AD,BootDeviceOptionsWmi +1B45CC0A-156A-428A-AF62-49864DA0E6E6,AprioriPei +1B49372D-CBBD-44D3-842C-8E900390DA8C,H19BatteryControl +1B496714-7685-402C-A5BA-37B8113D4E74,DellFreeFallSensorSmm +1B4AE0F8-ED1F-4FD1-9B18-B082290F86F5,EfiPlatformTypeLightningRidgeExrpProtocol +1B59CCDA-7DB2-4A55-AFC2-4364F824D288,McBankErrorInjection +1B5B480A-2B45-48AE-AA0A-D82B92A7738B,AppAdapterSgx3v0 +1B5C27FE-F01C-4FBC-AEAE-341B2E992A17,FspSFirmwareFileSystemFvGuid +1B6664CC-57B4-4E47-A477-2C9DD2413667,DellPchPtssTablePei +1B69BD70-9FAD-4A0E-8A3E-DC15AA40FC56,LEMBIOSLock +1B6BC809-C986-4937-934F-1EA58622FE50,AmiTseBootOrderChangeGuid +1B6E9D50-12E4-4B55-81D9-1ABFEC59D4FC,WakeCtrlSmm +1B76B808-B90A-42A4-B0A0-BE61B121E114,FjTpmMisc +1B799E86-28CC-4DBF-A763-F7F33FFD2772,SmuV13Dxe +1B838190-4625-4EAD-ABC9-CD5E6AF18FE0,EfiHiiExportDatabase +1B8B5F2B-605A-4D09-AFDA-842C3933A050,AmiFchUart1Dxe +1B8DDEA4-DEB2-4152-91C2-B73CB16CE464,PeiAtaPolicyPpi +1B9CD864-DA7C-483E-8D69-D35CB4AD27C9,EfiWheaPlatformNonStandardErrorSection +1BA0062E-C779-4582-8566-336AE8F78F09,SecCore_VolumeTopFile +1BA0ADA4-526B-4F11-A9BD-3F83EE17EA30,CopyRight +1BA41B68-465F-4B22-8406-2B82173DAE50,DellSpecialBootControlSmm +1BAD4160-CE02-4BDD-9D04-DCF7D7B72E0F,IioErrorHandler +1BAD711C-D451-4241-B1F3-8537812E0C70,EfiMeBiosExtensionSetup +1BB13967-8B24-411B-9828-18D285A9CC4D,AmiPpiGuid +1BB737EF-427A-4144-8B3B-B76EF38515E6,SdMmcPciHcPei +1BE14579-D805-4C3B-8874-410B818674E9,RealtekPxe +1BE65202-9318-492D-A551-08DF2BD60AEE,AmtPlatformPolicy +1BE9A477-92E6-4BA4-9496-C9DE8E152534,SbSocStarshipSp3Dxe +1BF06AEA-5BEC-4A8D-9576-749B09562D30,ProcessorProducerGuid +1BFC532E-F48A-4EBE-B2FB-2B286D70A6EB,IconUsbHD +1C015629-00CF-473D-BE1C-3561024F0569,AdlSemaDxe +1C0C34F6-D380-41FA-A049-8AD06C1A66AA,EfiEdidDiscoveredProtocolGuid +1C0D835F-C0C5-4848-B42B-95FEDBCC815C,GnbBristolRouting +1C110D74-159B-46B3-B47E-7B7AD22FA6D6,DellResetReduction +1C132679-BB95-479C-8A82-6DE72A52D6FD,AaeonPowerButtonSmi +1C14F9BE-034F-478C-AD0A-D4D178C11629,OemNetworkDxe +1C178237-6897-459E-9D36-67CE8EF94F76,EfiKmsFormatMd5sha128Guid +1C1EAB81-9229-42AC-B940-757C498A09ED,AmiTseOemPortingVar22 +1C324C08-EB94-4715-9180-F5A453C57269,OemGOPCallBack +1C33C958-FEA4-435F-93EF-0A9C14AE87E4,DellMfgAuthentication +1C377111-E07E-4B33-9B5B-30817D1F1BE3,DellIntrusionDetectSmm +1C3F1D99-4D35-4BBE-B75E-A2C92C7228DA,OemWwanSmBiosType133 +1C4C501A-8CDC-4D1F-8639-27E9049494C1,HpCommonAcpiArea +1C505528-32D7-4D70-8818-9A489B414ABA,PcieErrorLog +1C58AAC6-76C9-D94D-A14C-0059E13B96A3,AppleMtftp4Dxe +1C5C6E7E-552A-443E-9A04-7408ADEE99D3,FirmwareConfigDrv +1C5FDAF2-9FB3-431B-8ECD-B7D35CBEFAE9,EfiAfterPlatformLocksEvent +1C606E42-F267-4A2F-95EA-A081B62E3F4B,H19CheckPointHddService +1C675C27-6FB1-4170-94E7-3DFFE8BEADBA,LaunchPad3Drv +1C6A6DBE-CA59-44E4-8D42-68FAC524A89C,SystemAudioDxe +1C6B2FAF-D8BD-44D1-A91E-7321B4C2F3D1,ScriptSaveDxe +1C728BAF-96B6-46E6-B549-E50C45898E3A,TamperEventProtection +1C733CB5-4C8F-44D9-BBF0-95477089EB08,DellSmBiosStrucDa +1C7B1FD9-373C-4569-8DC1-8DB2FFFA7639,NistDxe +1C8020B7-D2F2-42F8-852B-CBC232CCC9BC,AsusROGLiveServiceSupportDxe +1C83550A-7E5B-4A30-9E93-E2153771AA25,FjDmiCpu +1C871D93-BA95-474D-BA2A-397CCF9D2691,OemTurnOnAmp +1C8B7F78-1699-40E6-AF33-9B995D16B043,PiSmmCommunicationPei +1C98780A-C67D-4D9B-A9D8-4AC0487A6D6E,PcdRecoveryPei +1CA0E202-FE9E-4776-9FAA-570C19617A06,EfiPciCallbackProtocol +1CA7E5F3-2385-427D-A4AF-F6E28BB8BBEC,AmdMemAm5Pei +1CAE7577-D662-4727-BAEC-777631D3A958,SystemVspCmosPei +1CB1ADDA-D8DD-4C6E-8DEF-A0DACB2AEC83,RetimerCapsuleUpdate +1CBC61DC-3D35-41ED-8E92-9147A0D68E77,AmdMemFp8StxDxe +1CBFC9B6-7F1E-4E9E-801F-FBCE4D92A76D,AmiTseBeforeTimeOutGuid +1CC640E2-28EE-4D0C-8211-5D0E30967EE6,DellRecoveryMgmtDxe +1CC6FA21-4A9D-46B4-9EBF-9E42F5D044F2,FjCapsuleResetHookSmm +1CE12314-AFBC-11F0-8A3E-AB44B8EE3120,PpmPolicyInitDxe +1CE34CFF-DFE9-4D9D-B264-166FFCB8315A,MebxSetup +1CE692F0-3317-4574-8B57-4800ED091F40,DellDxeComputrace +1CE7C25E-02E0-4CB8-9410-766EEE8B8A97,FjMfgTpmDxe +1CE9B08D-7649-4EE6-AEF5-729A4DA7E469,EcIoDxe +1CEBDD17-1325-42BB-8A7A-22857CF10A5E,AmdFabricRsDxe +1CEC16EC-1C60-449B-9775-23CA66B93F52,AmdBoardIdPei +1CEE181A-DF5C-4391-BCA8-CDE5A5A1A0BA,OemHooks +1CF369C2-3C8F-4D75-AAED-45CFEB8E9B6C,UsbPortDisable +1CF3F8B3-C5B1-49A2-AA59-5EEF92FFA63C,EfiIa32X64ErrorTypeBusCheckGuid +1CF40D19-EEAD-4C73-93DB-BBB8B6ACF929,SystemNUserUserManagerDxe +1CF59BF9-E3F6-4D9D-BB94-8B857278BBC6,GnbDxe +1CF6C0C8-FA85-43EE-94AF-DB27C54174C9,RAIDCorePei +1D000AE9-756B-4937-B736-1F3D96A5A8F0,Dptf +1D0CFB9B-EB00-43A6-819C-D218DF8DC4B4,BootMode +1D12B73E-7DDE-4910-93C5-2BDB041C6849,FjIbvBiosPasswordAbstractionDxeProtocol +1D154AE4-5BDB-4341-90E2-32531679CF14,TypeCEventMediator +1D201235-2F40-4FBC-8650-8502092D62AB,LenovoEaiaDxe +1D202CAB-C8AB-4D5C-94F7-3CFCC0D3D335,EfiSmmCpuServiceProtocolGuid +1D26ADC3-B011-EE2C-2177-89BBAACC3392,AmiBeforeCpuRcProtocol +1D292105-2653-11E5-B46F-B8E8562CBAFA,AppleCapsuleRuntimeDxe +1D3DE7F0-0807-424F-AA69-11A54E19A46F,EfiExtScsiPassThruProtocolGuid +1D3E9CB8-43AF-490B-830A-3516AA532047,EdkiiFaultTolerantWriteGuid +1D4B3C7B-7D01-4CFF-AF3A-0DAFB53F6321,FjGabiSystemDataLogoAbstraction +1D4B3C7B-7D01-4CFF-AF3A-0DAFB53F6322,FjGabiSystemDataLogoAbstractionFTS +1D57B5D5-BAB4-4D2B-B7EB-0EB41D7B189C,LibGlob +1D58E9FD-BA80-4A47-8190-08AE9BB8A0ED,DellTagsPolicy +1D6F730F-5A55-4078-869B-E0A18324BDC8,TemplateSec +1D6F853E-0006-40D8-9B4B-79618A5733B0,AmiTseOemPortingVar3Guid +1D6FE4A5-8E70-4D10-84CD-B1D33214F9B5,HpPopupsSupport +1D7ADD6E-B2DA-4B0B-B29F-49CB42F46356,EfiMemoryProducer +1D82219F-386F-4F26-AFAC-613F242C0760,DellSmmStatusCode +1D85CD7F-F43D-11D2-9A0C-0090273FC14D,EfiUnicodeCollationProtocolGuid +1D88C542-9DF7-424A-AA90-02B61F286938,WdtPei +1DA02C3C-62E5-438B-B0DB-9E5128379661,EarlySmmDevices +1DA353A3-6400-4241-9AB0-E3E65C690EF7,IchSmbusArpDisabled +1DA69AFD-C297-4EE2-A086-0A41EB2B4DC8,XnoteGopVbtPei +1DA97072-BDDC-4B30-99F1-72A0B56FFF2A,EfiMonotonicCounterArchProtocolGuid +1DACE8EE-CD97-491E-8A0C-305D6437323C,AsusOnBoardDeviceDxe +1DB184AE-81F5-4E72-8544-2BAB0C2CAC5C,AmiBbsDevicePath +1DB29AE0-9DCB-43BC-8D87-5DA14964DDE2,EfiUserInfoAccessSetupNormalGuid +1DB43EC9-DF5F-4CF5-AAF0-0E85DB4E149A,BootGuardDxe +1DBD1503-0A60-4230-AAA3-8016D8C3DE2F,EfiSmmIpmiTransportProtocol +1DCFBACA-6ADA-4C0D-86ED-AF658BDFEC0C,AmiPlatformToDriverAgentProtocol +1DCFF17C-AA53-4B78-B234-864027555035,LibUefi +1DD1D619-F9B8-463E-8681-D1DC7C07B72C,EdkiiNonDiscoverableSdhciDeviceGuid +1DDA5978-B29A-4EA7-AEFB-8B0BAA982E22,ExReportStatusCodeRouterPei +1DDBB0E2-6FB5-4B1F-A14C-F2E5B5E59168,aqnicdxe +1DDBFD6A-3423-462F-9150-A7FFA66FF0CA,StaticSkuDataDxeLightningRidgeEXRP +1DE0B8C2-FFB6-4BDF-97F5-0FFB33979038,BaseReportStatusCodeLibNull +1DE25879-6E2A-4D72-A768-288CCB9FA719,EfiMemoryConfigDataHob +1DE2AB60-EB98-4D6B-9DCE-A7EF2202B3AE,AmdAgesaParameterGroupPei +1DE64B8E-138B-4258-B7DD-F2D8EC142A9E,AmiFwUpdateBmc +1DE6EF1D-DB01-4C27-AD29-C582887E2E18,OemSataInitDxe +1DF18DA0-A18B-11DF-8C3A-0002A5D5C51B,SataSiI3132 +1DFB7BFA-BF8E-4D11-9766-2FB0D0442310,AmiAgesaDxe +1DFB7BFA-BF8E-4D12-9766-B0D014120415,UpdateHwSignature +1DFC7675-CB00-4BF8-B8F0-E1C993814D2E,FjWirelessLanDxe +1DFFE9F3-7B5F-4B44-8EBD-39A739EBA903,AcpiPlatform +1E00830B-8BA5-4D24-8609-E74994E13A39,Common_LilyPei +1E107FE3-565D-4AE0-94B5-563D9F96BFC8,EfiSmcInBandLoadDefault +1E1CAC3D-8460-4EDA-9791-6D1B2DA75E21,NvmeSmartFeature +1E21C326-0D40-40F2-9F02-3A9B7838AA6B,AmiIpmiPkgTokenSpace +1E2ACC41-E26A-483D-AFC7-A056C34E087B,EfiPlatformInfoGuid +1E2ACC41-E26A-483D-AFC7-A056C34E087C,EfiNorthPeakGuid +1E2ED096-30E2-4254-BD89-863BBEF82325,EfiTcg2FinalEventsTableGuid +1E30E33D-1854-437A-BD68-FC1553AA8BE4,CseEmmcSelectPpiGuid +1E321458-2CF2-4AFD-8102-C86423ECD18D,FjMiniCardModePei +1E43298F-3478-41A7-B577-86064635C728,OptionRomPkgTokenSpaceGuid +1E463F9D-4CFB-4396-A784-68C350BADCF1,AmdSpiHcProtocolDxe +1E469095-EFC8-4147-97DB-4D68B727E2E0,FwBlockService +1E4EAAB1-E637-443E-A5D6-56E60D97C619,UsbComboPeimPei +1E5668E2-8481-11D4-BCF1-0080C73C8881,EfiVariableArchProtocolGuid +1E6EBC58-55E2-4FE4-A396-AA2C228EE7E2,PhPlatformSiSmmCodeCheckSmm +1E753E16-DCEF-47D0-9A38-7ADECDB983ED,TcmLegX16FileGuid +1E75E77F-8A15-4653-964D-542C157EF40A,SgPeiPolicyInit +1E77550E-E429-4FA9-BEBF-B515ACF7D919,Ip6 +1E82B556-4EB6-479F-955A-78A5FE0C0CB2,BroadcomWirelessDxe +1E843AD6-E237-42FC-BDA2-DE78542E16DD,SstSpiFlash +1E8DCCE9-341C-4219-A790-F14C28B51CE4,L850Id0WAPei +1E8DCCE9-341C-4219-A790-F14C28B51CEE,LenovoEaiaPei +1E910FF4-3106-44F0-BB75-115A52FB9BAC,DellVideoDxe +1E93E633-D65A-459E-AB84-93D9EC266D18,EfiTapeIoProtocolGuid +1E93F29B-A3B2-F340-A605-DE31EE3DA031,EdkTerminal +1E97097A-C884-4BE4-A530-299F85BDC894,MediaSanitize +1E97E5F2-F850-0FD9-8191-C18FE43B0405,WnameDxe +1EA09F16-1A28-435B-8E8E-8AB7C1DE04D3,FjHiiString +1EA81BEC-F01A-4D98-A201-4A61CE2FC022,PerformanceExProtocolGuid +1EAF8A37-CD36-4267-831E-AC69789C5CCA,mSupplicantDriver +1EB667B3-3DD6-4F19-BA60-7C4638AC4062,AcerPortingDxe +1EBE5AB9-2129-49E7-84D7-EEB9FCE5DEDD,EfiEmmcCardInfoProtocolGuid +1EC0EFC9-C93A-4B62-9B27-C059ABD80E92,VlvPlatformInitDxe +1EC0F53A-FDE0-4576-8F25-7A1A410F58EB,StatusCodePei +1ED1D253-E62B-47C2-ACC3-50B859CBD511,Armani_BatteryHealthControlDxe +1ED46147-76E3-4171-BCE5-42D368D26AA6,DebugPortTableDxe +1EDC318F-4005-488D-AF3A-9BB5179BC6F1,GmchMbiDxe +1EE0E496-28B4-440B-A45A-7464BF4B32A2,FjUsbSecurityV +1EEA2BFE-01CB-40CC-A34E-CB224C800AA2,Tpm2DeviceLibSeC +1EF02CF1-BF69-49C3-8FDC-5BB55D224CFA,DellPowerButtonConfig +1EF08355-4136-443D-BE11-B4CB99524D80,HpWsCommonSmm +1EF46A7B-5F4D-4967-B3C4-A308D898EADD,AsusCalibrationDxeEntry +1F05933D-FF2E-4236-BE92-56682D3E8FB4,FdCapsule +1F08F001-AC83-43D3-996B-47FAE153CB2A,DisableAbtSetup +1F0F049E-3A68-4C97-865A-BC5EED7920E7,AmiPeiNbCpuOnlyResetPpi +1F1829F7-54D7-4A08-94D3-8DB412782531,SioPS2PowerOn +1F18C5B3-29ED-4D9E-A504-6D978E7ED569,QncS3CodeInLockBoxGuid +1F1DFC5B-5C64-49A3-A14A-AC2D3138B595,FjIbvAbstractionDxe +1F202FEC-DDA1-4BBF-8584-BD42E379CE99,DellDiagDxe +1F21D964-807D-49F4-AE4E-F52663D1A16F,FjCryptoDESDxe +1F28B56E-D26A-48FD-9FAC-9E18A2C5BBDB,CnvUefiVariables +1F2CCB4F-D817-404E-98E7-80E4851FB33E,GdbStub +1F2D63E1-FEBD-4DC7-9CC5-BA2B1CEF9C5B,FileExploreFormSetGuid +1F345462-CEA5-4ADD-9C43-5CA6720B9DA6,IrqBoardInfoRvp +1F36527E-A97C-45F8-B24A-9D95B0A940FE,AppleBrightnessControl +1F3CDFBE-F7AE-4453-8C48-C1AD35A4FD98,SmbiosDmiEditProtocol +1F4C6F90-B06B-48D8-A201-BAE5F1CD7D56,EfiPeiStallPpiGuid +1F642910-3D7B-4627-8D18-DC62671E0554,BiosReservedMemoryPolicyPpiGuid +1F6835A4-4A5D-4B02-86C5-B3FC87840E92,AsusOA3Bin +1F73B18D-4630-43C1-A1DE-6F80855D7DA4,EfiFormBrowserExProtocolGuid +1F77FFD9-C00D-4245-B2AC-F5F43E333C39,PtuLoader +1F78349D-7FBA-4686-8098-FA017EDA35FB,ArmShellCmdRunAxf +1F7A4AAB-E6AB-416C-98B8-31F614FFF198,DellSmmComputracePreInit +1F871708-1541-461F-91D5-4A90852DC913,FjGabiNvramMergeSmm +1F8ECE17-87A5-4196-B265-4F01FBF9AA2D,FjGabiLogoHandlerDxeBin +1F9BF300-67FB-46EE-B6E7-2B6F6590531C,HpCertificateManagerDriverWmiSmm +1FA1F39E-FEFF-4AAE-BD7B-38A070A3B609,PartitionDxe +1FA4DAFE-FA5D-4D75-BEA6-5863862C520A,TcgConfigDxe +1FAAA415-F8A9-4A33-B434-A7811FBEC145,SaveConfigMemData +1FAE70AC-8203-48F0-B9EF-E873FFECC1F2,PeiLegacyRegionPpi +1FBA8CFA-8194-49C4-BD8E-9F162A957BA1,WMISwSmiDXE +1FBD2960-4130-41E5-94AC-D2CF037FB37C,EfiAdapterInfoNetworkBootGuid +1FD28F7C-8CFE-46C4-AE0F-0CEBA37FF28B,SystemSignaturesDxe +1FD29BE6-70D0-42A4-A6E7-E5D10E6AC376,AmiHddPasswordVerified +1FD3AD5B-5E65-485E-9EBD-95B14D6ECCC6,SetupConfigUpdateDxeXPV +1FDF71C4-D46D-45FB-BF85-56F1C529725A,ComTypeControlPei +1FE16506-5CC5-4D89-B8FB-6EB5E134887D,DxeWhea +1FEAEE73-F8DC-439F-9FD3-A0ED92B5EBDA,SmbiosMFG +1FF7913E-D890-4360-AC75-B8D8384BD1E0,AmdSmmControl +1FFF93C2-8C76-49E4-8AB3-43D92F5445EF,LogoJpg +2000A832-C674-486A-81BE-CB4670A4F7FD,DellRebootDxe +201A92E1-2D0F-48E9-A3AB-93E1695A92F2,AppleHDA +2022B972-B1B9-4B55-A603-7851CB062E34,LePassKeyDxe +2029D12A-0A83-4277-86A2-712905201AE7,SpiWmi +202A2922-8C27-4943-9855-26180BF9F113,VariableInfo +202A2B0E-9A31-4812-B291-8747DF152439,Ps2MouseDxe +204810E0-4941-4C66-B99A-6BEE4F84453C,AtherosWiFi +204C3D37-D83F-49AB-883F-9B5D6C647762,FspTempRamExitGuid +20576248-C01A-439D-8CD6-418EAABE0A29,RasClvAdddcProtocol +20605BBA-7FB9-4279-959F-8DBF74CDB0C6,VideoBios +206E7181-A935-4BAF-949F-A875136CD46F,PldmBcc +208117F2-25F8-479D-B726-10C10BED6DC1,AppleLegacyRegion +20830080-CC28-4169-9836-7F42B8D0C8C9,GraphicsOutputDxe +209097AF-5ACF-4E2D-A31B-72257E05DC40,ODMMemoryOverride +209674EF-6060-43E4-BE87-E742E16BEB00,NvmeControllerPei +2098F2DE-AF12-42E4-AD75-D88203EA0683,SecureBIOCamera_Sunplus2 +20A1D839-853D-4067-B69C-552A0D05C1AA,DellFormBrowser +20A7378C-AA83-4CE1-821F-4740EE1B3F9F,PeiOperatorPresencePpi +20B0F1C2-B0D8-4C5D-AAD9-F44580DFDF8B,EfiPeiAmiKeycodePpi +20B181E2-33E8-4211-B9D7-9B8696764E66,WheaElog +20C7C6BE-56C6-46B7-B3AB-5588289AA803,XnoteSwSmiServiceDxe +20C95B72-F4E3-4BB2-A289-19DBFD23F531,PlatformInit +20D19705-E59D-4362-9956-FA533AFF2429,SetBoardId +20D6E759-4C4A-40C0-9533-2BF0066850FD,EfiQuiesceProtocol +20D8FFFE-15C3-4EA9-9D28-CFE2745D78F3,CryptoDxe +20DAF0FC-5548-44DC-A42A-60EAF0A22E47,DxePlatformTdtPolicyGuid +20DC4DF3-AEA8-4D12-9A20-C07EB9157E04,OemSetupCallBack +20DE009A-B0B3-43DA-8047-B5E2B19D6CC0,FlashOemHooKDxe +20DED343-E5FA-49C2-B20F-C18798743D41,OemPowerMgmtSmm +20DF5C15-5E32-42D7-BB67-3390A0E51FFD,HpErrorLoggingPei +20E28787-DF32-4BDA-B7E7-CBBDA3371EF8,IdeControllerProtocol +20E687BE-B09B-4DA1-BCFE-E804B3B97CE4,CsmeHealthDxe +20EA66CA-17C3-4DD4-A51F-956CC9E4FC26,AmdIspCamera +20F8FD36-6D00-40FB-B704-D12C153C62EB,CcEventEntryHob +21073EF1-FF66-41FF-9BF4-A3E936DB1901,FchHuashanPei +21094ECB-9F20-4781-AE4B-50728B389A6E,IchInit +210DCB72-BC14-4A19-A29B-F696EB7DE12B,EzSetup +2119BBD7-9432-4F47-B5E2-5C4EA31B6BDC,DxeIpl +213A595C-F512-4935-90E3-2CEAD077C721,DashDxe +21429B90-5F67-4E93-AF55-1D314D646E12,MemoryProfileInfo +2145F72F-E6F1-4440-A828-59DC9AAB5F89,EmmcDxe +215FDD18-BD50-4FEB-890B-58CA0B4739E9,EfiSioProtocolGuid +21605810-54B3-4109-8AFF-3B3FBF4AF040,DellPasswordPolicyDxeProtocol +2161BF9C-8038-4F12-A758-30140660F22F,StaticSkuDataDxeFischerLakeRP +2167F964-7298-4A8F-9A2A-BFE498D600A8,HddReadySmi +216A681C-9E51-415F-9ADA-CB9FBCD05F5D,DellFlashIoDxe +21729246-5DF1-46A1-A5C6-2484BCD706FB,LEMSetVariablePreInit +21782819-FDA0-4ADE-BD36-C95F079F057D,AsusBackupAccess +217FA926-F494-4B3F-AC45-D213C2A0294D,PostLogo +21834F44-9201-4AA3-9B15-AFD794D93BC4,OemWakeOnRtcPolicy +218596FC-6EBD-4D19-A79B-41B13448021C,OemSWBoardIDDxe +21877E2F-F86E-4E8A-9C9B-D7B152DD40D8,EfiPeiPlatformTypeNeonCityEpecbPpi +21891A9E-763E-4377-8841-8D5C90D88C51,NetworkStackSetupScreen +218E36A1-C2A4-4D42-8024-C9B80E3DAF47,FjFvFlashRt +218F1930-10AB-43B3-9C66-B98483A1AE9D,OpalBlockSidDxe +218F4B00-E4F0-4CAD-8A90-577B833D0128,BixbyDxeDxe +219144EA-D6B4-4D6A-B8F5-63CA8A09C8D0,CsSmmDriver +2197DD5B-B8D9-4897-92F1-18D75903E6AF,HpSleepStateSmm +21A05FD5-DB4A-4CFC-B84B-EB0DBB569934,IconGenericCD +21A74F63-CA10-4DC6-A4EB-36C93B9A063A,PlatformFlashSmmProtocol +21ADC483-021F-4F3B-8DCE-613CC981A269,menu_dots_selected +21AF95E1-371F-4712-9C07-798E3CB019E4,LockSMRAMEntryDxe +21B0CB55-4330-4343-AFF8-A68089124118,DellServiceMenuConfig +21B564BF-53EA-40D1-85AE-EFFC93D28640,FchKeithMdnDxe +21BE6180-733A-443B-DF46-41C008047687,AmdNbioPciePei +21BF3644-1CE7-4E87-8C60-0A5C607173A6,RemoteFWConfiguration +21C3B115-4E0B-470C-85C7-E105A575C97B,EdkiiEmbeddedGpioPpi +21CCF0B7-246B-412C-A334-0B65A07B28DF,SmmBaseOnSmmBase2Thunk +21D04395-96A0-4FD5-B477-A922648EDAF3,AsusSampleDxeWrapperPkg +21E173D6-C221-48EE-A18F-B73D9810FBF6,AsusApmPei +21E34727-3881-4DEE-8020-D8908A980311,EpuHwModeDxe +21E70404-DF72-4122-B030-281306EB7BE3,VbtEdpTypeCGuid +21F2A221-0CF9-4E0A-9FD0-2DADDC025E31,BctBaseSmmSTX +21F302AD-6E94-471B-84BC-B14800403A1D,EfiSmmCpuSaveStateProtocolGuid +21FF1FEE-D33A-4FCE-A65E-955EA3C41F40,QNCMemoryInitPpiGuid +22046D50-F390-498C-92E5-5BA4F8E7F8B6,SBSATAIDE +220AC432-1D43-49E5-A74F-4C9DA67AD23B,HotPlugDevice +220E57C8-4E71-493F-91B8-0F7F820A1DA2,I2cMouseDxe +220E73B6-6BDB-4413-8405-B974B108619A,EfiFirmwareVolume2ProtocolGuid +221521AE-0A35-44CD-B580-5AEDBB770B1D,glyphs +2216614E-CDBE-46E7-BA61-9BD2BC640393,AmiPspFlashSmm +22198FD5-4835-4842-BF31-EB957C7DD70D,GetNetByAddr +221D6760-4AC0-4C12-BA96-9C63E4D9C1C8,HwmInitPei +221F1D4F-034C-4BEA-B2BB-B7A9672B06D7,CrbSmi +222C386D-5ABC-4FB4-B124-FBB82488ACF4,PlatformPei +2236B8BC-E488-4424-BEB9-97C8A1483693,PlatformOpalDxe +2237C798-93E7-4119-B10C-CF75CD22BFE0,AmdApcbZpDxe +2240157B-A45A-46EB-9A7E-1E79C4781FD7,HWChangeWarning +224453CE-FED2-49CC-A42F-443FF9CCB6C7,Ast2600VgaDriverX64 +224FBFE4-ADB6-4DF2-B835-602182AEEF20,Clock +22597239-6107-DF44-AD3F-5F053E92222E,EmuSnpDxe +225C3A5A-5902-4307-968A-AF8DEFFE61E8,UsbPwrCtrlSmm +226824A3-1989-4D6C-BD17-C863845F7E99,DellSmiCpuDecodeProtocol +226A500A-E14F-414A-A956-40E5762D3D1E,PrmLoaderDxe +226D28E1-7672-48D5-ADDC-E5F91F398A3E,SetupConfigUpdateDxeExpertWorkStationRP +2272865B-EBF6-4047-B008-7889497F53BD,SuperMDriverProtocol +22766CBA-D444-4A04-9E77-50BB240F00A6,VPMSmm +22819110-7F6F-4852-B4BB-13A770149B0C,FpgaFormSet +228AAD82-E150-4288-B176-A1AAD77D783E,FjIbvTraceAbstractionDxeProtocol +228F344D-B3DE-43BB-A4D7-EA200B1B1482,EfiSmMonitorInitProtocolGuid +228F7D4F-231C-6BAA-BDCB-BEA9875B04D3,AmiCpmWrapperSmi +22951F5E-4F7B-405B-8ADA-ECDC431C616F,UefiWindowsInt10Workaround +229832D3-7A30-4B36-B827-F40CB7D45436,EfiPeiStatusCodePpiGuid +229B7EFD-DA02-46B9-93F4-E20C009F94E9,CpuS3DataDxe +229F268F-23B0-4436-83E3-8B7AE08A6BD8,EfiMfgUuidHob +22A5BB4D-F962-4D33-9CD6-FDAD39ACD153,PlatformBoardIdPei +22A8C2C1-9F75-4B9D-B037-22CC43E6929E,SioDummyPei +22AAB6B3-FDAD-4383-A6D4-1CBAD157C895,AcpiI3cSlaveSsdt +22AAFFEA-2358-4C53-9AF0-CC0CCB06E2EF,PanelResolution +22B194B4-CC0E-46C7-9FCE-DA10D6ED1731,PchSmbusArpEnabled +22BDEE84-C807-452E-B56E-F683FD76C989,BuslogicDxe +22BF0B85-4EB3-479B-A9E9-A5F7CFCCA787,LenovoSmartCardDetectDxe +22C71E5F-B32B-44E0-B705-B1ADCFE70C0C,SureStartPoliciesPei +22CEF43A-ED2B-4795-AF0D-918FF85B3573,ServiceBodyDxe +22DA1234-1DB3-4D56-8646-FD785A59337E,AmiDfciPlatform +22DC2B60-FE40-42AC-B01F-3AB1FAD9AAD8,EmuVariableFvbRuntimeDxe +22DF032E-B7B2-43EC-B903-BCE4190AED43,RstPeim32 +22EA234F-E72A-11E4-91F9-28D2447C4829,HttpUtilitiesDxe +22EB683B-1AD2-4BE9-AE1C-C4F1F281BDF7,PoweronFromKeyboardPortDxe +22F8B88D-4E9E-4DA3-8CD5-74463593EF13,DellPeiDiagLeds +22FBD744-CA98-4F6D-9882-954201312DA0,H2OVarCheckRuntimeDxe +22FDFF5D-EF58-4E45-B515-A41067D5C80B,AssetQrCode +22FF12F3-4B62-172F-37A6-A6BEDAB1FF63,I2CcontrolPei +230F6679-F703-4DC2-B2B7-41C670BCC0D1,BiosInfoRecovery +231BE53D-B6E3-44D8-A8D5-E0566E55663D,EsrtOverrideDxe +231CDC65-129E-4870-A882-79244127BDE3,SkipStoragePwdPrompt +231D3A65-9442-4507-A4E4-E9D2176578F1,DellSmBiosStrucB1 +2325F2FC-5683-4648-97C4-9A520DFBE325,AmiTcgPermFlags +232D6306-B70C-48BB-88BB-9FA6D47C8208,RtcStatus +232FB018-F308-4081-B280-812E6164123B,PasswordMgrDxe +23321FFD-1F8E-4597-84EC-4DAD0E2BA995,SmmLockS3 +2333A860-A228-462E-8121-7B49895C11C5,ASRockSIDxe +2336A93D-08D7-41C5-AFC1-CDB60C94CDA4,CaseOpenPei +2338337A-47B0-4C41-9CA7-0160FB94DFF4,PlatformFlashDxe +233C2592-1CEC-494A-A097-15DC96379777,FwVolDxe +233DF097-3218-47B2-9E09-FE58C2B20D22,LenovoPlatformStage2Pei +2342CA44-3B35-4A34-995B-CEDEEB1A9576,Intel945Uga +2345FB4D-0B26-4A14-AA2E-F7B955154495,StibpFeatureDxe +234DFAD6-8626-40FD-A1EF-E4B68CF57A3B,ProtectedDataDisplayPolicy +234E6146-1FC6-4508-8231-1294CC28DA4C,FjGrasscarryLaunch +2354D320-3EB3-4C81-99F4-CC4AE143463E,EfiEdkCompatibilityPkgTokenSpaceGuid +235BE51A-D4D5-49EF-9C46-D313056B7401,UsbPolicySmm +235C9BA7-2DA4-4DF4-92DD-5555FC7DB2AC,OemACRecoveryPei +2361A042-F0DA-4006-B3C1-3A130FAE8DF0,I2cTouchPanel +2362EA9C-84E5-4DFF-83BC-B5ACECB57CBB,AmiCsmThunkDriverGuid +2366C20F-E15A-11E3-8BF1-E4115B28BC50,HttpDxe +2374EDDF-F203-4FC0-A20E-61BAD73089D6,IoTrap +237CC158-6032-4832-B0BA-1F83C0FCA609,CoreHotKeyProtocol +2383608E-C6D0-4E3E-858D-45DFAC3543D5,PciHostBridge +2386622C-FC1A-4B5B-AE3A-C81FB30AF128,FjDxeLeg +2386E231-A9CF-4F52-946A-6F6B6C133B46,DellSmBiosTableLoaderDxe +238D654D-A6AD-41C8-A31B-67A3208625C3,LenovoMx25L3206EflashPartSmm +239421F6-F025-429C-9889-AB854E00EEE6,CheckRaid +239B7F68-26E1-4B48-B966-85338AA7B637,OemSioPei +239E812C-AD4A-4D5A-8BB9-169131C344BF,AmdIdsDebugPrintPei +23A089B3-EED5-4AC5-B2AB-43E3298C2343,VariableSmm +23A3E7BA-75D1-4CB9-9C8F-56FA4E48D99E,EfiTraceHubDebugLibIa32 +23A464AD-CB83-48B8-94AB-1A6FEFCFE522,EfiSioPpiGuid +23A7B657-077F-4ABC-AB7E-B70D8A389DBE,DellVariableProtocol +23AF8BFA-1D89-47CB-876C-1BE11FA0F4B0,AtaIdentifyData +23B461D0-3C94-490D-9A4B-4AE1916BD425,DellAtaAtapiIoProtocol +23B4BD04-198C-4A11-B65A-A52B33C98C18,AmiHspFtpmAcpi +23C29286-947D-4270-B061-7FE5D0758B63,Legacy2Region +23CACE14-EBA4-49F6-9681-C697FF0B649E,VirtioSerialDxe +23D1280D-43F0-4713-90B2-0E5E4221AF4C,BatteryState1 +23D93EAA-0723-4559-B768-5E22DF762DE4,LenovoTpmEnablerDxe +23EED05D-1B93-4A1A-8E1B-931D69E37952,Omap35xxBoardInterruptDxe +23F0F40F-686D-45E4-B26E-11F9F265CF66,BatteryInfoDxe +23F0F40F-686D-45E4-B28E-11F9F245CF62,MpmBatteryInfoDxe +23F69CD0-FF46-4DB6-B982-63EDF1A901FF,AmiTseOemPortingGuid2 +240286E6-55D1-4DD2-8E9A-AD26569C7ABD,BoardInitSmm +240612B5-A063-11D4-9A3A-0090273FC14D,IsaBusDxe +240612B5-A063-11D4-9A3A-0090273FC18E,SmmCoreDispatcher +240612B7-A063-11D4-9A3A-0090273FC14C,SystemUsbSupportPolicySmm +240612B7-A063-11D4-9A3A-0090273FC14D,SystemUsbBusDxe +240612B7-A063-11D4-9A3A-0090273FC14E,SystemUsbSupportPolicyDxe +24092BED-2736-40A7-8D87-515E8594F6B3,FjGabiOsEntryGateDxe +240C89B9-5BB1-494D-A0A6-8F0E1935B45B,AmdFabricStxKrkSmm +240E9BEF-B64B-4760-A05F-50027564EF1D,VariableBackupRestoreSmm +2413D304-AA41-4079-A81E-31B8D7C3FD6B,GpioV2PpiInitPei +24169E35-2454-4940-92BC-82321A2C7562,VlvInitPeim +242B3D0C-5FB8-4A75-9CD3-710DDFE42703,AmdNbioDxe +243373D3-C183-4F6A-9AE4-E38419FCDCCC,WarmResetFlagSmi +2433EC61-17BE-4B98-895C-333950C62318,RtkUndiDxe_2057 +243C8C8A-BBD0-4AA9-BE17-CF9B583130EC,SmmOEMInt15 +243E170B-83BB-4E43-840A-F9EC857FD783,FjGabiPostFlash +244338F5-ABDA-4DBD-8782-1DE293B5BBB4,PlatformStatusCodeHandlerPei +2443909F-892D-46D7-7977-4902259419AA,HpRtxXhciSmm +24486226-F8C2-41F5-B9DD-783E9E56DEA0,EfiMmioDeviceProtocolGuid +24503DD2-5A92-4DB8-95B6-0F0BF6FEA97C,AmdNbioPcieDxe +245CB4DA-8E15-4A1B-87E3-9878FFA07520,Legacy8259 +245DCA21-FB7B-11D3-8F01-00A0C969723B,EfiPxeBaseCodeCallbackProtocolGuid +246F9F0A-11E3-459A-AE06-372BDC4DE806,LenovoSystemStatusCodeGenericRt +2476ACB7-D4C7-48D3-AB73-7513B03BB5DF,AmdOemRasRsSmm +2477BE9E-8E1A-431E-B705-14E663717377,PsmiComboBufferGuid +2480271C-09C6-4F36-AD75-5E1390BD9929,QNCSmmDispatcher +24848D1D-A637-45DD-974F-BEBA0340FF96,RemotePlatformErase +2486829B-D3F3-47EC-827A-FC104907FC5C,SmmGenericSio +2493F533-A25C-4E65-B26C-CF4DD6B7903B,SctMilestoneTaskSmm +249CEF4D-7B90-49F1-B67F-2033F0942623,DellTcg2Dxe +249EDD7D-346D-4C90-B94F-16079EF061D5,AmdCpuPolicy +24A2D66F-EEDD-4086-9042-F26E4797EE69,RootBridgesConnectedEventGroupGuid +24A44CAF-0BF2-4514-90C4-C794B3E778F5,MePolicyInitDxe +24A6AB96-8A00-4CC6-BAE7-63A9D3DD3B42,SuperIoExDxe +24B09ABE-4E47-481C-A9AD-CEF12C392327,Omap35xxTokenSpaceGuid +24B14CB4-A14A-4E9A-AAD2-853335FA3297,AmdCpmModernStandbyFeatureDxe +24B4980D-3F4D-4529-B326-CBE87E35013C,AmdDmarControlPei +24BB68E0-0922-44C4-84EA-95FD75E59DE2,AsusGpnvVersion +24C33F98-505D-4177-90F7-A20CF8FF3020,ReTimerFmpDummy +24C5DC2F-53E2-40CA-9ED6-A5D9A49F463B,EfiHashAlgorithmSha1NoPadGuid +24C6F3E2-6ACD-436B-A604-56A5CF742A55,BaseFspPlatformInfoLibSample +24C856A9-46E7-4635-8017-0FDCCA1FF9C9,AmdFabricMdnSmm +24CCD374-3DF6-4181-86F6-E3C66920A145,UpdateMemoryRecord +24D7AC91-3A1A-44B7-8CD5-0800A66BCFE5,OemBadgingSupport +24DC0658-F2CD-4034-B50D-2634640C35BA,AsusHardwareSignature +24DDC83F-9F06-44AB-B696-60FE7DF2C948,RstVmdPeim +24E24F91-2E6D-4525-BAE9-B977DE2005D6,AepLogDrv +24E70042-D5C5-4260-8C39-0AD3AA32E93D,EfiSmmEndOfDxeProtocolGuid +24E9A512-3A25-4CBA-A0AE-67C053BDF3B6,DxeVideoTextOut +24FF7176-8B2A-4138-9509-3D5E3059BCF4,ExtendOperatingAmbientTemperatureModeDXE +25053BB9-01AE-4AF7-82A7-CDA6D9545921,TouchPad_Synaptics_2nd +25075106-F537-4BD4-AFA5-CFF0E6F3B2A6,AmdFabricRvDxe +2509B2F1-A022-4CCA-AF70-F9D321FB6649,EdkiiDeviceIdentifierTypePci +2515F54F-3277-47DA-86A5-484510DD08E1,AmdPspDxeV2Mdn +25247A74-9440-47D5-BF0A-ED92A4D6EBA4,DellComputraceBinary +2525B0F0-80C2-4AF7-BC68-3BE4BB42C11E,PermanentlyDisabled +2525C3F2-E255-4375-A7C9-92D1054D62B8,MsiBoardECPei +25264B72-7A80-4856-A7EC-15802270EE1B,CheckBootGuardKeyDxe +252E599F-D604-4BEA-8FEB-347668E93B8F,FjRTS54xx +25330D5D-5474-4EB8-8192-E6DE3D5ED0B6,DellVariable2Smm +253E85E9-993B-439B-B74C-6120F77B4723,PlatformReset +25462CDA-221F-47DF-AC1D-259CFAA4E326,DtPlatformDefaultDtbFile +254901AD-7DB7-45F8-93C8-93D579398D9F,PeiPciSegmentLibPciCfg2 +254B4A79-772C-45CC-05C9-17F84C2EA197,HpAmdXhciDxe +254BAFFE-F25E-45F1-A06F-5EF11443ACA4,AmdMcaZen5Dxe +2554EF5E-C9CA-4A48-9D94-249EB1E87C2D,LenovoCryptService +2555A2A2-101B-4775-B11E-47674F446628,FjPostManagerProtocolAbstractionReference +25566B03-B577-4CBF-958C-ED663EA24380,EfiSmmGpiDispatch2ProtocolGuid +255D96A8-1579-4ADF-8575-56D4B0467117,DellTcg2EarlyPlatformPei +256A381E-0165-4909-8663-EE317819292E,AIMT +258A5F45-00D5-485B-84DB-0B6D4AAB5E2F,TbtSsdt +258B415E-3E8E-4B82-8067-9EFC7949EAC8,ResetSystemDxe +258B77C1-5989-45A4-BFFF-7DAF147B2CE0,FjAddingFlexIoToSmBios +259311F9-A268-46C9-8DB4-79ACFB2B7DC1,EarlyDevices +259495EA-2DD9-4EA5-A111-61F58781499D,I2cMasterSmm +25A4FD4A-9703-4BA9-A190-B7C84EFB3E57,FdtVariableGuid +25A8824E-6BBF-4FB2-A200-84B0F7BECE6B,B57785 +25AC458A-CF60-476E-861A-211C757657A6,SnpDxePort +25ACF158-DD61-4E64-9A49-55851E9A26C7,CsmBlockIo +25AE661D-3652-4767-A800-2C3D03F4097A,Armani_ProductInfoSmm +25B09472-F258-49EA-A1CE-8A68F3A4A54B,InitOemSetupVariable +25BB7F51-752C-491E-BCB1-55EA608B3197,CertificateStorageSmm +25BDDDA9-CCF5-4D13-9954-EC69D30BABC4,AmdCpmZeroPowerOddPeim +25BFEBA1-A3BA-4BE2-9248-886392F7B008,AmdNbioPciePei +25C0310A-CB9E-47E0-CBC0-F7F45E55AC9F,DellMfgBootListConfigDxe +25C36CAC-80A6-400F-B0B1-8AEF82341801,OemReadyBoot +25CA4430-495D-42EF-8157-4D0AE2124862,HidAbsolutePointer +25D3605E-522F-4570-A197-56BDDACB5FED,BiosUpdatePlatformPolicyPei +25EC8AD0-0006-4F3E-908A-0CB82609938E,NvmExpressSmm +25ECAD7C-2C93-35B8-2E54-C71A4C02D3D1,QualCommSupplicantDxe +25F200AA-D3CB-470A-BF51-E7D162D22E6F,ShellDebug1HiiGuid +25F384DA-CB4F-4A89-9E12-1EB4BE79D6C1,EcMemoryIntrusionTestModeDxe +25F49067-A65B-48F5-BBBE-35418C488836,TcgDxeMainDxe +25FC783F-41AD-4BA1-B190-6D4B3FB6CC5B,ThunderboltDxe +2601C96E-243B-4509-AB14-DF2228E5B401,DellSbSmm +2605C8B7-EF64-475D-90F5-E767339F4D3E,OemUsbLightBarDxe +260AA875-0EED-4EE1-8A14-046B4FB17EF5,DetectRecoveryModePei +261230E3-22A4-3E55-40C6-50486D9F8D67,RTL8111dxe +2619EA76-4599-4978-8649-E7371170C256,OpticalDiskIdm +261E97B4-FBB5-4DB1-B25C-13270BA7BB60,EmulatedEepromDxe +262B2E3F-DA2D-4B81-8D1D-F938E851FDED,SmcBoardInfoVariable +263631D7-5836-4B74-BE48-EE22E92CE5D3,WinNtConsoleDxe +2636FCAC-B54E-4AA5-A720-49887CE228D2,ClearCmosPei +26452F27-45DE-4A94-807A-0E6FDC1CB962,EmuPeiGateDxe +266E31CC-13C5-4807-B9DC-39A6BA88FF1A,CpuInitDataHobGuid +26703ED8-9171-40A3-95C2-56436F8A5E56,EfiBpCommonPkgTokenSpaceGuid +2673B0C0-1F9F-45EF-FFFF-FFFF92FA6F0A,XnoteReportStatusCodePei +267FF286-B286-41B5-AE00-951EE5D39D09,BctBaseSmmRMB +268038B9-B691-404C-8E83-58014F3919FC,CheckCpuFanState +26841BDE-920A-4E7A-9FBE-637F477143A6,Ip4ConfigDxe +2686340E-665C-427F-8819-05BA54F030F5,IdeController2 +2688B232-9C02-4C12-BE1F-857C0FF2AAE3,TcgDxeplatform +268F33A9-CCCD-48BE-8817-86053AC32ED6,PeiSmmAccessPpiGuid +2696F127-44B2-4E14-8BFF-804AA177FE41,SDJpegDecoder +26A2481E-4424-46A2-9943-CC4039EAD8F8,S3Save +26BACCB1-6F42-11D4-BCE7-0080C73C8881,EfiCpuArchProtocolGuid +26BACCB2-6F42-11D4-BCE7-0080C73C8881,EfiMetronomeArchProtocolGuid +26BACCB3-6F42-11D4-BCE7-0080C73C8881,EfiTimerArchProtocolGuid +26C04CF3-F5FB-4968-8D57-C7FA0A932783,DellSbServicesSmm +26C628F2-CED5-466C-8237-433CA4D24241,MemoryEvContent +26C9D769-9167-4537-8219-D9F5FC2378BE,OemUsbTypeCDxe +26CC0FAD-BEB3-478A-91B2-0C188F726198,EfiPeiVirtualBlockIo2PpiGuid +26CC7C04-4E9D-4FED-AFBA-CBF23334DC0D,AmtWrapperDxe +26DC4851-195F-4AE1-9A19-FBF883BBB35E,AmiAptioSigOwner +26DDBA9F-5B0D-4E80-86B2-80DAE4D01B0E,FdiskOemDxe +26EBEC07-930B-4B92-81B7-2BC104D1CDBC,Nct5124dPeiInit +26EEB3DE-B689-492E-80F0-BE8BD7DA4BA7,EfiSmmConfigurationProtocolGuid +26F8AB01-D3CD-489C-984F-DFDEF768395B,PeiStatusCodeMemoryPpi +26FD847A-DC93-4D93-917C-6041A3856CBC,FchHuangshanDxe +26FDEB7E-B8AF-4CCF-AA97-02633CE48CA7,EfiProcessorSubClassGuid +2700F72F-E0EA-4767-9A1E-D172F0704778,PeiSelStatusCode +270279D6-2554-47BE-97D0-6AE5AD18B973,OemEeprom +2707E46D-DBD7-41C2-9C04-C9FDB8BAD86C,JpegDecoderDxe +2709A182-0DDA-4A91-BA53-11032B713633,AmiPspOfbd +271565A5-6E05-4948-BAE7-39AF389FFB97,DMBMPEI +2717997B-ABAC-4733-ADAF-9C19D8FBB7A1,CbmrDriver +271B424E-A4CC-4E0E-90A2-7EA4841F12F3,ExportHiiDb +271DD6F2-54CB-45E6-8585-8C923C1AC706,PchS3Peim +271F1343-20D6-4E14-9B62-3C0297F56F07,SmmPowerManagement +2721587E-2AE8-43A0-AAEB-19DDA16C7764,FlexIoPortConfigSmm +27270327-D3EC-4237-974D-D71ABB2EBFEA,FjMasterPasswordDxe +27287751-867A-46CD-91AF-416FF6AE3DFE,DellSystemIdConfigDxe +273820DB-55D9-5B44-93FC-6A4EC138EEC6,DellSpecialBootControlDxe +273D3086-65A3-463D-B5D6-AAC7CCC18445,PlatformTcg2Dxe +274365EF-0893-480C-9160-472A26D2DC0F,FjGabiGpioAbstraction +27470DBA-64DD-4C71-9CE5-5E3272207598,SioSmiSmbAlertDispatcher +274F0C8F-9E57-41D8-9966-29CCD48D31C2,SmmAccess +2755590C-6F3C-42FA-9EA4-A3BA543CDA25,EfiDebugSupportProtocolGuid +27584F62-1A26-41BA-85BE-74C0EEFF46AE,LANMacInfoDxe +27587B71-37F9-4A48-B570-58B6D14F6DEC,DellOromKbAccess +276E96AB-6101-4979-9980-E85BFD69102B,Common_AcpiDriverSupport +27723F8B-25A8-4DA1-A3FC-7B30E9871DC7,SmcOobPlatformPolicy +27755D2D-83DF-4916-BDFE-4FF3CD657965,POSTCODE0A_RGBKBCTRL_DXE +2785ED8A-795F-43A1-AE2D-6BFFECCBA646,AcpiUpdateCpuInfo +2786B637-5E93-4E57-B1D4-B69D8D496580,FjSysmanTeutatesSmmFjFextBin +278D0017-1F07-4F5E-A3EC-21D04DCC3A6F,IncompatiblePciDevice +279851D7-65A8-4009-A5B8-1F56BAB7E99D,AmdMemAm5Dxe +2799A453-FC10-4334-9E66-D3D6EF09D0EE,AmiTseOemPortingVar5Guid +279D52CB-5BD9-4BF7-99ED-5D365F73BEBB,AmdMiniRasRplServiceDxe +279DB133-B4C6-4A34-9BE3-C98326DC27DC,LEMHddSecurityEndProtocolHook +27A5159D-5E61-4809-919A-422E887101EF,PcatSingleSegmentPciCfgPei +27A71B1E-73EE-43D6-ACE3-521A2DC5D092,RepublishSecPpiPpi +27A95D13-15FB-4A2E-91E2-C784BF0D20D3,PersistenceConfigDxe +27A9836B-CD74-4DB2-9A8E-8A4FD52180B7,NvmeDeviceService +27AABECA-4BC5-4E6E-980B-BBD6627DA20E,TypeCWmiMessages +27ABF055-B1B8-4C26-8048-748F37BAA2DF,EfiEventExitBootServicesGuid +27B1960A-EE02-47A8-87B0-1222F119257F,FchTaishanPei +27BA7E67-D54D-4983-BE18-9DF07D2389DC,SystemNvmeServiceOwnerDxe +27BEDA18-AE2B-43C2-AF6B-74952441DE28,MonitorKeyDxe +27C10B10-114A-4D71-8C58-D67ED0F20D89,OemVGA +27C4686B-32B8-4BEC-A499-C5BA75639FC9,RsaSmm +27CFAC87-46CC-11D4-9A38-0090273FC14D,EfiRealTimeClockArchProtocolGuid +27CFAC88-46CC-11D4-9A38-0090273FC14D,EfiResetArchProtocolGuid +27D71940-D1F7-40F2-AA19-18C2B0564462,FjSysmanAmphionS3Resume +27DAEE12-488E-4E98-ADCF-38ADC10A6B68,H19ServiceBodySmm +27DE9EB2-73B4-43B2-ABD0-E87A5965424E,HddStandBySmm +27E569D5-0AFC-4D8F-8C90-783AC4A318AB,SaAcpiTables +27E94A0B-6E3C-4B4B-B876-176AE521CE60,DellHotSosDxe +27EEDF2D-469E-478C-805E-993CCFB5C0C1,CrbPxeLoader +27EEEC71-D849-4B64-A04B-5643CCEAC876,FchKunlunPei +27F05AF5-1644-4EF4-8944-48C4F75675A0,RealTimeClockDxe +27F3838F-BA27-4FFA-B374-35BEA28A431B,DellSmsc5544Dxe +27F4917B-A707-4AAD-9676-26DF168CBF0D,PchSpiSmm +27F51949-1577-4CF6-B2E2-AE9392A4EBB7,BootPriority +27F85559-359F-4B25-9B73-3EE5DE399121,DellSmbusHcSmm +27F9093F-527A-42AB-AE55-5C56DA8D9AB8,BootOrderDefaultSettings +280251C4-1D09-4035-9062-839ACB5F18C1,CpuMpPei +280BCC15-2CD7-467C-9647-1B30307D7ED5,AmiFriVariable +280DA667-74B6-410E-8ACD-D06C3F32EA20,IntelLANPei +2818256A-6BDB-4871-993C-95315854012E,EdidOverrideDxe +28260FD2-975F-48B4-B1A8-8F7919F55746,AmdOemRasBrhDxe +28324EF7-6BB3-4BAB-A2EC-18D5F7940F23,FjMaptDxe +28374747-76FF-41B3-9740-381EFAEF13BC,PspPlatform +283C945F-3FF5-4588-AD80-86E8708B942C,DellSimulatedECPei +283D62BE-957D-4863-8041-7E9C22201709,LfcNvsAcpi +283E7AD9-EFFA-468B-8289-887347D23300,FjCardReaderSmm +283FA2EE-532C-484D-9383-9F93B36F0B7E,EfiUpdateDataFileGuid +28451AA4-B4C4-4AA9-BE3A-1BBCC2E5553A,GptRecovery +2846412B-F50F-4A5B-8C8B-76644324AA66,FchSmbusDxe +2848A12F-3F86-47C7-81D8-D3FD47B205B2,CbsSetupDxeRPL +28638CFA-EA88-456C-92A5-F249CA488535,EfiRedirFruProtocol +2864CA7A-632C-456D-A4FB-B5B718566956,ReportStatusCodeRouterRuntimeDxe +286BF25A-C2C3-408C-B3B4-25E6758B7317,EfiTpmDeviceInstanceTpm20DtpmGuid +286EE96A-5B1F-484A-9689-CF770DC89185,SioShmLock +28758215-0D0D-4136-A8C8-68AB6711DF46,EcFwUpdateDxe +287D8F7E-6176-47DB-90EF-F1D6D2A3DE9E,BoardSmm +28825252-3211-352F-49CE-312534C41419,OdmGetPchCf9TrapHandleProtocol +2883464E-3CA2-4F4D-B903-21A1E3F61471,XhciControllerPei +2885E4AE-09A5-4EC8-A908-60C4E4A92B90,FchBixbyGpioPei +2885E4AE-09A5-4EC8-A908-60C4E4A92BAC,FchPromontoryGpioPei +288AB8A5-F2CF-4FCE-9C80-10A436C77276,ChineseDxe +2890B3EA-053D-1643-AD0C-D64808DA3FF1,HardwareInterruptProtocolGuid +2892389C-FBE9-43D7-B9FC-6C5D90D18456,TisDxe +2893CAF8-B638-41D6-8864-D924D189C0E8,SafeBatteryModeDxe +2894EC46-C67A-4256-87DE-34A741D85982,Mct +2896DAE0-778A-4231-86DF-1F54F752DB7B,FreeSpaceSkipFvCopyLib +2899C94A-1FB6-4B1A-B96B-8364975303E0,Ps2MouseAbsolutePointerDxe +28A02147-19D6-491C-AFEF-DB351BF46124,DiagnosticsJumper +28A03FF4-12B3-4305-A417-BB1A4F94081E,RamDiskDxe +28A76FE5-43D7-48A3-9714-C1B7BDD6DFB6,RedfishDiscoverDxe +28A88A39-DD84-483F-9BEF-BA1168C2F850,UbaInitPei +28AB63A9-5FB0-4C93-9C44-0DD8A1E9101D,AmdNbioAlibRVDxe +28B225EF-E6B1-4DC0-8D4D-49EFC857CCDF,FpgaSocketBbsGbe +28B5A45C-CC5D-4221-9DFF-86B0F42DDC01,LenovoIvbGopDriver +28BCCC59-7F4D-46E3-BFE3-8465CB5223A8,HpRpsuDetectDxe +28BCCC5A-7F4E-46E4-BFE4-8465CB5234B9,HpRpsuDetectPei +28BDE99C-E8A7-4E3E-9A8A-E66CD64F31C6,BasePciLibCf8 +28BE27E5-66CC-4A31-A315-DB14C3744D85,IscsiV6Private +28BF2E78-AD2D-4616-ABAD-7644CD7E47C8,FvBb1Pei +28C17F2E-4B7B-4708-885F-4784092C6254,ExBootItemDispatcher +28C7F2B1-B80B-4EEB-8DC7-0EA34954926E,FjEventLog +28D0232B-D26C-4B5F-94FF-B1340FC160B8,AmdCpuIdentifyPei +28D46803-7646-4DFE-90ED-8575584ED6E6,AmtDxePolicyInit +28D4DD89-169E-49DD-8486-A200A2FD3C21,AmiPerformanceProfiling +28E21F4C-DC8F-4C17-8B9A-92BCEE6835D5,OemACPIDriverHookDxe +28E50D66-A0EA-4A44-977D-D07319B9304A,HeciControlSmm +28E59971-3F7E-4E34-8DED-0745907B484D,FingerPrintBindingDriver +28EBF627-9BF1-4719-A676-4AF8362FEB23,RTS5242Dxe +28EEC887-BE28-4B44-9FC5-41C70784D3E1,SwSmi534D0040Shp +28F6EFF7-0A9F-4BE3-B12E-B59A04266ABA,MeIgnitionFsp +28F6FD2C-EFF2-42F0-9E9F-CAC87509DC46,OemSmi +28F7B66E-DF6B-4D34-A420-91CA108E9D00,SecureFlashAuthenticationPei +28FB2B1C-90FA-4D2E-BB97-B104A96DE97D,AmdDisableDashDxe +28FD5211-3777-4A13-9A2E-66A7341D15E4,FjClearsureDxe +29010E46-1CF4-465F-BEE5-0FD9E5535AD7,FjLvdsFwDownPei +29018044-0EC2-4650-891F-0813797863B7,MeLock +29019496-1EE5-4ABD-9CC5-74A210CE77C6,Ax88772UsbNetDriver +2906CC1F-09CA-4457-9A4F-C212C545D3D3,AppleEpidGroupPublicKeysRl +290A4467-9F89-4F1F-A73C-E10B9FAFBD1B,FjFlexIoDxe +290B026F-6905-4612-BA0F-F635DDE35285,ErrorTriangle +290EA249-6E88-423C-B0DA-75CDDE7920CC,AmtPetAlertDxe +29142FB2-26D9-4C3A-A4BA-7BBD0364EEAE,BaseSmbusLibNull +2915211A-3CF7-4B4D-B448-02DDBD2BF87C,CustomLogoWmiDriver +291A3B75-C685-475E-876B-2E40A6A7E18A,SetTimerPeriodDxe +291E46D4-CA63-4D33-9857-1397C9AD7C0D,LegacySmmSredir +29206FC2-9EAB-4612-ACA1-1E3D098FB1B3,LegacyVideoRom +2928D39C-917D-4F2F-9510-16AB73F204B2,BiosAcm_Field +292C13D2-C005-432D-BC17-E90701C8E84A,FjGenericItemStorageDxe +2938C3C9-4F9B-43B2-A429-7E6315AD6A9D,SmcRomHoleProtocol +293A571A-3308-443F-9F36-39DCFDBF3B83,DellEcIoDxe +293AAEB2-73B4-43B2-ABD0-E87A5965424E,AltModeSxSmi +2942476E-543E-4504-A0D2-0B2115E4A3C4,SwSmi534D0740 +29457247-977E-46AA-92E0-46E10E249225,AsusPeiGopVideo +294A6086-135A-4AD9-A89A-56D5A327F0E2,NbWrapperPei +294B196A-A3CC-4A43-857F-EEC26147857B,Tpm2DeviceLibSeC +294B1CEF-9BEB-42D5-9971-0C8963CDAF02,SmLogo +294B6514-CFCB-4CF4-8851-3F35330EAE60,RmtcPEI +294E3134-59C5-4C21-B59E-4A8F30515091,AmdPspPeiV2Shp +295B1031-F0B5-44F4-A75E-1CD2145C4D18,BreakpointCallbackDxe +296088B0-5AD7-46B7-A42B-004C2A0F00BB,AmdMemSmbiosV2SspPei +296E5F5A-3F3E-4B54-8395-98EBCC9407A6,AmiUsbCcid +296EB418-C4C8-4E05-AB59-39E8AF56F00A,EdkiiSmmExitBootServicesProtocolGuid +2977064F-AB96-4FA9-8545-F9C40251E07F,EfiPlatformPolicyProtocolGuid +2982A69D-A952-4A2A-A19B-0BE61B296199,PldmSmbios +2986883F-88E0-48D0-4B82-20C26948DDAC,TxtInfoHob +299141BB-211A-48A5-92C0-6F9A0A3A006E,PowerManagementAcpiTables2 +29926D4A-E531-490C-A529-C05E8A1D60D3,FwhFlashLibNull +299D6F8B-2EC9-4E40-9EC6-DDAA7EBF5FD9,SiInit +299DADAF-11A6-471B-9E65-CFE408F53DCE,FjSpeakerDxe +29A1A717-36E9-49E0-B381-EA3B5FF70942,LenovoSystemStatusCodePort80Rt +29A70110-7762-4211-AE88-FAB19B7665BE,MebxMenu +29B3C4C6-E5AA-49E4-8CE0-2772F782DDC2,WinNtGopDxe +29BAF53F-AA3E-4594-FFFF-FFFF85A7379C,XnotePlatformInfoDxe +29BE380A-FBC0-462B-A6C2-5C5A076CAFDE,ProjectPEI +29CBB005-C972-49F3-960F-292E2202CECD,FspNotifyPhasePeim +29CF55F8-B675-4F5D-8F2F-B87A3ECFD063,CsmVideo +29D02CE2-4A2C-45E1-9DC1-E7049B7DB321,SaDataHobGuid +29D0D0A1-446B-4AF4-AE36-526069E2D543,BBVersionHob +29D32BB5-1D1B-4DE0-8AA9-02D790CA643B,PmemResetNotify +29D40F30-E8BF-4803-88A6-4247A29A5318,AmdVersionDxe +29D8DD19-C836-45D9-8F05-322C27129C2A,SecureVariable +29E0564F-B702-4352-A3A1-15FABD4A4E4A,IioCfgUpdateDxeLightningRidgeEXECB3 +29E3DB8C-3B30-49D7-9262-53FB917B9A6B,BochsVga +29EA0DA2-84A0-4FC1-80E4-0531C7466EF6,DellSupportAssistUi +29F639F3-4BDA-49BA-89BF-BEC53CE48C2F,Tca9548aDxe +29FCFBE7-4B1E-3CB2-6D57-A994E8D044B0,AmdPlatformRasSspPei +2A0168CC-4320-452F-BACA-8BAEC7DAFBCA,AmdI2CMasterPei +2A1961E8-099E-4701-AEE0-F58C1ECF5B11,FjMiscControlSmm +2A197802-E469-4FA7-A37B-2D681BCF416F,TrackPointElan +2A1A6774-328D-4C58-9F30-019EFF54F9B2,MSIInBIOSFlash +2A1E1C92-AABA-4D62-AC40-F3A4C3387356,PeiSmbusLibSmbus2Ppi +2A205AA9-F7EA-47BE-B3BD-7631E99B4351,G3WakeupPei +2A2997C0-FC32-4098-A88D-0E5D7165C93F,ThermalSetting +2A304EE1-F3C3-4F35-95CD-93DD0DA00F2E,SystemSmbiosBcpDxe +2A32CCEA-5D78-46D7-BAED-8E53A1B31357,AcpiPlatformDxe +2A3398CC-652C-4919-9681-F2535A855F59,FjRandomNumberDxe +2A3CFEBD-27E8-4D0A-8B79-D688C2A3E1C0,EfiSmmLockBoxCommunicationGuid +2A3DC717-6C36-4F55-9D2E-CA5A73D62F17,DellTokenHandlerProtocol +2A4224A1-2609-40A7-88E2-A68DC0F1D180,SpiFlashProDxe +2A43BA5F-AC29-4FDC-8A3B-0328D0256F8C,SocketDxe +2A46715F-3581-4A55-8E73-2B769AAA30C5,RamDiskFormSetGuid +2A46A149-5F3A-41BE-87E7-982A68369D4A,AmdMemFp11StxhPei +2A4D1ADF-21DC-4B81-A42F-8B8EE2380060,EfiSmartCardReaderProtocolGuid +2A4DC6B7-41F5-45DD-B46F-2DD334C1CF65,LenovoConfigVariable +2A4EDBDD-CE8A-46C3-98AC-D1AD3DEE9D85,RepairResult +2A500CFB-920E-49F4-9988-5CE4C0EFD3AB,SmbiosDmiEditAfriSmi +2A534210-9280-41D8-AE79-CADA01A2B127,EfiDriverHealthProtocolGuid +2A537C0E-5D9C-45D3-A6CE-3AD02D3E3B53,ReserveMem +2A571201-4966-47F6-8B86-F31E41F32F10,EfiEventLegacyBootGuid +2A57AE75-8B7A-4C64-8656-DB51DDC36F7B,EfiHiiExtProtocol +2A591128-6CC7-42B1-8AF0-58933B682DBB,EfiExtendedSalMcaServicesProtocolGuid +2A5923F0-06FB-4A23-9D06-F976C7B3C312,PlatformStatusCodeHandlerDxe2 +2A6B4530-9099-4937-8FE7-F168EFE09C89,DellBoardConnectorMapPolicy +2A6E902B-F1F3-4275-BC7B-40FD4B5481E7,FlashUpdBootModePpiGuid +2A72D11E-7376-40F6-9C68-23FA2FE363F1,EfiEbcSimpleDebuggerProtocolGuid +2A7946E3-1AB2-49A9-ACCB-C6275139C1A5,TrEEDxe +2A7B832B-3EE0-44C2-8F3A-9FD43183B853,DellFmpPfat +2A82FCE6-8BB6-413E-B9EB-45DFC0522DF3,EfiSmmThunkProtocol +2A8EB7B1-4913-4B5C-A0C7-E70791A715BC,SystemMemoryManagerRt +2A9A39D5-95D8-4E2E-9793-BFAAF0B6820C,EarlySetPlatformHardwareSwitchPei +2A9D5E7F-A43A-4FC7-A25E-6E28D412FA6F,efi_pop_RT +2AA040F7-A1A3-4EEA-89CA-707E1A7E86B8,Int15Smm +2AA290DB-6B3D-40D0-9FED-89E004BB0CF2,LenovoSmmMeConfig +2AA8F59B-102D-4096-8FCD-B64422C637B5,UefiDiagnosticsApp +2AAEBE5F-BD22-4E05-B714-1B2B2338CD6A,RecoveryControl +2AAEC318-E84B-4E0B-BF41-AC65F17E9E2F,AmiTseOemPortingVar14 +2AB4A35F-C2AF-ABCD-A22B-4AD3C58B7960,LogDataDxe +2AB86EF5-ECB5-4134-B556-3854CA1FE1B4,EfiPeiReadOnlyVariable2PpiGuid +2ACB1E45-DFA4-4FF3-8F81-91F7D787D22D,SystemUsbMemoryManagerSmm +2ACB6627-DF02-4E23-B4F9-6A93FA6E9DA6,EfiSataControllerProtocol +2AD073BA-EA27-45B7-9CFA-F947018FB8EB,QcaWifiDxeDriver +2AD0FC59-2314-4BF3-8633-13FA22A624A0,PlatformPei +2AD511C7-1B60-4002-841D-2998DDC138EE,CryptoSMM +2AD81E19-2E9B-44AA-B4AC-9E2165322E1C,EfiUsbLegacyStack +2AD8E2D2-2E91-4CD1-95F5-E78FE5EBE316,EfiUsbProtocolGuid +2ADA836D-0A3D-43D6-A25A-3845CAD2D400,EfiCpuTokenSpace +2ADB6E4C-C983-4140-A160-FBC7D6B450D9,AmdSocAm4SmDxe +2ADB8F5B-C7D4-4E7E-BE2A-23634DF668A1,MouseDriver +2ADE58B0-D2BD-4AE7-B918-E9AAA1A45985,DellThrottlingControlProtocol +2AE9D80F-3FB2-4095-B7B1-E93157B946B6,EfiHashAlgorithmSha1Guid +2AEDA0EB-1392-4232-A4F9-C57A3C2FA2D9,BindingsSmm +2AF54A50-EE6D-4F12-BCFF-F0234FF57CA0,RTSCallbackHandleSmm +2B00C709-782F-4879-A59A-8E2FCE2271F8,AmdCdmaDsmDxe +2B0585EB-D8B8-49A9-8B8C-E21B01AEF2B7,AppleLegacyLoad +2B1D0832-2184-4C8F-A90D-8E4AF9DE5BCD,BootModePeim +2B268417-CFD4-4C29-85FC-4959300E4969,BcmCvUsbSmall +2B2D301B-EA3D-4237-8B52-9335A7A030BA,IioCfgUpdateDxeCLX64L +2B2F68CC-0CD2-44CF-8E8B-BBA20B1B5B75,EfiUsbBusProtocol +2B2F68D6-0CD2-44CF-8E8B-BBA20B1B5B75,EfiUsbIoProtocolGuid +2B2F68DA-0CD2-44CF-8E8B-BBA20B1B5B75,EfiUsbAtapiProtocol +2B341C7B-0B32-4A65-9D46-E1B3ABD4C25C,Smbios131 +2B346098-AA0B-4AE7-BDBE-88EB3CD6220F,BiosDiags20 +2B3685C5-CF90-4A67-8A48-9134BA32D677,PlatformStage1Pei +2B3FE36D-BE59-4110-8F42-7BAD910C9663,SsidDxe +2B4034AE-8566-412F-9CA5-67FD698FC261,TcoSmi +2B440005-2829-412F-B085-DD012BBE8A9F,AdvBootConfigDxe +2B475251-13C6-4547-B2F2-40762FEF9B89,SystemBootMenuDxeGui +2B4A109C-9ED7-47FE-80AA-2087E4E0301E,EcRotLockEcDxe +2B657C46-9AD6-45A5-AB5C-71CE3364AA3D,HQEepromSmm +2B72FC60-6D4F-42D5-8FF0-ABEFD5CDF859,HDCPSwSmi +2B73B074-2E67-498B-82AC-CE38FB770FFC,DxeSalLibEsal +2B798455-13A0-4910-B49D-2EB1FB5F77C8,ApobStxKrkDxe +2B7A240D-D5AD-4FD6-BE1C-DFA4415F5526,DtPlatformFormSet +2B7C4182-81B0-4AAA-9E70-B88AEC29B853,PeimBoardInit +2B872B22-6C11-4DFD-994A-96BC13920A43,fTPMTcg2Smm +2B8A4061-9131-4D2A-A20B-D845D0EB1D83,Smbrun +2B8EFD98-FF63-42B8-BCF3-F53615D15536,AbtSetup +2B94ADDD-AE11-4111-9FF0-60BCB65B223D,AcpiCommon +2B9B22DE-2AD4-4ABC-957D-5F18C504A05C,EfiSocketMpLinkVariable +2B9D21A0-E048-4333-9F02-D32FD5576752,ProductIdentify +2B9E5A05-686F-4E72-AF0A-2D7BAA61E918,AmdNbioPcieRVPei +2B9F22AC-2BE0-4886-9D12-66B1359FD0AE,DellAmdThunderboltSmm +2B9FFB52-1B13-416F-A87B-BC930DEF92A8,TcgEventEntryHobGuid +2BA071C0-B884-4D08-BCFF-518E16364C8B,PciHostBridge +2BA0D612-C3AD-4249-915D-AA0E8709485F,SdioDriver +2BA36F7A-F5E7-4D35-9149-60894CB37431,Nfa765Launcher +2BB5AFA9-FF33-417B-8497-CB773C2B93BF,CpuPei +2BBED685-6633-455F-A840-43A22B791FFF,AcpiFPDTSupport +2BC18FFC-7CF6-47C1-AF19-A4076DC00470,CbsBasePeiZP +2BC1C74A-122F-40B2-B223-082B7465225D,FspWrapperTokenSpaceGuid +2BD51C9B-EB2E-4CFB-95B7-0C5765FDCBC3,AtaDeviceService +2BD56418-461E-545A-8E24-A0BC15D40525,AsfUi +2BD66684-A214-493C-BAF9-70D9706E278A,DualModeDxe +2BD77D17-3771-4974-8644-F99CF5B266A7,IntelGigabitLanPolicyProtocol +2BD77D17-3771-4974-8644-F99CF5B266A8,Intel_10gLanPolicyProtocol +2BDED685-F733-455F-A840-43A22B791FB3,AcpiS3SaveDxe +2BE1E4A6-6505-43B3-9FFC-A3C8330E0432,TcgPei +2BE1E789-3548-43B3-9EEA-B4C8875E0321,A01ServiceBodyPei +2BF5D013-4E75-45FC-ACB4-9247145C1743,GigUndiDxe +2BFE7B9B-767A-44BE-80F9-6E0212899FE0,Pca9555aPei +2C009288-9C14-4AD9-8877-F0C2CBAA9893,HpKeyboardLayout +2C03C536-4594-4515-9E7A-D3D204FE1363,EfiFileExplorerProtocolGuid +2C056F2D-993B-4A54-8ADD-84ACE5D9CCE7,HpAcpiCore +2C0974A9-E7A3-4C45-B8B7-3A046E350A50,EnhancedMcaErrorLog +2C181BE1-8BAC-4433-873C-E5074CB5A723,UbaConfigDatabasePei +2C194230-54B6-4C95-B809-877E83309358,ASUSGamingBoard +2C20B724-C903-435D-A5E5-2899E291D94E,AmdCpmPmfBoardDxe +2C2275C9-3A7B-426F-BE54-2D22BD9D1092,EdkiiCryptoProtocol +2C2694BC-FDD8-452C-8899-2A1A6B401D56,SndwInstallDevTopology +2C29929E-27CF-4DD5-BB97-E5525791F5BA,DRYDXE +2C3FFC0D-0AB4-4D75-B8EE-0086D76B8A0C,CxlPostMemInit +2C6B9CB7-A13B-4EEE-80C0-1A240C8A69EE,IccOverClocking +2C6CACC6-6C3C-4AA7-B2DE-384DAE2B0352,RegAccessPeim +2C6FF095-525C-4128-BD00-B8DA5E52A76E,AmdCpmSocAm4SmbRDxe +2C7087F9-B414-4969-B616-6B13BFEC0E38,FjSystemResetSmm +2C7314B0-A18E-4DAF-8B23-1F21D41572A8,HddSpinDownSmm +2C75A2A2-101B-4775-B11E-47674EEF6628,FjPowerButtonAbstractionReference +2C824F87-0F2C-45D7-81A6-4F39E042BDDF,EfiPlatformTypeHedtCrbProtocol +2C82AB3C-A734-4C7E-A790-F379BBF88F9B,PlatformMilestoneHookSmm +2C8759D5-5C2D-66EF-925F-B66C101957E2,EfiIp6ProtocolGuid +2C878DFE-F92E-4D00-BCED-146AFE099841,MemCacheInit +2CA73883-7B65-4120-87D1-59F689C3CA3D,AsusEcSmmCallback +2CA88B53-D296-4080-A4A5-CAD9BAE24B09,LoadFixedAddressConfigurationTableGuid +2CB14F4D-5D75-4FED-AEA0-4BC36E081AD5,DeepS3ConfigSmm +2CB4F37A-0026-43AF-A948-D71976A96860,CpuIoDxe +2CB67ED1-5498-45AA-9971-214964509195,SecurityEventPei +2CBC152B-B48A-4060-B009-DCB9379E5015,RcPolicyOverridePei +2CBF0E0E-B445-48BE-ABDD-B09A71303FC5,FjRtcWakeupSmm +2CC14F4D-6D85-4EDD-FEA3-4BC66D083AD7,HpModernStandbySetupConfigSmm +2CC4C70B-0312-4CD7-BFC2-A7A89C88C08A,DriveLockDxe +2CC919D9-5995-4F3F-9169-62301A6C72AC,ECUpdateFramework +2CCAF69C-6261-47BD-AC46-E6F471D654D9,StorageInfoProtocolDxe +2CDF679F-7AA0-4D0F-AFE1-1ADAE27061C9,FjMfgFirstPowerOnDxe +2CE0E430-A83D-4045-9040-D6BF6EC86300,CustomLogoDxe +2CE5604F-A982-4D2E-8FD0-D1600C2E1515,PciDynamicSetup +2CE66CC0-3F7F-4859-AB07-E7542944DD19,PowerLoss +2CE70F66-AC57-4346-A91F-89281A07FAD6,ErrorDisplayFramework +2CFA6CCE-1A57-46FF-BE62-D6B1EA11254E,SmmCryptoAlgorithm +2D07DCE9-CF98-408F-A13C-20E41746AE95,TPMHwPresent +2D11AA6E-EAB1-44E1-A1E6-E511FCB01498,QCASUPP +2D1E361C-7B3F-4D15-8B1F-66E551FABDC7,SaLateInitSmm +2D1FED91-677D-4918-B58B-AB4BCE20E672,AbtChk +2D211BAB-0845-4D24-8BE6-A6EC7AB76572,AmdCpmOemSmm +2D2358B4-E96C-484D-B2DD-7C2EDFC7D56F,ConsolePrefFormSet +2D27C618-7DCD-41F5-BB10-21166BE7E143,BiosAc +2D2E62AA-9ECF-43B7-8219-94E7FC713DFE,SystemUsbMouseDxe +2D2E62CF-9ECF-43B7-8219-94E7FC713DFE,SystemUsbKbDxe +2D3F7085-BA63-4739-A15F-C8802B6B807B,NCT3933Pei +2D408713-4023-4324-B8EA-53C02A83D941,PeCoffExtraActionLibSmm +2D4AAC1B-91A5-4CD5-9B5C-B40F5D2851A1,SpiFlashInfo +2D4F898E-2A20-446F-9D90-CBF6B46D45CB,AmdRaidPassword +2D513AE1-714B-4F93-A57A-0A0CDDF48ECC,BiosUpdateFaultToleranceDxe +2D586AF2-47C4-47BB-A860-89495D5BBFEB,IntelVTdDmarPei +2D58A07F-38A7-490B-86A0-D39F60ED7939,FjGabiEntryDxeBin +2D59F041-53A4-40D0-A6CD-844DC0DFEF17,SmmS3SaveState +2D61B52A-69EF-497D-8317-5574AEC89BE4,FirmwarePassword +2D6447EF-3BC9-41A0-AC19-4D51D01B4CE6,AmiDeviceNameDevicePath +2D6BB83D-84A2-404A-B4CA-3E7AC0EFB3D2,BootOptionPolicyDxe +2D6DCB78-CAE2-4459-927C-64A6B7E64A75,DellEdiagsSmm +2D6F37BF-9AFC-4AA5-A026-32B2FCF30FB9,LenovoPlatformDxe +2D6F6BCC-9681-8E42-8579-B57DCD0060F0,AutoScanPei +2D710FD8-C396-4981-A64F-F96EAA3931E7,TceqAlertPei +2D710FD8-C4A7-4981-A64F-F96EAA3931E7,TceqAlertDxe +2D7522FA-67F0-4768-B6E0-FD76F17F4B04,DellPbaUpekDpba +2D7FCD87-4554-4564-B811-0F9167F782B3,CrbAcpiPlatform +2D8B2364-F465-4A70-B8AB-BBC730DEDDBF,LCDIdm +2D9BD72A-B238-4BFF-9BB9-B51E0D4D553C,SlotDataUpdateDxeLightningRidgeEXECB3 +2DA064D8-5A52-4DAC-B60F-54471A7FC372,CspFlashLibNull +2DBC8099-1A2C-0361-BB80-B9CC4F7F50D2,FlashPatchTableDxe +2DC22D1C-2B4D-4D04-9AD2-BC1D8FDE20FF,IsaAcpiDxe +2DCBE49A-1E5B-486E-BC23-48156B8282C9,X11DxeDriver +2DCD8815-74CB-4BED-A485-4B3928BF50EE,RsaBmcCommands +2DCE8BB1-BDD7-450E-B9AD-9CF4EBD4F890,EfiEventNotificationTypeCmcGuid +2DD27694-AD5C-4EC7-9870-BC58F9E17931,FjBiosSetupOptionControlBin +2DDFEDFE-C2D5-43E3-9E10-46DB2C7C1F26,SmbiosElogSetupScreen +2DE2AE4B-7489-4D91-9B63-9B12CC564540,A01ServiceBodyDxe +2DE648CB-3102-43CA-A02E-42E38EA5E789,ProcessorErrorHandler +2DEAE482-5796-40F2-8DF5-D87419D6F362,ASUSHDDPW +2DEBAA89-2D51-485F-A2FA-2A62F9422364,HiiStringLanguageService +2DED8109-2355-41F8-A657-D608D5CC1022,SdxcDxe +2DEE4B44-C08E-4E60-9AEB-A11E2ADAA4B5,FchPeiAux +2DF10014-CF21-4280-8C3F-E539B8EE5150,PpmPolicyInitDxe +2DF1E051-906D-4EFF-869D-24E65378FB9E,ConsoleInDevicesStartedProtocol +2DF5E0F8-469F-4730-983E-A7520FCF7108,CsmLoader +2DF61403-C180-45A5-A22B-1A3DB88FE9BA,DellGenericSioDxe +2DF6BA0B-7092-440D-BD04-FB091EC3F3C1,EdkiiPlatformSpecificResetHandlerProtocol +2DFE2E00-2CE9-4122-9B1F-DC5A6454C8AD,FixedFlashInfo +2E058B2B-EDC1-4431-87D9-C6C4EA102BE3,ScNvsAreaProtocolGuid +2E0F6A1D-B08E-456D-8815-77AEF39D4941,OemSlic +2E1128A1-18EC-419D-A058-1076E243E323,HpSioSecuritySmmProtocol +2E13E5F1-B86D-4CF8-990F-243B6B9B8C61,NvmeRaidDxe +2E1B8E61-9D16-466B-A802-3B1E92EA95EC,CbsSetupDxeSTP +2E1BB677-B167-4E39-9BB6-2F91467AC4CD,PciDxeInit +2E1C3FF9-DC75-41C5-BD48-26087B5DC92A,EdkiiVariableStorageIoCompletionProtocolGuid +2E226D21-7668-4A6C-916A-778AFA55A874,ClientronPeiDriver +2E2D1233-435E-F56F-7CC3-348CE660D1CF,SystemErrorEventsDxe +2E3044AC-879F-490F-9760-BBDFAF695F50,EfiLegacyBiosGuid +2E3AB8B6-AC9D-4D70-A675-54F52FB22D66,AtaPassThru +2E3C89F7-A519-4570-AB2B-91AC503CB312,AmdCpmOemInitPeim +2E3D2E75-9B2E-412D-B4B1-70416B8700FF,RecoveryOnFatFloppyDiskGuid +2E3F2275-89CD-4DE4-BD84-BEBFD94BCDCC,DellSmBiosDaCiSmm +2E551A63-E2F8-4401-B617-ECDE2338463C,PlatformMilestoneHookDxe +2E58E381-3D7C-43D4-9A89-8D331362A2C0,BiosPostLogoDiyDxe +2E5CFC2C-9CC0-4D78-BEAF-D84CBF20D1C8,efi_pop_LF +2E67047C-7647-40F8-886C-5C333C73272F,InitSerialPortPei +2E694472-97F9-4D3E-940B-360A2731DEBD,RegulatoryInfoSupportDxe +2E6A521C-F697-402D-9774-98B2B7E140F3,PlatformType +2E6FECFB-B0E1-4580-8966-29178C72022E,SmmS3BootScriptLibS3SmmSaveStateProtocol +2E71987C-4227-1E51-40E3-8A824DE9511B,PlatformSioHwSmi +2E7472A2-D7BF-4F5E-8FE4-BF19247856D0,SecCore +2E7D322C-0E5C-11DF-A0DE-1BF2A44EDC7E,VmwExtCfgDevDxe +2E7DB7A7-608E-4041-B45F-00359E0766C6,FvbServicesSmm +2E85FC4F-7050-4F09-9C5D-9A5DD01D3CB5,LegacyToEfiSmm +2E89AF61-6E76-42E6-8F3E-BCEE83C9526E,H19ServiceBodySmm +2E8A3B3E-F26C-11EA-BDE5-6726AD8F88BD,BootProgressPeim +2E8CD01A-BDB7-40B4-8376-E7C26EAC21FF,PciPlatform +2E8FF74E-8BA4-4CD6-814F-F96962DDFE27,DellDiagUtilityProtocol +2E97EA24-5866-4240-A891-D20AFC6074FF,AmdFabricZpSmm +2E9C3108-7C31-4728-8D61-F9EC77692383,AmdNbioGfxRPLPei +2EA77912-80A8-4947-BE69-CDD00AFBE556,EdkiiNonDiscoverableUfsDeviceGuid +2EA84160-ABA0-11DF-9896-0002A5D5C51B,PL301Axi +2EA9743A-23D9-425E-872C-F615AA195788,AppleRemovableMediaProtocol +2EAA04AA-5EED-4C27-B9EE-26916EC25A8F,RtkUndiDxeX64_011 +2EACAEFF-6452-4FEA-9B32-9B12CC56514F,A01SensitiveVariables +2EB172A7-68E5-4A80-9FF9-19DF37A693CA,DellBfaSmmProtocol +2EBE0275-6458-4AF9-91ED-D3F4EDB100AA,SignOn +2EBF1D8D-D363-448F-8D39-902F3FB81F75,SuperRTC +2EC3760F-B7FC-4FC7-B8B4-CF371C9628FF,ThunderboltXDomainDevice +2EC499F9-0337-4DA1-91CA-6BC4E8C03DA2,Mtftp6Dxe +2EC918ED-4DC2-4D77-BB83-A5912130F5B4,FchKTSataD3ColdSmm +2EC9DA37-EE35-4DE9-86C5-6D9A81DC38A7,AmdSevDxe +2ECED69B-2793-4388-BA3C-823040EBCCD2,EfiOSInfo +2ED4D0C3-809D-40A0-AEF6-52D683C86F23,AsusPTTPei +2ED74D39-F9D5-485D-8357-0E00FE871C12,TouchPad_Synaptics +2ED8BC59-0671-49ED-A86F-1B6760B380A8,SmuV13Pei +2EDBC810-AA96-4C83-B743-5ED9CFF79833,CnvDxe +2EE72E7C-FB9E-4318-B888-33A315C7A91D,PpmPolicy +2EE81ACB-64B2-41AE-8635-7030D16C4AA8,PchBiosWriteProtect +2EF1BA1A-C836-4A50-BF89-525FF29FF787,Mxm30Pei +2EF72ABE-8D76-49CC-86EB-47C7D1891C7F,SelfHealingDetectCorruptionPei +2EF779D2-D09A-420C-8BDA-52B6C430B559,Armani_EcCommunicationDxe +2EF9F762-4328-8406-2A59-62B9729A607B,DashUi +2EFEF5DE-BF55-4BCF-F01E-8F4EF0B96A9D,DatabaseManagerSmm +2EFF67E3-5987-46E8-8111-80FFA67AEB93,DellUsbMouse +2F0868D0-1A47-43F7-BD6B-D0C1F2514298,SmbusDebugDxe +2F08C089-2073-4BD9-9E7E-308A18327B53,IconWirelessSmall +2F0CA072-99C6-43AB-810A-528C43C68EEF,AmdSmmControl +2F1E20D4-17B6-434A-974B-CFAE19062CC2,DellMemorySlotConfigDxe +2F2295B6-1BB6-4CB7-BB9E-15C2C3424277,PcieSataController +2F240E12-E14D-475C-83B0-EFFF22D77BE7,EfiKmsFormatSha512512Guid +2F30DA26-F51B-4B6F-85C4-31873C281BCA,LinuxInitrdDynamicShellCommand +2F3962B2-57C5-44EC-9EFC-A69FD302032B,TopOfTemporaryRamPpiGuid +2F3B1D78-060E-4D5B-AC7E-1E1DB2128559,OemDevInit +2F46F5EF-F9B9-4E45-9ACC-B14C2AE072BA,SystemShutdownEvent +2F4DDD35-F8C0-46D2-B0E3-A701360D7499,PcieLaneDXE +2F56AEDE-B753-4A08-8A8B-5765931B9724,HpIntelChipsetAcpiArea +2F5AB7EA-DA90-4E84-83EE-5F7397254531,BindingsPei +2F62A818-4A72-CD40-90B9-FF00DAABEE7B,EmuThunk +2F707EBB-4A1A-11D4-9A38-0090273FC14D,EfiPciRootBridgeIoProtocolGuid +2F70E1E7-4F99-4401-851B-2042AE38FB74,AsusSetupHookDxe +2F72309E-D5B0-4A9D-84A9-1AB38C698F78,EcPs2Kbd +2F7673E9-7C0B-435A-9B22-A801BF25FCE5,SioThermalErrorDxe +2F7E0C26-A57F-5F4F-AFCC-CD3D5EE07CED,PlanarSelfRepairApplication +2F841C60-1B1F-4007-BE6D-753CCBE05740,ODMSMBIOSTypeCASmm +2F87BA6A-5C04-4385-A780-F3BF78A97BEC,EfiBlockIoCryptoAlgoAesXtsGuid +2F8CDF1D-80E6-4FF0-95DB-2C3E071A1774,000_X64 +2F9AC9E5-E3E9-4096-9EE9-28AA6F763E59,DellHttpsBootManagerSmm +2F9C1C3D-28AA-469F-85C0-193DB9D50678,DeferredPsbFuseDxe +2FA2A6DA-11D5-4DC3-999A-749648B03C56,PiSmmIpl +2FA5F75C-BF60-472F-AD9A-FD23AD5B937E,SmmUartModeGpioInit +2FA66F37-8D93-4023-B6A2-BC5049ACCF0B,DellPasswordPolicySmmProtocol +2FB216ED-4A67-4833-9F5C-248124CD9AAC,DxeGpioPolicy +2FB92EFA-2EE0-4BAE-9EB6-7444125E1EF7,DellGset +2FB92EFA-2EE0-4BAE-9EB6-7464125E1EF7,UhciDxe +2FC3B2D3-6EBA-42B0-A4A7-14C7A84B5D22,EslIp6ServiceGuid +2FC3EDE1-4414-4D1F-9029-D470C7DE4827,SioAcpiNvsArea +2FC61DE6-1791-479C-8A32-7ABB69A4D8D0,AmdPspFtpmPei +2FC95DA8-6DED-4E19-BA0F-A253032E144A,DellHotSosSmm +2FCC2A4E-6995-4688-812B-6EC7E7A41B51,RTL8152B_RTL8153_USB +2FD21CF6-E6E8-4FF2-A9CA-3B9F00E92889,rmHwA9x4Guid +2FD67077-63F5-4B43-B180-1974E5C70BEB,MTKSUPP +2FD8B7AD-F8FA-4021-9FC0-0AA572147CDC,CpuPei +2FDACAF6-669D-4F8C-8368-C3B3E6E32535,UsbBbs +2FDC69B5-45EC-4284-AEE2-0F9DE85AE9A5,AmiQrCode +2FE2CBFC-B9AA-4A93-AB5B-40173B581C42,FmpDxe +2FE607A1-B7D3-41D6-BE4A-DA60BD1CAAAC,FchSmmDispatcher +2FE800BE-8F01-4AA6-946B-D71388E1833F,EfiMtftp4ServiceBindingProtocolGuid +2FE93E1D-1D04-438F-A0F9-A84D781A7C57,EF_Allocator +2FEDFBE3-EC63-4B1A-8D28-1294912CFA2B,MobileDiagBinary +2FF29FA7-5E80-4ED9-B380-017D3C554FF4,EfiSmmRscHandlerProtocolGuid +2FF3EBE7-F9BB-4230-89E6-154D2B22656F,DiagnosticTestInterfaceDxe +2FFDAF4A-A9B5-4EF6-AA3B-A89611AAB284,DellSpiPartPromJet +300DE6C5-765C-4F89-BD6D-A623785ABC27,PchLibNull +30101AD1-A99E-4175-907F-7A8A561A8750,FjNvramMerge +301A0BC3-BA16-49F9-858B-DEE05F91E7B8,TpAcpiNvsInitDxe +301AF449-E0D7-43A3-8B1B-BC16725D374B,DxeDebugDispatchProtocolGuid +3020484F-4582-406E-B20F-89EACC93DC6A,DellSmmLegacyRegionProtocol +3022E512-B94A-4F12-806D-7EF1177899D8,PciHotPlug +3035F2C2-48EB-46BB-A599-B2338DD58867,AMIProjectPEI +304003EA-7A75-4776-83D4-6B784B6E1900,MemoryInfoSetupUtilityDxe +30461A00-DEEC-4EF1-B7B2-6CA9511B5982,AmiAgesaAcpi +30499E37-FC01-4DD6-8E07-2E3853DEBE60,AmdLegacyInterrupt +3054D6BF-E71D-4818-8E1F-17B012B58788,H19RecordLog +30572445-4C9B-4726-B080-D9AEA2B03DF1,PspPei +305DE41E-EA19-4D20-9A93-0E0DD42A3F67,Mec5107Pei +3065B008-5E9B-47A9-9FE0-001CDA3C5F68,CcgxFwUpdate +306C96E6-7613-44E9-A588-95609EBA01A1,BctBaseSmmBRH +3073D8AC-EFAB-4055-9B37-F62CD93A200A,IrqAllocatorDxe +3079818C-46D4-4A73-AEF3-E3E46CF1EEDB,EfiBootScriptExecutorVariableGuid +307D4A1D-DDD8-4E2F-AC68-D8B213C198FE,BiosAuditLogHandlerDxe +307F86DA-031F-4527-8EC4-2AE82DDFC086,OemAcpiDriver +30806658-1E9C-4A13-971E-707A69E958C8,Int15MicrocodeSmm +308DD02C-092B-4123-A2AF-3EF4440A6B4A,AmiResetTypeVariable +3090CDC2-5EFD-4FBE-B22D-584EBD3D08BA,TouchDriver +3095CD79-5B45-49DF-B27F-EF43843B8480,IrqBoardInfoSct +30965142-FC5A-4E6E-94DB-BBA441B36851,AmiPciOpromDataProtocol +309DE7F1-7F5E-4ACE-B49C-531BE5AA95EF,EfiGenericMemTestProtocolGuid +30A48939-C8F9-4018-BED7-9F9228F16781,BatteryHealthControlDxe +30A5E718-39CA-441C-BED3-F4A3A931458D,FchProm21SmmInit +30AC275E-BB30-4B84-A1CD-0AF1322C89C0,PeiSpeakerInterfacePpiGuid +30AD2B83-ADD0-414B-B11C-F93CC1D0B79B,AmiProcessTcgPpiRequestGuid +30ADD18D-E143-4329-A977-B49A659573AD,SpiAccessSmm +30AF1245-A58E-4EF7-8C75-B725939B3B9F,AmdCpmInitSmm +30AF4110-A58E-4EF7-8C75-B725939B3B9F,AmdCpmDisplayFeatureSmm +30B6EB8F-08A3-4E66-8279-D8681D127F59,LenovoTpmFwWufuDxe +30B7AA80-44B5-477E-8AC3-21493F5B9D43,FjClearRtcDayLight +30B851D3-90FA-4180-A702-97F4114F3076,FjGabiSettingsCoreAbstractionDxe +30CB00F8-2E45-4C18-BD3E-EE7AD3C02576,SECWDTPEI +30CC8A21-0476-4C80-B5C5-B26947E1891D,XhciDebugger +30CFE3E7-3DE1-4586-BE20-DEABA1B3B793,EfiPciEnumerationCompleteProtocolGuid +30D6ED39-28BD-4C0C-A799-6305A4FE8A6A,WatchDogTableDxe +30E7F470-4EB3-4856-8C83-31741A20F877,SdevTableDxe +30EB0F26-FC0A-4FD2-B9C9-751EA2BB1980,DataSource +30EB2979-B0F7-4D60-B2DC-1A2C96CEB1F4,PeiPlatformMemoryRangePpi +30F2B506-3F94-4A11-85D2-EBF60B35F594,ArmaniSmbiosUpdate +30F86179-A9EB-4456-9D3A-157DBB62BE3B,Int15CallbackSmm +30FD316A-6728-2E41-A690-0D1333D8CAC1,EmuGraphicsWindowProtocolGuid +310B3904-0728-4977-A90C-06B8ECD85A9F,A01DxeInstallHook +310E9B8C-CF90-421E-8E9B-9EEFB617C8EF,S3StorageDeviceInitList +311032C4-98A6-4E06-8C03-D815FD1FE709,LenovoSnbGopDriver +3115C2AC-27E1-14A9-53CD-AC4734802AD7,AmiPspSetPcdForRecovery +311FBE5F-655A-4D22-828D-373261C4C06E,WakeOnLanPortingDxe +31293F77-96BC-4780-8FCB-1ED1F9E425E3,UEFIH19SmmEnableCrashDump +312C0B23-93F2-466E-961B-6D584D0D26EE,ExpansionSlotConfigSmm +3137130C-D0A7-467E-9E8F-513816F159D8,OpromUpdateDxeNeonCityEPRP +3138C825-83ED-064A-A62A-CD13674E3F89,AppleDhcp4 +3138E8DC-B9A9-45BB-A5E8-6EBACD005E4C,TouchPadDriver +313C8DEC-DF8D-4502-92B5-1FF4883A55AE,FlashControllerNvsSmm +31401EE7-1600-437C-A11C-B1035D8E6070,PchAcpiTables +3141FD4D-EA02-4A70-9BCE-97EE837319AC,TrEEConfigDxe +314A7E73-EAF2-40F3-81B5-61FC83C468CF,EcdBoardId +314EE04C-1106-4DC6-ACBC-CF19C0DBC5CC,PlatformInitAdvancedPostMem +31519EC4-65F1-4790-B223-AA9330DD75FD,Secure96Dxe +3152BCA5-EADE-433D-862E-C01CDC291F44,EfiRngProtocolGuid +31609F3D-4C94-4FF0-B7E4-5B6CA2302DB3,GlobalAcpiNvs +316190C1-5E48-4C15-AC72-37532F3A1EC1,SystemUsbDatabaseSmm +316190D1-5E48-4C15-AC72-37532F3A1EC1,LenovoSystemUsbDatabaseSmm +316A13C6-B0CA-4CC9-8599-5415BADF1923,AaeonUartOverridePrs +316AFD2F-8F25-4642-B0CC-411F67FC0C47,AaeonPowerModePei +316B1230-0500-4592-8C09-EABA0FB6B078,SmmPcieSataController +316B1230-0500-4592-8C09-EABA0FB6B07F,SmmHddSecurity +316C608A-4429-49FC-9E2C-0B814D5EE4F3,PlatformPolicyManagerDxe +316C618A-4429-493C-9E2C-0BA14D5EE4F3,SstSpiChipDxe +31740724-5F96-48CA-AA0F-332ACA6B9A75,SpcrAcpiDxe +3175E6B9-4B01-496A-9A2B-64AF02D87E34,CpuExceptionHandlerLibNull +317BC006-9056-42C8-A1C1-92A1AABBC9EE,AmdCcxZenZpSmm +317CCC63-FDE4-48CE-BA03-D08CD45567CC,AtaDeviceDriverPei +31878C87-0B75-11D5-9A4F-0090273FC14D,EfiSimplePointerProtocolGuid +3188D183-D154-4DC3-8EC6-59804A623CCD,PCA9535Pei +319CE8BB-DA2E-4FF2-B69B-0A854146B489,SystemUsbHidParserDxe +319D0E01-0F72-4BFA-91D8-EBA049C5582F,Npce285xFlashSmm +31A0B6EF-A400-4419-8327-0FB134AA59E7,Mxm30Nbci +31A4878F-230D-4FC2-90BB-DA5F41A44B1B,DxeDebugportExtProtocolGuid +31A6406A-6BDF-4E46-B2A2-EBAA89C40920,EfiHiiImageProtocolGuid +31A8CB18-5C76-4668-839D-9FE804B419BB,CrbLastFfsPei +31A913BC-795F-4522-A28F-82A18CFB816A,SndwInitDxe +31AD0D89-75B3-4CF3-A1C2-877394EDC601,AmdNbioIOMMURPLPei +31AD1E44-9D60-4B15-B60E-8E70BE156323,UpekFingerPrintDevice +31C8F5D2-B558-41BE-9971-30ED8CB990C6,FjGabiFlashCommon10GbeRegionCtrlSmm +31CA5D1A-D511-4931-B782-AE6B2B178CD7,EfiIfrFrameworkGuid +31CE593D-108A-485D-ADB2-78F21F2966BE,EfiLegacyInterruptProtocolGuid +31CF7DDF-F02F-4783-BAA6-A087B2F83BE6,AssetIDOnRecoveryModePei +31E147A6-D39A-4147-9DA3-BEFD4D523243,SystemCdExpressPei +31E9FB14-51E2-46E9-9F81-F2CA52FCB2B4,DellDiagsSmmProtocol +31F5B262-7D9E-4FCC-9BB8-0E415D0CD748,BFGPei +31FD7EAF-80A7-435E-8E0A-3F185F8667DD,UsbCoreDxe +3209228F-94E2-4AA4-8E18-0791B7254C2F,DellAbsoluteSmm +320AFE62-E593-49CB-A9F1-D4C2F4AF014C,EfiS3SmmSaveStateProtocolGuid +320BDC39-3FA0-4BA9-BF2D-B33F72BA9CA1,AmiTpmSupportTypeProtocolguid +320E0C11-B5FE-4C20-B8A8-815A20700CEF,AppleIpAgentDxe +3212A3BC-B235-4E46-8929-CCC02F2447C9,DellVariable2RuntimeDxe +321BBE0C-3560-4BDF-8310-235CD7C173C0,RomHoleReplacementPpi +322ADD64-FB21-4564-B17F-1E4291446415,DellRadioUsbLocationsPolicy +3233B6B9-F4AC-4FE1-9021-71D0B4F0AD82,BiosMeFwLayout +3234B6D8-3517-474E-B181-DA891CBA5E13,PasswordUi +3237418A-478C-4700-B59F-768E2CCBC726,CmosDxe +3242A9D8-CE70-4AA0-955D-5E7B140DE4D2,EfiSmmCpuIo2ProtocolGuid +3243E65C-5CE3-47B7-B406-268CF8C08968,HpTimingData +32442D09-1D11-4E27-8AAB-90FE6ACB0489,SystemFormBrowserCoreDxe +3245EA7C-9209-41E7-BE2C-EB662B8C0622,FspFirmwareVersionPeim +32464FF8-EA81-444F-A0E8-B84882B84D1C,FjGabiSettingsApiItemAccessDxe +324E97B6-55FA-4F25-B40E-EE4125FB1215,IT889XDxe +325E1442-9BE1-498B-B007-BF4C38BDB0EC,FpgaInitPpi +3262D1AD-A8A8-4597-825E-DE6F167C3407,PlatformErrorHandler +326AE723-AE32-4589-98B8-CAC23CDCC1B1,PcAtChipsetPkgTokenSpaceGuid +326E7ACE-2133-1BA2-800A-B9C00ACCB17D,CpuSmmSaveRes +326E9CC6-9839-4885-B2ED-275903B668E1,SmmAccess +3273FEEA-FFA2-4EBA-A293-9F7EFDFEEF87,FanIdm +328096F2-00CE-4E32-BD0F-68B44052E463,HpUsbPowerOn +32898322-2DA1-474A-BAAA-F3F7CF569470,HardwareInterrupt2Protocol +328A35E4-F0C5-4456-A4E4-936EFDE8CEF6,AmiI2cMasterBinrary +3291E91D-C5D9-42B7-B3B1-8EC54B03F043,OemPeiSample +3297DA1A-161B-4D35-BCAC-D1597B6BDC01,CbsBasePeiPHX +329F126F-299E-4BC5-8310-179F10EB46C9,DellSmbProtocolAccess +32B8AB1B-07E3-4B42-8EE7-02902A293BCC,AmdFchWheaDxe +32C1C9F8-D53F-41C8-94D0-F6739F231011,BiosExtensionLoader +32C5DC09-E493-4E04-A388-574DEE0CEE7B,FjRandomNumberSmm +32C82722-A756-43D4-9BB5-E07E0B1495F7,DellFmpTpm +32CBA21F-F308-4CBC-9AB5-F5A3699F044A,EfiUserCredentialClassFingerprintGuid +32D2963A-FE5D-4F30-B633-6E5DC55803CC,EfiUsbFunctionIoProtocolGuid +32D4B2DD-1DB3-4AF9-91B0-FBAE6E6EA259,RtkUndiDxe +32D4B2DD-1DB3-4AF9-91B0-FBAE6E6EA25A,RtkUndiDxe +32D9116A-AF15-4976-908C-2C6E05CB789A,AmiMultiPlatformProtocol +32EA828B-523B-44CB-B7A4-7E0A2A49956C,FmacDriver +32EE5672-C9F9-4926-8228-0C4E3B0E69FE,AsusTopSwap +32F93C9E-83A0-4EE4-B66B-C704615D9895,ApobDummyDxe +32FAFCA8-0374-49BD-A090-B4B4603A50D6,PpmInitializePei +32FF59CD-0C33-48D0-A244-4BB811336403,EslUdp6ServiceGuid +32FF9F5C-56B4-4149-81A8-E748645E9551,HpSioSecuritySmm +330183C4-F848-4C88-AE5A-2248F91DF773,DellExtendedBatteryLifeSmm +3305B3F7-0ACF-49E9-9124-341760F467EB,AmdNbioBaseRplDxe +33065910-FE56-49AB-B03D-ED1AFF65B596,DeviceImageInterface +3307DD15-23BA-4546-A004-FCBCC47D4A49,SiliconPolicyPeiPreMem +330AA623-79E7-467C-81AA-DE9EE0F96A52,SmmThunk +330BE755-FBED-4F18-B9A8-495856D3D7A1,EfiCpuHotAddDataProtocol +330D4706-F2A0-4E4F-A369-B66FA8D54385,EfiHiiConfigAccessProtocolGuid +330E57C8-4E71-493F-91B9-0F7F820A1DA3,BatteryFwUpdateDxe +3316A5D0-FE16-40E2-8114-75E5724449F8,IntelLANDxe +33195652-2C4F-4B55-B6CB-63D3C38598D3,PchHsUartDxe +331BE2A7-BD90-4A81-A128-36B0B2057997,EfiPlatformTypeBuchananPassProtocol +331DEB15-454B-48D8-9B74-70D01F3F3556,UefiDriverEntryPoint +331F9815-9D94-4A26-9CD2-DE377B5E9A08,TbtRetimerCapsule2Dxe +332855B8-616E-4A50-AC7E-75A21B7FC4A1,Lnv32MFlashSmm +332A0926-429B-4624-9211-A36B23DF0389,OhciPei +332B3586-F0B4-46EE-A39C-786330E2D328,EfiFpgaHssiConfigDataProtocol +332CCFED-E5E7-49AB-820D-E34A54ED3F57,DellSmmMfgModeProtocol +333BB2A3-4F20-4C8B-AC38-0672D74315F8,AcpiPlatformPei +333BB2A3-4F20-4CCC-AC38-0672D7412345,FastBootPei +333F3A12-11DE-4014-9E53-0E15878C7268,AmdI2cTouchPadDxe +334D5254-6160-4E4A-A78C-E15D3B3B3334,MmcHost +3358F97F-63BE-47A8-89BB-ED63612E6C9F,LinUptpPure +335984BD-E805-409A-B8F8-D27ECE5FF7A6,EfiStatusCodeSpecificDataGuid +335A78E5-7D2D-45B9-B3B1-BE964E731DAB,DellFmpNvme +335B0F6A-FCBD-402A-B4BB-0C3EEDAAF9D3,EhciRouting +336074B2-2A13-46CD-B458-FD4AEBBA28A9,AmiGlkCpuPkgTokenSpaceGuid +336323C0-4BD2-4B0E-8B17-6DA1E143E220,AaeonEcSmm +3363551A-B717-4918-93B9-EBE6AFA57586,FjGabiFlashCommonMeRegionCtrlDxe +3364E8EE-91B8-4428-9FBC-1E9C5DCA398D,DellMemorySlotInfo +336CDDEA-AB28-4C4C-9F64-5FE0391FEBB8,DellAudioConfigPei +3370A4BD-8C23-4565-A2A2-065FEEDE6080,SecSMIFlash +3374B583-7A96-496E-9B8C-2BEFE911ADB7,AaeonUartOverride +337F4407-5AEE-4B83-B2A7-4EADCA3088CD,EfiHiiUserCredentialFormsetGuid +3381FC3F-8791-41E5-8871-A960A4ED24B7,MemoryInit +338695EA-CA84-4FA2-9DA8-5C4BB87905C6,XenioFdtDxe +3389A820-4A27-4FA9-ADBD-39AB18078FA7,AmdSb900PeiSmbus +338E6713-0295-4C05-A0BB-D945A4595F11,CbsBaseDxeSSP +339370BD-CFC6-4454-8EF7-704653120818,ThunderboltDROM +3399DA41-CE44-4FDD-8D32-E578381FEBE0,menu_bottom_right +339EC458-9B6A-4CEC-A47A-712873653299,StdFlashLibNull +33AE969B-E7CA-4BCD-9C4D-4531C18A5DFA,TouchDriver +33BA5130-2255-4802-9019-C875D5D66E77,OpalBlockSidWmi +33C27A86-0A39-48DA-9424-6813E5C3928D,CompalEcAutoFlash +33C27A86-0A39-48DA-9424-6813E5C3939D,A31CMFCDxe +33C27B86-0A39-48DA-9497-68A3E5C3928D,CompalPlatformHookDxe +33C6406D-2F6B-41B5-8705-52BAFB633C09,AlertStandardFormatDxe +33C69CBA-FB6B-40BA-B875-DE56D4607021,FjHddPasswordDxe +33C6B455-87A9-4C8C-A4F6-6DB508A6260E,SkipScanRemovableDev +33CB97AF-6C33-4C42-986B-07581FA366D4,BlockMmioToBlockIoDxe +33CDC56C-B1EF-4B21-87E4-225F42C67F4A,SystemProgressIndicator +33D33BF3-349E-4768-9459-836A9F7558FB,DxeIoLibCpuIo2 +33D6ABF9-6CFB-4FFE-9E68-6FC63FE60252,AmdPspIntrusionDetectionDxe +33D87F26-E58C-983F-F14C-A5FE58B10B64,AmdMemSmbiosV2PhxLpd5Pei +33F12300-FBF2-45E6-B6B7-79AF6029C7D4,CmosButtonLoadDefaultsPei +33FB3535-F15E-4C17-B303-5EB94595ECB6,SmmLockBox +340436B0-EBFA-408A-9B8B-565B1F77CF2C,Lpc47N20x +3417B225-916A-49F5-9AF5-C9C7BF937EA2,EfiMemoryMapDataHobBdat +34199FAA-81FC-44A2-9E66-56E2B18A1338,DashIoCfgPolicy +3423D855-3419-4D5D-B9EA-6C339FACBBE6,HPWMI +342414B7-0CDA-4BCD-9681-314FB865657D,MsiMeUpdateControl +343FF38A-32E2-48B3-910F-37E7FE9EF72E,MeCapsuleDxe +3458636B-9A94-44E7-BCA9-F8DFA1F5D894,LenovoSecureWipeLoader +345ECC0E-0CB6-4B75-BB57-1B129C47333E,EfiPlatformToDriverConfigurationClpGuid +346ACA3D-86AF-444E-BCB8-C56E6538BDE3,AmdCpmLpcUartPeim +346B093A-9002-4E99-A2F2-27A16C3DCD89,OemModifyOpRegion +3470CCF0-6054-11DD-AD8B-0800200C9A66,EzFlash +347B85F0-E917-4E74-85BA-F494071EEE52,FchSHSataD3ColdSmm +347CBF13-9C36-4E36-91F9-5BC76E5042D1,MacAddressPassThrough +347CC502-EB6C-44A0-9498-605888C94E0D,HandleStatusInSMM +34891F9C-54DA-44EA-8313-CAB8AAB1BD0C,FchProm21SsdtDxe +348C4D62-BFBD-4882-9ECE-C80BB1C4783B,HiiDatabase +348CA223-637B-4430-BAF3-1CE5D322B3FD,SetupBoot +3496A19A-2E99-41BA-833E-0FDE2EBF2A55,AmiFastBootProtocol +34989D8E-930A-4A95-AB04-2E6CFDFF6631,TcgPei +349BABBE-7159-4E58-9462-0EEFD8EAFB86,SocCrashLogAgent +349CF818-C0BA-4C43-929A-C8A1B1B3D255,InternalTpm2DeviceInterfaceGuid +34A66FCF-8F26-4F93-81E3-918F5F717DE3,FjS5WakePei +34B78650-B0BA-428F-87B1-A1AC762F7FBF,EfiHeciRuntimeProtocolGuid +34BC2673-256B-4BE2-9C4C-025EE484ACAE,DellXhciPei +34C8C28F-B61C-45A2-8F2E-89E46BECC63B,PeiVariable +34CC6167-7AE7-403E-8AB2-23837F398A30,PlatformInfo +34D51EB9-76DB-4CAF-94AE-934856E895F6,LenovoAtpDxe +34D8C727-FA83-4FDE-BF51-02426E4533DB,FjGpnvPei +34DF9766-19C0-44BD-BA4F-D2006A0C3DA5,CbsSetupSmmRPL +34E5798E-F44F-4526-A08C-39BCA6E8D7D5,EarlyProgramGpioPei +34E74B1B-8794-4402-AA43-99B5249B1CFD,DellSbSmm +34EB9E3F-9318-4CE7-99AD-9E7289038C52,WifiBootDevAuthList +34ECEADC-9229-44D1-85B1-B84071A13187,MebxDisplay +34F60DB9-D3E4-428B-B770-3541C8E05112,SgxConfig +34F85EE2-93C2-4481-B710-D3490CCA6333,AsusAcpiRamSmm +34FB0259-BD92-41CF-811B-17C9AD60518A,RemoteWakeUpPei +34FB5A1B-E3CD-4893-9403-0A39BA62FDA0,SvSmmSupport +35034CE2-A6E5-4FB4-BABE-A0156E9B2549,PlatDriOverrideDxe +350F9ED6-206C-4288-BDD1-8BAD8C053112,DellServiceApp +3513C4E2-06D6-4921-9C2B-E938777BA79E,EblCmdLibNull +35169D2C-2426-45CC-8AF4-5B618BC9A00A,EfiHeci2PmProtocolGuid +351D2427-262C-4A0B-874C-23703B4AA88D,AmdNbioBaseZPDxe +35269008-CF21-4A7C-A58C-5CBF2BDE4AA6,EmulatedEepromSmm +352C6AF8-315B-4BD6-B04F-31D4ED1EBE57,CbSupportPeim +35302F55-51C3-40DE-B68F-1EF144CCF1E8,LegacyUsbDxe +3538C287-F7D0-4C2A-BE3C-2D7E27A57A3F,BmcThermalPei +3542FFD8-ABDE-45ED-9847-0719EDA139DD,AsusAmdCpustringDxe +3543EC9D-4B27-4FA9-ADBD-1DE118078FA7,AmdSb900Pei +3543EC9D-4B27-4FA9-ADBD-1DF118078FA7,AmdSb800_PeiPei +3548423A-2B2C-4393-9826-B202959D2362,AbtCryptoDriver +35574ED4-E011-4F40-9FEC-6941C39CB549,OemPDFWUpdateFlagClean +355FBDA9-4572-49BC-95B9-545E71DEF9F9,FpgaSmm +3561188E-D848-4406-8F11-267097132BD5,FjLvdsRTD213xR_Dxe +35628CFC-3CFF-444F-99C1-D5F06A069914,EfiDevicePathPropertyDatabase +356471B1-B483-42AE-B6E7-3B2EBAB14E15,ServerCommonTokenSpace +356C2B12-3124-4451-BF66-B502D88A0074,XhciDxe +3578F929-7184-4275-B941-AAA906C8854F,WlanSuplct +357970A0-FF5D-4C36-AF68-0A29A46FF2D5,OemAfterMemDxe +35868FB1-4E8F-4C4E-93B4-F229CD89A927,PxeDriverRt +358E9F0F-DDC0-42D1-957B-DBF11497ECD8,EcCommunication +35935949-1E07-4FDE-B2C2-8448E074322A,FjPasswordInvalidHandler +3593A0D5-BD52-43A0-808E-CBFF5ECE2477,SecureWipeLoader +359A348A-CAAB-43D0-8E30-FF875929D531,PchIoExpanderPreMem +359E12F6-0941-40BF-8AD9-BB537FB10539,VariableSmiExportHii +35A19BFF-1849-477E-A589-7B44E9D89CA5,TypeACh +35B61F25-ABF2-4A11-A2D4-239CA475349C,AmdCpmVRMOverride +35B72237-3926-CF4A-A7F3-1449F9E0E4BD,EmuSimpleFileSystem +35B898CA-B6A9-49CE-8C72-904735CC49B7,DxeMainDxe +35C0C168-2607-4E51-BB53-448E3ED1A87F,PciBusNoEnumerationDxe +35C25B5C-BCD6-4BC5-940F-A27CD8CCC2C3,FjGabiSetupSettingsHandlerSmm +35C33F32-8C61-452D-8D14-9B5F53A2DFC0,SmmSpiInitilized +35C3FC82-1767-40E9-89A7-9A1CF23A8EF9,AaeonPowerModeSmm +35C5AB3E-B77A-450C-8854-159B2F0D32A5,Ich7MSmmDispatcher +35C84FF2-7BFE-453D-845F-683A492CF7B7,OvmfTpmMmioAccessiblePpi +35CA62F0-994C-40EC-8A94-ACF412811068,FdmInitPei +35CE663F-292D-4763-80F5-05C933F6EA15,RequiredUefiVarPeim +35D13CFD-0BAF-11E8-AE0A-B8E8562CBAFA,AppleHpetTimerDxe +35D180FA-6ADD-482C-B6EC-B59C49B53208,LpcSmsc100x +35DE0B4E-30FB-46C3-BD84-1FDBA158BB56,EdkiiPeiStorageSecurityCommandPpi +35E13ECA-DD98-448E-BF2B-4DD589D91CC8,SioResetSystemDxe +35E417A9-EE0B-48DC-A948-75F8AB93C933,RuntimeAcpiPei +35E7A725-8DD2-4CAC-8011-33CDA8109056,EfiJsonCapsuleDataTable +35EC7319-053B-45B8-8523-8666A662122C,LogoDxe +35ED21F6-C09A-4CB7-BF60-B5B85500B51E,SystemAudioDeviceDxe +35FF21BA-8DB0-48B4-A6A7-42440CE1DD7E,LegacyInt13Hook +36164812-A023-44E5-BD85-05BF3C7700AA,EfiFindFvPpiGuid +36232936-0E76-31C8-A13A-3AF2FC1C3932,AmiDebuServiceProtocolGuid +3629DDB1-228C-452E-B616-09ED316A9700,EfiPaddingNoneGuid +362C7275-4D8F-4607-8D8F-28893A8ACD60,EpuHwModePei +363037B4-1E19-4AF1-AA61-6FC8C01A427E,BoardUpdateAcpiDxe +3631BD9A-25E4-4B67-8D22-EFBB00ACE812,MAPS_SIO_InterfaceSmm +3635498C-4069-4D48-A26D-160941C0026D,DeviceFwUpdate +363E0444-DF24-4598-87D6-0A8BB0B31FCA,CommonElogSmm +36544866-6D93-7A48-88FB-669582D2516B,ApplePlatformInfoDatabaseDxe +3666DBCF-D79D-44C6-82B2-76F6383CA8AC,FjDfci +366DF820-5D6D-4884-9611-E3E595090D9E,TpmFmpUefiDrv +3672557A-06A7-43EF-60C3-1964F3DD1198,SmcOutBand +367712FD-6C5A-4600-BEA2-9A1F81AACC08,MiscGaIoPeim +3677770F-EFB2-43B2-B8AE-B302E9604882,AmiTseEventBeforeBootGuid +3677D529-326F-4603-A926-EAACE01DCBB0,EfiPciExpressBaseAddressGuid +36847262-75FA-4554-ABAB-CC02DF6845D7,RtkWLanDriver +368A32F1-90BB-4C37-BE0A-1FFD754AB42E,TilePei +368B3649-F204-4CD0-89A8-091077C070FA,AcpiPlatform +368CDA0D-CF31-4B9B-8CF6-E7D1BFFF157E,EfiConsoleLock +36914497-3E9C-4745-A7E0-44058E0A9121,IncreaseIdleFanSpeedSmm +3698D2B0-E727-4537-A636-A8770736ABFB,GetHostByDns +369A5862-06DE-49C6-A2A5-17B8A9664984,TouchPad_Synaptics +369BDF2F-D89F-4B18-94A4-6314220A1A61,RhProxySsdt +369DE372-AB36-4CE1-8E45-8806B76DD70F,PspResource +36A7A938-3E62-47D6-B395-3D3FE135F3D1,OneTimeFlagPeiInit +36AD1BAA-241A-4316-811F-220CEDCF15EA,AutoTpm +36AEBB56-1F8B-4BC1-8EFE-4085A5D4C40A,DellLegUsbMemSmm +36B37F21-9D04-44B5-95EC-4DE4CB2FE6FB,menu_locked_selected +36BF2BBE-78ED-49ED-88BB-9AC41630D4A8,DellRcaPkgBIOSIQDxe +36BF4038-C902-428E-96EB-DFE3B468167F,FchSmbusDxe +36C513EE-A338-4976-A0FB-6DDBA3DAFE87,DefaultdbtFile +36D7B17A-9D4C-4B62-8D3B-D4B657F7C1A6,OemInitBrightness +36E835BB-661D-4D37-8DE5-885325DAE910,RomCacheEnablePpi +36F36A89-7AC3-4A09-9921-890E2C9D80A8,FjGabiNvramSmm +37087B94-EF41-4977-93E2-3F6ADFDD06E1,LenovoSplashDxe +370C1DBF-9606-4FCC-B481-1388D6ABA12E,AsusSmmService +3713AB0F-97A0-44AC-8ACC-F2B14527F955,TccPolicyUpdateDxe +371FA4B8-8042-4ED6-ADA7-A987BD2CDF0A,LenovoSystemImageDisplayDxe +372079F5-0070-4907-922A-4C18A1F562A2,CbsSetupDxeRMB +37215D67-D2D0-486B-977D-B5BD4DC38010,Platform_AcerPortingDxe +3727E1A4-A28C-4792-A102-ABB2752CF045,AaeonGpnvDxe +37287C8B-DC93-45D5-9AAF-3CD2E906B12B,DellErrorHandlerSmm +37287C8B-DC93-45D5-9AAF-3CD2E906FFFF,DellDefaultBootListSmm +372CC32F-5C3A-4C56-8E20-9F06AC89E8D6,AcerPortingSmm +372F8C51-C43B-472A-82AF-54B5C3234D7F,CpPcBiosIdFile +37317709-3B19-446A-B184-63027E14AF01,DeviceGuardProtocolOverride +37347E20-5C3D-47B7-B233-1E353A7E0145,AppleHttpClient +373B03B3-D322-423D-94E6-2674A7215BE3,FjGabiFlashCommonDeRegionCtrlDxe +37499A9D-542F-4C89-A026-35DA142094E4,EfiUartDevicePathGuid +3749AC96-24B8-44E2-B895-4FABEC4CF40F,ErrorLogWmi +374CEED1-AD67-40C0-B2C9-3DBCC5A5D30A,PwByPassSmm +374DE830-81C5-4CC8-B2AB-28F0AB73710B,SmmCpuFeaturesLibStm +3750F0F4-480B-4FCD-A153-62A4BEB5D114,CrashLogPei +37542F9C-24E8-4834-8B1D-7C3E0645245D,EcMpmSmm +375EA976-3CCD-4E74-A845-26B9B324B13C,EfiUxixSystemConfig +3770BCE9-F09D-4446-9533-7948414F6CC0,FjGpioGHOPei +377766A3-A6D6-444B-B98F-012694C28653,SerialPortTypePei +377C66A3-8FE7-4EE8-85B8-F1A282569E3B,EfiPlatformIdeInitProtocolGuid +377C79B2-1A40-441E-B6F5-A170E3753725,LenovoTpmMeasureDxe +3780B594-32A4-4593-B8CE-8A3F404F61F4,PlatformToDriver +37813270-948F-4096-A2D8-98D321381F0C,PasswordInterfaceCoreDxe +378D7B65-8DA9-4773-B6E4-A47826A833E1,PcRtc +378D7B65-8DA9-4773-B6E4-A47826A833E2,PcRtcSmm +378DAEDC-F06B-4446-8314-40AB933C87A3,EfiMmCommunication2Protocol +3792095A-E309-4C1E-AA01-85F5655A17F1,EfiSmmAccessProtocolGuid +3792FF94-8614-45ED-902B-1207BF1490A8,PrintThunk +37A01080-2346-4A54-9900-D22B7B687C22,SmmPciRbIo +37A0D020-CCD1-11DD-AD8B-0800200C9A66,SystemIdeAtaAtapiPassThruDxe +37A104B0-2FD1-4288-83BF-CEB17768F40A,LenovoSmmKbdConfig +37A73E40-4E38-4E36-9045-E9FCBCB73BFE,FjRecoveryFlashDisplay +37A79FE7-6693-4EEB-8567-9B2C3E05F2F3,FjIntrusionSmm +37AC8831-8051-4465-754C-E992AE1400A7,HpRtxXhciDxe +37AED342-1F52-44A3-8DBA-EF2BDDF471D5,GabiSettingAbstractionSmm +37AFCF55-2E8C-4722-B950-B48B9165C56B,LenovoSetupMainDxe +37B1100E-4C66-9B44-D736-9BBBF169CE2F,xGbEI2cMasterDxe +37B30BC4-873C-4541-8B65-DEA370B674DD,WMISwSmiShp +37CAA14D-5072-4753-ACB2-CADA3E99A9E7,KeyBoardIdm +37D3E8E0-8858-4B84-A106-244BB8CBFDC3,LenovoLoggingVariable +37D43B2A-43A0-4AEA-AB79-E4FEF53C0F12,MicroCodepointerGuid +37DA43A1-BB9A-4805-9B92-0BDE11191149,ACPIRAM +37DCBC92-179C-4786-A2C7-732E0F3F24DB,SystemSecureFlashFvHobPei +37DDC7E9-7C1D-4E1B-B2CB-4ED5D12527B3,LenovoMePciUpdate +37EB4355-1FC5-42E6-9039-D575D5051C2C,HpFlashMeDxe +37ECDF24-8453-476A-AB58-F4CF8BFE6742,LenovoPhxGopDxe +380D2287-A41F-4702-98DF-EF8857A5CDDE,PepOvrDxe +3812723D-7E48-4E29-BC27-F5A39AC94EF1,ItkDataVarGuid +38133149-14F1-4179-B187-EFE7D3F7479D,FjGabiFlashCommonMeRegionCtrlSmm +381CE2A5-C603-48D2-9515-9B4141F4FDE7,AbtDebugDriver +3821290E-B8DD-4821-8182-0361DE51609D,AmdCpmOemAcpi +3822B866-E122-43BE-877D-4AC7729D6E78,DellNbThermalProtocol +38280505-4324-6130-730D-A0952B0F329E,S5MaxPowerSavingsPortingSmm +382F560D-17A9-4887-BD9C-EB439C1CC482,RaidDriver +38321DBA-4FE0-4E17-8AEC-413055EAEDC1,EfiLegacy8259ProtocolGuid +383269A3-4718-425A-A130-B35E804B865C,PlatformSioGpioInitPei +385A0223-C20F-4920-84DE-A01FC911E922,DBGP +385A982C-2F49-4043-A51E-4901025C8B6B,PrePiExtractGuidedSectionData +3863C4B4-AD58-4383-AB89-0E0B768DDB70,AplLayoutParsing +3868FC3B-7E45-43A7-906C-4BA47DE1754D,EfiSmmFaultTolerantWriteProtocolGuid +386A4B1C-DDE4-4FC5-9B03-9C928FCC6FD2,gear1 +386EB7BA-6344-44E8-985C-3978FD47916B,DellTpmdxe +38705437-5697-4715-85C6-29933073C212,SystemBoardPpi +387477C1-69C7-11D2-8E39-00A0C969723B,EfiSimpleTextInProtocolGuid +387477C2-69C7-11D2-8E39-00A0C969723B,EfiSimpleTextOutProtocolGuid +3876F590-7AC6-4E0C-82EF-7B9A8A7B8DC9,GpioPolicyPei +38802700-868A-4B4E-81D4-4F1BDCCFB46F,EfiExtendedSalSst +388278D3-7B85-42F0-ABA9-FB4BFD69F5AB,EfiBluetoothIoServiceBindingProtocolGuid +3885474D-8395-4AAB-8AA4-3743CE287646,FnWinKeySwap +38857C30-D9B8-4CBE-82C0-F9D8020CE5E3,PostCodePei +38871BF0-C64A-4896-B8E4-62D4850C7E68,DellOemSxSmm +38871BF0-C64A-4896-B8E4-62D7750C7D68,DellAcLossSmm +389244DB-3D6E-4E50-835D-5A775A325D89,LenovoMx25L64XflashPartDxe +38965BB5-8097-40F5-B742-8CC14A649B64,AmiPeiSbCustomPpiGuid +389CAF8D-998F-4AD8-BFAC-20BE4AD9804A,DellAuxMac +389F751F-1838-4388-8390-CD8154BD27F8,EfiFirmwareVolumeProtocolGuid +38A0EC22-FBE7-4911-8BC1-176E0D6C1DBD,IsaAcpi +38B8E214-1468-4BB7-95B1-74591E4C6E1D,AttemptUsbFirstHotkeyInfoHob +38B9F5EC-EB18-4CD4-BF13-F072659F4002,ExtendODMDxe +38BA01CA-B1FE-4DEA-8340-0963EB56E98A,AmdNbioIOMMUDxe +38C03ADC-2115-4FED-8002-714906AFBBF6,DMBM +38CDD10B-767D-4F6E-A744-67EE1DFE2FA5,PeiTxtMemoryUnlockedPpi +38D51B46-D275-475C-A951-80A7E1CF38B1,AmdCpmSensorFusionDxe +38D65EC3-8F39-4660-B8A6-F36AA3925475,AmiBdsConnectPolicyProtocolGuid +38DCB38F-D51E-11E3-9129-047D7B99E097,ProjectServiceSmm +38DDFE8F-8991-44AA-9889-83F4918465B0,EfiGpioOperationProtocolGuid +38E7E3DB-1211-4EFB-8709-9E41AB2810D1,FjHiddenAdminPage +38E8BEF9-E526-492B-990A-517428B37D06,FmpDxe +38E93FAE-C5F4-4700-940D-DC10E2FDB6C0,OemPeiRuntime +38ED731E-6A1B-441B-BF97-A7854C4A2B7F,EgsFhfPolicyOverridePei +38EF2B8B-CF3D-47E2-97E3-557115E43985,DellDiagsSbControlDxe +38F80EEE-FFA3-417B-ABF1-F713399007E8,WufuDxe +38FAB09C-2851-444C-9A43-F82725E4671F,AcpiDsdtDynamicCpu +39045756-FCA3-49BD-8DAE-C7BAE8389AFF,Tcg2Dxe +390712E4-0EDC-447D-9492-3FBC996DD044,H19CapsuleSystemFirmware +390C4486-C026-4083-8869-D8F260A49760,OemSyncSetupRN +390D8CDC-F738-46D9-82E4-BB0DCEEE3F9D,UsbBusSmm +390F84B3-221C-4D9E-B506-6DB9423E0A7E,ShellHttpHii +3911946A-7B2F-43AE-86BE-8EC5A8A356CD,AmdPspPeiV2Brh +39136FC7-1A11-49DE-BF35-0E78DDB524FC,EfiLegacySpiControllerProtocolGuid +3915886B-D833-4C23-B3ED-1453CCE7C5F2,IioCfgUpdateDxeLightningRidgeEXECB2 +391626DB-3CEC-4339-A3D6-9CDFF4690E12,PrepareWhiteListSmm +391B853F-F488-479B-A3D6-870766C7A38F,CryptoSmm +3920405B-C897-44DA-88F3-4C498A6FF736,EfiSmmIchnDispatchExProtocolGuid +3922DFF9-C892-45EB-A4CC-4F4EA2FCF05B,AicCcgFwUpdate +3924C33A-125E-40A8-8450-38C6671E021D,AmdNbioPei +392744DA-DF68-4C3B-966B-F20F0F47BC23,acer_SetupUtility_interface +392D4DAE-D3BD-4CAF-B1EF-57A78B6E39BC,NVMeInfoDxe +392DE324-E962-4A7A-B62D-10414AF6B9C8,HousingMonitoringDxe +39342586-4E0E-4833-B4BA-1256B0FFB471,FmpDxe +3935B0A1-A182-4887-BC56-675528E78877,SetupUtilityApp +395B0181-C9B9-4E2E-A82E-6B0D027119F9,AmdCcxZen5Smm +395BAA99-E4FC-4821-ACC3-B56E5246E066,RestoreCbsDxe +395C33FE-287F-413E-A055-8088C0E1D43E,SmmRsTableGuid +3961B4D9-1385-43F7-B9C8-6C3A389FBF99,MobileDiag +3962DEB5-FDF6-4829-889C-D544918E84D9,SmmLegacyRegion +39640BA6-7AB1-4D97-9FE2-1AB609C170FF,FjFlexIoPei +396C7B44-8526-42AE-B5D4-3F0AFD89017E,H19MPMSmm +396E583B-D2DD-45F6-86E8-119885777CDE,AtaLegacySmm +398262C1-5165-4725-87FC-BB786A972582,IchPowerButton +39882267-CE96-4F37-A3EB-00B03BA4FC55,EcSecureFlashSmm +39968AEF-54B2-42BF-8E3F-DF0B70A49356,OemGigaLanDriver +3999379D-F9CB-4EF2-BD0E-F241FF804628,RTS52xx +399A229D-F654-4CEF-9ED3-6FC3C992E311,PciDxeInit +399A229D-F654-4CEF-9ED3-6FC3C992E39C,PciDxeInit +399CF3A7-82C7-4D9B-9123-DB11842986D3,DpcDxe +39A349AD-0AFA-54E8-CA0D-7D6EA1E29567,TpmSmm +39A7FADC-9A24-4553-8CBD-9B72B24C22FD,DellPs2Emul +39AB0D02-C244-40DC-B391-5A6EC2CCFC1C,FidoDxe +39AB7B23-814E-4289-9BD9-67EB025C35DF,PowerManagementDxe2 +39B3CE2B-82D0-4C7E-B949-D5E65181B98A,IshFwLayout +39B68C46-F7FB-441B-B6EC-16B0F69821F3,EfiCapsuleReportGuid +39B7902B-2377-4F73-9835-B35128ABB8D1,AppleUpdateMTRR +39B89EF4-AE05-4FD4-A59E-C2BADB2BE732,I2cHidParserDxe +39C28A86-9097-48DA-B424-6C13E3D391FA,CompalEcDxe +39C28A86-9197-481A-B424-6C13E3D391FA,CompalEcSmm +39C2AE2A-33AC-32EA-3CA5-9B12EA564540,AcerToolsProcess +39C64B04-91AB-4D4A-B343-077A565B6089,FjInternalUsbConfig +39C7942C-C272-4912-9FE4-57F695CF5442,AmtBoot +39C8FAEE-FBEE-41A3-9282-123F18C48CD9,BroadwaterMemoryInitPei +39D1EDC0-C9ED-4663-90DB-7457FF0548C5,AmiErrorHandlerMain +39DE9293-5BD9-4728-827E-1242F3F9BE3A,HpAmdTbtDxe +39E35910-CA97-4851-811B-303822DA9036,AmdMemFp11StxhDxe +39E4761D-FF39-4603-B7A6-B5A5CEE1C9F2,Lily_RTLWlanDxe +39E8CA1A-7A69-4A73-834A-D06381933286,UsbPei +39E8CDA1-6A35-4CDD-A902-D1A795F70380,AmiResetTypeHob +39F5FC8B-F34D-4256-8689-DA3A44580544,DellNbEcSmm +39F62CCE-6825-4669-BB56-541ABA753A07,EfiGraphicsInfoHobGuid +39FD1631-64CB-410C-874D-240F88AED5F1,IGD +3A05D1CE-E283-4738-88C9-D152F335C0DC,MSIFreeDOS +3A09E64D-08A9-42D5-8234-1127E6AF05EB,SioPowerButtonOverrideSmm +3A18A5AF-F25B-42EE-8606-8D30A974916B,PasswordEncodeSmmProtocol +3A19FBFF-AB92-4004-AD2E-F769F53AAE63,ApobRplPei +3A29DD19-2C84-4A70-9A01-FBDDAFFB6461,DellMemoryS4 +3A2A83F2-98AC-4A8B-BBBC-DDDCC655A0D6,FchShastaDxe +3A2AEC67-77B8-40AE-9281-03519C9E7F08,LenovoAoacSmm +3A2B9049-C351-4556-99B0-8B0A9BE9981A,PlatformDiskDxe +3A3300AB-C929-487D-AB34-159BC13562C0,PchResetCallbackProtocolGuid +3A35EE58-8286-4F00-9A5B-1B6AB7680815,amiFVhoblistguid +3A3817E2-FB69-4FBC-834D-AEE6A9B14133,AmdCpmFwMessageInfoPei +3A4044D2-F614-4124-A772-207BCDBE3DB0,DellSbServicesDxe +3A4D7A7C-018A-4B42-81B3-DC10E3B591BD,UsbKeyboardLayoutKeyGuid +3A4E4376-4871-4B0E-A02F-ED36F2AECD00,AmiCsmVideoPolicyProtocolGuid +3A4F8687-0AF0-4F39-87CF-8A2DE97AB3DB,PasswordMgrSmm +3A53114D-5673-4DD9-B5B3-CB72C347669B,BFGSmm +3A61FD45-69A0-42AD-B261-24DA451BF442,ForceRecovery +3A666558-43E3-4D25-9169-DB81F5DB42E1,PKeyFileX509Guid +3A6A1473-13E0-4795-BA9F-22891277D74D,HdpEraseUnitAppDxe +3A7AA63A-88B9-410B-80C0-C97F146B6DF8,FjUtilSmm +3A829D04-3962-42DF-9137-B1D354AEA4AB,OemDxeGetBoardData +3A84B1D8-77B9-4786-8C06-C97009DCD5C1,AmdLegacyInterrupt +3A885AAE-3E30-42B9-A976-2F1F13BD7015,SecurityPkgList +3A95AD68-D735-418A-AF10-5AE516555994,AaeonLanByPassSmi +3AA7FD11-CC5F-11EC-95E0-E02BE9424581,DellLegacyBeep +3AA83745-9454-4F7A-A7C0-90DBD02FAB8E,BdsConnectDriversProtocolGuid +3AB14680-5D3F-4A4D-BCDC-CC380018C7F7,EfiDiskInfoNvmeInterfaceGuid +3AB38776-01BB-4A17-BC40-829BFF8F8DA5,FjLanFlexIo +3AB6529E-6F90-4863-AFFA-F5BA08DEA9AA,SbBeepLibPcAt +3AB85907-33CD-4D6C-93A5-9BE7E579BF95,FjNetworkServices +3AC66273-9F97-41B7-9AAD-5D781DA0B8A7,DellVideoDxe +3AC97E05-F217-4EBD-B134-8FDA26E85769,DebugDxe +3AC9D717-A920-4BB2-8EC8-F235094C7E50,CpuInfoSetupUtilityDxe +3ACC966D-8E33-45C6-B4FE-62724BCD15A9,AhciBusDxe +3ACEB0C0-3C72-11E4-9A56-74D435052646,TlsDxe +3ACF33EE-D892-40F4-A2FC-3854D2E1323D,EfiPeiCapsulePpiGuid +3AD722E7-8AD7-4ED3-A118-85966387DB07,SecureWipe +3AD9DF29-4501-478D-B1F8-7F7FE70E50F3,EfiUdp4ProtocolGuid +3ADF2D98-695A-4E7D-BE98-58314536D2E8,SimplifiedChineseDxe +3AE3D6F0-6483-45D6-9395-303C9789208D,TrEEConfigPei +3AE4CA4B-B55B-4C11-8FAC-7C95D7423F68,BiosGuardInstallGuidSmm +3AE7DCC4-D073-41EE-8D9B-85C38BC7878D,PowerOnRobotDxe +3AEE139D-EDC8-4599-BABC-508323B5D4A3,TpmEsrtFmpUpd +3AF6A731-3E9A-46A8-910D-DB4ECF37464D,InitXnoteSetupHiddenMenuDxe +3AF7320E-DE0E-408C-AF25-1C00E4AF2AD2,WyseThinClientSmm +3AF9647D-C46B-11E4-AA1D-B8E8562CBAFA,ChunkManager +3AFAA9D7-4A0C-4AAA-8C09-05199B22428C,OCMR_Setup_IGD +3B0673A3-5197-454C-BA76-E2D0C8C48EFD,GenericElog +3B0CF843-5A4D-41D7-B42E-123B3084CF88,SmmSpdAccess +3B1DEAB5-C75D-442E-9238-8E2FFB62B0BB,UefiPxe4BcDxe +3B1E4B7C-09D8-944F-A408-1309EB8B4427,EmuThreadThunkProtocolGuid +3B24F79D-91A0-46FF-BE29-458AE211FAC5,KbcEmul +3B286D06-DED4-441C-B4E4-444B50AA73BD,WifiBtDxe +3B2E5712-7F64-4E6C-9D18-63A6867CC744,AmdSocFp7r2RmbPei +3B37B724-4AF7-4A35-97B3-D2FB8F4F563C,DellStopShipConfig +3B387BFD-7ABC-4CF2-A0CA-B6A16C1B1B25,EdkiiFpdtExtendedFirmwarePerformance +3B3B7B6F-A2DE-4F1E-9B84-C6DDC1B36D4B,OemSleepSmi +3B3CB022-2614-4994-878E-C738CE85F6ED,ApobDummyPei +3B3EE27E-9BEF-463F-B03A-A5C9A098B7B5,CpuOverclockingConfigGuid +3B42EF57-16D3-44CB-8632-9FDB06B41451,MemoryInit +3B43161F-AEB4-43EC-9E1B-8050171B4899,BiosGuardRecoveryHook +3B4514C2-D098-404C-B1DC-D71AEACA4E96,AmdMemoryHobInfoPeimShp +3B462A2C-C75E-43C5-AC4F-D4AF0D5E002E,AmdFabricStxKrkPei +3B4D59EC-DFD9-4EC6-BB8A-E0FE2B4264A0,PciDxeInit +3B4D9B23-95AC-44F6-9FCD-0E9594586C72,BdsLibStringPackageGuid +3B6686BD-0D76-4030-B70E-B5519E2FC5A0,EfiCapsuleGuid +3B66F206-6386-4117-A7FD-F5B843A26A6F,HpNetworkFeatureByteKillDxe +3B68E4AC-78DC-4198-B5B0-9F341E503B7D,ProjectSMI +3B6A1473-13E0-4795-BA9F-22891277D74D,HdpEraseAppScreen +3B749932-2DE6-4021-A639-5753536A4FCF,AsusSensor +3B869FD8-6D10-4BA3-94D9-8966F763B3FB,HciDxe +3B897E94-4864-416B-8353-9479325497AC,OemDxe +3B8C8162-188C-46A4-AEC9-BE43F1D65697,EfiFwDisplayCapsuleGuid +3B95AA31-3793-434B-8667-C8070892E05E,EfiIp4ConfigProtocolGuid +3B9AEC47-FC79-4CA1-8F53-CFBA75DAA6FB,SchenkerSetupPei +3BA7E14B-176D-4B2A-948A-C86FB001943C,EfiErrorHandlingProtocol +3BB37EC4-82E8-4C84-AAA5-1E0BCFCDA6FD,DellFmpFtb +3BBCB209-26C8-4BA9-AD25-B95B45A04D26,BatteryState3 +3BBF8B1D-4B2D-8602-6CC2-C781BACEBAC8,Pca9535aDxe +3BBF8C98-7FE5-4728-AD52-1E07E571D610,PlatformWrapperPei +3BC1B285-8A15-4A82-AABF-4D7D13FB3265,EfiBusSpecificDriverOverrideProtocolGuid +3BC1C867-2274-43F8-A4BA-939A5BD6D473,DellBlockIo +3BC1F6DE-693E-4547-A300-21823CA420B2,PeiUsbControllerPpiGuid +3BC2BD12-AD2E-11D5-87DD-00062945C3B9,CpuStatusCodeDataTypeExceptionHandlerGuid +3BC42C6D-ABEC-41BA-8CCB-D8E0EF1CEF85,PCHPolicy +3BCA86E6-FFDD-47F8-9E76-0D7E1706F6CD,ModernPreloadDxe +3BCE2765-74D9-4FE2-9FEE-E579C06F736B,UsbOcUpdateDxeSierra +3BD2A492-96C0-4079-B420-FCF98EF103ED,EfiCertX509Sha256Guid +3BD2ED18-9D72-4208-9D8A-4BE274E6ED69,CapsuleUpdateApp +3BD2F4EC-E524-46E4-A9D8-510117425562,EfiHiiStandardFormGuid +3BD61419-4BB8-4921-92C8-BA84A7A3591F,ResetDateTimeDxe +3BD930FD-F823-4948-8691-98E6FE36ACE2,EfiDebugMaskPpi +3BEB5ABD-5BE5-40B7-B9D8-4026E3D6D6AE,FjUtil +3BEB6B06-09CE-4386-8884-F323ADD04F1F,GlobeTile +3BF4AF16-AB7C-4B43-898D-AB26AC5DDC6C,SecSMIFlash +3BF66866-3F8B-4CD8-B74C-B994111F535F,FfsIntegrityCheckDxe +3BFFECFD-D75F-4975-B888-3902BD69002B,MeGlobalNvsAreaProtocol +3C094B02-9797-495E-8CA8-940371396A08,FjS3SaveMem +3C0D6860-7396-488A-BF52-2D8647D35B28,MeOptionsSmm +3C0ED5E2-91EA-4B94-820D-9DAF9A3BB4A2,DmarAcpiTable +3C0F72B5-D51E-40C8-90F1-5A923E0D1F24,TpmResiliencyDxe +3C14C099-3143-46EF-AF18-DE4AD2C3A799,SystemHiiImageDisplayDxe +3C1ABB6F-5A5A-4E48-BDF9-5DEDC58E05AB,FjGabiFtsSystemDataSmmBin +3C1DE39F-D207-408A-AACC-731CFB7F1DD7,PciBus +3C206312-B8B6-496F-BCFA-2F645EF4ACDE,TransparentUnlockWmiSmm +3C234470-69D3-42E1-B323-C809300F3925,EfiPeiPlatformTypePurleyLbgepdvpPpi +3C23ED00-56B9-4B3D-96B6-44DB8FAF2E6B,BCVersion +3C2A0F82-36DF-4702-B0A3-5A5B0A0F89C1,OemSmm +3C33A10A-917E-4925-A2C4-8B545BF10A82,HddPwSmm +3C33FEA3-EAD2-47F1-98B3-4F10254966F5,SystemVariableHookProtocol +3C35B99D-D4B7-4885-ABD9-2BEA4B9F3A01,ASUSFTMDXE +3C43AFDD-570F-449B-A7B6-5F3315D73054,FjUsbInternSwitch +3C4836AE-B24B-40E3-B24B-9448ED095BFE,SpiDxe +3C4852D6-D47B-4F46-B05E-B5EDC1AA430A,TdthiProtocol +3C485EA4-449A-46CE-BB08-2A336EA96B4E,EfiCk505ClockPlatformInfoGuid +3C4AA94C-713C-45E9-B25C-83DAED1780AC,LoadEFINetworkStack +3C4FC0F3-D0FD-468C-9825-5EEA0E85355D,KEMaSMBIOSDxe +3C5766E8-269C-4E34-AA14-ED776E85B3B6,EfiCertRsa2048Guid +3C5C631D-7995-4415-8B16-9F4A8AD36FCF,Int10ToSmi +3C5C987D-7996-4415-8B16-9F4A8AD36FDD,Int10ToSmiDxe +3C646132-ED96-4EF0-93ED-B209AE6E727F,ManufactureDxeToolBin +3C699197-093C-4C69-B06B-128AE3481DC9,EfiAcpiDescriptionGuid +3C7200E9-005F-4EA4-87DE-A3DFAC8A27C3,EfiShellDynamicCommandProtocolGuid +3C7BC880-41F8-4869-AEFC-870A3ED28299,EfiHeciProtocolGuid +3C7D193C-682C-4C14-A68F-552DEA4F437E,PcdDataBaseSignatureGuid +3C80727F-6846-41BC-8E54-0107C10ACDF0,FchI3cHciDxe +3C887050-42C8-4958-A08E-495D910CF515,InstallSdevDxe +3C8B9970-870A-11E4-B7C6-B8E8562CBAFA,ChipsetGpioDxe +3C8D294C-5FC3-4451-BB31-C4C032295E6C,IdleLoopEventGuid +3C955AA4-41DC-4FD2-B0E8-27FB3C10E5FF,MiscFunctionPortingProtocol +3C983C33-7D22-5E0E-AA5B-A7CD24A31B54,Tcg2FTPMSmm +3C99F185-763E-4C34-B40E-5580EFF865D4,SecureEraseLog +3C9A095D-C3CB-4302-96E1-7105A7C46A69,AmdCcxZenRvDxe +3C9C8411-A0D3-4A00-979C-F3A9FF556CF7,AsusBiosPeiCrashFree +3CA3AD41-6DC5-4338-9C0F-5C6A25D2F597,HpBcuPreserveDataDxe +3CA59AB6-67CB-4385-9EDD-407C49F0D9BC,OemBootOsb +3CA6DB44-8614-4DCA-8B95-A35EFD51779E,DxeCheckCMOSHealth +3CC02D82-D40F-4897-96EF-2F35B3AAA096,I2cMaster +3CCC52E4-56D8-4AFA-A9CD-0E8E2D81488F,AsusSsidUpdate +3CCD3DD8-8D45-4FED-962D-2B38CD82B3C4,UserIdentifyManagerGuid +3CD405CE-2D91-44E9-895D-4459EECD8F9A,AmdRasRvApeiDxe +3CD652B4-6D33-4DCE-89DB-83DF9766FCCA,EfiVectorHandoffInfoPpiGuid +3CDC90C6-13FB-4A75-9E79-59E9DD78B9FA,EfiPeiReadOnlyVariablePpiGuid +3CE1E631-7008-477C-ADA7-5DCFC7C1494B,EdkiiPeiFirmwareVolumeInfoPrehashedFvPpi +3CEC37DF-90AD-4D88-AFF4-093056A6807D,SystemSecureFlashSleepTrapSmmDxe +3CEF354A-3B7A-4519-AD70-72A134698311,Ebl +3CF15020-4DB3-4769-9D37-913A3489FE7D,BindProtDbgDxe +3D0E663A-DC72-4489-87C5-E49EE773A452,IffsPpi +3D154670-6015-4425-B9C5-8035E34BE6FD,NvmExpressPei +3D17205B-4C49-47E2-8157-864CD3D80DBD,FatPei +3D18BA13-D9B1-4DD4-B916-D30796539ED8,EdkiiUfsHcPlatformProtocol +3D18D024-EA2F-4EDD-9FE3-672A37DB802D,OsTransparentUpdate +3D2AD454-BD5A-4F2F-A68E-185000CD2045,CmosInterfaceCoreSmm +3D2DBA75-5EBC-4EEA-A487-06AD9E1CACB3,DellI2cPlatformDxe +3D2F8940-A850-4543-B294-9B0BD0E750C7,HstiDxe +3D3CA290-B9A5-11E3-B75D-B8AC6F7D65E6,XenBusProtocolGuid +3D411389-F606-485E-B7BB-CB6EAB4672CD,FjBIOSMasterPasswordBin +3D417445-1F37-46D8-BC1F-D07014344974,AhciPciHcPei +3D49F3EA-AD1B-4866-8459-E5B58CA410D3,AmdMemMcsrUserPreferenceDxe +3D51D4DA-DE98-49A1-9442-9D81E0FBB6C2,WakeEventPei +3D532050-5CDA-4FD0-879E-0F7F630D5AFB,BrotliCustomDecompress +3D5674D0-AE75-4723-9159-1D653B40402F,DellTxTdxe +3D5ABD30-4175-87CE-6D64-D2ADE523C4BB,EfiVirtualCdGuid +3D61A466-AB40-409A-A698-F362D464B38F,EfiEventNotificationTypeBootGuid +3D64F384-CA32-42C6-A629-42A494B2CB4A,TpmCapsuleDxe +3D68B132-2652-47FD-B2E9-B417122B5A6D,DellCommonBoardInitSmm +3D6CDB0A-5B1F-43A3-A43B-441267F9DAB5,AmiSmbiosCpuInfoProtocol +3D7CD868-072E-4A7E-9C83-1DCE7C0DB0AC,DG_GOP +3D7F7739-A084-4FA9-9A83-6B4B0E2CD638,SATADxeConfiguration +3D806895-FB1E-4F67-A70D-5CC1A7D71857,EcdHctm +3D8BBB82-B153-4BAF-AB64-09E7F9785877,FjNuvotonNct5581Smm +3D92FF43-193F-46BE-B0E1-B820124BF6D9,FjGabiNvramAbstractionSmm +3D989471-CFAC-46B7-9B1C-08430109402D,TxtOneTouch +3D9FC54D-19E5-4AD0-B986-02D687D760E5,ASRLOGODXE +3DA02C3C-62E5-438B-B0DB-9E5128379661,EarlyDxeDevices +3DA97FDE-2261-4CFB-A171-74CD5A9AE279,SaveSpdToRomDxe +3DAB18DE-976C-40B9-972B-6CFD196E0C92,UsbViewerDxe +3DACF484-53DC-4BD6-84C9-AA17BCF2FFDC,PowerFailureRecoveryPei +3DACF585-53DC-4BD6-84C9-BB37BCF2FA23,SerialPortSettingPei +3DB287DE-F551-4DD1-AC5F-050FE6C10A6C,Smsc5028PeiInit +3DB39EF6-81BD-4E4A-A051-12F8FDEFD5C7,CertificateStorageSmm +3DC21D75-DE0E-4300-A0AA-19C41C0CF3DF,SaGlobalNvsAreaProtocol +3DC5DC4A-824A-44C5-89D0-D4547191E3F4,RstOneClickEnable +3DC82376-637B-40A6-A8FC-A565417F2C38,Ps2KeyboardDxe +3DD406D4-5EC9-4198-9907-F674E60B2994,BaseTraceHubInitLibNull +3DD57743-CA56-429A-B64F-77DE88F8ACF6,RecoveryBackup +3DD5AF4B-0925-4C81-93AC-79174C4782D8,NetworkBootConfigurationSmm +3DD7A87B-D5BD-44AF-986F-2E13DB5D274C,SnpDxe +3DD84775-EC79-4ECB-8404-74DE030C3F77,FmpDxe +3DDE54E9-8D18-4EA8-9423-C2E846E18E23,DellSmBiosStrucD3 +3DE30DC2-D84E-48EA-8E38-A9C17D743F10,TimerSMISmm +3DE852F6-34BF-4345-FFFF-FFFFCCE3A3EE,BootFailedDxe +3DEC6443-30AA-44FD-979E-84B91D3C1412,SbSocPhoenixPei +3DEC6443-30AA-44FD-979E-84B91D3CEEFD,SbSocRaphaelPei +3DF2AECB-7489-4D91-9BEA-9B135A564670,BdsCheckPointHandler +3DFC255F-9C86-48BC-972D-E522533768DB,LenovoRebootCp +3DFE0FAB-70C7-4B53-9855-985F14DB2DDA,RawIp4Tx +3DFE2E72-9F6D-4350-BA4F-20333B52B876,AmiSyncSetupData +3E197E9C-D8DC-42D3-89CE-B04FA9833756,RegularExpressionDxe +3E1C696D-FCF0-45A7-85A7-E86C2A1C1080,UefiDevicePathLibOptionalDevicePathProtocol +3E20BE3F-F9B0-460B-B43D-ECC3497D7BC7,DellSoftTAADxe +3E26A614-09F7-486A-A88F-A99BF15E1FA1,LenovoPcdInit +3E2F4F05-26FA-490F-AC3B-351BAF08B28D,ArmaniSxCallback +3E3066C0-BD31-4ADB-B2A4-6E6654C7B81F,LenovoEventLogSelfhealingEvent +3E3099F5-CBCC-4AE8-AEA0-2B7D1E7F8294,LpssDxe +3E35C163-4074-45DD-431E-23989DD86B32,EfiHttpUtilitiesProtocolGuid +3E405418-0D8C-4F1A-B055-BEF90841468D,TcoWdtHob +3E44AD09-D88B-4C52-B41B-B8C00536474A,LenovoSystemCryptSvcRt +3E4817FD-2742-4351-B59F-91493280329C,AlertStandardFormatPeim +3E5281CC-3A12-4ED7-831E-623D7A18D98A,AmdSocSp6StpPei +3E544221-56DE-432E-BBC8-46FACF14FE77,AmdBiosFlashDxe +3E5756E0-6709-4313-8B5A-31534A6542B8,OnboardTPMPei +3E58A128-55C8-4164-FFFF-FFFF38A05639,XnotePlatformPolicyRtDxe +3E591C00-9E4A-11DF-9244-0002A5D5C51B,EfiMmcHostProtocolGuid +3E5EF8CB-915D-4FDA-92DD-71042E0B7A01,PowerProfile +3E625104-1920-44B1-AE2C-1BDA57ED73EA,KtiRas +3E710061-647A-4C03-BE85-FAD6CCFA5A18,PcPassword +3E745226-9818-45B6-A2AC-D7CD0E8BA2BC,EfiUsb2HcProtocolGuid +3E74BFBF-893D-4097-B263-96DEE7EE2CFB,SetupStatusSmm +3E7598EE-FD81-46C9-9798-C2FD1A73E839,AIMTSmm +3E7788CA-2BFC-4FCE-8122-5176CA492D9F,CbsSetupDxeRV +3E7D2B56-3F47-42AA-8F6B-22F519818DAB,ScPcieSmiDispatchProtocolGuid +3E7DD42F-A67E-4D4F-BC02-2B5A6EC8DAE9,SetupVariablePei +3E91A5E2-26A1-4AE2-854B-08C39BAA0BC6,DellSdCardNotifyDxe +3E9A7EC8-EB9B-47AC-B78E-F1A4C3FC78EA,CbsBaseDxeSHP +3E9F711D-3496-46EE-9DA5-46DFBC1D686F,PlatformFlashPartSmm +3E9FF4C8-A355-4063-A487-610360C0ACCE,ThirdPartyNvme +3EA824D1-81E3-4FF5-BD43-BB9C65DF7C46,AmiCsmStartedProtocolGuid +3EAF5E3A-E4B2-48E6-A9F1-B75CF204BCC8,PeiBoardConfigInit +3EB9F0D3-40D0-435B-B692-809151807FF4,TCM_MPDriver +3EBD8C7C-733B-4667-8FD1-4ABEA366C95B,ASUSDirectKeyPEI +3EBD9E82-2C78-4DE6-9786-8D4BFCB7C881,EfiFaultTolerantWriteProtocolGuid +3EBDAF20-6667-40D8-B4EE-F5999AC1B71F,EfiSecHobDataPpiGuid +3EBFA8E6-511D-4B5B-A95F-FB38260F1C27,DeviceManagerFormSetGuid +3ECEB3C6-1B1C-4729-9C62-33DD81D65DDE,FchPromontoryCbsPei +3ED700B5-3A13-43BE-9450-00122E8B83D7,DataHubRecordPolicy +3EDBAAC4-5017-4870-8CC4-721F9EF1974F,CloudBmrApp +3EE63DEB-A003-45CB-A949-6754CD618C9C,AcerHwConfigSmm +3EED924D-2BC1-4876-B769-F31F85AB397F,FjHddEraseApp +3EEFF35F-147C-4CD1-A234-92A069700DB6,EfiMemorySetup +3EF7500E-CF55-474F-8E7E-009E0EACECD2,AmiUsbSmmProtocolGuid +3F06A22D-CD02-4EEA-B294-D6871DF1255D,LenovoVariableSmmProtocol +3F27C867-4720-4537-8D0C-20F32FF30C04,AmdMcaZen4Dxe +3F286E3E-16EA-4E5E-A2AD-63644F1AC3C7,PeiConsoleOutConsplitter +3F2BCF3A-7876-475B-B97D-EFAE8BEF75FC,AmdNbioGfxRNPei +3F31B066-82A2-4B2A-A6CE-AB0F7DD0066A,NVDimmMgmt +3F4592F4-D5DE-4C29-883E-63434BBE0B33,Cf9Reset +3F4CDD2B-A713-4443-A253-7EB22B71730E,BctBaseSmmRPL +3F557189-8DAE-45AE-A0B3-2B99CA7AA7A0,EfiFtwLiteProtocol +3F5A74B2-BF80-4850-8591-4F2DF5F9CB2B,PhoenixGdiProtocolGuid +3F626A59-87D2-4FCF-B5DE-9D12A8B2AF88,FeatureByte +3F68E889-CB77-4EFC-BC84-AFA0A64AD26E,LsConnectorDxe +3F7753EF-D36F-45CC-8A1A-2EAAFF1038B6,PciPlatform +3F7753EF-D36F-45CC-8A1A-2EAAFF1038B7,BootMediaInfo +3F78CB8D-72EE-414E-B023-DACA003BDDF5,ProjectSxSMI +3F78CB8D-72EE-414E-B023-DACA003EFCDE,AsusApmSmi +3F7E615B-0D45-4F80-88DC-26B234958560,FitDiagnosticsLoader +3F7F265B-29CE-4A54-8751-8A9E90719831,FjEdpDisplay +3F837872-2A07-4470-B8B7-9AC131360314,VariableEditDxe +3F8DC333-CCD5-4E58-B8CF-7B9A8F31EA96,AmiTseOemPortingVar29 +3F949D9F-CC66-479A-9AD3-F6C1C3FF4378,AmiSgxDxe +3F9615F9-1DD3-4185-920D-8D0D5B23D36C,fTPMInit +3F97727B-5E18-4C4F-BC65-9CB8DFE1802F,FjGabiSystemDataCmosAbstraction +3F9A7CA0-A30E-45E8-9CBB-B628D54A3588,OemPei +3F9CE6DB-37BC-49F0-9293-A9EC7BDAC3C9,AmiPeiSetupPcd +3FA0BB4A-180B-4458-9F12-6EA68F69E6CC,PxeRomB571699 +3FA4F847-D8EB-4DF4-BD49-103A0A847BBC,EfiKmsFormatMdc4128Guid +3FB208AC-2185-498C-BF46-DC23DA587B55,EmuRedfishService +3FB856A5-C8B0-4760-B49A-2EDD4FA35BFA,LenovoIbexPeakGlobalSmiControl +3FB90C4A-985E-46C3-AC50-4640F3261F1A,BiosFwInfo +3FBD651B-5F0B-47AF-BE25-AE35C63C8D5C,AmiCpmWrapperPei +3FBD651B-5F0B-47AF-BE25-AE35C63C8D5D,AmiCpmWrapperPei +3FC08BA1-EDC6-4E5F-BDC8-0E46B65C92F6,SmmGpiDispatch2OnSmmGpiDispatchThunk +3FC2A64E-0A39-48D1-9424-721344C1918A,CompalInfo +3FC69994-1900-468B-B2D9-E6163056C3E7,Ast2500Pei +3FCF2813-F138-411C-BFC4-DBE5B9499822,ODMEMUSBLAN +3FD1D3A2-99F7-420B-BC69-8BB1D492A332,Fid +3FD7FDB7-1C4E-43BA-A857-35857F9ED3F5,SystemVariableStoreManagerRuntimeDxe +3FDDA605-A76E-4F46-AD29-12F4531B3D08,EfiMpServiceProtocolGuid +3FE2A8A3-C400-48F8-832F-7881A394C250,IohInitDxe +3FE57AC2-C675-46B1-8458-AC6206588424,TpvDxe +3FE61B25-D0BD-4907-9CE0-F5285718824E,It8587eFlashDxe +3FE72C6D-3612-4061-84AF-80C5B7AC6E25,PeiIpmiCmosClear +3FE89372-C0CC-466B-AA4A-B76DBBB11BBB,DellPolicyDxe +3FECFD95-7CB2-4A6E-8FAC-DEFD9947E35E,ReportFvPei +3FEDD4A3-8112-4534-8DB2-E886EB35075E,ErrorMessage +3FEEC852-F14C-4E7F-97FD-4C3A8C5BBECC,FWkey +3FF7D152-EF86-47C3-97B0-CED9BB809A67,ClvBootTimeTestExecution +3FF97FC2-7920-4C72-9478-0C4DB7BEA399,TrackPointSynaptics +3FF9DDBC-14FA-4A7F-89D9-B770055A42A5,TbtUpdateHandle +3FFCAE95-23CF-4967-94F5-16352F68E43B,PpmInitialize +3FFFB2AA-4692-42E8-865E-7E111986FABE,wifi_2bars +40008162-93D0-48F2-80DA-7E32F4C98F8B,Udp6Dxe +4004DE5A-09A5-4F0C-94D7-82322E096AA7,DxeCapsuleLibNull +4004E454-89A0-11E3-89AA-97EF9D942ABC,ArmVExpressFastBootDxe +4006C0C1-FCB3-403E-996D-4A6C8724E06D,EfiLoadFile2ProtocolGuid +40093F23-630C-4626-9C48-40373B19CBBE,EfiKmsFormatGeneric2048Guid +40096A3A-5C2A-4FBC-AEF7-5475DD7AB334,BasePcdLibNull +400B4476-3081-11D6-87ED-00062945C3B9,SystemSpeakerDxe +401471E4-9E79-4664-BFB0-179524230567,LenovoVproIderAsfBoot +40155DB7-F2F6-4F7E-8BA8-A3466D4EF5FE,RngDxe +401F52EF-55AE-488A-9424-FEF53BEB1122,SmmPowerButton +402EEC6F-D0FC-4FFD-9956-FA9813EA2D7A,AcerHwSupportSmm +4059F377-27D5-4139-B7E7-F99591F7C46D,FchSmmDispatcher +405B2307-6839-4D52-AEB9-BECE64252800,ArmFvpDxe +405B6CD8-AF66-4993-B77F-35EFDA6BF7C5,SioSmbAlertDispatcherPei +405DA936-3737-4C0C-8E3F-E6172A568592,FileExplorerDxe +405DA936-3737-5B0B-8E3F-E6172A568592,RecoverBiosUiDxe +405F8FE6-5213-4B85-B821-97B77AFF795B,ASM104X_DXE +407868F3-D1A7-46C6-9FCB-6F67A5E3C7D9,HdAudioConfigGuid +407B4008-BF5B-11DF-9547-CF16E0D72085,PL111LcdGraphicsDxe +408E3BA4-8410-4C44-A51E-DF8BDB36056C,HpPlatformSmbiosDxe +408EDCEC-CF6D-477C-A5A8-B4844E3DE281,ConSplitterDxe +40902599-A3A9-43EE-AD76-D0482FBE29B5,PlatformVTdSampleDxe +40A0BE5C-ECA6-45F1-BFF5-619E26951E5C,HstiDxeV2 +40B086C3-95B5-444F-A895-CBF484A19A0F,AsusHwmSetupItem +40B09B5A-F0EF-4627-93D5-27F04B754D05,AmtReadyToBootGuid +40B207DD-89D7-4F58-B278-622176CA0998,SioResetSystemSmm +40B2D964-FE11-40DC-8283-2EFBDA295356,FmpDevicePkgTokenSpace +40B457F4-4409-492C-AE48-2A2B0CBCDA58,DellEcIoSmm +40B5FCCC-CD62-4B46-89BA-D7F5256D881D,DellPolicyPei +40BEAB40-CECE-4909-B133-20A413AE19E9,CpuMpDxe +40C1E78A-D6C5-4A41-805A-85D680F8FDB1,FmpDxe +40C83888-A477-490E-A0AD-7B968CA2D73F,DellVRHeatsinkDxe +40CDA63E-3F70-4B25-A50C-49DBD7EE343F,SmbiosType132 +40D85A8F-37E5-4788-997F-70478C4B7B48,SecureEraseDxe +40E064B2-0AE0-48B1-A07D-F8CF1E1A2310,EfiNetworkPkgTokenSpaceGuid +40F75919-0CDB-4DB2-A0FB-6881CE7E9770,UsbMouseAbsolutePointerDxe +40F93610-8D5F-43D3-A896-C61EE79F1376,HpSmbusSmm +40FC560C-C5D9-4219-8963-46605AB2570A,FjSysmanFwUpdaterBin +40FDF4FC-B7CC-4AC5-9BA2-A050D26656A7,SmcOptimizePei +41015350-BA3B-4916-B043-4615408A87B3,OememSmiCore +410C1D0C-656F-4769-8DFB-90F9A0303E9F,IconFireWireHD +4110465D-5FF3-4F4B-B580-24ED0D06747A,SmbiosPlatformDxe +411F7E6F-4666-58B2-D69E-D680C0F68BE2,SystemAcpiAddedValueDxe +41282EF2-9B5A-4EB7-95D8-D9CD7BDCE367,Oa2MagicNumber +41292206-4069-42A6-AC38-C4A5C123C6E5,BaseTraceHubLibNull +4131B0C5-DEC3-470A-AAD5-1509349DBFB4,AdlSioFunctionDxe +4133A446-3E9B-463E-982D-0B7A09B1F138,FjShutdownLogDxe +413B1952-D564-4AEB-8CDA-8353161500BC,S3SaveSmm +41401688-2862-431B-BAAC-6ECADAC384AB,PciCfg2OnPciCfgThunk +41415623-A074-4369-98C8-370770AED42B,AmdMemSmbiosV2RsPei +4143C17D-54BC-4903-9958-2454216BB21E,LpcPlatform +414D94AD-998D-47D2-BFCD-4E882241DE32,FwCapsuleHdr +414E6BDD-E47B-47CC-B244-BB61020CF516,EfiHardwareErrorVariableGuid +414FE699-1D18-4C80-8C92-6140737801E2,FjUartModeSelection +415928AD-31D9-4CBF-9E92-6D1F67EC5711,EfiNgnCfgOut +416CF182-4A5F-4F21-919A-0161D837181E,POSTCODE0A_DUALACCELEROMETERWMI_SMM +417560D0-80F6-4CB2-A15E-50ACD383691F,FchSmmDispatcher +41781F4F-A3CD-4750-8A2C-2192B4DFE52B,EfiPeiPlatformTypeHedtEvPpi +41789FB9-02AC-4484-BD40-A3147D7EDA25,PeiRecoveryLibNull +417DA59E-CB73-452B-90F3-A8D9B805004A,BootOrderDxe +41804D8B-2CF4-43CA-9034-18E5DD227C93,HpNetworkTransferDriverWmiSmm +41846A2E-7AAA-4498-BC26-B5ACD49F92E1,DellSmbBootPriority +418BC604-F15E-4843-85D0-2D2480B7E488,EfiMpstNodeData +418FAF6C-2BCF-4141-8983-9D33E1B67B4C,SpiControllerSmm +41943893-CDD0-4A3F-BA63-D1325E72061A,LenovoHdpManagerPei +41A4631C-BB02-45AF-BEDD-AEDC56E53E79,SuperMPei +41A78FEC-2270-421D-98C9-BD13E77DF19F,NtfsDxe +41AA21FB-7B8F-46D2-B726-C1BC5FE65243,HpSmbiosDoneDxe +41B13735-0E0A-4F67-96D1-B15DA28205FA,SIOBasicIODXE +41B168D3-7C13-430C-BFEE-B438C2795C1F,SmmWhea +41CF3880-0560-4D01-8624-3A0A47894574,DetectDevice +41D94CD2-35B6-455A-8258-D4E51334AADD,EfiIp4ProtocolGuid +41DC6838-029A-4D2E-860C-6EC6425B5EDD,AsusWlanUpdate +41E26B9C-ADA6-45B3-808E-2357A35B60D6,ArmBootMonFsFileInfoGuid +41E2F0CE-238A-4906-AEF8-37C531ADDF89,ThermalModePei +41E321D8-CE30-4160-B08A-75AA570BF36F,LenovoFlashDeviceInterfaceDxe +41E89AB0-BD3D-44B6-A431-E4836EFBF2CB,PowerManagement2 +41EADC00-8DB2-4BFE-B0EA-CBAAE7F4D31B,SetupModifyProtocol +41EF54AD-E2CA-4433-FD27-D9CACA621EAE,AmdNbioIOMMUDxe +41F19F4B-E16D-4908-89DA-BEA814A66093,AmdSpiHcProtocolSmm +41F46692-9513-4D1C-8BB3-B6A168182DE4,DellMePciPlatformConfigDxe +41F564F5-616E-41D7-B4E3-E124C7FEC024,TransitionBios +41F8606A-F74C-409D-9465-5219557CBC7D,DellFlashIoSmmProtocol +41F925DB-17FA-4493-9A2C-3249FBAC07EC,FjGabiFlashCommonFdRegionCtrlSmm +41FA68EA-3AF0-458B-AFD5-1EEFE9DD6F66,CsrPseudoOffsetInitDxe +4204A3CF-CDAB-4629-AD6B-65E647FC29D5,AmdCpmManageabilityBoardDxe +42076C6F-0CF3-4AE1-B3A8-49789CDD57DC,PSUDxe +4213591D-CEEF-425F-915B-AE4559680F62,XnoteSystemSetupDxe +4215689C-F529-4AFF-9BFE-FEF35AC5518C,ProjectPeiPriori +421E6422-EB00-4ED9-A58E-D01666CB3DAE,SmbiosDataUpdateDxeFischerLakeRP +4220AB9B-1730-49C5-A89F-B471CF43B221,FchPromontorySmmInit +4220AB9B-1730-49C5-A89F-B47FCF43A221,FchSmmInit +42293093-76B9-4482-8C02-3BEFDEA9B35D,TcgSmm +42322E78-4659-4704-A05E-F2D75D3726AC,GpioPolicyPei +42363877-5513-4019-BDFE-CC075B646711,GnbSocRenoirDxe +42363877-5513-4019-BDFE-CC075B6467FD,GnbSocRavenDxe +4239AA07-8DE8-4C67-A971-C6F3F56D7F93,RfTlsCertificates +423D7996-E4C3-4D88-BEFB-0A602576CACD,PlatformSpdReadPei +423F0216-FBD9-4ABD-A63C-60A4591A37C2,FjIbvTraceAbstractionPpi +4250CEC2-DDDB-400B-8C62-CF9864F6D154,AmiSioPortCompatibilityProtocolGuid +4265FD93-28A5-488D-A572-2A47B10561C0,D01PeiCallback +426A7245-6CBF-499A-94CE-02ED69AFC993,MemoryDiagnosticBios +426B3068-3BC7-4B73-ACE8-322F0D0A105B,BatteryHealthControlSmm +42734906-EAD7-4A98-ADBE-58BDA5CB64CE,EcKeyPei +4278A574-4769-4D60-B090-DD4916691590,RecoveryModuleLoadPei +4284A11C-18C1-4C10-B2D9-586A0160A523,EfiPeiPlatformTypeLightningRidgeExecB4Ppi +42857F0A-13F2-4B21-8A23-53D3F714B840,SystemCapsuleRt +42881C98-A4F3-44B0-A39D-DFA18667D8CD,EfiHashServiceBindingProtocolGuid +428BF17F-6116-4D59-843A-400470D17864,DellSpdSmbusAccessSmm +428DA2C1-39BE-41B1-88A6-A6FB870139A4,BsfWsRouting +429501D9-E447-40F4-867B-75C93A1DB54E,SmramCpuDataVariable +4296D9F4-F6FC-4DDE-8685-8CE2D79D90F0,EfiDriverHealthManagerFormSet +42AAA06F-B219-42A3-889E-413053ED10AE,FchSmbusDxe +42BB2364-F488-45DE-9311-E9E2CD37BD74,RtKbcDriver +42BB673D-09F3-4E2E-9FEE-D081131DED5B,BootScriptSaveDxe +42BBACA3-7161-4891-AC10-C75E2E4DF614,IffsPlatformPolicyProtocol +42C078EF-14A8-4E30-9329-6F12D796E54A,LibWchar +42C2F6B6-976F-4EBD-B6A9-FB4178F970FE,FchKernSmmInit +42C32DCF-F25A-47F3-8F4C-ABD478D77F50,DellPbaUpekDxe +42CF2D4A-78B4-4B80-80F9-96A83A630D70,UsbDeviceDxe +42D353B0-8C1E-4ACA-BEAC-28FB24F20C42,EfiDxeIpmiUsbTransportProtocol +42D54A0F-ECA8-49D4-997B-EF3FBE3B5BC0,OemDxeUpdateRx +42D69902-10E7-4907-AD3B-46A5BF25A1A0,NvmeUnlockPei +42DBABA6-846A-44E6-BD76-40280484D907,H19MpmShellInterface +42EEB698-B881-647A-324A-5A16EEAA9F3E,A01SysPassword +42EF76CE-A606-4881-BEA6-AD3F3EC9F754,Memory_OK_PEI +42F418E2-284B-41F2-BF6A-AF1C9166E66C,SystemSetupHttpBootDxe +42F58B27-5DC3-4FA7-844D-5A7DBFF06432,Enquire +42F5F135-3F50-4319-98A2-3B22DF559D20,SmbiosMemory +42FCB444-B881-49D8-A6E9-5A1695FC9F3E,SysPassword +4305ED99-9D86-492D-83AE-4D7359E99089,SioIt8669ePei +4306B556-2A3D-455C-A5EA-16ED450BD553,FjSystemResetPeiBin +4308B1F6-60F0-49FE-9E51-3A25992515BF,PoofAnimationState0 +430AC2F7-EEC6-4093-94F7-9F825A7C1C40,SdDxe +430DCC33-3169-44B9-B430-23FCAB9102E6,CheckEthernetState +430F6965-9A69-41C5-93ED-8BF06435C1C6,EdkiiPeiShadowMicrocodePpi +4311EDC0-6054-46D4-9E40-893EA952FCCC,EfiHiiPopupProtocolGuid +43130081-60D6-4C29-BBC0-AB0B5BB90483,DellMfgAuthenticationSmm +43172851-CF7E-4345-9FE0-D7012BB17B88,iFfsSmm +4325AFB3-9F11-42C7-A293-94AAE3804942,FjUpdateSystemInfoDxe +432F9D66-F40F-435E-B402-46D41A394CCE,AmiChipsetPolicy +4335ED99-9D86-492D-83AE-4D7359E99089,SioPlatformHook +4344558D-4EF9-4725-B1E4-3376E8D6974F,ShellLevel3HiiGuid +434DBB27-969C-47D1-876A-4146D4EB4E36,DellBluetoothSmm +43522AE9-ECFA-4826-BC07-0E057A87D607,RealtekGopDriver +4356B162-D0B2-11E1-8952-4437E6A60EA5,Lan9118Dxe +43573EA3-8F6B-4BCA-970B-EFFAB15AC0E8,SanitizationModeSsdt +435CB0E4-7C9A-4BB7-9907-8FD4643E978A,AuthVariableLibNull +435D621B-3C41-4536-B0C6-AF67059FC4BE,CrashLogDxe +43679142-87C4-44AD-AF02-B47F782D6CF3,PeiIpmiLibIpmiPpi +43788BEB-638F-434C-8A84-46D33A589E76,DxeBmcElog +437B9A30-299F-11ED-A261-0242AC120002,DebugLEDSmm +437F14D6-97AE-4DA8-A598-2E65791E6944,SplashBarDxe +43827082-110B-428F-B6BB-41F65E67B202,AsusUsbDxe +4383BB24-2E0F-47AB-8955-B9EE710ACE52,FjLanRtl8111xSmm +438A5B8D-98D6-4CCA-A182-BA8C0471B5E8,PchSmiDispatcher +438B7799-F4D5-47A6-A75C-305C4449F512,SwSmiDxe +4391AA92-6644-4D8A-9A84-DDD405C312F3,AppleBootPolicy +43A110CE-9CCD-402B-8C29-4A6D8AF77990,EslUdp4ServiceGuid +43A4C605-C66D-473E-A06A-37E9143FC439,PcRtc +43AC4333-472C-4B91-8C5C-52A8B4374256,IioCfgUpdateDxeNeonCityFPGA +43B03B31-057F-4F1F-9B53-C3A54F565586,SystemEventPei +43B16233-893C-4893-BF34-CDAC541926B0,UpdateSmbios +43B400A8-9980-4871-8D8E-9DA7CBD246DE,OemAmt +43B93232-AFBE-11D4-BD0F-0080C73C8881,PartitionDxe +43BB9EAB-7D57-4DEF-B0A2-A3A9F9C6EAE3,LenovoMailBoxDxe +43BC7B72-E961-4A59-8525-6F30A276625F,EcMemMappingDxe +43BE0B44-874B-4EAD-B09C-241A4FBD7EB3,EfiKmsFormatGeneric1024Guid +43BEB924-62EB-45FB-B0BF-9A97AF463D68,IteEcDxe +43C1B250-BF52-4DDE-8280-57E0AD61117D,H19AmdDimmSpdAccess +43CA74CA-7D29-49A0-B3B9-20F84015B27D,SecCoreNative +43CB767D-322C-4285-B2FA-E952BF2DD94C,AmdCpmSoundWireDxe +43DECD73-77CB-474D-BD6F-1A98E7E2B6C6,LenovoErrorManagerDxe +43E3023C-13DC-4BA6-99CB-AF6F9ECF8B73,H19DeviceFwUpdateHook +43E7ABDD-E352-4CFB-A230-4CDC1D350E5C,GraphicsConsole +43E7D039-EEA6-4C08-B741-096D39447845,SataDriveInfoSetupUtilityDxe +43EA62DB-C2E4-4AF7-AE94-2F48D708A3BC,OemSsidGpio +43F66FFD-B288-4139-BAD5-B89803E730A2,DxeTxtPolicyProtocol +43F9B080-C902-4737-B306-487050F7CAA5,fjHddEraseApp64 +4402CA38-808F-4279-BCEC-5BAF8D59092F,EfiSocketCommonRcVariable +440C38B7-ED16-49EA-9669-317EF906635D,I2cMasterDxe +440D38B7-E016-49EA-9769-317EF908835D,I2cHcOperation +44148713-6138-4890-A15B-5FF60C03F87B,EcSureStartRAPDataTransferSmm +4414D6D8-232C-4972-A4F7-2B21D4298786,I2cHost +441FFA18-8714-421E-8C95-587080796FEE,AmiSmmDebuServiceProtocolGuid +4426CCB2-E684-4A8A-AE40-20D4B025B710,EfiPeiS3ResumePpiGuid +442BA91E-B0A8-499F-94F7-2E922C9AAE0D,AodDxe +442BE18B-CA6E-4A23-9A99-9AFE8A213A32,SystemInformation +444C3203-F8B1-42A7-ABE9-2E58025BE12A,FpdtPerformanceProtocol +44577A0D-361A-45B2-B33D-BB9EE60D5A4F,ArmRealViewEbPkgTokenSpaceGuid +44640C32-33D7-4FB0-B1F9-6C7B232E994D,SpsPei +44640C32-33D7-4FB0-B1F9-6C7B232E994E,SpsMeSec +446DBF63-2502-4CDA-BCFA-2465D2B0FE9D,EfiCertX509Sha512Guid +44716DB9-AE66-4E93-BBBF-C78D9024DC47,KeepDevStaSmm +447559F0-D02E-4CF1-99BC-CA11654054C2,StdLibTokenSpaceGuid +447A1B58-8F3E-4658-ABAA-9E7B2280B90A,NvramSmm +447C8D3F-429F-405D-BDC6-35D75F3DC082,OFCRuntimeDxe +44830575-0A1A-450B-9FEF-BC88A1866A13,FjGabiBootOrderHandlerSmm +44883EC1-C77C-1749-B73D-30C7B468B556,ExFatDxe +4489DD91-8FBA-4F0E-B218-A24497805E1B,AmdFabricBrhPei +448F5DA4-6DD7-4FE1-9307-69224192215D,EfiSectionExtractionProtocolGuid +4495E47E-42A9-4007-8C17-B6664F909D04,BlockIoDxe +449C91B9-0907-49B5-AA76-04AF3097401C,SmbiosPlatformDxe +44A20657-10B8-4049-A148-ACD8812AF257,Tcg2Smm +44A2AD5D-612C-47B3-B06E-C8F50BFBF07D,OpalExtraInfoVariableGuid +44B3334D-A693-4AAE-AC8E-01E1904D9C75,AtaSmartFeature +44B79884-59F6-4D5F-869A-8C5436E09EB9,ADLINK_PsuAtAtxModeSwitch +44BA7D87-FD96-45B8-93D3-A8A0A94D0985,AmtConfig +44CDFA70-2C7C-4791-9AA3-EAE8777F0A8B,X11DPGPeiDriver +44CF7D20-DFF6-4209-9A1F-F6CD5F5CE88B,LenovoVariableInitSmm +44D763ED-7798-49A4-8B8B-C3D5BB2FD4FD,RestrictedBootfromRemovableMediaPei +44D88421-93BD-4325-BE63-051B531889CB,BiosCfgToolSmm +44E71185-2277-4557-BC53-957FAD9CA65C,FjLvdsRTD213xR_Dxe +44E7717F-075E-450D-98D5-54EBBB40701E,EfiPlatformTypeLightningRidgeExecB3Protocol +44F0DE6E-4D8C-4045-A8C7-4DD168856B9E,EfiRngAlgorithmSp80090Ctr256Guid +44F23590-DC88-11DD-AD8B-0800200C9A66,SystemAhciAtaAtapiPassThruDxe +44F7D21F-C36F-4766-BC5B-C72E97E6897B,Fip006Dxe +44F8D447-A021-46AA-9811-12C1EA02119D,BiosConnectLauncher +44FE07D3-C312-4AD4-B892-269AB069C8E1,BiosGuardSmm +45055A79-B385-4705-A3AC-11CE99A1CB47,StaticSkuDataDxeNeonCityEPRP +4513F345-0A25-42C4-8114-3A26BA6CF570,PlatformVTdInfoSamplePei +45177528-7C6A-4B5C-9C56-1A65BB5FC434,AmdCcxVhRnPei +45234652-62B3-4BF7-3878-B54FC44B5328,ForceLpmAspmDisable +453253B9-A204-46E4-B873-CA2249DA4888,SmbiosUpdateDxe +453368F6-7C85-434A-A98A-72D1B7FFA926,EmuIoThunkProtocolGuid +453C5E5A-482D-43F0-87C9-5941F3A38AC2,EfiKmsFormatSha1160Guid +45424D0C-E6AF-4AF2-AD99-FA77168742D1,SmartTimer +4542B4AD-29DE-409B-AE4F-93A8C25392E2,ClearCmosDxe +4549AB47-6E60-4293-B91D-31B610AD8056,EfiEsrtOperationProtocolGuid +454B0149-5B42-485E-8A8E-A20422790B97,AmdFabricBrhSmm +454DB25C-E506-4F90-A6DF-69E0223E3F2B,PramAddrDataGuid +4551F2F5-C684-4F27-936F-C7B04A5C5FF1,SecureBootDXE +45594FFD-60D8-45BB-8D6F-867BDF09E8C9,StorageSetupInfoProtocol +455D16DC-E3AF-4B5F-A9AD-A4BC198085BD,BaseDebugDeviceLibNull +456BBE01-99D0-45EA-BB5F-16D84BEDC559,EfiRestExServiceBindingProtocol +456D2859-A84B-4E47-A2EE-3276D886997D,EfiSmmSxDispatch2ProtocolGuid +456F1C50-750A-4671-89ED-F536A68C6D9D,AsusSetupVariableItem +45739A09-045E-40B5-9FA2-F7F66CB35551,DisplayDetectDxe +4579B72D-7EC4-4DD4-8486-083C86B182A7,IScsi4Dxe +457A68D7-15A5-4AF9-A252-9963FF9B0C34,PowerButtonSetupPei +4589CBF3-03F9-4998-9D6F-26343C69562A,LenovoComputraceLoaderDxe +458B03ED-6E53-414F-9F07-3A829C990641,DriveLockSmm +458CE95A-4942-09A9-5D21-A6B16D5DAD7F,RedfishCredentialDxe +459504D7-72D7-4BB2-956D-C9FA899920E8,OemFwLnk +45982835-D04F-4745-BCFD-519E6BB2DE7A,NvmeInfoSetupUtilityDxe +4599D26F-1A11-49B8-B91F-858745CFF824,AmiStandardDefaultsVariable +459C70C3-9344-4484-9F93-7822530D0D11,MePciPlatform +459FAFEE-3BCD-434D-90C9-A283ABAE84D5,HspfTPMAcpiSmm +45A36262-660C-495E-BDC4-50A852A44A11,MtkSuppDxeGen2 +45AAC157-93B6-46D6-AA9E-4CF6C32916A4,CRBSmm +45AC8863-E3FA-4A38-A23C-00BCD10CBD50,AmiNvramSmmCommunicationGuid +45AEE2D6-18B5-4DFE-92B3-2C04F61631AF,AaeonEcPei +45B19541-E875-48F7-AB36-A646BD4AD45B,HpPlatformInfoDxe +45B59855-500C-443B-B504-9AB4CA29BC68,EfiPlatformTypeLightningRidgeEX8S1NProtocol +45BCD98E-59AD-4174-9546-344A07485898,EfiSupplicantServiceBindingProtocolGuid +45BD5504-94A8-4301-B211-B0AE4F56E9AE,ThermalSMM +45CBB784-020C-46E2-8A14-BE20CA21C3F1,PowerLossNotifySettingDxe +45D68DB9-8B4E-48C0-99E9-F21F262DB653,XhciPei +45DC2877-0DF1-4BD4-810F-0C75111819CC,EcDxeRestorePei +45E78B8A-BD68-453A-8E9E-C3773108B213,SiInitPreMemPch +45E9D7AA-6D85-4DEC-8B88-8C4BE5A1A08D,NvmeSmmProtocol +45EAE125-2A1D-44E0-9953-7AB7F19888AF,DellDashPolicyVer3Protocol +45ECAD7C-8C93-25B8-5E53-171A4C02D3AB,WCN6855 +45F1CEC9-0C5C-4B31-BDF3-2FB6D7056BDF,HpDmarSmm +45F27DA8-DB9D-48E1-BF5E-458DEED9DE84,PchFlashControllerSmmProtocol +45F9602A-3475-4D1E-9FE9-BAC99F42AD49,AppleBacklightController +45FC167C-8B1B-49F8-A3FF-9FE54241C969,RfIScsiBoot +45FDB42B-1F95-4A53-9BA4-1C8BFB8BCB01,DellGpeConfig +45FF16E5-02B2-4C89-8604-E68C10DDE107,SmmCommonService +4612B275-356B-44D3-9315-33E6E936E64C,FjTpmInit +461A67CF-3D9B-4FC0-BCD2-7C606335DE0F,SystemSetupSecurityGuiDxe +461B2833-3DA5-4556-95F2-BA506131051B,ExtCfgDevDrvDxe +461DFED6-9D33-4AC0-8D25-57381ED0BBC0,AfterG3PolicyInit +46233426-744E-4763-958D-44B1200B320A,AmdMemoryHobInfoPeim +462CAA21-7614-4503-836E-8AB6F4662331,Enter_Setup +46310243-7B03-4132-BE44-2243FACA7CDD,CMDB +4635E90F-2432-4385-8B1F-5FE1B3C97747,SetupConfigUpdateDxeBigPineKey +4639A701-74F9-4635-B126-9FF048D6B0D0,AmiTseOemPortingVar17 +46419146-3D6E-473C-A3AA-22AB404F197C,FjDxeServicesTableDxe +464FDC84-D53F-4A7B-B491-87991228F08B,FjUsbDeviceDxe +4658B698-EAB5-647A-987A-5A1665478FF6,A01SysPasswordSmm +465EA4B9-0FFC-40E7-9CC2-0F2CC3E66DFF,TouchscreenIdm +465FDE84-E8B0-B04B-A843-A03F68F617A9,ThunkPpiList +4660828D-842A-4F69-B31B-D393662B5240,LenovoDeviceGuardDxe +466A7291-50DF-4B40-A2EB-CEE67D5428C9,AmiTseOemPortingVar16 +466C4F69-2CE5-4163-99E7-5A673F9C431C,VGAInformation +466DAAD5-4760-4F6E-9A7F-CEBE8455393E,FjPostScreenPostError +467313DE-4E30-43F1-943E-323F89845DB5,EfiBluetoothIoProtocolGuid +46805D61-0BB8-4680-A9BE-C96C751AB5A4,BaseIpmiLibNull +4698C2BD-A903-410E-AD1F-5EEF3A1AE422,OverClockSmiHandler +4698C8A1-4934-4A96-BB90-F7A55089CAFD,OemDxe +469AFF53-E625-4460-8F18-AA2206DAE5BE,DellDockSmm +469FC080-AEC1-11DF-927C-0002A5D5C51B,ArmPlatformPrePeiCore +46A2DC1D-6D2A-4558-BC0E-86B4B54B4236,OemCustomizeCsm16Config +46A9772D-D258-4210-9017-8799C57466BA,SwitchDellSystemID +46B94C2D-AF5D-4915-814D-159323AE780A,PowerButtonHandler +46C81ECA-E931-40B2-AECF-DFD8F00664EF,MtkWiFiDxe +46CF6120-9BDE-49B1-9D59-D35E355BF850,OdometerResetSmm +46D8ACDD-29C3-4013-81E8-37A425AB4F99,SystemVspCmosSmm +46DDB415-5244-49C7-9374-F0E298E7D386,EdkiiHttpTlsCipherList +46E3256A-E5C1-4D2A-8282-505AFB41CE65,DuetFwh +46E44855-BD60-4AB7-AB0D-A679B9447D77,EfiTcp6ProtocolGuid +46F3E816-66CA-4062-8A6C-623BFC90DD8E,FjSmbiosProducerDxe +46F56ACC-600B-450F-A59C-3A1A4AD4353E,PrmPkgTokenSpace +46F9D8DA-2670-44B2-9E42-C9B130CE2465,SmbiosMisc +46FAE56C-AC1E-4BAD-B152-549DCE042D80,BBSManagerLegacySmm +46FCD5D8-A9B3-42E3-904A-012F07BC5F5C,PowerOffSmm +470458CE-3E8A-40A7-BFCB-07755ABC4104,FjGabiGpio +47060D0C-BB2B-42D2-9A85-4DF1A2BFDFE2,BoardDxe +470A56EF-DC23-47C5-9D79-888E755C875F,HpLidSwitchingDxe +470CA824-F687-4148-885E-46311241C201,PchEhciPei +470CB248-E8AC-473C-BB4F-81069A1FE6FD,SmmFaultTolerantWriteDxe +470E1529-B79E-4E32-A0FE-6A156D29F9B2,EfiBootScriptSaveProtocolGuid +47144F62-B423-4524-AC6A-90106BAA89FB,AmiTpm20MeasureConfigurationInfoGuid +4717DA5F-E544-4B15-8D27-BACC292A832F,AmdSocFp6CznPei +471F5144-6037-4952-8B01-CFF586FDE6B3,AmiTseOemPortingVar26 +47220BF6-19D4-45F8-A816-4618F0496402,OemDxeSample +4723931D-F8AD-45BF-AC1F-929F7BA88E7F,ValidateExtendedBiosRegionDxe +4727E62C-DF17-4000-89E3-7AEE74AFEC63,FjGabiEntrySmiDispatcherDxe +472A583E-70CF-465A-BB77-53ADFCDB5883,OCMR_DXE +4735EC40-F0B8-4102-A4C1-2E83B6B0C0BD,FchHuashanDxe +473BF006-83E1-4B25-BC6A-DA8A20555B59,TouchPad_Sensel +474933A5-E26E-4722-8BA8-851D0154228F,FjHddErase +4759E93E-8F44-448F-88A1-BD97FC47BEA5,AmdPspP2CmboxV2 +47727552-A54B-4A84-8CC1-BFF23E239636,Tcg2PlatformPei +47727552-A54B-4A84-8CC1-BFF23E249637,XmlCliCommonPei +4772C6DA-506D-4C95-AC17-AE66885F6D53,DellGpe +4776E33F-DB47-479A-A25F-A1CD0AFAB38B,EfiKmsFormatAesxts128Guid +4778683F-B2BD-46B9-BF34-1BD00D5EC7F5,AmdMemoryHobInfoPeim +47889FB2-D671-4FAB-A0CA-DF0E44DF70D6,EfiPkcs7VerifyProtocolGuid +478C92A0-2622-42B7-A65D-5894169E4D24,ELabel +478FCDAD-760E-426C-869B-2F3345051750,DellHddSmartDxe +4795255C-7031-473C-AF8A-8BC7701ACCA5,fTPMAcpi +47970A28-8F4A-4CB2-91DE-BF344153189A,AmiCspFlashLibNull +47AA8FEE-48D0-11E4-A6D3-B8E8562CBAFA,SpiLockDxe +47AE3255-FA69-459F-D334-D8A57BF952A4,IspI2cMasterDxe +47B2138F-5A6B-4C65-9167-8740595D16AD,DellPasswordMgrSmm +47B7FA8C-F4BD-4AF6-8200-333086F0D2C8,EfiSmmReadyToLockProtocolGuid +47C1AC56-67DA-4BB0-BDFD-C4DB6CB9EEAB,ConsoleBootMsgDxe +47C7B221-C42A-11D2-8E57-00A0C969723B,EfiShellEnvironment2Guid +47C7B223-C42A-11D2-8E57-00A0C969723B,EfiShellInterfaceGuid +47DCFD49-F110-4EF8-98D4-D8C8883270DA,D01IhisiSmm +47E83D0C-2AF4-468D-9191-9CE468C18E9E,DellSmmPchGpioControl +47E87E67-FBC0-4C01-9002-4A0A6ECB92FF,AmiTseOemPortingVar4Guid +47EA2673-2533-4C07-AABA-69CE5A7C5D35,FspInit +47F229F9-C316-41A3-9F39-69EE22A4E8A8,LenovoEDU +47F48C99-CB23-4CF8-9D7D-CE7C86EF22A3,UsbTouchPanelDxe +47F8F645-8DEB-4304-BEE5-BA87D6C680E9,DellTcg2Pei +47FD99EB-C1E6-4F77-A31A-9F7FB4A8E7DE,menu_down_arrow +4807FC5F-CBF5-424A-869F-A63A133735BC,CvpCore +480F8AE9-0C46-4AA9-BC89-DB9FBA619806,EfiDpcProtocolGuid +4810C827-B373-47C6-B53E-AAD30E197CA1,LEMPostFlagSMMProtocol +481E9536-A9D8-4AD7-B2BD-27BD10E48D05,AmdDashPei +482D38C8-4A36-4242-4F03-7EAEC04B76EB,AmdSocFp6RnPei +48301049-EFDF-4DD4-8962-E26586123ADF,AmdMemoryHobInfoPeimRmb +4839023B-4C12-4EB2-B2B8-C91B42D878A0,IsctAcpi +48441C12-74EA-4FBD-BD1F-199CF39C5BE4,Kb902xFlashSmm +48459B6D-0E45-46AE-B5C4-E701A25A0D6D,PlatformCrisis +484C77C1-378E-41E4-B4F1-08A1555FB197,AsusWatchDogTimerDxe +48569430-485F-4ACC-A184-B35D11CB7560,AmdCpmUcsiDxe +4862AFF3-667C-5458-B274-A1C62DF8BA80,HeciInit +4866788F-6BA8-47D8-8306-ACF77F551046,FspNonVolatileStorageHob2 +48705A28-FF4E-4573-8164-A026963D801F,LenovoCapsuleUpdateVariable +487647C2-3D08-4D02-9AA4-7CE4F7BD5A7B,PlatformSmiSecureCheckSmm +487784C5-6299-4BA6-B096-5CC5277CF757,EdkiiCapsuleUpdatePolicyProtocol +487AD797-E10F-4BAF-9144-660AB11C2E29,WiFiLauncher +4882FE88-7AC6-418F-BEC4-3AF4373A3374,FjBootVariableCheck +48925241-D2ED-46D4-8A87-A18D153C2802,SmmOemEeprom +48959D4F-4574-470E-AA4C-CF144D1C1678,InstallVerbtableDxe +4896840D-46BB-412B-A30A-A62ABFB3682F,SpsAcpiSsdt +489E23AB-F146-40D2-931D-90275F151DF1,EzTpmUpdNtcTpmFwUpdDrv +48A2E1DF-F2D4-490D-8677-F7A5C6FCC96A,USBIdm +48AB15DF-8693-4E84-91FA-2763137B8E52,FjGabiSystemMonitoring +48AB7F57-DC34-4F6C-A7D3-B0B5B0A74314,EfiIa32X64ErrorTypeMsCheckGuid +48B05831-3298-49CC-86CD-3020D95381E7,ConfigDataUpdater +48C7F9E6-8F68-49DE-B698-0D6A014890F7,SiInitPreMem +48D51913-F340-4798-83D7-5CAB3D5C6DA7,AppleEffaceableBCENOR +48D65EC7-8B1E-4965-9AC2-B7AD627209CE,SaveMemoryConfig +48E40CAD-A6D2-4756-8AEB-81F468D4A856,Tpm20ShutdownOverrideguid +48E796BD-4ED3-4755-A8CA-4CF437258241,EfiPeiPlatformTypeNeonCityFpgaPpi +48ECB431-FB72-45C0-A922-F458FE040BD5,EfiEdidOverrideProtocolGuid +48F40D93-AF30-4410-9F4A-FF61947E3F62,MAPS_WatchDogTimerPEI +48FB21BF-47E5-406C-A73E-D83D00767214,FwhFlashPeiLibNull +48FBAE5F-09AC-4BDA-AFD8-B30884B2422A,AfterG3Init +4904B42F-9FC0-4C2E-BB3F-A2AB35123530,DebugAgentLibNull +4906415D-4B32-4D28-8557-21C390D76A3C,DeleteUefiCaFromDb +490D0119-4448-440D-8F5C-F58FB53EE057,PolicyInitDxe +490E9D85-8AEF-4193-8E56-F734A9FFAC8B,PeiSerialPortPpiGuid +49152E77-1ADA-4764-B7A2-7AFEFED95E8B,EfiDebugImageInfoTableGuid +49174342-7108-409B-8BBE-65FDA85389F5,SmiHandlerProfile +492261E4-0659-424C-82B6-73274389E7A7,DellRaidRom +492CB3AE-66DB-4F1E-91AE-534C48F2F83D,WheaSupport +492F48F1-D0EE-41E9-BBE8-92C98A3CB7F1,FchTacomaSsdt +492F92B4-F0EA-4875-9C59-80CED0B90A31,M24Lc256Pei +49328871-FE65-4586-A013-0ADAAEA1DAFF,FvbServicesRuntimeDxeRA +493B5BAC-BB9E-4BF5-8379-20E2ACA98541,EfiSaInfoProtocol +493D3613-845F-413C-A7C5-1BD890CDC4E1,AIMTBatteryInfo +4941D466-4042-4C49-2B8B-8C83834C1379,PegaPeim +49450E14-2BA1-40E9-9755-6FE327F8E022,DeviceChangeDxe +49462CB7-0CFF-41AC-B139-51DFF93D8140,TrackPointElan +4953F720-006D-41F5-990D-0AC7742ABB60,IntelGigabitLan +4953F720-006D-41F5-990D-0AC7742ABB61,Intel10GLan +495AA584-63D4-45F0-A4EF-36042B19A201,AppleVariablePolicy +495D1734-05D3-400F-AF35-C8BCD3B85CC3,DellSmmSysBootDevicesPolicyProtocol +4973D70C-1A94-412A-A3E1-2A4C98782BFA,OemDisplayRule +497E8A5D-C807-420F-8D85-47E772C7E6E4,IwlTransDriver +49818FD1-7413-4C71-84CF-6BFE670C6496,PEbiosinterface +49970331-E3FA-4637-9ABC-3B7868676970,AcpiPlatform +49AEACA9-69BB-4EB2-B5F9-1BF9E2508779,FchTacomaPei +49B7F3E1-6C08-4A5B-911C-E9E397ED4178,AcpiVariableHobOnSmramReserveHobThunk +49BA7EEB-49F4-4BB4-85DE-FD4FE7369E58,PlatformCpuPolicyPei +49BEA775-FB94-455D-9826-8DB4A04DBD02,POSTCODE0A_BASEFWUPDATE_DXE +49C6AC30-F172-4EA4-8599-3925855B4D47,DellDiagLedSmm +49E6316C-CC1D-4978-B889-FFAFC5C61D0C,FjErrorDisplay +49EA041E-6752-42CA-B0B1-7344FE2546B7,ArmTimerDxe +49EAB1A6-AF2F-4064-9B29-D9655B3B8DED,DellAmtConfigPei +49EDB1C1-BF21-4761-BB12-EB0031AABB39,EfiPeiFirmwareVolumeInfoPpiGuid +49F71D68-D464-435A-9C95-11325BACEFE6,QuickI2c +49F8C35C-B9EF-402A-AB44-871C139EB00D,FastBootSetupDxe +49F8D341-339B-4E88-A1CC-7FFD00343C59,DellS3ResumeStatusCodePei +49FC00CF-BBD2-4FD4-B9D1-F084A51EB708,ApobSspDxe +4A0266FE-FE57-4738-80AB-146E46F03A65,EfiWheaBootProtocol +4A033533-D570-43F6-BA84-61CBA70165F8,DellUefiClass3ConfigPei +4A0C7D11-CA7F-4C59-8659-6BDA5132A5A8,DtprDxe +4A0F0F08-EE19-4FE2-85B1-9AB4718D17D0,BiosSelfHealingSmm +4A153B6E-85A1-4982-98F4-6A8CFCA4ABA1,EfiExtendedSalSensorServicesProtocol +4A1A67D0-E77A-4F0A-AF1D-CC412BE93DC9,AmdCcxZenZpDxe +4A1D0E66-5271-4E22-83FE-90921B748213,EfiDxeIpmiTransportProtocol +4A2B80A1-6573-4691-AD18-56704DB74A59,HpSmbiosDoneSmm +4A2F3948-C40A-469D-86E7-4EDC54133B46,FchKernDxe +4A3602BC-1A05-4C82-99B4-588CD2A32CD5,LegacySredir +4A37320B-3FB3-4365-9730-9E89C600395D,SmmDispatcher +4A3CA68B-7723-48FB-803D-578CC1FEC44D,AptioFwCapsule +4A3E00AD-B667-4054-95B3-2E8F305BD6DD,PostMessagePei +4A3ED697-E9BC-40FE-BDD5-6F99FCDCE9F4,AmdNbioAlibZpDxe +4A436225-A1B5-48E1-828C-4E8E625F3ED6,FjGabiEntrySmm +4A49FE16-F432-4B93-A722-932432A20BCF,EFI +4A4CA1C6-871C-45BB-8801-6910A7AA5807,BiosInfo +4A4ECE10-61EB-4FC4-8839-F7CFDD962074,IccPei +4A5227D3-0BEF-4CAA-ACBD-EC84446C5C6C,MiscGaIoDxe +4A538818-5AE0-4EB2-B2EB-488B23657022,FvMainCompact +4A59F1EA-A18D-40A6-8717-C16DC5A6ABB6,PchCrashLogAgent +4A5CA267-4016-460F-80EE-7B4C3D77FD62,DellUserInterfaceDxe +4A64C620-1CEF-40A0-BE1C-EED6B20ECCE9,MrcHealthDataInit +4A64F200-F99C-42F3-80C7-0D91E2D3EB5D,SioGpioControlDxe +4A69756B-209B-4D57-8810-142DAC6BB7B5,FchSandstoneSmmInit +4A6D890F-93C3-4B6D-A67D-5F2C4DCE347B,RuntimeSmm +4A785A9F-FE09-405D-FFFF-FFFFD7BD2694,XnoteGopVbiosDxe +4A88EC66-0570-4AE2-BBBC-335A5C9BC287,CsrRegTableDxe +4A8FBED0-78BB-4382-9C6D-D1429190003A,CoreDefaultSettings +4A935D71-7D9E-4423-80E5-F8F8F4043F9C,ReadyToBootNotifySmm +4A9B9DB8-EC62-4A92-818F-8AA0246D246E,MiscSubclassDxe +4AA65902-3ED3-43B3-A52B-FC1D6C077AE4,AhciBusPei +4AAAE990-5F1C-4BA3-B0CE-66754D383521,NvmExpressLegacySmm +4AAFD29D-68DF-49EE-8AA9-347D375665A7,EfiCertPkcs7Guid +4AAFE3AA-DEEE-4D81-80F3-82D226C71C4B,PvScsiPassThruDxe +4AC94F68-E651-4B38-A1D8-2D5DEFFA0F60,HDAudioSmi +4AC99A7C-1DCF-4A51-8F06-5EEDFE8A8864,CryptoServiceRuntimeDxe +4ACA697E-F883-446F-98F7-096416FFFFFF,OhciDxe +4AD920EF-4D6F-4915-982A-DC16677131D5,EfiPeiPlatformTypeCrescentCityPpi +4AE7E1E8-9DFE-4E3E-85B4-A5F6ABD470FB,Cpuid +4AEDAA65-00F5-42F8-B737-B6BD1A4B5C48,FlashUcAcmDxe +4AF92599-8E76-4BB4-BFD2-F5A66E3041D4,EfiOcData +4AFA46F5-F97E-4A48-B761-7979FAFCC4F1,PldmSmi +4B0165A9-61D6-4E23-A0B5-3EC79C2E30D5,DxePchPlatformPolicyProtocolGuid +4B1D21E9-4DCA-4820-8112-61E52B815EC1,RtCommonService +4B215191-9A25-43FD-86B5-74E7AF723315,AmiNvmePassThruProtocolGuid +4B26CDB7-EFD0-42AE-9211-8C1711C3695B,PcdStatusCodeDxe +4B28E4C7-FF36-4E10-93CF-A82159E777C5,ResetSystemRuntimeDxe +4B3029CC-6B98-47FB-BC96-76DCB80441F0,EfiDiskInfoUfsInterfaceGuid +4B3082A3-80C6-4D7E-9CD0-583917265DF1,AmiSmbiosNvramGuid +4B3828AE-0ACE-45B6-8CDB-DAFC28BBF8C5,VAROEM +4B41EB16-9EF1-4CA8-8DF2-8485467BA977,KEMhDisp +4B47D616-A8D6-4552-9D44-CCAD2E0F4CF9,IScsiConfigGuid +4B490AFA-F1C7-487A-8812-EF2DA0CEE92C,AmdFabricMdnDxe +4B4D31BE-88C6-446A-A4A9-4AD0F612B32E,EvaluateDefaults4FirstBootGuid +4B4F517C-0145-4783-A1D7-018D20797555,PciHsUartDxe +4B562E45-2EB2-4E5C-BF2D-5763F4304DFB,UsbMassStorageSmm +4B5DC1DF-1EAA-48B2-A7E9-EAC489A00B5C,EdkiiBootLogo2Protocol +4B5DE05E-16F4-11ED-861D-0242AC120003,EcFmpCapsuleDxe +4B5F17C7-B567-4E47-BF3D-E4C21EF33497,ExpansionSlotConfigPortingDxe +4B63A5D4-CB08-47CD-AFD9-BEA33A30F313,CrashLogDxe +4B63A5D4-CB09-47CD-AFD9-BEA44A30F315,PopUpRework +4B680E2D-0D63-4F62-B930-7AE995B9B3A3,SmBusDxe +4B6B21A1-F26B-404F-8694-DB1C63A1D92A,LenovoAt24Rf08EepromSmm +4B6E1294-08D2-4131-83E4-14BE9FCD42C1,AmdMemRestorePei +4B709C41-2066-4684-A92A-CFAE7C7563FC,UpdateMsrSmi +4B837B03-6587-4D19-B82B-EDFAD836C0A0,SecMain +4B844201-6FE9-41D1-B46F-DFFC34E492A2,EfiDprRegsProgrammed +4B87C89B-39A9-478F-A4B6-816A9EDC5087,DellVariable2Dxe +4B8C9600-9958-443D-BE30-F4B7A7E53463,DxeSmartPowerOn +4B94F4FD-8FB9-4CF1-A0D8-EA03B4467BE2,OemThermal +4B9D17B3-4DC9-45D9-8F06-BDD3F9A45E5C,AmdI2c3MasterDxe +4BAED146-B579-4959-8150-F93F1C7A0B68,IntelGraphicsPreMemPeim +4BB346D2-8076-4671-8BC9-7B95CBB9A6DF,MonoStatusCode +4BBAF21C-98AD-421E-B53C-9EC2E8A87A29,AmdPlatformRasRsPei +4BC80B15-255D-4858-8072-51D6D98CF90E,SetHostName +4BCB4D93-46D2-94EF-BB82-5C8671B24D26,CxlErrorLogDxe +4BD01172-54D3-4A97-B6A0-DA57474CDF3C,FjGabiEntrySmmBin +4BD0EB2F-3A2D-442E-822D-753516F75424,PchInitDxeTgl +4BD56BE3-4975-4D8A-A0AD-C491204B5D4D,EfiAdapterInfoUndiIpv6SupportGuid +4BDE935B-7700-4E73-823D-AF9B402270AC,CloudBootCreateEmbeddedBoot +4BEB3357-F146-4E10-9F60-E4797906AFDA,PostMessageConfigUtilDxe +4BEB96B4-C069-4C49-845F-1C1CC68CD8D6,FchShastaSsdt +4BEECAFE-5F02-432E-44B9-3CA5CA5DF189,AmdNbioBaseSspDxe +4BF759DC-8DC5-4B66-B3B1-37B7F9185B61,TDP1204 +4BF98E30-17E0-11E9-B56E-0800200C9A66,ThermalSensors +4BFFC0D3-7E33-4370-8A28-3238FC33AD2F,DataStorageSmm +4C006CD9-19BA-4617-8483-609194A1ACFC,UsbInt13 +4C19049F-4137-4DD3-9C10-8B97A83FFDFA,EfiMemoryTypeInformationGuid +4C26DF71-EBE7-4DEA-B5E2-0B5980433908,GetAddrInfo +4C47E0B5-E369-469F-B359-28DBD736A131,PspSmm +4C494E55-5849-5342-4554-544552212121,SlpSupport +4C51A7BA-7195-442D-8792-BEEA6E2FF6EC,EfiLegacyBiosThunkProtocol +4C5C6A74-BAB7-46D6-8688-3B2E7F246E3F,SataController +4C612C0F-2CC9-4275-9484-C73FA66CA987,FjMacAddressPassThroughDriverBin +4C61D013-ECA5-4785-9625-B267A00E7721,LenovoTrustedDeviceSetupUIDxe +4C61D329-7746-40B4-98D0-54514A41AC22,PublicWmi +4C6E0267-C77D-410D-8100-1495911A989D,MetronomeDxe +4C7D1568-CF73-4676-A079-16F7F9600CCC,LenovoSecuritySmiDispatch +4C7E45BC-8A23-26CD-94AD-5D2C263F25FE,EfiIioRasProtocol +4C862FC6-0E54-4E36-8C8F-FF6F3167951F,FaultTolerantWriteLiteDxe +4C8A2451-C207-405B-9694-99EA13251341,EfiDebugMaskProtocolGuid +4C8BDF60-2085-4577-8A46-96CB180967BC,Tpm20Acpi +4C91B810-A28D-4BBC-BDF0-30A9C6C7EEC2,OemLOGO +4C9BA841-0A69-4567-9E37-42CBF5F7F269,OemGlobalNvsDxe +4CA16857-A0C5-4E46-BE0F-98A4BB314E5D,MemTest +4CA8A1EF-D4DA-4212-9F4D-41638E68B6C1,MemoryStorageChipsetDxe +4CBB6611-3608-492B-92A7-DD92FD6FE4FE,OEMBOARDPei +4CC14F19-C626-4AB6-9DEA-CA6C01FD10CD,AsusHeader +4CC771CB-777B-4F64-B0F9-C70ED4355D1C,MediaCradReaderConfigSmm +4CD28F5E-4BBB-4602-ACB8-741BAA7EB313,AmiTseOemPortingVar19 +4CD97B67-12BB-4FC5-8B2A-580ADB6A6368,AmiTseOemPortingVar12 +4CD9A941-CEF5-4940-9C1C-C5C33C27024B,ODMPowerLedProtocol +4CDF832E-1487-4EB5-BCBA-FE6D3849C74D,PdSolutionPei +4CE9D7AE-61B2-4461-9446-AB0376B4A7F7,FboSce +4CEC368E-8E8E-4D71-8BE1-958C45FC8A53,EfiSmmPeriodicTimerDispatch2ProtocolGuid +4CEF31DA-8682-4274-9CC4-AEE7516A5E7B,CapsuleApp +4CF36A40-5726-4A67-A94C-2CC87822E760,HpDtDxe +4CF484CD-135F-4FDC-BAFB-1AA104B48D36,HfsPlusDxe +4CF5B200-68B8-4CA5-9EEC-B23E3F50029A,EfiPciIoProtocolGuid +4CFD8C50-6368-4398-A7C7-ECCC2C51E152,CloudBmrDrv +4D00EF14-C4E0-426B-81B7-30A00A14AAD6,NandFlash +4D06B832-6987-40F2-B76D-D170B42DB182,TrEEPhysicalPresenceDxe +4D09FDA2-AE1C-4D47-9CD1-6B548A15CACA,EfiPlatformTypeWolfPassProtocol +4D0E0FBB-AD24-4213-B9B4-692B6662CB36,FjTpmDisable +4D0EBC36-88D7-492C-AF46-677BA21F6D81,SetupConfigUpdateDxeCLX64L +4D1514D2-FBDE-49C6-B20A-A40288A0D4AA,HstiIhvSmm +4D1EFB42-6A65-4C9C-81A7-FE2A6B885DA8,EventLogPei +4D20583A-7765-4E7A-8A67-DCDE74EE3EC5,HttpBootConfigGuid +4D2ADE73-B751-4C68-9FA2-61909EBC59EA,KEMhMarsDxe +4D2C22F3-C0E5-419E-8978-BC9C3CF843A8,DellFmpGbe +4D2E57EE-0E3F-44DD-93C4-D3B57E96945D,CpuS3DataDxe +4D330321-025F-4AAC-90D8-5ED900173B63,EfiDriverDiagnostics2ProtocolGuid +4D35A5A7-622E-4955-A5D2-CDA812940D74,FwBlockService +4D3708A0-6D9B-47D3-AD87-E80C781BC0A7,AmdApcbDxeV3 +4D37DA42-3A0C-4EDA-B9EB-BC0E1DB4713B,PpisNeededByDxeCorePei +4D392BA5-2BAA-44F9-96C4-DA443A6F3483,PhMicrocodeCheckPei +4D3AC0C9-5871-41E5-A6C8-171CDF5A6463,DL3x00UsbUndiDxe +4D426243-BB19-4F62-9D37-A6D92DCC2628,SmbiosOverride +4D478675-9D19-4EB2-9960-CBC88D6C3935,PlatformHmacShaSmm +4D48238D-6A23-4BEB-ADA2-D24FD833CC2C,HashService +4D4861C1-A82E-4E5F-9DD8-B00B30B84DDC,HeciTransportSmm +4D5640E5-2702-4DF8-88F4-564886FC43DC,PeiTxtScleanPpi +4D62B5E9-71C8-412A-8604-878C921D9AD1,SystemErrorLogSmm +4D6C0496-8DE4-4AF2-9A2E-9BE5B9156AC5,AmiPerfTuneDataHob +4D7161BC-BE35-43AF-879B-956EB37983D6,AmiMemoryPresentFunctionOverrideGuid +4D7267F0-F48C-4050-AE55-8FE1708096A0,ASRockNetFtpBin +4D72D689-CB91-4248-A60E-333C98276DDE,FjDeviceFwUpdateDxe +4D7C01B0-495C-4070-B0AA-875A64E61C67,FjHddSmm +4D85D326-58E0-43FD-9F63-58DF46789B7F,PciResourceAlloc +4D8B155B-C059-4C8F-8926-06FD4331DB8A,GetPcdInfoPpiGuid +4D8B77D9-E923-48F8-B070-4053D78B7E56,Tpm12DeviceLibTcg +4D922231-4F16-468F-A771-A1E5C29713C9,OemDisplayRule +4D9CBEF0-15A0-4D0C-83DB-5213E710C23F,Tcg2ConfigDxe +4DA62F29-32BA-4470-94FE-D7C84260D427,SecureBioXhci +4DB83B45-9CA8-41ED-9FC7-C3FC00267B8E,CountryCode +4DC2E02D-D5FB-4330-BD53-53797347DF01,HwmFanDxe +4DCAAB0A-1990-4352-8D2F-2D8F135598A5,EslTcp4ServiceGuid +4DCBF9BA-DEC1-42B0-8A09-01555694F6CF,GbtCustomizeButtonSmm +4DCD2C72-ECBD-4F47-84BB-2B3BD2BFF90B,UsbCrisisEnumPei +4DCE95D9-37A9-4DDC-8143-326CE9A49B3A,AmdSocFp8StxKrkDxe +4DD4DF07-3278-406F-B5DE-EC7EECC650E1,CrbPxeUefiDriver +4DDA8138-47CD-4019-9178-115003431B21,SWSMI_Shadow +4DDD67E7-BDF5-4473-8AB0-02821C084338,MemorySelfRepair +4DE01DE6-7CBB-4786-9F2A-9B9C7C97AC06,S3RestoreAcpiPei +4DE67E0A-162C-4999-A5B8-BA0E5D43284C,CmosChecksum +4DE9A180-FA40-4899-AB66-4E6325B0315D,GpioExpanderDxe +4DF17188-F320-4715-82DA-A05DEF51F111,AmdCpmOemInitPeim +4DF17188-F320-4715-82DA-A05DEF51F1D8,AmdCpmOemRvInitPeim +4DF19259-DC71-4D46-BEF1-357BB578C418,EfiPs2PolicyProtocolGuid +4DF53F89-D421-4F9D-8392-BE3BECC6288E,AhciInt13Dxe +4DF590C2-43CB-4ABE-BE51-0B55D3000EA6,SystemSetupCapsuleFromStorageDxe +4DF75915-6C88-4EF4-995D-834D866DBD20,CpuSetAgesaPcd +4DFA1C9F-D98D-43B9-8832-059CADEBE436,PeiPortingSample +4E02A019-85B1-4EC9-9A38-B7DF0508397C,OemMFGDonePcd +4E0F9BD4-E338-4B26-843E-BD3AD9B2837B,PRKeyGuid +4E11E955-CCCA-11D4-BD0D-0080C73C8881,EfiWinNtGopGuid +4E1356C2-0EED-463F-8147-9933ABDBC7D5,EfiKmsFormatRsasha2563072Guid +4E173307-92DB-4A4F-9A8E-86A85649B405,EfiAdminPasswordHob +4E1C4F95-90EA-47DE-9ACC-B8920189A1F5,SecPeiFspPlatformSecLibSample +4E2066E9-7C76-4B59-A30C-4AE1E2DC7F75,DellSmartAmpSmm +4E23D5B5-BF03-4CE1-B295-13E615D13A61,MpmPldmBase +4E245C15-66E1-47C4-92B0-0F5727591720,UnlockNextHddUserPassword +4E26451F-1989-4E2E-8D79-68947FE878BB,SDCardReadOnlyMode +4E28CA50-D582-44AC-A11F-E3D56526DB34,EdkiiPiSmmCommunicationRegionTableGuid +4E292F96-D843-4A55-A8C2-D481F27EBEEE,EfiEventNotificationTypeCpeGuid +4E304BC0-3B03-4A97-BB55-91375189A31D,iFlashDxeBin +4E32566D-8E9E-4F52-81D3-5BB9715F9727,OvmfPkKek1AppPrefix +4E348EF9-F02D-4DFB-847C-FC5CA755E426,FchSmmDispatcher +4E37AEAE-F9D7-464D-9969-0FFBEB6F423F,AsusRomLayoutDxe +4E3A82E6-E43F-460A-866E-9B5AAB804448,EslIp4ServiceGuid +4E3F9A17-ACA9-42F3-A8CC-E7340FB6DB6E,MemTopology +4E4E97F9-63FF-4BDA-90BB-C6F943FA5100,PlatformStatusCodeHandlerSmm2 +4E509696-E33F-408E-9AF5-CC8C20065385,SoftwareGuardConfigGuid +4E537B6B-C6A9-474F-A023-D512CD141A83,QrCodeGeneratorDxe +4E5B4FEA-936A-45BC-AC6A-2F8F14A6C29E,PrmConfigProtocol +4E613EA8-C01C-4BA7-BA09-38BD86815F85,FjPasswordServiceSmm +4E694D04-318B-4F89-A3B3-BA3560FD389E,HddSetupVarDefaults +4E6D9DEE-CAB0-413B-9F6E-59869DD364F6,CmosInterfaceCoreDxe +4E75CCB0-A653-4C76-A213-5B2DBCD2A9EF,TouchDriver +4E76928F-50AD-4334-B06B-A84213108A57,NtFwhPpiGuid +4E77C4E1-7879-4A1D-8A88-584BC2CD58C5,HpTriggerEfiDriverLoad +4E7AF417-C200-400A-9D18-865ADAD30896,AmiDddtPresentFlagHob +4E82091E-32A1-4689-8A00-CDE41ED63CDD,SioDxeInit +4E873773-8391-4E47-B7F4-CAFBDCC4B204,EfiDmaRemapProtocol +4E88068B-41B2-4E05-893C-DB0B43F7D348,FmpDxe +4E8EEBDC-CF55-4FB6-AA77-984AB53DE823,EmmcSoftwareTuning +4E8F4EBB-64B9-4E05-9B18-4CFE49235097,EfiMemorySubClassGuid +4E939DE9-D948-4B0F-88ED-E6E1CE517C1E,EdkiiIoMmuProtocol +4E98A9FE-DF5A-4136-B922-4FB970CBD733,CpuSmm +4E9BF661-4891-F0DF-2718-2EB41EAB5E43,CpuPowerManagementSmm +4EA43463-747C-46EB-97FB-B0E5C5F05306,UsbMouseAbsolutePointerDxe +4EA97C46-7491-4DFD-B442-747010F3CE5F,Main +4EA97C46-7491-4DFD-B542-747010F3CE7F,HpNetworkTransferWorker +4EA9D4FE-E6F6-410B-8037-0F98B5968B65,NbciEfi +4EA9D4FE-E6F6-410B-9037-0F98B5968B65,Mxm3Efi +4EB6E09C-D256-4E1E-B50A-874BD284B3DE,FspSiliconInitDonePpiGuid +4EBAAA68-EC78-4AF4-B5A8-6E9A9ECCF3FF,CombinedFWUpdate +4EC8B120-8307-11E0-BC91-0002A5D5C51B,PL011Uart +4ECB6C53-C641-4370-8CB2-3B0E496E8378,EfiExtendedSalVariableServicesProtocolGuid +4ECEC19C-6E5F-4815-8342-B55F2CC5DFC1,LenovoVproHiiDxe +4ED42C6A-AC97-46C9-9758-E1FA769D3AFA,OemIceSetup +4ED4BF27-4092-42E9-807D-527B1D00C9BD,EfiHobMemoryAllocStackGuid +4ED73FC1-3AE7-4BAF-98DE-9F2AEEAA00AF,FjS5WakeSmm +4ED88276-D4DF-4D03-8661-295801B2DA58,FastBootExceptionInfoHob +4EDD7BAF-BA98-47D8-85BF-831D98E786CD,Sdev +4EECDF66-C506-4458-9C0D-70021828FB31,SpiProtectionSmm +4EEF2D60-0E00-11DE-8C30-0800200C9A66,SataController +4EF83446-DCC5-46BE-A9A8-870390A6E28B,AmdAblPerformanceDxe +4EFA0DB6-26DC-4BB1-A76F-14BC630C7B3C,AmtForcePushPetHob +4EFA14DD-2A34-491C-B81E-7D05B210FCFA,RemapPwdPei +4EFC51DA-23A6-4790-A292-4985C7F5CDEF,LenovoComputraceEnablerDxe +4EFDD949-E871-4A21-96B6-B161B271B9BF,BiosIdentifiedInfo +4EFFB560-B28B-4E57-9DAD-4344E32EA3BA,MiscSubclass +4F08F6B4-640B-4F54-840F-F225BD00B9F3,SpiFvbServiceDxe +4F0DB016-304D-4E82-8551-7D2F39436D24,EmulatedEepromSmm +4F0F582E-6D6B-4BC0-9088-1819BAAF82D8,SystemBiosSelfHealingTestPei +4F11EC16-E52C-4C68-A34D-C83F4A453FF9,XnoteEspPeim +4F1F379F-2A62-48BB-AC34-D3F135C6E2B7,PcatSingleSegmentPciCfg2Pei +4F20C254-75D0-437C-93AB-CD2F88795E88,FjGabiIntrusionAbstraction +4F383D8B-A40E-44B6-85E8-F094BE746F88,FjIbvSfuControlAbstractionSmmProtocol +4F44FA64-A8D6-4C19-B61D-63109D77D3D2,AmiVerifyTcgVariablesGuid +4F4EA4C0-8603-4AB8-8C4B-C5145C8C86F6,RaidDriverSmm +4F4EF7F0-AA29-4CE9-BA41-643E0123A99F,HiiResourceSamleFormSetGuid +4F4FF580-B8A0-4332-A6B0-E2E568E36C9C,ASFVerbosity +4F51C243-7CEE-4144-8EED-234AC2DABD53,EfiPeiPlatformTypeLightningRidgeEX8S1NPpi +4F5890C7-F90E-42BA-9778-551BB6E51216,Dec1515Dxe +4F6878EA-FD51-48B2-9962-5CEFBBF6CEA2,TccDxe +4F6C5507-232F-4787-B95E-72F862490CB1,EventExitBootServicesFailedGuid +4F6DBF89-C97B-4F60-8178-22A82F96D062,MeLockStatusDxe +4F745D41-5598-4CF0-8A0A-923813DF9554,SmmUsbMassStorage +4F745D41-5598-4CF0-8A0A-923813DF9555,M2Smm +4F745D41-5598-4CF0-8A0A-923813DF9556,SmmCsm +4F792E68-E8C8-794E-B1D8-3703F3F2D5A5,EmulatorPkgTokenSpaceGuid +4F803CD9-3014-433E-9921-79BD8F6EA3E0,UcsiRefactorPd +4F821C7C-8E33-412A-AE63-D149F376CD1B,SmmWheaDxe +4F84E985-4C3B-4825-9F42-889109019422,GopConfigPei +4F874E36-4736-332F-B75A-BA8753217CD9,SioSmiDispatcher +4F89E208-E144-4804-9EC8-0F894F7E36D7,EfiPeiSectionExtractionPpiGuid +4F9147CB-972E-4F5C-B869-A02182C9D93C,PataController +4F921013-4F71-4C6C-BCF8-419B2B801932,SetupBrowser +4F948815-B4B9-43CB-8A33-90E060B34955,EfiUdp6ProtocolGuid +4F95E00D-6B84-40D1-B2A2-FDF718537183,WlanPei +4F967D7A-D55F-4B53-BDD9-269A80785D16,AdlSemaMiscellaneousDxe +4F9883C7-B309-4152-ACF3-223850478D88,SmcPkgTokenSpace +4FA09F49-AE5F-4D7E-870B-080030E1B63E,FvBbPei +4FA7E1F2-CE8B-4D38-A3F8-342DC4515446,IioCfgUpdateDxeNeonCityEPRP +4FAB12FA-21D5-42A2-8260-E0CFA50C899B,MonolithicCapsuleDxe +4FB0D5AF-D140-4078-83B5-39013075CEBB,FjBeepOnPOSTPei +4FB2CE1F-1A3A-42E3-BD0C-7B84F954189A,AcpiCallbacksSmm +4FB2F0D0-7183-4BFC-9E65-11A4031847D2,AmdCpmPlatformOscTableInstall +4FBB790E-71E9-42FF-9F8C-469C4FD0A04A,OpromCallback +4FC0733F-6FD2-491B-A890-5374521BF48F,AmiBoardInfo2ProtocolGuid +4FD14235-47A1-E350-123F-75925306279D,AmdSocAm4RnDxe +4FD1BA49-8F90-471A-A2C9-173C7A732FD0,SeCfTPMPolicyPpiGuid +4FD2D553-DABD-4C17-ADC1-32C8F3EDAAD9,LcdShadowDxe +4FD49958-F29D-4019-80F6-0700699D9540,OemWwanSmm +4FD5F726-BED2-410D-9097-C679DE190854,SetupLoadDefaultShp +4FDBCCB7-E829-4B4C-8887-B23FD7254B85,EfiRedfishPkgTokenSpace +4FE0ADEE-606B-4375-90B5-65698DFD0B9B,IntelUefiRaidDiskInfo +4FE772E8-FE3E-4086-B638-8C493C490488,PhysicalPresencePei +4FEBE43F-256E-4C82-A20A-BC0D03C72185,PTN3460CfgPei +4FED14B0-2B0C-4E20-9071-61094B1C4B55,EzFlashInterfaceWrapper +4FEEDBF2-3E3C-4D99-AD5F-D92195DDEDD6,FjWatchdogGHO +4FF26BC4-694E-4994-89C2-E9E44690D174,HpNvErrorLog +4FF2E88A-A404-46F7-9A2A-35E00844F6E6,SpiDeviceDxe +4FF3AA5B-105C-4409-87CD-59C15B7FC5D8,DellGlobalNvsDxe +4FF7A6BC-EE56-407B-A593-999294C615FC,DellErrorMsg +4FFF2014-2086-4EE6-9B58-886D1967861C,SecPeiDxeTimerLibUefiCpu +5007A40E-A5E0-44F7-86AE-662F9A91DA26,FvOnFv2Thunk +500CC042-E300-4759-9211-868B9AD0E207,FjUIDxe +5011522C-7B0E-4ACB-8E30-9B1D133CF2E0,FmpAuthenticationLibNull +5014B9B7-B3FE-4D0D-8F5A-2B27132B7779,AdvBdsDxe +501BD93A-F1A9-4F4C-A946-7867DF975537,LenovoEn25Qh64FlashPartSmm +501C5B87-8181-4AE5-A6B2-D05ACE0D83DE,SmcOobPlatformPolicyCallback +501F30E9-D14F-47DA-AE60-B101E4189D07,AhciInt13Smm +5023B95C-DB26-429B-A648-BD47664C8012,AmiMediaDevicePath +5029FBE0-39E9-43F8-A9F0-E78E1789FC27,SystemSwSmiAllocatorDxe +502B04F3-71AB-47B4-BEAE-4736EA190AA4,PciDxeInit +502D4D8C-E607-4613-B187-3ACAB0169AD7,DellDualBootBlockDxe +502D8541-01BE-4FB3-8986-3F9916548164,DellTpmSmm +503A80A4-34C3-47B4-BB6E-00AD1F36CF47,AmdLegacyInterrupt +503E70FE-047A-410B-A55F-4F63C9382C1E,CpuIo2OnCpuIoThunk +5045A8A6-7D74-4037-AAED-1449DBAEBCCC,PciLookupTableDxe +504F2F1F-E7EB-46F9-AA07-0606F311AA1A,SmmPlatform +5053697E-2CBC-4819-90D9-0580DEEE5754,EfiCapsuleArchProtocolGuid +50578334-FCFD-4DCA-B3AF-47DD76E946CF,AmdNbioDxe +5058F21C-BC34-11D4-BD18-0080C73C8881,Fat2 +506533A6-E626-4500-B14F-17939C0E5B60,AcpiSupportDxe +506F83CD-5C6F-47F1-9FE1-BEE297309D32,SpsPeiPreMem +5074C00E-698B-4763-91E6-41663F6CC7C9,PBSPeiInitPei +50827A85-7639-42E0-99E7-156405E1790D,HpPlatformErrorHandler +508A61DC-2C57-4848-A54A-58015179C94A,ApplePowerState +5091388A-4BB6-4DA5-A493-5EE7A90CEA5E,OemBoardID +50A18017-37AD-8743-BCF2-DF1A8FF12FAB,EmuReset +50AE2DAB-3A4C-4F77-85EA-FC4271FC376A,Ps2WakeupSmm +50AE892F-E01C-46BC-9E47-064E2503776B,NICIdm +50B4FAD4-9D0D-440B-812C-D8E3EC21244D,XhciHandlerCommon +50BEA1E5-A2C5-46E9-9B3A-59596516B00A,ArmVirtVariable +50C511E0-3C68-4FD1-B7EC-2589657EA225,IDDxe +50C59A68-1920-4B6E-A296-2D37C0619EB9,SetupMenuSmm +50C86A39-C194-4B03-8B4E-22CE463BB2A0,DellSmmDiagLeds +50D51651-E5EA-4C7A-9DEF-7CF8A63AFC91,AmdPspDxeV2Phx +50DC5C90-1D33-4FD6-87E5-063B1DFA2170,AmiSerialProtocolGuid +50DE3789-BD33-4AEF-B182-7FE9183E88DA,DellErrorHandlerSmmProtocolGuidVer2 +50E22E0A-4103-9999-9BE0-AA8CECBCE694,AmdRasApeiDxe +50EE664D-7703-42C3-9E69-8C89DE70D1D5,SioInit +50F6096D-7C98-4C78-9A1D-C5A1833B6A88,AmiTcgNvflagSample +50FB1120-0FB7-4B1C-9CEE-071B97703827,LGSetupPreservePolicyRuntime +5101D37B-CD13-493C-BD7C-40A3E45FC19B,UfsPciHcDxe +5104F56C-AA34-47E3-B4C1-1BF301C20758,PdmDxe +510550E0-BBCE-4EBF-BBA0-946E3D18E705,PhEmulateKbcSmm +51080191-ED06-4AA0-BFD7-F04837CF70DB,SbRomArmorSmm +510DF6A1-B6C1-4948-AEE7-59F220F898BD,SataController +510F8CC8-8500-4D16-A298-96D28584D6C2,DellPolicySmm +510FDE31-692D-4D86-8DB7-7F460C0A7B7E,PprVlsErrorLogListener +511110E8-A64B-4B88-A473-E0D296AF5352,TouchDriver +51116915-C34B-4D8E-86DB-6A70F2E60DAA,NVMe +51116915-C34B-4D8E-86DB-6A70F2E60DAC,IOBufferCopyController +5111B2D3-B8F7-45BF-8A63-2A1678F67A41,PeiSmmControl +5112A2AA-E175-477E-A4E4-D0B7E689BA9F,SystemEventLogDxe +5113378D-C3A5-4B6C-8F5C-9FA82CBE4F6B,BiosRecoveryPei +51175C7F-0360-4042-A3F2-F17222B400AC,SbFlashControllerSmm +511760B2-E47D-44B4-8366-0F2CD3BC1D38,DellSmmRadioDeviceProtocol +51177887-A697-436F-937F-1CDC421A3DCB,AmdRasRsServiceDxe +5122FA7B-17A3-4A8B-89AE-A93ADE92EADF,DigitalThermalSensor +51271E13-7DE3-43AF-8BC2-71AD3B824325,ShellMapGuid +512EC22F-CFF1-4101-BE42-6FA79BC50374,HpLibArchiveWorker +5138B5C5-9369-48EC-5B97-38A2F7096675,PrevBootErrSrcHob +5142E880-97AC-4AB3-8F06-F36765DF7066,OemACRecoveryDxe +5145C2AC-17E1-44A9-83CD-AC8724805AD2,AmiPspPlatform +5147A340-1B75-43F4-BA0F-46393D697FD4,FjGabiSettingsSmm +5148B18E-F1EC-41A8-9292-E2592E6F7547,FlabLoadPvUadmDxe +514A1936-2C6E-437F-B068-04CB15F53AF9,AmdRasRsDxe +514D2AFD-2096-4283-9DA6-700CD27DC7A5,ScSmmIoTrapControlGuid +515B224B-B059-460B-85C7-C28658F4B898,LenovoHpmSmm +5162AE21-17ED-45B7-AA9D-E669A3A33525,DellStorageAgentSmmProtocol +5167FD5D-AAA2-4FE1-9D0D-5CFCAB36C14C,LegacyRegion2OnLegacyRegionThunk +51688885-024C-439B-B3DE-9C08E8F591DB,SmmEventLog +5169AF60-8C5A-4243-B3E9-56C56D18EE26,SmmIpmiProtocolGuid +51739E2A-A022-4D73-ADB9-91F0C9BC7142,MpServicesOnFrameworkMpServicesThunk +517DC096-EFFC-4937-8002-87F8B1BF94BF,ResetHandler +5187359B-790D-425B-A593-CA1CDB3CEBAD,EfiTcpSockProtocol +518FBAE6-76DF-4A3A-860D-3E416ED9F203,SmmInt15Handler +5190E4AD-E902-462E-9509-A7AB1F51B27C,KEMhSpiMux +51924AE9-BE81-4820-94BA-7C9546E702D0,Tcg2PpVendorLibNull +5199296F-2808-4AFA-94C4-99F6B06C871E,ACPIS4Smm +519D1BDE-27B4-4408-990D-FEFDB6B5220B,ServiceResetSmm +519EAE59-C1D0-4A1C-8B21-F06B620DAD21,RedfishPlatformDxe +519FE23A-7C3D-40A9-9F65-B911EA1930E1,HpLegacyFlashWrapper +51AA59DE-FDF2-4EA3-BC63-875FB7842EE9,EfiHashAlgorithmSha256Guid +51AA65FC-82B6-49E6-95E2-E6827A8D7DB4,AmiHddHpaProtocolGuid +51AF821C-ADAF-4ABC-9FBF-26CD5245BA22,DellSmmGpioControlProtocol +51B632C7-3B9E-4474-8D4A-503AC2B0ECB2,AEPFreezeLockSmm +51BCC804-428A-4A6A-B352-E4844AED9105,NtfsPei +51C4C059-67F0-4E3C-9A55-FF42A8291C8C,PeiSmbusLibSmbusPpi +51C9DF0F-21B9-1015-9151-12872F032A51,HardwareHealthManagementPei +51C9F40C-5243-4473-B265-B3C8FFAFF9FA,Crc32SectionExtractDxe +51CCF399-4FDF-4E55-A45B-E123F84D456A,ConPlatformDxe +51D27BF0-6414-4C69-AE20-BF017C326505,WmiSetupUnderOsSmm +51D2DA4C-5950-43A8-B8D6-133A686072EA,FchSmbusDxe +51D4BACC-E70A-4136-9426-546973ED938C,LenovoPlatformS3SaveDxe +51D528BA-9730-4460-ABD4-B1E5E3A472ED,PcieLanePEI +51D687C8-196E-4CFE-8A0C-8368980EA8B6,DellChassisConfigSmm +51DD345A-B3FA-4119-B5D0-C5FAD7F37B31,DualBiosPei +51E1CEC6-1F2C-4BF2-988E-CA3EAB7AEF37,FjSystemDataRt +51E9B4F9-555D-476C-8BB5-BD18D9A68878,EfiAmiSioProtocolGuid +51FAE33E-9C59-4926-857F-65997BD4137F,VariablePolicyStubDxe +5200907B-59FF-49E7-9AF9-EE2DFA83624F,DellStatusServicePeiInit +520B070E-83AD-4135-AD62-07DFBD66396A,Armani_BatteryInfoDxe +520C3847-71A0-40E7-A895-8C8997C33455,AmdMemFeatPei +520F9C58-9F9D-48C6-A0A0-D9FE6D8FDE77,LenovoTdtAm +5210F89F-899E-4075-81F9-35594E77CB9D,CcgOnlyPei +5215290B-7FE9-44D4-8DDB-251166EEBE7F,OemMonotonicDxe +522670C3-3D4E-4EC3-8A83-34467DAFE4BA,SmmSxDispatch2OnSmmSxDispatchThunk +52272F15-C22F-4B53-830A-FBEF9C3F643B,RealtekLan +5229AE5A-AB8E-4693-A8FD-B7D7CBCE694C,PTSataController +52312CDF-D4A9-453E-A9DF-9FDAF51CD622,DellSmmDelay +523F3049-819A-4998-8405-7848BC8C4942,BiosCfgTool +523FA0E8-8639-47BB-B859-939A450DBF77,EnhancedFat +52416508-181C-4899-8CCA-E020A2BD3F18,ODMSMM +5242AADB-BDAB-4B92-B7D5-A58B6E0EEE6B,IchSmbusArpDisabledPei +5243ED17-6742-484C-8922-F2FDB1DC2725,WmiSensorHandler +5244407B-C852-480D-BAB5-938C832C5581,ASRockSIPei +524685A0-89A0-11E3-9D4D-BFA9F6A40308,AndroidFastbootPlatformProtocolGuid +524B4384-D632-4862-9D3A-6D82C9E85825,SystemInventoryInfo +524E19D8-8066-4BEB-8BBD-6FF9E405B3A7,MeResiliencyDxe +52534DC0-3328-4153-A17C-9FA795654C05,FjGpioGHODxe +5255DFB0-0E7C-47DC-95A7-0B838DA09BB0,UpiPlatformHooksPeim +525B672C-8C8F-0361-AE8E-565EE0F563B8,MemInfoDxe +5261213D-3A3D-441E-B3AF-21D3F7A4CA17,EfiScsiBusProtocol +52715B77-04A5-487A-B980-CDC371B5BEC8,AsusPostErrPei +5272EFC4-D506-4CED-A415-DA68B0515120,PciDxeInit +527EA834-EBB5-44EC-AA27-BC0FDCC0226C,FjSecureServicesDxe +52888EAE-5B10-47D0-A87F-B822ABA0CAF4,EfiPeiCoreFvLocationPpi +5291C916-8638-4296-BD84-3F4ACBB2D5A3,AmdAgesaParameterGroupPei +52978AFB-F8D1-4B0F-974A-0B7C9445E4EB,AmdCcxZen3CznPei +529D3F93-E8E9-4E73-B1E1-BDF6A9D50113,ArpDxe +52A7AA5D-3B23-4F06-FFFF-FFFFA95DD84E,XnoteSetupSecurityDxe +52A88B2A-65FD-4951-8B25-06FB6598128B,DellSpiPartEon +52A9B223-FAB8-4A24-AEA6-461A59BD3F33,AmdSmbiosDxe +52B3DBA7-9565-48E8-8E13-EC7196721B3C,PlatformInfoPei +52BAF47B-6920-4304-A031-A45CC345DA3F,POSTCODE01_TPM_CONFIG_POLICY_SMM +52C05B14-0B98-496C-BC3B-04B50211D680,PeiCore +52C78312-8EDC-4233-98F2-1A1AA5E388A5,EfiNvmExpressPassThruProtocolGuid +52C877FD-C27C-4779-B750-7880B28B4306,SetupConfigUpdateDxeNeonCityEPRP +52CE9845-5AF4-43E2-BAFD-230812547AC2,PlatformGpioProtocolGuid +52DAA304-DEB3-449B-AFB8-A88A54F28F95,OhciPei +52DFCF2E-5BE5-4376-BC22-14F788A4A425,AmdNbioEarlyPhaseRVPei +52E75865-F4A4-4FFA-A9F0-D3048EA79F84,ThermalPei +52ED90D3-BBF8-45FB-B24C-5121655D23B8,FjHddFeaturesDxe +52EDB5F1-9632-4CE5-8B82-3099200E66DA,SoftSkuSmm +52EFDE98-4C81-4423-8C6D-4ECAE61DDDD9,UsbOcUpdateDxeGlacier +52F934EE-7F15-4723-90CF-4E37127718A5,TcgPeiPei +52F9F971-5302-4F46-B1A6-1E55669B52C8,SxStateSmiPkg +52FA6F82-5255-45E1-8ABF-C62EDA2C89BA,SmbiosType133 +52FE8196-F9DE-4D07-B22F-51F77A0E7C41,LocalApicTimerDxe +5303664A-4222-474C-97A4-9A0D97D0020A,SVI3ManagementPei +53070378-119A-4836-77BD-893C824ACEB2,FchPromontoryXhciPei +53070378-119A-4836-82BD-893C824ACEB2,FchPei +531AED6E-3DEE-45EB-8DF1-B70ADB1F885D,TrueTypeDecoderDxe +531BDEF7-EF15-4C27-8441-110E61B48933,HpPwdPresentModule +531D43E0-5BC6-4FF6-8499-5EAE5B195E53,PeiFramework +531E5D9B-419B-4C3C-9561-B894F695DDE4,FvbVariableStoragePei +532A50A2-BCE6-4675-80EC-53EE57A68FA2,FchBixbySmmInit +532B6532-6499-428D-ACB1-F6F779C94DF9,AuthvarMailboxVariable +53322F73-3965-45A7-8B54-61972744102E,IntelUefiRaidDiskInfo +533AC901-A115-4806-9C4E-BD6D72C7ABDE,UpdateErrorInfo +534A6A34-CF78-4A56-BEDB-CB49A8D8060C,RTCWakeup +534BA4FD-D74C-1E41-AA7D-BB551364FBAD,AppleDebugSupportDxe +534DB6EE-FEBD-4F63-9C1F-8425CA82C6E1,DellPsidWarnings +534F73CF-0937-418A-90C7-4F1079DCAED1,PeiRamBootDxe +5351724A-7D47-4834-9C59-0DD01F305E16,FjSmmSupport +53531469-558E-4AF1-803A-F966F27C573B,BatteryState2 +535A720E-06C0-4BB9-B563-452216ABBED4,HdLcdArmVExpress +535A7AD6-C204-49B4-B762-4B32BF4ED314,PchInitDxeCnl +5360BFF6-3911-4495-AE3C-B02FF004B585,DxePciLibI440FxQ35 +536DF136-BD96-4E1E-ADF5-6B637C139063,UuidDxe +537186B9-1EB2-4114-B1FC-8AA894093544,EfiPrevBootNgnDimmCfgVariable +53838958-1CA0-4649-B93C-33F51EE085A7,EcRotSupportShowInSetup +538997F7-4B2E-4E6F-8AF1-0E8CF1AA9C69,PlatformWrapperDxe +5396C008-D8F9-4D76-B60E-9F9AABA2924A,LenovoStartupMenuDxe +53984C6A-1B4A-4174-9512-A65E5BC8B278,PlatformStage1 +539A558A-C4C7-4978-B52D-1492415EF64D,RomDataMigration +539D8AAD-C6AC-426C-B61F-228E6D1501B6,LenovoHpmDxe +53A3CB31-7E97-4512-B2EB-BFA0AB8FD75A,DeviceDetect +53A4BF3F-82A4-4758-8A08-7EDD2EDFF2B5,PlatformEmmcController +53A4C71B-B581-4170-91B3-8DB87A4B5C46,EfiFvbExtensionProtocol +53A58D06-AC27-4D8C-B5E9-F08A80654170,EfiExtendedSalStallServicesProtocolGuid +53AB1ACD-EDB1-4E3A-A2C7-978D721D179D,FspSecCoreS +53AC1948-0ED0-428A-B4DD-D2FFF2F5776F,LenovoFlashProtectPei +53AD0657-8A74-4358-9F32-04AB4B5A0B92,SecureFlashEspFlagSmm +53B4BD04-098C-4A11-B65A-A02B33C98C08,HSPfTPMAcpi +53BCC14F-C24F-434C-B294-8ED2D4CC1860,DataHubDxe +53CB13DF-A56F-4101-BB4F-9BE040657BB5,StdBoardSmm +53CD299F-2BC1-40C0-8C07-23F64FDB30E0,EdkiiPlatformLogoProtocolGuid +53CE1482-8B8D-4B24-888A-C2BDA19CF4A1,UefiToPublicWmiRouter +53D7E8EC-56F5-4F9C-8198-7BFB2ED4E05E,BootSectorWriteProtect +53DBDED9-C255-4908-847E-E191583AC7DC,UpdateFruSmbios +53E65F94-B418-4541-9A12-18839A56B427,Thc +53F019E9-BB0C-424B-870A-1FAF10B1CB4C,iFfsPei +53F5C473-46B5-45F3-8261-E4A59A9E755D,AmdPspPeiV2Stp +53F66425-21F2-45F3-99D5-ECAE1E21663A,H19TpmDetection +53FEBC13-C534-483E-8DA0-968E6FFD18D0,SecureBIOCameraSunplus +5402F0A2-7818-478B-8744-048AAE94BE0D,DellTpm20Dxe +540D61D0-C2D8-4E2E-8AD0-5C3D1B56CD4E,UpdateSmbiosEcVersion +54141B25-D623-42B8-A249-3C2BB739AC4C,DummyDriverDxe +541D5A75-95EE-43C7-9E5D-2394DC486249,AmiTseAdminPasswordValidGuid +54289C30-4D54-4BA4-8D06-1C6B9B2DC23D,CpPcHotkeyData +542D6248-4198-4960-9F59-2384646D63B4,AmiOpromPolicyProtocolGuid +543323CE-9F0C-4DDF-A33C-BC3B3A5AC227,SmmBmcElog +54357618-E106-406C-A5CE-AD7A1BA3CCCD,ExternalUsbPortConfigDxe +54360212-BD31-403B-A983-C5E472049E40,OneTimeFlagsPeiInit +5440D0DA-F426-45F7-BB50-B282212FDBAF,DellAmdCbsApcbUpdateSmmStp +5446C293-339B-47CD-B719-585DE39408CC,PostReport +544C6868-AA26-4B94-A43D-80A1BF4E65EF,DellErrorHandlerSmm +5466B9AA-EE2F-4FDB-84A3-A330BE1301FF,AmdHstiV2 +546AD295-0C64-4CE6-A06F-FB9CD04B41CD,SystemFlashCommunicationDxe +54706D54-2251-46F6-90A8-AFF0D4CD1E7D,WifiConnectionManagerDxe +5473C07A-3DCB-4DCA-BD6F-1E9689E7349A,EfiFirmwareFileSystem3Guid +547957B2-D791-4CFF-8808-8024897B4D98,PLX8605PEI +5479662B-6AE4-49E8-A6BD-6DE4B625811F,KeyboardDxe +5479E09C-2E74-481B-89F8-B0172E388D1F,StartWatchDog +547C4CBE-BC2A-454D-AEE0-D29E487E0ACA,ErrorLogHookPoint +547C5CAE-2640-4ACF-9532-0E25B3F03F05,WheaDxe +5487F114-45E6-4D34-95E5-C7CF09E8AEA9,FjNvramVariablesAccessReferencePei +54891A9E-763E-4377-8841-8D5C90D88CDE,TerminalSrc +548A6718-6BC0-45A9-B4E9-6F63B0E1DD43,RtkUndiDxeClientron +549070BD-3FBD-47C9-B640-975C306F175D,AmdCpmDsdt +54913A6D-F4EE-4CDB-8475-74062BFCECF5,NvramMailboxAddressVariable +5493C51C-79C8-4C2E-9758-1DB5B52B13B7,DellSmmNbDockProtocol +54975633-0945-4D9C-97C2-E0CC6469A5A3,MeLibPei +549F3345-8B83-4F08-A4DC-34BF55028A0F,ClientCorePeiPreMem +54A3058D-8537-4A32-BDB0-4027BB688727,ITEAcPowerLossPei +54A85D82-3A54-4006-9C0E-E527295C4FA8,SetupLangService +54AAC64F-8A72-4093-8051-F4D23C5D2A4A,SbSocBixbyDxe +54AB2D48-8067-42A2-BAED-71F8E04FFE6D,BootDevTypeOrderInfoDxe +54AB7A17-AD08-4F86-83C2-4CF398EBC0AD,AsusPostErrDxe +54AFED50-5999-4594-9B79-F0AAA09FA32C,DashIoCfgDxe +54B070F3-9EB8-47CC-ADAF-39029C853CBB,NvramSmiDxe +54B0E2D1-F3EA-46D1-8DBA-367A347824EF,OemWakeOnLanPolicy +54B34347-C478-4865-8415-742E5155B204,UefiRestNetwork +54B6C2D3-79A9-400C-A3F6-D737CBEC6368,IioPlatformHooksPeim +54BD6A5D-38F2-44BD-84AB-108BE4F45914,DellChassisConfigDxe +54C32CBF-A3B9-4CCE-9C43-E059E32255DF,SystemFirmwareDeviceSmm +54C61C94-287D-4DC5-99D5-D38D1A53AE6B,PlatformInfoHob +54CB734C-975C-4A74-9556-57AE6D9A2229,TrackPointElan +54CE6010-2A6D-42AA-B1E2-FD97DE9C4DA8,AppleDebugSupportFireWireInit +54D2878F-25CD-4A2B-8420-EBD18E609C76,OemHookStatusCodeLibNull +54EA32CF-F34A-4ACA-951C-1203B7C51725,OemRgbLbDxe +54EB2B7F-0CC3-4E1B-B03D-E81756F642B9,GfxInitPei +54EEEF50-2EC0-45B8-80CA-9CB1AB819507,ApobRmbDxe +54FCC43E-AA89-4333-9A85-CDEA24051E9E,EfiSupplicantProtocolGuid +55025E9D-32E9-403B-81C1-F9E3D9D70640,AmdHsti +5503017E-3B17-411A-A670-09BB039F1B6F,CrashLogDxe +550303D2-F033-4468-857A-442C10E199E9,LenovoDriveEraseDxe +5504DF0C-F54D-465F-9200-F0383DBA1BC3,DualMeFlashExe +5507247A-846B-4F22-B55F-72B4049435EF,AmtLockKbd +55073147-BE8A-493D-8342-BDFC17E7F2BA,AmdNbioBaseRplPei +5507E3F0-9C84-47DC-8CEA-C29A01B7CD5D,SioBdsPlugin +550E42E1-B6FA-4E99-BBD9-1A901F001D7A,AmiVendorKeysNvGuid +552BA34F-949E-404D-B6E2-02BA73534307,PlatformRasConfigSmm +553087F6-BAAC-4D7F-97B4-31D8179AAE15,GetNameInfo +553F15CC-ADC0-4364-B935-A5BFE2BFD2F9,FjI2cPDControllerDxe +5542AB6E-501E-4D60-97DB-ED717584BD1E,DellTcg2EarlyDxe +5542CCE1-DF5C-4D1B-ABCA-364F77D399FB,EfiHiiCompatibilityProtocolGuid +55461099-28DE-4A16-B51E-D0D18A0793F9,CmosButtonLoadDefaultsDxe +5546A554-C246-46D6-97E1-2506D2D8B674,AmiUpdateBoardIdHob +5552575A-7E00-4D61-A3A4-F7547351B49E,SmmBaseRuntime +55538D1E-B4C5-4BD5-B594-9B5BA9774F1E,AodSetupDxe +555F76EA-785F-40D7-9174-153C43636C68,CirrusLogic5430Dxe +55648B91-0E7D-40A3-A9B3-A815D7EADF97,EfiRestExProtocol +5568E427-68FC-4F3D-AC74-CA555231CC68,LinuxEfiInitrdMedia +5568E42E-DD33-4F6C-867F-7E73451104FE,StaticSkuDataDxeLightningRidgeEXECB4 +556A3B81-399D-4951-82C5-BC72FE5EFBCB,FjMfgFeaturesDxe +557423A1-63AB-406C-BE7E-91CDBC08C457,QemuRamfb +5578AE16-F1C9-4E8F-B129-BA07F8FCF84A,IdeSetupProtocol +558D8B04-1C4E-4782-BB99-AFF903074C26,AmdCpmPciHotPlugDxe +55961E20-B0D9-4553-9948-E3ECF0BE0889,PlatformConfigPei +55987E62-1DF6-41D1-9062-334FCAC3E54D,GraphicsSplitter +55A2532E-297A-4AFD-90BF-139BFF5BB4D7,LenovoSystemAcpiTablesPei +55A267FC-6607-4023-884E-48E5D3D3F4E2,DellHiiparserDxeDriver +55A981A5-F371-4BA3-93A5-37FA0CA95089,SynQuacerGpioPei +55AE03B0-681D-450E-8AA5-81B94DBA5362,SystemVspEvaPei +55AF6E44-086A-491E-829A-7D95502539F5,RtSmmOemDriver +55B1D734-C5E1-49DB-9647-B16AFB0E305B,EfiHash2ProtocolGuid +55B71FB5-17C6-410E-B5BD-5FA2E3D4466B,EfiI2cBusConfigurationManagementProtocolGuid +55BB5A4B-3B3F-442C-BF09-0F87A67E8EE7,BindingsDxe +55BDA60B-1D0F-42D5-9F09-2D3D3067B899,EarlyDevices +55CF7CCE-051F-42C3-9CA9-20DB5CAD9AE4,AmiEventLogsHiiHandle +55D2C031-C1DB-4FD4-AC8C-C7EBE54E3E1D,DxeGraphicsOutput +55D460DB-8FEA-415A-B95D-70145AE0675C,DxePrintLibPrint2Protocol +55E3774A-EB45-4FD2-AAAE-B7DEEB504A0E,Tcg2Pei +55E76644-78A5-4A82-A900-7126A5798892,HeciInit +55E86300-F0B2-44AA-A5A4-EAEECE2E983B,PlatformToDriverDxe +55F10D34-4F05-426A-9A72-613EA8544DE0,AmdCpmPmfBoardPeim +55F6A413-280F-41E3-9394-6580F29DD7D0,DellSmmBbsmanagerLegacy +55F9900A-BFB0-4B30-83EE-7F437FAFAE33,LenovoDriveEraseSmm +55FFDD87-F6C2-49DD-A724-F197E60AB020,LemKeyboardLayoutProtocol +560467CE-83F8-4765-886B-6A0C03678CD8,HpNotificationsDefaultsAndWmi +5604D863-BF24-439B-BBF6-636D72036E07,SpiUtil +560BF58A-1E0D-4D7E-953F-2980A261E031,EfiSioVariableGuid +560FE30A-760C-46FA-989A-206F48C17C80,UsbHubTuningDxe +561196F1-1234-4145-8893-8893A1F97D97,FjOnScreenKeyboardDxe +561230EC-E2A5-4E58-80C2-30486D9F8D62,RtkUndiDxe +5618EC3F-A4EF-4EED-8759-64EEB780B4BE,DellSetupD4Smm +561DE4F7-BC8E-4E9A-A741-3E0D1A735621,DeepSleepSmm +563413A6-9DD1-4B7F-9E7C-5536E92AA55A,UefiDriverAsix +5639867A-8C8E-408D-AC2F-4B61BDC0BBBB,EfiBluetoothAttributeServiceBindingProtocolGuid +563C75D2-045D-43FD-A7C0-A472B0AD0255,gear6 +563E434B-6EDA-40DC-9123-A0FA0166EB4C,FjGpioAlderLakePei +563F8EDE-1FA5-45A2-BE23-B0B6A07DE239,DramPolicyPpiGuid +563FAFF1-EC71-4EB8-9E6E-60BF1447E285,FlashUcAcmSmm +5640497F-645E-4611-B915-E682C8BD4783,AsrockClockGenDxe +56417BED-6BBE-4882-86A0-3AE8BB17F8F9,EfiKmsFormatRsasha11024Guid +564B33CD-C92A-4593-90BF-2473E43C6322,EfiHobMemoryAllocBspStoreGuid +564F3ED7-6044-422D-9E48-65AAF585621E,FjPostErrorLogDxe +56521F06-0A62-4822-9963-DF019D72C7E1,PchSmmSpiProtocol +56546975-C450-44B2-9D25-CE83C5820161,LegacyBridgeProtocol +565D3FCA-F06D-4FED-95EB-370EDFFA9E57,AsrBootOptionDxe +565EC8BA-A484-11E3-802B-B8AC6F7D65E6,XenBusDxe +56627FB7-0D7E-45FB-9A18-958D92E2780A,FjPostScreenDxe +5678DBEB-6702-44DA-8C0C-60942AC1F980,Ps2KbdPei +56966690-24E8-4DFA-BEA8-BFCD83DA44B8,MultiPdtDxe +56AA1233-7407-4058-9E17-88DE138EA15D,AmdCcxZen3CznDxe +56B70419-7103-4D0E-83F4-F3546BD21E40,EzFileExplorerLite +56BBC314-B442-4D5A-BA5C-D842DAFDBB24,PlatformInitAdvancedPreMem +56BD294C-4488-4B6D-A637-EAF159B43BED,OpromUpdateDxeCLX64L +56BF094C-69F6-49DD-8C1C-1ECEFF71C9E5,CsmRt32 +56BF4B67-8DCF-424F-99A9-0F44B7F8C925,ODDBiosBootSupportDxe +56CBE66A-BF3C-48F9-B9DE-8DA42F906074,SbPcdPei +56CD6FEF-9038-49DA-8275-1B2F5B9791A9,EzFmpUpdOpt +56D23D33-07D7-48F9-81D6-7ED5991ECE88,OpaPlatCfgNvVar +56D60EE4-5CCF-485C-BBBB-FEDAE2B24146,RegAccessDxe +56DBFC7E-4D04-C73D-8A5E-73819BD23CA6,AmdSocSp3r3CpDxe +56E83C34-1451-4285-890D-E1F17EBD9C44,MeFirmwareRevisionCheck +56EC3091-954C-11D2-8E3F-00A0C969723B,EfiLoadFileProtocolGuid +56ED21B6-BA23-429E-8932-376D8E182EE3,FspPerformanceDataGuid +56EEE346-500C-4936-951A-2DA5F0FF39BB,DellGrasslakeConfig +56F0BAAE-F887-45D3-814E-B6D5C489E0F9,AmiAgesaChipsetPei +56F63543-A9FB-4432-AA6D-44827005B74A,Lily_RTLWlanbin +56FC768F-B603-4454-8083-BFE98D6084F9,GnbPei +5700D4C0-B7B1-4222-AC5C-DD410642FDA7,DellUsbChargerSmm +57144639-7BD1-4E72-B97B-D8A8C3AE2A9E,PlatformFlashSmm +571A2DDE-E141-4D73-927D-85F5A7BB187E,AmiTcgLibDxe +571D1ED1-C2D9-418E-953A-248EBC687048,DellIdeSmm +572528F4-9BC6-41BD-9D14-5AAD93464A51,NationalPC8374L +5726C43B-C1E0-4735-8049-5110EDF2851C,AmdSocFp8PhxPei +57292E63-5BD0-4787-AC14-43E6B0A1515B,OememSmi +5733EBA8-492D-46FA-AA6A-379779E10B77,EfiMpstSupportProtocol +57354F58-C310-4884-AB1C-D770510BA7D6,FanTuningPei +573A445F-4FB6-C2D3-2CC0-5B9C772CFB94,AmdRasSspApeiDxe +5740766A-718E-4DC0-9935-C36F7D3F884F,DefaultdbxFile +575B08F4-A946-4341-B46A-765CC9F04644,PCIeIdm +575DFB6F-4009-495F-B23E-A6A084CEA57B,Int40InterfaceSmm +57651554-BE8F-4546-80C6-36323D52935A,AmdPlatformRasRsDxe +5774B56B-40B5-4FD6-98F7-D4D27C86CA49,FjGenericItemProtectedStorageDxe +577D959C-E967-4546-8620-C778FAE5DA05,EfiDebuggerConfigurationProtocolGuid +5785E965-8357-48A1-AC12-CAF77A35FC72,PlatformStatusCodeHandlerSmm +5786ADE9-7DBE-4453-BBF7-6C181FD06458,AmdCpmOemHiiDxe +5788464F-3773-4A29-8AF7-E81BBEE419C3,ATAIdentify +578C315A-68CF-4E81-B5C6-22DB40D010BC,EfiI2cMasterProtocolGuid +578C3195-D8C1-44F1-8A06-2B592FBE6AF3,TouchInputFilterDriver +578DC3C1-DFD2-4314-997F-F882CF50E5E7,FjEvteApp +578F70A0-066D-11ED-B939-0242AC120002,AmdMemStpSp6Dxe +579A7D1F-C166-4D0D-ADDB-B20B8B768B72,TmeInitDxe +579B3063-8114-4FCD-9DF1-0E4519AF7744,ShellResolution +57A13B87-133D-4BF3-BFF1-1BCAC7176CF1,EdkiiTcgPpi +57A2146B-2F5F-4BFE-86B6-303471F2F47C,FchShastaPei +57A913EF-DBD8-47CC-89BF-7D86DE822FA6,DellTcg2ConfigInfoTpm20 +57B82766-596A-45BD-8168-27E2BF41EF5C,DellPermanentDeviceSmm +57BDA600-D3FF-4A59-84CF-CCB53C941AAB,CrbSmbiosType4 +57C295E7-4411-47FB-A176-68CE13ED449C,VideoIdm +57CE81B5-B995-4703-A42A-8774A353E5AA,AsusRunTimePaysBios +57D16189-7A07-4EFD-9701-5A19FE120E73,PermanentlyRemoval +57D21D52-3896-497C-9C20-B144BE7AD1CC,UnlockPei +57D55F85-C177-4A84-A2DD-8668E6F082E1,DellCipherSmm +57D59D87-A2A9-482C-8EC7-D9F9FA3E20F4,PlatformWmiAslSupport +57E56594-CE95-46AD-9531-3C49310CA7CE,Ofbd +57E9BE79-FA6E-4A83-A3EA-AB2B6678E4CA,ACPISxSMICore +57E9EEE9-EB7D-4453-BBF7-6C138BF06458,AmdCpmDisplayFeatureDxe +57E9EEE9-EB7D-4453-BBF7-6C181FD09027,AmdAgesaDxeDriver +57F435A8-1C37-4834-AD61-B03D94DDCEF3,DellPasswordMgrDxe +57F4434C-A01B-487F-A426-AC7BE1D79DA2,UefiHotkey +57F48613-300A-4101-A76D-4F73C533B5B8,PriorBootDxe +57F55732-CF55-43C7-B66B-216CE2282888,MonoStatusCodePei +57FDAAFB-DB48-4546-B73C-58428D8261B3,MtkSuppDxe +58014AAF-1C4A-4868-9042-58BCD1637054,FchProm21CbsPei +5802BCE4-EEEE-4E33-A130-EBAD27F0E439,MsegSmramGuid +58053681-13F3-47F6-B137-CDB3E888D9A4,ExtendedDataGuid +5808F44B-E501-467F-8899-670B9ADBD01C,RealtekLib +58094BEC-30FE-459A-B232-3A60D1C78C16,WheaErrorLogListener +58099949-C88B-4117-81A9-DB8949917CD8,SpdDxe +580DD900-385D-11D7-883A-00500473D4EB,Uhcd +58105900-9D9F-4F6E-8E0C-1F257113A3A6,ADLINK_ComHotCablePEI +5810798A-ED30-4080-8DD7-B9667A748C02,HashInstanceLibSha256 +581F20FE-3C59-46EB-8D9F-47E6D38A1C3B,IsvtCheckpointDxe +5820DE98-FC8E-4B0B-A4B9-0A940D162A7E,SioDevStatusVar +5820EEB4-C135-4854-9D2A-AA9EFC4475E9,MeFwDowngrade +5821A154-1E3C-4EC0-92C9-2A66AB2FF186,FjNuvotonNct6796Smm +58279C2D-FB19-466E-B42E-CD437016DC25,AmiTseDriverHealthCtrl +58293BDD-1E0C-42C6-8376-61F049F77A97,AmdPspAspt +58295EC1-2EFF-4D01-A31C-67C42D6B3862,FDUpdateSMM +582BB1AF-0A33-4644-898D-94FC89C838F3,HwmThermalDxe +583CF04B-42E3-4638-AA22-02E4D3330A61,MacToUUID +5848FD2D-D6AF-474B-8275-95DDE70AE823,SmramCpuDataHeaderGuid +584CC99F-4BE8-43D1-A45A-933DC39479FC,AmiPeiNbCustomPpiGuid +5853694A-467F-4464-BBF9-0C971A74CB36,L05UefiDriveIdentificationDxe +5859CB76-6BEF-468A-BE2D-B3DD1A27F012,EfiUsbPolicyProtocolGuid +586032E3-1386-4ECC-B547-EB285E21066D,AmiAgesaPei +587743EC-B505-4E9F-9F2B-3DF703D7B1D4,KEMrWdtSci +587E72D7-CC50-4F79-8209-CA291FC1A10F,EfiHiiConfigRoutingProtocolGuid +587E8797-C2FB-41B7-AE9B-F53A6C562DF5,DellCsmConfig +58830DE7-9739-4869-88BE-DC8CA24CE9C1,AutoMeud +588ACA73-2ED8-4F76-9310-6F4D0B449242,AsusHeader +588DD486-6641-458E-82A7-5CBEB8602111,AmdCpmOemInitPeim +588DD486-6641-458E-82A7-5CBEB8602F30,AmdCpmOemInitPeim +589532D8-2D0C-4626-A552-075CFACA5027,CustomLogoSmmDriver +589BC616-BB4F-47ED-92F7-93393C697E25,AmiSbSmiProtocol +589F4B42-A905-11E0-8264-0800200C9A66,SctMilestoneTaskProtocol +58A18C8F-D9D8-4E9D-BC43-3449B6BBCE01,ComputraceDxe +58A30313-70D7-4201-8212-995765B3527F,DriveOptionSwitch +58A6FDE2-F873-468B-8989-DB4DE5E06CE9,HddSecurityErase +58A90A52-929F-44F8-AC35-A7E1AB18AC91,FPVARBAK +58AD4172-08AB-4AB4-99E6-8AA2F2B354DE,AdlSioFunctionPei +58B35361-8922-41BC-B313-EF7ED9ADFDF7,SecMigrationPei +58B8E0BC-05A5-4015-A47B-774A50346C1E,CompalSsidSvidDxeSetting +58B8E0FE-15B8-4915-A47B-774A50346211,ProjectHookDxe +58B9CFCD-7BEA-43EE-AEE2-896AC2E0D6C4,AdapterWarningsDxe +58BB9C75-D7E1-46AA-9F80-7B176F3B404B,AmdMemSmbiosV2StxLpd5Pei +58C518B1-76F3-11D4-BCEA-0080C73C8881,EfiWinNtThunkProtocolGuid +58C9681A-6956-41FA-B0AA-A3246D880E9A,DellWmiSmm +58CAD20D-D51F-B385-7F84-E829CA2F7C3A,EcGpioControl2Smm +58CDC779-DC8C-491B-BAC3-F86E06D1865F,DellGpeOrom +58DC368D-7BFA-4E77-ABBC-0E29418DF930,EfiSmmIoTrapDispatch2ProtocolGuid +58E26F0D-CBAC-4BBA-B70F-18221415665A,VirtioRngDxe +58E352D3-92AC-498A-B751-099335AD5F77,FjIbvBiosPasswordsAbstractionSmm +58E6ED63-1694-440B-9388-E98FED6B65AF,EfiSocketProtocolGuid +58E81D7C-4D7F-4C6F-AAE6-32A99F25FD17,DellPsidDxe +58E8A611-AB19-47DC-9850-3985DE8DF1FD,PsmiMapHobGuid +58EB25EE-FBCB-419D-B9DD-12C38FFFBF0D,WlanControllerPei +58EE5E10-D0CF-4071-B1D7-980236E71412,GnbPhoenixRouting +58EE5E10-D0CF-4071-B1D7-980236E71E4E,GnbRaphaelRouting +590915CC-8622-4D61-BE64-C33EE760141F,DellSmBiosSmmDriver +590A0D26-06E5-4D20-8A82-59EA1B34982D,UniversalPayloadSmbiosTable +5917EF16-F723-4BB9-A64B-D8C532F4D8B5,EfiUserCredentialClassHandprintGuid +591F64F9-1CB8-4029-8868-F5A2C0CF3600,I2cPlatformDxe +5920F406-5868-44F5-A9B9-6D4031481CC9,LenovoOemSecPei +59216A68-0664-4293-82E6-5DCF4F99A06F,AmdCpmUcsiPeim +59223FC7-AAD9-4358-AD1A-ADB4B25BFEF9,I2cTouchHidDxe +59242DD8-E7CF-4979-B60E-A6067E2A185F,LegacyRegion +5924BE03-9DD8-4BAB-808F-C21CABFE0B4B,DellErrorHandlerPei +592626DA-4A1E-8B39-28BA-FEAD92C4A0A4,RedfishHostInterfaceDxe +59287178-59B2-49CA-BC63-532B12EA2C53,PchSmbusSmm +592AB072-3987-4DB3-86B0-EBD8D43E4B76,AmdFabricRsPei +59324945-EC44-4C0D-B1CD-9DB139DF070C,EfiIScsiInitiatorNameProtocolGuid +59378206-861B-4380-A349-2F2F4F030C4B,DashBiosManagerSmm +594AC308-8819-4284-B661-B7570881CC0F,RfSecureBoot +5959E027-BAB0-4342-AA4B-8F73F017B485,OemRuntimeFunction +595A6EDC-6D2C-474A-9082-3B992851DFFE,OemCapsuleGuid +596AA5A8-1289-4E30-B311-F74E64F30991,SmmSecureBios +5971B3C4-8FD0-411C-A53F-0A5EF400A094,DellPasswordSync +597F29A1-F354-4FBB-AFF4-BCBDA6A87C2C,LpcFlashPeiLibNull +598E95A1-9674-4C10-9342-3F06317033F7,SmbiosType13 +599438A7-4292-4977-8C06-FFC16C445E83,AmdApcbZpSmm +59A3F3D3-DD73-47E7-9688-E96C1A6F50D1,DellRecoverySiPei +59ADD62D-A1C0-44C5-A90F-A1168770468C,PlatformInit +59AF16B0-661D-4865-A381-38DE68385D8D,OpalSecurity +59B042E7-04A7-4D18-967A-8D31E3F34E8C,BiosConnectIqIntegrationDxe +59B90A53-461B-4C50-A79F-A32773C319AE,IdeBusSrc +59C2B0BD-BC73-4428-AA7F-8EE98DEFB2C3,AmdNbioBaseRmbPei +59C341BB-28BF-4867-9951-DA479E349D52,MTKSuppGen2 +59C34225-6FD4-4212-88F7-8845F2459DCE,FjPcieClkControl +59C5679B-08CB-4A53-B2AD-8CFD8359EEC5,OemACPIDriverDxe +59CFEAD5-DEEC-4F47-B9A5-222C25633283,FjGabiFlashDescriptorSmmProtocol +59D02FCD-9233-4D34-BCFE-87CA81D3DDA7,EfiGenericElogProtocol +59D0D225-38D7-4828-A7F9-1AB9BBF397A0,MAPS_SerialPortControlSmm +59D1C24F-50F1-401A-B101-F33E0DAED443,EfiGenericVariableGuid +59DBE71F-7508-49D3-9008-08FF60F47B82,WOLPlatformPortingSmm +59DFF742-7858-42B0-8D5B-12C2AD003D6C,MrcOemHooksPpi +59EAD3A3-A920-4A80-9298-AA7B235647AF,PeiMeConfig +59EDB77D-5397-4127-8A58-81D7B4132471,AmdPspPeiV2StxKrk +5A05F81C-C465-4C6F-9246-BFCC37534B88,BatteryInfo +5A0B785F-C5CD-4905-9274-868737A59388,IrstRemap +5A0EF9DD-A808-457D-8655-5C17BAF919C8,HpUsbControlDxe +5A112448-0523-4621-B96C-CF32F6AEF3A4,MemoryStorageKernelSmm +5A18C536-DB68-4154-908D-0E1D53BE8247,VariableStorageSelectorSmm +5A235B65-4BA0-4A97-89A2-C127DEA193A2,AsusOnBoardDimm +5A35A163-1B41-4396-A776-9A1FC51426F4,SyncSetup +5A35F091-B3E4-4DA7-BA74-C9303D3577F9,FjPowerButtonDxe +5A38B969-CD6A-4814-82E6-559F840BBC58,ISPDxe +5A3F3BD1-B7A6-404B-A0F7-285E1B898B00,DiskControllerSmbios +5A662487-0749-4163-A9A0-C29C395F6503,OemDMIUpdate +5A665BC5-9EC5-4230-AF45-27AD9D5E8DEA,AmdPspP2CmboxV2SspSmmBuffer +5A676AE9-DB23-4A68-A24D-AA5FECD57486,EfiVmdDriverProtocol +5A677D2C-DAB2-46F1-A4FC-C3255045807A,StringMarshalDxe +5A68191B-9B97-4752-9946-E36A5DA942B1,EfiPrimaryStandardErrorDevice +5A6A93F4-2907-4A34-BD11-6CA8A0959E09,EfiCmosDataHobInstalled +5A79206F-E6CB-4A81-8B8F-70D1E24BFA2F,OemASMediaUSBPortDisable +5AA6A59D-5784-420B-A6E5-D8F641BD9732,EfiRasfSupportProtocol +5AAB83E5-F027-4CA7-BFD0-16358CC9E453,WdtDxe +5AADEA58-008C-4D12-AA0D-C85889AAA73B,SbSetPcdPei +5AC39AF2-F9F6-469C-88CE-141AC465F370,FjAtaWriteReadVerify +5AC7A2F1-52F8-4BC2-8459-AEA64753A054,FjFirstPowerOnMessageBin +5AC804F2-7D19-5B5C-A22D-FAF4A8FE5178,AcpiVariableHobOnSmramReserveHob +5ACEC36D-23B3-4C4F-A2B7-B2BFD72A059E,ProcessorIdm +5AD19B8E-71DA-40E6-B30E-FF2B8168C10C,DellThermalDebugDxeDriver +5AD621B8-C28A-4417-B67A-F77FD14BFBE4,AmiHeciDeliverSmmRuntimeDxe +5AD75102-5B4C-44A9-A7D6-DA925BBC49A5,EhciSmm +5AD83885-8955-499B-8E9A-EBC24B6E76B1,AmdNbioSmuV9Dxe +5ADAB7F5-4AE8-FBB8-8F44-8CB7D8EBBF2F,CpuTechSmm +5ADE106C-10ED-4C66-8E16-86C4E52EC47A,FjRealtekLanDriver +5AE0C053-C2B3-4E7D-ADD9-FD3CEBC6D3D9,SlotDataUpdateDxeLightningRidgeEXRP +5AE3F37E-4EAE-41AE-8240-35465B5E81EB,CORE_DXE +5AEA42B5-31E1-4515-BC31-B8D5257565A6,EfiExtendedSalBaseIoServicesProtocolGuid +5AEB83E6-3A55-4F99-B993-C91EB059C152,LEMDiskRelatedProtocolOnVmd +5AEC47DA-A9EA-4522-A3DD-9BBE138D7056,DynamicFv +5B02E5E0-C169-49F9-879A-CE1806F0357A,IpmiBoot +5B0691F3-8FF2-4A94-A16F-F4BF95756EA5,HpEdk2KeyboardEngine +5B0E3ECB-0A1F-4E57-A9D1-E68A9F32ED0D,LANWakeupSmm +5B1B31A1-9562-11D2-8E3F-00A0C969723B,EfiLoadedImageProtocolGuid +5B232086-350A-42C7-A70E-3497B5765D85,OEMSSDT +5B2820BB-9A8A-443D-A84C-73B925C5727A,AmdApcbRvDxe +5B417B70-7F5F-496F-A803-8A0A2CAC34E3,EfiPlatformTypePurleyLbgepdvpProtocol +5B439945-4333-419F-8D88-84C69562E2F6,EfiPlatformTypeCrescentCityProtocol +5B442B31-1F54-4616-A6CC-3CEC4DB3A34B,SraSmmStub +5B446ED1-E30B-4FAA-871A-3654ECA36080,EfiIp4Config2ProtocolGuid +5B4F6194-44DB-4179-B6F2-7B94ADAD312B,AsfDxe +5B51FEF7-C79D-4434-8F1B-AA62DE3E2C64,EfiDMArGenericErrorSectionGuid +5B525F29-827D-4CA3-BEB5-8954B56C0573,EfiSmBmcVariable +5B60CCFD-1011-4BCF-B7D1-BB99CA96A603,SystemFatPei +5B61EDEF-52C8-41FD-AAE7-0938DDF0BB5E,DellRCSetupDxe +5B68A1FE-B135-4965-82A4-103CB4BCF92E,DellServiceOsInterfaceSmm +5B6BB60C-5AAF-4217-9825-0933D8328588,Ax88772 +5B6DAB96-195D-4D24-9727-A7D0E93665C6,IconSD +5B6DBCBC-85F4-4BFC-AF96-188581325C42,AmdLegacyInterrupt +5B6F7107-BB3C-4660-92CD-542690280BBD,BootDiscoveryPolicyMgrFormset +5B74570A-03B1-4F5E-8ADB-FB7BB194D7CC,NVMeInfoSmm +5B74C741-4A5F-4A8E-B689-D804AB4368FD,DxeRealtekCrcInit +5B7CC220-E183-481C-87F4-27A92D8DB88F,SiInitPreMemFsp +5B7DF90B-2B93-4493-ABAA-4805BF008AEA,HpDmarSetup +5B85965C-455D-4CC6-9C4C-7F086967D2B0,PKeyFileSha256Guid +5B862868-7474-4CF2-81A1-9FCA12FEB5B0,FjSiidSmm +5B94E419-C795-414D-A0D4-B80A877BE5FE,FspSecCoreT +5B990069-AAF3-4CE8-93AE-533D0D30A56B,OemSSID +5BAB88BA-E0E2-4674-B6AD-B812F6881CD6,DxeVlvPlatformPolicyGuid +5BAC0CE8-902A-4482-9C26-F281C9388E33,FjNvramSmiSmm +5BAD89FF-B7E6-42C9-814A-CF2485D6E98A,EfiEventNotificationTypeNmiGuid +5BBA83E5-F027-4CA7-BFD0-16358CC9E123,IccOverClocking +5BBA83E6-F027-4CA7-BFD0-16358CC9E123,IntelIvbGopDriver +5BBC3340-6122-4925-BB48-44333899FFEC,AsusSecuredCorePC +5BCE8C69-40F2-87C4-047B-CEABF009F7ED,MctpSmbusSmm +5BCEC275-6968-4FBF-8339-90685DE8AD81,TouchDriver +5BD4977A-580F-4F1A-B3C2-5198E6DCBEEA,AmiCspGlobalNvsDxe +5BD5555A-835F-4F1A-B3C2-7777E6DCBFFF,AMTConfigurationDxe +5BD7E09C-A2F7-4873-8DCE-28D395DA98F7,DellRmt3Smm +5BDCD685-D80A-42E6-9867-A84CCE7F828E,TbtSmm +5BDDE605-B107-419E-9510-AA3C434EBBE4,LegacyBiosPlatform +5BDEE236-0CB5-4D86-A608-EE7B0C5F2956,LenovoSecureErrorManagerDxe +5BE3BDF4-53CF-46A3-A6A9-73C34A6E5EE3,NvmExpressDxe +5BE3BDF4-53CF-46A3-A6A9-73C34A6E5EE4,NVMeSmm +5BE40F57-FA68-4610-BBBF-E9C5FCDAD365,GetPcdInfoProtocolGuid +5BEC0DF8-B466-4442-91F2-721DAB8F7DA1,AudioSmm +5BEDB5CC-D830-4EB2-8742-2D4CC9B54F2C,Ip6Dxe +5BF3654C-7E7D-4FBA-8BC6-2AEBCD6F68EB,Apple80211 +5BF62B21-4118-48E8-AAE0-46EA19615C04,H19PlatformServiceSmm +5C0083DB-3F7D-4B20-AC9B-73FC651B2503,SocketPkgList +5C08E2E2-AD70-4C99-94A2-AE604EA033DA,IcnsConvert +5C0DFC5E-B4CB-4484-B768-260D7184FB58,AmdCcxZen4Smm +5C0F03D2-13C7-4C8C-B92E-2ECC692CA5C8,DfuMeFirmware +5C0FB3B9-F7BB-467B-A4DC-89D7D5A58432,AsusResLoader +5C198761-16A8-4E69-972C-89D67954F81D,EfiDriverSupportedEfiVersionProtocolGuid +5C1997D7-8D45-4F21-AF3C-2206B8ED8BEC,PL061GpioDxe +5C19A130-A447-4DD8-BFD4-1CA7E2210A5C,FastbootDxe +5C1D737E-36D6-45B1-862C-6B9C244F4C07,PlatformStatusCodeHandlerDxe +5C266089-E103-4D43-9AB5-12D7095BE2AF,IntelSaGopDriver +5C284C81-B0AE-4E87-A322-B04C85624323,EfiEventNotificationTypeSei +5C2CD12E-E2F2-4276-A0F2-4A17832F774D,FchSmbusPei +5C337A89-C708-4B03-9485-C08BCA6FA8FA,SmmEntry64 +5C3C5472-1ADC-44D8-93F5-78B31B950931,aModelName +5C3FF3EA-5E95-44AB-A042-F1CB952D0CE9,IntelRaidBiosThunk +5C403B01-8C30-4E68-96A0-55612F9C32B9,AsusEcDxeBs +5C43D50E-311D-4481-86E3-3842549EDC1C,AmdHotPlugRsSmm +5C44EAF7-FF0B-462E-87F4-2D46460BF48F,TraceHubStatusCodeHandlerSmm +5C476C6E-BB09-11E1-86A7-78E7D1AF36D1,HpNetworkTransferDriver +5C536A02-BDFE-4F47-BF72-18FF5DEAF8E9,FchSandstonePei +5C59F275-630A-4855-898C-9AD0C252F823,BrightnessHardwareEcSmm +5C6FA2C9-9768-45F6-8E64-5AECCADAB481,DxeCpuCacheProtocol +5C7C1793-AA9B-434E-B307-B7FFCAB49FAD,RTCWakeup +5C7F8702-838F-43DF-91E6-7833B6F2A067,DxeCoreReportStatusCodeLibFromHob +5C98DE6E-CB69-465F-B6B9-F661E26E6F9D,LibGdtoa +5C9D17C2-4DD8-45D9-8E06-BDD3F8B45E4B,AmdI2cMasterDxe +5CA8EC13-18DE-48E6-B037-67A2772F3EBB,Tcg2Pei_ +5CAB08D5-AD8F-4D8B-B828-D17A8D9FE977,TrEEPlatformDxe +5CAC0099-0DC9-48E5-8068-BB95F5400A9F,RecoveryOnDataCdGuid +5CB5C776-60D5-45EE-883C-452708CD743F,EfiLoadPeImageProtocolGuid +5CB9CB3D-31A4-480C-9498-29D269BACFBA,EdkiiPeiMpServices2Ppi +5CBC260D-CDC0-4BCB-9F74-0A3EA8160905,FjKbcEmiSmm +5CBDEC0C-BD0C-4C3B-8C83-8FEB1104BA69,Cf9Reset +5CBEF321-9B75-3120-88CD-5D123412CBCD,ATIPwrXSmi +5CD10F33-B73B-465F-A89B-7A881137D416,H19ServiceBodyDxe +5CD9649D-2874-4834-802B-C559C94703AE,Usb4CmDxe +5CDDFAF3-E9A7-4D16-BDCE-1E002DF475BB,UefiDebugLibConOut +5CDEEC47-2538-11E7-A438-B8E8562CBAFA,AppleVoiceOver +5CE5C0AD-34EB-4B2B-8E15-EEAE353AC515,OemSVN_ID_Smi +5CEA02C9-4D07-69D3-269F-4496FBE096F9,EfiPersistentVirtualDiskGuid +5CEBCDE6-1096-4FE2-9921-5F8E25281A3E,CpuSmm +5CF308B5-FA23-4100-8A76-F326C2814880,AmiMeasureCPUMicrocodeGuid +5CF32E0B-8EDF-2E44-9CDA-93205E99EC1C,EmuThunkProtocolGuid +5CF32E68-7660-449B-80E6-7EA36E03F6A8,EfiUserCredentialClassUnknownGuid +5CF98C48-F2A3-462A-90D6-8837400B4C09,ForceEfiBootDxe +5D11C653-8154-4AC3-A8C2-FBA28920FC90,VariableFlashInfoHob +5D1C5BFF-3B25-4983-9A33-D4691BB3E9A3,UltraFunctionSwSmi +5D1F3F9E-8CEE-4299-93C2-4C64EBB58977,GetServByName +5D206DD3-516A-47DC-A1BC-6DA204AABE08,AmiOnboardRaidController +5D337D63-2677-4868-8251-B97C6D1F0E90,YukonEthernet +5D3D7AC4-BD45-4B01-B9DE-A58F4E3216CC,AmdCpmThunderboltMid +5D3D9BCB-B134-4CE0-B71A-AC6E65A75127,SioSsdtDxe +5D3F625B-A39D-410C-8D6A-9C31056406DE,ODMServiceDxe +5D44BE77-5669-41D0-B685-1BF3F83EFB98,DellPasswordUi +5D5450D7-990C-4180-A803-8E63F0608307,EfiSmmMpProtocol +5D6B38C8-5510-4458-B48D-9581CFA7B00D,EdkiiDeviceSecurityProtocol +5D7022B2-D3CF-4310-AC0A-4708DC4E5469,IioCxl2SsdtInstallDxe +5D71AF21-F162-4FAE-97A6-4C92CA8FC623,FchSmmDispatcher +5D724549-D2B1-4EB2-8263-AF5ABB12EB03,SamsungWa +5D744BC4-CA94-4F8A-9C50-EBC2A107303E,SerialIoUartDriver +5D751BCA-5A2D-BEC3-8B77-86F30CA893D3,PeiGraphicsOutput +5D758BFB-B323-4F6C-9017-A3238CE65163,LenovoSetupRestartDxe +5D7FE222-B0D3-400F-B092-5657623BD0BE,BootBlockProtectionDxe +5D8111C9-B4F9-46F3-9DDB-73A41AC696C5,password_capslock_indicator +5D8AFDDF-5C95-4DA5-BB46-832F0D4BBC76,HpGraphicalFontSubComp +5D9498AB-959E-4E6F-8C0B-8691C029B71C,OobMsmDxeDriver +5D9516D3-BC49-4337-9FC7-29DF3526EC87,EfiPeiPlatformTypeLightningRidgeEX8S2NPpi +5D9631B7-578B-43E0-9EFC-EB2C20124801,SkipPlatformAuth +5D9F96DB-E731-4CAA-A00D-72E187CD7762,EfiEapProtocolGuid +5DA9E544-DC2D-4670-A3D5-985236D5DE45,DellHotSosSmmDriver +5DAA4237-0031-4B0B-967C-74477129D6F0,H19CheckPointMultiThreaing +5DAF50A5-EA81-4DE2-8F9B-CABDA9CF5C14,SecureBootConfigFormSetGuid +5DB12509-4550-4347-96B3-73C0FF6E869F,EfiRedfishDiscoverProtocol +5DB37E5C-2EEB-43F8-ADA0-243702D3945D,DellSioConfigDxe +5DB79943-DA75-415E-9282-74471AA2CFAA,CmosWarningPageUp +5DBA82CC-E80D-4478-A07D-394F362D3524,RasClvSddcProtocol +5DC03827-C9CB-4C83-B15F-6EAFBF86476C,AppleUartDxe +5DC2E5EB-352A-4BC9-85A6-F21B59067154,OEMComDxe +5DCFD448-794C-40E9-BDE4-4A923A9253F8,OemNvramDxe +5DD41324-E81E-4582-A45A-BF8E53A91548,OdmDxeGNVS +5DD4B7AD-C8D5-48C0-A506-7ED791EB1A8D,AmdFabricStxhSmm +5DEF82D2-6ED7-47DE-B0AC-11E55BAFFB05,LpcFlashLibNull +5DF4E4F9-9BCE-4C38-9D9C-8DFE61687AA5,UfsEraseDxe +5DF5A523-3036-4E1A-83E3-35D755EB4081,D01ODMWmiDxe +5DF9946D-8170-4FB5-854F-A98865F9878F,gear5 +5DFAE03E-9C19-4996-85BF-65297BD4137F,PlatformVTdSampleDxe +5E0AD13C-014B-4921-9966-ACDEB04F3CC7,RemapIommuPei +5E1BB4F6-0D47-46F3-A18A-41EB400BD0F9,DellVirtRtcSmmProtocol +5E36941D-EBA5-4DD4-B6EE-D91C7A512290,AsusSmartHsioPei +5E3848D4-0DB5-4FC0-9729-3F353D4F879F,EfiLegacySpiSmmFlashProtocolGuid +5E3C397D-A1A8-4CE6-B058-3A2EB7EEDCDF,AmdSocSp6ShpDxe +5E4A8420-FEC0-40D3-98AE-C4CA45502B93,ODMDiagDxeProtocol +5E523CB4-D397-4986-87BD-A6DD8B22F455,AtaAtapiPassThruDxe +5E559C23-1FAA-4AE1-8D4A-C6CF026C766F,FirmwareIdGuid +5E566252-4F6C-071A-485D-C0B6CD6D05EF,AmdPspP2CmboxV2SmmBuffer +5E5BBC2F-E001-4FAE-94E5-D413E9CA2238,FjSystemDataDriverSmm +5E5CF20F-B63F-11E1-835E-386077F11E9D,I2cTouchPanelDxe +5E7063D3-0C12-475B-9835-14ABB1CB0EE9,SerialRecoveryDevicePpi +5E794317-A07E-45DF-94BB-1C997D6232CA,AmiFwRecoveryCapsule +5E7A99D0-761F-4C26-8269-8571D85B0FEC,ICE30plusSMI +5E90A50D-6955-4A49-9032-DA3812F8E8E5,AmiSmbiosProtocolGuid +5E90F2AE-E938-48F4-87F9-5A219E68DFD0,AmdNbioPei +5E90FA7C-9F13-4C4A-96A7-C115FF568798,LenovoVariableStorePei +5E93C847-456D-40B3-A6B4-78B0C9CF7F20,EfiEapManagement2ProtocolGuid +5E948FE3-26D3-42B5-AF17-610287188DEC,EfiDiskInfoIdeInterfaceGuid +5E975522-176F-4E2D-BB25-64ADCC7792A4,BaseDebugDeviceLibNull +5E9AEA45-1101-4A6E-9905-CC13B6C96608,LogoDxe +5E9CABA3-F2B1-497A-ADAC-24F575E9CDE9,TcgDxe +5E9E1E5A-D6BC-4AC6-A161-854B7BB5E10A,Realtek8153Lan +5E9F8130-8F37-4006-B224-DEA482383084,DashManagementDxe +5EA17ABD-7B30-441D-83AE-3B73C1564B42,PspS3Smm +5EA93CAF-A8DD-4400-9FF6-FE343BCAF308,AodSmmSsp +5EAD1D32-C38A-4508-8DCF-0B9918957A4C,AmdMemoryHobInfoPeim +5EC57454-ECB9-49B5-98C2-FBF2021BBE6E,OemPSU +5EC7E137-3FE2-441E-A336-F657268733A6,DeviceBlacklist +5EC9DF0F-9FB9-4CD5-9BAE-12872F032A6A,PeiIpmiUsb +5ECC77F9-AB79-4E0E-90D3-79C31B61B778,UsbMouseSmm +5ED1678F-B3F8-11E3-93B8-047D7B99E097,SmapiSmm +5EDA3123-0840-45F7-ADAB-13A655EF3BB7,DellAcpiConfig +5EDAE60B-A9B0-4246-91DC-E97A4E4ADB2E,Armani_PowerReportSmm +5EFDBD4A-64B1-4F21-8A53-A13E8740E6D7,FchYuntaiDsdt +5F035AFB-AB8D-460E-AC58-254B8939E15C,SystemBiosSelfHealingPremiumPei +5F03BA33-8C6B-4C24-AA2E-14A2657BD454,EfiUserCredentialClassSmartCardGuid +5F05B20F-4A56-C231-FA0B-A7B1F110041D,EfiRegexSyntaxTypePosixExtendedGuid +5F0CAB3E-F820-4FD3-B5F1-4568ADA0ACC6,PiSmmCommunicationPei +5F0D7C9C-A3F5-4184-836D-DCEF650A493D,FjUCMPei +5F0FBE1B-1673-4FD2-9BDD-31D7909D5161,AmdNbioBaseRnPei +5F171F5F-8385-4086-A69B-1FCF06AE4A3D,AmiOsPpiConfirmationOverrideGuid +5F1B0D5B-DB44-4B81-A69D-553C591AF092,OCMR_DXE +5F2719E2-4235-44EB-B908-CF74CE26B343,OemManufactureModeDxe +5F439A0B-45D8-4682-A4F4-F0576B513441,EfiSmmCpuIoGuid +5F46BBF3-DF4B-4794-826A-29217E631412,GnbSocPhoenixPei +5F46BBF3-DF4B-4794-826A-29217E63794F,GnbSocRaphaelPei +5F4735F7-DCF9-40FD-8858-026F931942A9,DxeIchInit +5F4B7803-A45D-450A-9105-A1A259C2D363,TPMHwPresentShp +5F53F1DE-E647-425D-8B59-2DDEE19E8C76,SecureBootMgrDxe +5F56DA51-6E43-435E-A167-FA4415E8E6B8,FjGabiCoreDxeBin +5F59B483-73A4-4507-AC11-A1D26EFA187B,SmbiosProcessorDxe +5F5D3502-8A4B-40CA-88A2-2305427A131A,SaPegDataHob +5F5F605D-1583-4A2D-A6B2-EB12DAB4A2B6,ShellBcfgHiiGuid +5F65D21A-8867-45D3-A41A-526F9FE2C598,SystemImageDecoderDxe +5F65DFDB-AC20-4F43-9B21-269E81A0EA7E,PdmWindowButtonGuid +5F67D40C-1D06-4E3E-8B4A-D2713F46E1DC,EfiSmtpProtocol +5F6A843E-D188-41A3-BA3C-A83D8997DC7F,BootPriority +5F712C4A-8B9C-4EE6-ADC6-F4241E2A4129,SmbiosType1 +5F749A1D-9500-48CE-A41F-D0F2F71DEF8C,AmdSocAm4BrDxe +5F7CE43D-565A-4420-B4F8-22ECA7245755,AmiDbrFileGuid +5F7D4E0E-3D6D-42BC-A942-0E91E83E3C31,EfiPeiTcgLogHobGuid +5F82BC22-85E1-489D-93A1-42BBD664B434,IioCfgUpdateDxeLightningRidgeEXECB1 +5F8504C4-BCAA-4600-B435-347EEC6B5E14,MmioSerialUart0 +5F864C8D-F2AE-4221-B8CA-F64ECFB0ACA7,OemDebug +5F87BA17-957D-433D-9E15-C0E7C8798899,AmiDigitalSignatureProtocolGuid +5FAC7360-D4F2-4C9E-A7ED-F2595E670889,SctIsaHcProtocolGuid +5FAD2389-2BC7-4BD2-83D3-429FB6AEA33F,EfiSerialPortTokenSpaceGuid +5FB81FA3-BF65-43AD-A47B-DF70C3112B5A,SvSmmHandler +5FC093B3-9400-4D36-B34F-4EEB07AA65D4,PciDxeInit +5FC364AD-4D63-4B80-B10C-0C8780ADA917,XhciSmiDispatcher +5FC8EEE0-9BF2-498F-B4D3-C51ED4C87BB4,LenovoSetupConfigDxe +5FCD1B11-2981-4EB8-8E03-4A0B5448DF5B,HpRemoteDiagnosticsDriverWmiSmm +5FCEA791-516E-4B61-892C-7229D4FF23D4,Int15ActiveLFP +5FD509E7-02D5-44C1-8BB7-AB29971EEF7E,FjGenericDeviceControlPei +5FD72392-6196-4684-AF2F-7999815B5D45,Smbus2Arp +5FD88B4C-B658-4650-B3CE-A59BB991BFD4,IgdPanelConfigGuid +5FDEE00D-DA40-405A-B92E-CF4A80EA8F76,AmiCcidPresence +5FE33B4A-DC10-4EB5-7E51-364C56D911F4,D01SecureEraseDxe +5FECEF6B-5FA4-4570-8163-0CF72A9C04C5,Ps2Main +5FF69DC2-7613-48F5-9395-35D5481D4EF8,IntelDRSDxe +5FF75356-3EBD-4589-B8BB-FEE7A372E3F3,XnoteBatteryStatusDisplay +5FF80B57-7F8F-48AC-A1DD-207414F503DB,WakeOnLanPei +60002AF3-DC95-4253-88AD-8BD876D83750,DellMfgModeSmm +6000589A-DA4A-44A4-ABE3-4329B098207A,AmdSocFp11StxhDxe +6010BEA0-A051-408D-9A6E-B744D468A05D,WinCapsuleUpdate +601211DC-0B12-4C09-AE27-AB0EC9692468,EfiTxtInfoProtocol +602160C7-E080-4AFE-BE4A-BB5D9B87042D,AcpiTableDxe +60319E22-7547-4BC6-B393-FBA7409F4E25,OemReadyToBoot +603445BC-975D-44A5-FFFF-FFFFB9465403,XnoteSetupAdvancedDxe +60400EBE-52A3-46CF-A322-E21C4718FA88,AaeonEcDxe +60445AE7-B5B2-482F-8672-B51018C95BC7,FjGpioGHOSmm +6046E678-24EF-4005-BA39-BDA11F6D555D,AmtInt16_csm +6048B8EC-6D17-45C0-9BCF-63D164B41AB3,LanRom +6056677A-1288-477D-B7C1-0708CD98A71E,AsusCheckDmi +605CED2C-583B-4171-9311-AA6E146B1A4B,I2cMasterDxe +605E41B8-E923-47CC-87B1-A6E38526E78D,SmbiosCompatiInfo +605EA650-C65C-42E1-BA80-91A52AB618C6,EfiEndOfPeiSignalPpiGuid +605EC241-85E0-4760-A5D2-0D02448FD468,Tca9548aPei +6069277B-246B-45D5-BD6D-81820E10C11F,CommonSmiCallBackSmm +606C2668-E9A4-46E7-A06B-3B9B7EE15CA0,OemPxeBoot +60707C56-8B72-435B-AB8F-251C9C0D2A34,BiosAuditLogSetupDxe +60740CF3-D428-4500-80E6-04A5798241ED,HstiIhvDxe +60745C8C-FE6B-4C6B-B770-3F7C35EFF696,TamperEventS3Check +6074610C-93C6-4A50-9AAA-0927DE7C6975,FirewireDeviceDxe +60798953-1E91-46C9-B521-316623424522,WheaErrorLog +607F766C-7455-42BE-930B-E4D76DB2720F,EfiTrEEProtocolGuid +60812E8C-505B-4D3E-A5B7-1715656CE362,ProjectDxeDriver +6083745A-36FE-4C37-859A-55B773AEC2D3,FchBixbyPei +608FBD1D-15E1-40C4-9443-662ECC0C07AA,DxeOemDriver +6096140B-F2AA-4FB5-950D-D8FE833564DC,AmdDashDxe +609724A2-DBFE-4E3E-A129-9E01A74E49BB,HpPlatformErrorLoggingDxe +609758B3-DA0C-4CAB-84F0-793E8434C57C,AcerProductInfoDxe +6098E606-472C-4F51-8A40-24376D2C66B7,System +609C6CAE-C55E-4DBA-BAAE-FFF021EAE196,MediaSanitizationDynamicSetup +60A14F6F-55B9-47A3-B067-01A93027F3FE,AppleMemoryTest +60AC3A8F-4D66-4CD4-895A-C3F06E6665EE,iFfsAcpiTables +60B27E1A-D65E-4DB0-B2BB-C16FA71E44AB,PdmWindowSpinGuid +60B5E939-0FCF-4227-BA83-6BBED45BC0E3,EfiBootStateGuid +60B751F7-43B9-4238-8819-6B862B68C889,PhPlatformDxe +60B9DA4F-993D-411D-B43A-08B41E7BEC24,AsrockAmdSetupDxeMts +60BCD5C8-76F7-45AF-A541-C813EB86B635,AmdCpmWirelessButtonHidDxe +60C79D40-74FA-4DC4-A654-14C32E2E217C,FjFirmwareOnlineUpdate +60C83BC9-89FB-48D5-8962-A5DCE1D4C0FE,PostMessageDxe +60CDBBE2-3951-42D8-A963-8638A002E3B5,SetupUtilitySilicon2 +60DC3885-9DCF-498C-9A32-DADB6AFA99A0,ErrorCodeHandlerDxe +60DE9928-47DD-4516-BAFB-34FA8F74A5D3,AppAuthenticationDxe +60E7BCDC-9ED0-40E7-A9E3-99404CFBD4B2,AlarmLEDBeeper +60EBDAA4-1565-4D9A-99C8-88DFA65549A5,DellFlashScreenDxe +60EC7720-512B-4490-9FD1-A336769AE01F,SmmControlPei +60EDA97E-3631-40A4-85D4-4A28065086B8,AcerWMI +60FABA47-419B-4E50-85C7-20E86AEE00FC,ASRockNetTcpWrapper +60FF8964-E906-41D0-AFED-F241E974E08E,EfiDxeSmmReadyToLockProtocolGuid +6107BE23-5BAA-4FC9-8FC9-F2AEA77B07A7,FireWireOhci +6107EF7B-D384-4A24-BC9B-5FEF731F6A5B,IsaUartDxe +6108476E-4C45-4EC0-A7F2-5C2B3170EB71,WlanSupplicantDriver +610CDB96-7E56-44CA-BFF4-7D9B6000D87B,EventLogDxe +611114F1-A37B-4468-A436-5BDDA16AA240,EdkiiHttpCallbackProtocol +61141CA0-1444-4C4E-A16D-B601E0A09466,LenovoSystemKbcInitDxe +61187967-9A77-419D-AAEA-64DD56190815,AmiPeiSbOemPlatformPolicyOverridePpi +612A76D7-5FDD-44E4-8702-9B84497B49EA,OemAcpiDriver +612E0D09-5D11-4516-82EE-6DD605FE265F,DellTxtDxe +613AD642-6A48-4E88-9005-28769360BE73,LenovoSplash2Protocol +613D7B84-F774-497F-9A18-6C0ED78D139D,SystemDefaultVariableProviderPei +6141E486-7543-4F1A-A579-FF532ED78E75,ResetSystemPei +61422D26-81EC-47FF-B6CF-939EAEE73FBA,StatusCodeDxe +614778F8-B85F-438E-9674-52DE7E32EAA2,ChargeLedDebugDxe +615E6021-603D-4124-B7EA-C48A3737BACD,BiosKnobsDataBin +6162A355-D641-469F-82E5-CFFFF2722973,TcrOverMarvellNotify +61631080-5573-4310-9AC5-0BAFC95E1C1B,AmdCcxZen3Smm +6169AB1C-B05F-4D9C-AFEA-192911E41CE2,AmdPspSmmV2 +6169D4F6-0659-4FB5-B03C-3645D8C80DC8,AmiTseOemPortingVar21 +617076FC-65EE-4340-9B18-7E72FEC05D5A,SmcAOCPei +617362EF-CAFF-47D4-A131-E95E4A345751,AmdUsb4Pei +617BE79C-3133-474E-8017-A733595B4930,ECSMI +61851894-6B92-48C8-A5EB-4E2A5BCF3D5F,SmartCoverPortingDxe +61896BB8-550A-48A6-BA27-F07408D0AAB9,FjIbvSfuPolicyAbstractionDxeProtocol +61939199-2908-4A7C-BC76-F428AA4B1EA1,KEMrCPLDPei +6195F786-D7B1-45F1-9AC7-82EF976ADF4C,SmcNVDIMMSmmDriver +6199DC36-E114-4E0D-8099-99A0BD80A971,DxePlatformSgPolicy +619C2B94-FE5A-45C3-B445-C6AF9BDD7CE0,BiosGuardSecSMIFlash +61A4AFB6-69E8-4EDB-A606-20FB31C13F82,lBoot +61A4D49E-6F68-4F1B-B922-A86EED0B07A2,EfiUgaIoProtocolGuid +61A72ECF-F7BF-444E-BE85-221339D0F00B,SdLegacySmm +61ACEEC7-603F-40AA-8EFF-663D5294D19C,HpPlatformFeatures +61AD3083-DCAD-4850-A50C-73B23B3B14F9,IsaIoDxe +61AFA223-8AC8-4440-9AB5-762B1BF05156,Mtftp4Dxe +61AFA251-8AC8-4440-9AB5-762B1BF05156,Mtftp6Dxe +61BD410A-69F6-436F-9437-16B4F3108F3B,StaticSkuDataDxeHedtCRB +61C4F60B-8195-459C-8BA1-B7B01B64DCEF,PlatformS3SaveDxe +61C68702-4D7E-4F43-8DEF-A74305CE74C5,PeiSmmControlPpiGuid +61DD33EA-421F-4CC0-8929-FFEEA9A1A261,EdkiiPeiAtaAhciHostControllerPpi +61EC04FC-48E6-D813-25C9-8DAA44750B12,EfiPlatformMemory2ErrorSectionGuid +61ED3D94-30D8-408C-97DF-DEDF2740F630,AmtLockPbtn +61F0BA73-93A9-419D-BD69-ADE3C5D5217B,CbsSetupDxeSTX +61F2DAE7-75D0-4EF2-AEE0-939CC3285ED8,AsusSeupItemControllBin +61F3D1BE-542E-4894-B3DA-2143C20B04CA,AsusSecurityJumperDxe +61F6E81A-7BBA-4A7F-B9F2-B0A3B5D461C5,DellFileExplorerDxe +61FE34BB-92EB-49BD-9151-4DB9184B9A6C,FjRuntimeServicesTableSmm +6200BFA9-8529-4DF0-AD67-7DA8DF6B0A4A,FjSystemIdentifierDxe +6205C3A4-1149-491A-A6D6-1E723B8783B1,MainPkgList +621734D8-8B5E-4C01-B330-9F89A1081710,PlatformHookLibSerialPortPpi +62197EF0-7B7E-11E2-B92A-0800200C9A66,BootOptionsPkgList +621D9B95-166A-432B-982D-2D4EEC7875A6,UncoreMiscDxe +621DE6C6-0F5E-4EE3-A102-0BDE769A0AD4,LenovoRemoteConfigUpdateDxe +62265FF8-A0BC-46A8-947E-67FEC0D7907B,AmdAcpiHmatService +62327151-AFC3-4187-89DD-788F0F16B6D5,MiscConfigPei +62331B78-D8D0-4C8C-8CCB-D27DFE32DB9B,EfiLegacySpiSmmControllerProtocolGuid +62408AD5-4EAC-432B-AB9B-C4B85BFAED02,DxeIpmiLibIpmiProtocol +624B948F-6EBA-4DFD-9DDA-10B0073A3735,SocketPkgFpga +62512C92-63C4-4D80-82B1-C1A4DC4480E5,EfiMiscProducer +62547EAC-2878-4342-BB6E-B60F1E0DD3F1,NCT7802YPeiInit +62652B53-79D9-4CF2-B5AA-AD99810A7F17,EfiHpIoxAccess +62674376-D362-45B3-9A6B-0E0D4098CADA,EmbeddedPowerButtonDxe +626967C7-071B-4D9A-9D0C-F112CF0836E9,EfiCrystalRidge +6269CF63-0737-46BF-80AD-9A035F76127E,PowerFailureRecoverySmm +626D93DB-2C42-48C3-915A-71F968A81B04,FmpDxe +627EE2DA-3BF9-439B-929F-2E0E6E9DBA62,BootScriptSmmPrivateDataGuid +627FBCC3-41F0-4378-99B6-533DCE8850A0,SmbusPei +62835C96-19B8-4D6D-BE13-3AA184784344,SbSocStarshipSp3Pei +62864A34-4733-4DC8-9CC3-F86EDD0B3276,ThunderboltSmm +628A497D-2BF6-4264-8741-069DBD3399D6,ConSplitter +628C866A-9CBB-4E00-BF85-7A9E350E0816,PegaSmiDxe +62960CF3-40FF-4263-A77C-DFDEBD191B4B,EfiBluetoothConfigProtocolGuid +6298FE18-D5EF-42B7-BB0C-2953283F5704,SleepSmi +6298FE18-D5EF-42B7-BB0C-295328569842,ResetSmi +62BDF38A-E3D5-492C-950C-23A7F66E672E,EfiPrimaryConsoleOutDevice +62C1E22F-BF7A-462E-A037-BF97BBC3ADF9,EzConfigDxe +62C38AE7-4BF4-4112-B2C8-88B50F317BC9,AgesaSmmSaveMemoryConfig +62CE3D93-25D8-48E0-BAB3-1ABE7C25DC49,MctpSmbusDxe +62CEEF5A-1D7C-4943-9B3A-95E2494C8990,Emul6064KbdInputProtocolGuid +62D171CB-78CD-4480-8678-C6A2A797A8DE,CpuArchDxe +62DA6A56-13FB-485A-A8DA-A3DD7912CB6B,AmiResetSystemEventGuid +62DC08AC-A651-4EE9-AF81-EAA9261E9780,S3NvramSave +62E0B0A2-9D9E-4D5D-85B3-4F5092702FD1,HpClockBufferPei +62E135CA-88C1-4F15-93E1-01193B3499F4,ASiXUsbEthernet +62EB36E4-61DC-4861-9451-45AB2D3EFABA,BiosImageInterface +62EB9C56-A79C-4423-A7F0-891A345208CD,IioDmiInitPeim +62F45A1F-B263-4159-A8BD-F54427226CB3,TypeAAh +62FC1B9A-8851-4654-90AD-CEA8C07FE259,IchSpi +63017E66-D790-4EE6-A0AC-6192AA74ACF7,UCR +6302D008-7F9B-4F30-87AC-60C9FEF5DA4E,EfiShellProtocolGuid +630972DF-8AB5-4A51-9A88-5DCEE225CC70,BootOrderSmm +630AEB10-2106-4234-9DB3-836A3663F50D,BaseCacheAsRamLibNull +630EAF59-9E9E-4515-9F0D-45D556BCAC1A,GetEdid +630FBB44-65DE-43BD-B503-8DE5914536B5,FchProm21GpioPei +6317D53B-0771-42B9-B6A8-D06FDC2DAE96,FjWirelessLanSmm +631B4DF7-BAEA-4C1F-A061-5B6462652822,DellDiagsDxe +63220A49-7909-44D6-A6D0-F3634CC921A6,OemPei +63296C52-01CF-4EEA-A47C-782A14DA6894,SmramSaveInfoHandlerSmm +632D5625-B73D-43B8-AF30-8D225D96168E,BasePalLibNull +633194BE-1697-11E1-B5F0-2CB24824019B,AmiPeiEndOfMemDetectGuid +633205EB-9A1F-4CA7-AAC2-AD810DB10BAF,FjMfgChangeSetupDefaultDxe +6339D487-26BA-424B-9A5D-687E25D740BC,Tcg2ConfigFormSetGuid +633EF394-8950-4544-8AA3-E6B0B72014D8,AmdMemSmbiosV2RmbPei +63438C6E-971C-4E40-8F0B-1109457BE333,LenovoCpuInitPhnxDxe +634DF746-6F4B-4684-93E6-526653E7C35A,OemThermalPolicy +634E8DB5-C432-43BE-A653-9CA2922CC458,Nvme +6362004D-B2A3-44E1-AF2F-E860E5BD572E,CbsSetupSmmBRH +63722DE5-EC4A-4237-953F-5502246776B2,EventLogSmm +6372357A-06D7-43EF-B55C-1964F3DD6916,DxeIpmiInitialize +637E0BA6-C5BB-41B7-A23B-3A65CFC3E9DB,BatteryState5 +637EB153-DB4A-42F1-9101-AAA0FE3EE156,FjVgaSmm +63809859-F029-41C3-9F34-EEEB9EA787A5,IioInit +63811871-CCD2-1042-AACB-5E5B88FF6E68,DiagAccess +6381293C-7AFE-49D9-AFFA-4B8F879A9BCC,DellAutoRtcResetPei +63819805-67BB-46EF-AA8D-1524A19A01E4,SmallLogo +63819805-DDDD-46EF-AA8D-1524A19A01E4,SmallLogo +6388CB0C-CD3A-4D1E-B26C-4D823D8B4BDF,PciExpressDxe +638E449C-8659-4887-8281-275FAED2A743,HpTxtTpm2Provision +6392C853-B610-4A4E-9644-3DBF88AE11EE,NuvotonFwManagementDxe +639707CE-F961-4F3D-99BD-7DFAFFCB1D54,PlatformInit +639B7869-4303-44C6-89AE-ADF4F1333318,EcSecureFlashDxe +63AA9A76-D85F-4A38-B851-A09D4DC1FC1D,EcRegionAccessDxe +63AAAFFA-53BD-4ED1-B5A3-A8A5619C563F,SlotDataUpdateDxeLightningRidgeEXECB2 +63B013F9-6A3C-416B-8FB2-3E03BB75C125,DellSmbiosDxe +63B079FF-216B-408C-8C2C-1AFD25812AA9,CheckAudioState +63B2BC2D-DF5D-419B-873C-2C78A6604A7A,SgDxePolicyInit +63B5AF02-29C8-47A1-90FB-55D331FE4791,AmdHotPlugSspSmm +63B6E435-32BC-49C6-81BD-B7A1A0FE1A6C,PeiSmbusPolicyPpiGuid +63B93CAD-EB6D-4418-9C6D-98702F3D5262,Win7BootModeFeatureByte +63C2637F-F476-4D48-96C5-FF0BD01147AB,PasswordMeasurementDxe +63C4785A-CA34-4012-A3C8-0B6A324F5546,EfiRngAlgorithmX9313DesGuid +63C64ECE-DA83-479D-B382-F4939072C80D,DellGraphicsDrv +63CBCC47-65BA-4C19-9FC0-0AD81C9DB818,SleepStateSmi +63D1F792-7731-4A44-BC8E-9180A36FD0A8,IccOverClocking +63D91D20-EDF8-48A3-87A9-D6526811DB1F,Armani_PowerReportDxe +63DAB9CE-5D03-4560-8A89-D81366363A2C,ChipsetErrReporting +63E3BDCF-2AC7-4AC0-9B92-03A7541422FF,Hash2DxeCrypto +63E60A51-497D-D427-C4A5-B8ABDC3AAEB6,EfiRegexSyntaxTypePerlGuid +63EA1463-FBFA-428A-B97F-E222755852D7,HighMemDxe +63EBC012-0D65-4D56-85E7-F5A7F4022730,KEMhLpcDecodeDxe +63FA7900-6DD2-4BB3-9976-870FE27A53C2,BackButtonSmall +63FF8EF1-20A2-41A7-AE88-1E262E8AF33F,AmdNbioIOMMURMBPei +64021DFE-A62C-42A7-BF46-15078CDF9F89,EfiLpcPolicyProtocol +64192DCA-D034-49D2-A6DE-65A829EB4C74,IccPersistentData +64196C76-58E3-0B4D-9484-B54F7C4349CA,BootModePei +641F19D4-BD65-4D5F-918C-2D53F3D49707,FJPBA_64 +642237C7-35D4-472D-8365-12E0CCF27A22,BootMaintFormSetGuid +6426C814-601A-4116-9E9F-BF9D6F8F254F,DellFlashUpdateDxe +642CD590-8059-4C0A-A958-C5EC07D23C4B,EfiPlatformToDriverConfigurationProtocolGuid +64302048-7006-49C4-AF0A-5ACE61257437,ConfigRouting +64376478-47EA-49E7-AEFF-D763F84729F9,dGpuDetect +6439C273-09B3-43CB-B25E-C675F5BCC73D,AmdMemBrhSp5Pei +643B8786-B417-48D2-8F5E-7819931CAED8,PeiInMemory +643DB325-A252-4BD5-B563-CEA73D64ADA8,FjSystemDataFvDriverDxe +643DF777-F312-42ED-81CC-1B1F57E18AD6,PchSmbusArpDisabled +6441F818-6362-4E44-B570-7DBA31DD2453,EfiVariableWriteArchProtocolGuid +645462F4-AF50-4FC5-838F-1DFBE3225511,UsbCdcNcm +6456ED61-3579-41C9-8A26-0A0BD62B78FC,Ip4IScsiConfigGuid +6467DB88-3E72-4488-91E8-7E028AD08CF8,DellIntrusionDetectPei +6470A429-20F8-4F17-A8C7-00EAEC19FD0B,FchEspiCmdPei +64730D93-E45B-4AF1-91B3-75B52ECBFAE9,MrdMultiBoardSupport +6483998C-9638-4C72-BD1A-77C55C5CEE8C,OSDSMIfunctionSmm +648CE07B-AE5D-4973-BD3C-8C9153C05DC5,SgInfoHob +6490F1C5-EBCC-4665-8892-0075B9BB49B7,CpuDxe +64980BB9-7BA3-4CB0-AA83-FE396A7F6724,UbaMainPeim +64A11188-5B86-4F59-A702-73365896E65E,AcpiVTD +64A892DC-5561-4536-92C7-799BFC183355,EfiIsaAcpiProtocolGuid +64AAEAE0-92DF-4980-8668-6EB5EAAF4393,FvInfoPei +64AF2828-82FD-49B7-BBD9-7B02BAB72CD5,DellEDiagsSmm +64AFC5D0-1DDF-4724-BE8F-ECECC0468E77,AmdNbioSmm +64BEA199-7C6C-4F51-B0DA-F42C897DA5CC,SetupDataParser +64C0771F-0901-471E-BE1F-CB7DADDFB247,DxeTAC +64C475EF-344B-492C-93AD-AB9EB4395004,EfiCompatibleMemoryTestedProtocol +64C96700-6B4C-480C-A3E1-B8BDE8F602B2,AmiPeiAfterMrcGuid +64CB24DF-A67F-5212-BB5F-ABE151768BB6,PowerLedSmm +64D025C4-1EBF-4C22-927B-74FE43DDA412,OemSyncSetupRV +64DC5B4E-9179-4918-8903-D75E1BC8B263,Mec5107Dxe +64E6D006-E62A-481E-8F5A-3F76C9184741,AmdSmmCommunication +64F0A6E6-DDA9-4A5A-99A6-9CC8B8B9A733,FjMfgAcCheckDxe +64F784EB-69FE-4548-BFEB-ADD7606997CC,SaveRestroreFrameBuffer +650870ED-2F7D-4686-BE6E-2D0494F4B629,EventLogPei +650DFE73-6AC8-45E6-9215-9872BEC8B276,ICCDXE +6520932A-3C30-48A7-9E9D-4DD10CD49D4C,EcLabProductionModeSmm +65246A3B-33EF-4F7E-B657-A4A633F130B0,LenovoSystemVariableSmm +65289AE5-1589-484C-A610-90E10AC2DB28,SiSaPolicyPpiGuid +652B38A9-77F4-453F-89D5-E7BDC352FC53,PeiUsbHostControllerPpiGuid +652EC62A-DC15-4B73-B6BD-DAA13BF1D88C,Cf9ResetSmm +652FC80A-684E-40B6-86AC-710148E2C540,ObjMgr +6537C422-DC1A-4ABB-9D25-EAAFE3D3DFCD,AMDPhxGenericGop +6540F933-425F-464B-B4AD-B93A6ED0A8F5,OcInit +65468E65-77F3-40AA-A149-32F223B0A3BA,ControllerDiscoveryPei +654A4AC8-30B0-4361-92C5-72D1F32A589D,TypeCPostWmiMessages +654CE064-776B-4759-98F5-AB0EDF692D0E,AmdPspDxeV2Stp +654FE61A-2EDA-4749-A76A-56ED7ADE1CBE,CmosPei +654FE61B-2EDB-4740-A76B-56ED7ADE1CBF,PowerLossFun +654FE61C-2EDC-4741-A76C-56ED7ADE1CB0,RTCSingleWakeUpInPei +65530BC7-A359-410F-B010-5AADC7EC2B62,EfiTcp4ProtocolGuid +655B0D2F-BCF1-4B1E-9A6A-A2E891BB50E4,BiosGuardFirmwareVersionPeim +655E4407-C79C-42B7-BE2C-9E1A266B08A3,AmdFabricRsSmm +655E4C19-9D7B-4491-AD10-A49FF355C00A,FastBootOptionBds +65639144-D492-4328-A498-F4B5545E4A30,IffsPartitionStatusProtocol +65675786-ACCA-4B11-8AB7-F843AA2A8BEA,WdtHob +6568A3D6-015F-4B4A-9C89-1D146314130A,EfiSmmBaseThunkCommunicationGuid +65691229-3CE4-4147-ACCA-E558A23AD1AA,PciePortControl +656F7E22-5701-4341-A9A7-99A5D40A5245,AmdFabricSspDxe +6572045F-B1BF-458E-BC02-706762C609AE,EfiHeciSmmRuntimeProtocolGuid +657417C6-3C37-4C7C-907A-72C9EF34F802,FjEcDxe +6579AF18-92A2-415D-81D8-8B8FD867B42E,AmdSocSp5BrhPei +657F02D5-969B-402F-ABAE-E3B354D721D9,WifiProfileSyncDxe +65838FDF-F450-4394-B4CC-43953E72943D,FjDashCtrlDrv +658D56F0-4364-4721-B70E-732DDC8A2771,TrustedDeviceSetupApp +658DE942-03CE-43A3-891D-46423C5345BC,DellMfgSmm +6595CA83-8D11-4BA5-BDD1-92879864D320,PiSmmCpuDxeSmm +65986603-43BC-4ABF-94D8-5A58847381A6,SiliconPolicyDxe +659CD151-CA74-47AC-80DF-055F35BDBF4B,ControllerDiscoverySmm +659E9707-D2D6-4A66-9E38-4E840B3245C5,OemAfterSmbiosDxe +65A18235-5096-4032-8C63-214F0249CE8D,BaseMemoryLibSse2 +65A72030-B02E-4BF3-8424-BA5F2FC56DE7,LenovoSetupUnderOsSmm +65E5746E-9C14-467D-B5B3-932A66D59F79,XhciPei +65E9EB9D-812D-4161-99C5-05AC4BCCA494,DellSmmGpe +65EB76C2-7131-4229-B8BA-CA64C7B92D75,SecureCorePcDeviceIdentifierDxe +65EC2EBB-79A4-41DA-AA73-074B884226C1,PlatformDxe +65FA678B-A1D8-40FD-B913-DFFA9ADA2816,DellHddSecurityDxe +65FB555D-5CCA-40C3-9967-227988288DD8,LenovoSupervisorPasswordManagerSmmProtocol +66014986-A45D-4C22-9F6B-7D4EF2038CAB,OemHddHeadParkSmm +6602BA49-08E4-4428-9661-D5E7157F8A9D,AmdLegacyInterrupt +66077457-4E51-4BB6-889B-1E8E1939A214,SmmWakeOnLan +66099139-C91F-4DD5-88EC-5707DE6881A4,HpFBCacheDxe +660C7774-313B-434A-8633-5D1488CCD172,I2CTPResetPei +66247CE3-F9C5-44BB-B53A-7EA96C435FC1,H19ReflowProcess +6626A54F-7E98-4145-8F8F-8DB70D3B04CE,PartialMirrorHandler +6629B2AC-295D-4566-8CCB-EC4182453FE0,AmdLegacyInterrupt +662AD66E-F52D-47F6-A350-488DB9F8AF68,FirmwareUserInterface +664EF1F6-19BF-4498-AB6A-FC0572FB9851,SmmGenericElogProtocol +6652DF0F-E80E-4BA1-8C3F-2A4E5B56324A,SioSmiWdtDispatcher +6653876C-F6A1-45BB-A027-20455093BC6D,SecPeiFspPlatformSecLibVlv2 +66595A32-1877-4AE1-8748-809666EDADC7,AppleVTdDxe +665D3F60-AD3E-4CAD-8E26-DB46EEE9F1B5,RnRConfig +665E3FF5-46CC-11D4-9A38-0090273FC14D,EfiWatchdogTimerArchProtocolGuid +665E3FF6-46CC-11D4-9A38-0090273FC14D,EfiBdsArchProtocolGuid +66633083-3F16-43B2-8ED2-801A2EDC3824,DashBiosManagerDxe +666C5BD6-FD14-45A8-A639-E382A7E1BAA2,OemNVMEGen5 +666E8FFF-F937-41A7-AF2F-F72B790DEB8C,SmbiosDataUpdateDxeXPV +6672D686-98C0-4585-9C15-9469AD4DBBD1,DHCP_vProPei +667A8B1C-9C97-4B2A-AE7E-568772FE45F3,BaseResetSystemLibNull +667C65FD-F778-44EB-ABBE-A5497AF8A85F,PciLegacy +667DD791-C6B3-4C27-8A6B-0F8E722DEB41,EfiEventNotificationTypeDmarGuid +667EF084-74EF-4707-90B3-75145920B39C,EfiPeiBootInNonS3ModePpi +6683D10C-CF6E-4914-B5B4-AB8ED7370ED7,AmiValidBootImageCertTblGuid +6684D675-EE06-49B2-876F-79C58FDDA5B7,IrmtAcpiTableStorageGuid +668706B2-BCFC-4AD4-A185-75E79F3FE169,NvmeDynamicSetup +668C17B3-7E21-4229-A072-2936F414D73D,LEMRomLayoutDxe +668F4529-63D0-4BB5-B65D-6FBB9D36A44A,QemuBootOrder +66916462-1F93-4C06-AB1F-F0F63583B916,OemDptf +669346EF-FDAD-4AEB-08A6-21462D3FEF7D,PerformancePkgTokenSpaceGuid +6695974D-968C-420B-80B9-7870CD20118F,PlatformSecLibNull +6696936D-3637-467C-87CB-14EA8248948C,SimpleTextInOutSerial +6697CE1C-D9B6-4535-B661-8B731BFF0408,SmbiosType2 +6699390B-DD2B-432F-BEB2-8C7D6A2C0CFC,HpPlatformPeiServices +669A9747-A65E-4F39-8FD6-9557573BC9DA,DellSystemIdPolicy +66A06013-AEBC-4A1F-A01A-AA3A74F98836,HeciAccessSmm +66A5851D-661E-4904-85D4-0A6608805CBD,OemEepromLanDisable +66BC00DC-8557-4FC1-9BEC-137760E27E96,RasClvMirrorFailoverProtocol +66BE3B16-4E6C-4BF6-A4E8-F879B8ACF16D,DellSecurityAuditDisplayConfig +66BF079F-2A14-47ED-A0F2-90CAF356E088,ASM108XPEI +66C36996-C62E-4D13-BF9A-756E66B01A3D,StoreRestoreMbrDefaultsAndWmi +66CEB16A-66DD-40A7-AAFF-0A9B9F83FD6B,WwanReadySettingDxe +66D54351-4C4B-4470-9599-F17A32752871,AplRecoveryPei +66DE8584-DE01-4BAB-B5D0-8B99594372FC,IchUhciPei +66DECFBB-345C-4892-9C92-D07C70DBC817,AmdFwConfigSmm +66DFDAC0-AA71-434E-8BE7-6A959B42C3A9,OemAmt +66E6C2E4-0245-4545-8165-12322480AF31,AdvancedPmaxDxe +66ED4721-3C98-4D3E-81E3-D03DD39A7254,EfiUdp6ServiceBindingProtocolGuid +66EECF40-6312-4A1A-A83A-B3B2F8D8A71A,LenovoVariableDxe +66F0C42D-0D0E-4C23-93C0-2D5295DC5E21,BiosGuardHob +66F831AD-FCCC-4221-B11C-7F4F4802B690,CbsBaseDxeSTX +66F8B964-A3F1-497B-B228-26B89EC3BDCA,AmdDrtmControlPei +67056139-CE96-4688-B7E7-73803EA528FA,ConfigChangePromptDxe +6707536E-46AF-42D3-8F6C-15F2F202C234,MXMdat +6711A637-2C2B-48EA-BD29-88E8A2F80B93,DellFingerPrintReader +6713DB37-20C7-4E23-BD42-C5B300A6AE32,SmmPBDispatch2OnSmmPBDispatchThunk +671AC69C-AF3A-47F1-884F-A4B04B257057,AmdPspPeiV2Phx +67269263-0AF1-45DD-93C8-299921D0E1E9,SmbiosUpdateDataProtocolGuid +672A0C68-2BF0-46F9-93C3-C4E7DC0FA555,UsbCredentialProvider +67329203-BAA6-49CA-B3C2-3784EB517017,KvmPlatformDxe +67375F4E-29AE-433F-9C2A-29EE6C7F5F2A,EmulationEDIDPEI +6737934B-A27E-4C05-AD5B-6AB86273680B,AmiNbMrcInfo +6737F69B-B8CC-45BC-9327-CCF5EEF70CDE,AmiPlatformIdeProtocolGuid +674177F0-730F-4EB9-A269-9C5F285230D8,DellUsbBusDxe +67439E94-FD37-4A32-BD53-3B97386432E4,Ahci +67451698-1825-4AC5-999D-F350CC7D5D72,CryptoPPI +67499F84-F2E5-4DD2-9E56-C6E389DD6173,DellRtcAutoOnSmm +675846BF-969B-4F29-ACBB-81BF308EB457,FjSiidPostHandler +675B8766-7F03-4181-9BE1-73BC45DFF799,EfiIpmiCmosClearVariable +67620EFF-C802-4BE8-BFA1-125EB25D1E8A,PublicWmiDxe +67666768-9C64-4CAA-BAF4-CA3E4CB7697A,EfiSmbSmmDaCiProtocolVer2 +6776572C-FE56-42CA-9B93-3D0960E7583A,IconBrokenBoot +67791E00-0C05-4AE7-A921-FC4057221653,TxtOneTouchDxe +677DA7BA-DF14-429A-A74F-78417E8B09E4,PhMePeim +67820532-7613-4DD3-9ED7-3D9BE3A7DA63,Aint13 +67856945-C6BF-476A-925D-EBD1CD2EAE11,KEMrJtagDxe +6789A9E8-6FE9-4E1C-90F9-59329ED27300,AmdFabricRmbDxe +6799D91E-0311-41F0-99AF-F162B9EC93CE,ProcessVideoOpromDxe +679AEE8A-CE51-4CCB-9AF8-90E055B3933E,NvmeRecoveryPei +679E3A98-341D-464F-8D78-3CE744F0BEB7,FchYuntaiSsdt +67A54A24-3F4F-4048-8787-3E5AA2A0B7D2,SAPolicy +67AC0B1E-54C2-41A6-B57E-C2A321416ABC,ActiveBios2 +67AFDE5F-EF16-47B8-BA19-C21B3907DBF1,MiscGaIoSmm +67B495CF-17CE-424B-9633-49773AE63908,UsbWorkaroundDxe +67B5787C-0E6A-4796-943E-A093B73A0267,HiiUtilitiesProtocol +67BBC344-84BC-4E5C-B4DF-F5E4A00E1F3A,SdHostDriver +67BC3883-7E79-4BC1-A33E-3AF7D17589BA,AmiHddPowerMgmtProtocolGuid +67C4F112-3385-4E55-9C5B-C05B717C4228,EfiSmmSwapAddressRangeProtocolGuid +67C53648-DA56-4726-AE21-FBA4D04686B3,RsdpPlus +67C5DCDB-CFF3-469F-FFFF-FFFFA7E16F95,XnotePlatformPolicyPei +67C63A11-F89D-4500-8270-D9DB251EB2AF,Ps2KeyboardPei +67CA9132-4415-4815-B2E0-DBDF68787871,OemMedinaEC +67CDD184-C0D9-4358-B376-330BF67D01AD,HpCommonFlashInfoSmm +67D1C54D-B8F7-4D69-A8F3-FF9116C4C02A,FchKunlunMultiFchSmm +67D6F4CD-D6B8-4573-BF4A-DE5E252D61AE,EfiJsonCapsuleId +67DB1E5C-EE66-48FD-A4B5-E9BD16EAFDF6,SmmAccessPei +67EE3885-80D7-4494-A5FD-445527E23F0E,FirmwareRollbackProtectionDynamicUpdate +67EF7A73-2594-4A5E-930A-E166FABCD2C8,EfiDmiFormatFru +67F8444F-8743-48F1-A328-1EAAB8736080,EfiCertRsa2048Sha1Guid +67FA951E-4FA2-9F4E-A658-4DBD954AC22E,HpSmbiosDxe +67FB408E-A519-40E9-8321-79F13FFDF9AF,RstResourcePei +680027A0-2FDF-4E07-B518-E3631685914D,HpStorageResetHookDxe +6806C45F-13C4-4274-B8A3-055EF641A060,DxeFileExplorerProtocol +6807217E-E8DE-42D0-91D9-60AECED7420D,Stall +68155128-AB86-437C-B235-4F860939A56C,TouchDriver +68198A68-D249-4826-BC5E-45DF0CCA2A53,EmuLinuxLoader +681D2368-4540-4FA9-8C1D-8B79DBF6B9AE,HybridGraphicDxe +681F3771-6F1D-42DE-9AA2-F82BBCDBC5F9,WinNtFlashMapPei +6820ABD4-A292-4817-9147-D91DC8C53542,EfiPlatformErrorHandlingProtocol +682316BC-5595-4152-97AC-8A5FCCC6EA8D,AmtLockPs2ConInDxe +682FC854-D0CB-4C9F-A8C4-F4F97A39EF3E,OemProcMemInitLibPpi +6834FE45-4AEE-4FC6-BCB5-FF45B7A871E2,BeagleBoardTokenSpaceGuid +683732B5-2A38-43A8-9CE2-02CD7250DCD9,A01BootDeviceServiceDxe +6841E518-1D6F-4B75-B4D1-CF190DC56B01,PegaHotkeyHook +68455128-AB86-437C-B235-4F860939A57C,TouchDriver +6847CC74-E9EC-4F8F-A29D-AB44E754A8FC,ArmMpCoreInfoPpiGuid +68501047-111F-4BD2-AA33-6C1ECE271259,ApplePlatformInitDxe +685026CA-92FA-45FD-BC72-BA44700EE575,UsbPortXhciPlatform +68642720-69BB-4BC7-98CF-5C31EE74AFFB,PeiWakeOnLan +6865C455-8626-40D8-90F4-A69460A4AB5A,DcaHob +68661738-D70D-4BA1-BFCE-7DBABE14FB9C,FileExplorer +6869C5B3-AC8D-4973-8B37-E354DBF34ADD,CmosManagerSmm +686A1553-4BD8-4794-AA27-27F57384A990,DellEepromToNvs +68744031-8608-4B25-BBA1-DB4EA319D6EA,OememDxe +68744033-8608-4B25-BBA1-DB4EA319D6EA,ModernStandby +6874C031-8260-4B25-BBA1-DC4EA319D6EA,OemDxe +6877BA45-7E87-449F-984F-FD04503D7A28,SmcSetPowerStatusSmm +687A830D-55FB-415A-9520-182789353284,SetupExit +68866B10-73DA-45EA-A808-15A57D947F98,WatchdogRuntimeDxe +6888A4AE-AFCE-E84B-9102-F7B9DAE6A030,EmuBlockIoProtocolGuid +688BC4BB-6FDB-4B33-A8E1-D7A952DF4B4A,AmdSmmControl +6895F6F0-8879-45B8-A9D9-9639E532319E,UhciPeiUsb +6896350D-C3F1-4A4C-B42D-448D572896C7,DellBootMenuFlashBin +6898A004-3D24-4F38-8507-DC226B3D90CA,SpsPeiPostMem +689CDA29-29A8-42F6-93FC-46BA5F180651,ImagePasswordProceed +689E4C62-70BF-4CF3-88BB-33B318268670,EfiBlockIoCryptoAlgoAesCbcMsBitlockerGuid +68A10D85-6858-4402-B070-028B3EA21747,SpiFvbServiceSmm +68B09391-751F-46FF-A4D6-71B8502F52AB,KeyboardLayoutDxe +68B81E51-2583-4582-95DB-C5723236C4F1,NonSmmEmul6064TrapProtocolGuid +68BC3095-8839-4A97-8FEA-BEE06ECA7BBB,LenovoW25Q32FlashPartDxe +68D076CD-D8F3-409B-987F-1012CDB88242,SlotDataUpdateDxeLightningRidgeEXECB4 +68D89864-C0A8-490D-BE18-C83D67240928,SmbiosDataUpdateDxeNeonCityFPGA +68EDC148-7120-41B4-9F53-F51BFC81A74E,CbsSetupSmmSTXH +68F0810C-1DDC-4407-BD65-872101407AB7,AmdCpmManageabilitySmm +68F19A73-C447-4FDD-B4B7-F380F7DD290F,FprGoodixDriver +69000FC4-15E6-45CF-A6D4-73337A9B5958,AmdCcxZenZpPei +69003CE2-F796-4EC4-AD17-B4D409298636,MctpSmbusSmm +69031D31-FC0A-4CEE-9803-F53015C4208D,RealtekGopLoader +6903A447-CB4F-45F6-89A2-7E7E2F9EE14C,InstallMsdm +69056653-3FC6-4382-90EC-B5FAF7599FD3,CnlHsioTuning +6906E93B-603B-4A0F-8692-832004AAF2DB,PchSmmPeriodicTimerControl +69110D87-9BB3-47FC-B412-22E4F135AE38,AmdCpmMemEyeToolDxe +69125D01-F951-47E9-9583-EF6A27AF703E,SpiAccessDxe +69282DF3-778F-4269-91AA-D7DF6E193317,Uc2OnUcThunk +6932FEBD-2397-462E-B0F9-EEB619FA693B,StatusReport +6941C2B0-CE44-4099-983A-03913B3D765F,EncryptDriver +69439F6E-FA94-4428-AE02-1F5C22EC72AE,AdlinkMeConfig +6950AFFF-6EE3-11DD-AD8B-0800200C9A66,AmdAgesaDxeDriv +6956714C-ACC3-448F-86B6-56AD3A2EB1BD,AdditionalLenovoUI +69585D92-B50A-4AD7-B265-2EB1AE066574,FmpDxe +695BEC93-82AE-4C17-BDAD-7F184F4E651D,LibC +695D7835-8D47-4C11-AB22-FA8ACCE7AE7A,EdkiiPlatformSpecificResetFilterProtocol +695D8AA1-42EE-4C46-805C-6EA6BCE799E3,EfiPeiVirtualBlockIoPpiGuid +69735520-DA83-444A-93DC-BDDD59E59182,Heci3Smm +6973BC24-57F4-46B0-8766-C025ABB97AA4,NvmeShutdownNotificationDxe +697CFA95-B1F2-4ED7-A0D2-7AC6E47B3C99,HybridGraphicsDxe +697D81A2-CF18-4DC0-9E0D-06113B618A3F,EfiExtendedSalMpServicesProtocolGuid +697E6EE3-2EAF-41CC-AC6E-F4EFDFE93E6D,AsfMsg +697F0EA1-B630-4B93-9B08-EAFFC5D5FC45,FmpDxe +6983D90E-3EF7-4D09-8F36-63AE0C59CFF2,DellDiagSmm +6987936E-ED34-44DB-AE97-1FA5E4ED2116,HelloWorld +6988173D-B7C9-47BE-BDDF-255A18676913,UefiDriverPolicyDXE +698AC232-28A6-40EC-94AA-7D302DBF5667,PdrCapsule +699190BD-6456-4286-823C-28E4442DFCAB,AmdMpmPowerSupply +69967A8C-1159-4522-AA89-74CDC6E599A0,IdeSecurityPwnv +6996FC68-B040-4616-A89C-60B4C95D7BE6,ProjectDxePriori +699ADD70-8554-4993-83F6-D2CDC081DD85,SerialCapsuleGuid +69A79759-1373-4367-A6C4-C7F59EFD986E,FspReservedMemoryResourceHobGuid +69AA54B8-9795-4E7A-8689-64A96C9FE3E9,PeiGpioControl +69B792EA-39CE-402D-A2A6-F721DE351DFE,EdkiiSmmMemoryAttributeProtocol +69C5D214-F993-4C34-9011-A06787E5C956,FjSxEnterResumeDispatchSmm +69C5D5FB-FE8D-4336-BE00-582C621A23E3,AmdI2cConfigDxe +69CA132E-062C-4D7F-BE7F-9B0B8446C888,PhLegacyRegionSmm +69D13BF0-AF91-4D96-AA9F-2184C5CE3BC0,PlatformModuleTokenSpaceGuid +69DAB0B4-5FD9-4FEC-AA30-298D2B5A342E,DellFormBrowser3 +69E1A19F-BC8C-4021-B3D9-E0B2545092C6,OC_Tuner +69E6DD6D-F09E-485F-9627-EB70E9CFC82A,UbaInitDxe +69EF78BC-3B71-4ECC-834F-3B74F9148430,DellSmmFlashWriteProtect +69F04F6E-BCCF-45F8-894E-2C68088F94FF,I2cKbDxe +69F3077F-4D4E-4FDE-BBE3-9DCDB120F39B,UsbOcUpdateDxeFischerLakeRP +69F97A4E-1395-434A-A5D3-FF9CEA284885,DellDiagsConfig +69FD8E47-A161-4550-B01A-5594CEB2B2B2,IdeBusDxe +69FEEBE1-D86E-49EB-B60F-A87CB0FBC822,FchSmbusDxe +6A056C67-3128-4102-9EC7-265E73AAB860,GopCardEnabler +6A061113-FE54-4A07-A28E-0A69359EB069,SgTpvACPI +6A0F22E8-69EE-4F1C-9336-69863FD96EE9,SecurityEventDxe +6A11F1A1-318B-4712-89C9-2DBF00995BE0,Cf9Reset +6A159D4F-6E6B-4523-AEB5-F7AF1C444B0F,EfiPprVariable +6A1EE763-D47A-43B4-AABE-EF1DE2AB56FC,EfiHiiPackageListProtocolGuid +6A30E568-598D-407A-A777-8AEE93BA2812,AmdPlatformRasBrhPei +6A3AEA11-2CC2-4B66-B4D3-A8779D6087C1,SystemSecureBiosPei +6A3DEF38-0A45-4107-A74E-ABF2B8EAED86,MemorySubClass +6A4B2718-CAF3-4D51-BD91-9EB1D6229F57,PasswordEncodeProtocol +6A504489-884E-4465-A02F-03B248CDEF13,UserInterfaceTheme +6A54AF9C-00FE-46EE-9AA1-359C9822C8FC,SlotDataUpdateDxeEldorado +6A628EFE-3682-4FDC-A31E-C635BDF18CC8,BdsMilestone +6A763867-4086-40EC-A5AC-6D63021EFEDC,DellSmbDaTokenCfgPolicyGuidVer2 +6A79EBF1-BBB6-42A7-BDA1-5EACF52F2480,MotherBoardHealthDxe +6A7A5CFF-E8D9-4F70-BADA-75AB3025CE14,EfiComponentName2ProtocolGuid +6A7B1C86-590E-47A7-971A-C49B408D5ED7,LenovoSetupSecurityDxe +6A7FD3F4-53EE-4DEC-A1E5-69175B7FD581,CpuCrashLogAgent +6A8209ED-5D36-4906-A316-5541006F558E,OneKeyBatteryDxe +6A85825E-C459-4108-9B81-6602953468E4,FjGenericItemStorageSmm +6A8A395F-4C07-49D1-B94C-22ED50D425F8,LenovoSecureKeyDxe +6A8AC704-E589-4DD0-8EE0-31F87FBE3323,DxeTouchPanelInit +6A908656-35A0-4740-BE0F-4B364FB7945B,FchI3cConsumerSPD5Pei +6A969F3E-ED1F-41FE-A932-43994B05548F,SocWdtSmm +6A9839EE-070E-4B5F-8CCD-87BB12345F38,HddPasswordDxe +6A9D5926-EB27-473E-82E3-223B12CCAA12,FjGabiFlashCoreAbstractionDxe +6AA1A3CC-52C4-4B03-99F7-288F345C1DB3,DellAudioConfigDxe +6AB36EA4-CBF2-48DC-B610-9EBF193A5DEF,OemDisplayModePei +6AB58A31-4BD5-4CAC-8966-9A7FF01C000B,PlatformVTdSamplePei +6AC3044D-E062-4F23-A60B-286764DD09F5,DellSmbiosSmm +6AC5D123-C6E5-41BA-9BE3-A0371EE54B78,SetupConfigUpdateDxeNeonCityFPGA +6AD37609-A9F9-4587-9023-7820E10F5B7A,HiiLayoutPkgDxe +6AD9A60F-5815-4C7C-8A10-5053D2BF7A1B,EfiSerialTerminalDeviceType +6ADFFA83-55AE-4C9F-94A4-800C469BDABC,StaticSkuDataDxeLightningRidgeEXECB2 +6AEA1B20-6384-4B5F-ABAC-776A11698DED,LegacyBiosReverseThunk +6AF31B2C-03BE-46C1-B12D-EA4A36DFA74C,EdkiiPeiNvmExpressPassThruPpi +6AFD2B77-98C1-4ACD-A6F9-8A9439DE0FB1,EfiSmmStatusCodeProtocolGuid +6AFDA662-BFB0-43B8-9848-B67DCD452157,EcdShellApp +6B1AB225-2E47-4A61-8FF5-B8EA42EE3EA8,SecureFlashDxe +6B1C5323-297E-4720-B959-56D6F30FEE00,YieldingDelayDxe +6B1EFA14-06B8-4127-975A-5B2DCF5392E2,SmcPostMsgHotKey_DXE +6B216D1D-5D32-41FD-9698-6F8E58199454,FlashInfoSmm +6B26DE1E-3DF2-4A1D-9B7F-B816B8C90872,ComputraceSmm +6B274332-01AB-4AC3-B3AE-1DE3C65AC3AC,PmemResetNotifySmm +6B287864-759C-42C4-B435-A74AB694CD3B,SpecialBootStubDxe +6B309956-6617-472B-BBC7-2A09E55E3E52,ProgressBarFullLeftEndcap +6B30C738-A391-11D4-9A3B-0090273FC14D,EfiPlatformDriverOverrideProtocolGuid +6B35FEF5-022F-4596-8422-59AFA264C03A,WmiRmtApi +6B38F7B4-AD98-40E9-9093-ACA2B5A253C4,DiskIoDxe +6B41B553-A649-11D4-BD02-0080C73C8881,WinNtSerialIoDxe +6B4D57F0-6AB0-4A7D-BAB2-23425EF055E5,ICE30plusDXE +6B4FDBD2-47E1-4A09-BA8E-8E041F208B95,PchUsb +6B558CE3-69E5-4C67-A634-F7FE72ADBE84,BlockMmioProtocolGuid +6B588D7C-C72E-4A78-8858-77E1DA8FC7F7,ProjectOwnProtocol +6B6D0A03-FD5D-4E10-9774-2D3EAA62EB61,SklRaidDriver +6B6FD380-2C55-42C6-98BF-CBBC5A9AA666,SocketSetup +6B7067C7-A843-A34C-9530-48446963B740,KeyMapLibNull +6B760600-8E5A-4945-AB9C-5732FA90A0B3,FjLanCapsuleDxe +6B789215-B063-45FD-868A-668A49F00EC6,TXTWrapperPei +6B844C5B-6B75-42CA-8E8E-1CB94412B59B,TcgPeiplatform +6B85F263-F584-44F8-BB5D-F02C40795D8E,SmmTcgStorageSec +6B8947C2-4287-4D91-8FE0-A381EA5B568F,rmHwA15Guid +6B8CE99C-9C68-41EC-B507-E03A143C7ED4,WirelessUndiLauncher +6B9FD3F7-16DF-45E8-BD39-B94A66541A5D,EdkiiPiSmmMemoryAttributesTableGuid +6BA22418-4704-4507-ADC4-364B8667E586,LoadSecureWipeImage +6BA6F808-527F-4186-9C30-670499BD92D1,DellSmmComputraceAcpiMode +6BB0C4DE-DCA4-4F3E-BCA8-330635DA4EF3,EmulationDfxSetup +6BB4F5CD-8022-448D-BC6D-771BAE935FC6,EfiKmsFormatSha256256Guid +6BB945E8-3743-433E-B90E-29B30D5DC630,EfiIpmiTransportProtocol +6BBD635A-B13D-4A06-9F8F-1FA086D4EC0F,EcMudSmm +6BC32C76-91DB-4548-A419-0B889EB8196F,EventLogApplication +6BCF854D-132D-49B2-815C-F00151C7BBBB,FjRt8111EepromLess +6BD1E7D5-8234-4894-951F-FEE390C2EB6E,FchSmmDiagDispatcher +6BD7DE60-9EF7-4899-97D0-ABFFFDE970F2,EfiCryptoPkgTokenSpace +6BDF1640-FFC1-4C89-BA76-8DAB230E750C,AsusModuleToIntPeiWrapper +6BE18C9C-BF61-499E-88EC-5CD57430460C,ScSmiDispatcher +6BE272C7-1320-4CCD-9017-D4612C012B25,AdapterInfoPlatformSecurityGuid +6BFF8B94-D98E-4C7E-8300-E5B64701C118,ApobZpRvDxe +6C02F70F-9FBC-4A44-AC19-C648A7AA5541,FjKbcEmiDxe +6C077FAF-8258-4C08-B86D-B8DC632632B4,SmmPlatform +6C09C5B9-BF3F-46D2-9198-4A064826F414,EfiWheaPlatformSupportProtocol +6C0E75B4-B0B9-44D1-8210-3377D7B4E066,SmmAccessPei +6C160B26-E04C-4098-A6AC-C8C7B6471A86,SetupConfigUpdateDxeLightningRidgeEXECB2 +6C1623A2-3245-4F42-A8CE-F73B054FAAFC,MpmDxe +6C2004EF-4E0E-4BE4-B14C-340EB4AA5891,StatusCodeHandlerRuntimeDxe +6C289241-E240-483F-9E3E-872C0396B599,FlashSmiSmm +6C32B3FF-9F2C-44C5-A036-348A388C631B,PchIoExpander +6C33341C-BA4C-4DB4-9BD6-6356971DECEF,FjDisableManufacturingMode +6C3A7C66-3D26-4B1B-B803-2D801243BE29,AmdMbistRsPei +6C4077DF-8D80-6219-B80B-1F2573308D45,DellSecurityDxe +6C440404-5F74-44B8-CCE4-4B048830CCFC,LockLegacyResourcesDxe +6C4B1F2D-221D-4D86-AEE8-FD4CFABA879B,HQEepromDxe +6C50CDCB-7F46-4DCC-8DDD-D9F0A3C61128,EfiPpmGlobalNvsAreaProtocol +6C6872FE-56A9-4403-BB98-958D62DE87F1,UefiSerialPortInfo +6C77FAE1-A934-457A-982E-BCC12F9717AD,AmdPspIntrusionDetectionPei +6C79BA9B-5926-4295-A450-46B3401D95A5,AcpiPlatform1 +6C8E136F-D3E6-4131-AC32-4687CB4ABD27,FmpDxe +6C92CB60-08C1-4149-BF94-60B7C5206011,MAPS_WatchDogTimerDXE +6C9A8087-B68E-4F3D-B87D-A76C829C7D3E,CcgxDiscoverySmm +6C9AA1EC-286E-4A0A-AA98-E2E530626F4D,AmdiGpuVgaControlDxe +6CBC8D0A-7ACE-40C5-92E5-F0DA0A8A869E,FjRealtekLanDriverSetup +6CC094E8-8278-47AB-868C-D826539968C1,AsusPcie2ClkReqMapping +6CC45765-CCE4-42FD-BC56-011AAAC6C9A8,EfiPeiReset2PpiGuid +6CD3857B-1A86-4734-814D-8302E514AE79,AthQCA6174Undi +6CDDBF28-89AC-4E01-9692-616B8A1009C8,FvFileLoaderOnLoadFileThunk +6CDF9BAA-0934-43C2-A85F-286386097604,SystemHddPwdSmm +6CE1E567-46C9-420C-A17E-615D02AE5534,ATPowerDxe +6CE58A5A-030A-4B59-A688-D1D37D7EA985,TpmPlatformMeasurement +6CE6B0DE-781C-4F6C-B42D-98346C614BEC,HpetTimerDxe +6CEC977B-142E-4EBA-ACBB-74D882B166CA,OemCustomDefaults +6CEE9C4A-E2A0-4F3D-A921-CE25F328C4BA,AsfSmm +6CF4D043-2D22-4FF0-AAB0-C5F932847400,SataDeviceFeatureDxe +6CF8600B-6B56-447D-AC08-05F8C3B00054,Tpm2ReservedNvIndexPei +6CFDBB02-DB4B-4C87-BE13-B4E79E68CE51,CbsBasePei +6CFF6068-4FD3-4779-95B8-4DFC90722371,PlatformVTdInfoSamplePei +6D000308-C913-40DB-AD40-B3094FB0F756,AmdCcxXvDxe +6D1D13B3-8874-4E92-AED5-22FC7C4F7391,BiosGuardDxe +6D1EAD71-0CEF-4B2A-B9AE-05D5E9B847CF,PasswordInterfaceCoreSmm +6D29159C-CC7A-4757-8185-42DDB2BECB89,CompalWSMTSmm +6D33944A-EC75-4855-A54D-809C75241F6C,BdsDxe +6D3569D4-85E5-4943-AE46-EE67A6E1AB5A,EfiTelnetServerProtocol +6D36ACC4-B9A1-474F-B333-071A56F3D4F4,AmdFabricRmbPei +6D39E536-4269-49FA-B7CD-25C35A4F8AD3,NvmeEraseDxe +6D3A727D-66C8-4D19-87E6-0215861490F3,EfiUnixSerialPort +6D3D1021-E7FC-42C2-B301-ECE9DB198287,SystemSpeakerPei +6D4849D1-DC04-4D57-BC90-2E0B5CFF1828,AmiPldmInterfaceBin +6D497A7A-D7DA-467C-B485-B7FB3493C41F,DxePciSegementLibEsal +6D4BAA0B-F431-4370-AF19-99D6209239F6,BiosGuardServices +6D54157F-94EF-41AF-B34C-DC7611E6D483,Common_SxApp +6D582DBC-DB85-4514-8FCC-5ADF6227B147,EfiPeiS3Resume2PpiGuid +6D5B6696-F2EE-4729-97D3-A7B8EEF3DBBE,LegacySioDxe +6D5C61C2-7694-4775-9F03-ED1E80DEC318,menu_top_mid +6D5C76B2-3B6D-43CE-94E2-0D6FD2A63BC8,RtkUsbUndiDxe +6D6963AB-906D-4A65-A7CA-BD40E5D6AF2B,Udp4Dxe +6D6963AB-906D-4A65-A7CA-BD40E5D6AF4D,Tcp4Dxe +6D6D9E06-7122-4587-88C5-BD3D13C7E8C4,AmdMemAm4RnPei +6D7A5333-52E0-4910-9DE7-91CDB06395F6,XnoteFlashCommunicationSmm +6D7E4A32-9A73-46BA-94A1-5F2F25EF3E29,EfiMemRasProtocol +6D85CF0A-4A5F-49B0-BAFD-A90992677FF7,WinbondWpcn381u +6D86FB36-BA90-472C-B583-3FBED3FB209A,FspHobGuid +6D9361B4-B534-4C25-99D3-1F12C6794E8E,IioRasInit +6D9BF711-A90D-42F9-A3FB-DD08B6E89037,SLP20EncryptedOEMPublicKeyVariableGuid +6DA12BD9-140A-4FF5-991B-5B471CA4456F,FjSystemIdentifierSmm +6DA4D20D-892D-4EDF-97A7-FEA2D88E26D7,HotKeyPei +6DA62821-54AF-4836-8EF0-8905EF9BD733,AmdCpmModernStandbyFeatureDxe +6DA670E8-3D73-4EB2-A721-A2DDF682FDD8,Tpm12MeasureConfigurationInfoFuncGuid +6DAB4706-5D57-4BDB-9A0E-393A4178D13E,TiOnlySmm +6DADA47D-645A-4128-B292-57A475E1456A,AppleSecureBootDxe +6DADF1D1-D4CC-4910-BB6E-82B1FD80FF3D,EfiSmmPeiSmramMemoryReserveGuid +6DB075DE-449E-2644-96D0-CC5A1B4C3B2A,FirmwareVolumePei +6DB21643-241A-4CC9-82DD-46A1E4845ECC,StrongPasswordPoliciesSync +6DB6CF42-0A3C-4BC9-97DB-9CED03B7F18D,DellHotKeySmmProtocol +6DB72521-256A-4CC1-12DD-96A1E6699ECC,PowerEffcienfyPoliciesSync +6DB9486F-6AF6-4090-984D-238482CE3EA4,BdatAccessHandler +6DC01095-9001-4E4D-B852-AF429EADFF57,OemPowerMgmtDxe +6DCBD5ED-E82D-4C44-BDA1-7194199AD92A,EfiFmpCapsuleGuid +6DDBF08B-CFC9-43CC-9E81-0784BA312CA0,BeagleBoardTimerDxe +6DE7DBA1-C28A-47F7-AF06-1810E1495C56,FjJapanFeatureSupport +6DF5FD0E-4076-41B9-96B5-10E4C9720BB3,OemApControlDxe +6DFD6E9F-9278-48D8-8F45-B6CFF2C2B69C,TpmMeasurementLibNull +6DFF3937-F9F2-41EB-A1D4-59D6E5D9640A,NvmePassThruOverride +6E056FF9-C695-4364-9E2C-6126F5CEEAAE,EfiPeiFirmwareVolumeInfoMeasurementExcludedPpiGuid +6E057ECF-FA99-4F39-95BC-59F9921D17E4,EdkiiSmmReadyToBootProtocolGuid +6E13B746-80DD-4EDC-B178-D25BD4838FBA,HwmThermalSmm +6E185705-E3AD-45EF-83C1-F1F9567AF396,DisconnectKbd +6E1C42D2-278F-4227-BEDE-548CF3206680,AmdMemoryHobInfoPeimBrh +6E27120A-A510-48AC-BD66-7083DA4D594F,CmosWarningPEI +6E2FFCF4-6899-414C-9B55-3A08842E650C,AppleIvyBridgeGop +6E32EAF6-32D1-43E0-B6E1-DCF6DA81DF76,LenovoN25Q064FlashPartSmm +6E36078B-6B6F-42BC-981E-4C639AFA4D6D,FmpDxe +6E448793-9CDF-4787-9392-4B6A6D5FFCA8,DellHwManagerDxe +6E5228F3-933E-4961-9573-0F1E61B522AC,LenovoSmbiosVpro +6E53E391-40FC-4539-9055-06469C50AFBC,AmiPciAccessCspBaseLibOverride +6E5950E5-8610-4AC9-9153-A3D352124A7A,AmdCcxVhRnSmm +6E59DF06-62D3-40B0-82B5-175CF84A94E4,OEMPEI +6E5ED30F-EC52-4136-8A41-3F4324218E41,DeviceIoOnPciRootBridgeIoThunk +6E605536-A30A-4D56-939E-1C373F798D7B,TcgLockDownVar +6E66DAE5-4108-40B5-89A9-C6103F0639EC,GlobeBorder +6E67A6B5-84EF-4F26-902F-E508D8F3F1AF,AmdMemCzPei +6E6E4A75-EF14-47FB-B43A-67EC43B87D22,SpiFlashProSmm +6E6EBC2D-77AB-46CF-B2A7-CC968B0E8AF3,mAmiTcgInterfaceVarGuid +6E6F05AC-234B-465B-9450-C36E6D7566C5,LenovoSystemIsaKbcDxe +6E6F55F6-8F74-4F71-8264-F11BA0581441,DashPldmBcc +6E7139CA-2B21-4168-9804-867FAF71F95D,BoardInitPei +6E7181AA-A835-47BE-9C49-0743354D2F5D,RecoveryPcdDataBase +6E72A82C-14A5-4F02-A377-4A423BB1817F,WindowsNameLabel +6E7CDEE1-414B-44C2-9D0C-BD2698F45982,WakeOnLanPortingDxe +6E7D90A7-9336-461C-8AE9-859C51A9A716,ReadyToBootNotifyDxe +6E851687-A7A9-4AA2-8DD0-673E03E51433,SetSockOpt +6E881000-5749-11E8-9BF0-8CDCD426C973,RedfishConfigHandlerDriver +6E8CD2B7-B636-4859-85ED-C637BDCA5919,DellDaServiceTag +6E900CF0-D596-43E1-B9F9-D9E0584CB207,DellFnUsbEmulationSmmProtocol +6E97D4F4-1898-4408-A62D-99CADED32FD8,DellDxeSbAcpi +6E987F90-95A5-411B-BED3-A5277F17B132,UdiDxeDriver +6E98C278-4B75-4E0F-81A8-F3E1459F0524,FjCmosAccessSmm +6E9A4C69-57C6-4FCD-B083-4F2C3BDB6051,FdtPlatformDxe +6EA0F71C-614A-437E-8F49-243AD4E83268,Emul6064TrapProtocolGuid +6EB44D26-1D39-4FEB-A993-4DAAFB5F8D85,HybridDriver +6EC99217-69BB-4AD6-9B4E-8F4AB9AF72B9,ResetTesting +6ECBD5A1-C0F8-4702-8301-4FC2C5470A51,EfiArmTfCpuDriverEpDescriptor +6ECD1463-4A4A-461B-AF5F-5A33E3B2162B,EfiPeiGraphicsPpiGuid +6ECEFFFD-614D-452E-A81D-25E56B0DEF98,BatteryState0 +6ECF9B39-9DD7-4175-B657-CAB9437598DE,AlwaysPublishInt13ForCdrom +6ECFCE51-5724-450C-A38A-58553E954422,SmmAccessPei +6EDC0599-3935-4F3D-A1AF-3CCC1FBC8655,FastbootWmi +6EE1B483-A9B8-4EAF-9AE1-3B28C5CFF36B,SkipTpmStartupGuid +6EEDE20E-8F32-4FE2-BEB7-7A00F3CCDBC3,OpromUpdateDxeLightningRidgeEXRP +6EFAC84F-0AB0-4747-81BE-855562590449,XenIoProtocolGuid +6EFF177D-E4EF-4E1D-8419-DB717231EB7D,OemThermalDptfSettings +6F0198AA-1F1D-426D-AE3E-39AB633FCC28,Cf9ResetDxe +6F052B94-59F5-4606-A017-06CBDC5C20BA,MctpSmbusSmm +6F0CF054-AE6A-418C-A7CE-3C7A7CD74EC0,LogoPcx +6F0E5C58-E5C2-42A9-925C-A0CF93A86291,NvmeShutdownNotificationSmm +6F17DD8C-770A-427C-B291-C8EB644F979A,DellHwManagerSmm +6F19BE81-7381-4AF3-BB26-553311726E34,AsusAmlBuffSmi +6F19CF0F-7280-44C2-B7A5-0A575C47E16E,EcLabProductionModeDxe +6F1B1FA2-561D-47C3-A22D-DBDC21246D8F,TrustedChannelSmm +6F1E6343-DCB6-4109-A5B6-20F533806229,RtkUefiLan +6F20F7C8-E5EF-4F21-8D19-EDC5F0C496AE,MemInfoProtocolGuid +6F2AD552-F066-4ED6-ADA3-D92A3D8EA16E,CcgOnlySmm +6F2C06A8-D4B4-4A93-9F78-2B480BE80E0F,EfiSmiFlashProtocolGuid +6F4FA299-8F46-4BB2-8039-9B0A82289D07,DellSimulationDetection +6F625A69-7DB1-4F7B-94C2-056A785252CE,RsaInit +6F64916E-9F7A-4C35-B952-CD041EFB05A3,DefaultKEKFile +6F69F994-7E17-45FB-B62A-D7823195BEAB,AtaFreezeLockDxe +6F6F82F2-0D31-4319-8E31-CC722538E894,SystemVariableStoreManagerSmmRuntimeDxe +6F6FED5B-3741-4D4B-8AC7-C74914874A77,SbCrisis +6F71926E-60CE-428D-AA58-A3D9FB879429,IfConfig6 +6F7E5A78-6F5E-42F4-9C30-8E144182C5D6,ProjectHookPei +6F7E5A78-6F5E-42F4-9C30-8E144182D5F9,CompalCommonHookPei +6F7E88AD-C634-498A-84AF-CAEC526A3A51,AaeonModuleDxe +6F86764B-BBE4-49A1-A5D2-32E6A6861834,FchSmmDiagDispatcher +6F871ADD-9D86-4676-8BAD-68E2E451FC5B,MicrocodeFlashAccessLibNull +6F8AC3D2-ED4C-4386-8FDB-2EE920AB50B3,FchHuashanMultiFchDxe +6F8C2B35-FEF4-448D-8256-E11B19D61077,EfiSecPlatformInformationPpiGuid +6F902A6D-97F1-42DD-A717-8ADD6170C365,AcpiUpdate +6F9233D3-7B4E-4C7D-B41C-265412D4B7C3,ShmAcpi +6F92E393-03C0-427B-BBEB-4EF807B55BD8,IconNetworkRecovery +6F960C35-FFED-4778-99A1-4D998CE519B9,AmdNbioSmuV10Dxe +6F9ADAED-DBB6-4B6D-A3C5-A69BFC7D4578,FjTpmLicense +6F9B3CFA-1AF2-4174-A1C7-8F6310D68BE4,SwSmi534D0140 +6FA2994E-144F-404A-ADC9-31C3BC7196C9,DellGraphics3Drv +6FAFC957-08E9-4252-9C7F-E8108576AA11,SmartCoverSmm +6FBA9427-B3F4-4AAE-BAF3-C97288512994,LegacyUsbIrqSolutionWASmm +6FC01D84-46C5-4E83-91B7-FD8FBABD7B12,BiosInfo +6FC53026-4ADC-41ED-80A6-B8923471DE34,FjSystemConfigurationSmm +6FCC781C-27A7-4A8E-B4D1-E70F235F4FCF,PlatformPciDxe +6FCCBB10-6D6E-6A6E-9C2B-2B625FFF8566,RtErrorLogging +6FCE3BB9-9742-4CFD-8E9E-39F98DCA3271,AmiPciSmmHandoffProtocolGuid +6FD18837-36E6-46EC-8F61-6730E3E23D50,JhiDxe +6FD1DCC5-B5B9-4A82-8728-8D854428A4A3,DxeFfsGfxDriver +6FD5B00C-D426-4283-9887-6CF5CF1CB1FE,EfiUserManagerProtocolGuid +6FDE3AF8-37AD-43FC-B728-F4D341F39240,PhoenixSmmWatchdogTimerProtocolGuid +6FDF2BA1-F952-4748-BB6D-31A76D377A82,OdmDebugSmm +6FE38843-6500-42C2-A535-7769DEA56AA4,FpgaLoaderPeim +6FEE88FF-49ED-48F1-B77B-EAD15771ABE7,FmpDxe +6FF23F1D-877C-4B1B-93FC-F142B2EEA6A7,EfiGopDisplayBrightnessProtocolGuid +6FF479F5-6120-4A41-A8C9-D9500F7DF594,Mdot2Driver +6FFEC78D-7DBF-4F8B-968D-2F43A080C13F,PhoenixDesktopWindowProtocolGuid +700A8874-D215-4ABB-9EF2-7A80128560E0,EmmcSoftwareTuningStorage +700A8874-D215-4ACC-9EF2-7A80128560E0,UfsPlatform +70101EAF-0085-440C-B356-8EE36FEF24F0,EfiLegacyRegion2ProtocolGuid +70107F3E-AD8F-442C-A311-7495097F35F8,CountrySupport +7013D46A-D631-4DCE-ABB7-41760E02C7C7,DellTpmBusConfigDxe +70162AA9-875E-4FC9-8608-27CE6FA4F33C,FjSecureUpdateDxe +701E020C-E977-4B7E-89FB-5C3A503C4C5D,ThinkCenterHWDiag +702100AD-3964-49CB-8511-E8627B384AD0,RASMiscDriver +70232FB4-81F4-49F6-AA05-51D99EBDC352,PciPlatform +7030AB02-B04D-4ABE-8801-20201D0C566A,ASUSFancyStart +70456853-D70E-496C-B6B1-CF88A30BE1A9,AmdVersionPei +704EA695-F373-42D4-BF1B-44BB7F60C295,menu_bottom_left +704EBEA2-5EE6-4898-9659-018B74B44789,EfiSeCOperationProtocolGuid +7050210F-D434-4D76-B118-71DDFC6F4E43,OpalPasswordSmm +705D9A12-6281-4B05-BB64-C9FE38649CDF,SetupMenuDxe +7064F130-846E-4CE2-83C1-4BBCBCBF1AE5,AppleBootPolicy +706B0EFA-8768-44B6-8CB2-469B47A80C47,LenovoFidoCp +706C1E0C-44FC-4012-9B71-3DBFEC762F35,PlatformFlashSmm +70718A53-E05E-41A4-8420-378BEA75951F,ClickBiosUiSimple +7074566A-2F33-43D9-9C32-2DA17AE27BAD,BootDeviceInfoDxe +7076876E-80C2-4EE6-AAD2-28B349A6865B,EfiCertX509Sha384Guid +707B3C6E-99A6-4E17-84A0-40284C1B3F38,LenovoPiSaveStateAccess +707BE83E-0BF6-40A5-BE64-34C03AA0B8E2,EfiSmbusArpMapGuid +7081E22F-CAC6-4053-9468-675782CF88E5,EfiEventDxeDispatchGuid +70858A67-D4D5-4632-BF0E-D18E2C29C550,DTBTPEI +70943B04-3B8A-4F08-A412-F97C5B02F6BE,IntelPcieLanDxe +70995504-D7AA-4BBA-803A-A3A9C729A37E,DellSmmDpstProtocol +709E6472-1BCD-43BD-8B6B-CD2D6D08B967,AcpiAtd +70A4D159-1F01-4203-A598-7C2794151CE6,EfiOsBootOptionNames +70ADF2BD-D392-44FA-92E7-3884783343AF,SDPlatformInitSmm +70AEBF01-9EA0-48D8-AE17-3A184B12DBFE,TseDefaultBootOrder +70B0AF26-F847-4BB6-AAB9-CDE84FC61431,EdkiiIoMmuPpi +70B221AF-FDFF-4FDE-9968-1AF623A956D9,EfiI2cHostProtocolGuid +70B312BF-974B-4C6A-A70A-EE231B22958A,FjPowerButton_jp +70B4DE8C-3B01-4F0A-A2F3-93CEE977313E,EfiJedecNvDimm +70B8BACB-0B26-4048-A6F8-03A6AF2C5029,BootScriptHideSmm +70D57D67-7F05-494D-A014-B75D7345B700,StorageSecurityCommandDxe +70E1A818-0BE1-4449-BFD4-9EF68C7F02A8,ReFlash +70E56C5E-280C-44B0-A497-09681ABC375E,DmiDataGuid +70E65212-F3AD-495F-B3A1-7A63542ED7D5,DellTcgPei2 +70EEECBE-727A-4244-904C-DB6BF0055392,EfiEcAccessProtocolGuid +70F582F8-1D71-4480-A64E-9755F5A9E225,AmdMemSspSp3Pei +70F64793-C323-4261-AC2C-D876F27C5345,EfiKmsFormatGeneric256Guid +70FB9CE0-2CB1-4FD7-80EE-AB4B6CF4B43F,GetHostByName +70FFF0FF-A543-45B9-8BE3-1BDB90412080,TcgInternalflagGuid +7101700F-A1C9-44E7-B68D-01FCEBC9C04A,FchBixbyEarlyLink +71032D4B-4B91-4EC1-AD53-81827FB43108,AmdCpmGpioInitDxe +710E415A-6A5B-4AEA-973F-6DD3F9CB0056,PLEDPEI +71100A17-76EA-48BD-8263-1A31B2952438,DellSystemPolicy3 +7112633D-590A-434E-8F99-80EBAEE13170,LenovoVariableChkDxe +71148D38-5925-4021-91AB-CB252AF74531,AcerPDDockPXE +71148D39-5926-4022-91AC-CB252AF74530,AsusEzFlash +71148D39-5926-4022-91AC-CB252AF74532,AcerDockIIPXE +71198574-FE9A-45B5-A2F8-4D2987066D20,AsusWMIMethod +711C703F-C285-4B10-A3B0-36ECBD3C8BE2,EfiCapsuleVendorGuid +711CFE45-DEEF-4CF5-A094-E8522761CED6,PdHostInterfaceTiSmm +711E7D64-1131-494B-A2D1-84806CD72D53,EfiTcgTreeLogHobGuid +71202EEE-5F53-40D9-AB3D-9E0C26D96657,AmiTseSetupEnterGuid +71224824-6C22-45D7-9C1A-9E7CBFF18924,NCT6106DSECPeiInit +7122810D-CCD3-4B09-A0AB-8D107645C978,DellMonotonicCounterSmm +71287108-BF58-41EA-B71C-B3622DEBCA9D,DellSmmSbGeneric +71298B1B-26AA-44D8-87CD-91A087C3481A,SmbiosDataUpdateDxeLightningRidgeEXECB3 +712B5720-7D64-4F52-FFFF-FFFF9946CF56,PxeOnDemandDxe +71332179-AE93-469A-89C5-9EFF7A780D51,AsusWifiPublish +714845FE-F8B8-4B45-9AAE-708ECDDFCB77,ExFatDxe +7148E18C-703E-4F59-AC3D-3A923A0DAA50,OemDxeEcVer +7149FE42-011E-4E93-98D8-D24869B7031F,I2cMasterPeim +715783DE-BC09-46BC-AE7D-E39879591197,AmdCcxXvPei +7166543F-3E35-41A2-9118-577BBA62C693,AmdAgesaParameterGroupPei +716EF0D9-FF83-4F69-81E9-518BD39A8E70,EfiSdMmcPassThruProtocolGuid +716FB533-26BD-4BAC-9820-229BD5A7D300,FprGoodixMocPrometheusDriver +7171F76B-EDCD-4F00-A7E5-559F71B8A00D,AmdMemSh5Dxe +7172526E-F691-4B01-AE22-A19FCC35F651,FchTacomaDsdt +71761D37-32B2-45CD-A7D0-B0FEDD93E8CF,EfiDirectedIoDMArErrorSectionGuid +717886AB-C40A-44CF-9114-4119E84B0DC7,PciCfgOnPciCfg2Thunk +717A0EAA-9B18-461A-B6EC-AC09794CA631,LenovoSystemAcpiSupportDxe +717FC150-ABD9-4614-8015-0B3323EAB95C,AmiNvramSpdMap +7197C8A7-6559-4C93-93D5-8A84F988798B,PlatformBootManagerProtocol +71A19494-2AB6-4E96-8581-CF34254273FE,MeBiosPayloadDataProtocol +71A37E51-F3C8-4B99-B335-A661CA8AD13A,AmdCpmOemInitDxe +71A37E51-F3C8-4B99-B335-A661CA8AD33A,AmdIncompatiblePci +71A62895-1CD4-4B9A-A77B-571FD71BEFC9,OemAcpiDriver +71A8917B-0891-4E27-8A73-A9B334840393,AmiPeiBeforeMrcGuid +71A9EA61-5A35-4A5D-ACEF-9CF86D6D67E0,EdkiiPeiCapsuleOnDiskPpi +71AC8619-B70C-4974-9307-F646E73CCCFA,PlainPasswordTransfer +71B22C89-B849-4D83-8115-4563A626AC8D,KEMhGpioAccPei +71B8D01E-D764-4BC6-9D02-0007F8382F54,FjCmosAccessRt +71B8D0AC-ABA1-46B4-8D28-09C9FCA0158D,IwlMei +71C4C155-D54B-4D59-A2C1-F9A5723C65A8,EfiIsPlatformSupportWheaProtocolGuid +71C914AC-EC48-43D5-A9BA-64BFC69C73DA,BiosConnectLoader +71DB7B7E-4165-48FA-AC9D-F9AF4CEFC534,DellPropertyDxeProtocol +71E218BA-0F3F-46B6-A42E-93A2C1195A31,AmdRadeonDriver +71E6D4BC-4837-45F1-A2D7-3F9308B17ED7,PlatformVariableHob +71ED12D1-250B-42FB-8C17-10DCFA771701,AmiLegacyInterrupt +71EE5E94-65B9-45D5-821A-3A4D86CFE6BE,EfiUserCredentialProtocolGuid +71F3B066-936A-4C84-9228-23230FD47C79,ImagePasswordFill +71F7CA83-96C5-4742-BAA2-76B807A06B95,SctGopVbeBltBin +71F7D079-099F-4C15-8A84-C44A3629D181,SbSocBrhPei +71FAE25E-4427-4C48-B707-FC5BF2F6742E,RTKUndiDxe +71FD84CD-353B-464D-B7A4-6EA7B96995CB,NonDiscoverablePciDeviceDxe +71FE861A-5450-48B6-BFB0-B93522616F99,TPS65950 +72002D05-2C57-48B4-B9DD-D2F19035A44B,HpDtSmm +720E6687-43C4-84EA-E1B5-23AAED359840,IntelGbeUndi +72120D23-40FF-4AB5-855C-C8C6DE9AAE54,FchSmmDiagDispatcher +72133706-A922-43F1-9C75-581D9AE8F666,AmdNbioSmuV9Pei +721ACF02-4D77-4C2A-B3DC-270B7BA9E4B0,FspNonVolatileStorageHobGuid +721C8B66-426C-4E86-8E99-3457C46AB0B9,SystemBiosSetupDxe +7223263E-035D-4495-81AE-7DDEBCD8616F,SystemAudioDeviceSmm +72234213-0FD7-48A1-A59F-B41BC107FBCD,ACPIOSFRVariableGuid +72234E22-8A17-4E30-AEC5-F3B3397E6691,SxCallback +722A7C2F-81B3-407A-98C7-CF9158CF904B,SiInitPreMemFsp +722E4818-344E-4421-88CD-491CB908C142,DellSetupCfgPolicies +7235C51C-0C80-4CAB-87AC-3B084A6304B1,OvmfPlatformConfigGuid +7238A672-755C-45E2-84C1-4C720CB2A8D1,EcCloseShmApi +72405B40-38DA-4ABA-9283-CA8321C23E63,FvReportPei +725FC6B0-984D-11E3-AD96-047D7B99E097,SetupMenuInterfaceCoreDxe +726205B4-2E4D-4606-998B-6B2A3E8858E4,DellWBootCapsuleProtocol +726A9E51-7B0E-4F77-9159-9239EB5DEA34,SioIt8659eDxe +72725F0E-5CD9-4997-8530-08D464C1FC46,XnoteCapsulePolicyDxe +72727297-BC14-4886-A642-617BC50A5265,IccInitDxe +7273772B-6DAA-4E2F-9063-6C95FDA931BF,AdlSemaPei +72748AA2-B149-4D14-8FF1-10F5836C8933,AmdSmmDriver +7279D04D-AAAE-994A-8A5C-5AEA41D1FE3A,AppleArpDxe +727F171D-99C0-42F7-8D1A-A61390AF5BB1,AbsoluteDxe +72896A9A-4A1A-46C3-A2EC-012DF5A89565,ClientronSmbiosDxe +728CAE6C-1FFC-449B-8681-BB2A621E0022,ContinueButtonSmall +72938FE7-5DC9-49B4-AAF0-2D23828A3190,DimmTypeDialogDxe +729B3079-8913-4E12-AFEF-2CA264799469,AmdAcpiDxe +72A71390-9AD6-4C1C-AE00-E050AF18A708,OemImageLanguage +72B11962-5759-4975-AE95-F8C3FE55EF1D,PchSmbusSmm +72B4CDB4-B297-4747-B1BA-5A4839D332AE,AmdFabricRnSmm +72BEE9DC-F9C8-4ACD-8D69-49C4E5BE6297,KEMhSDIO +72BF10F7-DF2F-413C-A27C-C41FD9710722,PdHostInterfaceCypressPei +72CAB13A-8E3D-4C49-967E-487A1C291E51,DellTagsSmm +72D78EA6-4DEE-11E3-8100-F3842A48D0A0,Isp1761PeriphDxe +72DA3348-8D1E-4655-AF88-84ED025FB268,FjGabiMiscellaneousSmm +72E07DA8-63A9-42D4-83D5-0BB518384475,EfiLegacyBootMarker +72E40094-2EE1-497A-8F33-4C934A9E9C0C,EfiSmmSmbusProtocolGuid +72EAA79D-D346-43C1-B6A2-B85EEE729133,NoBootDeviceOptionSmm +72F9BDAC-8ECC-4DEA-8AB1-5B593333148F,LenovoSecureSuiteApp +72FE44FF-44FC-4653-918A-0D5E76C416D2,SetupConfigUpdateDxeLightningRidgeEXECB3 +7300C4A1-43F2-4017-A51B-C81A7F40585B,EfiSmmStandbyButtonDispatch2ProtocolGuid +7305D9B2-95AE-4250-BD78-396C3B6AC2EE,RecoveryImageReadWriteV2 +7307BD0F-8B7A-4BA5-9AF6-3997D1E32786,AmdNbioSmuV10Pei +7310E28E-96EA-4360-946E-5ADC6BE8F531,DellSmmEcIoProtocol +7317BA01-C34C-4DE2-BB19-1AD8A612A1A4,FjVariableAccessServicesSmm +732B020D-DFDA-425D-9470-4BBF2F1B007C,DellQueryStdPcdValues +73303035-D6D0-46B5-8ECA-139EE287C000,RaidDriver +7338B21C-B7FF-4B81-9B50-0F2A71626C83,TouchPadDriver +733CBAC2-B23F-4B92-BC8E-FB01CE5907B7,FvbServicesRuntimeDxe +73400E57-A467-45AB-9F8C-D2519F76ABA4,DeviceFwServiceDxe +7348AD47-2E40-4846-B658-B9213469C130,DellEcPolicy2 +734AA01D-95EC-45B7-A23A-2D86D8FDEBB6,AmiTcgStorageSecurityInitProtocol +734E8BE9-4801-4A31-A3FA-D61CCB601CA9,OptionRomPolicy +734F8167-996B-4C5D-BBA3-815A72167FF8,BFGDxe +735CE436-D125-41D2-A524-F6699B9709A0,AcpiDynamicPci +735F8C64-D696-44D0-BDF2-447FD05A5406,EmbeddedExternalDeviceProtocolGuid +73656701-D13A-47AB-B0EE-4849537CDFAC,SgxEarlyInitPeimSPR +736AC82E-4216-42F1-8EDE-91EC63D0EC43,FjSysmanSetupHooks +736BF370-E38F-4AF1-850F-97360ED229A8,PlatformResetNotifySmm +736D8886-6D2B-4684-ADDE-84BFAB0F2737,SmiFlashLibs +737FE1C2-15E7-45D6-B37B-319FE880F733,SmmBase +73852F31-9834-4EC7-97EE-41E584DC3C49,LEMComputraceApiSmm +7385DBBE-8050-4FAF-8B64-4C386E1FAA88,CodeAccessCheckS3Pei +738A9314-82C1-4592-8FF7-C1BDF1B20ED4,ShellTftpHiiGuid +738B84B5-1E84-4EB9-8EF8-95A167EA4AEE,NvidiaGraphicsDxe +738C6917-71F0-4D45-AB68-91744136AEEA,AppleIpAgent +738ECAE2-DBF9-4C00-A0F6-586F3A506139,FchMultiFchPei +73905351-EB4D-4637-A83B-D1BF6C1C48EB,TSEInvalidateBgrtStatusProtocolGuid +7391A960-CCD1-11DD-AD8B-0800200C9A66,LenovoSystemIdeAtaAtapiPassThruSmm +7394F350-394D-488C-BB75-0CAB7B120AC5,EdkiiDeviceIdentifierTypeUsb +73995A5C-C2AB-48CC-A404-E39B38505C56,PlatformRecoveryOrderGuid +739C2226-3264-4454-991C-8DC44A73D6AF,ProjectPeiDriver +739D1A2B-FBA1-404A-8784-25CFA57BEACD,HddAcousticDynamicSetup +73A54106-8C88-4BA9-B08E-FD879A1682CA,NvdimmCommon +73ADAAC0-9857-4D74-B0D7-EC6094882D99,BaseTraceHubDebugLibNull +73C7B7DE-F679-4724-ABAD-79F256B64320,WakeOnLanPortingSmm +73CB6D5E-2BE4-434E-AD6B-4D7FB8700C16,FjUsbCdcDxe +73CD248F-420B-4618-8F74-E15FF48258B5,AmdCpmAdaptiveS4Dxe +73D1D476-A7C9-4EFD-8F8B-D532EF381708,EfiPlatformTxtDeviceMemory +73DAB30F-3F9C-4160-B064-439CE16C3EDE,SystemBootManagerDxe +73DC6B53-A5CB-4605-97B9-0E83FDE59194,HQUcsiDriver +73DDB5E1-5FB4-4751-AF1E-83CF75BECBB6,EfiPeiConsplitAmiKeycodePpi +73E6F6B4-D029-4E87-8405-6067C8BD02A6,UsbPei +73E79970-4936-443B-B9A5-E0B61BC1288E,PlatformVTdSampleDxe +73E8D659-D2A2-4720-8316-B9BAD21E5A29,CbsBaseDxeRN +73E9457A-CEA1-4917-9A9C-9F1F0F0FD322,DebugPortDxe +73F19D89-1EA3-45B8-86A2-9E153947A034,SBURetimerFMP +73F3E50E-23C5-4586-BC6C-7E5223FA3C43,OemPortMappingPolicy +73F53712-2A64-4B86-961D-C25B63DF198C,AmdNbioIOMMURVDxe +73F70B77-943B-4090-99E8-4F8E4D824A43,wifi_none +73FA8DD2-589A-424C-82EB-2D360F09D900,HwmFanSmm +73FF4F56-AA8E-4451-B316-36353667AD44,FspBootLoaderTolumHobGuid +7408D748-FC8C-4EE6-9288-C4BEC092A410,EfiPeiMasterBootModePpiGuid +740A6C4B-3813-4A05-84B5-9AEE2BBE9F5E,FjFvFlashSmm +740BBF85-47EB-45D7-905B-244451A0FD77,FirebirdCheckDxe +742F95A8-714A-5C43-88BA-B3361F12EEE6,BootRomFlash +74346897-9E0C-4B41-BF1F-BAA1ECB85DA6,IioCfgUpdateDxeLightningRidgeEXRP +74375386-DA3C-4FA2-BBA2-F53E37353422,AmdAcpConfigurationDxe +7449D85D-C41F-474D-A34B-DF839241ED4E,DellAnimationDxe +744C9DBD-74DE-424D-AB59-AA398305871F,EDIDParserDriver +744D080F-EDF3-4FF4-9870-A2DA5BA5F0E6,PlatformDefaultSettings +744EBDEA-F30A-4F13-A0B8-F7D7982A57DB,BiosPasswordDxe +7459A7D4-6533-4480-BBA7-79E25A4443C9,AmiTseDriverHealth +745D377A-B988-47B2-B18F-BBC80DC56698,EfiVirtualMemoryAccessProtocol +7462660F-1CBD-48DA-AD11-91717913831C,EfiPciOptionRomTableGuid +74627A28-DB74-4102-B2B2-F8D788AFFFEF,HpIcicleDefaultAndWmi +7465BA75-88A7-4B61-9A7E-6D4EDF6804DC,AmiUdfMediaGuid +7474A4C6-7F30-4DE1-BC68-DA5EFE615B52,SmbiosDataUpdateDxeNeonCityEPRP +748221BC-2BA9-1545-8AA9-A03A8591999E,AppleNetVolume +748C36F5-6DCC-4857-8AF6-64E66EFFBA00,KeyboardLayoutSetup +748EA80F-96B4-4315-A277-28ACED336830,RklComp +7497B957-20C3-4E47-A2C0-594966FD28FD,UefiDriverPolicyDXE +74A016D4-4E4B-45B5-AE97-4E6E33D65125,LenovoBlockPowerButtonDxe +74A9FE73-8E72-4FAD-8043-ED4AF82C08AE,SwSmi534D0B40 +74AB5A17-82D7-472B-B2CC-22CB825844C4,FjDeviceInfoBaseDriver +74B3E9BF-A025-4D4E-B5B6-508F8B67085E,GetMemoryValue +74BD9FE0-8902-11E3-B9D3-F72238FC9A31,AndroidFastbootTransportProtocolGuid +74C4F1BE-FE72-4268-A685-C4CE71070401,AsusTestVersionHeader +74C83F3A-5EE3-4EB7-B945-702B839FB1A6,DxePlatform +74C85C25-09DD-497D-9F71-91C172283ED4,SioFanMapDxe +74CBEC3C-8190-42A0-9C02-D1C5ADC706D7,AppleAirport +74CDC9BE-9FEF-444F-FFFF-FFFF14E55121,XnotePlatformManagerDxe +74D3B506-EE9C-47ED-B749-41261401DA78,QNCInitDxe +74D782CD-F238-42F7-91E3-977D5B4BBBD6,OemACRecoveryDxe +74D936FA-D8BD-4633-B64D-6424BDD23D24,FwBlockServiceSmm +74DB4ECD-3429-46D6-9BD3-88B50A8190A7,EcKeySmm +74DBE0FE-5621-4616-A978-8C1E239F191E,SmmMemoryManager +74DDF801-A7DC-4410-9DF8-C08E6D9FD6BB,FpgaCapsule +74E1B217-7CE5-432D-8C1B-0C216FADA7DF,ApobStxKrkPei +7502B5FB-33FC-42F0-A90C-A45E5B63449B,FjGpioCometLakePei +75032015-D156-423E-BFA3-7A65ABA47105,EfiI2cBusConfigurationManagementProtocolGuid +750890A6-7ACF-4F4F-81BD-B400C2BEA95A,AcpiModeEnable +750D5755-A0C9-42D3-A326-B5D465413523,AppleSEPDxe +750F8E5A-59BE-485B-A717-FD850FC8772B,FchKunlunMultiFchDxe +75153C93-7AD2-4452-8036-644AD4AAFF25,AsusPcieSsdUpdate +75189FA6-7BCF-4F4F-81BD-A4F1C3BEA95A,CptSwSmi +752F3136-4E16-4FDC-A22A-E5F46812F4CA,EfiShellParametersProtocolGuid +753630C9-FAE5-47A9-BBBF-88D621CD7282,SmmChildDispatcher +7537E889-FC63-42D2-B400-F7646C45CEE3,CastroCovePmicNvm +75472C94-6221-4CF2-9EC7-1462CB726B1B,AmdSocAm5PhxDxe +754AAF56-099B-440D-8DCD-626F4E2C52F4,RsaIScsiSupport +754BFF96-1234-4B41-B437-EF1B0C8CA155,KEMrPegConfigPei +755877A6-4F10-4A5C-9B2E-852123B9682C,FlashSmiDxe +755B6596-6896-4BA3-B3DD-1C629FD1EA88,AmiFlashProtocolGuid +755DFF82-93BE-4E9F-891F-955909D1EA19,RtkUndiDxeDriver +7565FA5B-101B-4493-9F27-1ECBD4BECC6C,AsusSetArmouryCrateField +7576CC89-8FA3-4CAD-BA02-6119B46ED44A,AmiSioSmmHandoffProtocolGuid +7578B307-B25B-44F9-892E-209B0E3993C6,Emul6064MsInputProtocolGuid +757DC0D7-EFFE-4C12-BC6F-D7E833EB9015,FjOA30Support +75816CA2-8FBD-439B-A120-C47FF86F0E29,BHInitDxe +7581D88A-F866-42C1-8683-26281938E5BF,RtkWifiSupDriver +75839B0B-0A99-4233-8AA4-3866F6CEF4B3,FpgaSocketVariable +7583C1FA-0BD6-447C-9E4E-397E1AE338B2,SystemSureBootPei +75844C24-A8FE-4331-8D0B-554C4606009B,RTKUSB +7585C771-3CE4-41FE-B780-845CD85BA444,FirmwarePassword +75862FE4-4FC6-4188-804B-29DC7733178B,StallServicePei +75866B1C-3F5F-4C01-929D-CEA40F1F6710,FjIbvSfuPolicyAbstractionSmmProtocol +758880AB-4CA2-4DAA-A83E-D1F9ADF2C2F1,DellSmmSioEmi +758AF8A7-2A04-4937-99E0-837D1F97C76F,LenovoSystemAcpiNumaDxe +75B0755B-B0D9-4205-BBF7-63289FFB8045,ProjectSmm +75B0886E-CD6A-469F-AE0B-8CED9033D199,EfiBpdtLibBp2DataGuid +75BA309D-5DFD-49BF-ACE8-28B39B52BDF7,CbsBasePeiRPL +75BE667C-48E1-452D-B0FC-363138ED87FF,PStateControl +75BFCE76-56F4-4FE1-B257-8B075E8F98A8,OemIp3SMI +75C024B9-C20C-4506-B85C-7C7356F0239B,AddonNetworkControlSmm +75C640C2-030E-4C57-81E2-532B1DD7339F,MemoryStorageKernelDxe +75C8F622-8090-4017-850C-3FA40B027984,SmcMemMapOut +75CA7C9D-502E-468A-9AAF-7F2A29E6DBCF,AmiSbHddPolicyProtocolGuid +75CE4288-DE5D-4E24-90B5-F75BD78E6BA1,SecureFirmwareVolumeDxe +75CF14AE-3441-49DC-AA10-BB35A7BA8BAB,EdkiiPlatformSpecificResetHandlerPpi +75D02D7A-5A2D-497A-9A4F-D7CE38EA1389,SDPreOSVariable +75E78806-C68F-4839-8A68-B29084820659,ExStatusCodeHandlerPei +75FBCDBA-28C4-455A-A71D-536C9AB65093,SmcSetupModify +75FC3BBA-72A4-61DA-4171-074C824223C1,DigistorWorkAround +76016A54-9959-495D-BB3E-BA35E25A51CB,SystemSetupMainDxe +7604B120-A55C-4A36-A9F6-420E5ADA995C,MpmAsfPei +760640DA-ECAC-4229-A591-7D3066EB242D,PldmImportBin +760A41FF-3619-4F01-B95F-A2E0E699D487,ServiceBodySmm +760E5D5F-9AD3-4055-B4C9-2F9F6E29CC2F,BiosLockDxe +760F874E-B8CB-405E-AA32-A46AE2F3D680,VariableDefaultUpdate +7612F7CE-C685-465A-91D4-D12F9E933383,SpiHcOperation +7627B2DE-4342-4DDA-A339-A96DAA057DDF,AsusMbSwWmiSmm +763EEAEB-FE2A-4778-BE0A-3842EF8610A8,BIOSLOCK +763F61A7-BCFD-4657-87B2-8DBCAD6425F9,DellOpalHddSecurityDxe +763FEE95-85A1-412E-9276-01BE8FAE6CE1,DellSetupASPMDxe +7644C181-FA6E-46DA-80CB-04B9904062E8,EfiPathFileName +76504DF8-9D28-4099-8EC8-5A67CBE886B0,EsataBootControlDxe +7652F853-6243-4358-2BBD-6F235DCA34AB,DellSmmHwAccessInfo +765317F6-F080-4261-8926-3F47D182BF64,FjTpmLicenseDxe +765F7890-5755-406D-9B02-C44E7182680C,LEMBoardId +76624D51-E916-46A0-824C-AB27E0AF3E77,SioSwSmi +7668AF85-DFEF-4C57-BCC4-8807FAFE7BE9,TouchPadDriver +76700A4A-25C7-4B2F-B190-8DABB2EF2129,FchSmbusDxe +7671D9D0-53DB-4173-AA69-2327F21F0BC7,EfiAuthenticationInfoProtocolGuid +767965D6-F35A-41A9-8BE4-695E92C32B47,CapsuleIFWUSmm +768007EF-E607-4417-8F5D-BCFE16DAE336,SmbusConfigGuid +76864548-0261-410E-A8B4-01615BFA3E0A,FwKeyHobPei +7687A497-FF4E-48FF-BCAA-67DBF65C42D1,AsrockBfgdxe +768BEDFD-7B4B-4C9F-B2FF-6377E3387243,NTFS +768BEDFD-7B4B-4C9F-B2FF-6377E3387651,OemGNVSDxe +768BEDFD-7B4B-4C9F-B2FF-6377E3387671,SmbusDxe +768BEDFD-7B4B-4C9F-B2FF-6377E3387691,SmbusSmm +768BEDFD-7B4B-4C9F-B2FF-6377E3387692,OemSmi +7692B160-3591-47AA-BDEE-655297662E76,UefiDMBMHooKInt13Protocol +769B1A29-C083-450A-8C96-D750FAF4530E,LenovoCertAuthDxe +76A1DF7D-754C-40E1-BC72-3FCAD842DEF6,DellDaEppid +76A7B4FC-C8D5-462D-A4D2-6E88338A772A,PlatformCpuPolicy +76B6BDFA-2ACD-4462-9E3F-CB58C969D937,PerformanceProtocolGuid +76B75C23-FE4F-4E17-A2AD-1A653DBB494A,EfiExtendedSalLockServicesProtocol +76BE1ABF-1E1E-321D-B7F0-9E0984FDDABC,ProgressBar +76BE7979-4701-48EF-9E6C-44B9EF030923,GpioV2ControllerPei +76CA0AD8-4A14-4389-B7E5-FD88791762AD,FmpDxe +76CBE15D-3C00-4597-8F13-621D77E879E1,AmtSaveMebxConfig +76D1059D-2E22-40EF-A31F-C49DBBC0DBCE,SetupCheckSumPei +76D5CF91-0C55-434E-97C2-D2825C82E610,OemActivation3 +76E1E9EE-5FC7-4613-B96F-FA797796573A,DellPbaMgrSmm +76EB2674-B3F2-4489-BB6D-E2448F7EF614,BiosSelfHealingPei +76ED6631-44FE-4ED2-8B5D-1B5355BB25E8,LogoDxe +76ED893A-B2F9-4C7D-A05F-1EA170ECF6CD,IntelGraphicsPeim +76F3992D-529E-4EFE-8BBE-8E1ED432C223,AmiMeasurePciopromGuid +76FA2425-086F-4E33-8DFF-4E7D961A67DC,FjSiidRt +76FDC1AE-A42A-416A-98E3-A2F29146DAC3,AppleDhcpProtocolDxe +7701AA8F-27EB-4562-8C59-4731CAA24E7C,ScPmcFunctionDisableResetHobGuid +7701D7E5-7D1D-4432-A468-673DAB8ADE60,LdrMemoryDescriptorGuid +7702A696-6521-4FE8-A786-528B4D86F5F1,DfciDevSettingsMgr +77085416-E137-44A0-89F3-0C7DA7F2F52A,OemNecTseEsaSwitch +77148690-7E43-4673-AFAE-34532CDD4248,SmmControlDxe +77165917-C00B-434B-BADC-A8FBFF437E7D,BeepExampleDxe +77197B37-A0FB-487C-9CDF-FC36179B73DE,DellStatusCodeHandlerDxe +7721929A-D56A-450D-2501-8EA51FA61974,SbCmos +772484B2-7482-4B91-9F9A-AD43F81C5881,EfiMiscSubClassGuid +77265330-9FB0-4AA5-8E37-35064728F5C3,IioCfgUpdateDxeSierra +773779CA-2AE8-4073-8BC5-43376A61BFD5,DellEcPolicy +7739F24C-93D7-11D4-9A3A-0090273FC14D,EfiHobListGuid +773CB08B-511A-4BD5-85AD-41D4F4B64A52,AmtSetupDxe +77447790-51B4-4A81-A8D2-7EF78E9F35C9,I2CSpeedDXE +77475D4F-7965-4038-B970-863FC73E0761,BSDP +7750576E-EBB3-454B-887C-6521B3CD34A5,AmdMemoryHobInfoPeim +77509744-7507-4B5C-BF6C-3BAB83652F4D,BctBaseSmmRV +7755CA7B-CA8F-43C5-889B-E1F59A93D575,IntelGopDriver +7758FA0F-2CAB-4684-949F-C20506339539,DellProfileManager +77617ECB-E229-4E20-B8F9-DF8245624D7A,SystemAcpiTableLoaderDxe +77651BCC-7262-484F-A74F-650821285D9D,BiosSelfHealingDxe +77786445-99AC-4C2E-9FF1-990965770530,NCT3933Smm +777BAA93-9260-421B-9173-FA62611B6188,HciPei +77892615-7C7A-4AEF-A320-2A0C15C44B95,BiosRegionLock +778E8993-0C45-41F7-976A-4C088855E6B6,AmdIspCamera +77A6009E-116E-464D-8EF8-B35201A022DD,DigitalThermalSensorSmm +77AB535A-45FC-624B-5560-F7B281D1F96E,EfiVirtualDiskGuid +77AED9BC-0938-4026-9D10-F6846027F366,ApobMdnDxe +77B35E10-AC21-4DFB-B094-DDA8878A6521,ASM1061Pei +77BC641D-582D-4B1C-BB79-594EDF3630EF,VTPCR7EventLog +77C0B0CB-0406-4868-AEB5-C36B01D42FF6,MemoryInitWrapper +77C2687E-975A-679C-BE44-2EF67868CEAC,IhisiRegister +77CB5A2E-59C8-490E-B69D-A3862BE5B3A0,EobonPriorityMap +77CC5D6F-E1A8-4ABA-8AE8-1D92DE3B50F1,OemNVME +77CF025D-D743-4DE5-AC39-AE4A591064B0,RestoreVariablesDxe +77D71582-4274-0EC5-36CD-65A2CC4FD663,DellWsmtEnforceSmm +77DE2CD5-67B8-4749-A8EF-7E26EFFC07AF,CbsSetupDxeBRH +77E5B618-2612-4C28-BCDF-A2B14D8A3EFE,IFlashDxe +77EB6C06-FD48-488B-A1B3-AE0A70801369,CryptoDXE +77EC5618-2101-4112-86B1-2F752AE10F1A,EcSecureFlashDxe +77ECCE3A-7398-4C04-981D-D778E793E0F9,TransferNvramPasswordToSmram +77F04055-3E04-4821-BEB0-B2AEE4983198,FchSongshanI3cPei +77FA9ABD-0359-4D32-BD60-28F4E78F784B,MicrosoftVendor +7807E404-8281-4FF1-8457-0B54BABE263F,HitachiH8s2113Dxe +7808F5C2-9CB0-4609-907F-B18453C363B4,DellStorageAgentsDxe +78092548-48CF-449B-9BDB-F63849856460,AmiProtocolInternalHlxeGuid +78097BB6-48CF-449B-9BDB-F63849856460,mAmiPpiInternalVarGuid +780A399B-CADF-402B-85C7-F734D70AFE81,SmartCoverPortingSmm +78247C57-63DB-4708-99C2-A8B4A9A61F6B,EfiMtftp4ProtocolGuid +78259433-7B6D-4DB3-9AE8-36C4C2C3A17D,MeInfoSetup +78270D5E-9450-4FAE-8818-B91EA39864CD,ChipsetLibServicesSmm +7827D4B0-926E-48F9-8ABD-69816EF86D16,AppleDmgBootDxe +782C4946-0167-4C2B-949D-8DC4E53D25A7,FjUartModeSelection +782FD612-46F3-47A2-83D9-8FDB86E6FED1,FjGabiMiscAbstractionSmm +7833616E-AE0D-594F-870C-80E68682D587,ThunkProtocolList +783658A3-4172-4421-A299-E009079C0CB4,EfiLegacyBiosPlatformProtocolGuid +783AA974-DFB0-487B-906F-120FB9486E88,SetupConfigUpdateDxeLightningRidgeEXECB4 +783D7527-85EE-4A95-A909-03F745E4E91D,TimerSmiDxe +7862806A-7171-47A0-98A2-12F3505A1EF2,AtapiCommandSmm +786DA51A-86A5-47C5-BF8D-04877BE47260,AmiPciExpressGen3LibNull +786EC0AC-65AE-4D1B-B137-0D110A483797,IScsiCHAPAuthInfoGuid +786FE7F0-88B0-4FF0-822D-559D04D89156,PcieResizingDxe +7872D787-4DAD-4496-BE61-EDB5B5F012E7,SpdDataReadPei +787D4843-68AC-4C28-BE53-BAC272BAECF9,DellVariable2RuntimeDxe +787E0C4A-4A27-4891-9489-AF5074C36E89,EfiTraceHubStatusCodeHandleHeaderPpi +78871234-8787-7878-A19B-0BE61B233187,DeviceWa +788B4AB1-294F-4FD4-BEB7-4F5E0709E9AC,DnAPartitionDxe +788DD6A1-F1EE-4BBA-A925-C0E7D66271BD,SystemBoardDxe +788E1D9F-1EAB-47D2-A2F3-78CAE87D6012,IdccDataHubGuid +78941450-90AB-4FB1-B75F-589214E24A0C,FontPackageGuid +78965B98-B0BF-449E-8B22-D2914E498A98,EfiSmmStandbyButtonDispatchProtocolGuid +78A6FB37-8F27-40A4-9C4E-9FC9E438D5E2,AmiTseOemPortingVar8 +78AE4297-C10F-4D77-B6EC-521F34BF06F8,SmbiosDataUpdateDxeEldorado +78AF76C7-8A5C-420F-8DE6-12678D101590,TrackPointElan +78B55289-5393-4A3A-834A-111AD7726970,DellIoExpanderPca9555Smm +78B9EC8B-C000-46C5-AC93-24A0C1BB00CE,PwdCredentialProviderGuid +78BE11C4-EE44-4A22-9F05-03852EC5C978,EfiKmsFormatMd2128Guid +78BEE926-692F-48FD-9EDB-01422EF0D7AB,EfiEventMemoryMapChangeGuid +78BF418F-559B-43D5-940A-EFFA174217F7,DrySMI +78CE2354-CFBC-4643-AEBA-07A27FA892BF,WdtPersistentData +78D19E50-2B62-407F-9F49-C652A4124002,VariableRegionInfoDxe +78D87F9A-321E-4A07-875F-8D83A3D06E59,FpgaSocketN4Pe +78DE67FC-7CFB-423E-AE1C-253F9B645E25,EarlyDxe +78E1AF79-A9C1-44F6-AD49-8622C1776FAE,OemDxeDetectBlueTooth +78E4D245-CD4D-4A05-A2BA-4743E86CFCAB,EfiSecurityPolicyProtocolGuid +78E977ED-6E0F-4774-B5D1-9DC7F75F339F,FchPromontoryUsb +78EB25EE-F78B-419D-B0DD-12C38FFFBF1D,DeepPei +78EF0A56-1CF0-4535-B5DA-F6FD2F405A11,FmpDxe +78FFCA55-4869-4393-BEE9-72E58BD3BE38,SystemFixedBusNumbersDxe +7901F717-FE24-4C8B-87AD-C05F35660747,OemIp3Smi +790217BD-BECF-485B-9170-5FF711318B27,EfiHiiRestStyleFormset +7907C558-4C57-480E-9439-7F6684852920,DellMeLocalFwUpdateDxe_ME130 +7914C493-F439-4C6C-AB23-7F72150E72D4,ImageAppleLogo +79263F9A-1701-4382-98C2-573F3558E6C8,PlatformFvbLibNull +792930B0-7B29-4ECD-8B0C-65D62644C343,CbsSetupSmmSTX +7929D36E-968A-4A4B-87CE-2375B1C7311D,DxePortingSample +792F0DE4-ECB7-4EA9-B25E-A531FBA36809,H19AesEncryptPswd +7934156D-CFCE-460E-92F5-A07909A59ECA,BiosGuardModule +79395A8A-53BB-41BE-A6E6-F65E9AE4E0EA,KEMhAcpi +793CBEA0-DA56-47F2-8264-24310CB75196,LenovoSystemVariableDxe +7942EDD0-C023-4357-93ED-F6626D711E9E,PeiIpmiBmcInitialize +794610DA-D0EE-466B-81B3-8197213A6978,SystemSwSmiAllocatorSmm +794B23CB-ECCE-497F-A14D-96E1AFCB00E3,NPKReserveMemGuid +795231E2-A205-4B8D-8C8D-7353B713DF7D,efi_pop_mid_pressed +795477D9-1786-4D8A-8B89-3FA7623F7EF8,DellSbPowerOffPei +7958EB26-C098-46EC-B5B7-BE9FF13F8E32,DellBoardPolicyPei +7979919A-3D8D-4BB5-B832-45CC4FC7DE57,DellDptfPolicyProtocol +797A72A9-EAE3-495E-995D-A20D85F509AB,PreserveHobVariablesToNvram +7982477A-B285-42E8-B22D-A30E7E3CFE26,Dispatcher +79839D38-DD05-489C-B3EF-F27BDA08E572,AmiAgesaSxSmi +798B3F5F-F5FE-4AE7-9E85-D71613D8CFFC,KEMaEAPI +798E722E-15B2-4E13-8AE9-6BA30FF7F167,IntelSmbiosDataHobGuid +79971BCB-D5C6-4D5A-9C24-BCA46C2ADBBE,BdsDriverProxy +799B0CB3-F2FD-4571-8522-29536EFE30BF,SystemEventLogSmm +79AA6086-035A-4AD9-A89A-A6D5AA27F0E2,NbPei +79AB769C-E959-4B09-9718-80A896012C28,DellNetworkTransferDriver +79AC2D9C-9216-43C5-A074-0B45C76422C1,SmmRedirElogProtocol +79B26A82-5C07-4AAA-A8F3-8AD195D271A2,SetupConfigUpdateDxeFischerLakeRP +79BA7128-D5EF-4B41-912C-5F80DC9E1B24,AmdMemoryHobInfoPeimRs +79C3AC4A-DEC6-48F1-AFFE-E7B95A1CCB32,PoofAnimationState2 +79C5C7B7-1083-42A6-AD15-2A4E7C4274D7,DxeSmmDriverEntryPoint +79CA4208-BBA1-4A9A-8456-E1E66A81484E,Legacy8259 +79CB58C4-AC51-442F-AFD7-98E47D2E9908,EfiBootScriptExecutorContextGuid +79CD78D8-6EDC-4978-BD02-3299C387AB17,StatusCodeHandlerSmm +79CE097A-91AA-41FF-B3A8-534559B30DB1,PasswordHob +79DE6AEF-BE2D-4BB2-ACBF-0A67E289DBAF,AmdCcxVhSmm +79DED328-7FCE-4909-9AFD-D66176AF97A6,OobRx +79E0EDD7-9D1D-4F41-AE1A-F896169E5216,LenovoWmaPolicyDxe +79E17317-1CBB-4A25-9884-91E041C05C2E,DellSmmMfgBootListPolicyProtocol +79E39A83-D013-4B2E-836A-A99A7147351C,DellPbaScardDxe +79E4A61C-ED73-4312-94FE-E3E7563362A9,PrintDxe +79E5CA15-7A2D-4F37-A63B-D1C7BBCA47AD,AhciPei +79E5F681-59F4-4415-8E46-8C223CF517E6,EfiBootMediaHobGuid +79E8C9C7-1152-4F00-B831-14F1C4041AE0,EfiIntelMfgFormatFru +79EACCCC-AD8F-4448-BBBC-9DB8C922AC62,AbtUnlock +79F90154-83F4-478C-80BF-878AC32E0A2C,RTL8111EPV +79FBAD19-F9E1-4D08-B7BC-358453195E41,AmiTpmRollbackSmmProtocolGuid +79FD86B3-D74F-4D6F-9577-FBE062977086,SerialDebugInitDxe +7A073909-6D74-4C73-9F05-3E0B055CA623,PlatformSioInitDxe +7A08CB98-E9BC-41C3-BE19-B302F3F1F523,DellSolPostMessage +7A08CB98-E9BC-41C3-BE19-B302F3F1F595,Terminal +7A1CC2C0-7AF6-4F68-A564-CC03558FC3C5,SuperMDxe +7A2099C9-9AF8-4FE5-9812-BBC352762EF5,HpSioComPortWAPei +7A2634E5-4DB0-4E01-AB8B-B833E5F25AF1,FlashControllerNvsDxe +7A28436A-E113-406A-AFF9-0DBF7F643E02,EfiTcgPrivateInterfaceGuid +7A2A4270-38BA-45C6-B53C-C83B342D5B15,TisPei +7A345DCA-0C26-4F2A-A89A-57C08DDD22EE,NvVariableInfo +7A379D61-0784-40DC-B28E-E96007CF30F1,LegacyUsbSmm +7A3FA48C-12F2-4B0E-9E74-2977711F598B,AmdCcxZen3RmbPei +7A422A24-0CF1-407D-AAF1-6A74C0103B98,SystemUsbHidPointerDxe +7A4D1E44-4531-41B0-A0C5-B19ED7A1B097,SureStartPoliciesDxe +7A4DCEF3-788E-4595-9F0B-4B97803BC97A,SaveRestoreGPT +7A54B36F-F745-462C-B11F-16E03E52B617,AsusSpdTransfer +7A564231-240D-4BDB-8B87-8F589A988E13,SystemVspBcpRuntimeDxe +7A59B29B-910B-4171-8242-A85A0DF25B5B,EfiHttpProtocolGuid +7A5DBC75-5B2B-4E67-BDE1-D48EEE761562,EfiSmmSpiReadyProtocolGuid +7A627E16-679D-4814-8F82-EEAF3881F098,BatteryState6 +7A699129-DAA0-4224-8629-7338DE5D45ED,TpmDriver +7A6CA3B8-EE1B-489C-B300-24544A7BD418,ShellCTestApp +7A6DF3DB-1C0A-45C2-8251-AFE794D7D6B3,PciExpressPciCfg2 +7A7F24EB-426C-476F-AE54-09A23A9E04C1,FjIbvAbstractionSmm +7A8406BD-E03C-4DAD-B532-E3CCED635CC5,AmdI2cTouchPanelDxe +7A9354D9-0468-444A-81CE-0BF617D890DF,EfiFirmwareFileSystemGuid +7A97840A-F3F6-49EC-928A-36D90A76D6A5,RecoveryFchInitPei +7A9A372D-3487-402E-B489-5FC551A43BD1,X11DPHDxeDriver +7AA35A69-506C-444F-A7AF-694BF56F71C8,EfiFirmwareVolumeDispatchProtocol +7AA553A5-FE0A-4453-870D-42A6555DC26C,PchInitDxeEbg +7AA7B16D-0E14-4951-8B85-3F6572FCE258,SystemErrorLogPei +7AADBC0B-45B8-4694-BB98-A991961799D8,FlashInterfacePei +7AB0F90A-BDF8-4010-A434-4329FB61330D,SmBusPei +7AB22C56-2510-4FD2-AC18-57394419FBAB,UsbOcUpdateDxeNeonCityFPGA +7AB33A91-ACE5-4326-B572-E7EE33D39F16,EfiManagedNetworkProtocolGuid +7AB80BCC-9BD4-4FD2-811C-60634073AC9C,PdHostInterfaceCypressSmm +7ABBC454-F737-4322-931C-B1BB62A01D6F,BootMonFs +7ABCFE4A-F5D2-413A-9828-259E6B128DC9,LcfcWorkaroundMfgDoneDxe +7ABEC993-53D6-464F-8371-FFAFD97F3928,AmiCryptoPkgTokenSpace +7AC954F0-4FBB-4D9C-A2BF-E8A5922E6F30,AmdNbioPei +7AD33249-4BC9-4D31-9855-06D3A8C052A0,WlanControllerSmm +7AD9BAE7-864D-4F7E-9D11-1CAD8018FE7A,LenovoTpmFwUpdateSmm +7ADA185E-7E10-4F7C-B2DA-26E99102C88D,AmdCpmDiscreteUSB4Dxe +7ADAF482-ECE1-42C1-8FB0-BF8955340696,AmdMemSmbiosV2BrhPei +7ADBAD98-7FE1-4774-9260-747327435E6D,SpsAcpiHooks +7AE1026D-C7FA-4867-9C14-A00534A6C547,DMIRecovery +7AE3CEB7-2EE2-48FA-AA49-3510BC83CABF,PeiSeCPlatformPolicyPpiGuid +7AF77F94-4C38-4FF1-8CCD-3E084F2FFEC0,SkylakeGraphics +7AFFD257-51D0-439A-A89A-85A3419308E4,DellJSONParserDriver +7B04A674-8EF3-443E-999D-D62508BD3A3E,PldmImportBinShp +7B05F6C6-B8E3-4007-9F81-68E3773D6E20,LEMPasswordStoreProtocol +7B07D184-02D0-4BFD-AD6E-554C39353A13,LenovoSysConfigReqDxe +7B0E51C3-46FF-4D6C-AA5D-61DB3F44F50E,EcMemMappingPei +7B0F6DDD-8600-4F54-AF52-0D4738C2D308,DellUefiClass3ConfigSmm +7B123212-02AE-4C43-820E-90C07E085242,FjGpioGeminilakePei +7B17ED3D-3892-43B4-B5E5-DF802B4F4855,SureStartPoliciesSmm +7B2349E0-522D-4F8E-B927-69D97C9E795F,EfiPaddingRsassaPssGuid +7B3EC697-49AC-4966-958D-9703F7F836B2,PlatformHardwareHarden +7B3F16BE-79CD-4A78-A27E-B329B1DF500D,H2ODisplayEngineLocalMetroDxe +7B44CE84-91F2-4C19-A1D3-33185A658DAF,FjS5WakeDxe +7B59316E-E9DF-435F-98CD-5726645BE863,EfiHfiPcieGen3Protocol +7B60EE35-C708-4C2B-9094-478DC163358F,FjSysmanYggdrasilPei +7B668A4F-45E1-4A26-8DEC-81A4A1E58888,PspDxe +7B69DCB6-424C-4844-A53D-087056382870,S3NotifyDispatchPei +7B6F1DA6-EA4F-4938-A79F-0C58E1442AA1,LenovoPopManagerDxe +7B77FB8B-1E0D-4D7E-953F-3980A261E076,TdtVolatileSetupData +7B77FB8B-1E0D-4D7E-953F-3980A261E077,IccVolatileSetupData +7B7B65B6-E350-4139-8FE4-665772D32A45,IhisiSmm +7B7B65B6-E350-4139-8FE4-665772D32A47,IhisiSmm +7B8837AE-081E-4D3F-8AAD-87BB93952F38,WlanControllerDxe +7B8DAD98-4B25-438A-BC31-F6CC931D5BB4,PlatformInitRecoveryPei +7B8DB049-C7C7-4D3B-809F-926DEE47CCA2,SBSMI +7B8EE7A1-4E35-4556-BB56-6797E24445C2,PeiCpuPlatformPolicyPpi +7B8F8199-42C7-DB87-307E-2892F3849538,AmdCpmOemInitPeim +7B9937AE-092E-4D5F-8BBD-87BB14162F38,SerialPortSettingDxe +7B9A0A12-42F8-4D4C-82B6-32F0CA1953F4,AmiBoardInfoFileGuid +7B9BE2E0-E28A-4197-AD3E-32F062F9462C,AddressBasedMirror +7BAC95D3-0DDF-42F3-9E24-7C644940379A,BdsStringPackGuid +7BAEC70B-57E0-4C76-8E87-2F9E28088343,EfiVT100PlusGuid +7BB28B99-61BB-11D5-9A5D-0090273FC14D,Logo +7BB61314-11B5-4833-BCAD-B1601CA088C9,SmbiosType0 +7BB880C9-82C8-40C4-95FE-3330B984844C,DashIoCfgSmm +7BBB9525-97BA-4516-B660-1B0EB78744A5,DellSmBiosStrucD0 +7BBC4123-5D5E-4C1C-95D1-30EBA48701CA,S4SlpDelaySmm +7BC065CF-AFE8-4396-AE9F-BA27DFBECF3D,PlatformKtiEparamUpdateData +7BC2ABF4-DDC6-4E04-BFB0-D9BDB6888915,DxeFvMain2Test +7BCB37D2-D280-453D-BC91-E1E4E6208A70,KEMhSmbEfi +7BD19958-CF71-48DD-953C-640505C52D4A,DellMultiFuncDevDxe +7BD7AB9F-DB9F-455D-8566-387B2F13D404,UsbPwrCtrlPei +7BD9DDF7-8B83-488E-AEC9-24C78610289C,VirtioFsDxe +7BE725B2-F56C-41C7-9F03-1E7B56B65971,SystemUsbMemoryManagerDxe +7BEEEF98-3028-4260-96F1-BEEBA31A787C,OemSioResChangePei +7BF3F3C8-4FCA-49A7-804F-9033D2E47841,AmdNbioBaseZPPei +7BF444F5-CB15-4DEF-99DF-E725D9A8E380,RamDisk +7BF5FECC-C5B5-4B25-811B-B4B50B2879F7,PeiIpmiTransportPpi +7BF9BE38-9B8D-4D62-AD06-6805BEED9852,FjFlexIoDetectionViaI2C +7C03567F-C840-4E9C-BFCC-652793C2FBFB,DpfServicesDxe +7C04A583-9E3E-4F1C-AD65-E05268D0B4D1,FullShell +7C05C4AC-68F5-4526-BD10-7FABAF822369,semaInit +7C069ADA-DE4E-488C-B0FC-4F2E057D96D8,DUFontDriver +7C095EED-C8DE-49BD-90D4-6C9A3A3BE9C3,DellRmtPlatSiSmm +7C0C91D4-63DF-4AB4-AD2E-B01C6DF3E07B,OemStandaloneDxe +7C0D8842-B2D7-4E06-863D-F84218013BC7,LenovoPttPolicyDxe +7C245213-345E-44EF-9FD3-7B6DA92AA499,UsbPortDisableOverrideDxe +7C257A30-F8BA-404A-8476-666F9E19BC56,GabiSettingItemCallbackDxe +7C29785C-66B9-49FC-B797-1CA5550EF283,PeiUsbIoPpiGuid +7C2D1E53-E565-47EA-8A1E-DC97459926B0,OemServiceSmm +7C2E0E5E-7C35-4611-BC93-036013EDBE3D,AsusWmiAtkDxeSmmCoreBin +7C2E2D27-E8BD-4F5C-A569-AF65B77AA55D,DellPttSetupDxe +7C2E3F7B-A17A-4070-AE83-13FF416F62B2,MsiBoardNvs +7C347F9B-6FAE-45A5-906E-F8DFEBEE64FF,DellWmiSecurityMgr +7C365CF5-19B7-48F2-80F5-0A3267F69FEA,SmiSecurityVerify +7C380900-1B96-4615-978E-89E02E2C89D0,DebugDriverDxe +7C46C6A4-362F-4964-AF20-9333E552DCC3,PciHotPlug +7C4BC2E3-7C7E-43D5-AEBF-FF57810AC2DA,AsusWmiAtkDxeCore +7C5A8EE9-7EC5-443C-A867-3549B667EEA6,WakeOnLanPortingPei +7C604CBD-5440-46E1-97F7-A4DF8DD09C1C,AmdSmmControl +7C69E035-60D9-4782-AAAA-B05F2F8C1B09,PeiReportStatusConOut +7C79AC8C-5E6C-4E3D-BA6F-C260EE7C172E,SmmRuntime +7C81C66A-4F11-47AB-82D3-67C4D635AED1,LegacyMebxLaunch +7C820E3D-C3F7-42C1-A022-7FE434A87DFB,FvNetworkDxe +7C8507DD-DFCF-4BF7-9BB1-090D5C5944FB,BoardNvs +7C8BDE83-9E3E-4F1C-AD65-E05268D0B4D1,RealtekUndi +7C96D656-6B21-45A7-84D8-5068EEE1D415,MAPS_SmartFanDxe +7C9A98F8-2B2B-4027-8F16-F7D277D58025,IntelBootGuardKeyManifest +7C9AAA66-0D1A-4A23-BEA3-25195F6BC22C,FchKunlunMultiFchPei +7C9E5A63-B987-435E-B17F-9E9CFA53F880,SmmPlatform +7C9FE380-CFD2-4BF0-9B96-E5DF40635ECB,RealtekGopDriver +7CA1024F-EB17-11E5-9DBA-28D2447C4829,TlsAuthConfigDxe +7CAB2E8A-B799-4540-8517-58644D03CC9F,LenovoAtpSmiServices +7CB40E99-3186-4A5D-829D-802C5793F132,DellAcpiSharedMemSmm +7CB919C8-D499-4629-ACB3-22769E343DDB,DellFlashIoSmm +7CBB4CF0-21FE-4C99-848D-77E93167128A,DellSfpSmm +7CBD5702-C8E3-4F7E-BA08-EC7EF1BB2D67,IrqTableInfo +7CBDCA19-4776-A997-7CA7-56D5343F2904,EarlyOneTimeFlags +7CC1567C-CCB8-4C50-80BA-D44A3B667415,AmdSb800_PeiInterfacePei +7CC1667C-CCB8-4C50-80BA-D44A3B667415,SbInterfacePei +7CC6C4D7-A271-4FDD-B29C-AD561CB3FF4C,WtCardReaderDxe +7CC7ED80-9A68-4781-80E4-DA1699105AFE,EfiLightIsaIoProtocol +7CCA3104-2A1D-4E84-9C7C-44B97A234012,HpSioSecurityPei +7CCAD11A-EFA4-4F82-BDE7-7D07FF90B280,BootOrderWmi +7CCB2D7E-CD15-417E-A5C8-003DA6325B9F,PowerStateManager +7CD73063-546E-4C09-ABD2-11C6B04ACC4E,SataPowerManagementSmm +7CE247D8-A588-40EC-B311-F820800EFA02,H19FingerprintVendorDriver +7CE501E6-4BBB-478B-9B41-5FA66A36042A,AmdRasBrhServiceDxe +7CE700F9-BB44-4157-9655-DCCC39432C1C,FjKbcDxe +7CE75114-8272-45AF-B536-761BD38852CE,Slp21PubKey +7CE88FB3-4BD7-4679-87A8-A8D8DEE50D2B,EfiEventReadyToBootGuid +7CEA4F7E-2052-46ED-BEFD-E22A44DC65E7,Tpm20HobGuid +7CFACBB0-B515-4970-AE98-38F540E73482,H2OVerifyRegionDxe +7D019990-8CE1-46F5-A776-3C5198676AA0,EfiExtendedSalResetServicesProtocolGuid +7D06E47C-B32C-496F-940E-F30CDE0B7CE5,SystemFirmwareDeviceBlockSmm +7D08D718-48EC-4C52-919D-407E5B1A94E4,IntelGigabitLan +7D0EEA4D-74CA-4118-898E-964181DC5D1B,SmmIpl +7D113AA9-6280-48C6-BACE-DFE7668E8307,AmiMpTpmBin +7D15608C-EE1A-43CC-A27A-BE9D8BA0F5F8,DellTcgServicesPei +7D17EF81-57C8-4210-957C-6FDAA8EA1DD6,PciHotPlugDxe +7D19E8AD-1089-42B7-A440-D8318A44E89F,SioIt8659ePei +7D24A234-A8C2-4718-BF60-A2EF070F414E,OpalPasswordSmm +7D24A567-A8C2-4718-DC60-A2EF070F414E,SmmCrcInit +7D277BE3-8778-4139-A33C-738065720098,FjIbvSfuSecFlashAbstractionDxeProtocol +7D279373-EECC-4D4F-AE2F-CEC4B706B06A,Tpm2AcpiTableStorage +7D29BF67-6131-4CCC-91DE-BB8291565701,CbsBaseDxeSTXH +7D2BD134-500D-4F42-AEE2-26ACCFB6CB1D,LibStdio +7D3DCEEE-CBCE-4EA7-8709-6E552F1EDBDE,FlaSStatusguid +7D47DC17-F443-42A1-BCC3-54FD06A95821,SDPngDecoder +7D4E94A9-269A-47A1-80F0-2B0EB42F7B4B,Int15ServiceSmm +7D51F6CC-9272-6541-A74F-6B784082D285,AcAdapterWarnDxe +7D574D54-D364-4D4A-95E3-4945DB7AD3EE,ShellInstall1HiiGuid +7D5FF0E3-2FB7-4E19-8419-44266CB60000,DP +7D655829-26DD-4342-96AD-04899477C3FA,SpiSmmStub +7D6A1A2A-6B25-48DA-BE80-B8C88EF9AD56,DymanicUpdateBiosSizeInfo +7D6B8734-B754-443F-B588-7743843AD3F1,AmiSmbiosMemoryInfoHob +7D6B8869-8317-43D1-9E4E-ADB0B0F58407,FjMfgPostSatControlDxe +7D6DF4FD-3650-4E77-BF3A-84DC988A025C,TcgStorageSecurity +7D7789CD-FD20-4C05-A579-91253D5E3D9E,DellCmosManagerPeiSrc +7D77B32E-BAB2-4CC7-8378-7550513F3FCA,UsbOcUpdateDxeLightningRidgeEXECB4 +7D84B2C2-22A1-4372-B12C-EBB232D3A6A3,VlvPolicyPpiGuid +7D86C03A-B1F6-4F0F-AB43-81D925F19481,WarmResetFlagDxe +7D916D80-5BB1-458C-A48F-E25FDD51EF94,EfiTtyTermGuid +7D9BE232-0D3D-47C1-B45C-344C5B5152AD,FjClearsureSmm +7D9DDBFB-FB67-4303-90B0-9A7A7FF29B57,OpromUpdateDxeLightningRidgeEXECB1 +7DA45AA9-6DBF-4F1B-A43E-3287CBE51351,TpmPkgList +7DA53855-F630-4A30-9D85-0E99DFD92A06,EfiPlatformTypeLightningRidgeExecB4Protocol +7DA68578-C0E9-4742-8DE5-C91ACA88D5A7,DellBoardPolicySmm +7DA6F287-4BE3-45CC-8515-E27486936C0E,BoardSyncPspFwAToPspFwBDxe +7DADBC98-6489-4D1C-907A-8EE243AF805B,AsusEupPei +7DB8BFAE-B3BC-483A-8252-E0F213151AA7,ODMWlanTpowerOnOverride +7DC20199-DE28-4A91-A89C-FF06F237352C,PrePostHotkey +7DCAF14D-1499-4149-8364-1673CD1CE75C,PecNbDxe +7DCE671B-C223-446A-A705-ED637AAF6771,EdkiiCryptoPpi +7DD26A06-9942-41A8-B9CF-09DE46D5D219,BBSManagerDxe +7DE2F2F8-B627-441C-B352-5B02EE035C47,LenovoAIOFmpDxe +7DF0DD67-5B91-4D40-A835-58013457010A,SmbiosDataUpdateDxeHedtCRB +7DFA9220-5145-42CB-A815-0865C1B952F9,FidoUsbDxe +7E0C6E3E-C80F-47D1-8ADA-554926B2B6B3,GenericMemoryTestDxe +7E13637A-C3F8-43D1-B051-ED19D708EC7A,PeiIdeRecoveryNativeModePpi +7E1F0D85-04FF-4BB2-866A-31A2996A48A8,EfiPeiFvFileLoaderPpiGuid +7E24E860-A62C-4312-82F2-E7B58D0537C9,SceBootOrderSaveRestore +7E374E25-8E01-4FEE-87F2-390C23C606CD,PlatformAcpiTable +7E3D95E4-89F8-41B9-B788-5FB22D77F9A3,SmcNVDIMMDxeDriver +7E4B2ACB-7391-408F-B143-3A0B07C6E165,FdoModeEnabledHobGuid +7E4F3635-6E28-40C6-BCFB-2B1A46459946,BiosPasswordDxe +7E631AA5-AFCE-437B-81FA-FA34EA14B3C3,ExFatRecovery +7E66ABA5-5780-4ACB-A50F-8198989C69C3,FjGabiSettingsDxe +7E696C3E-5C5D-4A64-9650-E792FAD24128,AdlDriverSmm +7E6A6CF5-C89C-492F-AC37-2307849C3AD5,EfiCpuPpmProtocol +7E715650-10E6-4B7B-896A-4DC5FC742BC5,LenovoModulesSmmThunkSmm +7E7369CE-0188-4183-8C2D-DAF7B730E42B,AmiCmosBadHobGuid +7E7507B4-45E1-21D6-43E3-32B9F7F4720E,Ds125Br401aPei +7E7F16FA-B957-47AB-B58B-7AC40DA44A5E,SIIDDxe +7E8567C5-ADFE-44A6-A1FC-6514105C6B24,FjCameraCapsuleDxe +7E8ADB71-9A5B-4AC7-82BE-E8598285DC14,LANWakeupDxe +7E9099D2-F1EF-45F0-944A-7B7F241A0ABF,StaticSkuDataDxeGlacier +7E97A470-EFDB-4D02-8FCE-6190D27BA296,EfiExtendedSalRtcServicesProtocolGuid +7E983BCE-5C99-4BE0-B3D0-210E8FDDD3C0,VlanceDxe +7E99BC9E-EDE9-48C1-85B9-689432817F8F,SystemEsrtDxe +7EA76D38-C57A-412D-AF1D-D58BEE2B85B1,LenovoVproPetAlert +7EA7AACF-7ED3-4166-8271-B21156523620,SamplePlatformDevicePolicyDxe +7EAF93A7-7026-46FD-B359-6A98DEE70860,AsusCloudRecovery +7EB51510-729B-482E-AA28-C9EB6A7FB837,SioSxIntruderDxe +7EB7126D-C45E-4BD0-9357-7F507C5C9CF9,RomLayoutPei +7EB88C46-22FF-4CBD-8FE7-495383FAB1E4,PciBoardDxeInit +7EBB920D-1AAF-46D9-B2AF-541E1DCE148B,EdkiiPlatformHasDeviceTree +7EC6E119-1FD8-4C84-8E57-FF55D166C91E,PlutonSecurityProcessorV2 +7ECBEF8F-2C6E-4CC0-B8B8-BF536396CC9D,HpQX448Pei +7ECD9C20-68B9-4A6F-B515-D64FF500B109,FsRecovery +7ED59FC2-3395-5DD2-A31C-1EF2F098E166,GopConsole +7EDE6A1F-548E-453E-A95C-66939FE0295C,SwitchableGraphicsPei +7EDF76E9-3DCD-474F-A3BB-DE3B18A47D61,MEC1416PeiInit +7EE2BD44-3DA0-11D4-9A38-0090273FC14D,EfiIsaIoProtocolGuid +7EE44C61-ADDA-4D27-A4A3-A5615C16C644,MemoryInit +7EF09900-7397-45C0-9CA6-698324391870,DellAutoOsRecoveryDxe +7EF21E8C-2FC1-4BC3-A84A-73025EAAB896,ProgressBarFullMiddle +7F0013A7-DC79-4B22-8099-11F75FDC829D,EfiCacheSubClassGuid +7F009393-A908-4EEE-843B-0771FCED8F59,MpmOemFunction +7F0690AD-1725-4930-8137-94D0FCF5F63A,AmdXgbeAndDisplayConfigurePei +7F06A90F-AE0D-4887-82C0-FEC7F4F68B29,EmmcBlockIoPei +7F0FE834-0727-4640-95E9-9B1C056F87B8,CypressCCGx +7F133760-9CA0-4D4F-A201-038AB955B1B5,SetSystemState +7F1647C8-B76E-44B2-A565-F70FF19CD19E,EfiDns6ServiceBindingProtocolGuid +7F19E716-419C-4E79-8E37-C2BD84EB6528,PeiSpiSoftStrapsPpi +7F1D8127-EB69-44DD-A88A-ED37BDB97DB3,OemBadgingSmm +7F2BFC42-9BDE-4E9D-BE83-1BB752DF0C3A,SystemBiosSelfHealingPei +7F342334-54C3-40FB-A289-DA000A0637BD,BeepInterfaceCoreDxe +7F380019-B951-4BBD-BEDF-8DD7A621D773,OemNvDriverTypeDxe +7F3E00EE-B826-4358-8FFA-C30C3AF526F2,LenovoTpm2ConfigSmm +7F4158D3-074D-456D-8CB2-01F9C8F79DAA,EfiTpmDeviceSelectedGuid +7F480A20-7A19-4764-A5CA-4E9B8AECAF1E,PchPciBus +7F4A3A75-538C-4259-B420-C44818CBC553,ATIPwrXDXE +7F4F86F6-EBC9-4603-A4C2-C7CC8B4476DB,Heci2BarSaveRestoreGuid +7F51CB64-A6CF-4DA1-9E3D-E9F3976B3C92,FchSmmDispatcher +7F5E4E31-81B1-47E5-9E21-1E4B5BC2F61D,EdkiiPeiFirmwareVolumeInfoStoredHashFvPpi +7F630637-39BE-401D-AC06-57DC9117DF13,SDEVUpdate +7F6E0A24-DBFD-43DF-9755-0292D7D3DD48,IsaFloppyPei +7F786C3D-C586-48BE-BBBE-1D8273481C00,AsmUsb4InitPei +7F81D838-F91D-4C44-8552-8FB912122FDD,GopDxe +7F843E9E-BA26-4D3C-82F7-C703D87D334D,PhI2cPlatformSupport +7F865306-830D-4DC2-8E9A-B7856F925A0A,SupplicantDriver +7F8D35BD-0CE3-4654-B5D3-73FC4B38AABF,PlatformEarlyDxe +7F9263F2-0BC0-4AA0-8503-6D69513BCA15,AsusHddGptRecovery +7F955A3E-AFB5-4122-B925-4B1171F693F5,AmiBlockIoWriteProtectionProtocolGuid +7FA5F220-9F11-49B5-85A2-045AAC347D27,BackupService +7FA68D82-10A4-4E71-9524-D3D9500D3CDF,PlatformSecureLibNull +7FA9284E-40B3-417F-A2BB-58EAE1026314,FjSystemResetDxe +7FB30861-8941-4748-953A-2C59D93F9171,BiosConnectUiManager +7FB6E2BA-C550-4529-A85D-A8A9D13B851E,FjGrasscarryDxe +7FC90770-0E89-4A20-8152-6CB777B56F48,FlashInfoDxe +7FD082A9-3D6B-44E3-9C31-74D6B80F965C,SetupConfigUpdateDxeLightningRidgeEXECB1 +7FD24CF7-2BF6-4547-8441-845E793C619D,AmdSocSp5BrhDxe +7FE9EA1F-4224-4C7B-9F44-FEC1728E7DA1,FjDevInfo +7FEB1D5D-33F4-48D3-BD11-C4B36B6D0E57,FmpDxe +7FECA3CE-F18C-4DCE-9465-4DEB949298C9,E022X7 +7FECA3CE-F18C-4DCE-9465-58D6FB0692B8,0_X64 +7FECA3CE-F18C-4DCE-9465-80FF64F2AB7C,0_X64 +7FED72EE-0170-4814-9878-A8FB1864DFAF,SmmRelocateDxe +7FF2BC6B-FCB9-4381-A602-45CDF9BFFFB4,DelAmiCapsuleImageLoadedVar +7FF2FCB3-E868-492D-9063-6D22E6A2B14C,SDConfigureSSID +7FFC3700-7C5E-423F-A04B-32E9F16A6727,SuperMPeiPrococol +7FFF52C8-82DE-4820-8960-5093102E484D,IncompatiblePciDevice +80023209-6386-4C1D-909B-63506A2146FF,HWM_SetupDXE +80030344-4BA0-4F2C-A6AC-1E0E928F2470,AmiAgesaSbPei +800594D2-39E7-4088-9BDD-D979737DEEE1,SmbiosDataUpdateDxeCLX64L +80060E80-2C20-429E-946B-1C89097F0BED,VariableServiceDxe +80144152-6770-45D0-8463-E4B48EBE4B5B,HpAmdTbtPei +801ADCA0-815E-46A4-84F7-657F53621A57,SectionExtractionDxe +801B5C4B-6AE2-4065-9F72-82CA760C2ECA,EfiRsaTpmClearOwnership +801DE6B4-2036-46B7-B8F7-79205CBD1772,SmartCoverPortingPei +801E9DEF-DDBB-4CA3-9698-C9158EB86AEA,AmiPeriodicSmiControlProtocolGuid +8029A5B5-4088-48D2-96E0-F7052BC0A842,PttHciSmm +802C5E65-D47B-461B-A456-6C89C5CC3B30,SetVariableToWirelessDeviceDriver +802C5E65-D47B-461B-A9D9-6C89C5CC3A10,DxeRealtekMAC +8041F38B-0A34-49D7-A905-03AEEF4826F7,PlatformSsdtImageGuid +8045548F-FD94-458A-9BC8-BEADB5733D46,AbtDisk +80522809-D926-4D50-8E71-1E897AB29E1D,FjPowerDeliveryCapsuleDxe +805B032B-6A00-46F5-8501-CB88A21D5321,BcmDhd +805D1C5A-EF12-490A-9E7B-9F4AA2F97E73,AmiPspNvramSmm +806040CA-DAD9-4978-A3B4-2D2AB0C8A48F,QemuKernelLoaderFsDxe +80680ACD-2F8D-48B0-BFA9-3E3177AA9E27,OsVersionDxe +80752470-6EDE-485D-AC36-DC1BA66091EE,LenovoSpecialSwSmi +807E2D68-B13F-490A-A2FB-346A39459978,NCT6685DSmmDxe +807E2D68-B13F-490A-A2FB-346A39459D09,NCT6685DSmm +807E2D68-B13F-490A-A2FB-346A39459D0A,ECHeartbeatSmm +80897901-91F6-4EFE-9579-3353A0C02DAB,SDMediaDevice +809FBBFD-127A-4249-88BC-FD0E767F4FFD,IconInternalHD +80A1BB91-2036-46DD-9CC8-97A1F2F7E5BC,HpSmmCoreServices +80A1CF80-A85D-4C1A-9131-1FEFC5959618,AsusPcieCardReaderUpdate +80A29A57-BF37-4403-B7B0-D654E84F8A6D,PchInitDxeEhl +80AADD0D-8053-4BA7-941B-36F48BB23001,DellSystemPwSmm +80B08E6A-C6CE-430F-9C07-52A9526DB0F9,CompalWSMTDxe +80B33A95-B978-434A-9195-3C118E9F35CB,MsiBoardSmm +80BD20ED-46AC-4F66-ACBA-9A1658DB1830,AcerSystemStatusProtocol +80C905A4-1E0C-47F2-8417-977FB539C06F,PowerButton +80CF7257-87AB-47F9-A3FE-D50B76D89541,PcdDxe +80D7491A-F7D9-479D-A8F7-1B393B02ED66,FastBootRuntime +80DBD530-B74C-4F11-8C03-418665532831,EfiMemoryConfigDataGuid +80DED13D-B821-4824-A0DD-52CA968C3A04,AmdCpmOemGpioDxe +80E1202E-2697-4264-9CC9-80762C3E5863,RecoveryFormSet +80E66E0A-CCD1-43FA-A7B1-2D5EE0F13910,PciRootBridge +80EBBF8D-82DE-42C9-945A-E7AD7EB0C284,CaRemoval +80EC6BA2-C4B4-4ACC-B89C-F61D8BACD675,OCUR +80F03C1F-89BD-4240-93A8-AC99E9A929FC,DellPowerOffConfig +80F195B5-D7B6-4C64-84EC-1F3BE795751D,FjPasswordSkipPei +80FD2A83-B5AF-4A67-88BD-08388BDF1ADF,DellTcg2ServicesDxe +8101F7F3-07D2-4518-A987-EF51EA64AFAD,BatteryFwUpdateDxe +8108AC4E-9F11-4D59-850E-E21A522C59B2,BmAutoCreateBootOptionGuid +81212A96-09ED-4996-9471-8D729C8E69ED,EfiFirmwareErrorSectionGuid +812136D3-4D3A-433A-9418-29BB9BF78F6E,EdkiiSystemFmpCapsuleConfigFileGuid +8122CEBD-F4FD-4EA8-976C-F003ADDC4CB4,EfiPeiIpmiTransportPpi +812BA1E0-6A75-4AE5-AD37-63D030974501,VtioDxe +8133139A-2B04-4C37-ACF2-6956DED13A77,OemThermalPolicy +81334616-86CE-49C2-B6F9-1804E61C73F6,LenovoIgdCustomize +8149FBB8-A2CF-4234-B506-B76255F7A36D,EfiQpiRcParm +81510D98-2110-489F-8E26-7FE825CD837E,LenovoVariableCommandSmiDispatch +8151A914-2437-41D0-A410-14DF75F9BE70,SystemMassStorageEventDxe +816C3759-DFE4-4644-AA17-1F090E02A599,TiOnlyPei +81791CAF-44AD-441F-B0A2-322BA8FC95ED,FchImcControl +8180B47F-EBB0-4303-A389-74FD15356BA6,DebugLogDxe +81A4F912-E72F-44ED-8931-16A9FE9650E0,KbcEmulDxe +81AFA132-8D94-4101-A538-833C05D145D9,BoardSelectDxe +81BC1E82-D8B2-4444-A336-E83D80654A6C,DynamicPowerSwitch +81C0C020-E99E-4406-9656-5E686A0E0CC3,FjTpm +81C53D89-E238-4133-BBD2-5BDA8BEDEC85,StorageEraseDxe +81C9FDB4-4D6F-4D98-B7B8-6A9DAF677E73,D01HddPassword +81CD3462-6A1A-42F8-829B-8D77481DDB64,AmiPciExpressGen2LibNull +81D12896-975E-487F-AE40-1C37B4D7A820,DeviceWufuEsrtDxe +81D1675C-86F6-48DF-BD95-9A6E4F0925C3,EdkiiVariablePolicyProtocol +81E4B34A-268C-4FCC-8E39-1C1D3E6F6E69,HddReadyDXE +81E67795-D8A3-43B2-8B5F-E0326F76AB91,wifi_4bars +81E68098-6F95-4CE8-AA8F-A7FFC89E0B9D,AmdGopConfigDrvDxe +81EC4A75-A7AE-487E-993F-2190BD47423A,LEMEventLogProtocolDxe +81F0BCF2-F1AD-4DDE-9E5B-75EB3427ABC4,DellMfgModePeiDriver +81F81D8B-B746-4B24-B649-2654F7281E4A,EcMemoryIntrusionTestModeSmm +81F93099-0A7F-4F1A-94D4-B3BE3FACEA6A,SmcIpmiOemCommandSetProtocol +81F935F5-F1E2-483C-8204-B1E7015120A3,FjFastBootDxe +820C59BB-274C-43B2-83EA-DAC673035A59,SataController +820D6942-B13F-4B91-AF2C-774025D84A22,DellAutoBifurcateSiSmm +820F3F0D-4D08-6C35-858A-D98EF42C051D,AmdPlatformRasSspDxe +820F6119-9F09-4C95-85BA-8AEBC21D4E89,FjPowerButtonStatePei +8214E213-180C-4822-A236-CDCA43F43C88,CbsSetupSmmMdn +8216D0CC-7F6E-46F1-982C-E6219D4AE066,AmdMemSspSp3Dxe +8217E118-1058-4C9B-936E-5B3027C2394B,PchLpcDxe +82180E9E-FB32-4086-AB38-370BB29134E3,MemoryStorageChipsetSmm +8218965D-20C0-4DD6-81A0-845C52270743,LenovoSetupDateTimeDxe +821ACA26-29EA-4993-839F-597FC021708D,AbsoluteAbtInstaller +821C9A09-541A-40F6-9F43-0AD193A12CFE,EdkiiMemoryProfileGuid +821D8B77-246D-4E96-8E10-3467D56AB1BA,SetupAdvanced +821D8B77-246D-4E96-8E10-3467D56AB1BB,SetupMain +822A31D8-0AA7-415D-BEEF-C5C896509C50,BctBaseSmmPHX +822A9647-5479-44F0-AC85-8869074D76AD,DellForeignKeyboardLayout +822D8836-2477-4F8C-9330-2F8695EBE4F9,FjSkylakeRtcBattery +8231DBBB-30E6-459B-BA4B-5ECE97561539,DellUsbCsmSwitchDxe +823B8A1A-6D01-45A6-8098-20DDD1C7B3D0,PlatformLtDxeLibNull +823F654C-D966-45A4-A4CC-5FB6741E34BE,AmdNbioEarlyPhaseRMBPei +82479446-5371-44F7-87BF-C808BC9A9925,SplashPei +824C0DEA-8B01-4F12-A68D-A5DAEE2B9714,AmdMemSmbiosV2StxhPei +824D5A3A-AF92-4C0C-9F19-19526DCA4ABB,FspmArchConfigPpi +8253972C-9CE7-4539-87EC-A248A48084C7,AddressTranslationDsm +8256C18C-27FE-4199-B369-C6C95C555F06,H19AmdFTpmUpdate +825880CC-DBB5-4955-8AFF-B26FA33C84AA,AppleFirmwareFeatures +82594D34-85DC-49D4-992E-238E622F6152,OemSmmSample +825AE2A9-9C84-497E-94E0-09C237765948,ThermalInitDxe +825BDE6A-E9E4-4CC8-9C2D-09B29C3BD426,EfiCpPcPlatTokenSpace +82627ACF-D92D-416D-8A6F-783CACD91223,AoacEcWakeupCustomPpi +826824B6-CC9B-4D62-8E7A-0FFBF6013CBE,SmmHeciProtocol +826BCF56-BAC4-43F4-8EA1-8CDF0A121ABD,LenovoTranslateService +826CA512-CF10-4AC9-B187-BE01496631BD,EfiCertSha1Guid +827E45A4-C285-4E45-8BC7-CD8E58D9EE84,AmdPspRomArmorSmm +82805649-7247-4DA4-8643-C8144D27E2E5,ProcMemErrReporting +82820F9F-4197-46D0-A96C-B1D15BAD988E,AmiUsbVideoProtocol +82833414-C8F4-4B62-AB6A-E4D5DAAB130F,HwmInitDxe +82841737-79FD-4AC2-A948-2E5C94E80E63,DashManagementPei +828C017B-BA8E-40E6-BDA4-45B6F9F6A8CD,AmdNbioIOMMUDxe +8296AF37-D183-4416-B3B6-19D2A80AD4A8,EbcDebugger +82988420-7467-4490-9059-FEB448DD1963,MeConfig +829C8576-8CF7-43DB-81E6-D955324BF931,OememDxeGNVS +829D41D2-6CA5-485B-A1A2-D1B79627ABCD,EfiOpaSocketMapHob +829FDCA9-6917-4713-A3AD-F04CF3E1B25F,S4SlpDelayDxe +82A3935E-BA18-4703-A7D7-6D356FFE26BA,CameraSmm +82A6080E-07CB-4841-A94E-D340FD0C5284,NvmeInfoDxe +82AB4703-FE33-49C3-AE40-4A20132C792A,AmdPspDxeV2Shp +82ADB73C-E005-4E07-976D-F7F75314EC4F,FchSmmDispatcher +82BF4973-734D-4324-A3D3-FCC0EE3AD51E,DellEarlyLogoPei +82C93B6D-68ED-440E-A826-BDC7AEF8EE0D,WirelessBluetoothDetect +82D18B9E-153A-4BD7-9270-ABC14ACE5DC8,UefiDriverRealTek +82D3F268-757A-44CD-A87D-13FDA972B999,EfiPlatformTypeLightningRidgeExecB1Protocol +82DDD68B-9163-4187-9B27-20A8FD60A71D,EdkiiIfrBitVarstore +82E1070A-B808-4F26-A8E9-ACDCDFF2721A,Rtk8153UsbUndiDxe +82ECEE48-9571-4427-8485-85A5A45A0F39,DxeSmmReadyToLockOnExitPmAuthThunk +82EF44E3-2C70-11E7-8DF1-B8E8562CBAFA,AppleVariableRuntimeDxe +82FBE26B-53D4-448F-924C-7BE0126ECA4F,DellPxeUndiRom +832D97EB-8FD7-45BB-ACFE-2A468F51C1BD,DellMultiFuncDevConfigSmm +832EF075-7D39-4E4C-83B9-B1EBF34DA2D6,PcdInitDxe +83381B06-2EEA-4CF3-9B5F-D75B9B5C93DE,GetServByPort +833D3ABA-39B4-43A2-B930-7A34533931B3,UnitTestFrameworkPkgTokenSpace +83410FC1-2C86-470A-AF66-3966A1ED42BD,PhAmtSupport +8341855A-F272-4FFE-BBEE-DAEAC5CEDDC7,DellStorageAgentSmmRegister +834C0C5F-ADB3-4372-AEEB-03E4E9E6C591,IntelFspPkgTokenSpaceGuid +83705B89-CBF9-44F8-8546-E0124C682D08,SpiNorFlashJedecSmm +8373FD38-D98B-4C8A-851E-2E9396748AF3,TxeFwDowngradeDxe +8376BDCA-5E03-4735-951A-4A74141E5886,TrEEConfigDxe +8378AB1E-4147-400A-8D84-E3DE981C0453,TamperResistantBoot +837B3E7E-4259-4E35-87ED-397A24CA1593,MpmSensorInfoDxe +837D8904-2231-4558-8F70-EE72790BAB9C,ClientronLanDevInfoDxe +837DCA9E-E874-4D82-B29A-23FE0E23D1E2,VirtioMmioTransportGuid +837DD75D-9862-4E68-87F9-64F855BB83EC,HpNetworkFeatureByteKillSmm +83890F3D-B747-4F4D-8C21-12908759A53F,HstiIhvProviderDxeEGS +838DCF34-907B-4D55-9A4B-A0EF7167B5F4,NvramPei +83965ED8-D618-4176-81D1-57B822627CA1,FjSecuredCorePcDxe +839B07A6-054D-491C-9B15-3A3906449990,ThunderboltSmm +839EB770-5C64-4EED-A6D5-EC515B2B2B23,PlatformVTdInfoSamplePei +83ADC55E-24E1-471A-BF47-272F49CD8F9A,FjGabiFlashCoreDxe +83B698B9-0208-4ECF-BB83-CE42D0BEFC4A,DellPwByPassSmm +83C233EB-D01A-45D8-9FA1-AF40206FCC9B,AmiTseOemPortingVar20 +83C30E53-7A4C-4273-A686-65E9DC09D75B,AcpiDebugTable +83C8BCBA-810F-4D22-9CA5-1F27B092D547,GNVS +83DB711B-ADAC-46B3-BBFF-5E6E28CFFBD2,DellWlanSmm +83DD3B39-7CAF-4FAC-A542-E050B767E3A7,VirtioPciDeviceDxe +83E053E5-3BF6-4C2D-9B86-72BE3CF2EDCC,I2cMouseDxe +83EC3FC9-CB74-4B2B-89B9-E98F0972F2A8,RotateScreen +83EC90A9-D791-4613-9C57-68C3DE923C3B,MeSmbiosUpdateConfig +83F01464-99BD-45E5-B383-AF6305D8E9E6,EfiUdp4ServiceBindingProtocolGuid +83FA5AED-5171-4949-BDC9-0CBC9E123663,FwCapsuleRecoveryPPI +83FAAFBF-FC4B-469F-892A-798E66A6F50A,RestJsonStructureDxe +83FEE84D-9321-4908-895D-4F6E355CEC55,HDMIPConFW +8401A045-6F70-4505-8471-7015B40355E3,UsbBusPei +8401A046-6F70-4505-8471-7015B40355E3,UsbBotPei +8404B613-EA35-466F-BC7B-9F51C965198E,AsusBackDoorPW +841C04A6-A8B5-49D8-B65D-86CDB36D4416,SmuV11Pei +841DDA73-0A8D-4D49-AF60-2A145D2176CE,EfiNgnAcpiSmmInterfaceProtocol +84245DBA-1B6B-43CD-AB59-7B2FEE2C5BEF,ASRockBIOSInfoDxe +842546AF-5AEA-40DB-8695-42E52575CA45,A01DataServiceBodySmm +842680F2-1A9C-48E6-A433-BE9ACB0DD438,EfiIpmiBoot +842A454A-75E5-408B-8B1C-36420E4E3F21,NvramSmi +842C4FC7-1E52-492E-9E64-70F998CD8811,SDSmbiosUpdate +8434DA1F-5CEB-402E-A93C-038CBE0F3F0E,OemActivation3Smm +843CE545-9F06-410F-BA6C-311D66AD643A,MFGDoneSync2Setup +843DC720-AB1E-42CB-9357-8A0078F3561B,EfiSmmControl2ProtocolGuid +844EC5BC-AE49-41B2-A70A-0AEE59505518,DellAdvSysMgmtDxe +84562A94-1CFF-11DF-AB3F-FB61AA51C41C,PmRuntimeDxe +8456F6DB-043B-405E-B18D-684E69B05DE7,AmiOemRasDxe +845A6EE9-ABEB-4DDC-8983-0A13A2D1A79D,TdxDxe +8467C103-6FF6-4D66-86F6-E1124C111E94,DellHotKeyHandlerSmm +8467C103-6FF6-4D66-86F6-E1124C111E95,NbLegUsbPolicyload +846E721C-E036-4F2F-90A6-8094917FB077,NvmePciHcPei +84762744-FFA7-4228-B430-87AE0C2C3BE7,EmulatedEepromSmm +847BC3FE-B974-446D-9449-5AD5412E993B,BootManagerDxe +84821C5D-1CFE-4E2D-819D-5019448D175C,SmmSxCallBack +848377A0-A78D-469D-B766-87186AA6770D,EpuHwModeDxe +8489334D-4219-4CA1-9B42-1D46B0B75861,TcgPpVendorLibNull +848E908E-BD11-428E-94F9-7A0EEFCD37A6,BaseCsrToPcieLibNull +84945A3D-49C8-4059-8F34-6A4532D32A47,VariableEditSmm +8495E3A1-43D9-11E8-927F-A4C4943F0C96,NvdimmInitializer +84991287-3FF0-4FCC-9C11-C7E041862C76,DellPowerManagementDxe +849E502A-75B6-4F9C-AD12-1E01F1DC0C40,AmdAgesaParameterGroupPei +84C31E7D-3703-42D3-B43B-1FEE41666D9A,SystemFormBrowserMetroViewLayoutDxe +84CB67EC-B27D-4F83-897D-16A95B626EBE,BoardInitAdvancedPostMem +84D3E3DC-98AD-4D40-9396-57E8ADC7868E,GetVariableHookDxe +84D4AD5B-1702-442E-BDD8-57E1196111E5,SmmAccessDxe2 +84DA4361-EE8A-4769-9368-4F28A1C92032,EfiBxtTokenSpaceGuid +84DDA68C-CA5A-4C30-9261-DD6DE7E45A95,EzSetupPortingDxe +84E7016D-1EB8-4637-B01E-9EED018C7AE0,BiosGuardNvs +84E90BA3-CB79-4267-AE2F-437B86DAA6F4,DellTrustChainingPei +84EEA114-C6BE-4445-8F90-51D97863E363,CpuHotplugSmm +84F258E9-5AA9-4DD6-A4D4-209B3BE31B0C,OfflineCrashDumpDxe +84FA65AF-21BC-43BE-85FF-8AA7E7832A1D,AmiPciExpressLibNull +84FB407D-D076-4DDD-871F-33373A26BABB,FchPromontorySsdt +84FB407D-D086-4DDD-822F-33373A26BACC,FchTaishanSsdt +84FB69A7-C858-483A-BB90-D3BCAFBCC6ED,DatabaseManagerDxe +850CBAD8-5CF2-4B46-8FF6-ACED339EDDB0,HeciControlPei +8513DFD9-F651-43F7-9296-B31D5316CAB9,PlatformBootMode +8519ED6D-228A-4A7D-A9E3-6E24D94FE22F,AmdCpmAdaptiveS4Peim +851A6355-CE10-4F67-9D13-91B3281A95D3,LenovoSystemOemActivationDxe +851D895C-2212-4D81-8316-18D7C13E5F60,AmdHspFtpmDxe +85226559-0DEF-48D8-A8C9-B746D6A4DF01,AmiMemoryErrorReportPpi +85254EA7-4759-4FC4-82D4-5EED5FB0A4A0,DefaultPKFile +853C36E2-D7F5-4CED-BF73-E0111A648082,AsusOA2Bin +855328E7-F96F-4398-9E7F-1F0A8C014E2C,AppleMeDriverDxe +8555FD40-140B-4F3C-905E-3BF378A099FA,EfiActiveManagementProtocol +855D2C2A-8A68-4783-AEC0-CCD995CBA569,FchKeithMdnSsdt +855D6DC1-9FE8-42E0-9F76-50C2E2DD2E06,AmdPspDxeV2Rpl +85674556-04B3-4151-8612-53C628835F34,H19DxeInstallHook +856C6A10-F3B8-4C2E-A273-7868C09BE8EA,MmcMediaDevice +85768E4A-6CDC-444E-93DF-936685B5DFCC,VlvRefCodePkgTokenSpaceGuid +85794F19-3BBB-4392-BB3C-06E3EB45E387,D01HookAcpiProtocol +858031F3-96A2-406E-ABCC-ED264A3A31D6,CryptRuntimeDxe +858189AC-0ECA-4666-BAB8-9972409953C8,AcRecoverySmm +858EBE6F-360F-415B-B7DC-463AAEB03412,TcgLegacy +858ECEAE-4A83-41BE-9643-6ABB93943A4C,RealtekGopDriver +85941FF3-13C9-46E6-9EE7-68B487B83F27,AaeonSmartBoost +85984EC9-E300-4277-AC62-640FABADB6A5,DellSbDxe +859A2015-3C7B-4F4E-847F-7AA88C8714A5,ConfigChangePromptSmm +859F2D28-2894-4EF7-A05C-F8BFC7922DB7,HidSimplePointer +85A00CB2-2924-4849-95C4-787852F03FC7,PlatformSmm +85A084FA-6B0E-BD4C-A20E-156E46103155,Legacy8259 +85A5550B-3E76-42E4-8826-F9879983DE69,DellOA3 +85A6D3E6-B65B-4AFC-B38F-C6D54AF6DDC8,EfiSpiConfigurationProtocolGuid +85A8AB57-0644-4110-850F-981322047070,EdkiiSmmLegacyBootProtocolGuid +85B0C7D3-70AD-4FB0-9556-64419E7F713C,FjAcpiSmiSmm +85B75607-F7CE-471E-B7E4-2AEA5F7232EE,EfiUserInfoAccessSetupAdminGuid +85B79D5D-EAAD-4A85-BA28-03D1362E668D,FchI2cMasterPei +85D80233-B31B-40F2-8131-034405FC5936,SmbiosType133 +85D8435F-A603-4DAD-A285-7230D84F9F69,AcerDiagnosticLogDxe +85D91856-70A3-411D-9612-4531C060D867,ITE8225DxeInit +85DB8287-B268-4DF4-9226-7302B211E303,OSSelect +8600C3A8-4213-456E-832A-D51E8E5F4AB1,AppleHeciDxe +8614567D-35BE-4415-8D88-BD7D0C9C70C0,PlatformOverridesManagerGuid +861AB7EA-0E47-40B3-AEA6-48D07AF4703C,CsbSmartCover +86212936-0E76-41C8-A03A-2AF2FC1C39E2,EfiRscHandlerProtocolGuid +8623FAE0-D68A-4E4C-8D3A-BADC1FEEA00D,FjSetupInterface +8624F36D-6DE0-44C3-8322-74AD419D3A90,AmdErrorLogDxe +8628752A-6CB7-4814-96FC-24A815AC2226,EfiHashAlgorithmSha256NoPadGuid +863095D8-3BF4-447C-AE10-15B3AE9936FD,LenovoSystemBootModePei +863B519B-57F0-4FF4-BEC8-140AF94FE106,DellChassisPei +863D214F-0920-437B-8CAD-88EA83A24E97,DatahubStatusCodeHandlerDxe +864693E2-EDE8-4DF8-8871-38C0BAA157EB,PeiFspWrapperHobProcessLibSample +86488440-41BB-42C7-93AC-450FBF7766BF,SystemBootMenuDxe +864B10FE-3D5E-4908-88CC-F08D4EDC0050,LenovoSystemPciIsaBusDxe +864C95F3-1558-4D13-A474-11D0023576E2,SureStartPcdSmm +864E1CA8-85EB-4D63-9DCC-6E0FC90FFD55,SioBusDxe +8650A9D0-3A80-43F2-85D8-6D10CDBF611E,SuperMSmm +8657015B-EA43-440D-949A-AF3BE365C0FC,IoMmuDxe +86574ACD-5A8F-4FFF-A64F-6A1702786850,CommonSetupDxe +865A5A9B-B85D-474C-8455-65D1BE844BE2,EfiDebugAgentGuid +865A5AAB-B85D-474C-8455-65D1BE844BE2,EfiSourceLevelDebugPkgTokenSpaceGuid +865F8FA9-BD72-4D38-A1C6-6041F426E92F,DellSbDxe +8663617C-CA3A-4B25-B63E-6FFB3894D65A,SioSmiSwDispatcher +867864C8-3986-41A6-AA26-A3A41F1B5DC3,StringMarshalSmm +86787704-8FED-11E3-B3FF-F33B73ACFEC2,TcpFastbootTransportDxe +867BC78A-10AC-B6A2-88B5-C412ABC42A62,DellPlatformErrorHandlerSmm +8680725B-3E11-46B7-AB11-2B30180386BA,DustFilterWmi +8683EFB2-FDE1-4AFF-B2DB-E96449FDD4E9,S3Pei +86843F56-675D-40A5-9530-BC858372F103,OsSelectionVariableGuid +868A660F-47F8-4088-A4C0-C55FF8DB0C96,LEMPhyPresenceSet12 +8698C9AB-DF46-4B3C-B119-1D4CC1199497,Realtek5243CardReader +86997AE6-D443-4939-B729-A3D0F32FB772,OneClickRecovery +869C711D-649C-44FE-8B9E-2CBB2911C3E6,EfiPeiDelayedDispatchPpi +86A075CC-7854-4B11-AF71-95B8762D941A,N17PQ3Gop +86A885EE-D71E-2ED6-0FC1-9D6CCC9677EB,FmpDxe +86AD232B-D33A-465C-BF5F-41370BA92FE2,EfiMiniShellFile +86B091ED-1463-43B5-82A1-2C8B83CB8917,EfiPlatformRasPolicyProtocol +86B9FA34-F889-4DDC-AEC7-40D286EC6181,I2cTouchScreenDxe +86BA6273-0562-4CD6-8971-8732949A1191,BiosInitToFactorySupportSmm +86C17F69-6A91-451A-86B6-F92EBC602831,AthQCA9377Undi +86C29AA5-0DB0-4343-BD52-7A729F37C96D,AmiDigitalSignaturePPIGuid +86C77A67-0B97-4633-A187-49104D0685C7,NuvotonFwManagementDxe +86CDDF93-4872-4597-8AF9-A35AE4D3725F,IScsiDxe +86D64391-9699-417C-9506-14FEE06B8E54,RfBootOptions +86D70125-BAA3-4296-A62F-602BEBBB9081,DxeIpl +86E82AC3-D6AF-47A4-8C93-0C76C7B3CCD3,LegacyBiosMiscSmm +86ED8CBA-839E-46FF-A740-3504D8A79808,PeiOemModule +86EDAAE5-073C-4C89-B949-8984AC8A55F3,SdMmcDevice +86F5680A-155C-4BC8-AC77-573848E2AD3D,AmiTreePpiGuid +86F61BDF-5BFD-46D3-B0F9-E43728DA1D2E,OCMR_CPU_POWER_MANAGEMENT_DXE +86F67A12-2E32-44FC-8D6C-7901E2B5649A,CapsuleUpdatePolicyDxe +8708203B-8948-4E51-BEE7-8C1B56EEC9CD,FjPvCredentialProviderDxe +870CAF91-B79B-4EBA-920F-71E3DD4789F4,HeciRuntimeDxe +870E0F5A-1981-45F6-AE26-0391425CC46F,CpuCsrAccessSMM +871349B8-C7E6-443A-B9ED-91A41AFFFC82,SmuV11Dxe +8714C537-6D4B-4247-AA6C-29E8495F9100,FspNotifyDxe +871669D2-A12B-4785-8049-06048E4A1C52,HpBlockingDriver +871CA5C8-FA45-E413-7491-02CDAC5F90AE,AcerBIOSConfigurationToolSmm +87346F74-B249-49B8-8287-2702CE61109C,BiosGuardServices +87367F87-1119-41CE-AAEC-8BE0111F558A,EfiJsonConfigDataTable +87438836-AD8D-4E3E-9249-895120A67240,DebugCommunicationLibUsb +874E9954-24D4-43E6-90A1-C5775340CF45,AmiPlatformInfoHob +875F4197-2AFC-42F5-B090-4DF03B1DA613,SpanishDxe +876730C9-9A69-4508-9579-CEBD1462A5FE,AmiSsidInit +876E11E2-5B23-4EA4-AF2A-4065EFBAD841,LenovoVariableStoreSmm +877609BF-BBE2-4C9E-B45B-A46859C76C73,FjGabiSettingsApiSmm +87777B50-6429-4F8A-8A62-F5B14F1F5948,FruCpuFeature3v0 +877F57F6-689B-4FC1-A7AF-02DF7FD536E8,AdlSemaSmm +87837AA2-EEB7-434E-9EAC-9D49639E72A2,OtaShellCommands +878AC2CC-5343-46F2-B563-51F89DAF56BA,IntelIGopVbt +878CA608-293F-482E-83A9-50A484B5D4ED,EDockSmm +8790C65B-61E2-41A0-B6AD-FCE066F18414,EarlyConsoleOutInterfaceDxe +87AB821C-79B8-4EF6-A913-21D22063F55F,AcpiPlatform +87AE079C-1143-48D7-A6DC-D9E6115DBBCA,FjGpioAlderLakeDxe +87C2106E-8790-459D-BD44-2EF32A68C3F9,IhisiServicesSmm +87C3E993-B28D-4226-89C9-120DBC92ACBF,SmBusSmm +87C4741D-CEF4-48A1-89AA-7F86EFA0A21A,MediaCapsuleEarly +87C73C1C-1529-4EF5-A3FA-08D73EF8C827,DellSmmSioDash +87C76262-F1F3-4452-B805-47438A6793A7,SgDxePolicyInit +87C8BAD7-0595-4053-8297-DEDE395F5D5B,EfiDhcp6ProtocolGuid +87D243DD-F77A-43F8-A21E-6B04DD76749B,DellEccErrorLog3Smm +87D402CD-8B07-4B93-B38B-F8799F28B033,AmiTxtDxe +87DAA0C1-99BB-4435-AB35-36BC7DCA4EDA,UsbKeyboardPei +87DD3539-0667-4BB7-9FB2-47D3C50B021B,PhoenixDesktopMessageProtocolGuid +87E1BB14-4D5C-7C4E-A90E-E1415687D062,EmuTimer +87E328F9-93A5-4375-BA69-93A7A77A5D9B,LenovoInitMePolicy +87E36301-0406-44DB-AAF3-9E0E591F3725,VConfig +87E4A8F8-B74A-40B5-B019-E10A5DE11236,VbiosHookSmm +87EA012D-CBAD-44C1-8431-61193A060941,PeriodicSmiControl +87FB2BE8-F1E6-448D-970A-BE4DFE7921CB,AaeonSxSmi +87FC8DCF-660E-4FFF-8776-D6BA053DEDD1,DellIoExpanderPca9555Dxe +87FFC11C-D0AB-4D12-A779-0A5474050759,OemProtocol +88015920-2B9B-4B2E-840C-AD76BC6C3ABF,AmdNbioDxe +8803FA9A-0D33-4022-856B-AB5932A0F8BF,AmdInitPostPeim +880AACA3-4ADC-4A04-9079-B747340825E5,EfiPropertiesTableGuid +880AE5C9-FA45-9B63-7489-9B12CC564540,AcerBIOSConfigurationToolDxe +880D81BF-DA88-49E1-9543-A58247FEAD1A,LenovoSetupAutomationSmm +881807D2-98D1-4EC9-AFA0-7746C42F2449,PeiAmtStatusCodePpi +8825B553-85A6-466A-9846-0CC23C5AEA42,SystemSetupCapsuleUpdateDxe +88286B57-478E-ECBE-6407-D8BA02E7873C,UsbPortConfigPortingDxe +882C5D54-1DAD-4F4A-8316-4BDF841E09D0,EfiNorthPeakStatusCodeHandlePpi +882C5E65-D37B-441B-A1D9-6C89C5CC3AE1,UsbDonglePei +882F2546-EF1F-4090-9F9C-93845AD7841C,SmBusControllerIdentifier +884441DA-4459-4796-A5AE-D39F30E97A9E,LanWakeupPei +88523DDF-3AAC-41F6-B15F-DC7BEA434B39,TrackPointSynaptics +88548343-32E6-45D4-B1F1-1D4FA72DD4A3,MeFwuDxe +8863C0AD-7724-C84B-88E5-A33B116D1485,Host +88640B94-021C-4926-9198-0A98FB7A0826,COM_TYPE +8868E871-E4F1-11D3-BC22-0080C73C8881,EfiAcpi20TableGuid +886ACB20-78C0-4F88-9D3C-BADCE37EDA47,LenovoN25Q064FlashPartDxe +887B83CD-B40B-4390-94E2-EF77F36AE101,FjDxe +88863325-C803-469B-9904-6FB2E33F0070,AssetIDOnS3 +88888888-8888-8888-8888-888888888888,WholeFv +889004EE-8388-43BE-8975-C593FC50BB4A,EmulatedEepromDxe +88A15A4F-977D-4682-B17C-DA1F316C1F32,RomLayout +88AEC621-2E0A-4280-BFCE-8AC7E31E774F,BH611FJ1 +88B00BA7-7561-43EE-9733-E41BDA8498E0,AmdCpmEcInitPeim +88B1FC50-4536-4931-A8CD-AB54BA416AC0,VmdVrocWrapper +88B468B3-A48B-4B87-ABE2-8E56DFFDAF8D,DualBiosSMM +88B49226-A63F-4505-9D3C-B5A67B846133,FrameworkSmmStatusCodeOnPiSmmStatusCodeThunk +88C065E7-900D-4899-B7B0-CD404E113F95,PchPortCF9hTrap +88C17E54-EBFE-4531-A992-581029F58126,FspPcdInit +88C5D0C5-B0FF-4E06-97D8-A84B2E259EA8,SaveRestoreGptDefaultsAndWmi +88C61F0D-DFA9-4087-8687-626A8B010E0C,PasswordLockSmall +88C9D306-0900-4EB5-8260-3E2DBEDA1F89,PeiPostScriptTablePpiGuid +88D01BB9-247A-46F6-BB6E-BBA49F1124F8,DellSmmEventDxe +88D3D12C-5B7B-497E-A27B-1CB65D42BF0F,BrightnessHardwareGopDxe +88E31BA1-1856-4B8B-BBDF-F816DD940AEF,S3Communication +88E502C8-27ED-4390-AE14-937607595823,DellIntrusionDetectPei +88EA1FCB-3A5D-4ACF-A0B3-AACB36D4E90F,UsbLegacyControlSmm +88EB4F41-E574-4144-9C93-79485B110910,DellCoreServiceHWIDDxe +88EC827F-6CDE-41DD-8B55-BD62449C4F1B,VbtMipiPanel2Guid +88F6ED8D-7D6E-40EB-84B4-D66FBDDCE5C0,AmdMemSmbiosV2PhxPei +88F74F5E-E998-4D59-44D8-225FEF02FCE3,TiXio2001BridgeConfig +88FAE289-0A6A-4097-9CCA-2BED645B094D,AplDxeIpl +88FEEAAB-BFBA-4CB9-8907-31BC6E546DBE,SXApp +8900C607-C0AA-478E-AF00-65870BC951FD,SetupStatusDxe +8900E28F-DE99-4FC4-894B-6F41CD139A48,InfineonTpmUpdateDxe +8901FE25-27D3-4815-A63D-35851C4F50EF,FjGabiPostFlashAbstraction +890987B9-3E09-4608-A468-5E0987B204ED,FchSongshanI3cDxe +890A3508-E816-41CF-B7E6-ED28E5BB5C28,AmtCompatiblity +890C2CEF-43C8-4209-A78D-AE14AA1798B4,AmiTcgPlatformPpiAfterMem +8913AADD-564E-4CF8-B176-F3F985979C5F,RomHoleReplacementProtocol +89173692-9AC2-4C86-9ECC-F37782DDEBAA,LenovoHdpManagerSmm +891A4B58-440A-4792-BEC5-173E2E3E6797,PostMessageDxe +891BF95C-A903-42E7-8D5F-B7F9B6C8831C,PchLpcPei +89276AFE-0B07-4B39-AF5F-506FC0D21091,CbmrSetup +893BF598-FA5D-4B6C-8829-6016ECC443E7,MainErrorHandler +8956E299-D5D9-4453-8B3F-BBC8131336AB,OemSmi +8958EDFF-02F7-4E49-87B1-FBA4BE4E8768,SmbiosDataUpdateDxeLightningRidgeEXECB4 +8962C28B-0DFE-4739-A73F-092D374A7A13,efi_pop_RT_pressed +89680AAC-452B-4B44-AEF7-800B6BFAF195,EfiIchTokenSpace +8969E833-7DC7-4DAC-A2ED-08251482EE5B,I2cPssMonzaDxe +897508C5-FCDA-4DB9-8A7E-6214CF6C246C,LenovoNvmeInit +897508C5-FCDA-4DB9-8A7E-6214CF6CFFFF,LenovoHstiUpdate +8975A90C-238C-4FA8-9EF1-03C6C359CA39,AmdCpmDiscreteUSB4Peim +8977B212-0A43-4048-993B-B39AC7B0FE21,gear9 +897A5222-978B-49AB-BAA0-FC523FB92602,FjThermalSmm +897C64C1-0CB7-4FA2-815C-307463E535B5,OemManufactureModePei +8980E2D0-6C77-423B-8E3A-8D3D40D10CBB,RTL8852BEWifiDriver +898415A1-06F1-4C21-B83A-C555CF2F2364,DellMemoryThrottleProtocol +89843C0B-5701-4FF6-A473-65759904F735,EfiBmcAcpiSwChildPolicyProtocol +8987081E-DAEB-44A9-8BEF-A195B22D9417,BasePciLibPciExpress +898890E9-84B2-4F3A-8C58-D8577813E0AC,EfiBluetoothAttributeProtocolGuid +89908199-9126-4EA2-849B-06A75C245D0B,MeResiliencyDxe +899407D7-99FE-43D8-9A21-79EC328CAC21,Setup +899AFD18-75E8-408B-A41A-6E2E7ECDF454,EfiExtendedSalMtcServicesProtocolGuid +89A1B278-A1A1-4DF7-B137-DE5AD7C47913,EfiPchTokenSpaceGuid +89A27A0C-33A6-426A-A433-43EBC7BA5A5E,RaidOptionSetup +89ADA336-4455-11E0-B7E6-A801E0D72085,InitResetArch +89B6C309-F785-421F-A03C-38A800345201,AmdCpmUartDxe +89BB21EF-991D-4EA3-BE7A-1CC78533B17F,PlutonSecurityProcessor +89BC66BA-030B-4D04-A567-C66727EB9911,FjGenericItemProtectedStorageSmm +89BF244F-E569-416F-B110-8AE5EFD5171C,DellDxePrereq +89C44717-7EE4-487B-8F5C-8E609556A90F,VideoInitDoneSent +89CFE3CE-C127-42F8-BD69-2910AF7B87A7,SmmBoardInit +89DEEF37-31D8-469C-95B6-0169BC866CFB,EfiIpProtocol +89E1DBEE-54CE-422E-9C98-362A3EFDF92D,LemPostFlagPpi +89E3C1DC-B5E3-4D34-AEAD-DD7EB2828C18,UsbTimingPolicyProtocolGuid +89E549B0-21A9-4F76-9DFA-1B71E2A7C3F2,S3Resume2Pei +89E549B0-7CFE-449D-9BA3-10D8B2312D71,S3Resume2Pei +89EFE6DE-9CF2-4B7F-8F0B-AEBBA5A25B26,ComputraceComponents +89F06049-F297-4436-8540-E0BF9E92B56B,SdioRecovery +89F09528-C33A-47FB-BA19-FADE80A39F76,DxePlatformDxe +89F639BD-092D-4952-BEC8-F1F05FE3409C,OemActivation +89FD3E04-D647-42D1-8972-A6156FC3A0DD,LockLegacyResourcesPortingDxe +8A002AF2-EC39-4B01-BC64-84284267DF44,ASM104X_PEI +8A107CC5-DCDA-4FB7-A272-4243B41AFBFE,AppleGraphicsPolicy +8A1C3C80-A891-4EEA-9197-6635E277C4DB,HpVrocDxe +8A219718-4EF5-4761-91C8-C0F04BDA9E56,EfiDhcp4ProtocolGuid +8A2FDFC3-0395-442C-B9F7-9A3D69D2094C,SoftKbd +8A39B8EF-6680-4A7F-9AC4-18365214A3F0,AmdSocSp3r3CglDxe +8A47CA0A-B201-46EF-8883-54D4557A93A0,DisplayLogoDxe +8A4E8240-74F8-4024-AE2B-B39221C9FA59,NvOptimusSMM +8A50765D-1582-41EB-8289-1409419C24DD,LenovoMfgDoneSmm +8A563114-70F2-4ADC-9A47-19424DFBE82C,CrbPciePei +8A6093B1-02B8-4685-B250-48CAB364BCF8,FjPeiSetPlatformHardwareSwitch +8A66BB48-6F23-4809-938D-33ACA6C481AE,FjPciPei +8A6B4A83-42FE-45D2-A2EF-46F06C7D9852,EfiUserCredentialClassSecureCardGuid +8A76A029-F948-4A56-93D0-2E2BC2ABDB4B,OemACRecoveryPei +8A78B107-0FDD-4CC8-B7BA-DC3E13CB8524,PeiCpuIoPei +8A813C26-0297-4608-975A-2D744204C746,LenovoTamperSmm +8A867F67-89D8-4134-BBBD-64BBAA5256F5,AmdCpmI2cDxe +8A8A6221-E240-4E09-ABC3-B1DF3609B027,AmdNbioPcieDxe +8A8D0AD0-E28C-4907-A651-AE9D65CD9298,TileSmm +8A91B1E1-56C7-4ADC-ABEB-1C2CA1729EFF,AmiPostManagerProtocolGuid +8A97886A-EEE1-4BF8-AD20-68F398F95B12,AMDPSPKvmMiscDxe +8A97B11E-EE8E-11E2-B664-047D7B99E097,AcpiInterfaceCoreDxe +8A99693A-F42D-442B-B369-DDD6780DA710,PlatformHstiSetupDxe +8A9EE24D-DAE8-401F-A591-241DF848407F,WwanSmm +8A9F7CFC-5BFC-458F-986F-BC3D1BA7AC89,DellSpiPartStMicro +8AA67071-8BEC-47AB-83C8-CD0EB723D072,IdeBusDriverBindingProtocol +8AAE7EE0-8EE6-4F3B-9A03-EE3437593E03,OemSmmSx +8AAEDB2A-A6BB-47C6-94CE-1B8096423F2A,EfiSocketServiceBindingProtocolGuid +8AAFF1F7-D011-4AE5-8324-DFA470F75D33,AsfDxe +8AB17F97-758F-47AA-BA64-DDC63C3A1D86,H19DbxService +8AB1D576-5977-4A89-9414-099D90B53E79,TpvSmm +8AB2F241-77FA-49C7-BD2C-FD71A743FD8A,PostMessagePei +8AC88C0F-6220-F243-8E27-56E17CC503DB,AppleNetLoadFile2 +8ACEFE43-D9A5-471D-B802-9879862AC3BC,FchSmbusDxe +8AD3148F-945F-46B4-8ACD-71469EA73945,Tcg2ConfigPei +8AE83DA6-881F-4BA6-997D-7BF16ED553B4,OemSmi +8AE96C45-9798-45E5-A952-143B6330A540,ClientronSmbiosUpdateDxe +8AF1FE4F-DB8D-43A4-AA5D-4ADE632A0FE9,SmcPeiSerialTextOut +8AF7DD16-2342-4987-9426-6604A207E24B,HddStandBy +8AF7DD16-2342-4987-9426-6604A207E26A,PasswordSeverityDxe +8B013FF3-31D2-4693-83E6-59FA0C73F0E3,CompalCommonHookDxe +8B01E5B6-4F19-46E8-AB93-1C53671B90CC,EfiTpmDeviceInstanceTpm12Guid +8B05600F-4E47-46ED-BDB0-44115D465D08,UpSmbiosData +8B0E1353-358C-4E2F-9345-EEBF1DAB989B,AsrockRtlandxe +8B12F29F-7135-4EAB-AFDA-0512F74B65EA,AmdSb900Dxe +8B24E4D4-C84C-4FFC-81E5-D3EACC3F08DD,ApplePlatformInfoDB +8B29BE94-5B8B-4E04-B771-5761FF97B113,FjFpCredentialProviderDxe +8B335317-B490-4C75-93DF-C68201346758,FjSetupControlDxe +8B33FFE0-D71C-4F82-9CEB-C97058C13F8E,BootFormSet +8B34EAC7-2690-460B-8BA5-D5CF32831735,EfiCapsuleInfo +8B48D921-54F7-11E4-9FF3-047D7B99E097,WirelessDeviceSupportDxe +8B529353-1FCC-4AC0-A121-90BE9F9CBF7A,DellDiagsLegacy +8B5FBABD-F51F-4942-BF16-16AAA38AE52B,AcpiPlatform +8B63F985-5DED-448A-8996-A008BED45AA8,SystemDeleteSignaturesDxe +8B68002A-817B-0361-BABA-6341A44EA052,DPTFPolicy +8B702C70-A9FE-45F6-BA66-951B50BA3B92,OpalRevertDxe +8B778A74-C275-49D5-93ED-4D709A129CB1,AbtDxe +8B786703-E8C7-4BEA-8F07-CDF991B90999,AmdPspDxeV2Rv +8B7E5420-1B71-442A-9916-C13A4FE02482,SmbiosDataUpdateDxeLightningRidgeEXRP +8B8214F9-4ADB-47DD-AC62-8313C537E9FA,SmmBasePeim +8B843E20-8132-4852-90CC-551A4E4A7F1C,EfiDevicePathToTextProtocolGuid +8B87A12B-F438-49C0-8A7B-8D16A1FDACD4,Rt8111FPciUndiDxe +8B8AFD01-8A32-4249-9800-FABC2B1084E5,BluetoothSmm +8B8EE015-62B3-40EC-A9E5-836CBFE1F33D,TouchPadDriver +8B8F683B-F376-4BA0-B8D7-B4BBD30319CC,AtSha204aDxe +8B921AB5-A1C3-4660-BD4B-FA00B7248421,PlatformFlashPartDxe +8B93CA34-91CC-4D2A-8C74-371F92691F13,RetimerFMP +8B9947AE-0A9E-4D5F-8A8D-87C914136F38,FlexIoCardDxe +8B9D3EE0-4BA4-433B-9C48-4E830B3B40FD,FloppyCtrl +8BA016CD-3EE3-4934-9BEE-AED08EA572B9,PspPlatform +8BA65DE3-39E1-4AFD-A8FE-7DD0BAFEFCC0,DxePalLibEsal +8BAA47AE-0A9E-4D5F-898D-87C914682F38,RTS545XDxe +8BB070F1-A8F3-471D-8616-774BA3F430A0,SmmIpmiTransportProtocol +8BB18D0B-9193-4DC5-BDA0-7BEA3735DC34,FjUsbHub +8BB59471-823C-4A11-B610-CE3985793EB1,DellSystemPolicy +8BB76937-EC61-4E48-B397-6667DA243486,FjDtPlatformSetupServicesDxe +8BBC2910-04E8-4450-A6CD-349E5D4D765B,DellRuntimeAcpiDxe +8BBE7DE7-6FFB-4128-8C33-23852EBC7920,EarlyVideoPei +8BC1714D-FFCB-41C3-89DC-6C74D06D98EA,EfiSmmPciRootBridgeIoProtocolGuid +8BCEDDD7-E285-4168-9B3F-09AF66C93FFE,S3ResumePei +8BE1FE5B-0B4E-4AB4-B77B-5E03403DF501,DellUsbTouchPanelDxe +8BE4DF61-93CA-11D2-AA0D-00E098032B8C,EfiGlobalVariableGuid +8BEB8C19-3FEC-4FAB-A378-C903E890FCAE,AmiEventLogsFormset +8BEEDB0D-A31A-0361-A312-5DC8574C65F1,AzaliaPolicyPei +8BF0A193-CC00-4779-9DB3-3EA35DC77BCD,AmdPspPeiV2StxH +8C0ACC5E-28C1-4599-8238-9558A9D7A428,UsbTypeCPowerLimitPei +8C1015F8-483A-4919-A078-EA338F3C7DD4,SmmCommBuffer +8C1CAD13-167D-486F-8B20-12FF6D1305CC,FjPowerButtonDxe +8C2487EA-9AF3-11E3-B966-B8AC6F7D65E6,XenPvBlkDxe +8C2BDD31-8FC6-4C74-A5B1-E967E51CA482,AsusFnLockOption +8C3319E7-2BF8-4BF9-8FD5-036641F678D6,SecureWipe +8C376010-2400-4D7D-B47B-9D851DF3C9D1,PchMeUma +8C3CFB87-F7AE-4A36-AAFF-931FDC5F436E,AzaliaInitPei +8C439043-85CA-467A-96F1-CB14F4D0DCDA,LegacyRegionDxe +8C4C9A41-BF56-4627-9E0A-C8386D66115C,EfiTcgPlatformProtocolGuid +8C542316-A1E5-4001-89E7-15EDFF12577D,gear11 +8C72C36E-DACC-4E81-8D60-FFA61D88FF54,EfiPeiPlatformpeiExecutedPpi +8C7330CD-BAD5-48D1-A7D0-F11A822BCDC8,FjGpioCoffeeLakeDxe +8C783970-F02A-4A4D-AF09-8797A51EEC8D,PowerManagement +8C7D4D1E-98AD-4CEE-8483-DD7005002544,ProjectPEI +8C7DB881-DA76-4486-8654-8152EE3470A3,MuVarPolicyFoundationDxe +8C801E8A-1A95-450F-BC59-AE490DF23029,FjShutdownLogSmm +8C86F037-50E9-4CFB-9DDB-903F084F3A40,FjIbvNvramGateReferenceDxe +8C87E0A0-B390-4BE3-819C-7C6C83CAE4EB,SmmBaseHelper +8C8A2E6C-A56C-4A6C-8C9B-B4B6BB4208AE,NvmeRaidDxe +8C8BC8DB-1930-470B-B6C4-0D8C2E6A9FD4,LnvPdrDxe +8C8CE578-8A3D-4F1C-9935-896185C32DD3,EfiFirmwareFileSystem2Guid +8C91E049-9BF9-440E-BBAD-7DC5FC082C02,DWMciDxe +8C927876-EC71-4DE4-A91D-8AD478CA9539,CpuRas +8C939604-0700-4415-9D62-1161DB8164A6,AmiTcgPlatformProtocolguid +8C9D8537-9479-40F4-8C82-70D1EF5F7353,UsbOcUpdateDxeLightningRidgeEXECB2 +8C9F4DE3-7B90-47EF-9308-287CECD66DE8,EdkiiPlatformSpecificResetFilterPpi +8CB50D77-4524-4F78-A9AD-628DF311203E,FjCypressConfigDriver +8CB53645-72FF-42A9-8ECA-0D7EC3D726C9,EcRotUnlockEcPei +8CB71915-531F-4AF5-82BF-A09140817BAA,FLASHMAPBIN +8CC435C5-6330-4269-B0C3-E3BD05C86FB8,DebugCommunicationLibSerialPort +8CC4C372-D69A-4201-BC19-07799B699369,CollectBootInfoProtocol +8CD89386-C897-3098-9687-C46A5B7DEC05,AmdCpmManageabilityDxe +8CE0E1E9-26DC-4F24-ADBD-6871B8223703,PciSdxcDxe +8CE65FC0-8F33-42A7-A2EA-46DEBE231EA6,XhciDxe +8CE8BC38-805D-442D-8DB0-479275CB1BF2,SystemErrorLogDxe +8CF2F62C-BC9B-4821-808D-EC9EC421A1A0,EfiPartitionInfoProtocolGuid +8CF6052D-8153-435F-ABA4-114B6A3FB53D,DellAhciSmm +8CFADE70-1806-440F-FFFF-FFFFE7CB5DA6,XnotePlatformPolicyDxe +8CFC5233-23C6-49E3-8A2D-7E581AB305BA,EdbCfg +8CFDB8C8-D6B2-40F3-8E97-02307CC98B7C,EfiVariableIndexTableGuid +8CFE04F2-027A-4BA0-A034-6CEC64865B24,SecureBIOCameraSonix +8D05A3A8-8464-4230-8A9F-C3EB968296FA,FmpDxe +8D07B6FB-3C1A-4AA9-A736-7039C8529BDD,PciDeviceInfoDxe +8D12E231-C667-4FD1-98F2-2449A7E7B2E5,EfiSmmControlProtocolGuid +8D1933CD-E806-4D83-9F9D-FF10E64D76D5,ISL95856Pei +8D1AE715-7F82-449D-A26C-62AC650AF73F,Int15PanelType +8D1F8D27-31C2-4B5B-B736-4BB5B4A25FBA,ASRGetDLSiteWrapper +8D1FB8C0-D28A-45A0-AD3C-73ECB9DC114C,FjDmiBoardBiosInfo +8D22D303-69D5-40C9-A71E-5C38C951FC18,LegacyUsbIrqSolutionWADxe +8D247131-385E-491F-BA68-8DE95530B3A6,EfiSetupVariableDefault +8D25EF2C-2015-416E-B8AA-2369FECD4BDA,CTA9x4ArmVExpressLibSec +8D3113BD-4D86-4186-8D2B-24569306E598,KEMhLpcDecodePei +8D3168FD-8CD5-4B35-9AA0-3C964D4CC14A,RstVmdDriver +8D32716A-60DF-4BDE-8647-3D178CC82B6C,DellMePlatformConfigDxe +8D33AA3A-AC58-4C2D-9966-F18AB8C11393,LegacyUsbDxe +8D3BE215-D6F6-4264-BEA6-28073FB13AAA,ChipsetSmmThunk +8D3BE215-D6F6-4264-BEA6-28073FB13AEA,SmmThunk +8D44C8C2-80E5-49E7-BC12-AE089E48FA42,AmiTsePkgTokenSpace +8D463051-692F-4924-9AEC-0A833B1BA49B,PxeRomAr8132 +8D46CE70-B62D-4CF7-875C-BEC8016D7D01,DellTcg2ConfigInfoTpm12 +8D48BD70-C8A3-4C06-901B-747946AAC358,EfiIsaHcPpiGuid +8D4A8276-1994-4E82-983A-A71753617797,menu_checked_selected +8D4EF3A5-8958-405D-98C4-ED91B71583F5,H2OEventLogConfigManagerDxe +8D59D32B-C655-4AE9-9B15-F25904992A43,EfiAbsolutePointerProtocolGuid +8D59EBC8-B85E-400E-970A-1F995D1DB91E,IntelSnbGopDriver +8D5EA70B-02EB-48D8-BEAB-459778C5DE1F,SmmConfidentialMem +8D658AF6-178B-432B-9692-ABE717D9BDA8,FchHuashanDsdt +8D6756B9-E55E-4D6A-A3A5-5E4D72DDF772,PciHostBridge +8D6F1ADD-45A5-45A8-8BB8-0C3A953148FA,ReadyForLockProtocol +8D7AE6A9-B490-45E1-8795-C2BEAADC3814,RawIp4Rx +8D7F9B78-FE02-41F7-B515-0841C429654B,WiFiSupplicant +8D91A3ED-9040-46E0-8248-FBBE3F2BE808,ErrorLogPolicyDxe +8DA47F11-AA15-48C8-B0A7-23EE4852086B,A01WMISmmHandler +8DA5D50B-A39C-4FF7-AB4F-7426A145D0E4,RandomNumberGen +8DAA8C2C-5E2B-4158-8ADF-5FACFC0E9B77,AcerLID +8DAC5195-3FD5-4E32-9C2A-1A65BD699932,AmiTseOemPortingVar9 +8DB6415E-1C83-4E8C-BB14-5560B58FC844,EmulationEDID +8DB699CC-BC81-41E2-AAC6-D81D5300D759,PartitionVariable +8DB954AD-047A-459A-AC0F-F3758779F61A,DellMfgModePei +8DBBB229-87E3-4CBC-B2F7-6A54C830D166,HpCableDetect +8DC58D0D-67F5-4B97-9DFC-E442BB9A5648,tftp +8DCE1957-D774-4FDA-B90F-0B231CB2E0CC,DellSmmServices +8DCEEEBB-5741-4092-884D-144EC472682D,PrmAddressTranslateModule +8DD46B11-0403-4B4C-B372-7041CB151834,DellFlashUpdate2Pei +8DD9176D-EE87-4F0E-8A84-3F998311F930,Dhcp6Dxe +8DD9176E-EE87-4F0E-8A84-3F998311F930,Dhcp4Dxe +8DD91798-EE87-4F0E-8A84-3F998311F930,ArpDxe +8DDE1037-94E5-4B84-8611-279A004BA8F5,PspP2Cmbox +8DE287AC-9460-465C-B8FA-F6E9866AE56D,xgbe_atl +8DE29E5A-BABA-4696-B07D-33E83D5AD811,CbsBaseDxe +8DEEC992-D39C-4A5C-AB6B-986E14242B9D,EfiDiskInfoSdMmcInterfaceGuid +8DEFE6CA-2AF0-474E-9642-838282B3C982,BiosAuditLogHandlerSmm +8DF01A06-9BD5-4BF7-B021-DB4FD9CCF45B,EfiHashAlgorithmSha224Guid +8DF39C0E-8170-4415-B7B3-DA2613B51046,EarlyGuidHobPei +8DFAE5D4-B50E-4C10-96E6-F2C266CACBB6,VideoRom +8E008510-9BB1-457D-9F70-897ABA865DB9,EfiLegacyBiosExtProtocolGuid +8E09C390-1B30-415E-AF5C-D42AB0160F8C,AmiCbsDxe +8E199D3F-3A74-492B-8CB3-93D668D87D07,IsRecovery +8E1F3306-C9CC-46E6-83BC-5928B0DD036E,OpalDeviceService +8E201427-463A-4D24-A0F4-25A875F61BAA,DellModBayConfig +8E21ADB5-0B93-465B-BE61-1725DE06C2AC,EXT +8E3119C0-F712-4E67-94DF-6F8EFBB60685,PlatformSetupMainInfoDxe +8E325979-3FE1-4927-AAE2-8F5C4BD2AF0D,SdMmcPciHcDxe +8E38A88A-C267-4131-A8CD-C0BC80A24CB5,CbsSetupDxeSSP +8E3C826C-B69E-4F56-95AB-1324DD02E28B,StdBoardPei +8E4318C2-599A-435B-BC14-D9C9FA4172CE,AmdMemChanXLatDxe +8E46DDDD-3D49-4A9D-B875-3C086F6AA2BD,EdkiiVt400 +8E477676-55FD-48CF-9210-15A99B27D740,Slp10 +8E47929C-C80E-40CE-B013-807FEFC94110,IntelGigabitLanDxe +8E55BB3F-1148-4EA5-BDB6-425E4584FF78,DefaultUpdate +8E57AE62-99DC-4F12-ACB7-216E2DD031AD,DxeCrcInit +8E5C4BEA-34FF-4E32-8358-3363DA01E628,LenovoSystemXhciResetSystem +8E61FD6B-7A8B-404F-B83F-AA90A47CABDF,SmmSmbiosElog +8E6553E6-A152-4A6A-96C6-016FEDC3495E,AmdPlatformCustomizePei +8E68E3C5-FC59-4280-8467-3800D31A8162,IccOverClocking9_5 +8E6FEDCA-62B4-4E8F-8C42-9B8F40EF60CD,HpCallbackRegistrationDxe +8E724EB4-F314-497A-84F3-367A47E60910,DellIoExpanderDxe +8E74A1A7-8A76-4D29-9441-3C176018CB9F,SmbusSmm +8E74EFFB-C02A-4320-81F1-4B1114D10910,IntelPpiLayoutLoadPei +8E83304D-5BF1-454B-B111-AC574A5121E7,AsusMyAsusDxe +8E88BF4D-9F15-4206-BBD5-55D368B62AD1,NvmeRecoveryDxe +8E8CBC58-834C-41E3-B8CA-F00CCF5A717C,IccOverclockingProtocol +8E8FB93D-6F87-4CF8-9A9E-DF5B898D223A,MaintenanceLed +8E973F83-ABCA-49E4-A940-4EAD5A6D8A1E,LenovoNationalLpcPc87393 +8E9A984C-57E7-4BEB-A62B-58982E0620F1,DellNvmePwSmm +8EA278A7-90B8-455F-BE18-23172EAC6068,HpDigitalSignatureVerificationNotInSmm +8EA278A7-90B8-455F-BE18-23172EAC6069,HpDigitalSignatureVerificationInSmm +8EAD4DEF-45E8-4F6D-96AB-E5BC991D2F69,BatteryInfoSmm +8EAE69C2-4079-4B0D-B075-8BA0653A432F,NetworkStackOverridePei +8EB0B9CB-367F-43EB-8E99-3A192CD4F7F3,CrbSmbiosType0 +8EB48F19-CC92-4031-8D3D-EE473CCC87EB,SystemPrivateKey +8EB7B229-27E3-4FBC-B9F1-3A245B3AF1D6,HpCableDetect +8EB9B46C-8F80-4E6A-9FBF-EC892FBA2807,SmmAccessPei +8EC24268-E545-4242-B536-04F94C889969,BoardUpdatePolicyDxe +8EC38829-A59F-40E3-BAD0-85F815A157D1,DellServiceResetSmm +8EC40FB3-4205-4D57-9039-A192832C7CED,DellEcConfigDxe +8EC41824-6658-4B55-9364-771A0658F5E2,WarmResetFlagShell +8ED29AC6-D6AA-4FE8-ADC5-B7E58791A013,DellSmmPowerOffProtocol +8EE41730-CD91-FE40-A83A-F60F1ECB492D,IcnsConvert +8EE54DF3-FC96-40ED-A1CA-3A1B265F9528,ProjectPei +8EE7D3BA-FA46-4C15-A8C7-DF18B3DA43CF,SystemSecureVariableStoragePei +8EEF9AD2-463E-425F-A4FE-2F6783D6F97E,GenericSio +8EF61509-890B-4FF2-B352-1C0E9CDDEC8B,I2CLibPei +8F0B5301-C79B-44F1-8FD3-26D73E316700,PowerMgmtSmm +8F163A88-2376-40B3-89F7-AAC73E29E941,HpRemoteDiagnosticsDriver +8F1A65CF-1D27-4354-9F77-4DB764471B4A,AmiOemRasSmm +8F1AC44A-CE7E-4E29-95BB-92E321BB1573,SecFspWrapperPlatformSecLibSample +8F2156F2-887A-4BA8-BEF9-005C16293B7A,AmiMemoryInfoSample +8F26EF0A-4F7F-4E4B-9802-8C22B700FFAC,EnglishDxe +8F27C2A7-A8FB-4645-ACC7-DAF4C80C4F95,DellODMDxe +8F2C127E-117D-484B-8A44-FBD911BE125E,IpmiRedirFru +8F3D37B9-B955-4320-97F6-BE359DE9E3B2,HpPlatformInfoDxe +8F3F1DE2-2FE4-4D5C-A8EC-49E8CCA17EBC,RsdpPlus +8F439D8B-07B2-4121-AA95-8AC91571AA75,DellErrorHandlerDxe +8F439D8B-07B2-4121-AA95-8AC91571FFFF,DellDefaultBootListDxe +8F4B8F82-9B91-4028-86E6-F4DB7D4C1DFF,Bds +8F4CD826-A5A0-4E93-9522-CFB0AB72926C,SataController +8F5572A4-6BF9-4A27-B8B8-85282E0C9C14,AmiApcbSmm +8F5A2E02-538C-4D59-B920-C4786ACBC552,Ahci +8F5C2D02-AF2B-49DE-B8D8-DF90130A2512,FlashMeDxe +8F644FA9-E850-4DB1-9CE2-0B44698E8DA4,EfiFirmwareVolumeBlock2ProtocolGuid +8F6F4178-E25F-442C-B54F-D805205EA3FF,DellXhciSmm +8F7170F5-419E-D3AE-B045-7FB5D199BDA5,AmdSocAm4RnPei +8F76DA58-1F99-4275-A4EC-4756515B1CE8,EfiBluetoothLeConfigProtocolGuid +8F7D7B1D-0E1C-4C98-B12E-4EC99C4081AC,EmptyApplication +8F7E1A3A-9657-44F0-B9E6-4EF74B22D543,EfiTraceHubDebugLibX64 +8F7F3D20-9823-42DD-9FF7-53DAC93EF407,CsrPseudoOffsetInitPeim +8F87955A-85EC-4826-B4FE-173B914AB383,XhciSmm +8F8B0266-C275-411A-87EC-AAD81EB1F026,FjMfgPowerOffDxe +8F8EB724-139E-4A32-A3D0-F7D376E5B908,RecoveryDeviceMap +8F92960E-2880-4659-B857-915A8901BDC8,Ip6Dxe +8F92960F-2880-4659-B857-915A8901BDC8,Ip4Dxe +8F9296EF-2880-4659-B857-915A8901BDC8,Ip4Config +8F98528C-F736-4A84-AAA3-376A8E43BF51,ImagePasswordEmpty +8F9D4825-797D-48FC-8471-845025792EF6,EdkiiS3SmmInitDone +8FAAD0A7-02B4-432F-8F5C-B880965D8B41,SmmCommunicationBufferDxe +8FB38CF8-D25D-4855-8F15-C07A0F6B8EA7,BiosReservedMemoryInit +8FB4CD1D-0660-466E-8ED0-AD723FD7DBAE,AmdNbioAlibRPLDxe +8FB82DA4-C3BE-42A6-8A70-7B94D60972A6,DellSbAccessSmm +8FBECFE2-1313-4CF6-AD2C-D3B9472F62D3,SmartTimer +8FC1FDD4-3876-449B-A41C-6A788495FC78,BiosAttributesMgr2Dxe +8FC6AAAA-4561-4815-8CF7-B87312992DCE,UserAuthenticationSmm +8FD1935A-6A80-4535-B714-C3CBE45A5C5C,PeiSerialTextOut +8FDB0B2D-996F-4C1C-89E0-C32E6DCE6CA6,AmdPspDxeV2Brh +8FDC888D-2162-4971-81C2-35D3A1AA5047,EfiRasMpLinkProtocol +8FE545E5-DCA9-4D52-BFCD-8F13E717015F,AmiReflashProtocolGuid +8FEEECF1-BCFD-4A78-9231-4801566B3567,AbsoluteComputraceInstaller +8FF4D380-8891-4495-AF40-716CD55C07E8,LEMPostLogoDIYDxe +8FF5354A-634F-4637-B3CE-4DF1CE6B56FE,RtkUndi8111H +8FFA88FB-4395-F6B4-0525-93FF277A6215,IfwiId +9006872D-3A86-4BAE-A2F0-E527B9D7119E,IntelLanUefiDriver +900901B9-41CD-4D54-A842-4D559980960B,AmdCpmThunderboltPeim +900C2FE6-679F-4B93-B656-25136FA93946,SelfhealingSupportShowInSetup +901E524A-5A57-4C2D-93A4-74F516E07C07,ClientronServiceDxe +90253CDA-4E1F-4CD6-9EA4-276F8725BDD0,SwSmi534D3320 +9029F23E-E1EE-40D1-9382-36DD61A63EAA,NCT6686DPeiInit +9029F23E-E1EE-40D1-9382-36DD61A6791D,NCT6791DPeiInit +9029F23E-E1EE-40D1-9382-36DD61A81866,F81966PeiInit +903718F3-575D-4D9C-BC78-65A11381A026,DellImgSrvBaseRom +903AF10A-BDE0-46CE-A061-8DBFF2D24269,Kb902xFlashDxe +903B2AC9-F6BF-4397-A4AC-2DC8FBEE30A3,DellHddScp +903BD9EC-1E93-43D6-A1C9-B6AB65AC9270,RtkUndiDxe +9042A9DE-23DC-4A38-96FB-7ADED080516A,EfiGraphicsOutputProtocolGuid +9044434C-40E8-47A1-A3BA-8507F3C0E256,CpuUncoreTokenSpace +904C7B88-70CF-4557-9023-85AA2153AAF0,AsusControlCenterBios +905064E0-F09A-4FCD-8780-3F10D8F0126C,FchPromontoryPlusGpioSmmInit +905CE085-E8B7-476F-B1E0-63C6A4583B5B,HPOA3Dxe +905CF1B3-32F8-489C-A641-46A714583262,PcieErrorEnable +905DC1AD-C44D-4965-98AC-B6B4444BFD65,UfsPciHcPei +905F13B0-8F91-4B0A-BD76-E1E78F9422E4,UdfDxe +9069C144-0A7E-41EF-9C07-418BCA9BF939,AcpiDebugSmm +907125C0-A5F1-11E3-A3FE-A3198B49350C,FvSimpleFileSystem +907303D5-394D-4E7C-A430-7B6A764BDC3C,AmdNbioPcieDxe +9073E4E0-60EC-4B6E-9903-4C223C260F3C,EfiVendorKeysNvGuid +90766A99-9CA5-44DE-94DA-DCC1D2D6DA1F,UsraPpi +907AB054-712B-41BA-930F-2BBFB7F57ECB,DellQuickSetSmm +907AB576-C955-4A95-AE7E-596D2256CC61,OverrideGetVBiosVbt +908C3852-B61B-4F26-AB66-F74F97E7DC1C,AmtBypass +9096EB5B-59D1-49F8-866C-78D24631A6B4,EndOfDxeBeforePciEnumEventGroupGuid +90A06ED8-D514-4CC5-B11C-7743BEE24C55,AmdSocAm4RvDxe +90A330BD-6F89-4900-933A-C25EB4356348,SDController +90B2B846-CA6D-4D6E-A8D3-C140A8E110AC,SystemFirmwareDescriptor +90BD1EF6-F66A-4B4A-9879-B0701B99BC3C,NbBrhRouting +90BF2BFB-F998-4CBC-AD72-008D4D047A4B,PeiTbtInit +90C35CC1-C3A5-4F48-9AE6-922FCE6D827E,LnvWlanPxeBoot +90C5A43A-8513-4695-AF0B-F4AA7FCFB898,TouchPad_Sensel +90C8D394-4E04-439C-BA55-2D8CFCB414ED,SataDriver +90C9751D-FA74-4EA6-8C4B-F44D2BE8CD48,FmpDxe +90C9751D-FA74-4EA6-8C4B-F44D2BE8CD4B,FmpDxe +90CB75DB-71FC-489D-AACF-943477EC7212,SmartTimer +90CBFE5B-9784-44A4-8CB8-C640AEB9EA1C,DellSystemUsbPortConfigSmm +90DADB68-B868-4D62-A07F-09B3B64DA039,Mebx +90E01103-F784-4020-91AC-C51E8BF553B2,LenovoWmaPciDxe +90E2AE43-90AE-4679-6EDF-BEA81D4DC8AC,HpRtcInitPei +90EC2C4D-28BE-4726-AF9B-94BC6CBE17F2,NearTdpLockOcPeim +90EC42CB-B780-4EB8-8E99-C8E3E5F37530,UefiPciLibPciRootBridgeIo +90FAE0B9-AC26-4482-B532-9BED052A8F8B,VmwVariableDxe +9100696B-368F-4F9A-984A-D606E578CCC1,SetupConfigUpdateDxeLightningRidgeEXRP +9104D81E-05B6-4754-A2DE-7DB342FE5496,DellAcpiSharedMemDxe +910A077B-4B23-40FF-8DCD-64685349310C,SoftSkuStatus +910CC93A-F2B7-4630-884D-625D570FACF6,IshCapsuleDxe +910DCA07-1F94-4EE7-AF2F-FF72F3154353,EfiSmmBaseHelperReadyProtocolGuid +911A3B22-8301-4CD8-835B-CC70826D5829,AmdiGpuVbsWA +911D584C-35F7-4955-BEF9-B452769DDC3A,DebugSupportDxe +912740BE-2284-4734-B971-84B027353F0C,FspHeaderFileGuid +912C464D-DDBF-43C0-B725-F1F61EA42875,AmdCpmOemRnInitPeim +913D8F08-0130-4E85-B58E-389CA566C1EC,DellDeviceDetectionDxe +913FA238-7B16-4B72-A5F0-815E7D2C8C1F,AmiTseOemPortingVar24 +9140CA7B-CABD-4A09-88F7-0862043CC286,DellSmstTransfer +91472655-50E0-4D81-9AF6-239E6F431B8C,H19StartupMenu +914AEBE7-4635-459B-AA1C-11E219B03A10,EfiMdePkgTokenSpaceGuid +91538AC9-A5D3-4DEF-9A70-28A087DEFA79,AppleDataHubUpdate +91574965-A7EF-4DC6-AD6A-5356CC21C500,DellBootLayerDxe +915CB605-0E96-4C75-B724-53DCBAE7ADB5,DellDxeDiagLeds +9168384A-5F66-4CF7-AEB6-845BDEBD3012,PlatformFlashAccessLibDxe +9173C39B-08DA-429A-BE15-0F7481CF72CE,AMTLockUsbKBD +91797A08-B861-49A6-A271-7ECA11D79025,MemTestPei +91812ACA-332D-4215-B832-45C88FC7DE57,DellDptfChipsetPei +918211CE-A1D2-43A0-A04E-75B5BF44500E,EfiCPTokenSpaceGuid +9189541F-AC0C-4368-9062-70E1957C3445,EfiVirtualLockstep +918AB56A-365D-4EF5-B712-45994FCDDE57,OdmEmDellSMBiosUpdate +918ABA30-3D8D-4BB5-B849-45CC4FC7DE7C,Dptf +918ABACA-3D8D-4BB5-B832-45CC4FC7DE57,DellDptfDxeLoad +919B9699-8DD0-4376-AA0B-0E54CCA47D8F,FPVARIABLE +91A1DDCF-5374-4939-8951-D7293F1A786F,EnhancedSpeedstepProtocolGuid +91A44D23-5DCC-4425-91E6-42DA61640BA7,AsusBootDeviceSkip +91A737E6-7B54-4B5F-A491-ED5EF5C5A732,LastBootErrorLog +91ABC830-16FC-4D9E-A189-5FC8BB411402,AmiSmmDigitalSignatureProtocolGuid +91AD7375-8E8E-49D2-A343-68BC78273955,HddPasswordPei +91B43F81-DFCA-4EBA-93E1-FAD501E8F6D2,AmiScceMMCEnabledPpiGuid +91B4D9C1-141C-4824-8D02-3C298E36EB3F,SataDriver +91B886FD-2636-4FA8-A4A9-2EB04F235E09,CpuPeiBeforeMem +91B9F3D6-7AF3-450A-869D-3B30D0C96E62,DellAbsoluteDxe +91BA201E-1621-46FC-825A-B0363ECAD4BC,DellPbaFpDxe +91BAC015-3A26-40FF-9F3E-C3F4FE9D24F9,SystemSmbiosAddedValueDxe +91C74E50-361D-4CDA-A16B-C92BE4BF16EE,AmiTcmSignalguid +91CE67A8-E0AA-4012-B99F-B6FCF3048EAA,ArmScmiClockProtocol +91D1E327-FE5A-49B8-AB65-0ECE2DDB45EC,EdkiiDynamicTableFactoryProtocol +91D211BF-37C2-495A-8DF7-9546BD2555C0,PpamPlatformSmm +91D34812-236F-4B8B-B527-27F96A0CC3DF,MTKWiFiDxe +91E7996D-7681-477C-BDFE-AD11447E66CE,RealtekLomSmm +91EFC190-DE79-441F-B57F-BB0F7D8A8B4D,FjM2WlanEnableDisablePei +91F6E9EB-9902-44B3-A487-C8E148D0F4EE,EmcaErrorLog +91F72280-36CC-4BF3-AC40-BC029E4B3177,inf +91FB89E6-F282-49BC-AC80-275E50B7B298,XnotePlatformPolicyFsp +9204A71D-2050-4AB7-AD42-749CF9ADB4EB,Lpc47N20x +9205CDE5-5AE5-4A4B-BFBF-F6211967EEF9,LibLocale +9210E52A-729E-4817-85C8-F45500CE24C6,PchLpcSmm +921165A1-8D72-4451-9FF6-EAB508C319AB,OemSmbios +9219007F-D094-4761-9EB5-C14CF9D716C0,FlashInfoPei +921B35BF-0255-4722-BF5A-5B8B69093593,IchInitPei +921C9FE6-81F3-423E-B1C2-E92815054B60,CrbModernStandbySmm +921CD783-3E22-4579-A71F-00D74197FCC8,HeciSmm +921CD783-3E22-4579-A71F-00D74197FCC9,SpsSmm +9221315B-30BB-46B5-813E-1B1BF4712BD3,Defaults +9221BC02-8F2E-4CCA-BA89-EA6F91A4175E,CsmLoader +92299EAF-6692-485D-AE2C-CD077897408B,LenovoMailboxSmmProtocol +922DBE2C-528C-4484-FFFF-FFFFCFDAD219,XnoteSystemPolicySmm +92504A36-247E-4E21-A80C-72FE49FA638D,BrightnessHardwareVbiosAtiSmm +9257B1B6-82DF-4B69-A83B-C16D671B9A9F,ScreenCap +92604CDD-239F-4663-97DE-AFEAD4D95AB0,FjIbvTraceAbstractionSmmProtocol +92685943-D810-47FF-A112-CC8490776A1F,CORE_PEI +926C9CD0-4BB8-479B-9AC4-8A2A23F85307,BaseIoLibIntrinsic +927AE345-BB7B-434F-8D29-71BE0D12AB2C,AmdFabricZpDxe +927D36AB-C278-4EC5-B2F3-8BAA4B8E1F34,FjGabiSystemDataEventLogAbstraction +9282ED2E-F8CE-CA47-AF50-3542332F7D53,AppleDnsResolver +92854555-35E8-4AB2-B0E2-CF56C9F4DE18,AXUsbUndiDxe +928939B2-4235-462F-9580-F6A2B2C21A4F,QemuAcpiTableNotifyProtocol +928EF6D4-72BC-4686-B57B-1EEB6ABD4F93,AcpiReset +929189C9-0670-4C0B-AF7D-135D1550C8C0,RecvDgram +929E8A68-0FB6-4F20-AC5E-D294C50B1CBB,TcpConnect_DXE +92ABFB76-D724-4585-A513-EB5FF3EB1C5D,AmdCpmSharedBPei +92AC65A1-8D72-4451-9FF6-EAB508C319AB,OemDxe +92B144D7-A2DF-481F-9BD7-8A7968638EB5,PcdRecoveryPreserveData +92B7896C-3362-46CE-99B3-4F5E3C34EB42,UniversalPayloadSmbios3Table +92BA9255-2819-4479-867A-1C58F072C5B2,TCG_MADriver +92C6033D-A685-BB41-AA2F-6F6E2CD374A2,AppleSmbios +92C78E4E-C994-4F9E-82AB-AF1DBA6858C9,DellSmmComputrace +92C7D0BB-679E-479D-878D-D4B82968578B,WdtAppProtocol +92D11080-496F-4D95-BE7E-037488382B0A,EfiStatusCodeDataTypeStringGuid +92D83572-3D44-40E3-8718-36446B3EBA2E,IdentifyAcpiTable +92E33939-A133-4C30-6E13-1165DA59A8A4,DeviceBlacklistDefaultsSmm +92E33E65-20F0-455D-9D71-02C09D5060AE,PciPort +92F7436E-7395-4DA1-A7BE-F352F0BCD79C,LibContainer +93022F8C-1F09-47EF-BBB2-5814FF609DF5,FileSystem +93039971-8545-4B04-B45E-32EB8326040E,EfiHiiPlatformSetupFormsetGuid +930C273B-A875-4713-9373-F12E8483E125,IntelGigabitLan_I210 +9310979D-A58F-413E-913F-5E9294D8ED2A,SetupCheckSumListInit +93145CD2-7B23-4516-BB23-E338CB2D2748,HddIdentifyDxe +9317EC24-7CB0-4D0E-8B32-2ED9209CD8AF,EfiPaddingRsassaPkcs1V1P5Guid +931E1E51-83DD-427F-B5E0-5F25E2C504A8,AdapterWarnings +931F5366-FBB9-4C2C-9362-B532CBEB4F66,ServiceResetDxe +931FC048-C71D-4455-8930-470630E30EE5,SmmPerformanceExProtocolGuid +932C56C9-EB98-43C6-8514-2EB8A31B5277,HpIOXAccess +932F47E6-2362-4002-803E-3CD54B138F85,EfiScsiIoProtocolGuid +93390241-7D4D-4986-8A06-D46C982F5ECD,CrystalRidgePeim +934CE8DA-5E2A-4184-8A15-8E0847988431,AmiOptionRomPolicyProtocolGuid +935405E1-2F8C-4A7C-A89A-336060C4B0D2,DellCoreService +93570BE6-3AD5-45C8-8FA6-9A8633E22D2B,DxeCallback +935D2F78-3A1F-4DE6-B28D-123A40DD2DEC,SmmGenericElog +93677DE0-9A9B-47DF-8674-60E76858AEAB,AudioSpeakerIdm +936A2417-D1FE-4BF3-974A-EC00CE20A064,PeiPostStart +936DADBA-EB50-458B-A896-C7A28C010398,ClearPasswordByRtcRemoval +93755C1C-BE15-4D5A-BF95-5F9753853CB6,FileSelectUIDxe +937710D0-EF10-42BE-92E1-8494722B17B5,DellDirtyShutdownDxe +937FE521-95AE-4D1A-8929-48BCD90AD31A,EfiIp6ConfigProtocolGuid +938302C0-7ACC-4193-8D81-D9717A4DBC24,FPPBA +93A599F2-6D82-4FCC-9970-49BB013D695A,OpteeRngDxe +93B80003-9FB3-11D4-9A3A-0090273FC14D,IsaSerialDxe +93B80004-9FB3-11D4-9A3A-0090273FC14D,PciBusDxe +93BA1826-DFFB-45DD-82A7-E7DCAA3BBDF3,SmmVariableWriteGuid +93BB96AF-B9F2-4EB8-9462-E0BA74564236,UefiOvmfPkgTokenSpaceGuid +93BBA9CE-F020-4740-8B4E-9ECCE3909CCD,AmdMemFp8StxPei +93C81A74-B648-4F7F-925E-E4A0CDCC776D,VlvInitDxe +93C95FC4-B741-4587-9304-1C5A2BE6F742,ApplePlatformSecurityPolicy +93CFC972-6B9F-4031-A542-C7299F126924,FjNuvotonNct6796Pei +93D4BED3-C6EB-41A1-9FDC-724FD3C5C13E,DellFmpDock +93E18521-9E52-4EEB-A230-7C24B2EC03E8,LenovoMfgDoneDxe +93E1BD6D-6CC6-4EFA-A047-3C1ED9E95F89,LenovoTpmConfigDxe +93E34C7E-B50E-11DF-9223-2443DFD72085,ArmVeNorFlashDxe +93F1025B-B6D4-4F2F-A4A9-A4ABA0CF604F,aDefaultDxe +9400D59B-0E9C-4F6C-B59A-FC20009DB9EC,AmiPciIrqProgramGuid +9401BD4F-1A00-4990-AB56-DAF0E4E348DE,AmiHddSmartInitProtocolGuid +94118D41-65A5-497C-90A1-9D78591C797A,AmdNbioPei +94223E4B-D03E-40CD-82D5-0443158B22F9,OemSetupScreenSyncVariable +942681AC-4F3D-46AC-9AEA-D4F25F21248A,FjMeFwUpdateOdm +942F8076-3335-4EF9-93CC-74A470263DDA,SetAutoUmaModeSmm +9437D7F5-6D31-4494-9A4B-F6EEB21B6CC3,SioScriptPEI +943D6B8B-D4D0-4005-81A0-AF26E5E07F03,MeFwLayout +94440339-CC93-4506-B4C6-EE8D0F4CA191,EdkiiNonDiscoverableAmbaDeviceGuid +944C14CC-3B44-4973-A8D5-EBE0B923F7D0,GPIOPei +94567C6F-F7A9-4229-1330-FE11CCAB3A11,AmiInternalUcodeHob +945A0C97-4882-410A-9F30-E31C99398F7B,DxeIchSpiDxe +94621F9E-B5CA-4CFD-82BE-0C542EB0D9BE,TftpServer +94710277-9396-45BA-8A47-534A5B46F391,ClearPassword +94734718-0BBC-47FB-96A5-EE7A5AE6A2AD,Dhcp4Dxe +947558B9-64EB-4764-9F74-5EDBEA0C7481,DxePlatform +94796E10-7CF6-4A20-A3A0-4CF1A8341A16,menu_dots +947B9E77-9231-449C-BED5-FD4051BD4E39,AmdSocAm4CznDxe +94813714-E10A-4798-9909-8C904F66B4D9,NvmExpressPei +9487D2AF-B394-4119-A981-CE133B11DB7A,BoardModernStandbyDxe +9487D2AF-B394-4119-A981-CE133B11DB7B,BoardModernStandbySmm +948FA1ED-F8D0-4ECA-81B4-194D8364CCF6,AmdSocSp6ShpPei +94925FB1-EEF4-41ED-BD7A-CDB04AAA81C7,DellSbAcpiConfig +949822BC-26D3-4BC6-954B-F2C581342DE1,SystemXhciDxe +9498F6C5-1B77-4AE7-A045-DBC29EB5541D,StatusCodeLoggerDxe +94AB2F58-1438-4EF1-9152-18941A3A0E68,EfiSecurity2ArchProtocolGuid +94B9E8AE-8877-479A-9842-F5974B82CED3,EfiBoardFeaturesGuid +94C0203B-54C9-416E-A6E0-47E8D4786901,EfiPeiPlatformTypeLightningRidgeExecB3Ppi +94C210EA-3113-4563-ADEB-76FE759C2F46,Tcg2MmDependencyDxe +94C69847-A0CF-4635-AA23-D2667BD7F791,SdioBusInitProtocol +94D02FCF-045C-45D3-B023-1A8B5CA5C70A,BIOSVer +94D411B7-7669-45C3-BA3B-F3A58A715681,EfiHiiFrontPageClass +94E24C26-80FA-427D-80FB-E374E9E9BF85,Dhcp6Dxe +94ED2946-24EA-11DF-AF40-4300B0D2BA57,LegacyMemoryAllocatorDxe +94EDD12A-419B-447F-9434-9B3B70783903,PlatformDxe +94EDD133-419B-447F-9434-9B3B70883903,ModernStandbyResouceCheck +94FF8FFA-65BF-4918-95CE-8141E487CA6B,PolicySampleDriver +950216A2-A621-479C-A13D-2990617BDFE7,ReadOnlyVariable2OnReadOnlyVariableThunk +950C3A26-E0C2-491C-B6B2-0374F5C73B96,SmmChildDispatcher2 +950E191B-8524-4F51-80A1-5C4F1B03F35C,PeiSha256HashPpiGuid +950FC066-ECC9-4BCE-82B1-BA7D68F44283,AplSmbiosGetFlashData +9511F0F0-833C-4DCD-A9E5-3CBE2393EDD5,POESS4CallbackBin +9516D89E-0A6D-4AF6-8C26-5526F11EE82E,BrightnessControlSmm +951B65E5-8872-41ED-AD1D-D5681F4AF033,EfiSpiHostProtocolGuid +951CCE35-A7D4-4905-89FD-FC9BC3B56B83,ClientCore +9524B339-5702-4D07-87E3-47ABA10E0C1E,SmbiosMemory +9527D62D-A1C0-44C5-A90F-A11687701127,PlatformInitPostMem +952821AA-EACD-465B-B478-5429DFC9A747,OA2 +952CB795-FF36-48CF-A249-4DF486D6AB8D,EfiTlsServiceBindingProtocolGuid +952EEE95-A6AF-43DA-A559-F349A46D710A,SimpleBootFlag +95367732-2D61-4A2E-A5B0-B8A143DC9303,ClientronDxeDriver +95409D5D-0A41-4258-8A99-810A22126BBE,OemSmbios +9546E07C-2CBB-4C88-986C-CD341086F044,EfiDebugSupportPeriodicCallbackProtocolGuid +954B4980-FF90-4B02-977F-91292251A3E3,DellAutoBifurcateBoardCfgDxe +954E2958-EBB2-4687-B98F-844DF4FAC63A,CompalSsidSvidDxeProgram +955C708E-B46A-488B-9D5B-D7E61D0F9609,SmbiosDataUpdateDxeEVB +9566132D-C678-484B-9B56-D4CF3F4F690F,MetroMsgDxe +956A2ED0-A6CF-409A-B8F5-35F14C3E3C02,EfiIderControllerDriverProtocol +9581983A-3663-46F0-83EC-8A0506EB63E7,BiosInfoChecker +9588502A-5370-11E3-8631-D7C5951364C8,AndroidFastbootApp +958AC2CA-9904-43AA-B9DE-35E5D4C41217,EfiOdmemGnvsAreaProtocol +95924E18-771C-42A9-B885-BEDDB60D2D38,LenovoSmmKeyboardConfigProtocol +95A1046F-5EA7-4C6D-86A7-AA91B7421E68,CspFlashPeiLibNull +95A7DF51-966F-499C-BCAB-9C2422C0D3D2,FchI3cPei +95A9A93E-A86E-4926-AAEF-9918E772D987,EfiEraseBlockProtocolGuid +95AF7E4D-C45D-47FF-AEB2-D9BC13466B3F,AppleAhciController +95BA4462-7EF0-49A3-9702-6896C39E414C,CbsSetupDxePHX +95BF86AD-A1E0-4143-B487-004B1C2E05FA,DxeCmosInit +95C051C5-F123-432E-9383-B9CF113F082E,LenovoTcgServicesSmm +95C3AB19-59C2-4418-A35F-CAB8724F8028,USRATraceLibNull +95C894B4-DAEC-46E1-8600-3C4C7FC985D6,BiosGuardRecovery +95C8D770-E1A4-4422-B263-E32F14FD8186,Ax88772b +95CC7C54-FB3A-46A7-BCB1-3D68AA2BE526,GnbDxe +95CCEFDF-EA27-455D-87D5-BC76CA05B871,AMTAutoProvision +95DE1CFA-71C6-4FB4-A538-6EEAF1DD3970,HWTopSwapFromECSmi +95DE95F8-A215-48C3-814A-40F07B925D24,AmdMemRestoreDxe +95DFCAE5-BB28-4D6B-B1E2-3AF3A6BF434F,PTID +95E3669D-34BE-4775-A651-7EA41B69D89E,Dhcp6Dxe +95E8152B-1B98-4F11-8A77-DB26583EBC42,AmiPeiSbInitPolicyGuid +95E89B6F-73DF-47E1-8F9B-DE52BDD37F53,OemPcdUpdate +95EB69CA-0240-49F1-B03C-D5F9C19C00B8,MeUpdateFaultToleranceDxe +95EBEE68-F645-4866-9BA9-51D3EEB3B650,FmpDxe +95ECB758-627E-4A2E-B7B8-DC863EFE3425,AmiDeviceGuardApi +95EF106E-469F-41D8-AFFF-CA5292A4D97C,AEPFreezeLockDxe +960241A5-5CE6-4EBF-B9C4-E37D294BEBA9,FspWrapperPeim +960C2719-4FDE-7E4A-44C6-26A6B2EFE9B2,SmmNvmExpressCsm +960CEA3A-20E6-4D33-AAAD-C9BD3CA5961D,TmeInitDxe +96107C8E-9490-4767-9D0D-5590F1F6E1FC,PhysicalPresenceDxe +961578FE-B6B7-44C3-AF35-6BC705CD2B1F,Fat +961578FE-B6B7-44C3-AF35-6BC705CD3B3F,MacMiscDxe +9618C0DC-50A4-496C-994F-7241F282ED01,PlatformInitPreMem +961C19BE-D1AC-4BA7-87AF-4AE0F09DF2A6,TrEEPei +96213700-AB86-4397-9D57-ABC7FE75478C,MpmMoselleDxe +9622E42C-8E38-4A08-9E8F-54F784652F6B,AcpiTableDxe +964E5B21-6000-23D2-9E39-01A0C969723B,SioIoProtocol +964E5B21-6459-11D2-8E39-00A0C969723B,EfiBlockIoProtocolGuid +964E5B22-6459-11D2-8E39-00A0C969723B,EfiSimpleFileSystemProtocolGuid +966DFABF-A140-4BBA-83CA-12021090BB44,DxeIchSmbusLightDxe +96735D5D-4595-4183-B1D7-934CC402AA95,ramdisk +96751A3D-72F4-41A6-A794-ED5D0E67AE6B,EfiCcMeasurementProtocol +967CFBD0-DF81-11EA-8B6E-0800200C9A66,FlashPei +967DF566-4DB7-3D52-39EC-1B9F450D5ACD,Sff8472Dxe +968BC767-031B-4798-FFFF-FFFF1EE81120,XnotePlatformInfoPei +968C1D9F-80C4-43B7-8CAE-668AA56C4E71,SmbiosPeim +9698CA50-54BB-4B43-B1CC-EC1338B7D767,Mec5105InitPei +96A1C8FE-4023-456D-9066-0D8DBB54B88E,FjGabiSystemData +96B5C032-DF4C-4B6E-8232-438DCF448D0E,NullMemoryTestDxe +96BDEA61-C364-4513-B6B3-037E9AD54CE4,SetSsidSvidDxe +96C35B25-319B-4ABD-9F6B-02ED49BCBD1E,GuiPwdPrompt +96C836D9-451E-47F4-B8E3-EA4CA2073857,FjMiscControlDxe +96CC2936-0E9B-4016-B6A9-BBCD3500A4E9,OemGigaLanDriverDxe +96D0626B-71D5-4001-AC71-E05B103BD45D,F10App +96D4FDCD-1502-424D-9D4C-9B12D2DCAE5C,MicrocodeFmpImageTypeIdGuid +96DED71A-B9E7-4EAD-962C-01693CED2A64,I2CPeiInitGuid +96E198EC-CDBC-4C21-9743-EB4577648E59,IccDxe +96E9CA61-6C2E-4FF3-B265-F21904C44181,CbsSetupSmmSTP +96EB4AD6-A32A-11D4-BCFD-0080C73C8881,EfiWinNtIoProtocolGuid +96F1AC24-2B21-45FA-A0B5-67010C95E9D8,AhciMmioSmm +96F46153-97A7-4793-ACC1-FA19BF78EA97,EdkiiPeCoffImageEmulatorProtocol +96F5296D-05F7-4F3C-8467-E456890E0CB5,EdkiiEndOfS3Resume +96FD1838-4496-4AE7-BE7C-8515296BFBED,HpDiagnosticsPortingSetupConfigSmm +9708ADB2-28B1-46F7-9A6C-E74497FA6679,EfiSdioProtocol +970B1E38-9701-47AA-88A5-566A9F232264,AcerGnvsSmm +970F9BDA-88FC-494C-9EA1-26419663CE11,SmmCf9Trap +97134844-245E-48AB-BE0C-07114F63C9E5,CrbPxePei +97159409-CE5F-4C1C-BDAE-7BD6981C2C11,SmcSetPowerStatus +97159409-CE5F-4C1C-BDAE-7BD6981C2C4F,SmcOpromCtl +971D0D87-78D1-4C65-A836-A420DCAC2028,DellAmdArchDepexDxe +9727502C-034E-472B-8E1B-67BB28C6CFDB,DebugAgentDxe +97276B3B-9FD1-4AC0-B8C1-D346DB4146F5,DefaultsManagerWmi +972F9755-D73E-4362-BF62-2AA56A8DA511,DellCapsuleUpdateWrapper +9737D7CA-D869-45E5-A5EF-75D9438688DE,PlatformGOPPolicy +973A0673-3AAA-479C-9746-DBD7DEAAA0B4,DellHotKeysPolicy +973BE267-0960-40C7-9856-FA73C92A46BA,DellServiceResetDxe +973D4FCA-7331-44AF-BDCC-FA0B13C43862,SmbiosUpdateDxe +97422AA1-855E-44B2-AEFD-905E0C8F4169,FjDtSmbiosDxe +974231D5-ED4B-44D1-8870-CE515CC14D68,FlashUpdate +9751D7BC-AB9E-4058-BB92-0A0582E02615,DellUsbChargerPei +9759BD61-F11E-4FEE-9004-1E8C88E72223,gear10 +97696D59-7430-4CD9-BC28-19C769FB04FD,DellHotSosPei +976C0B53-45E2-4D17-8328-8E8F5CA3002A,OobEthDxe +9776BECA-53D3-4735-C41F-4A74131E5822,A01TPMHookEntryPoint +977C97C1-47E1-4B6B-9669-436699CBE45B,SiPkgTokenSpaceGuid +9785929B-3DF4-47D8-BC0F-1A1F35B0F170,HhmPei +978D7247-98EA-4A14-BF98-32A35F34566B,AcpiPowerButton +978FD233-09A8-4FA0-98E2-D4B62C203251,WarmResetFlagOS +978FE043-D7AF-422E-8A92-2B48E463BDE6,EfiKmsFormatGeneric512Guid +979333C2-DF0B-48EC-88A7-88A7E6E5479B,FjSmbiosEventLogDxe +97A03375-250D-4C59-93A8-F76796725E18,AmdApcbRvSmm +97A0429F-3945-485B-8336-1C5274713F03,AmiPspPei +97A20DF5-6F57-4C76-9095-0F6439F8A81C,fTPMTisDxe +97AF1D95-203C-42DE-8D6B-D13EB7E5A55A,PEFirmwareUpdateDxe +97B1CDCE-AFBB-42F5-9328-1CFEFE912E66,IncreasePcieIdleFanSpeedSmm +97B4FA0C-4D7E-C2D0-678E-FB92E96D2CC2,NfitBindingProtocol +97B53FD2-A84C-4469-803F-A16D13AF1479,HeciSmmRuntimeDxe +97B5E066-4144-422D-AD2B-C31A6F6A1D2E,SmmOemDriver +97B97368-1831-434C-A9D8-A20440A91C48,Vmxnet2Dxe +97BAE479-C473-4424-9040-69F5BF9F74F8,OcrEntryCall +97BB442B-F9FE-45E3-8A28-439EEDCD1813,DualBiosPei +97BCA79E-2422-4EAD-A101-BACE644A5AC8,OemBadgingSupportDxe +97C81E5D-8FA0-486A-AAEA-0EFDF090FE4F,SerialIo +97CA1A5B-B760-4D1F-A54B-D19092032C90,DebuggerTerminalVar +97CC0EB1-CD3B-447A-9319-E3279ED02D51,ShowInSetup +97CC7188-79C9-449F-B969-065B64BF9C69,BiosExtensionLoader +97CDCF04-4C8E-42FE-8015-11CC8A6E9D81,Tpm2DeviceLibRouterPei +97E35ADE-233D-4F18-828A-8A0524EBEDDE,menu_none_selected +97E409E6-4CC1-11D9-81F6-000000000000,MiniSetupResourceSection +97E8965F-C761-4F48-B6E4-9FFA9CB2A2D6,AmiDeploymentModeNvGuid +97F81DD7-1D4D-47DA-9021-D2084AF325AB,DellTcg2PlatformDxe +97F91E78-EA12-4EA6-B7B3-7B0678C28673,AmiPeiPciTableInitPpiGuid +980BB149-F036-4449-BCF0-58C22207CBB1,FjNuvotonNct6796Dxe +9819ED2A-D201-3519-87DB-61C616E11507,FmpDxe +981A25E0-0D83-436D-9183-C1AA53B81438,ODMDiagnosticTestSmm +981A25E0-0D83-436D-9184-C1AA53BB143A,SmmOemServicesDriver +981A26E0-0D83-436D-9183-C1AA53B81438,SMBiosFunction +981AD9CD-8685-4AAB-AFDA-0512F74B65EA,SB900SmbusLight +981CEAEE-931C-4A17-B9C8-66C7BCFD77E1,SecurityFormSet +9826A826-004E-4197-B179-9F489AF1E3C9,SystemBoardInfo +982C298B-F4FA-41CB-B838-77AA688FB839,EfiUgaDrawProtocolGuid +982D8C6F-F6F6-4135-A309-A4593EA56417,AmiInternalFactoryTdcTdpHob +982DDBE9-2B79-485F-9AC3-FA67B508C913,Vmxnet3Dxe +982ECA04-0492-4AF0-9C6E-354A3BEAC9FF,HpCoreBootOrder +9842073D-95D9-9F49-BD3F-2E29525125DF,EmuBusDriver +984820B1-6D76-46C2-8146-25F245663D17,EmuPciPei +9848733F-B8A1-4B80-B548-D6C0A569C088,AmdPspDxeV2StxH +9851740C-22E0-440D-9090-EF2D71C251C9,AmiCmosAccessDxeProtocolGuid +98538A96-6116-4BE1-A609-BBCCCC2E0D15,VariableProviderSmm +98584C0B-49D6-4BAF-B542-ECEE2582409C,AsusBackupDxe +9859BB19-407C-4F8B-BCE1-F8DA6565F4A5,AndroidBootImgProtocol +985EEE91-BCAC-4238-8778-57EFDC93F24E,MainFormSet +9870A4C5-C65E-4D84-AE30-855348AF07C7,FjErrors2Screen +987555D6-595D-4CFA-B895-59B89368BD4D,IntelVTdDxe +9876CCAD-47B4-4BDB-B65E-16F193C4F3DB,EfiProcessorGenericErrorSectionGuid +9879341A-197E-4CF6-9BDA-48392F85045F,LEMProductTYpe +987EA6EA-FBFD-4273-B819-A7210ADF6760,StatusCodeReport +987F7795-E948-49AC-8366-FCC51A95D6E1,AsusABMSetupItem +9889665E-A0B4-4341-9711-2AB98252D282,FjUsbTypecPwrLimitCtrlDxe +988E6D64-D7F9-4EAB-84C5-29BF677A6DAC,PoweronFromKeyboardPortSmm +98948C4A-70F2-4035-8E9F-5927493CFC07,FaultTolerantWriteSmmDxe +989B6C1C-6FE1-D64E-A292-1313C410F0F2,Ip4Config +989D5548-AC40-45F3-ADF5-D05F94A891AE,EfiBmcLanProtocol +98A04529-1391-4FEA-AEED-2DCE76A63E14,DustFilter +98A4CA0B-7FE1-48B0-B68D-23EB0E259C13,ScsiPassThruAtapi +98AC0EEC-0F3C-4156-80A3-C9BB0C10ABC2,SmmPTDispatch2OnSmmPTDispatchThunk +98B29A61-827F-4A28-B1AE-3B00A978537E,OemPeiSetSetupItemPcd +98B5B58C-E2E8-4A06-AACB-E4CE316C2B68,DustFilterReminderDxe +98B8D59B-E8BA-48EE-98DD-C295392F1EDB,EfiConfigFileNameGuid +98BA1A5C-DAF7-451F-829E-698D08ABC065,FchI3cConsumerSPD5Dxe +98BBCDA4-18B4-46D3-BD1F-6A3A52D44CF8,SmmAccess2OnSmmAccessThunk +98C281E5-F906-43DD-A92B-B003BF2765DA,PeiNtThunkPpiGuid +98C5594F-9759-11E2-9F93-047D7B99E097,SecureBootService +98C80A4F-E16B-4D11-939A-ABE561260330,EdkiiCapsuleOnDiskName +98C8588C-640A-4BB4-AEA0-3F81CDE17524,FspDxeIpl +98CC7CBA-90DC-4A70-8EF0-2A66222886A2,EsrtConfigPreserve +98CF19ED-4109-4681-B79D-9196757C7824,EfiSocketMemoryVariable +98D8A754-8482-46E2-828C-BB632F34D9F7,DellHotSosDxeDriver +98DFFDDF-CE49-4049-87FF-ECCBD3C6C0D2,EcIoPeim +98E21F53-590C-43CE-99C8-637B6580A5DA,DellUsbExtSmm +98E419F2-4141-4004-BD7C-450D2B73E18C,H2OCryptoServicesPreMemPei +98EF6039-130B-4784-9125-B723128F1639,FjNuvotonNct5581Dxe +9901C780-3E33-4D18-B54A-CF7234AFDB50,DellPolicySmm +99042912-122A-11D4-BD0D-0080C73C8881,EfiWinNtMemory +99044EE3-71C1-4C63-B66F-254FABE353CA,RaidDriverPei +9905D167-3D73-4A94-835F-03AFA1656AE6,FjFextSmm +9906EC03-DD8E-42E4-9EC0-D33F77397266,OemWorkaroundDxe +99341558-39A1-42B9-A1B2-1CA4F1720F8E,AmiCommunicationPei +993E9ACB-288C-4788-87EA-09F7A15FD765,AmdCcxVhPei +99442FC3-1A01-40F7-95A0-D65427961581,DellOnboardNicDxe +994C5A88-FCE2-43E5-9EA4-2FABCB15301D,SmmStatusCode +9950A4C8-F315-4FCE-ADC8-E1BB61F1CCCB,PeiHeciPei +995188B1-9F96-11D4-87AE-0006292E8A3B,EfiAuthorizationProtocol +9951DD61-4EA0-4D47-F540-40B4E4453507,DellTouchPadHid +99549F44-49BB-4820-B9D2-901329412D67,IdeController +995C6ECA-171B-45FD-A3AA-FD4C9C9DEF59,EfiSpiSmmConfigurationProtocolGuid +995D96C1-6651-46B0-BF3E-83C017B43B1D,DellSmBiosStrucDe +9960E17D-FD1C-419A-9A90-3944542C67AE,PowerButtonSetupDxe +9962883C-C025-4EBB-B699-4EA4D147C8A8,AmiTxtTcgPeim +99649826-952B-4ED5-92A8-4ED69B717FE3,AaeonGpnvSmm +996B4E92-D1EB-4E35-B194-BF9E0C524ACC,AssetIDOnRecoveryModeDxe +996EC11C-5397-4E73-B58F-827E52906DEF,EfiVectorHandoffTableGuid +99796403-CF03-42EC-A817-7183411D79E2,PchSmbusDxe +997FB7DF-DB23-40ED-A807-9612D2F4A3E8,TopSwapRestorePei +99846A70-614D-4062-820E-2473E4E128E3,FchEspiCmdSmm +999ABACA-3D6A-82B5-B562-12CC4F33DE57,DellDptfExtraGnvsArea +999BD818-7DF7-4A9A-A502-9B75033E6A0F,EsrtDxe +999E699C-B013-475E-B17B-F3A8AE5C4875,EdkiiDebugPpi +99A1E3F5-0887-43C7-B00A-F14A646BC142,DellSbSmmHooks +99A45B83-0BFB-4C38-8835-D59571010103,MAPS_DiagLEDDxe +99A96812-4730-4290-8BFE-7B4E514FF93B,EfiGlobalVariableControl +99B0F38D-1F27-4F46-9F44-42D694722882,AmdCpmMemEyeToolSmm +99C062A1-A4DF-4E99-813B-C283E1EFE761,SbSocRenoirDxe +99C078B7-D7D1-4EE2-B585-CC64A309640A,FjEvte +99C20A37-042A-46E2-80F4-E4027FDBC86F,PlatformSmm +99CA20D6-3BF8-4E90-A430-C6FDCC5A8E80,OemRaidDiskInfo +99CE8846-DB18-4D9E-B3BE-8B96E1CD55CE,SioMec152xPei +99D5757C-D906-11E0-8D78-8DE44824019B,PchEfiRaidDriverExecution +99D6037C-D317-4AF0-B0D2-3959530E6B16,CollectPOSTFlag +99DF8490-F92E-4A45-8A3E-A80C85D32826,SataEraseDxe +99E06CA1-3779-48B4-8D0A-8A496230E10F,NetworkOfflineLockerSmi +99E275E7-75A0-4B37-A2E6-C5385E6C00CB,AmiMaskedDevicePath +99E7FEA1-9A6F-4D68-A754-30793B78A738,RasInit +99E87DCF-6162-40C5-9FA1-32111F5197F7,WebServer +99EF5934-7822-49C4-83A4-50C1AFBCBE00,MeCapsule +99F03B99-98D8-49DD-A8D3-3219D0FFE41E,Mtftp6Dxe +99F1AE6D-A4CD-43EF-9A85-B0FD4F6CC091,LegacyBiosPlatform +99F2839C-57C3-411E-ABC3-ADE5267D960D,OzmosisDefaults +99FAB6EA-648B-6EAC-3EEA-5A16EEA64C3E,A01UnlockPassword +99FDC8FD-849B-4EBA-AD13-FB9699C90A4D,CustomizedDisplayLibGuid +9A069A23-836F-41DF-AF02-F14BEC97DE72,FmpDxe +9A07118A-768D-449B-97D0-6ADC8F2B0244,CpuMpPei +9A08BC1A-7561-4A68-8875-C0977C91573C,NetBootUI +9A09E60C-50F2-4602-9248-1F29382DDF3B,AmdCpmAudioFeatureDxe +9A29BBE9-74BB-41D3-BCAE-6B086E0FE0C5,SmuV11DxeVMR +9A306620-F506-46C6-A095-30F75040AE79,SystemAhciPeimPei +9A44198E-A4A2-44E6-8A1F-39BEFDAC896F,EfiCustomizedDecompressProtocol +9A473A4A-4CEB-B95A-415E-5BA0BC639B2E,EfiRegexSyntaxTypeEcma262Guid +9A4E9246-D553-11D5-87E2-00062945C3B9,EfiStatusCodeDataTypeDebugGuid +9A5163E7-5C29-453F-825C-837A46A81E15,SerialDxe +9A54122B-F5E4-40D8-AE61-A71E406ED449,ChaosKeyDxe +9A55DA14-D845-4B3D-92DC-332143CC5C1C,HDAudioDxe +9A595246-6F53-4526-B856-3C0667F4DA67,LEMAllDriversConnectedEventHook +9A5F2711-B97F-4D5E-B111-265652D44587,WolPwrControlSmm +9A61F154-4A83-B8C5-80DE-239BFF40D66B,AmdRasDxe +9A6C1378-802C-4969-8C7B-85DFFBE82DF4,IntelPcieUndiDriver +9A6DC1AC-94C0-43B1-8714-4C70FD58A815,BaseS3BootScriptLibNull +9A6F58B2-7444-4EBA-8FAD-A033EF79ACDF,SecureBIOCamera_Sunplus +9A713C0D-2053-44AC-9D4A-E7933C4205A9,EcIoDxe +9A74B389-9607-4C99-BD57-A2E7D272DAE1,DellBootMenuFlashDxe +9A78788A-BBE8-11E4-809E-67611E5D46B0,EfiEventNotificationTypeSea +9A7A6AB4-9DA6-4AA4-90CB-6D4B79EDA7B9,HashInstanceLibSha1 +9A7EF41E-C140-4BD1-B884-1E11240B4CE6,PeiPlatformMemorySizePpi +9A83BECB-9354-482C-A316-E2ADE07D1ABC,AmdMemRestoreDxe +9A871B00-1C16-4F61-8D2C-93B6654B5AD6,FdtClientDxe +9A89909B-71D8-4E48-BD52-6BF2E65C0857,PlatformHiiAMDDxe +9A8D3433-9FE8-42B6-870B-1E31C84EBE3B,BootScriptExecutorImageGuid +9A8F82D5-39B1-48DA-92DC-A22DA8834DF6,MeSsdtAcpiTableStorage +9A9A912B-5F53-4586-8820-704485A29D21,MePlatformReset +9A9DA223-B117-4799-A070-4D2CFCB1C442,F75111PeiPkg +9AADE345-E064-4355-A815-874564DCA760,AccessPoint80211 +9AB047AF-C26E-4DBF-B468-27AC6536482E,TraceHubStatusCodeHandlerPei +9AB332EF-81D9-43D1-867A-03DD574E8566,DellBbsmanagerDxe +9AB86388-95F2-4F69-ACDC-E1749E5409F0,VariableCheckerSmm +9AB9A129-B8FA-4045-BB05-48DBCE724F82,HWMINIT +9ABCBDDF-A4B5-4FDC-93F2-52AE580A49CD,BootDeviceInitAttributeDxe +9AC8B567-5FDB-46E5-8B12-ACFC4B24C5EC,OemDataRegionRestore +9ACC38D2-959B-490C-90EA-723D9D902108,AmdMemAm4SspPei +9AD125EF-A62E-4B76-86CE-18252861266E,AsusWifiMtk +9AD981C0-735F-11E3-A4C4-047D7B99E097,SwSmiInterfaceCoreSmm +9AE51047-E0B9-4A50-9E72-84E359D20189,OpromUpdateDxeLightningRidgeEXECB2 +9AF1DA25-F06C-43BB-BE88-834550BF765B,DellGSetConfig +9B013FF3-31D2-4693-83E6-60FA0C73F0F7,CompalCommonHookSmm +9B048C93-3FB1-4F6D-8592-133E26F94FFD,DellStealthMode2Policy +9B0FF2C0-E245-11E1-8EFF-D0DF9A35C106,ChipsetSvcDxe +9B1531F9-FB32-49AC-A8CB-C78B11DC746B,RTL8153 +9B182CEE-AED5-4D95-B2A9-A2CF6CDFEAA8,OemAcpiPlatform +9B2031FD-5759-4E8D-8DF5-2DDE44797EBF,DxeFlipToBoot +9B243EAD-77D0-4354-B78F-70B39AA48F0D,SystemVspBcpSmm +9B2756FC-BB82-44D8-9F2B-BCFCA688E3C1,NvmeInfoDxe +9B32B55D-D4D1-4329-B787-5A027B0ACE49,FjSwitchOnboardLANControllers +9B3ADA4F-AE56-4C24-8DEA-F03B7558AE50,PcdPeim +9B3F28D5-10A6-46C8-BA72-BD40B847A71A,AmiTcgPlatformPeiAfterMem +9B4236D3-34E5-4E36-A7F9-0AC8B7705160,CnvVfrSetupMenu +9B4BACCB-55C7-40F8-8439-13E3EB729B3F,BATMonintor +9B517978-EBA1-44E7-BA65-7C2CD08BF8E9,EdkiiPlatformLogoProtocol +9B5E3ADA-8B4C-4262-9D08-B1AC2B6585C5,HdaBeepRltkAlc3146 +9B680FCE-AD6B-4F3A-B60B-F59899003443,DevicePathDxe +9B69E973-CBDC-4035-9AE8-EC9C7617FA28,LEMPostFlagProtocol +9B6EECF6-FBDC-4DB6-9562-D25F40D57661,MicrocodeLoaderPpi +9B72CEDB-ED9F-4462-8208-D8866F826ACA,HpCommonAcpiHardwareIdSsdt +9B75E867-2746-48BE-B706-B1B93A348693,AsusModuleToIntDxeWrapper +9B77CADB-2007-42B3-9B02-7CBC28F40273,AmdCpmPtZeroPowerOddDxe +9B8A0C3A-5186-4B55-89F4-CAFDE613DAB1,BootScriptHidePei +9B8AC1A1-F326-4905-A43D-E1CCC6DE6BC1,KEMrBootCnt +9B942747-154E-4D29-A436-BF7100C8B53B,Ip4Config2NvDataGuid +9B9BFDDE-E245-431D-97A1-EADE9F8F627E,ServerHotplugSmm +9BA1D976-0624-41A3-8650-28165E8D9AE8,BaseDebugLibNull +9BA21891-7E7D-4E94-B8DF-F4D2D320801C,ROMss +9BB08B63-7756-4D1D-B7F6-B9BC2371F33F,SioEasyCleanWmiSmm +9BB65D37-8CA8-4789-BE45-EE18536EE089,UsbOcUpdateDxeNeonCityEPECB +9BB6E29A-2272-426A-AB77-9B7FE5EFEA84,EfiPeiPlatformTypeHedtCrbPpi +9BB995EB-92EB-490B-B864-13B868A7953C,UsbPortControlPei +9BBE29E9-FDA1-41EC-AD52-452213742D2E,EdkiiFormDisplayEngineProtocolGuid +9BCEDB6D-13CA-473E-B605-8A47688729FA,ODMDXE +9BD36F4F-08DC-4EAB-8637-2BC1BD5E0D95,EfiRasClvTester +9BD4232A-E5B0-418C-9ABD-B0B8574F138C,EcStorageAgentPei +9BD56875-85E9-4510-9DC0-1F842608591F,FjGpioGeminilakeDxe +9BE4D575-B6F1-4AC6-91AA-E2A7376D5A26,ASRockHDAudioPei +9BE82016-23FD-4ECE-826A-55A683A25F0C,SioFlexIoSmbiosDxe +9BEA1D1C-D130-42FF-BBFB-1B9DA3933DDD,SecureBioXhci +9BEC7109-6D7A-413A-8E4B-019CED0503E1,AmiBoardInfoSectionGuid +9BF0A5F3-36DD-4CCB-B05A-8D70F6F78ADF,ExpansionSlotConfigPortingDxe +9BF253B5-B562-4EFC-9891-50B322BE766C,AddSmbiosForNFA765 +9BF467DC-DF4E-441D-8356-C3863D6645D9,AsusFMPDxe +9BFE0707-8174-4B8A-A5F5-556FB10E8843,RTCWakeup +9BFF300D-D647-480E-9FF3-2006D3D7CCC6,DellMultiDisplayDxe +9C080BCC-38EF-4F9F-BDC1-B2F5D11E9CB7,SyncSagVariable +9C0AAED4-74C5-4043-B417-A3223814CE76,ArmPlatformTokenSpaceGuid +9C0E458D-EAE7-1234-A3BA-3CE1CC335168,AmiHidServiceDriver +9C0E458D-EAE7-4191-A3BA-3CE1CC315168,HidKeyboardDxe +9C1080EE-D02E-487F-9432-F3BF086EC180,GenericMemoryTestDxe +9C109E5E-BF38-4A78-9CAC-43DE7E726F9E,AmiMemoryAbsentOverrideGuid +9C18BEE8-C612-4003-852F-D4F173D5F0C9,DellTcg2ConfigInfoCommon +9C1E8BCF-7072-45F4-ACC3-98700A0FC907,AmdUnbXvDxe +9C25E18B-76BA-43DA-A132-DBB0997CEFEF,WinNtSimpleFileSystemDxe +9C2A7FEC-B7F2-4BCF-90ED-FDDE21EB5C55,FjCrid +9C452F5C-6200-4AA6-8068-F44B4F36D41E,H2OKeyDescDxe +9C4D5E0C-1C12-4BC5-83D4-E671BDD61E40,DellServiceOsInterfaceSmm +9C4FB516-3A1E-D847-A1A1-7058B6986732,EfiEmuSystemConfig +9C53CE0E-0E9F-4F20-B1A1-150E4349D777,Tpm12PPILockOverrideguid +9C5835AB-E86D-48A9-95D0-3735B75F82F6,LnvAMDArmor3 +9C5F9A77-DB16-4174-8E30-AA0BE19BC1FE,H19EmmcSecureErase +9C5FA4C6-746B-40A3-91CE-EC045F9D3716,SmbiosRecoveryDmiEdit +9C72F7FB-86B6-406F-B86E-F3809A86C138,AmiSmmDummyProtocolRedir +9C76C900-1E8C-11E0-8766-0002A5D5C51B,L2X0CacheLibNull +9C799F08-212E-49A0-9CF1-C4FDB0130FCC,DellBeepErrorCodePei +9C7C3AA7-5332-4917-82B9-56A5F3E62A07,FspReservedMemoryResourceHobGfxGuid +9C7CCB02-9154-4864-9E4B-DC0487E37660,DhcpDummyDxe +9C82D2DE-1F8D-4496-A5B0-FCE7537F6ABC,FchHuashanMultiFchSmm +9C91D86F-DDA2-477D-B122-1660C585CB9F,DellCpldUpdateDxe +9C939BA6-1FCC-46F6-B4E1-102DBE186567,EfiAcpiDisDispatchProtocolGuid +9C98C00A-2E9B-4896-95C8-AC64358284E5,AmiDxeHashInterfaceguid +9C9E1444-A361-44F9-9888-F87517124B1A,SioSsdtDxe +9CA93627-B65B-4324-A202-C0B461764543,EfiPeiSmbus2PpiGuid +9CB0F5CC-B0F3-4ADD-8583-3C8AF6C00DE0,DxeS3BootScriptLibS3SaveStateProtocol +9CB2E73F-7325-40F4-A484-659BB344C3CD,SgxPolicyStatusGuid +9CB5D4AE-DE86-4622-A1D1-3BCAAB418FE9,IAxTblDxe +9CBA9D12-A029-4366-AB1E-172B81914757,OntarioGenericVBios +9CC029DB-E893-4B8F-9808-11155DC3B7AE,CmlComp +9CC55D7D-FBFF-431C-BC14-334EAEA6052B,SmmCoreDispatcherDxe +9CC767FB-683D-45F9-ADBA-1C7FC78BEED9,SmuV13Dxe +9CCA03FC-4C9E-4A19-9B06-ED7B479BDE55,EfiSmmPeriodicTimerDispatchProtocolGuid +9CCFE1AC-784C-463D-B145-396D7014D559,VideoInitPeim +9CDA2EF0-EBCA-499C-A193-95B468625528,EventLogDxe +9CDD2B26-2411-4637-BAEA-A1A8F197B1DC,AmdMemSh5Pei +9CE4D938-9C87-41D0-9E55-34923FAF8B4F,AmiPeiNbInitPolicyGuid +9CF0F18E-7C7D-49DE-B5AA-BBBAD6B21007,AmiCallback +9CF30325-DC5C-4556-A8B0-74215C5F7FC4,HeciPei +9CFBC2E6-2905-4C2A-81CD-36C58B2CB5DB,LenovoPasskey +9CFCACBF-3071-4533-944E-40EAE56AAE9E,ApobRnPei +9CFD802C-09A1-43D6-8217-AA49C1F90D2C,Mebx +9D09195C-EB6D-457A-907F-C0E0B3A97757,AsusGlobalVariable +9D0AE5C4-7282-4996-9633-C4CE9D9ADBAC,PlatformPei +9D0CEA63-745B-417D-BBA4-E5193061C907,DxeFrb +9D0DA369-540B-46F8-85A0-2B5F2C301E15,EfiTimeVariable +9D1A8B60-6CB0-11DE-8E91-0002A5D5C51B,ThunderboltNhiDxe +9D1E9E1D-B7BE-4AE4-B6A2-0B05544A4122,Mctp +9D225237-FA01-464C-A949-BAABC02D31D0,StatusCodeHandlerPei +9D311AE6-837B-41EE-907C-BA3A8766CE5E,SgxLateInitSPR +9D36F7EF-6078-4419-8C46-2BBDB0E0C7B3,AmiBoardSioInitProtocolGuid +9D37AFF1-A6AE-447F-915D-DF2C4466364B,MTKWIFI +9D4548B9-A48D-4DB4-9A68-32C5139E2018,Tcg2MmSwSmiRegistered +9D4EF6AE-7941-4BC3-B5EA-FF61ECC2FC17,HpetTimer +9D52C986-0B16-420A-8D4D-D2EAEB593DBF,AssetIDDxeProtocol +9D52E46E-F07E-44E8-9A90-F8576C91C211,BaseFspDebugLibSerialPort +9D58058E-C8DD-4A9F-B176-DFCB92354815,LenovoEn25Qh128FlashPartDxe +9D5EB938-9A44-4568-8192-C1563BEBAA01,LenovoIsscDxe +9D5FD24C-53DF-44AC-A336-B4879CDB29D9,AmdSpiRomProtectPei +9D60F495-DBF2-4B06-AFCA-F62C1C89647F,PasswordLockWhite +9D7A05E9-F740-44C3-858B-75586A8F9C8E,dbxVar +9D7AF408-64A3-4AF4-83C9-2D1095F700D1,CpuMpPei +9D81AC84-25F7-45CE-83D0-886EE0334398,MTKSupp +9D8243E8-8381-453D-ACEB-C350EE7757CA,StartupMenuApp +9D83F169-17C4-4E7E-90A7-6381A5C21831,ClientronSecureBootDxe +9D8964FD-9CF1-427E-AF66-80054E949DC0,DellSecureBootDxe +9D933189-EEE7-457C-981E-581C1A639FC3,AbtExtendedMessageProtocol +9D94D324-0D45-407D-9337-734CF92C0EF2,KeyboardConfig +9D994E6A-5612-4D9F-AE8F-45CE771D57EA,RTSCallbackHandleDxe +9D99A394-1878-4D2C-98E9-C16B8EC47933,DramSharedMailBox +9D9A39D8-BD42-4A73-A4D5-8EE94BE11380,EfiDhcp4ServiceBindingProtocolGuid +9D9F2522-242C-439B-A9AC-248DFE244639,FcclSmbios +9DA34AE0-EAF9-4BBF-8EC3-FD60226C44BE,EfiResetNotificationProtocolGuid +9DA54910-78B9-CBE5-725C-87E49C07471B,WtGetEdidDxe +9DAECAB8-AFB8-40D3-80CD-3545D5025DBB,CpuSmm +9DB1BC64-D6CD-4005-923F-94045B3F1F73,SecureBioFw +9DB2466C-4E61-49CE-9AFD-789AE72C8F5D,HpLibArchiveDriver +9DB4032F-F8B3-4758-B88E-124708BDB9C0,DellAutoBifurcateDxe +9DB72E22-9262-4A18-8FE0-85E03DFA9673,SmmCpuSync2Protocol +9DBD72F9-BDFC-4A4E-862B-331F91983234,SetupVarStructCheck +9DC0DDAA-56BD-447A-95CC-5180433110F9,menu_top_left +9DC1A3C2-EA96-4E3A-840E-9840A247F0A1,ThunderboltDxe +9DCACA24-81F8-43EC-91CA-25CC68F67583,AmdPlatformRasRmbDxe +9DD92425-6737-45CD-829C-1AC2CD20C873,LenovoAt24Rf08EepromPei +9DDF1845-E5CA-452B-B105-17C87FE293E0,SceBootOrderSaveRestore +9DE698D3-491E-4F9A-842D-0D9E9785AE18,PerfTunePei +9DF83401-C0A9-4FBD-BE58-986493837BE8,FjFlashMapSmm +9E039967-FB3B-4BE4-83AA-F72F309E481E,EventLogDxe +9E0C30BC-3F06-4BA6-8288-09179B855DBE,FrameworkBdsFrontPageFormsetGuid +9E0D9B8A-1D50-448F-8FC6-12F32218A346,IT889XPei +9E140B52-A636-4E66-A060-7DDE153B5E9B,HpTbtSetup +9E1CC850-6731-4848-8752-6673C7005EEE,FspInitPreMem +9E23D768-D2F3-4366-9FC3-3A7ABA864374,EfiVlanConfigProtocolGuid +9E278343-9BA3-4E8C-8D54-5DF04A99AFF8,AsusTCG2InfoSetupItem +9E2E1579-77D3-4905-AD14-4479BEC03DA2,IrqBoardInfoRvpM +9E37D110-80BA-4F24-B8FA-2A1D2539E513,EmulatedEepromPei +9E37D253-ABF8-4985-8E23-BACA10395613,OemSkuTokenSpace +9E40EBE8-52D4-4081-AB06-0DCA3464A4A6,DeepSmi +9E43E128-C74D-42F4-8C0C-4811674A17B5,EfiMonitorKeyFilterProtocol +9E498932-4ABC-45AF-A34D-0247787BE7C6,EfiDiskInfoAhciInterfaceGuid +9E53D652-D0E1-4906-A0CB-31685C32BFCC,DellNbEcPei +9E5628D5-ECD5-41A2-868B-99EB933A326E,AhciRom +9E58292B-7C68-497D-A0CE-6500FD9F1B95,EdkiiWorkingBlockSignatureGuid +9E5DAEB4-4B91-4466-9EBE-81C7E4401E6D,H2OFormBrowserDxe +9E625A27-4840-47CC-A6B5-1E9311CFC60E,Pkpub +9E6584F1-FB33-4BD0-922D-47E5B7F5DBF1,GMUXDriver +9E66F251-727C-418C-BFD6-C2B4252818EA,EfiHiiImageDecoderProtocolGuid +9E6A5868-6BC0-4F5D-BA8F-4874D31E41C9,DellUefiClass3ConfigDxe +9E6AB24C-F800-42B1-92A2-B352ACB97005,AutomaticPowerOn +9E702787-C760-4CED-BF46-EDC428F182EE,GopOverrideDriver +9E71D609-6D24-47FD-B572-6140F8D9C2A4,PchTcoSmiDispatchProtocol +9E76472E-DB4A-44B7-997C-3A3560B037B2,AcerLidSmm +9E7C00CF-355A-4D4E-BF60-0428CFF95540,BaseSerialPortLib16550 +9E85F0D5-5185-482B-8D50-5671307FEA80,AppleDiagnosticVault +9E863906-A40F-4875-977F-5B93FF237FC6,TerminalDxe +9E876632-FBB4-41B7-9800-30E0B4E8273F,AmdSmmControl +9E8AD3F4-383D-4EC3-816E-7A4749371290,FvbSmmDxe +9E8DD95D-868B-41A4-966C-107338C291BB,SmbiosDataUpdateDxeLightningRidgeEXECB2 +9E90E60F-FD1E-4B01-BA6E-9FDE5A02E60B,DellConnectionMgr +9E9F374B-8F16-4230-9824-5846EE766A97,EfiSecPlatformInformation2PpiGuid +9EA28D33-0175-4788-BEA8-6950516030A5,SmBusPei +9EA5DF0F-A35C-48C1-BAC9-F63452B47C3E,LenovoSystemCapsuleRt +9EA6AFE6-6E5B-4F9E-A1E6-86F049033834,ReportStatusCodeRouterPei +9EA6D6D7-7CD0-4695-AD99-4D32E93577A5,BrightnessHardwareVbiosNvidiaSmm +9EADE774-C736-493E-B2A1-9CE0415861FA,AmdXgbeWorkaroundPei +9EBA2D25-BBE3-4AC2-A2C6-C87F44A1278C,PasswordUI +9ECD1C5A-90F2-471B-8419-1DB62BD9CC27,FjImonCalibration +9ECD3C5A-90F2-471B-8419-1DB62BD9CC27,SmscUSX2064 +9ECD3C5A-90F2-471B-8419-1DB63BD9CC27,FjSmbusProgram +9ECD574F-CB36-4A9A-B2AE-E98B2762572E,FjMeIshDxe +9EDAD122-904B-4150-9AC6-B94653750453,AcChargeBeepSMI +9EDCBD06-3C78-4822-BD6E-A6847F7531C4,FastBootTseHook +9EE045D9-C35E-4967-8469-6C7E74508168,FjGrasscarryPartition +9EE045D9-C35E-4967-8469-6C7E74508169,FjRecPat +9EE41A8C-C112-4E4F-B2F0-65D0F9B133DB,DellPasswordPolicyExtSmmProtocol +9EE4CD62-7FA7-4183-9012-F6C4CF6E2C7D,NVBIOSINFO +9EEDA353-2930-46CB-A023-03E4E358A90C,FchPromontoryPlusSmmInit +9EF82BFE-707F-468F-A944-A61626E47DC9,AcpiGlobalVariable +9EF8C276-B3E6-4AD9-8FE7-C74F71C47248,AAFTblSMI +9EFE0B7E-27E8-46D5-8387-CDDAFD2C3A67,ASRockNetDnsBin +9F00131E-5248-44A6-BF84-93ED18E1780F,SioMec152xDxe +9F0053CA-35CA-4DF3-A45E-8C8FA8D1023E,TouchPadDriver +9F048812-A546-4C85-A5CF-A0785423705D,SystemConfigUpdate +9F1D2270-2E0F-4D07-9477-587989B8A32C,InterWifiDriver +9F1D2270-2E0F-4D07-9477-587989B8A32D,NetworkDevice +9F2171EC-7D0F-460F-915D-C58A0F7E6764,AmdNbioPei +9F3A0016-AE55-4288-829D-D22FD344C347,AmiBoardInfo +9F3A0016-AE55-4288-829D-D55FD3AAC347,AmiBoardInfo2 +9F3A00FF-AEFF-42FF-82FF-D22FD344C3FF,IrqBoardInfo +9F455D3B-2B8A-4C06-960B-A71B9714B9CD,StatusCodeDxe +9F49A879-3D71-42B3-A0AD-DDB1F33010A3,EfiSpiAcpiProtocolGuid +9F53EC68-49A7-7F4B-88DE-C41A96FDBAA6,Ip4Dxe +9F58E424-B96B-45A5-ADDC-D2FE394A99D9,AmiPeiEndMemoryDetect +9F5E8C5E-0373-4A08-8DB5-1F913316C5E4,LenovoSecuritySmiDispatchProtocol +9F606D27-E218-4112-834B-8ABCE950B1FB,SmbiosRpTable +9F6D574F-CA37-41DB-8E4B-78106A338813,SwSmi534D0C40 +9F732236-7A4E-4F27-9EEB-AB579F8F7A47,AudioPlaybackSmm +9F7DCADE-11EA-448A-A46F-76E003657DD1,VariableSmmRuntimeDxe +9F81528C-3E31-420D-A9E8-074FD1C2C22A,HpKeyPressTrigger +9F83F5ED-F407-4BD3-9B16-DC27A7016BBD,PlatformFirmwareVersionDxe +9F899796-1A84-461E-9523-F1B85CE895B5,RTL8111D +9F8B12CF-E796-408F-9D59-3ACDDC0AFBE3,Datahub2SmbiosThunk +9F8D3B44-A115-4687-87EA-2C29BEB092AD,DellMemorySlotConfigSmm +9F94D327-0B18-4245-8FF2-832E300D2CEF,WifiConfig +9F972E33-9B91-4A94-8540-5A00640C2771,POSTCODE0A_RGBKBCTRL_SMM +9F9A9506-5597-4515-BAB6-8BCDE784BA87,UniversalPayloadAcpiTable +9FA1B225-3346-461B-A069-ED01B673D240,EfiI2cBusProtocolGuid +9FA2F805-3D86-42BC-A9C3-2B26A5DF09F9,LenovoPchConfig +9FAA80EE-21D1-4331-93F5-D6485689C53D,FingerPrintSwSmi +9FAAD0FF-0E0C-4885-A738-BAB4E4FA1E66,FspmWrapperPeim +9FB02E41-2F22-4F41-B926-850B7D7C2A5B,DellAutoBifurcateSiDxe +9FB1A1F3-3B71-4324-B39A-745CBB015FFF,Ip4Dxe +9FB4B4A7-42C0-4BCD-8540-9BCC6711F83E,SystemUsbMassStorageDxe +9FB63BF9-B522-4203-9A53-20EC854A312A,DellDaNonVolitileStorage +9FB6793F-7008-4963-AED6-35AFB265DF60,FjGpioGeminilakeSmm +9FB8AC55-D266-4F86-AC43-BF2BA74F5A7A,AmdCcxZen5Dxe +9FB9A8A1-2F4A-43A6-889C-D0F7B6C47AD5,EfiDhcp6ServiceBindingProtocolGuid +9FBFB853-7098-4929-B262-43537D88A414,SystemErrorCheckPEI +9FC7B519-3522-4A71-BEB6-F99F5B2DBF92,VgaConfigurationReadyToBoot +9FCC1AA3-8BEC-485C-FFFF-FFFF20686CDB,XnoteAcpiNvsDxe +9FCFD3EE-38C3-4AAF-9512-EC416371F64A,DellDxeMain +9FD2360E-6B48-11D5-8E71-00902707B35E,PciHostBridge1 +9FD5A342-7177-4837-95A5-34E080A8328C,TxtDxe +9FD7E742-ACB4-4C6B-9D16-91B363858253,HeciControlDxe +9FE02F9C-5BDA-4971-A918-B79451B43E43,FmpDxe +9FE09C87-6FD8-4063-8EBE-6809EF5EABC5,HpCompressDecompress +9FE0FCFF-B023-49A1-A2C8-ACCE1AA010BB,FboSmiFlashLink +9FE10324-D10E-4CF2-99C4-F1B5A0B4732A,PostMessageSmm +9FE1D71B-3F91-4103-AE62-3FEECA4D2BAA,SpiFlash +9FE6A332-1A1F-43E3-BD25-F7891C6FC74A,EfiBmcSelfTestLogProtocol +9FE7DE69-0AEA-470A-B50A-139813649189,KekVar +9FF8B817-D14C-4A43-9314-123DA3960AD6,AmdMemAm4ZpPei +9FF8B917-D14C-4A43-9314-123DA3960AD6,AmdMemAm4Dxe +A0015941-01A1-4146-B101-B1BB05D8631C,EfiEvPpi +A001B7E9-84BB-4819-B7DA-93FF51730889,AsusOptConfigPei +A00490BA-3F1A-4B4C-AB90-4FA99726A1E8,EfiBlockIoCryptoProtocolGuid +A017BA59-DCAD-473B-BBB3-294E9AF20D34,OemPeiHook +A018CFFB-49A2-4975-83DD-7276D480009E,FjOemIgcFmpDriver +A01E498C-96E8-2A4C-95F4-85248F989753,FwBlockService +A023D3F6-F297-4307-8552-E6572B30B520,menu_mid_mid +A023D4A1-05A1-4797-B84F-03B854FD05F1,EneDXE +A030D115-54DD-447B-9064-F206883D7CCC,PeiTpmInitializationDonePpiGuid +A0337044-949C-423E-B581-DAE2AD435534,VbtInfoGuid +A034147D-690C-4154-8DE6-C044641DE942,FspVariableNvDataHobGuid +A035D164-1FE5-4DF8-B5F6-23F42BFBEC09,SeedProtocolDxe +A03A9429-C570-4EF9-9E00-C7A673976E5F,SmmControlDxe +A041B8D6-3F17-4582-AAC7-5A615672E295,DellSioPolicyConfigDxe +A04A27F4-DF00-4D42-B552-39511302113D,DriverSampleFormSetGuid +A052A0E0-F7BC-48BA-8DB5-ADF9F2F9307B,DellRomArmorDxe +A0534D92-9776-4E4E-9234-C9DC1849DBB5,PlatformFlashAccessLibNull +A053F561-F56B-4140-8901-B4CB5D70929E,BootScriptThunkGuid +A05B6FFD-87AF-4E42-95C9-6228B63CF3F3,EfiSmmUsbDispatchProtocolGuid +A05ECE52-15A8-424E-BFD3-FCF3D566A09C,AmtPolicyInitPei +A05F5C06-1782-48AA-962A-86A0892022B6,ASM1061Dxe +A062CF1F-8473-4AA3-8793-600BC4FFA9A9,EfiLegacySredirProtocolGuid +A062CF1F-8473-4AA3-8793-600BC4FFE9A8,CsmDxe +A06F2CE4-10BF-4D1D-8436-45E596E73777,USBTimingEx +A06F2CE4-10BF-4D1D-8436-45E596E73B67,DaylightSavBoot +A071C476-F78C-41C2-A173-B43D699A2C80,AppleEfiSocShutdown +A07B3BDF-B78A-41EE-A276-55C225A07B0B,EfiPeiPlatformTypeOpalCitySthiPpi +A07D8A73-D4F9-4AA0-BC25-391CCFC47E98,I2cControllerTemplate +A08276EC-A0FE-4E06-8670-385336C7D093,x86Thunk +A08CD08E-CA79-445A-AB1B-A5BB039B569E,I2CSpeedPei +A0A13495-A2BF-44E1-98F8-CC08D1AE604A,OemPeiSetGpio +A0A3FEC9-FE9D-4CE7-8DB4-9C54F3F19E5A,HpSetup +A0A8D728-BC2D-483F-B583-28489B77C8F6,FprSynapticsPrometheusDriver +A0AAFF71-35DA-41EE-863F-A24F429E59E4,IconSelected +A0AD1682-AE5C-4A9C-9195-F271585CE07E,RSTeRaidDriver +A0B76FEC-502C-401D-9705-20AEF6EAF832,EcAuditLogSmm +A0B852E0-4842-4222-8964-C82EDCFF0D6B,AsusUsbChargeSmm +A0B87E92-6392-47FE-9AA0-90203147EC04,DellHddPwSmm +A0BAD9F7-AB78-491B-B583-C52B7F84B9E0,SmmControl +A0C0B7EF-99FF-417F-8B9F-5AD4701D90D6,Tpm12DeviceLibAtmelI2c +A0C3B7DC-4E19-48EC-A8C7-BA58E2E08FF4,AmdCpmOemInitPeim +A0C6D314-97B1-4FB5-ADCE-05138A2B5D00,FjHddEraseDxe +A0C6D918-8DEE-41BB-9D92-6753A572B652,EfiTpmStateInitHub +A0C98B77-CBA5-4BB8-993B-4AF6CE33ECE4,Tcg2Pei +A0D75050-8DA7-4E58-9AD4-00FB9E3DB2F0,AsusI2cDetect +A0D7E505-5DD4-4459-A4D3-36119563C4F9,DellAudioPei +A0E4DE1F-ED01-419A-957D-237903108BA8,EfiNgnCfgCur +A0E5A45F-5374-46B3-B51E-D310B2C48AAE,ProjectOwnPeiProtocol +A0E8E04C-9B5A-43BE-8B7D-C98760492B68,SectionExtractionDxe +A0E8EE6A-0E92-44D4-861B-0EAA4ACA44A2,EfiKmsFormatAescbc128Guid +A0EAF572-69D8-4825-B1B0-9EE3B4C64FA7,ASUSGamingBoard +A0EEE2E2-E7B7-4964-8959-908259DD096B,FjAlsSmm +A0EF80E3-F9AB-4CBA-98FD-704620F4048D,SecFlashUpdDxe +A0F4A3BF-022F-4AE5-AB09-825E7AB30894,BoardInitPostMemPeim +A1047342-BDBA-4DAE-A67A-40979B65C7F8,EfiSocketPowermanagementVar +A1147A20-3144-4F8D-8295-B48311C8E4A4,ArmJunoTokenSpaceGuid +A11585B7-8FA2-4F1C-AA6F-DD6309469613,MeFwUpdLcl +A11A707C-EB9A-450F-8CB6-9284B56A9F80,FjGabiEntrySmiDispatcherSmm +A11D8F9F-2A52-40BC-9B82-BCCD7D281EEA,PchGpioUnlockSmm +A11F5FED-63A1-414A-B8FE-FB2184C242FD,HpDtPrivateWmiSmm +A128BD92-E5D3-4A8C-A902-559989BDCA05,DellPermanentDeviceDisablePei +A134273C-0429-4B93-A30C-305D5EC22DB5,KEMhGpioAccDxe +A1445693-5659-030E-C256-42A1868A6D9B,MktmeCoreInitPeim +A14694E4-78DF-4EF1-A118-7654FF6CFA9D,IpmiSdrReader +A14AEEAA-C07B-4846-BF54-C4943783EBCD,FchSmmDiagDispatcher +A15E7FDE-9D23-4A61-B3FE-E02B30BD80E6,ADCLOMUEFIdriverDxe +A15EE4CD-C21C-44D2-9547-2F49869FB9D3,LenovoTpm2ConfigPei +A160BF99-2AA4-4D7D-9993-899CB12DF376,MmCoreDataHob +A16473FD-D474-4C89-AEC7-90B83C738609,EdkiiPeiAtaPassThruPpi +A166D63D-3815-4FA2-BAB6-555D96BA516F,FjMemoryInfo2 +A1671208-7269-4E1B-BADA-CE0F51844C2A,PlatformTcoReset +A16BA302-6514-4287-BEE3-6223B7DE2C21,NVRAMID +A17EF0D6-52A0-4B70-8FAB-FC60E81C396F,FchDxeAux +A17F4A89-5F19-444F-B7BE-48195E0575DB,SmbiosGenDxe +A17F8AAB-42F9-4D94-82CD-A099E1DD52DF,BootTimeDxe +A18596AC-1FC5-478D-BF14-0B415813D71F,Ohci +A1902AB9-5394-45F2-857A-12824213EEFB,AsusMsoaDxe +A196BA47-8ED3-4188-A765-FA964DD7ED7A,LenovoSystemErrorLogDxe +A19832B9-AC25-11D3-9A2D-0090273FC14D,EfiSimpleNetworkProtocolGuid +A19A6C36-7053-4E2C-8BD0-E8286230E473,PciHostBridgeLibNull +A19B1FE7-C1BC-49F8-875F-54A5D542443F,CpuIo2Dxe +A19FB0EE-05F4-4CD6-8F28-59B782FF95C6,PciExpress +A1A38D16-5CD1-4109-BE88-BF0DB27A9838,CbsBaseDxeRPL +A1AFF049-FDEB-442A-B320-13AB4CB72BBC,EfiMdeModulePkgTokenSpaceGuid +A1B0B230-67DC-431E-A94A-A96AF1EBE637,Tpm2DeviceLibTcg2 +A1B8C9FD-3D04-43AA-8399-720A629EBF3F,LemSecureBoot +A1B8C9FD-3D04-43AA-8399-720A629EBF4F,LemSecureBootForceKey +A1B98C63-7032-4ED7-8CF2-8169D2788BA8,SpecificResetProtocolDxe +A1C85085-3053-4C4B-A9F6-724D22A76EF9,AmiLegacyTpmguid +A1CD8AB7-B86F-43AD-877F-B3438DFF792E,HPLnx +A1D99CBA-81F9-49BF-A15B-D7EBD7F0BB8D,PCAL6408A +A1DD808E-1E95-4399-ABC0-653C82E8530C,JunoAcpiTableFile +A1DF608E-8027-413F-A2F2-1DF7863F906B,OhciDxe +A1E37052-80D9-4E65-A317-3E9A55C43EC9,EfiIdeControllerInitProtocolGuid +A1E429CA-A933-402C-B6BD-314ED5142541,FjMrcOutputInterfaceCezanne +A1E96071-C1DD-4595-80D8-3D497F7AB527,OemMS +A1E96071-C1DD-4595-80D8-3D497F7AB577,LenovoWifiVariable +A1EEAB87-C859-479D-89B5-1461F4061A3E,FspInApiModePpi +A1F1B3F0-A60C-4462-801F-BEC99DF51821,HpOemSlic +A1F436EA-A127-4EF8-957C-8048606FF670,UndiRuntimeDxe +A1FF7424-7A1A-478E-A9E4-92F357D12832,LoaderMemoryMapInfo +A20CD5AB-83AC-4F82-B9E3-987B8BAF9AFE,UsbXhcAcpiTablePatchDxe +A20F7425-BC87-47D1-945C-637603323584,PlatformConfigTool +A210F973-229D-4F4D-AA37-9895E6C9EABA,DpcDxe +A216E8AB-19A4-43FF-86A3-C57938F03B06,FireWireDevice +A219423C-92FE-41AE-965C-2EFFC6018670,PdSolutionSmm +A222C87E-68EC-4545-A86B-A89031A45E82,OemCleanFlag +A226CA17-7907-4E77-8807-5D4878A38FA7,HpDiagnosticsPorting +A2271DF1-BCBB-4F1D-98A9-06BC172F071A,EfiExtendedSalFvBlockServicesProtocolGuid +A229F23E-E1FF-40D1-9382-36DD61A63EAA,AltModePei +A2424BB5-5441-4EFE-A608-2CCD60824C06,NvVariableFailDetectPei +A245D6D8-AFD4-4359-8F7E-7D829CA27158,HpMpmProtocol +A24FEE8C-AB1D-4B84-8E74-5DB474D8FEA8,UefiDiagnostic +A25334B3-467C-4152-AC84-F4C201EEF8C3,AmdFabricStxhDxe +A25C2D8C-2F92-4626-8D63-843BA9439630,TxtDxeProtocol +A25F2FCD-C168-4E77-AD3E-A488ACB725AB,CompletePowerManagementProtocol +A2627D18-010B-45B8-AD38-AB01691FC850,AmdHspConfigPei +A2702A3C-62FD-402D-B8C3-1D18F6C6FDE5,AodSetupDxe +A2760074-ED4C-4719-8382-C942CBF16D85,DisplayTypeDxe +A27D40FC-EA2B-4F3F-BD17-D5032A79546F,LEMELocker +A27E7C62-249F-4B7B-BD5C-807202035DEC,DellFlashUpdatePei +A287558B-D9DD-461B-A929-EC2AD2FEF591,DellSpiPartSst +A2990B11-F05C-4182-9703-BB02275DB8F9,SmcNvdimmSmmProtocol +A29A63E3-E4E7-495F-8A6A-07738300CBB3,AmiTcgPlatformDxe +A2AA0A8F-43D5-4B21-A26B-5D02476AD457,AmdCcxZen5Pei +A2AB9D42-967A-45B3-9507-28CCC7021F51,UnknownBoot +A2AEDCB3-8080-4C3F-B414-7A05D25E0699,DellNtfsDxe +A2B05C85-8D5B-4FF3-B7D1-8FBE92B4AA32,PchEvaInt15HandlerFile +A2B8BC76-C45B-40B0-A23E-D6827C835D1E,TouchPad_Elan +A2BCE73D-5B22-4FC7-80F5-F1A9D26ED758,WheaErrorInj2 +A2C1808F-0D4F-4CC9-A619-D1E641D39D49,LenovoSecurityConfigVariable +A2C74B0C-F38F-42F6-A147-379013ED92ED,OEMIP3SMBIOS +A2CC7663-4D7C-448A-AAB5-4C034B6FDAB7,rmHwA5Guid +A2CF63C6-D44F-4CD0-8AF6-722A0138C021,ArmPlatformLibSecNull +A2DE77BB-797D-4BB5-80C4-19AEB8B5CD29,ASUSFAKESMI +A2DF5376-C2ED-49C0-90FF-8B173B0FD066,EsaFull +A2E160F3-018D-486C-A7B5-10B0E669EDA3,DellVariable2Dxe +A2E5609E-8C2D-42E6-A2FC-12BC74BD437F,EfiPeiPlatformTypeNeonCityEprpPpi +A2EE1AF9-CFDB-4F73-829F-3D2CF7E51472,DellBoardPolicyDxe +A2EFA9DA-5218-4653-B357-FC51D73E0754,SecureBootServiceDxe +A2F03EEA-9304-40BE-87B2-7F457B01232A,AsusSmbios +A2F436EA-A127-4EF8-957C-8048606FF670,SnpDxe +A2F68EA6-61D6-4B84-A9C3-497D8A5E3804,RtcWakeUp +A2FA40D4-68A7-4A4F-9446-7ACD93FD2391,UsbDebugCard +A30D9B7C-DED3-48D6-83A6-3FF43444C37A,AppleDxeManufacturingFixture +A31280AD-481E-41B6-95E8-127F4C984779,TianoCustomDecompressGuid +A31B1AF7-3A9B-424A-8636-9885E9DE06F6,ASUSPei +A33319B5-8EE1-45E0-8C9F-809F5B0902CC,RsdpPlusProtocol +A334E8C1-F49F-49AA-9F82-9210205FC1FB,FchSandstoneDxe +A3358D8F-B7AF-47B7-A324-9036FBD73DDC,FjMfgErrorCheckDxe +A340C064-723C-4A9C-A4DD-D5B47A26FBB0,EsrtManagementProtocolGuid +A342B464-0D5D-4576-9400-750FF10719E7,XmlCliCommonSmm +A34CF082-0F50-4F0D-898A-3D39302BC51E,IntelFsp2WrapperTokenSpaceGuid +A3527D16-E6CC-42F5-BADB-BF3DE177742B,UsbCbiDxe +A353290B-867D-4CD3-A81B-4B7E5E100E16,EfiPlatformTxtPolicyData +A356AB39-35C4-35DA-B37A-F8EA9E8B36A3,EfiStatusCodeDataTypeProgressCode +A35AFACA-8C95-4EEC-9453-D8E5B560A8BA,Afu32FlashDriverSmm +A3610442-E69F-4DF3-82CA-2360C4031A23,ReportStatusCodeRouterPei +A362215D-75B6-4B54-80E5-7434751877F3,RtkUndiDxe +A36495C1-C205-414E-B71F-4BE3476D699C,FSVariable +A368D636-4C77-4B50-AAE8-F99E2DA40440,PnpRuntimeDxe +A37A9E43-9077-4539-9B90-BD719B032B23,SpiControllerDxe +A37C58CC-DC2B-450E-85E2-F4C538F2209B,Armani_ProductInfoDxe +A38C6898-2B5C-4FF6-9326-2E63212E56C2,PeiSpiPpiGuid +A391E822-7044-4CF4-BE5B-345E44B8627C,SgPlatformPolicyPpi +A3922B1A-35E4-4132-9CED-91D38D7171D8,FpgaSocketPkgList +A3979E64-ACE8-4DDC-BC07-4D66B8FD0977,EfiIpSec2ProtocolGuid +A3A209D9-2DE3-403B-9C6C-DB3CDC5ECFCD,LnvSolPei +A3AD355A-13D0-4DCF-9C21-3D2C5F1BAD5F,FboGroupForm +A3AEC012-9A26-4AA5-986C-004423E43975,SnapshotLite +A3B3D093-1B04-45BF-8D23-2334607C7B40,PlatformDeepS5 +A3B3E6F8-EFCA-4BC1-88FB-CB87339B2579,EfiKmsFormatGeneric160Guid +A3BC19A6-3572-4AF4-BCE4-CD43A8D1F6AF,ASUSITEBS +A3C4B758-FA8C-4A75-91E2-807EC3B3DA34,DeepSleepDxe +A3CD8EAC-B4E6-4B68-9641-0D3763799890,Int15Backlight +A3CF349D-639C-4D08-AC4A-C95341FB4F94,AppleIrRemoteDxe +A3D5ABB6-9DA4-43EE-BE3B-BDC47D70F8FA,CPULowSpeed +A3D93A29-501B-4F6E-869A-6FD4BCEF90A7,DellSmbFactDefault +A3EAAB3C-BA3A-4524-9DC7-7E339996F496,ASUSRT +A3EDC05D-B618-4FF6-9552-76D7886343C8,OvmfLoadedX86LinuxKernelProtocol +A3F03487-9FC5-4DDC-9A44-4B61B4D276D8,FjCapsuleUpdateDxe +A3F436EA-A127-4EF8-957C-8048606FF670,BCDxe +A3FF0EF5-0C28-42F5-B544-8C7DE1E80014,PiSmmCpuDxeSmm +A40610B7-4988-43CD-9D95-9BE9E0E7A311,IntelGigabitLan_I210 +A40DAE55-2F33-42F5-B064-C8D62CCF3B87,AppleSystemInitialization +A410F39B-76BB-425C-ADD3-8678A41C89DC,SystemVspEvaRuntimeDxe +A4223CF1-6B27-4994-8FCB-A3A279C04E81,EfiGenericElogSmmProtocolInstallled +A428AD0A-5034-4E37-8F9D-DB2CE72A59B3,SmbiosOverride +A42B4684-26EA-40D0-AA38-94C21C3C4E59,ATIPwrXPEI +A42F4ACF-5A88-4DE3-A54D-EE7CA94C1246,AppleSpiIoCnl +A43B03DC-C18A-41B1-91C8-3FF9AAA25713,ExitFormSet +A43F5A9E-B29E-451B-8526-44C3E43D5067,SioInit +A44A669C-ACE0-4696-8179-F5EA87930C4F,HpErrorLoggingDxe +A4524A9C-0B5E-492D-AEC9-308631B189B4,AmiSetTcgReadytobootGuid +A4578B9E-C666-4161-A168-159FF541ACD3,CnvUefiConfigVariables +A457CFAD-64EA-49EE-A532-566AC2B6D6C4,PolyFuseWarningsDxe +A45B3A0D-2E55-4C03-AD9C-27D4820B507E,EfiUgaSplashProtocol +A45BE8D5-B988-4F70-9F16-8BFBC6884669,PchInitSmm +A45E60D1-C719-44AA-B07A-AA777F85906D,PeiAtaControllerPpiGuid +A46423E3-4617-49F1-B9FF-D1BFA9115839,EfiSecurityArchProtocolGuid +A464BF8C-77AB-4BD8-AEF1-82DAE1A06AF6,FjGabiFlashDescriptorDxeProtocol +A469DDBD-16D0-4535-BAE3-77274BD70B4C,FwBlockServiceSmm +A46B1A31-AD66-4905-92F6-2B4659DC3063,EfiExtendedSalPciServicesProtocolGuid +A46BA67D-B169-4E04-9AAC-1845CBDEE0AA,AcpiMetronomeDxe +A46C3330-BE36-4977-9D24-A7CF92EEF0FE,PxeDhcp4Dxe +A46D9EE7-C6B4-42C0-8378-6E4BDC50406B,SetupLoadDefault +A477AF13-877D-4060-BAA1-25D1BEA08AD3,EfiKmsFormatRsasha2562048Guid +A47EE2D8-F60E-42FD-8E58-7BD65EE4C29B,CpuIo2Smm +A48261AE-B7C1-463B-BF32-8625B6779A0E,UsbIoExt +A484323B-FF47-422A-ADAB-8D1E1BC13860,HpS3ConfigDxe +A485D6C7-D76B-4DE0-BE57-96C1D2DFE520,It8587eFlashSmm +A487A478-51EF-48AA-8794-7BEE2A0562F1,tftpDynamicCommand +A490D6C3-A8DF-4235-B756-3A2ECF32BC24,AmdMemSmbiosV2ZpPei +A4928C81-0703-4AD7-A32B-7525BC3FE1F5,LenovoSecureUpdateDxe +A4B05B8E-B30D-4426-50B6-6D05DDEA84A9,HpHoneywellLcn +A4B9A806-B574-4354-BFC7-05217DC0FAF4,FlashHookSmm +A4C55A05-88D4-44CB-8DC7-B3C092802E22,FchSmbusPei +A4C751FC-23AE-4C3E-92E9-4964CF63F349,EfiUnicodeCollation2ProtocolGuid +A4CB211C-3E43-4775-BF1A-8CECE36E793B,AaeonLanByPassPkg +A4D53F5B-C216-4C8A-83D9-390B4A656CD4,AmdSocFp7PhxDxe +A4E221CB-C1E7-4292-98B7-4B2A41FC254F,Cf9Reset +A4E7949F-F818-49DE-AEC0-08B0DB6E250C,T23SmbiosOverride +A4E9A172-9D5B-47AE-BFCF-2C9FCA6F0ADC,AmdSocSp3r3CglPei +A4EC8ADB-B7A8-47D1-8E52-EC820D0ACF6F,FvbSmm +A4EE0728-E5D7-4AC5-B21E-658ED857E834,ArmMpCoreInfoGuid +A4EED3AF-9837-46B3-9275-C71CB47071F9,NetsecDxe +A4F2909C-5E2A-438A-91BA-272B0923049A,PlatformSetup +A4FD00D3-821A-4519-85BB-2E1987A6F4E1,LenovoMx25L3206EflashPartDxe +A5095ECF-A28F-453C-960F-8757E4A480B1,Cf9Reset +A510A614-2192-11DF-AF29-2754E86B3594,PciExpressHostBridge +A51BC7A4-0ED6-44C2-B5FB-B86FDE077DE1,AmiSetupNVLockDxe +A52509C7-5ECD-42D1-85A2-46C37135D12D,GopPolicyDxe +A5288050-8828-46C4-8F72-1CD735A56520,Slp20Dxe +A53EF7E2-9F46-4B56-ADC8-FE93B25D1758,FjDeviceInfoRealtekLan +A53F1264-54B1-4707-84F9-32DCD52FC58C,FjExtSmm +A5559F06-6415-4759-8869-DE15F9CD9C9B,IffsGlobalNvsAreaProtocol +A55701F5-E3EF-43DE-AC72-249B573FAD2C,EfiIa32X64ErrorTypeCacheCheckGuid +A56074DB-65FE-45F7-BD21-2D2BDD8E9652,EfiLegacyDevOrderVariableGuid +A5683620-7998-4BB2-A377-1C1E31E1E215,TcgDxe +A56897A1-A77F-4600-84DB-22B0A801FA9A,SmmRuntime +A56FAD72-A264-4370-85C5-00584654DCE2,InstallVerbTablePei +A570F393-B0F5-44A4-8550-61600597B409,BootScriptHideDxe +A57C1118-6AFC-46D2-BAE6-929262D3EB1E,EfiDxeSystemBoardProtocol +A58C5D1D-C22B-4845-90BC-8C94FCE96457,FastBootOption +A59176BC-A151-49C8-B54A-B4AC96F436C3,96BoardsI2cDxe +A59A0056-3341-44B5-9C9C-6D76F7673817,SignOn +A59E8FCF-BDA0-43BB-90B1-D3732ECAA877,EfiScsiPassThruProtocolGuid +A5A6C69C-B50F-4157-801C-4ED786A55370,AmdCcxZen4Dxe +A5AAB9E3-C727-48CD-8BBF-427233854948,EfiI2cHostProtocolGuid +A5BC1114-6F64-4EDE-B863-3E83ED7C83B1,EfiPlatformMemoryErrorSectionGuid +A5C02C56-19A7-43B5-A0D0-04518A1CA69E,AmdErrorPei +A5C059A1-94E4-4AA7-87B5-AB155C2BF072,EfiCertX509Guid +A5C1EF72-9379-4370-B4C7-0F5126CAC38E,TrEEConfigPei +A5C6D68B-E78A-4426-9278-A8F0D9EB4D8F,UsbMassStorageDxe +A5CE755B-EA21-4884-88C7-C7D4B1AE2837,ProgressBar +A5CFD301-408D-E8C2-44FE-07ACB1D56BAF,Sff8472Pei +A5D75589-589E-49FB-8F93-F494280EA1BD,SmbiosType140 +A5DEFDFF-944C-4B4D-9A76-8CF3ACAD2F7B,IntelRaidAtaAtapiPassThru +A5E369C8-ABF9-4B43-B212-FF1BFD35666D,CbsSetupDxeZP +A5F36439-BD52-49FB-B158-7F6688952BEA,OemSpecialLogoSupport +A5F8F888-7191-429B-81AE-2688F415BD2B,DellSmmGpioLookupPolicy +A5FADA55-1CAF-4486-9CDB-24018E71E952,PxeDriverDl +A6077307-B297-4051-9AC0-A0DC8147E601,menu_locked +A60A27AF-C1EB-4823-B674-F0369EA40349,RTL8852CEWifiDriver +A60B21B1-A200-4785-A86E-5106E76A3604,DellDynamicBacklightControlSmm +A60C6B59-E459-425D-9C69-0BCC9CB27D81,EfiGetPcdInfoPpiGuid +A60C7DCD-512F-4F02-B180-522E015E06B7,PpmProcessorSupportProtocol_3 +A610E170-08AF-11E3-A05F-047D7B99E097,ConfigurationVariable +A6185DDA-B5C7-4735-B871-8D6BCCCAC8C1,Pca9536Dxe +A6190292-DE59-421E-BA6A-1C7D17DFDFA7,AmdAblPerformanceDxe +A622AB73-1E7F-43C8-A465-0D5B267F1A37,MicrowindowsDxe +A622E42C-8E38-4A08-9E8F-54F784652F6B,SystemAcpiOA30Dxe +A62D933A-9293-4D9F-9A16-CE81994CC4F2,AppleDebugSupport +A630B937-3AB3-4263-85B1-A63E98F29949,PcieErrorHandler +A6351A87-2965-4718-88C7-0B5B5AC0B5E4,AmiMrcInfoHob +A640936B-F84C-4B97-9F95-2BFE78C1F0A1,KEMhHwmDxe +A6442A85-7E2A-4A4F-B26B-98E1E64C221F,AmdMpmSensor +A6688890-BFF0-4F03-9B1E-76AE86EEC5AB,LenovoSystemAcpiTablesDxe +A66ADAD6-972C-465B-84D6-072ABE8D6911,DellNuvotonTpmFwMgmtDxe +A671FACE-B99F-48AB-B3B0-F25E5EE4B115,TcgSetupDxe +A673005A-69F6-4597-8AF9-7AACA0039296,Int15BootDisplay +A67A75D2-CCCE-49C1-1BCD-61C310527E89,AmdNbioBaseSspPei +A67E68F0-A73D-40D0-98F5-121DEFB5C12D,HstiIhvProviderDxe +A6848B1E-73A6-429C-9B1C-C9528607725D,BoardDPTF +A6885402-D022-4B0E-A509-4711B90F2A39,ReportStatusCodeRouterSmm +A69B58A9-6C05-4DC1-85BF-AF80DCE6D97D,EfiTraceHubTokenSpace +A6A1ACA8-7499-4370-A331-5E8F92EC30D5,OemPeiSetAcLossControl +A6A1C030-F956-4A9E-9540-D0E81D2E33F2,LenovoSmBiosHole +A6A3A962-C591-4701-9D25-73D0226D89DC,PeiRamBootCacheRdy +A6A72875-2962-4C18-9F46-8DA644CCFE00,EfiIScsiInitiatorNameProtocolGuid +A6A79162-E325-4C30-BCC3-59373064EFB3,EfiTcoResetProtocolGuid +A6AECE92-0012-4E10-88EF-588D8DCCA8E4,DellSioIt8669eSmm +A6AEF1F6-F25A-4082-AF39-2229BCF5A6E1,AmtStatusCodePei +A6AFE798-A426-4651-AA19-BB0A448D8134,FrameworkHiiAlias +A6BCC829-889F-4EB5-A490-1B4C1AAF789C,SetupConfigUpdateDxeEVB +A6C0E11E-929E-42B3-90CC-4F778E03FF57,PkpubKey +A6C300F4-A5D0-43E9-81BC-C4FB5069E4A2,FjGabiEntryDxe +A6C37DD6-0D83-4127-B1E8-A1E600A797BD,HPWMIDxe +A6C7C690-ADD8-4178-BC97-F6A4C1206285,c_pg4306 +A6CA8BDC-AE14-4C13-9364-2F0E09CE0F54,AmdCpmEcInitDxe +A6CC6BC8-2ADA-46C3-BBA4-E99672CC9530,PciUartDxe +A6DB3378-CFD7-4BFD-A1C4-2709FEC52F8B,AmiTseOemPortingVar10 +A6DEFC45-18DC-41C9-B2A8-D0089DE08DD3,UfsPassThruDxe +A6F691AC-31C8-4444-854C-E2C1A6950F92,DuetBds +A6F7DEF5-10C2-4DBF-9B48-195388C56507,LANControllerSmm +A702CE64-AB7A-498F-BAE6-CE18BBAE4C31,BrightnessHardwareVbiosSmm +A708BD51-F56F-4DA2-8F78-1480CB2C1D84,SMSC5045PeiInit +A7119441-E153-970D-5508-75DCDFA41974,SbSocSummitDxe +A721B30A-5A7C-4B6F-AC69-07496129A26A,FjRealtekLanControl +A732241F-383D-4D9C-8AE1-8E09837589D7,XenBusRootDeviceGuid +A733A552-26E6-4803-92DE-6C5543EE54EA,SlotDataUpdateDxeSierra +A73D663D-A491-4278-9A69-9521BE3379F2,ArmVeTimerDxe +A74B3AEF-2502-40C5-83A9-3524776273EA,SioGpioControlSmm +A74CB083-C630-479F-9ECF-ADBAFD2F1704,BlueToothPei +A74D7B1D-0393-40D7-9AB2-0AE36CF3F1E8,TraceHubPostCodeHandlerPei +A75E4CED-D316-4CFE-942C-36A25789F04D,SetupConfigUpdateDxeGlacier +A767E093-458D-4DE4-A2A2-08C7CB5FB844,DellFreeFallSensorPei +A76B4E22-B50A-401D-8B35-5124B0BA4104,TcgPeiPolicyGuid +A770C357-B693-4E6D-A6CF-D21C728E550B,EdkiiFormBrowserEx2ProtocolGuid +A7717414-C616-4977-9420-844712A735BF,EfiCertTypeRsa2048Sha256Guid +A7732DA8-11AA-4366-9715-CD92CFB7D362,SataController +A775A229-DBF2-455D-B737-FBD53D368A26,OTP +A77B2472-E282-4E9F-A245-C2C0E27BBCC1,EfiBlockIo2ProtocolGuid +A77C8452-0821-4544-AE47-257489855F91,AmiPspNvramDxe +A799931B-FDB0-40B2-8A25-D26B58885379,AmdSocAm4BrPei +A799B420-F79B-44F0-A167-BC3F99DD6166,CbsBaseDxeSTP +A79DC347-DEB4-4A4E-8497-CA5F8E7F0601,DellImageServerSmm +A79EED97-4B98-4974-9690-37B32D6A5B56,RTSMArmVExpressLibSec +A7A11C86-C539-4BB8-8920-E7CCB5306DE3,SDTgaDecoder +A7A15766-449B-AA93-114B-71B47BE174CA,DellDataWipeSmm +A7AF67CB-603B-4D42-BA21-70BFB6293F96,EfiRngAlgorithmSp80090Hash256Guid +A7B0CEAC-480A-4F8B-ACE3-7679BE16EAF9,PdHostInterfaceTiPei +A7B36DCF-C75A-4BE8-BE2F-E4840CBE163B,DellPbaMgrDxe +A7B81226-FE2B-43B3-9BC7-6B24B5920DBF,DellAcLossPei +A7BBB38E-3AB4-409D-B11B-EE31A2688B0E,OemHooksPei +A7C0687A-E8B9-42EC-B8A5-A950DF6EF94A,AlternativeDefaultMemoryQuota +A7C13377-CD27-48E7-A488-F38E3A51D11D,SDGifDecoder +A7C619FF-9A64-4A89-947B-E7953E2427CB,PegaBsDxe +A7C88FAE-EBEC-45ED-A7C5-5FA755177306,PerfTuneWdtPpi +A7CED760-C71C-4E1A-ACB1-89604D5216CB,EfiIioUdsProtocolGuid +A7CF5E50-A5B4-43E2-9BC2-E64F9F74CF6E,OemPei +A7D09FE1-74D4-4BA5-847C-12ED5B19ADE4,PeiUsb2HostControllerPpi +A7D41F88-1CB8-4BFB-901C-F68BD2A47E9D,EcMeDisableDxe +A7D8002B-923B-41C0-884C-3FC3795203FA,SystemVariableStoreProtocol +A7D8D9A6-6AB0-4AEB-AD9D-163E59A7A380,SystemDiagnosticSplashScreenApp +A7E2CE72-DC32-4BC0-9E35-FEB30AE5CC47,AmiEarlyBistPpi +A7E45308-81B0-43AE-AD30-2398395C27DF,ClearPassword +A7E9ADAA-35C3-4A6B-A3B7-6C38BAA24F1F,BootBlockVisibleUpdateDxe +A7EBBFED-CD82-4278-94DC-80F0CDE46FE4,GpioV2ProtocolInitDxe +A7EDEBD8-A8D7-48F8-81FB-837656B82077,AmiNvramBackupRomAreaGuid +A7EE90B1-FB4A-4478-B868-367EE9EC97E2,FmpDxe +A7EEAF1E-969F-40EE-A21E-1856F5E6D41C,InstallMSDMTable +A7F43547-1FF1-4BCC-9425-A082909BCD0D,SystemSureBootDxe +A7FD9E38-C005-45AD-8B65-F13CF6A1FD79,AmdUnbXvPei +A8021F3B-B649-4C18-8270-A796ACCF32E1,EfiEmmcWpHobGuid +A80CF838-838E-4739-B49E-D97D20DDE98F,GpioControlPei +A80E8FC8-332C-4359-9622-84E83D90FD5A,BiosCriticalInfo +A80FFB86-4CAC-4D76-80ED-25F62054AD87,WifiConnectionManagerDxe +A8154B55-2021-4D40-AE81-2E23A02DCC46,FtdiUsbSerialDxe +A817E61D-049A-4509-BEB0-79FCA7696235,PlatformDriOverrideDxe +A81BD805-268C-45AA-8BDD-0B8EB92A5341,SmmFlash +A81DD68E-F878-49FF-8309-798444A9C035,AbtSmm +A82485CE-AD6B-4101-99D3-E1358C9E7E37,EdkiiCpuFeaturesSetDone +A82FAE00-DB01-4737-A6DA-7A2E1A75C203,SmbiosDataUpdateDxeSierra +A833441A-0CA0-4032-859A-3CFF7B6646A7,DellImageServerDxe +A838CBB5-59EF-4493-89D0-133C8968905D,CrbSmbios +A8499E65-A6F6-48B0-96DB-45C266030D83,SiInitPreMemFsp +A84B495B-79F4-40AB-8B60-653F69DCD944,AmiHeciDeliverProtocolGuid +A85027FC-0E09-4FA9-A407-CAD206FB4F1D,PlatformStage1Pei +A85DCA1B-198F-4E14-A673-874264687E85,DataSink +A8656175-9210-4AB5-8ED4-A7503BD92F0C,BoardSmbiosDxe +A869B539-26F0-4F22-9A3E-F434E6898984,ProcessErrorCodeDxe +A8752510-D83E-400A-85DE-FD1587882AFE,DellLomConfig +A883FD70-4E7E-4B17-8EBB-C5646FF154CA,SpiMouseDxe +A886C548-0CDD-4E2E-B364-AE956AAA4554,SwSmi534D0540 +A8913EC1-C00C-4C3A-A245-077C0CA35738,AspmOverrideDxe +A89599DD-AE31-419D-80C3-3426BC0A8E4D,CxlDxe +A89BB035-B7E2-42CF-B27D-C1A50FCBC1CA,DellUnzipDriver +A89EC8E0-0BA1-40AA-A03E-ABDDA5295CDE,PciExpressDxe +A8A2093B-FEFA-43C1-8E62-CE526847265E,AmitcEfiOsVariableGuid +A8A2F6E1-6F62-4CFB-9E47-93CFD6D6E476,DellLegacyUsbSmm +A8B31E06-7068-5D87-A1A6-10754A09B92D,FTPMSmm +A8BA4592-4D57-41C9-AD6C-0791BD23A99B,OemUsbPorting +A8BC51CC-5A30-41D5-8B1A-EB46ABC527FA,IioRas +A8C60A60-A950-48CB-A612-7FA732DF7243,OemRuntime +A8C67255-E029-4B1A-968E-ECA6E9C11C73,AmtSmbios +A8C6A171-5478-4A7C-9EB6-655C6CCC4E3A,InsydeReportFvPei +A8C77EB8-EBD6-4E51-A61A-B0366206B17B,BctBaseSmmSTP +A8CDA0A2-4F37-4A1B-8E10-8EF3CC3BF3A8,EdkiiNonDiscoverableUhciDeviceGuid +A8CEC941-CD87-4AB7-980C-4C77C33BF3BA,ImcErrorHandler +A8CF6278-8758-458D-ADFB-3471F5AD50B1,SystemHddPwdPei +A8D599F5-F45B-4396-8761-E1C7F7222A4E,FjPowerOnTimeCounterSmm +A8DB985F-CB2C-4822-B8B1-1C8E48123FA5,FjGabiPasswordHandlerSmm +A8E80DDF-A3BB-4880-9DB2-9BB1B8BB1212,SbMetronome +A8F14FA9-FC88-45F4-A622-F06E6C56E632,FirmwareBootMediaInfoPei +A8F634A5-28F1-4456-A9D5-7E24B99BDB65,PcxDecoderDxe +A8F7B053-CAD8-438F-98B3-200D4603B79C,OemLanSsid +A8F960C6-4CC3-4417-8AD9-2A3B3F8027EA,AmiMemoryInfoGuid +A8FB59B6-8417-48A1-B565-199849271066,AsusVerbTable +A90F8536-4AF8-45D6-B58D-D225FD1C06D9,FjI2cTouchPanelDxe +A912F198-7F0E-4803-B908-B757B806EC83,Hello +A9177B11-8825-3A50-AE81-2E23A02DAA42,DashUsbSerialDxe +A919B3B6-D44E-41F0-9179-8AA24FF2260E,PCIeSataDynamicSetup +A91EE51F-0FF0-4A6C-A6F4-9214303AEDF7,MeEsrtUpdate +A92CC133-370E-47F0-9980-5D78896BEFE4,PlatformMilestoneHookDxePrior +A92CDB4B-82F1-4E0B-A516-8A655D371524,VirtioNetDxe +A9388856-F674-4B2B-98B8-6F463029711C,SbSocRsDxe +A93A7745-FC4C-4435-8B60-B5BC3B7E9135,WheaLastBootError +A9474AB8-1AB4-43BE-90B3-17D119FE8086,PxeDriverDl +A94A6AEF-D69B-4010-BA24-F91E1FE62ADA,LenovoSystemSecureBootDxe +A94A9BF3-DF9E-4C11-A9CE-23C1F66FEE13,OobMsmSmm +A94B6FBA-BB07-4A98-8749-A860D6EB7724,LegacyBiosPlatformHookDxe +A954E4B0-0380-41F6-95C1-B8ADE56C2319,OemHookPei +A95C1D60-CB9F-4BD8-A030-3F1C4A185156,SecureBootMod +A960F489-9773-40CD-852C-55822D533F19,H19ComputraceRuntimeDxe +A9620E5C-5FA1-40B7-8B21-50B632F88F38,EfiLoader +A9626A70-A4AC-4B9B-8396-8C931E11904F,AmdCpmPmfDxe +A9638A2E-8862-439C-BA51-032161F6FE31,BayhubSecureErase +A9731431-D968-4277-B752-A3A9A6AE1898,PeiIpmiPpiGuid +A974C9A7-F765-4411-9191-41D36D5139B9,AmiSerialUart0 +A9759271-49CD-49BE-8764-5DEBFBE68F73,AmdResetManager +A97C91D0-6FEB-4555-B0DA-4E79EC009D68,GraphicalFirmwareInterface +A97EAC62-6F1A-4B05-8CFB-65B1CE7D6A3C,BiosVideoDxe +A9874C4B-599B-4B46-8161-FA4E72E53BBA,ShadowDownPei +A9920538-40A4-4335-9D71-1EF546AEFB27,DellSfpPei +A993B66C-22EA-46BA-A27A-0A23356D901C,AmiHddTemperatureProtocol +A9A048F6-48A0-4714-B7DA-A9AD87D4DAC9,EfiRestJsonStructureProtocol +A9A7A430-A520-4279-AB90-95683EFFEEC6,SioChip1Smm +A9ACE824-4486-44E6-915A-8FBAED0799B9,SetupDataProviderDxe +A9B54638-4F79-4369-BCA3-44B2B593ACB8,OemSmi +A9B700CF-019E-4D8B-A3A7-88E1EA01699E,HddSecurity +A9C8E043-B66A-42B9-A48F-98B23491EBAB,Cf9Reset +A9C9211C-7B14-4DA9-A14F-3AF7451CC0F8,BiosUpdateExtendedPlatformPolicySmm +A9CA7993-FB8F-4BE4-8CE1-E2AB9F2ECD04,SGXSetupSmm +A9CC8E41-4BC1-4D1A-8E0C-C721DDFCE881,H19VariableLock +A9CE66D5-6D37-451E-A9BF-F58F7A0B3CC2,ASM1061_DXE +A9D372DE-D677-4B41-8FAD-9EC178DE19CE,DellVideoDevice2Protocol +A9DC6F60-F861-47D1-8751-ECAAE7D27291,LibMath +A9DD1597-F2C5-4CB6-AA7B-EE01AE806185,AmiSmmNvmeControllerProtocolGuid +A9E7CEF1-5682-42CC-B123-9930973F4A9F,EfiMpInitLibUpDepProtocol +A9E8E979-4B94-4150-B949-51D45FE5EA18,LEMDisableSecSMIFlashProtocol +A9E9888F-CA84-436B-B0D8-A03DEB351CAE,AppAdapterMkTme3v0 +A9F634A5-29F1-4456-A9D5-6E24B88BDB65,BmpDecoderDxe +A9F8D54E-1107-4F0A-ADD0-4587E7A4A735,IntelSiliconPkgTokenSpaceGuid +AA00D50B-4911-428F-B91A-A59DDB13E24C,EdkiiSmmCpuRendezvousProtocol +AA0E8BC1-DABC-46B0-A844-37B8169B2BEA,EfiPciHotPlugInitProtocolGuid +AA17ADD4-756C-460D-94B8-4388D7FB3E59,EdkiiPlatformBootManagerProtocol +AA1AA47C-3668-4F75-B51B-0C1C6499764C,AmiGetPstatesZen4 +AA1FF342-8968-4C70-882B-9E46DE9E4E78,OemSsidDataUpdateDxe +AA236098-86C3-4A56-8B89-B715E04AB5CE,SsidPei +AA298E94-A45D-45B5-8CE5-4FB71FBA4CE0,RpmcSmm +AA2A3D4A-FDBB-4C27-BF42-1C74F1742E82,OemIp3Pei +AA324A7F-A676-46DC-A35D-A404226A7A04,ReprotErrorCodeStatus +AA382865-12B0-44E5-A731-6DEF4DF34CE7,LenovoPromptService +AA40B708-9073-4436-B5FE-D22D7ABBA5C4,MemoryDiagnosticDxe +AA40D00E-5B9B-4DAD-A487-FC1BCBEF8170,SgPeiInitPpi +AA4100C0-7F70-EABF-B720-5B6F7ACA5EEB,EepromDxe +AA430398-3C8A-4817-8ED0-6291B5C77D6A,RTL8111HN +AA48FBB2-9F87-4DFD-B416-575938F0C8F4,PropertiesTableAttributesDxe +AA506A03-4A54-492B-8F2B-9AD9A949358A,UfsBootLunIdHobGuid +AA5324ED-DC11-4D5D-A52B-FABDD7E80634,PlacementDxe +AA600F06-26F5-428F-B4F1-913BEF6E4DBB,FspWrapperExtractGuidedPeim +AA652CB9-2D52-4624-9FAE-D4E58B67CA46,PchSpiPeim +AA69724F-11C0-4B04-A860-2E8E196B03CA,AmdMemBrhSp5Dxe +AA6E807F-88C8-4237-EE25-AAC45BF18804,EfiIntelLanDriver +AA6E8785-726E-441D-ACB8-F75FB0B2B9F2,CoreEG2 +AA7B4695-00B4-4468-AD92-99370AC031C5,LegacyRegion2 +AA7E190D-BE21-4409-8E67-A2CD0F61E170,UniversalPayloadSerialPortInfo +AA8818DF-D0B1-45E4-A7F2-B6DB0E752BA7,AmdPmfDxe +AA893E19-A641-4819-AD23-011B7C24250D,IT8728SioAcBackSmm +AA924214-DFCB-4BEE-AA33-FAE9729AF000,A01ODMSmmServiceDriver +AA9BD7A7-CAFB-4499-A4A9-0B346B40A622,SmmRegisterInfo +AAA76748-3602-450A-B905-6A98A3E6D363,ProjectDxe +AAB16018-679D-4461-BA20-E70CF7866A9B,EfiSystemTypeFru +AAB18F19-FE14-4666-8604-87FF6D662C9A,EfiSpiSmmNorFlashProtocolGuid +AAB53D89-3AC6-40D1-8C65-44EA1FCA9A4E,AmiPspRebuildBSmmCommunicate +AAB5438C-F15B-4DEF-B61A-5280B62BFB58,FchSongshanMultiFchPei +AABDBE33-DBDC-43D3-AFE3-AB37F9B46782,LEMCBMRDxe +AABE9A45-B345-49D2-88EF-6AD0B85ED7E6,AmiRomLayoutProtocolGuid +AABE9A88-F09C-429F-B293-2D2DA9DA9980,AudioDxe +AABF95D6-F40C-405F-8360-6A59794B8040,BasePciSegmentLibPci +AAC33064-9ED0-4B89-A5AD-3EA767960B22,FaultTolerantWritePei +AAC9B0AF-A46A-49D8-8016-9B9DAD2C7F5E,DxeBoardConfigInit +AAD04E7E-F6E6-4694-B14F-E2D608740E29,SmbiosType3 +AAD10051-5D94-4B9F-B778-E4555EE3CCCA,IioSmm +AAD1E926-23B8-4C3A-8B44-0C9A031664F2,FmpDxe +AAD8B9F8-2C83-4E4B-96E8-C5B8B8AC56BF,JedecNvDimmSMM +AADE7C97-98E7-4CFA-B4EF-BBE20506A31D,EcIoSmmProtocol +AADFA1AC-E923-4673-B1B8-714AD849F790,SystemFormBrowserSimpleTextViewLayoutDxe +AAE2EA7B-E052-4371-8E4B-FF0E52D80F66,AdlinkSetupItemMod +AAE65279-0761-41D1-BA13-4A3C1383603F,Ozmosis +AAEACCFD-F27B-4C17-B610-75CA1F2DFB52,EfiEbcVmTestProtocolGuid +AAECDC89-2A49-46F1-A163-F7979C039998,IdeBusSrc +AAEEA070-C492-4469-B378-BBAB2060A4A7,BiosAttributesMgr2Smm +AAF32C78-947B-439A-A180-2E144EC37792,EfiAuthenticatedVariableGuid +AAF691F4-9851-4120-8A43-1129B2829899,FjDtPowerFailureRecoveryPlatformDxe +AAF875D2-0968-4585-A40A-B35C9FE0CAEC,AodSmmZp +AB1404CA-4801-4208-98BF-30D521DAD4D3,AmiTseUserPasswordValidGuid +AB17430C-135B-46A6-95C0-57052798A584,PlatformIbraTopSwapPei +AB189162-6DB5-4EFC-AC59-D0B3CC851119,OemEarlyPei +AB1C1816-D542-4E6F-9B1E-8ECD9253E2E7,ArmGlobalVariablePpiGuid +AB21ACC3-BA33-EE2C-66BC-125677111AB2,AmiDebuggerCpuProtocol +AB226E66-31D8-4613-879D-D2FAB610263C,EdkiiDynamicTablesPkgTokenSpace +AB248E8D-ABE1-11D4-BD0D-0080C73C8881,WinNtUgaDxe +AB248E99-ABE1-11D4-BD0D-0080C73C8881,EfiWinNtUgaGuid +AB27C87B-91B9-4F1C-B942-8437B164277A,FchHuangshanPei +AB294A92-EAF5-4CF3-AB2B-2D4BED4DB63D,PeiMfgMemoryTestPpiGuid +AB2BEE2F-C1A6-4399-853D-C07C774FFD0D,EfiLpcWpce791PolicyProtocolGuid +AB359CE3-99B3-AE18-C89D-95D3B072E19B,EfiStatusCodeDataTypeError +AB38A0DF-6873-44A9-87E6-D4EB56148449,EfiRamDiskProtocolGuid +AB3E46F0-844B-456E-8911-5D4546172410,EventCtrl +AB4E44B3-1786-4BCB-BB8F-98C349140D69,FchHuashanSsdt +AB52EAE3-1E20-4114-B61A-EC3ECDAAC1F0,AdlNxpPei +AB5A4DF4-F0D7-49A8-BF5C-F25DA04C2533,CpuGlobalNvsAreaProtocolGuid +AB5AD18D-331A-4B7F-9B7F-64EFBAF1AD31,PTInterfacePei +AB5BCFE8-BEE9-47B7-B7E5-7EEA4D357A01,UpdateAsfTableDxe +AB5ED376-DD38-4D22-AE89-B645A4A3236E,SynQuacerI2cDxe +AB6CC986-8D03-400C-9FA3-96609C3B7BD3,AmiUsbInterface +AB741FF0-0B9F-4E6B-AAFA-79402241B814,PreserveCACert +AB78D6A5-7E2A-47AA-9F32-780793C0DADB,RfInventory +AB7ED12E-1D78-4635-AB87-23F00A911EC7,RomLayoutDxe +AB8F1705-7EB6-4D08-A9B3-918BDE24F479,UpdatePcdPei +AB971179-52CF-4D7A-A91E-3B14DB19BB74,SmartCoverPei +ABA99AB9-C7E0-42CF-A584-1C93AC103AB7,DellVideoSmm +ABAA46B8-84A3-4E74-882F-6368F6EDC9B8,SystemUserMasterHddPwdDxe +ABB40EE1-D13C-483F-8490-1EA55F73BCC1,StdBoardDxe +ABB50A68-0CA7-4C9F-8DB4-56C34E01CB95,SystemFirmwareDeviceBlockDxe +ABB74F50-FD2D-4072-A321-CAFC72977EFA,SmmRelocatePei +ABBCE13D-E25A-4D9F-A1F9-2F7710786892,Platform +ABC36AAC-2031-4422-896E-0A3B899AD0B4,Microcode +ABC6BAEB-AA8D-401D-9B17-C6DA6AF4F48E,DashManagement +ABCB1463-3275-4B96-9CBB-ABBDFF4AEDBE,MultiLanguageDxe +ABCDFB96-ED90-4C7E-A82B-EC98F99305ED,CbsBasePeiSSP +ABD42895-78CF-4872-8444-1B5C180BFBDA,EfiPeiSmbusPpiGuid +ABD42895-78CF-4872-8444-1B5C180BFBFF,EfiPeiBootScriptExecuterPpiGuid +ABDD8BEC-9825-4678-AD5A-27C74FADBAA7,TPM20Esrt +ABEA0163-A472-4152-9A07-2E954C230FF5,OemPei +ABFC0212-9344-439C-8653-699234CFAD03,AmdCpmWwanInitDxe +ABFE2830-855B-4A98-94D6-EEB23D1EBF45,AmdIdsDebugPrintDxe +AC05BF33-995A-4ED4-AAB8-EF7AE80F5CB0,UefiCpuPkgTokenSpaceGuid +AC0AD9E7-6BCA-4EF3-924F-BDE0D026BB23,PlatformPort80HandlerDxe +AC255206-DCF9-4837-8353-72BBBC0AC849,OzmosisTheme +AC274B5F-4D79-48D1-96DF-FEE354CF7083,EfiSerialPortTokenSpace +AC3435BB-B1D3-4EF8-957C-8048606FF671,FrameworkHiiOnUefiHiiThunk +AC38DBC2-8525-48F8-9607-FD9C917BE42E,AmdErrorLogDisplayDxe +AC3AE4F1-6050-4609-B701-6A90B0972E74,AmdNbioAlibDxe +AC3DA503-65E7-4153-96FC-8707FB7594FB,ASUSBIOSInfo +AC422CC1-D916-489A-B165-536FDFC633C2,PlatformDxe +AC44EB5B-286B-4A41-BF5C-B75B8286454B,PchAnOddDetect +AC4CE557-F5CD-439E-963C-40F09683DAC5,AppleKeyMapAggregator +AC4E8F32-1CEE-4493-9EF0-AAD8773F8323,RTS5229 +AC5919D9-F137-4F87-869F-D863EDA88ED2,LenovoInitVproPolicy +AC5B47BB-2C77-4688-B555-987E1846C843,AcerProductInfoSmm +AC5E14DD-4567-41F7-9E29-5F52CD314214,X11DPHSmmDriver +AC60ED9F-523E-4F5B-94CA-3961346A00BA,LenovoVariableInitDxe +AC62D8B4-3E8F-4ED2-9AD6-DCEAA1CB96A3,DataAccessSupport +AC64F0C4-25C1-47C8-AC74-B1527456351D,EfiPlatformTypeHedtEvProtocol +AC65572E-F3A7-4D9C-93FE-22A221C14591,DellSetupDMASupportDxe +AC6993CF-43C8-4FCB-840C-B7CF2E079977,PciHotPlug2 +AC6A415B-844B-4288-B618-D14D6144DFE1,FjGpioAbstractionReference +AC6A515B-844B-4388-B618-D14D6144DFE1,FjGpioAbstractionReference +AC6F7D21-3704-4D4D-ACED-FE32C6AAAFF4,DTbtPeiPreMem +AC6FD56A-3D41-4EFD-A1B9-870293811A28,PhMebxHotkey +AC7FA810-44E5-4CA6-9D17-778CC5B034EB,AsrockAmdSetupDxeRv +AC80A942-12F1-4296-922E-30E91F751412,SbSocPhoenixDxe +AC80A942-12F1-4296-922E-30E91F753975,SbSocRaphaelDxe +AC86A8CC-BAE4-4BE9-9D59-4DAC6D7703ED,LEMFactoryDefaultDxe +AC874606-8727-41A0-BCCD-43A4237466DD,EneUpdDXE +AC8F7B00-C65B-4568-8806-9DEA9E5F1085,DellStatusCodeHandlerSmm +AC95AD3D-4366-44BF-9A62-E4B29D7A2206,SmmAccess2Dxe +AC991242-FBB0-42FA-AEF4-AA9746FD68E1,SmuV13Dxe +AC9CF0A8-E551-4BE2-AD0A-E1B564EEA273,AmiCpuInfo_2Protocol +ACA0F10C-04C9-4C4E-9D7B-B7A097F5E1EC,LenovoEn25Qh64FlashPartDxe +ACA24109-6C7A-4CEC-9133-5FB9D8274910,IntelLtsxFit +ACA606BC-0627-4718-A8B9-B7FA160D8096,PdHostInterfaceIteDxe +ACAEAA7A-C039-4424-88DA-F42212EA0E55,PchPcieSmm +ACB93B08-5CDC-4A8F-93D4-06E342DF182E,PchPeiInitPpiGuid +ACC8E1E4-9F9F-4E40-A57E-F99E52F34CA5,AmtForcePushPetPolicy +ACD03321-777E-4D3D-B1C8-20CFD88820C9,EfiRngAlgorithmX931AesGuid +ACD28235-075B-48B5-98A1-DA04FCAF84F3,SiInitDxe +ACD49C8D-6947-490E-AAD1-C338AC67253E,PspClearNVDxe +ACD88BB8-D466-4B8A-8DA5-EC6407A83B28,NvmeHealthDxe +ACDEA335-34B9-4FD0-A4B8-FA4DD0F73958,SmuV12DxeCZN +ACE09B4D-CE11-4E48-8C9C-8D6901F70787,MeOptionsDxe +ACE91E4E-238E-4A8B-9A4F-87B7DC82C066,CvpPeriphSpi +ACED1C77-4EA5-4710-9412-EED3135F9C7D,SaveTraceHubConfig +AD0D149F-BA67-4E0B-A6A2-4E8853673EA5,ErrorGlobeTile +AD14AC1B-DA15-4CE5-A7E2-1F5437EDB4B3,SmbiosMemory +AD15A0D6-8BEC-4ACF-A073-D01DE77E2D88,EfiVTUTF8Guid +AD17A972-5892-4440-A78B-1BFE5F49B709,AsusSetBiosLockDown +AD1A3937-A666-4E2B-9A35-8942A609931C,PowerFailureRecoveryDxe +AD1F487A-BA56-48DC-8EAA-E8FBEA74B8F2,ASM104X_SMI +AD21F7A0-7F5B-47FE-8CC0-241F318CABF5,AppleLegacyStartup +AD3D267D-50E1-4B94-95D3-1025EF5B8391,SecFlashUpdDXE +AD414DD9-076F-40FA-8B6A-1B6779ADECA3,AcpiDebugTables +AD416CE3-A483-45B1-94C2-4B4E4D575562,TcgMor +AD46DFB0-01D8-4D84-BBAB-1359A983AB9F,OemPeim +AD49E1DA-5E83-4A0F-ACC7-67F08CAEAA78,TrEEPei +AD4A0D05-806D-4FE4-96AD-3BD62D8C4CE0,DellDoSiodiagLedDxe +AD53BB27-F696-4213-ACBB-AEFA2F4B8BDC,OemModelIDDxe +AD5B2C0E-F480-4912-875B-6182F056C5D1,DellStatusDetectPei +AD608272-D07F-4964-801E-7BD3B7888652,MonotonicCounterRuntimeDxe +AD61999A-507E-47E6-BA28-79CC609FA1A4,FspWrapperNotifyDxe +AD61F191-AE5F-4C0E-B9FA-E869D288C64F,EfiCpuIo2ProtocolGuid +AD651C7D-3C22-4DBF-92E8-38A7CDAE87B2,VirtualUncachedPagesProtocolGuid +AD6BF297-4E16-4A91-843C-FFCFBF986E51,SecureBIOCamera +AD70855E-0CC5-4ABF-8979-BE762A949EA3,IncompatiblePciDeviceSupport +AD77AE29-4C20-4FDD-8504-8176619B676A,AmiHddSecurityEndProtocolGuid +AD7C7A22-5F5D-4864-A8EF-2B78AD0A52D8,DellUsbExtDxe +AD82C06C-34C0-44F0-BA98-801C3CA7592F,AmdNbioDxe +AD82F436-75C5-4AA9-9293-C5550A7FF971,EdkiiDebugPrintErrorLevel +AD873A33-61E5-45DE-BB73-84F8461FB9EF,DellHddSecurity +AD92822B-30C8-49B1-8AF3-63CCDF19B07F,DxeSmmIoLibSmm +AD9457DD-E964-4562-AE91-1CDF6FCEC52A,POSTCODE0A_BASEVERSIONWMI_SMM +AD9C4381-1EDE-430C-8D42-23767C465D52,EfiUsbKeyboardConnectGuid +ADA0B656-AD68-4281-813E-5ADA5A65583F,EcRotClearVariable +ADA1C665-7A8A-467C-84EA-7172B2B65862,FchSSSataD3ColdSmm +ADB5951F-E8B9-42B1-9BFE-39D7B55484C8,HpRuntimeBiosUpdateCheckSmm +ADB7B9E6-70B7-48D4-B6A5-18FA15EBCD78,IntelCpuPcdsSetDoneProtocol +ADB99273-4FA6-4943-BBBF-565E7CFE9004,AmdFabricRplDxe +ADBDD6EB-27B2-4A42-B392-F29C00C8D861,DeviceAddressPolicyProtocol +ADC0425F-E954-459C-BAA4-60FED1C1162A,VariableBackupRestoreDxe +ADCBFD3F-95F8-4EE9-9F1A-6DA826862D4D,DiagnosticTestBIOSInterfaceSmm +ADCCA887-5330-414A-81A1-5B578146A397,TgaDecoderDxe +ADD70A4D-1067-4FA3-A669-94C82877F106,TpmNvmeSupport +ADDEBF82-A560-46B9-A280-78C6AB61AEDA,ErrorManager +ADF01BF6-47D6-495D-B95B-687777807214,FirmwarePerformancePei +ADF3A128-416D-4060-8DDF-30A1D7AAB699,EfiSmmIchnDispatch2ProtocolGuid +ADF47106-5CF8-4D02-BCF9-BACCC7D3162B,CrbSmbiosDxe +ADF956AD-E98C-484C-AE11-B51C7D336447,ConfidentialComputingSecret +ADFC6F79-AA9F-462B-ABDB-C48E0F6356BF,AmdFabricRnDxe +ADFE34C8-9AE1-4F8F-BE13-CF96A2CB2C5B,ChipsetFormSet +AE02ADF3-E05A-4170-AFC6-C1F0EEE86518,Fadr +AE076D12-F66E-4DD5-8825-86C820A21CAF,DualBiosSmi +AE08C457-5787-4658-92C1-9177417FC0F8,OemPeiSetCstateSupport +AE0B5B70-D044-4456-BA51-970E4C6870BF,EfiTraceHubStatusCodeHandleSmm +AE0CC06C-1167-48C1-89A2-90499DF68FC3,XnoteEsrtDxe +AE2020DF-C175-4344-B755-BBA47744F8B1,PeiVideoTextOut +AE23AAC4-ABB4-4A96-A198-E06CC8475CF7,FchDxeLpcClkRun +AE23D34B-0323-4707-A434-1DDAC210753B,OemBadgingSupportDxe +AE24851D-E414-4062-959D-5F43EA99363C,DellAudioDxe +AE265864-CF5D-41A8-913D-71C155E76442,CpuIoPei +AE3356F4-F95B-404B-B1DE-64EB5D5E5BBE,MemRas +AE3AA8AD-B581-4AA0-898E-14EF42D25F30,XnoteSecurityMenuSetup +AE3D28CC-E05B-4FA1-A011-7EB55A3F1401,EfiDns4ProtocolGuid +AE3D856A-655D-478D-8E48-1661311AA3BF,HpEsrtDxe +AE402620-E6FA-4E09-9B63-3FD5BDABF77D,I225_PXE +AE4C11C8-1D6C-F24E-A183-E1CA36D1A8A9,HfsPlus +AE587172-CA15-48E1-8BE1-29DDF05C6A1E,OemSpecVtdRmrr +AE587172-CC15-48E1-8BE0-29DDF05C6A1F,DxeSelStatusCode +AE587172-CC15-48E1-8BE1-29DDF05C6A1E,OemVtdRmrr +AE58978D-8EB0-42CC-FFFF-FFFFA419F039,XnoteSetupMainDxe +AE6376EB-C813-482D-8005-40023A674EC1,FPSmbiosType140 +AE65A8B4-05A3-4CFC-A486-F3149AA34BC0,DellMfgModeDxe +AE65F02C-EEE9-4AAC-8C73-47AA4D7CF2BE,LenovoFmpDxe +AE67A517-EB4C-4D22-9751-D66470D9B5DF,OemDeviceDisablePolicy +AE68A9F6-3A3E-4AD2-869B-27C927CC5FD2,DellOA2 +AE717C2F-1A42-4F2B-8861-78B79CA07E07,FV_MAIN_NESTED +AE724F8D-62C6-4638-A065-0138F47B6D23,UefiPxeBcDxe +AE7300AB-0E4A-43F0-B077-42B9DFC46033,FjGpnvSmm +AE73630A-022D-4884-A696-F728CBF53AEF,SetupItemLinkageSmm +AE80D021-618E-11D4-BCD7-0080C73C8881,EfiDataHubProtocolGuid +AE87A309-FC97-4E55-94DD-BB1B061CE84A,FjSystemConfigurationRt +AE8F0389-6BA2-47D3-9E55-80B3DD9B8A98,DfciMenu +AE933E1C-CC47-4E38-8F0E-E2F61D2605DF,EfiPeiSmmCommunicationPpiGuid +AE9F1E7C-80C9-4A23-917F-7450BA578E0F,TheftRecoverySmm +AEA6B965-DCF5-4311-B4B8-0F12464494D2,BootScriptDataGuid +AEA7C021-B7AB-4ECE-8035-536C234A40DC,SyncBIOSimagePei +AEA8F032-4601-0189-2411-6C8E3027EE8E,DellDataWipeDxe +AEA90534-A602-46E2-B3E5-1F01DA2664BB,OemVMDHiddenSlot +AEAD58C8-C3E1-4ED2-9193-5E0D5D71803D,StatusCodeLoggerPei +AEB157E1-ECAA-418E-BE87-A8E5FAB12D20,SmbiosUpdateDxe +AEB8657C-AEBF-40A1-9866-BB22C7223FF0,Sha1AndRsaDxe +AEB9C5C1-94F1-4D02-BFD9-4602DB2D3C54,EfiTcg2PhysicalPresenceGuid +AEBB0EF3-9450-43DA-B2CF-323D04C937CF,DellWmiBiosAttribDxe +AEBFFA01-7EDC-49FF-8D88-CB848C5E8670,SiPolicyPpiGuid +AEC4159D-F2FC-4090-95CE-38317A8ED64C,FirmwarePerformanceTable +AEC7B585-9AFC-400B-A8C5-78E135EFF845,ApobRplDxe +AED6AA78-D5BF-4BC5-8CC5-F9EE47CF9299,CapsuleRuntimeDxe +AEDA2428-9A22-4637-9B21-545E28FBB829,EfiEblAddCommandProtocolGuid +AEDB04D0-EE2B-499A-B673-D71AF876CF83,DellSocketDxe +AEE17FF6-B810-4A8A-9D4D-8B9C3289C1AC,SmcSwSMI +AEF41E72-D85E-4EA9-980B-66E5820DE19E,LenovoSmartBootDxe +AEF82756-87F2-4CF6-BE80-E59055295AA1,PEbiosinterface +AEFAF26C-FB6D-4FEF-AF7A-9D78FF201FCA,FirmwareUpdate +AF060190-5E3A-4025-AFBD-E1F905BFAA4C,EfiHiiImageDecoderNamePngGuid +AF1450C2-70DE-44D5-80B1-B90D44277990,PasswordSupport +AF198108-862B-4B46-AAB8-B0B34D3ADE0F,WifiPxeControl +AF1BB1DB-9931-4CB0-8629-B9319BB0EFA0,DfciSARecovery +AF23B340-97B4-4685-8D4F-A3F28169B21D,EdkiiVarCheckProtocolGuid +AF2417F4-7B7E-4C2E-94BB-7A3389A157CA,EfiPeiPlatformTypeLightningRidgeExrpPpi +AF277E13-3F21-40B2-9452-43503BAD0670,BixbyPei +AF29FB7F-EAB7-4211-9684-CE8D4A47A0C7,StaticSkuDataDxeExpertWorkStationRP +AF34C37F-F5D7-47F7-B586-B593CB338C35,ClientronSecureBootDxe +AF382531-52E6-4CC4-B247-DB8E320CBBA3,SmbiosDMIEditBoard +AF3969DD-43BC-43C4-9E46-9C3310AF6DA0,RtErrorLoggingDXE +AF405B70-23A4-11E9-96B9-A0C589EF4E75,DellDiagUiManager +AF43E178-C2E9-4712-A7CD-08BFDAC7482C,UfsPciHcDxe +AF4A1998-4949-4545-9C4C-C1E7C042E056,ScPcieDeviceTablePpiGuid +AF4CC162-D41C-455A-AB45-6DBCC1CD32F3,LpssDummyProtocolGuid +AF4F281F-519F-4A39-8182-4B053D429874,DellTpmBusConfigDxe +AF525A5E-183E-4309-9E49-EA22CF412EAE,MsiBoardECSmm +AF56054C-8B1A-409F-BAF0-893CB964AA4E,FjSysmanWatchdogPeiBin +AF59F2F5-5E28-4E03-80E2-4727545AF811,PchReset +AF5B3C56-95E6-4434-9373-39BB718ACD00,DellFmpInterface +AF5C26EF-CC97-4D80-A2BF-3D0CD5DFC86F,ThunderboltPei +AF6AC311-84C3-11D2-8E3C-00A0C969723B,EfiDeviceIoProtocolGuid +AF784AF2-76E8-45D1-A0FF-68724CE98AFF,EcBlinkPei +AF8898C9-9B92-4556-8318-E425C9DE0A65,F2App +AF8A30CC-08E4-4E73-9E8E-2E39674D9E63,DellServiceMenu2 +AF9BAFE5-3459-4803-B8EE-5D6FC7FC511E,ApobRsPei +AF9FFD67-EC10-488A-9DFC-6CBF5EE22C2E,EfiAcpiVariableGuid +AFA4CF3F-AF71-4C30-A4FB-2910E771F9B0,AmiNvmeControllerProtocolGuid +AFAB5682-F6CA-4E04-88BF-66638C23EFA1,WifiProvisioningDxe +AFB3D17B-A330-4860-9BEB-E3C7D1D49C50,FjSecureServicesSmm +AFB436A3-CE6E-4106-BFA8-ECF7EB1B6486,AsusPTTDxe +AFB575B0-1FAC-0361-B6F3-9D6DAAAAE9D3,OemWlanPowerSwitch +AFB6DFD0-8D22-4931-BEE9-B08F384CC1F7,LenovoCustomizedLogoSmm +AFBFDE41-2E6E-4262-BA65-62B9236E5495,EfiTimestampProtocolGuid +AFC04099-0D39-405D-BE46-846F08C51A31,AcpiPlatform +AFD33148-A91F-4256-84A8-2F8976CE77AF,PowerReportDxe +AFD69E65-1CB3-472C-BE63-0C98A2C0665C,RAIDXpert2_F50_0x00 +AFE62C45-75C9-496E-A23D-DA7B51209B72,CbsBaseDxeMDN +AFE751C5-05D4-4898-BF94-1A4B50F35FD4,DellSmmCryptoAlgorithm +AFF1AFA8-07F5-46FA-A7AB-60F4C993B9BF,MpmKvm +AFF347CA-AEA4-4447-968A-E6FE751C24C6,AmiAfuProtocol +AFFC90DD-B014-4737-89E9-D1A0F50CD25E,CPLDPEI +AFFE115B-8589-456D-BAB5-8F2EDA53AEB7,ArmPlatformUpdateFdtEventGuid +B0090FD6-3DAD-4A9C-B638-83077B751353,HpIciclePei +B00E7F2A-450A-47D9-9372-172ECD15B744,FjS5P +B00EE730-80CD-4178-927D-378A75F9A3D1,RTLWifiDriver +B017C09D-EDC1-4940-B13E-57E95660C90F,AhciRom +B02DE24A-0794-434A-A8A0-04A0F68D857A,N17PQ3Gop +B02EAF8F-28A1-44A8-9947-72DF3A8A4DDD,UefiDMBMEDUSmi +B02F63AF-96D2-4040-A15B-CBB8ADF81933,AmdMemSmbiosDxe +B0392493-4E68-CEC7-992C-F6B5E029BAD2,AmdSocAm4VmrPei +B03ABACF-A532-5E78-ACA0-B11F765B3AFD,CpuDxe +B03D4E0D-5156-44AB-BEDB-9675A3D57D41,PhPlatformSiSmmCodeCheckDxe +B040C9F7-5F6A-4B67-A7E5-4EAD9412F920,AmdFabricBrhDxe +B053ED84-880C-4F7E-A57E-2C82C6E9BCBF,OemWlanBT +B05E6B60-323F-4BCF-9A2B-5DBFB07301EF,AmdNbioEarlyPhaseRNPei +B0649250-512B-41AB-8608-FE0757311B8B,AmdPspPeiV2Ssp +B065BC30-E7A8-4502-B653-5D7A954D2314,DellLegacyBootInfoDxe +B0695C20-F9FC-4372-800F-63B06FB52A4F,OemIp3Dxe +B06F2CF8-8433-41A3-B513-B115C8E7EB8F,BiosUpdateExtendedPlatformPolicyPei +B07156B4-5947-4885-A3ED-FB1DFA949AE4,PdHostInterfaceItePei +B0732526-38C8-4B40-8877-61C7B06AAC45,EfiCpuIoProtocolGuid +B0767CBC-4705-4D35-8866-17A9B85E3843,EfiMemoryConfigVariableGuid +B078474C-A6E0-465D-8229-B46110CC437B,OemAdjustHsioWorkaround +B0792197-ABC3-4BB1-9FD3-CBEA8FD41373,BaseAmiBeepLibNull +B079EE3C-37A6-47E6-BF8A-94A7E85C41AE,MFTSmm +B085B8FC-CCFC-4337-A59C-DE4ACA1B0365,AmdCpmSocAm4SmBrPei +B08A11E4-E2B7-4B75-B515-AF610668BFD1,EdkiiPeiBootInCapsuleOnDiskModePpi +B091E7D2-05A0-4198-94F0-74B7B8C55459,EfiFlashMapHobGuid +B092E8A7-5B70-4ABC-944F-6A63195B0DA7,HpRpsuDetectSmm +B093BDD6-2DE2-4871-8768-EE1DA57249B4,TcgPasswordAuthenticationGuid +B098F766-B17A-4005-8309-EB23F1448C15,AmiCmosBadFlagHob +B09CB87C-67D8-412B-BB9D-9F4B214D720A,VTd +B09E43FC-FF63-4C77-A05A-AA5DC35D5032,ECHeartbeatDxe +B09ED1E3-DDDF-429F-9780-C3B0C4857924,ScsConfigGuid +B09FBA70-839F-4079-920B-81D8964361F6,AmdNbioSmuV8Pei +B0A034CF-41CE-4104-8ED3-4F97E8ADB981,SioDummyDxe +B0A6DB04-8A0F-4F4F-9C45-C3344515A583,FjGabiFlashCoreAbstractionSmm +B0ADDE44-2985-40FE-9484-1B08772931EE,WheaERST +B0AE3E81-C6B0-4D35-AD51-9117E0651EA3,PlatformEmmcHs400TuningInfoGuid +B0AE51A7-E711-4F1E-BA16-1012261A6D71,WifiFmacDriver +B0B2AB82-2E9B-4F89-A3D8-F5A99968950C,EfiPlatformTypeOpalCitySthiProtocol +B0B86877-C921-4D8D-9957-B73D6BA20BAD,EcCapsuleDXE +B0BAADB8-F11A-4C35-8F24-A57651133210,D01DbmfFileSelectUIDxe +B0C0DDBA-AF2E-4804-8EAD-E40651230D83,DellUefiClass3ConfigDxe +B0C2372B-9393-4CBC-9CAF-53913C9DCE29,FlashDeviceFvbRuntimeDxe +B0C4F9D7-2F31-4B68-BF3E-C5AFACD59025,FjPostScreenMfgPowerOffDxe +B0D0314D-57C3-4453-9486-18822D8C81BA,FmpDxe +B0D3C4C9-5954-4A84-80BF-144CE9F02223,PostBackLightControl +B0D542D9-E531-418F-B7CA-B9F58D6DDA45,OemCloudBootInterfaceSmm +B0D6ED53-B844-43F5-BD2F-61095264E77E,PchSmiDispatcher +B0D8F3C1-B7DE-4C11-BC89-2FB562C8C411,EdkiiSmmVarCheckProtocolGuid +B0DAEB4F-1EF7-11E4-BBCC-78E7D1AF36D1,HpNetworkBiosUpdateDxeDriver +B0E11362-00DA-4611-8D7D-10EF2527F653,VideoBiosDataBlock +B0EAE4F8-9A04-4C6D-A748-793DAA0F65DF,TlsAuthConfigGuid +B0EB46FF-DB1D-43F8-8339-B8103A3A1412,PciDxeInit +B0EB46FF-DB1D-43F8-8339-B8103A3A5AE8,PciDxeInit +B0EC5D53-7481-4821-AC57-69DDB2868DE6,UndiLayer +B0EE53D4-A049-4A79-B2FF-19D9FAEFAA94,EcpPeiPciCfgPpiGuid +B0F0D157-AD8F-45EF-BFD6-F525AABC3092,GabiSettingItemDefaultRestoreSmm +B0F901E4-C424-45DE-9081-95E20BDE6FB5,TcgConfigFormSetGuid +B0FC49FA-4F5F-4542-81C4-E54DB9592022,LNVRNR +B1095967-FCF4-4C53-BC16-7E3DF9C247EB,StdFlashPeiLibNull +B10ADFA1-9E43-487F-AAF3-A7A9BDEAF4AC,ProgressBarFullRightEndcap +B11216C5-44E4-472C-ACB7-128A5A3AD7A1,OpromUpdateDxeNeonCityFPGA +B11E930D-A082-42E2-A7F2-C63767A4D3E7,AsusSIBoardDxe +B122A262-3551-4F48-8892-55F6C0614290,EfiFirmwareClassGuid +B122A263-3661-4F68-9929-78F8B0D62180,EfiSystemResourceTableGuid +B129AD37-3F38-444B-E425-9AA991A81893,HpOsToUefiInterface +B129FD4F-3E47-4BAA-B050-03CC41599BAF,OemI2cDevices +B12BF2D5-05A7-4CAC-8210-0FED4B3CD67D,AmiCpuPeiPreMem +B12DC6A0-1022-46B6-B995-8646AD5E5EEB,AcpiPcatProtocol +B13AFF9D-C66D-46AD-8C23-723482EFC841,PlatformEmmcDxe +B13EDD38-684C-41ED-A305-D7B7E32497DF,Smbios +B144E169-AFB1-4426-B0EC-099728909342,MuxGraphicsSwitch +B147CD7E-17D3-4D66-AB39-472B1DA659C1,UefiTableDxe +B14AFFC9-F12B-4EAA-B335-1CD84889F6F1,CrConfigUtil +B14BA91B-CCD9-4CF9-8FF3-BD159DDE760C,FjScrtyBootService +B15239D6-6A01-4808-A0F7-B7F20F073555,Ax88772 +B15E091B-C90E-4F0D-81E4-BB32A2DA68FA,OemCloudBootInterfaceDxe +B1625D3C-9D2D-4E0D-B864-8A763EE4EC50,TcpDxe +B162D432-E339-4316-862D-00280AB6A07E,BiosEventLogConfigUtilDxe +B1659B1F-F74E-4866-9D66-2930900391A5,FwBlockService +B167C2F5-E26A-4DFF-8E1C-0807C7F02A88,AmiCcidIoProtocol +B16F81D3-A684-439D-A721-F617C9EB8ED8,FjCameraCapsulePei +B177D4A9-D6E3-48A3-92F7-B548DE879D94,SraDxe +B178E5AA-0876-420A-B40F-E39B4E6EE05B,WarmBootPei +B180019E-9820-4DC0-8B40-A773E23D4F35,RamDisk +B18348FE-D540-4ADA-8745-172C109D3A22,FjExtDxe +B18D3493-7E62-48DB-A4DA-8120BFB14394,FdiskOemSmmProtocol +B18E803F-F4D2-49DC-9C10-643174F56B97,Usb_Lan_Ax88179 +B1951813-0CFA-418E-B312-33368D5902EB,SystemPwSmm +B1975734-77C2-4827-9617-914883F3B578,ATFHobPeim +B199DEA9-FD5C-4A84-8082-2F4170780305,EarlyPL011BaseAddressGuid +B1A44F23-EDCC-4425-A1E6-22DA61640BA7,AsusESALaunchDetect +B1A49A06-B630-4BF5-85BD-0997CE642D49,TouchDriver +B1A81722-50C3-4AA6-8BBF-DD0D83989134,HhmSmm +B1AEE818-B959-487B-A795-16C2A54CB36E,DellPeiMain +B1B621D5-F19C-41A5-830B-D9152C69AAE0,FdtTableGuid +B1BAC051-D5C2-4AC1-AC7D-9D2F518A1E7B,AmdApcbSmmV3 +B1BE0BC5-6C28-442D-AA37-151B4257BD78,EdkiiNonDiscoverableXhciDeviceGuid +B1BE2060-4EF0-49ED-AD8A-2F7230573034,OEMIp3ECPei +B1C6D274-064F-46C7-A924-DCF85F3D747E,AmiRedfishIScsi +B1CAA183-FA67-44F5-8D77-B528C309207E,DxeDbgModuleLocator +B1CD7448-319C-41AA-821D-3E606BF6F90D,SmcOemActivation +B1D7B153-118C-48EB-982C-B55FCE99F6F4,GpnvErrorLoggingToken +B1DA0ADF-4F77-4070-A88E-BFFE1C60529A,AMITSE +B1DBC95C-0EE7-4261-B290-5BF0A4DB9527,DellSmmRadioExecProtocol +B1DD2F34-DA6D-4B8D-9D1C-DCB76B6E400F,NvStoreRestoreDefaultSmm +B1DFF070-1322-4CD9-A5B0-F56BA2B54E23,AmdNbioGfxMDNDxe +B1E9E2CA-B078-4070-BCCD-87449AC7D2A6,CpuS3Pei +B1EE129E-DA36-4181-91F8-04A4923766A7,EfiDriverFamilyOverrideProtocolGuid +B1EE7CB1-5D00-467F-9E60-24CD8341937A,SetupLoadDefaultDxe +B1F7AF2F-2807-478C-A893-2BF4DDD1F62B,PeiVariableAuth +B1FBF84A-C091-4A80-A744-23442A2B7BDF,AmiChipsetPkgTokenSpaceGuid +B20005B0-BB2D-496F-869C-230B4479E7D1,EdkiiNonDiscoverableOhciDeviceGuid +B219E140-DFFC-11E3-B956-0022681E6906,DnsDxe +B2360B42-7173-420A-8696-46CA6BAB1060,MeasuredFvHobGuid +B23AFDA0-D1D3-4F5A-B01F-62ED16A97863,HpAudioPei +B23CE2C1-16A0-4F69-980A-95C77216F9A2,EfiPeiPlatformTypeKyanitePpi +B242BEFE-9E51-4A0F-9ACC-8323F6CA27AE,FjGabiFtsSystemDataDxe +B246672E-71A8-453E-A0F2-95DECD7A1B86,H19ComputraceSmm +B2585B69-FB63-4220-844A-8FBEA8BF01AF,PeiIoLibCpuIo +B25B13E9-0324-4F59-AEE6-AC4A5D5785CC,EcBlockPei +B265299C-654E-4DD7-8616-358561C008A3,SystemVariableStoreManagerSmm +B268252E-541A-4907-9542-6AC8196C5D2D,AmdNbioPcieZPPei +B26B30A8-2172-4A46-9B4F-4D5B08DD6E40,T23OwnerStringService +B26BCCA7-D044-49E1-B1B5-E2A96BB7C225,MitigationDxe +B26E6830-629F-443F-BE20-D26E502C25BC,AmdFchHwmSmm +B273CC44-E62A-41DC-9CAD-BDB4235459D8,UnicodeCollationDxe +B2768462-14E4-4B8F-AFB0-B274B367BAF0,LoadSetupDefaultDxe +B27DAB38-9814-4E06-A5A2-65AE9A14258F,AmiIntSmmCommProtocol +B28CBC31-FD64-404E-83DF-ED162AF76B4B,CertificateBasedAuthenticationDxe +B29328EE-68FC-4966-9ACE-BE21FADB7328,AsusVariable +B295BD1C-63E3-48E3-B265-F7DFA2070123,AmiMultiLanSupportProtocolGuid +B2A191A9-9BAC-4C83-A2F3-D5F6E71EFD03,ArmPlatformSysConfigLibNull +B2A23305-9455-489C-AA81-21DB48C41EAB,LenovoAoacDxe +B2A3D57C-7071-014E-B3EB-3C98D09CB32E,IntrusionDetect +B2AB115E-C8B6-4036-BF31-E74BD8926CCE,DxePlatformAmtPolicy +B2AB8AD0-5ED9-435F-B223-356B645D547B,AmdCpmABRecoverySmm +B2B0F1BD-5791-4802-93F0-71D3A0FE993D,ClientronServiceSmm +B2B73FA6-7224-49D1-82B5-1DBB115F1C50,OdmAudioLib +B2BD9B02-9DF7-4E4B-A484-C27988EFBC77,AsusMbSwWmiDxe +B2BF51E0-6543-4ACB-B09E-FD826E1AF4C0,RasClvPcieErrHandProtocol +B2C62021-9E80-4250-B567-896EA8360AD1,DellFlashRecoveryImagePei +B2C7D8F7-4E7F-46A9-8CDE-F9FB6D276278,EfiAmiDebugRxPkgTokenSpace +B2C9CD52-86B3-4031-B830-8BD84495ABC8,HddSpinDownDxe +B2CD74DE-11F9-418C-BF2E-DAC3035AAB7A,IsPlatformSupportWhea +B2D0CEAF-848E-4B07-BFEA-6FE6C740B3D2,EcMpmPei +B2DDC6BE-D2EE-4EF1-992C-2CD695115DA3,AmdCpmOemInitPeim +B2DED54E-47CD-8416-1818-FBB243809984,AmdSocFp6RnDxe +B2DEDC91-D59F-48D2-898A-12490C74A4E0,EfiIfrBootMaintenanceGuid +B2E56A22-DFE7-4850-97AE-10E76112DE05,BatteryInfoDxe +B2E6299D-686A-4214-B070-080367FC5340,DellInstallHiiPidListHobPei +B2F436AC-A127-4EE8-957A-5048606DD681,MarvellNicSerialDriver +B2FA4764-3B6E-43D3-91DF-87D15A3E5668,AmiAhciBusProtocolGuid +B2FA5764-3B6E-43D3-91DF-87D15A3E5668,AmiAhciSmmProtocolGuid +B304F34D-B27B-452C-8931-CF60A2F0D268,FchProm21GpioDxe +B30DFEED-947F-4396-B15A-DFBDB916DC24,EdkiiPeiSdMmcHostControllerPpiGuid +B31FF060-8363-11DF-8395-0800200C9A66,SystemAhciBusSmm +B323179B-97FB-477E-B0FE-D88591FA11AB,PeCoffLoaderProtocolGuid +B3246CB7-E9D4-419C-9E0C-84E10A3CD2FD,HstiIhvProviderDxeFHF +B324F29B-5E97-4BF9-B4E0-5125C1F605D5,AsrockRtlansmi +B326872A-4DC2-4DB3-88B2-F6C4475F8C91,CpuConfigGuid +B326FD7C-F982-410A-96C6-1C1E499E1559,WyseThinClientDxe +B336F62D-4135-4A55-AE4E-4971BBF0885D,RealTimeClock +B342BEBB-41C3-40AB-AA70-E9F3742D1835,AmdCcxZen3Dxe +B344259B-9957-4548-8BD1-B31464BB8370,DataStorageDxe +B347F047-AF8C-490E-AC07-0AA9B7E53858,EfiWinNtSystemConfigGuid +B34ADD50-05D4-4C99-BC55-F3F2F7F52E1A,LegacyToEfiDxe +B34E5765-2E04-4DAF-867F-7F40BE6FC33D,ExtFs +B35AD166-FCBA-4D4D-89C7-4B47104E3AFD,AppleSpiIoSkl +B3685A91-F96F-4959-A539-A63C3B9ACED3,UsbLanDriver +B3711230-CA04-4F11-9A84-2D8111F8AA83,EcBlockSmm +B3737A34-628C-43CF-9A65-C235772F1819,FjScrtyRuntimeService +B3738534-9051-40D1-9333-91284A5990CE,AmiPciHotPlugLibNull +B375D24E-863A-2DC3-C429-7DAB7323AB9B,SceBootOrderSaveRestore +B3762FA2-54D6-4EBC-84DE-4CFA9340FCB3,AcpiAMLDxe +B37C08EA-12BB-440F-8169-389E1705DA16,OemGlobalNVSDxe +B38573B6-6200-4AC5-B51D-82E65938D783,RecoveryOnFatIdeDiskGuid +B3884E99-9CBC-4CE8-855E-53A12ED0B8F4,AsusIpmiPei +B38CFE42-F0A2-40A5-8F95-EAE71D32B5D3,RtHooks +B3903068-7482-4424-BA4B-405F8FD7654E,SiPolicyHobGuid +B3930571-BEBA-4FC5-9203-9427242E6A43,EfiBluetoothHcProtocolGuid +B396DA3A-52B2-4CD6-A89A-13E7C4AE9790,AmiTcgStorageSecurityProtocol +B39C4342-F66D-40C6-85B4-B529DE7B6A64,UpdateRandomNum +B3ABBE0A-8B28-4446-BB2C-4409BCC75FD9,AsusGpnvDxe +B3B0654A-969D-4096-86CB-27E262A02083,PeiCoreEntryPoint +B3B88F4B-7042-488E-A255-66F965E8D435,PasswordPopupDxe +B3B99742-BE07-4CE9-A1AF-B36AD93D74B4,FjIbvNvramGateReferenceSmm +B3BFAB9B-9F9C-4E8B-AD37-7F8C51FC6280,EfiPeiI2cMasterPpiGuid +B3C14FF3-BAE8-456C-8631-27FE0CEB340C,ScEspiSmiDispatchProtocolGuid +B3D3502E-CB82-4017-AB34-2F17D2D7035F,PepBccdSmm +B3DA895C-6A27-4C4C-94E4-2359BE2532F5,SecureEraseDxe +B3DAE700-2A77-4EA4-AF79-3297B484BE61,AmiMeasurePcioprom +B3E123D0-7A1E-4DB4-AF66-BED41E9C6638,ScDeviceTableHobGuid +B3F56470-6141-4621-8F19-704E577AA9E8,DriverSampleInventoryGuid +B3F79D9A-436C-DC11-B052-CD85DF524CE6,EfiRegularExpressionProtocolGuid +B3F9713B-70CC-43E9-BC34-D960C6F4ACC9,FchKeithDsdt +B40612B2-A063-11D4-9A3A-0090273FC14D,UsbCbi1Dxe +B40612B9-A063-11D4-9A3A-0090273FC14D,UsbBotDxe +B40637B3-4270-4D2F-B2B5-D41CFC4E0A56,CapsuleSmi +B4186561-8967-4113-BC5F-284B7670C4A0,DellDxeDelay +B41956E1-7CA2-42DB-9562-168389F0F066,BootGuardPei +B422FB70-E835-448D-A921-EBA460E105B6,SmmIpmiLibSmmIpmiProtocol +B4282EDB-2371-44E0-9AB3-F33B3F7AA7CC,SecureBIOCameraSonix +B42B8D12-2ACB-499A-A920-DD5BE6CF09B1,WdtProtocol +B42E97CF-B811-4A09-9810-FEE8F53A561E,PlatformHstiDxe +B430F89F-EB33-4514-B490-1885ADDBF840,TypeAEh +B43348C1-E0AA-4767-AE22-2F31333152B6,L05BatFwUpdateProtocol +B4339807-7CAC-49BA-9FB7-6231C622F270,BeginStickyBootButton +B43499EA-57B6-4015-BDBD-AEA5D3D4F592,ApobBrhDxe +B43B03C4-FEB0-410B-A0A0-C25B1C8F8DD8,EcStorageAgentDxe +B441DF87-8D94-4811-85F7-0F9A7BF89D2A,MeAlertAtHandler +B44A486C-8BB3-457A-A8CE-F89B179C9504,DellEcIoPei +B4536FB5-E251-4EDA-8BCF-D43875BD1A11,GnbRenoirRouting +B4536FB5-E251-4EDA-8BCF-D43875BD1A37,GnbRavenRouting +B4571193-961A-4D20-A111-91C8B024ED79,SwSmi534D0640 +B4598C09-DA08-5F75-A956-2CFF901B1C24,MonacoFont +B45B5FC4-D6A6-4523-A229-E7772097EF14,DellLegUsbMemInfoDxe +B45EBA39-D53E-4A94-A839-D501633A5918,SystemNvmeAspiLegacySmm +B461563A-CBA3-4396-9051-7F8B109F60C5,AsusDxeSmmNvram +B469B35A-0934-4039-9A36-7382C428F892,FjVariableRt +B47417C7-E21F-4AC9-B0A2-7A158223A137,SetupConfigUpdateDxeNeonCityEPECB +B4788552-650A-43D2-BFE4-324B4E1B435D,ToBootEvent +B47EDFE6-D417-4161-950D-E824E920E5F0,AcerGetBootMode +B48D9BEA-84FA-46D5-B289-3BC77BB9EE33,OemHookDxe +B4909CF3-7B93-4751-9BD8-5BA8220B9BB2,BootManager +B494DF39-A5F8-48A1-B2D0-EF523AD91C55,PeiPolicyInit +B4A1208E-4D9A-4EA2-9D6B-E41A61E6C5AC,PeiAmtPlatformPolicyPpi +B4BBA6C8-121F-457E-A06E-54331EB81C42,EcRotDisableSecProt +B4C26857-8FE5-42BE-968B-39F45E921D45,AppleDxePState +B4D311E6-721D-4051-956D-2410C1D789AA,TseSwitchingToPostScreen +B4DE05C0-1BD0-11E1-8F0E-77F34724019B,TbtOemBoard +B4E0CDFC-30CD-4B29-A445-B0AA95A532E4,SmmAccessPei +B4E58F43-730A-46D7-B15F-1E06203EFC28,BxtRefCodePkgTokenSpaceGuid +B4F03647-68C2-49E7-4A4A-EBA399F55EB2,HpLinuxRepsetWrapperWks +B50AB2CA-48D0-11E4-A6D3-B8E8562CBAFA,SerialMojoDxe +B51AF856-7196-433C-885E-C7DEC8384266,Manufacture +B51B8D2D-D28B-4FD5-9872-888B99F8A292,LEMEventLogProtocolSmm +B52B06E8-FB01-4404-8768-5C9417B33849,N17PQ1Gop +B5320E5F-0875-42BC-A5B7-15AF36CE87CF,TcgDmarDxe +B535ABF6-967D-43F2-B494-A1EB8E21A28E,AppleRomInformation +B53BE3D7-3BA8-4868-A02A-8E15FB2C9299,CommonElogDxe +B540A530-6978-4DA7-91CB-7207D764D262,FastBootVariableGuid +B54299AD-B521-4BB8-A361-689249FE72B9,AodSmm +B55600FD-A787-4EF3-803A-D1C9B546F24E,ErrorLogReport +B55A4515-5895-4EA8-845B-75B7480F6502,SmmControl2OnSmmControlThunk +B579B530-C797-4839-883E-EFCABD7756E9,VerbTable +B57A1DF6-FFDB-4247-A3DF-3A562176751A,UefiDebugLibStdErr +B57EC3FE-F833-4BA6-8578-2A7D6A87444B,EfiSpiNorFlashProtocolGuid +B5852752-C452-4666-B189-03EEE5E3A07B,KEMoPLATFORMMENUDxe +B589283B-0C57-4600-9AC8-493F5AB9D333,DataAccessHandler +B58A69FE-163E-4CC0-A487-304D34D5489F,EfiTcgMADriverHobGuid +B590D584-A947-4888-B468-0A449309A10F,FchS3SaveDxe +B597FB4A-3527-4982-A4E4-8E212C3CCA9C,AcpiSdevAcpiTable +B59AE9E1-C127-4EED-A3A6-4A0772CF7A4E,EsrtFmpDxe +B59DAEA4-FADE-413E-A522-13639044AC2D,ElinkPei +B5A05743-9B71-489B-A0ED-A0EB3950D23B,SecPeiDxeTimerLibCpu +B5A7329F-0D17-401F-9DAD-A090F8AA0BAC,OemPei +B5ADE90F-DC14-47A7-8002-E87238AAE930,LEMEfiNvmExpressPassThruProtocolHook +B5AE312C-BC8A-43B1-9C62-EBB826DD5D07,GrubFile +B5AEB34F-3047-4955-B880-ADD36D86DC0F,EdkiiPayloadCommandLine +B5AF1D7A-B8CF-4EB3-8925-A820E16B687D,BootScriptDataBootTimeGuid +B5AF45A9-C3EA-41EF-B65C-4EA982DA9D49,KvmPlatformDxe +B5B1181B-ACEE-4CC7-866F-9D8DFD27B399,LenovoEventLogVariableStoreDxe +B5B35764-460C-4A06-99FC-77A17C1B5CEB,EfiPciOverrideProtocolGuid +B5B4E5D6-1866-466A-8782-23FED9EC359E,CrisRecoveryGlk +B5BB551E-F2A7-43B9-813A-F77DD80900F5,HpCertificateManagerDriver +B5BD8969-0978-414B-BA9F-C46B0A95B76B,DellReFlashSmm +B5BE0BFE-5882-4189-80F3-9A2383F574C2,EfiPlatformTypeKyaniteProtocol +B5C59087-FEAC-4B41-9D80-790BA5AA070F,FwVersion +B5C63B66-55E8-44DD-9993-BD8D06B55A4B,RemoveSMBIOS +B5CB5393-7FDA-4383-B660-055C7E8AD991,KeyboardBacklightBin +B5CEC017-74CB-4E10-BAC3-924A4CC629C8,AmiTseOemPortingVar7 +B5D09084-80AD-4759-B51C-27548AFB8B8D,EfiGpioProtocol +B5D0D3B8-4B79-4A48-B981-24201FAF200C,H2OVerifyRegionPei +B5E7C7AF-A3E7-4D3C-B217-04596E4C368F,AmiRedFishSecBootApiGuid +B5F33FB5-66D5-4901-BAF1-F0C774FC6588,VgaDriverPolicyDxe +B5F53C73-3A8B-49E3-A428-B7D15A2FD994,CbsBaseDxeRMB +B601F8C4-43B7-4784-95B1-F4226CB40CEE,RuntimeDxe +B60A3E6B-18C4-46E5-A29A-C9A10665A28E,EfiI2cIoProtocolGuid +B60D320C-25AE-4DCF-B848-196A7E55972F,KeepCriticalData +B60D67C6-9546-4C1D-B1DA-681B001C53C0,H2OUveConfigUtilDxe +B60DC6E8-3B6F-11D5-AF09-00A0C944A05B,EfiSalMcaInitPmiProtocolGuid +B619A1FF-3B3F-4941-B0F4-2B053BBD1720,FpgaFvDataLibPei +B625B186-E063-44F7-8905-6A74DC6F52B4,EfiDns4ServiceBindingProtocolGuid +B629D9F6-D390-4FB3-AA0A-D248C73EA8F6,SmcOobMd5 +B62EFBBB-3923-4CB9-A6E8-DB818E828A80,MebxSetupBrowser +B633AD75-118C-4E7C-BEDF-A31D3234221E,SmmStatus +B6363410-FD56-4D85-A9C4-D7041C0B51CA,FjMfgSetPostPassedGpioDxe +B63BF800-F267-4F55-9217-E97FB3B69846,DynamicPageCount +B63EBF4E-D196-40BA-AB63-1FA9A6068E84,LenovoOsOptDefaultDxe +B63F8EC7-A9C9-4472-A4C0-4D8BF365CC51,EfiSdHostIoProtocolGuid +B6460A49-0AC1-484F-AE58-F16EB239DB3D,TpmBootFlowVariable +B64702DA-E6B5-43C8-8CE8-D253071E9D6C,RedfishRestExDxe +B65694CC-09E3-4C3B-B5CD-05F44D3CDBFF,MmFvDispatch +B65971BE-BABF-49ED-9DD2-48EC8DB4ABD3,LenovoSoundService +B65BF670-FC37-4225-AB85-EC960A7A1ED9,UsraRegisterFilterLibNull +B65F896E-6E6D-4D5A-8BCE-2E458E971D6C,AmdPspPeiV2Rpl +B66C5FDE-2483-475D-8A6B-BFB6B751E20C,AmdHotPlugBrhSmm +B670E168-BD14-4D33-86B0-E632848403F1,AmdMemoryHobInfoPeimV2 +B674D90A-9BDA-410D-A26C-14D6AFFEBD6E,CompalCMFCDxe +B674D90A-9BDA-410D-A26C-14D6AFFEBD6F,CompalEDIDDxe +B675297C-4203-48E5-AF9F-B500C7C47BAC,UsbTypeCChargingSmm +B67854CB-34C7-435A-83E4-A1117B68E259,FjGabiEntrySmiDispatcherDxe +B686FCA1-9462-4E91-A704-A68C834100A4,SetupConfigUpdateDxeBlizzard +B68EFDCA-BEE2-4BF6-B86E-45DC3CCBFE3C,DellDoSiodiagLedPei +B6993DC9-A51D-47E2-8EA1-BA1D80CCA822,FchSmmDiagDispatcher +B6A2AFF3-767C-5658-C37A-D1C82EF76543,MeUma +B6AF30D6-3EDA-4C72-9352-43DC3DC82752,SioSxLedControl +B6B5FAB9-75C4-4AAE-8314-7FFFA7156EAA,VARBAK +B6B643B8-2B41-4A61-A224-D4F476EF580C,AmdCpmOemInitDxe +B6B9295F-CABF-4CEC-BB14-FE4246F2173A,iFfsDxe +B6C0DCB6-434E-4BEC-BDAC-8EE7ED8A4EC8,ArithChk +B6C1C466-E78A-4202-801A-B7950E956E0B,ProjectDXE +B6C26249-C597-46FA-B559-7537F04A3564,AIMTSensorInfo +B6C9FA82-9B26-4BE9-8C40-87A370E48365,AmiPlatformWrapperPei +B6CB37E2-E2FE-400D-AAC2-A093EE2C55F1,VariableCmosDxe +B6D47007-1445-41DC-BC8C-8AC34D7FB236,HpMMIOHConfigDxe +B6DC988A-3D85-414D-888F-7816263533D8,UcodeCapsuleDxe +B6DD6150-70B2-4DB4-AD9A-3C7C2B04E580,AsusEcDxeSmm +B6E17DD5-5CA0-4E3A-858C-A14345AE0B83,SwSmi534D0040 +B6E78A31-AF84-4B5D-92FC-5077C483F891,PostCodeDxe +B6E9A733-EB75-41B6-B30C-009BCF3801C8,BasePostCodeLibPort80 +B6EC423C-21D2-490D-85C6-DD5864EAA674,PeiBaseMemoryTestPpiGuid +B6F44CC0-9E45-11DF-BE21-0002A5D5C51B,MmcDxe +B703C820-4D3D-4658-8EED-5B2F9DE54711,efi_pop_LF_pressed +B7084E63-46B7-4D1A-8677-E30B53DBF050,EfiFrameworkDevicePath +B709EFA0-47A6-4B41-B931-12ECE7A8EE56,EfiSmmPowerButtonDispatchProtocolGuid +B70CDF18-CFE2-453C-AF07-31CAC6345A16,HpCommonSmm +B70F32F3-28CC-40BC-8E0A-682783BD6F68,BiosPasswordSmm +B7139637-C114-447C-B73E-CDBCD307BEBB,WinCSMDxe +B716A6F8-F3A1-4B8E-8582-5A303F1CDD64,PchSpiWrap +B71ECD12-E01E-440B-AA52-4D6E59D45B3C,DellSecurityConfig +B723EFF4-EE4A-40BD-BD7B-22272E36B3E7,ObbyFirmwareFileSystemFvGuid +B72B4B3A-1BE2-44BB-9EDB-B6215F113682,FjIfSecureBootAndRaid +B733C141-E88F-4786-94AF-8B87BC4867FE,PttSsdtAcpiTableGuid +B7358BEB-6A52-4D50-98F9-7EDD70B4B320,CommonPciPlatformDxe +B73D3EA3-8C99-4682-88D5-A08EB6BFD561,IT889XSmm +B73F054B-D1F8-4496-98E8-DFEACF8D8511,ClientronBds +B73F81B9-1DFC-487C-824C-0509EE2B0128,DebugServicePei +B73FE497-B92E-416E-8326-45AD0D270092,IbbrFirmwareFileSystemFvGuid +B74B152F-5271-498B-A4A2-5722CBBEC614,DellPolyFuseStringPolicySmm +B74BB37A-ECA2-4F79-A544-90569ABE6B99,LenovoSystemSmmCommunicationSmm +B74E676E-3B2E-483F-9458-C378FE0AC69F,Tcm32FileGuid +B74EAE11-AAEE-476A-AB0F-351063D67825,MeUpdate +B750C811-02C2-4BED-99B2-8C6960080D45,IrqBoardInfoOverride +B7520A2D-509A-423B-B7CD-E320E805C7E0,Usb4PlatformDxe +B7542192-9E4B-427F-88FB-18A0198236E3,PdHostInterfaceTiDxe +B7543E56-08D7-4C4F-B5D6-7E3ADFCB82C4,FjOemActivationSmm +B7564097-959B-470E-954D-920EC49DE19C,AmdLegacyInterrupt +B759169B-61E2-4F92-9447-23E3DCD33CEC,AmdCcxZenRvSmm +B7611005-1F26-45BA-A3DB-01F39DDB2785,BootMode +B761DA21-76EC-4AB0-99E8-4DC251B72CB5,DellSmmEcProtocol +B76373AA-0259-416C-8170-DE9A0B6F955E,BzmDxe +B76E5014-EB63-47EB-8915-686FCC3820B9,AmdNbioBaseCZPei +B7784107-973C-4957-905E-54455A47E07D,AmdNbioPcieDxe +B795675E-7583-4F98-AC6A-F9DDBBCC32E8,SystemFirmwareManagementRuntimeDxe +B796223A-3776-4010-BABD-7E138F9167FC,PlatformSecureUpdatePei +B7963BA1-D5A8-4ABD-B5CE-41940B006901,WakeUpInDxe +B798078A-F00D-4F90-9DCA-D4326EF84BBF,HPReadBackCreateHpCleanNvram +B7A1F481-1298-473A-A832-4D8AB83331CD,OemSetup +B7A1FDA8-CB3E-4E69-87AF-B67FEC563548,GnbIoApicUpdate +B7A5041A-78BA-49E3-B73B-54C757811FB6,IdeBusPei +B7A5041B-78BA-48E3-B63B-44C7578113B6,FloppyPeimPei +B7A777D1-6EB6-469E-AD1F-1165EB92B3FF,DellPropertySmmProtocol +B7AFDD62-3E29-4FF9-9236-3AAB2A8C82F2,AmdSmmControl +B7B82AD8-3349-4968-A940-7B8C265FF9B4,RtkUndiDxe +B7B82AD8-3349-4968-A940-7B8C265FF9B5,RtkUsbUndiDxe +B7B82AD8-3349-4968-A940-7B8C265FF9B9,b57undix64 +B7BC0E96-57D2-4310-AEEF-74AC77DF0DAF,SetupXpBoot +B7C14441-ACA2-4F7F-8AB1-47B9C88635A9,DashIoCfgSmm +B7C2AB7A-8D0B-4A95-892C-C93F30A673C8,AsusRecoveryFailedDxe +B7D19491-E55A-470D-8508-85A5DFA41974,SbDxe +B7D9F0D7-EBDB-4EE4-AB77-B30C4B9093CC,TbtSmm +B7DDFF7A-1726-11E6-B12F-B8E8562CBAFA,WiFiPlatformDxe +B7DE919D-E2F1-45EA-B66C-D1E035081894,AmdCpmThunderboltSmm +B7DF1944-C9E5-473C-BFCB-34EF8155B373,HpM2IoExpanderSmm +B7DFB4E1-052F-449F-87BE-9818FC91B733,EfiRuntimeArchProtocolGuid +B7E329EC-AD60-4D61-86E3-01A7904E223D,gear7 +B7EE4835-84CE-4B15-BF52-2D11574CE470,HardwareSignatureEntry +B7F50E91-A759-412C-ADE4-DCD03E7F7C28,XhciDxe +B7FC8359-5175-457C-B591-8AE8FDC47605,UsbOcUpdateDxeEVB +B80764EF-4E70-419E-9FF7-A98910504B90,PS8625PeiPkg +B8167809-E73A-4387-8323-0AFE83D3074F,SmmAslSmiProtocol +B8192EAD-CB81-4712-AC86-CA44D1B19265,DisableUsbSmiMode +B81A9587-D1D1-418E-CCCF-508DAFCE4D8C,GraphicsConfigurationDefaultsSmm +B81BFAB0-0EB3-4CF9-8465-7FA986361664,EfiUfsDeviceConfigProtocolGuid +B831F761-ACBB-49B7-A5D4-EF4B77502A9E,SmbiosDataUpdateDxeBlizzard +B835353D-4049-410B-8F18-4C749C4C7A78,DxeSleepEvent +B835921B-FD04-412E-9748-9889881B75B2,AmiI2cHid +B847EF5E-A5B0-45DF-BECD-06CA113FBF7B,LanDriver +B84B4FC3-A84A-47F4-999D-F00C1FD50139,CryptoServiceSmm +B8502C59-B268-4BE8-ADD6-601AFEAA4BC9,SpiKeyboard +B850A139-BABB-4D91-9F27-72D2EF01BF3A,VbtMipiJdiGuid +B859281C-16FA-45A8-9201-1C3830A973BD,GecUpdateSMI +B85C7FEA-AEBF-492B-96C6-42EA133BCF29,AmiTseHddSecurity +B8642E41-D350-4BFF-9DEC-4940F15CD6E5,nfa765x64 +B86B0E9F-9FAF-4368-A131-62416F3DD21B,AmdMemFp7Dxe +B871F3BB-04B7-48B8-9D8D-ABFAA9EDDE61,AsusWatchDogTimerPei +B874E099-B86F-417D-8DD5-A0C054AEF060,BoardSyncAPCBSmm +B87AA73F-DCB3-4533-8398-6C1284272840,ReserveMemFlagVariable +B87C2ACB-AC3A-4D96-9E4E-A5B9587A6298,StaticSkuDataDxeEldorado +B88303F6-2E0E-41CC-8510-F5892BF1D9D9,PlatformVariableInitPei +B88CF2B3-5CCE-482C-8DB4-6F329A73BD6D,Rtk8156UsbUndiDxe +B8916C45-0680-40FA-B88F-89F9D42EEC51,FchSmbusDxe +B894C949-A1F8-41C1-A7C0-DF523AD91C15,MrcPlatformHooksPeim +B8969637-81DE-43AF-BC9A-24D98913F2F6,HandleParsingHiiGuid +B89FD028-D4C6-4BB7-BCA4-17D8C945DC23,DellVideoDeviceSmm +B8A31DAA-33FD-48F4-B84A-4D391FFA1F45,EventLogPei +B8A3F491-0243-45C4-B670-C1BF619802AE,HpRuntimeBiosUpdateCheckDxe +B8A6E7C5-B8FD-425C-A67E-1009DF1F10B5,LenovoUserManagerDxe +B8AB793E-27A7-4107-907F-3FF4320D7F15,FchKunlunSmmInit +B8AC7FB2-4211-4C2B-B62F-504421666C87,RngTest +B8B8B609-0B6C-4B8C-A731-DE03A6C3F3DC,ScBiosWriteProtect +B8C2663C-F9FD-452A-ABD8-20556FE2AE65,BiosAuditLogHandlerPei +B8C45127-8A9D-4362-B20A-6C0012CB1430,PlatformSecureVariableSmm +B8CDCED7-BDC4-4464-9A1A-FF3FBDF74869,MePlatformGetResetType +B8D62377-7970-4CE1-87F4-9DDE56AE8982,BiosGuardVerifyRomImage +B8D6A844-AB11-454F-B2AF-2D8BCF6F4DCA,PeripheralDxeInit +B8D8CAF2-9E94-462C-A834-6C99FC05EFCF,ArmScmiClock2Protocol +B8D9777E-D72A-451F-9BDB-BAFB52A68415,ArmCpuDxe +B8E123B0-F23B-49A7-AE74-7E1636EB8F16,FjPasswordCtrl +B8E62775-BB0A-43F0-A843-5BE8B14F8CCD,BootGraphicsResourceTableDxe +B8E63775-BB0A-43F0-A843-5BE8B14F8CCD,SystemAcpiBgrtDxe +B8FE3D49-DCF3-4CBB-8070-47B4F5A34559,GopDebugDxe +B904772F-F8A1-4147-82FF-56CAF2D6E042,PlatformSecureBiosPei +B90510C4-A6DE-4E45-A50C-A46CCAFEEF91,BaseBoardDXE +B912F198-7F0E-4803-B908-B757B806EC83,AppleImg4VerificationDxe +B913CF23-9B49-47AC-A7C8-EA6539502A40,ExtendOperatingAmbientTemperatureModePEI +B91547F5-4D24-4EEF-8507-74DDABEB71AD,AmiSmmNvmePassThruProtocolGuid +B91978DF-9FC1-427D-BB05-4C828455CA27,EfiSioControlProtocolGuid +B921DC51-49D4-4C14-9089-931C2D6B92BE,AmdSocAm4RvPei +B9237513-6C44-4411-A990-21E556E05ADE,EfiKmsFormatGeneric3072Guid +B92FEC73-D902-4690-9B92-430E0E906369,AmiPspPlatformDxe +B937BAC9-B41B-4914-BC32-72410400F9DE,SetupDataProviderPei +B941CF11-E648-401C-92A1-342A70C6B742,DellSmbVersionManifest +B94A1958-05F4-E7F5-4053-286F96ADB3ED,TrackPointAWS +B94FC17C-579C-4AB3-BA28-678D1813D1D6,DellBiosConnectNetwork +B958B78C-1D3E-EE40-8BF4-F0632D063916,EmuThunkPpi +B95E9FDA-26DE-48D2-8807-1F9107AC5E3A,UefiPxeBcDxe +B970D89B-6AF8-4B8B-9045-B06D8DC2C8B6,PdSolutionDxe +B979746A-8C1F-4A2B-97E4-78E93A71A70A,EfiBdatAccess +B97FCC2A-477F-4939-AEC7-EF4236D88E3B,SureStartPcdDxe +B981A835-6EE8-4F4C-AE0B-210AA0BFBF01,RngDxe +B9846521-FF99-4953-8FA2-85C9ADCCE5AF,PeiGfxDriver +B98999A4-E96F-475A-99FC-762126F50F5A,SmbiosUpdateData +B98BD3B2-EC40-4826-9547-16DCB6BFA60A,DellBcRcvExtractor +B9A3F174-1B36-4AEC-99E2-F2855EB4C3DE,BoardInfoDxe +B9A61AD0-2802-41F3-B513-9651CE6BD575,OvmfTpmDiscoveredPpi +B9B038B0-E2B6-4AAB-9435-4165ECFED032,AmiTsePasswordPromptExitGuid +B9B0F38D-1F27-4F46-9F44-42D694729882,AmdCpmOemSmm +B9B13798-D409-4D58-86E5-B1836CBEF387,DxeOverClock +B9B20B00-2FE5-8445-ACC5-8E29EF01A3E6,AppleMemoryTest +B9B9D0B4-E65C-400F-90D5-0729012F32E2,DefaultsAndWmi +B9C0BEEA-3F1C-45C0-822B-B0908F668F65,NTFS +B9C1528F-B5D6-489E-B568-C4F0A9764D1C,FjGpioCoffeeLakeSmm +B9C37931-F069-418C-9E19-31B0BC031887,LenovoPostValidatorPei +B9C42F17-8179-6E98-B2B7-21865B1ACA3E,FTPMDxe +B9C464F5-E8DF-49FB-8FE5-86DA958D8133,ASRockHDAudioDxe +B9C47EEF-D7D2-4CC7-9BD2-88A7FED4938C,FjGabiLogoHandlerSmm +B9C87A34-3FC6-41A9-AA66-CD011F75CB80,LenovoCustomizedLogoDxe +B9CABA9B-E5C5-41DC-86E2-E7CEF87B81CB,SystemFlashCommunicationSmm +B9CFEBC9-9CDE-4F0D-A0AA-BD7D017200F8,TdtPlatformPolicy +B9D4C360-BCFB-4F9B-9298-53C136982258,EfiFormBrowser2ProtocolGuid +B9E0ABFE-5979-4914-977F-6DEE78C278A6,EfiPeiLoadFilePpiGuid +B9EC7CE0-2059-49A7-BCDF-C07D4CCC6E9E,DellFmpClassic +B9F10C17-6CA0-40B5-9B44-6253CFC7D24B,GdbDebugAgent +B9F2AC77-54C7-4075-B42E-C36325A9468D,LenovoVerifiedBootPei +B9F5C05A-C8C4-4D1C-966F-1977EF2CA54D,AmdPlatformRasRnDxe +B9F93638-35F5-447D-B908-A2B852AA0B89,LenovoSmbiosTcgDxe +BA05B97C-8EBF-48B7-858D-4B0AFBF0D7DA,BiosGuardRecoveryWorker +BA080879-3AF4-4639-9613-D1FC8ED8A669,EfiJedecNvDimmSmm +BA0C203A-166B-4B93-9636-8327AB2BF71F,AmdErrorLogDisplayBrhDxe +BA0ECDFD-A429-49B9-A961-11EEFF784C7F,OemPei +BA102EAD-5308-4F9B-9E22-C1CE4DC44F49,RSAKey +BA118F88-5B65-4584-9C5A-C2D087F6ED1E,IrsiRuntimeDxe +BA15E887-ABF5-438F-B87A-3110F1C8ACE2,XhciPdoResetWA +BA23B311-343D-11E6-9185-5820B1D65299,EfiHttpBootCallbackProtocolGuid +BA23D959-EFCB-4340-B0A9-B33F9CF05CB8,PhPlatformPei +BA24061E-B532-4375-A5E4-99C1CAE45D18,EcSecureFlashPei +BA246BC7-7E2F-4AE4-817A-FFDE572E39DE,AppleSmc2 +BA25E07A-E253-442C-90FF-B4C92FAD6990,UsbMassStoragePei +BA26C482-C1DE-4B97-A8BD-160DFDB984AC,FchPromontoryGpioDxe +BA28936B-4051-48CF-A5CD-B63D7BFCA84A,SmBusDxe +BA2EF68E-3F4F-4532-909D-5C23220DF84B,DashPldmSmbios +BA31025C-4AA8-4CAE-98CA-BA12C6BC7D78,SmmControl2Dxe +BA320263-FFD4-4DA5-A617-D832193E835E,AmdRasRsServiceSmm +BA33F15D-4000-45C1-8E88-F91692D457E3,MpInformationHob +BA37EEEC-2B01-48CE-B3D3-AF6EC1893330,AmdNbioIOMMUDxe +BA37F2C5-B0F3-4A95-B55F-F25F4F6F8452,IntelGraphicsPeim +BA4548D4-B207-4F68-B1D6-10AC7F9CF1C8,HddPasswordPei +BA51887A-BEB9-45DA-8E37-98A6B46E7C58,IeHeciInit +BA522681-CF67-49E2-925F-F60B32819039,FspInitNotify +BA57B64D-4AD2-68B8-AB93-AF89654F7DBE,AmdBoardIdDxe +BA5B13F3-8B83-4871-8C3D-44CE683EAC1E,AmtLibPei +BA658945-DEE1-42B3-9FA4-BB6B22FB03E4,efi_pop_mid +BA67550C-3628-4137-A53E-42660E081604,MePlatformPolicy +BA6BADE3-B38B-49AD-AD8F-D6086F240E78,AsusApmDxe +BA73672C-A5D3-11D4-BD00-0080C73C8881,EfiWinNtConsoleGuid +BA7BE337-6CFB-4DBB-B26C-21EC2FC16073,SecCore +BA7C38E3-6F1C-49D1-9CF9-5C67324EA40B,FjLidDxe +BA7C46D1-9C5E-4FC8-943D-1A491F23FE01,AmiIso9660MediaGuid +BA846D12-59AC-4E18-88FF-E04687552416,SmiCallback +BA87DD62-AB60-46DE-8FD8-023510D52D11,gear12 +BA929954-35B0-4DD3-90CD-9634BD7E1CF1,ResetDxe +BAA1B6EF-F6B3-46DF-BDE6-40CD666F04EC,FchPromontoryPlusSsdt +BAA9B7C4-2B4A-4047-B254-C12B42F00D67,CrisRecoveryApl +BAAEAD09-02A0-4131-9E0D-BC529EF0FF2A,EfiTcgMpDriverHobGuid +BAB4F20F-0981-4B5F-A047-6EF83BEEAB3C,EhciPei +BAC76586-3515-420B-A1B7-235A716ECAAD,OutOfBand +BACA647C-883B-4169-9E89-7910C060FFEE,GopConfigNex +BACE07C2-8987-11DB-A59A-0040D02B1835,EfiUnixGop +BAE29D7B-89BB-4223-AF76-96D0B3249B36,SsaBiosServicesPpi +BAE5596A-14DF-40FC-810E-BB2428009600,HpCmosButton +BAE7599F-3C6B-43B7-BDF0-9CE07AA91AA6,CpuIoDxe +BAEB5BEE-5B33-480A-8AB7-B29C85E7CEAB,FspGlobalDataInitPei +BAF029A0-B2F3-45EE-8B52-D402177BE6B8,LenovoOsOptDefaultSmm +BAF1E6DE-209E-4ADB-8D96-FD8B71F3F683,EfiEventUserProfileChangedGuid +BAF3E67B-B175-49F6-84FF-75C354439CFD,FirmwareUpdate +BAFCAE65-945C-466F-FFFF-FFFF8B5877A4,XnoteReportStatusCodeSmm +BB00A5CA-08CE-462F-A537-43C74A825CA4,EfiMpInitLibMpDepProtocol +BB11ECFE-820F-4968-BBA6-F76AFE302596,ArmTokenSpaceGuid +BB1A3984-D171-4003-9094-46AF866B45A2,IconPasswordLock +BB1A61A2-6DB5-4BD7-8A98-7823C92B0A2A,FvbServicesSmm +BB1FBD4F-2E30-4793-9BED-74F672BC8FFE,PchResetRuntime +BB218CF7-A58F-414C-972C-6EA37FC5C862,OemAdpTypeDxe +BB25CF6F-F1D4-11D2-9A0C-0090273FC1FD,EfiSerialIoProtocolGuid +BB2800D9-67E8-4C69-BE5A-4E5AC6A9CC4F,QuantaIFDxe +BB2F0636-B0DD-489B-ADB6-606FE3A47258,CpuHotAdd +BB3B5FE5-4736-48DA-8C9F-76CE085F0515,FchSmbusPei +BB3BF734-D640-4CF5-AFEA-CA8CFA6020D1,ASUS_USBFLASHBACK +BB5B5907-5F8E-42AD-915D-5D98B52ED697,PlatformStage2 +BB5F17A9-7757-45A7-BA24-7EF53EADE84D,AmdSocFp11StxhPei +BB628AE0-CD4F-49FE-8D60-63186FD1E05B,EfiCacheInstallPpi +BB62E663-625D-40B2-A088-BBE83623A245,EfiEapManagementProtocolGuid +BB65942B-521F-4EC3-BAF9-A92540CF60D2,SataController +BB676756-99A8-44E0-8128-AE2BABAD4C69,EcAuditLogDxe +BB67A43B-C7AE-4299-A275-7526DC697735,PlatformStatusCodeHandlerPei2 +BB696233-9D1F-4AC5-B057-41DDAD3B0CC1,OemAcpiMode +BB6CBEFF-E072-40D2-A6EB-BAB75BDE87E7,TcgPlatformSetupPolicyGuid +BB7119B6-EF1F-4056-9321-CF29CC7A2FBC,I2cPlatformDxe +BB76F1EA-750F-4131-BB54-A880AD72C9E2,TimerWakeSmm +BB801A52-C90F-4EDE-91B2-82520888CBC3,IntelgbeUndiDxe +BB83F95F-EDBC-4884-A520-CD42AF388FAE,BaseDebugLibSerialPort +BB87B31D-F366-47E9-885E-E816B09B97B6,DellAlertStandardFormatSmm +BB8C2CF3-A5E3-49EF-941B-4A01FAC6FD5F,SmiFlashDxe +BB906FAA-2A47-5C67-DD9F-6867FE125D4F,DGPU_GOP_2 +BB9175E1-3E95-4B7E-8750-9D6AA34EB7F6,AsrockApmoff +BB927FCE-C965-4A80-B4F7-D065D961EF2A,FjGpnv +BB929DA9-68F7-4035-B22C-A3BB3F23DA55,SataControllerDriverGuid +BB983CCF-151D-40E1-A07B-4A17BE168292,EfiMemoryOverwriteRequestControlLockGuid +BB9C7AB7-B8D9-4BF3-9C29-9BF341E217BC,EfiPlatformCpuInfoGuid +BB9D2F77-E1FD-4451-A946-6E868D216E4D,PlatformNotifyDispatchPei +BBA544D9-4747-4C3C-9371-F1ACB6B13CA3,DellNbEcDxe +BBAC47BF-CE55-4D4C-B728-A8866EE23000,I2CApplicationPei +BBADFF1E-B651-4014-B476-D42919A839D2,UsbTextLookupDxe +BBB31581-855A-44D7-A550-8A585D9B2DE9,BaseCryptLibRuntimeCryptProtocol +BBB71DD1-B993-487C-839E-7A7536B49E46,FjPowerButtonPei +BBB77CB9-762D-436C-AC40-8EE4901C3446,AmdPbsSetupDxe +BBB810BB-5EF0-4E8F-B298-AD74AA50EF0A,EfiTcgWakeEventDataHobGuid +BBC98A25-89B0-474B-AC85-8E524EB33E25,PchSmiRegister +BBCB6F85-303C-4EB9-8182-AF98D4B3020C,Tpm2DeviceLibTrEE +BBCF59BE-2613-4960-A0A4-639B4A970206,HpEdidOverride +BBCFF46C-C8D3-4113-8985-B9D4F3B3F64E,FspBootLoaderTemporaryMemoryGuid +BBE2668C-0EFC-46FB-9137-4F2DA8F419F3,ConsolePrefDxe +BBEB4F87-720B-45D4-AA61-FBF6D4C54961,AmtMacPassThrough +BC00DE36-935C-4577-8DC5-487F06B6DD12,DellSystemUsbPortConfigPei +BC05DC37-9DA0-4050-9728-F34DDB01E200,BiosRegionLockEntry +BC05DC37-9DA0-4050-9728-F34DDB01E301,SpiLockSmi +BC0814B1-CCF4-4C6A-A906-9E08D5E14529,ODMServiceSmm +BC09EAD4-8094-432D-A4C8-381F87D5F531,MpmSerialIoDxe +BC0B9FB8-97CF-4B17-9A9E-F574E62CBCC4,Ip4BmcLanConfig +BC0FE6BB-2CC9-463E-9082-FA1176FC67DE,EdkIIRedfishConfigHandlerProtocol +BC114B43-8CB4-4FC6-862F-FE226BAD050E,HpRpsuSetupDxe +BC13B357-3C0F-40C6-85A8-D18D269898C1,OSDSMIfunctionDxe +BC1A046C-7DBD-41F2-94E5-D7595554CAF4,SystemFirmwareReportDxe +BC1CFBDB-7E50-42BE-B487-22E0A90CB052,FspTempRamExitPpi +BC28E0DE-66F6-49E6-B81F-AF4DD9A8AA15,POSTCODE0A_BASESMBIOS_DXE +BC2B7672-A48B-4D58-B39E-AEE3707B5A23,Tpm12DeviceLibDTpm +BC3245BD-B982-4F55-9F79-056AD7E987C5,AhciSmm +BC327DBD-B982-4F55-9F79-056AD7E987C5,SmiFlash +BC412D75-2729-4C3A-B193-5B9A588FF66F,FirmwarePerformanceProtocol +BC468182-0C0B-D645-A8AC-FB5D81076AE8,UserInterfaceThemeDriver +BC46CC5F-13F2-44CF-A598-CCA3444D4E2B,GpioExpanderPei +BC52476E-F67E-4301-B262-369C4878AAC2,PlatformSeCHookProtocolGuid +BC559DEA-2681-9345-9BE9-07850AF39E6E,ShaHash +BC59E2E1-7492-4031-806E-C48DCCC3A026,FspInitPeim +BC5F861C-86ED-417E-BB7B-6C026BCD755B,EfiFrbCodeProtocol +BC5F861C-86ED-417E-BB7B-6C026BDC6523,EfiSelStatusCodeProtocol +BC5FA650-EDBB-4D0D-B3A3-D98907F847DF,PeiBlockIoPpiGuid +BC6102DD-3CC7-4B86-9A2C-4E125CABDF3A,FchKunlunDxe +BC62157E-3E33-4FEC-9920-2D3B36D750DF,EfiLoadedImageDevicePathProtocolGuid +BC664EF6-4C70-4FE4-B336-83E2FC47B697,DellEpsaBin +BC74787A-BE99-4A2F-8C9C-C6D7E5C77AD3,BoardUpdatePolicySmm +BC79959D-47E5-47DE-8E8C-49DE89B1FD9D,FjDeviceFirmwareUpdateProtocol +BC7A1133-4C66-C6BA-B4D8-EB9FEFB9F146,AmdSocSp3r3CpPei +BC85572D-F297-4D9C-93FE-DD9226C14591,DellSetupSerrDxe +BC8C4A18-E784-42A7-993F-88BCE13247C5,SupplicantDriver +BC93AC24-BBAA-49DE-8EB5-2396F87929E0,AmdNbioAlibRMBDxe +BCA793DC-6532-4BEF-96B4-FC297D1FEA98,DellPciBusPei +BCABB6DD-3E9F-47E2-B8FB-10B39AF6342C,DellDaTaaMac +BCAD34A1-DEB7-4FFC-90D8-B0643BD8271A,AmtMacPassThrough +BCAF98C9-22B0-3B4F-9CBD-C8A6B4DBCEE9,EmuSec +BCB59C90-DC86-11DD-AD8B-0800200C9A66,SystemAhciAtaAtapiPassThruSmm +BCB93998-0048-4E9E-9494-46BEDF8D8A06,PchSmiDispatcher +BCBB3912-29FA-4B25-B619-3C0D739FEF51,DellHotKeyHandlerDxe +BCC87E0D-86D6-4D4D-8040-2D983D368BD1,EmuGopDxe +BCCAD460-4F7D-4E51-8A5D-3BBA236D9EBB,AppleBootBeep +BCCBF64A-5231-426E-AE37-4CC70F15813D,SetupLanguageDxe +BCCDE9D2-BABD-44F5-BB3F-D7B16174F64B,AsfDxe +BCD9DF8C-BE89-4007-986F-FA401A4AF94E,Int15PanelColor +BCDAF080-1BDE-4E22-AE6A-43541E128EC4,EfiIsaHcProtocolGuid +BCEA6548-E204-4486-8F2A-36E13C7838CE,FpgaSocketSetup +BCECAD77-6299-415D-AE48-733C45476891,DxeWifiManager +BCED1375-8E68-4D9F-B8B4-37862B22FA6D,SDPlatformInitDxe +BCF5F0BD-BF2E-4CFA-BE94-43DDDEC445B0,FjMemResizedLogDxe +BCF94D6E-86D9-4A87-A446-B21B803BD140,BootDeviceInfoSmm +BCFEEAA3-F3BC-4196-B9A6-AE569A6C0033,SmuV13Pei +BD0ABB5D-A29F-4001-A3CA-98485EF7F224,AcpiSmmPlatform +BD0B5ED6-468C-4372-AE52-47BA08F81A1F,RepSetHandler +BD18369D-C242-45CA-82AD-138AC2E29BAB,EfiSmmIoTrapDispatchProtocol +BD1C1A1C-04EC-47ED-8AB7-D19319C64138,FastBoot +BD22D0BF-4818-4EF8-BDCD-B3478F52A802,HeavyPciBusDebug +BD26CDC9-A092-462A-877A-5AB6ADCE4812,EfiPlatformCpuProtocolGuid +BD2B77A3-500F-41B4-93F9-637EC6C23DB7,SmuV11PeiVMR +BD445D79-B7AD-4F04-9AD8-29BD2040EB3C,EfiLockBoxProtocolGuid +BD446386-7F8A-4EE1-A014-8D3BAB92B4E9,EmulationPlatformInit +BD44F629-EAE7-4198-87F1-39FAB0FD717E,FspEventEndOfFirmwareGuid +BD45A258-C7BD-4BF0-B254-D0D45E02F877,DellCmosManagerDxeSrc +BD463212-701B-4E34-BEC1-F3FB7602F8AA,IsaHostControllerDxe +BD4759AA-5104-42A3-BC64-785920E86C99,FchProm21GpioSmm +BD4E9C29-855C-4BD8-8173-3F10B617F250,FjDisableDefaultConfigOrMfgModeBin +BD6736AC-B126-4FEA-9D1D-174D4A899F22,SystemErrorMenuDxe +BD67BF44-CAB8-4A1B-A3F9-FC3CE2D0E764,DellUsbMassStorageDxe +BD6C3E7A-ECA5-4C3A-BD11-C705F9ACEF16,FileExplorer +BD712601-082F-4C59-8677-2C8A3C297948,LoadFileOnFv2 +BD7E9A27-D6C5-416A-B245-5F507D95B2BD,WinNtBusDriverDxe +BD809BFE-1E29-4CA0-AE2C-1C7C8E79A00C,WarmResetFlagPei +BD839E54-FE54-4B64-9FA3-0A806B1042BC,HddDynamicSwitch +BD85F7FA-8ADF-42F8-B400-BF46E5E8ADC7,PxeDriverI219 +BD87394D-465C-40A9-9657-FBED21789860,BinConvert +BD87C542-9CFF-4D4A-A890-02B6AF986F34,PeiOverClock +BD87C547-93FF-4F4A-A890-02B1AF986F34,OverclockInterface +BD88EC68-EBE4-4F7B-935A-4F666642E75F,EfiAcpiEnDispatchProtocolGuid +BD8C1056-9F36-44EC-92A8-A6337F817986,EfiEdidActiveProtocolGuid +BD9320EB-7BB9-4AED-A682-CF4F96BE244C,IntelMchFieldAcpiTables +BD996F6E-7767-4827-9208-B1C299000E4A,PspResource +BD9CA80B-940E-4B55-88A4-BB3A3CC99863,DellStatusServiceSmmInit +BDA39D3A-451B-4350-8266-81AB10FA0523,PeiDxeDebugLibReportStatusCode +BDAD7D1A-4C48-4C75-B5BC-D002D17F6397,AhciRecovery +BDB38125-4D63-49F4-8212-61CF5A190AF8,EfiUserInfoAccessSetupRestrictedGuid +BDC8E6AF-D9BC-4379-A72A-E0C4E75DAE1C,EfiHttpServiceBindingProtocolGuid +BDCBB03C-545E-43C1-8AA8-F058C4FA81A8,DxeGpioControl +BDCE85BB-FBAA-4F4E-9264-501A2C249581,S3SaveStateDxe +BDCFFDBD-AAC1-4704-8F49-EC25064324C0,DellSbSmmProtocol +BDD4822C-5A9B-4673-9ADA-50CAC7246FCE,FjFlashServiceDxe +BDD56254-6890-446D-9171-3C370A584B2C,ITEAcPowerLossSmm +BDE92229-F9A5-4897-81E4-8BAB6792A395,DellDtLegUsbPolicy +BDE97C22-D8EB-4625-BC36-773457AE25DB,AMDGenericGop +BDF8B095-EDE5-4250-B577-C5CB5515B7AE,AmdCpmABRecoveryDxe +BDFAAD26-4D7F-44A6-8719-375ECB4AA407,DellPxeBaseRom +BDFCC092-36A4-4668-BAFE-EC8F1B02A28A,DellMultiFuncDevConfig +BDFD9E08-3113-4259-86ED-58DD830535D8,StorageFlushDxe +BDFDE060-7E41-4EAE-AD9B-E5BBA7A48A3A,EfiDevicePathPropertyDatabase +BDFE430E-8F2A-4DB0-9991-6F856594777E,SystemEhciDxe +BDFE5FAA-2A35-44BB-B17A-8084D4E2B9E9,FvbServicesRuntimeDxe +BE0FEABA-3443-4919-9F3A-2D4216329EA9,WinNtAutoScan +BE189D38-C963-41CF-B695-D90E9E545A13,UfsBlockIoPei +BE216BA8-38C4-4535-A6CA-5DCA5B43ADDF,SmiVariable +BE2565F8-DC13-45AC-AB4B-08B4FEDE5A4D,ComputeHDDPHashProtocol +BE2DB903-B7C2-4ABC-8F64-B06E705D27E7,PostWave +BE2E5EC2-1450-4A9A-B364-4F777B42216D,SwSmi534D0340 +BE2FEDC4-2F51-4110-9327-36FAB7429AAB,EfiPlatformTypeLightningRidgeEx_8s2nProtocol +BE4425A1-18DB-47EF-9273-273E95007014,EfiPlatformTypeNeonCityEpecbProtocol +BE45377F-F862-42BD-8886-314C67BC16E4,LfcWmiServiceSmm +BE499C92-7D4B-11D4-BCEE-0080C73C8881,EfiDebugAssertProtocol +BE4F6DF4-5CB5-4658-91C8-AD8106B8150F,FjManufacturingModeSignOn +BE644001-E7D4-48B1-B096-8BA047BC7AE7,EfiHtBistHob +BE6B4F66-5B89-4DC2-9102-A178C8621CF2,UefiBootMarkerProtocol +BE6D9471-C8BF-4B35-BEA7-7687CDF7E142,AmdMemFp7Pei +BE731247-5FA2-4D5B-9DB6-5385CCCD59E1,UsbOcUpdateDxeLightningRidgeEXECB3 +BE733C7B-07D9-4401-A08E-F475B0FA11ED,SystemPowerOnEvent +BE7FDB92-E3BE-4517-BD4B-C6FCBE00DAA1,MpDmaBrhDxe +BE8A2412-E62A-422A-870D-6185B7A32271,OemEcVerUpd +BE9BE8AE-EBBB-450F-962C-BE1938E3FEF9,F2HotKeyAndCorrectPassClr0199 +BEA143EC-5DEC-4C6B-A631-2C2E27759487,DreamTeamSleepSmi +BEA1E7E4-9C23-4436-B3FD-4420DC6778F8,USBCSecurity +BEA26CCC-CE96-45D2-964F-509B1BA17A81,FjNvramSmiDxe +BEA39084-044A-4C88-8763-2BFAFFA8950C,LTEB +BEAEFFE1-0633-41B5-913C-9389339C2927,RedfishPlatformConfigDxe +BEB07103-05F9-4B5D-89AF-29471D593CD5,S5Charging +BEC14E72-A956-4676-87E7-B092087F5F6C,FjIntrusion +BEE0DC09-B048-476D-A0BB-ACF9B4F65C41,DellUsbKbPei +BEE9B6CE-2F8A-11D4-BD0D-0080C73C8881,EfiWinNtCpuModel +BEF1437F-8AEB-436C-8D7C-08BA5FE449AF,FjDtSetupServicesDxe +BEF4D2B1-C53B-4933-A3BA-2A422C89A439,AmiFriProtocol +BEF5ED27-4E93-40F8-AE11-6B41E1D4BCA9,AbtEraseDxe +BF00D49C-7784-4A06-9F5C-12FB9E68C72B,FjGabiFlashCoreSmm +BF0A78BA-EC29-49CF-A1C9-7AE54EAB6A51,EfiMtftp6ProtocolGuid +BF13D47C-7671-414E-B3EB-1784073EC5FE,EcInit +BF27A268-F369-43A2-B295-242DEE7F3C29,DellPowerButtonDxe +BF2AE378-01E0-4605-9E3B-2EE2FC7339DE,FmpDxe +BF3C55E3-2B74-4722-8105-62053C27CFBC,PowerOnHddIdleNotification +BF420205-644E-4718-9C39-679B7854F446,AmdSpiFvbSmm +BF43D37C-7071-414E-B3EB-3C98D08AA32E,EcInit +BF43D37C-7078-414E-B3EB-3C98D08AA32E,FjSysmanSmcsUpdater +BF4B9D10-13EC-43DD-8880-E90B718F27DE,EmbeddedDeviceGuid +BF5543BB-17F8-4C51-B4AD-59C0E9D2D48D,OemNbTypeDxe +BF639845-D046-43F9-ADBC-D0086AE25871,DellSmmThermalDebugProtocol +BF66FDF7-F64C-4B11-8AB7-F843AA2A8BEA,AmiCapsuleHob +BF6F4946-F369-47E9-9084-230C7F9E737A,BCdpfLauncher +BF708ECD-A953-442A-FFFF-FFFF748E01AE,XnoteReportStatusCodeDxe +BF73D2BF-AC8C-4D83-A3B9-4A0F420074B3,LenovoStatusCodeMeDebugDxe +BF7862C9-CDFF-4261-8385-B61916CD2E9A,EmmcDllTuning +BF7D4885-BEE7-48A4-BEC3-2E7160A48A0D,FjGabiFlashCommonEcRegionCtrlDxe +BF7D48A5-BDE7-48A4-BEC3-2E6160A48A0D,FjGabiFlashCommonGbeRegionCtrlDxe +BF8764D9-AE9A-4EB8-AAE3-04E5F675D866,FmacDriver +BF885A32-2ACF-495D-A7BA-D3F92FA96289,DellXhciDxe +BF89F10D-B205-474F-96E3-7A7BB1B4A407,VgaClassDxe +BF90FDDC-F163-4FC6-A5A3-D0FDC8F7CE68,AmiUpdateCspResources +BFA8CC03-C1CD-439E-BCF6-14207A2CDE94,PowerEfficiencySync +BFB01142-3061-48A4-922F-9D246E201120,AmiTcgResetVarHobGuid +BFBEDBD4-1B7E-42F5-A528-4351E860F120,S3SupportSmm +BFC2B71F-ACBF-4E54-9B19-B6EEB400507B,AmdCpmPmfDxe +BFD59D42-FE0F-4251-B772-4B098A1AEC85,ActiveBios +BFD7DC1D-24F1-40D9-82E7-2E09BB6B4EBE,EfiDriverConfiguration2ProtocolGuid +BFDCAD58-3630-4300-A2C6-0DB46CECA482,OemGlobalNvsDxe +BFDCAD58-3630-4301-A2C6-0DB46CECA482,OemGlobalNvsSmm +BFE13A90-C143-43C2-9704-71E39E6D43AE,IntelVtdSmm +BFE205C9-5B17-4F8F-9375-89614AF8E199,OEMDXE +BFE9131B-0F64-4D0F-94A4-0D830DB928A3,MeSmmProtocolThunk +BFEE74C2-60BD-467B-9261-B72A881E49EE,LenovoMailBoxSmm +BFFAC9BC-1C98-40CD-8692-1F97D163EBB6,UniqueSleepStateBlinkRatesSmm +C007C321-E87E-46B4-A5B5-C33E845D89EB,WarmBootDxe +C0092746-B67B-4D02-FFFF-FFFF78E038D1,XnoteAcpiPlatformDxe +C0113C45-1638-4F3E-BC29-95CD8FB72005,OemNvemDetectDxe +C01766EF-C809-4BD0-92D0-5E55A6F3E6F5,VirtualSerial +C020489E-6DB2-4EF2-9AA5-CA06FC11D36A,EfiAcpiVariableCompatiblityGuid +C026632A-073C-444A-AD9C-5E963FEBBC0F,FchSmmDispatcher +C02B0573-2B4E-4A31-A31A-94567B50442C,PchUsbPolicyPpiGuid +C02B908F-E892-4502-ACB7-545319989F6F,RealTimeClock +C034A2CB-1190-4638-9DDF-6F297824741E,TestPointStubDxe +C03DDD47-DC0A-4319-9FEC-44B078C242E6,AmiTseOemPortingVar13 +C0512F00-0181-48C0-8B71-90504B8F991E,EfiBootNameLabel +C0557EED-9A89-4770-9626-FCA051F2BA09,PerfTuneWdtProtocol +C0571D26-6176-11E9-8647-D663BD873D93,DebugInfo +C05A042A-7E6F-410A-9177-E288D13C3C34,PsrControlDxe +C05ED2D1-5DDE-4B6E-A1AE-0B306ACB42BC,TrEEDxe +C0622982-A30A-48A5-8150-5ABF4191056F,LEMBootModeDxeSmm +C0645FCC-5000-4BCB-9AE0-4D46796F1390,PdHostInterfaceIteSmm +C067DBFA-2C8B-4A7C-921B-28DCB25D9EDA,AmdNbioEarlyPhaseRPLPei +C06C5A03-704C-45D6-808E-4D9E867897D3,AppleEffaceableLocker +C07119A7-98AA-4DCE-B347-9608634AA06A,DiagnosticsConnection +C0734D12-7927-432B-986B-A7E3A35BA005,LightPciBusPciBusDxe +C0757D65-3F84-2592-AEB9-33D19BABCCF7,TmpDecFileHolder +C0757D75-3F84-2592-AEB9-33D19BABCCF7,TmpDecFileHolderDxe +C076EC0C-7028-4399-A072-71EE5C448B9F,EfiCustomModeEnableGuid +C07A1EB5-5C04-4100-817B-0A11BB5F15DC,CppcDxe +C07CCCFC-B4BF-4A30-A25F-1F57C0522629,FdiskOemSmm +C095791A-3001-47B2-80C9-EAC7319F2FA4,EfiFirmwarePerformanceGuid +C0988B6D-C3F6-4C25-B565-ECB116912411,OemDisplayRule +C09C81CB-31E9-4DE6-A9F9-17A144354245,AdvancedPkgList +C0A02971-C45C-47A6-AAAA-3F089A7B7A50,DellRmtPlatSiDxe +C0A235DB-17E7-448A-B8E4-2E29FDFBB158,LenovoEventLogVariableStoreSmm +C0A2EC40-7CA9-4FF7-A17C-08B81D70DE80,ECSmmFramework +C0A8BD98-DED0-4313-9970-6FE2794CD157,AmdCpmOemInitPeim +C0B9206E-B6AB-4DF0-B3D6-286AC76698BD,DellD010AlegacyVideoRom +C0CC43BD-C920-4064-935B-93B447379470,PowerManagementAcpiTableStorageGuid +C0CD2D36-A81B-450D-A502-3767DFA29826,EfiPlatformTypeNeonCityEprpProtocol +C0CFEB8B-6EE1-443B-BCC9-854E7C9B416D,LenovoSystemStatusCodePort80Smm +C0D5EC34-13E4-403B-9643-54AA7F72259D,SystemSecureFlashAuthenticationSmm +C0E0A489-FB6C-4509-B1B3-C7119D489502,XnoteAcpiNvsSmm +C0EBC974-B5B2-4725-9091-9F45578F213C,AddressTranslationDsmMemRas +C0EC00FD-C2F8-4E47-90EF-9C8155285BEC,TcgNvramHobGuid +C0EE640C-B469-4EB1-8F11-46ACA1427307,WmiRmtApiDXE +C0FDBE28-4E64-44AB-9F7E-F33140E4FA2F,FanTableDxe +C10194E7-DEB2-4AF4-9EEE-BFFDE4D7D4C7,TimestampDxe +C10A9E4D-BDB4-4B1A-82CC-D901F86F5739,DellSmmDiagLeds +C10FB8CA-55A8-4132-8263-3D5B82359F04,AmiHidServiceDriver +C112BF94-5CD0-45EC-AA7F-D3DEDAAB765F,OemWSsdtDriver +C1172A76-6A56-4C09-B1FD-C29F94DA1380,AmdMemoryHobInfoPeim +C1176733-159F-42D5-BCB9-320660B17310,UbaConfigDatabasePpi +C118F50D-391D-45F4-B3D3-11BC931AA56D,DsdtAsl +C11B7A48-BA61-48B4-9198-48972B538007,SystemSdLegacySmm +C11CCB12-C17A-4266-B47D-18FD101811EA,HdpBackupToNvram +C128CADC-623E-4E41-97CB-A7138E627460,BaseFspSecPlatformLibNull +C12A7328-F81F-11D2-BA4B-00A0C93EC93B,EfiPartTypeSystemPartGuid +C12C4E6A-BC3D-4A91-8299-7E0A4D5B5289,SmcOemID +C1300EE7-4BF6-4164-9FDC-DC3E8EFB7FBD,AmdNbioPei +C13111A8-6BC9-11E5-8797-001ACA00BFC4,BlueFieldDxe +C13C549F-2CBB-4868-9EE4-97D5DC69FA47,OneTimeBootDxe +C1443436-B954-43BA-8278-C1E442C21539,DellFlashWriteProtect +C144476F-F118-4C84-A936-417C8AFBD437,GenericUSBDebugger +C146B184-8891-49D3-B734-CACDD84FC942,ATH9K_UndiLayer +C153205A-E898-4C24-8689-A4B4BCC5C8A2,PeiCachePpiGuid +C1544C01-92A4-4198-8A84-778583C23621,EfiPxeDhcp4CallbackProtocol +C162FF6A-F5A5-4DB7-9ECF-80EEC2501768,UtilityPartitionDxe +C166B802-190F-4BFE-B8CD-EE53971A063C,PeiMeCore +C1685343-EE19-4BAF-B47D-5C995DF7FA2F,StaticSkuDataDxeEVB +C16E2B26-B1D9-42BD-9002-BAB27F18A573,PspFarCheckDxe +C171DBBB-3AF7-408B-954E-789BFFD8CD2E,AsusBackupPei +C178E415-6E49-469A-B73D-F6C5EB4101EB,AmdSpiRomProtectDxe +C181D3D6-ECDC-45D8-B586-9EA1851867E4,PlatformStatusCodeHandlerRuntimeDxe +C182FB38-0FE4-4BEC-9270-A273E1EF2C80,AmdXgbeWorkaroundDxe +C184562C-6864-40A3-A081-C8D35E82B920,WinCeGuid +C18B8105-AB89-44DE-8D37-50B31FAE5D1E,SgTpvAcpiTables +C18BF867-0B3B-4C40-811D-242100665912,SystemSdLegacyDxe +C194C6EA-B68C-4981-B64B-9BD271474B20,PchSpiRuntime +C19783FD-E21E-451A-830E-C7CB23DB52CC,menu_mid_left +C19A6517-3FE4-49D8-94B6-C4D77350AA44,FlashUtilityDxe +C1A0DA4E-2836-4B7D-A5D2-B67A2242438C,OemGpioEarlyInit +C1A69A12-8653-4FDE-A215-48FCD95288C3,PlatformSetupDxe +C1A74056-260E-4871-A031-E645A65B6E11,EfiExtendedSalVirtualServicesProtocol +C1A78A9E-11E8-4910-91A5-FE48F5F4C20D,DellEpsaDxe +C1AABE42-2CA8-4361-B37A-1466520E960E,FjNvsAreaRt +C1AB12F7-74AA-408D-A2F4-C6CEFD179871,EdkiiMigratedFvInfo +C1B135AA-7ACB-45D0-80B7-862B8D5F0CD5,AmdFabricRvSmm +C1B2415B-3D28-4766-AAE8-EFBEF3BF1451,AmdSocSp6StpDxe +C1C31CFA-911C-4324-AB4C-79E8E6DE48E8,LEMDisposalProcess +C1C41626-504C-4092-ACA9-41F936934328,EfiCertSha256Guid +C1C418F9-591D-461C-82A2-B9CD96DFEA86,LegacyInterrupt +C1D5258B-F61A-4C02-9293-A005BEB3EAA1,PngDecoderDxe +C1D61CB0-78B0-42F0-BC3F-F54DFEC65DB2,PartialMirrorHandler +C1D7859D-5719-46C3-A298-D071E30264D1,AcousticSetupProtocol +C1DBFAE7-D47A-4D0D-83B5-9E6F4162D15C,EXFAT +C1E63AC4-D0CF-4CE6-835B-EED0E6A8A45B,EfiPaddingRsaesOaepGuid +C1E6791D-F35B-43EF-920A-BE06BA7F86A1,AmiTcgPlatformPpiBeforeMem +C1E9FFFB-5557-4CB5-A5F5-1FBD902A74ED,LibIIO +C1F7EE7A-4D23-4287-97BB-C0FD265D09BF,OpromUpdateDxeEldorado +C1FBD624-27EA-40D1-AA48-94C3DC5C7E0D,SbPei +C1FCD448-6300-4458-B864-28DF015364BC,EfiPeiLoadedImagePpiGuid +C1FF0D4A-15B0-498E-9B7E-924DC0317849,semaProtocol +C21561DD-2349-4B9E-94D0-5627FCD22A69,FjPostScreenMfgAcCheckDxe +C2199640-29C0-4F0A-990C-71BF9B14430D,DellSfpDxe +C21CF0E2-6ABC-4C3B-9DE6-3ABA8C3F83C9,DxeIchSmbus +C22077A1-5F9B-4891-9D1C-DEAA3632E921,DellUefiBootInfoDxe +C2223A0B-80D3-4C35-891F-BD0CC4E990F0,LenovoSystemFvFileLoader +C2239ACD-21D0-4CB0-B7DB-6D35EE7B0CC1,FirmwareRevisionSyncPei +C2281410-58B3-4F74-9458-22901ACEB901,EepromInterfaceCoreDxe +C22E6B8A-8159-49A3-B353-E84B79DF19C0,VARIABLE +C246FBBF-F75C-43F7-88A6-B5FD0CF1DB7F,AmiDbtFileGuid +C24E74B6-4155-4E64-9A91-C1E44F5D0BBE,OemGlobalNvsSmm +C26B2DBB-83B2-4AF2-BBD7-D4558036DE11,EcCapsuleDxe +C2702B74-800C-4131-8746-8FB5B89CE4AC,EfiSmmAccess2ProtocolGuid +C27B193A-D076-4AC6-8DA1-7AC67B4ACA06,ProjectPei +C280C73E-15CA-11DA-B0CA-001083FFCA4D,EfiAuthenticationChapLocalGuid +C282E903-24E5-4418-A978-A7419249C9B0,SmmTxtConfigLock +C2891AB9-9D96-475D-BE55-9EDF18F4D5EF,UsbIrq +C2922FC7-D114-47F1-8AF9-A4C0966683D1,PriorBootSmm +C29602C5-1D88-45DA-A332-55F3C693D427,UsbOcUpdateDxeArcherCityModular +C2998CC8-A0AA-46E6-A634-EE32BF113188,AmtDriverPeimPei +C2A743FE-9951-4299-9817-71DB147570D9,SmmPlatformDxe +C2AD1A7F-D9DF-4638-8DAC-015996C88857,ScPolicyHobGuid +C2BE3FBC-0EB0-4BBD-BE9A-3202481B76B2,SmbiosDataUpdateDxeBigPineKey +C2C0E2E1-CBDB-454C-8F27-96ACEE196367,BctBaseSmmZP +C2C79FD0-313C-4C4D-B9F1-ED26F00CA955,XhciDxe +C2D38A48-D3AC-43DA-A484-17F980864DEA,AmdHspFtpmPei +C2D52983-0B1B-4C98-97F7-F756C5370763,TimeAlarmDevDxe +C2D52AC9-7C0E-47F3-8738-865B3F3BCF99,AmiPciPlatform +C2E5D736-0771-42AC-B99F-1B7F1CA5610A,FileAccessPei +C2E5E29C-E39B-4E8D-9909-E00A145359FD,HpFlashMe +C2EF28BB-C6BD-4CB6-A3A1-BF6BB7EDA9F3,SecureBIOCamera +C2F1BD4E-9FEE-4079-909B-C683A86750CC,FchHuangshanSsdt +C2F9AE46-3437-4FEF-9CB1-9A568B282FEE,FspSecCoreM +C3068C28-3579-4670-B38D-2E21AD057993,PlatformHiiAdvancedDxe +C3069C81-6717-4FB6-B646-04214894BAB4,SmcSwSmiFlashDxe +C30792A9-10F1-4B0E-9AF6-C95CD8B027CA,FjLanReInitPei +C30ADC21-4AA5-4313-A7E7-53395B42BEAB,AmdCpmDisplayFeatureSmmBr +C30B94E3-C8F2-4AB0-91AB-FA8DF621B1C9,MnpDxe +C30FFF4A-10C6-4C0F-A454-FD319BAF6CE6,IntelBootGuardBootPolicy +C311C600-84E9-4F1E-BF44-BF36E3415158,LenovoMailBoxPei +C3158ABD-DB62-460F-B64C-FC258BB94A83,BiosLiveUpdateDxe +C319F914-34A4-4845-98C1-1689B98C2C13,FjSlp1Support +C31A6189-639A-458B-B040-D7D506CA8F4F,GetHostByAddr +C3253C90-A24F-4599-A664-1F8813778FC9,ArmGlobalVariableGuid +C3274B63-ADE0-414C-BC43-12AB926C634B,IdeBusPei +C32A66D5-D8B7-2640-B768-082C8F083C37,ThunkPpiToProtocolPei +C32B1741-9035-4935-AA2F-3E49ABC9D77F,HpThermalDiagsDxe +C358B1F8-8A88-40B6-89BB-28ECD6EDDB24,PxeDriver +C35B1E30-30F0-4F14-B603-28556F14F874,DellDtDevCountsDxe +C35F272C-97C2-465A-A216-696B668A8CFE,UserProfileManagerGuid +C35F9520-5791-4667-ADE4-1CFDA837722D,AmiSmiVariableDxeDriverStarted +C37297CC-3FD9-4026-9890-7A1628184620,EcIoPeim +C3745B97-5133-4BF7-8185-663617B95EBF,UsbPwrCtrlDxe +C3811036-710B-4E39-8CF1-0AF9BE3A8198,TimerDxe +C384EED1-B17A-40E4-B0C9-BE86D8B4DE40,KEMhResetBtnPei +C38E6D34-5A7F-4BF9-BE57-94DD30380276,EfiPccardSsProtocol +C38FB0E2-0C43-49C9-B544-9B17AA4DCBA3,PowerManagementAcpiTables +C3944F59-4029-CCEB-AE0D-D4A6B479924F,UsbPortConfigDxe +C39B4C90-CB56-49BC-9534-012F69A1C2CC,UuidPeiInit +C3A657D6-5FD4-4BAC-BEDE-0EF613750870,CrashLogVariableUpdateDxe +C3B95ACF-4ED2-8462-AA52-788415A61C4B,GpsOnWwanSmm +C3C242D1-0103-4C74-9A19-3C5C3B47EBCE,DellBiosAttributesSmm +C3D69D87-5200-4AAB-A6DB-2569BA1A92FC,Tpm2DeviceLibRouterDxe +C3DFAEFE-D237-4A20-8BBF-5444FDE098DE,FjPostScreenMfgFirstPowerOnDxe +C3E36D09-8294-4B97-A857-D5288FE33E28,EfiBiosIdGuid +C3E69EB2-0429-4BD6-AE4A-8CA02FBACC2E,AdvancedAcpiDxe +C3EE3EF0-63E6-4F59-A437-AFA63C46C835,SmmAslSmi +C3EF34B6-057D-4614-B35D-FD4384FA2391,AmdFabricRplSmm +C40DAA42-6E1D-4F6F-96F0-5E17BC8A1D4B,AmiHeciDeliverRuntimeDxe +C40DF81F-7436-4661-B645-A933B5D2F3C1,AsusFWUpdateInterface +C41459C2-A281-40D3-B30A-2B9DFF3F3DA0,DellSaveMemoryConfigDxe +C41E9862-D078-4E7D-9062-00E3FAC34C19,AsusEcPei +C41F8C82-B3E6-47E0-A61D-0F9E429E6996,DebugCommunicationLibUsb3Dxe +C426C295-9829-441E-931E-9CE35E3F9FE6,UiThirdPartyApp +C42DD02B-BB83-4118-8F16-31011415A63A,UserLEDCtrlPei +C4331752-8BAC-4F2A-A9C3-418ADFB033C4,DellSpiPartWinbond +C43E2CF0-BEDC-461F-AACD-A4FA466EA382,LenovoTpmConfigPei +C4408AAC-281F-4C4A-BE99-2E5C56BCC16D,OdometerInitDxe +C448F450-D9D2-4BDF-AC47-6EB2A225D54B,AmdOemRasRsDxe +C4491F51-66B9-4590-95E4-E2B4AD777703,HeciSmm +C45BC25F-3937-4FC4-AC79-BBE8BD3E5F97,AdlinkBSCSmm +C463CEAC-FC57-4F36-88B7-356C750C3BCA,UhciPei +C464322E-3DC4-49AD-B9FD-AF1B56B2249B,HwAssetDxe +C468B382-4550-4909-AD57-2496141B3F4A,AsrockRaidX64 +C46ACCBC-5765-40E3-87D2-82A568AC991B,PcieRpConfigGuid +C46CCD44-D365-4C2C-9BDC-42E61B57E23F,FjI2CProtocol +C4700DAB-41B6-4FDF-CCAA-E39736FFF2BA,I2cPlatformSpecificDxe +C47D89B9-B9DC-4CA0-BB20-5B06EBE57A1D,IpmbDxe +C48D651C-9D0E-4CE7-AD39-EDD1AB836B30,AmiTseAfterFirstBootOptionGuid +C49189F3-1D4C-4AD7-A439-D013AB720931,PerfTunePpi +C491D352-7623-4843-ACCC-2791A7574421,DefaultdbFile2 +C4968F6A-5CCC-4BDC-9E86-B7A65A2EEAF1,AmdCdmaDsmDxe +C4975200-64F1-4FB6-9773-F6A9F89D985E,SaPegDataVariable +C498F432-B8B7-44BF-86D3-7B36F2EC1390,IFWIVersionHobGuid +C49A3700-A175-4451-BAE1-3E5F91D0D46A,DellAmdCbsApcbUpdateSmm +C4A58D6D-3677-49CB-A00A-9470765FB55E,AddPerfRecordProtocolGuid +C4B4A7FB-D2E2-422C-4179-E5D46B1E1AA6,OneKeyRecovery +C4B50EB2-ED16-4283-A5B0-A7341C3F997B,ArmTrustedMonitorLibNull +C4B769CD-2876-41BD-ADA2-79677F9697C3,aDefaultPei +C4B8C7FB-D2E2-441C-BAD6-E5D46B1E1AA6,L05DxeServiceBody +C4BBBAE3-F891-4D4A-90EE-0F05D932C151,FpdtPei +C4C7A1A9-D639-442D-B358-09D06AE18BFC,DellDaAssetTag +C4CC0DE8-0687-4422-99C1-65351A5D5F95,UserDefaults +C4D1F932-821F-4744-BF06-6D30F7730F8D,Ps2KeyboardDxe +C4E83158-DE62-4A33-A381-75A4C0EED568,PhysicalPresence +C4EB3614-4986-42B9-8C0D-9FE118278908,CrystalRidge +C4ECA0B2-5277-4F2B-3ECB-E4175C94812E,ExtraS3Memory +C4F2D007-37FD-422D-B63D-7ED73886E6CA,IdeRController +C5046EFD-7BC3-4206-987C-32DA45026E6D,PlatformInitDxe +C5068BAC-A7DC-42F1-AE80-CAA24BB4904B,PttPassThruPpiGuid +C50842D6-B284-4F3D-904B-E2DC83E00AF8,EarlyConsoleOutInterfacePei +C50B323E-9075-4F2A-AC8E-D2596A1085CC,EfiSmmIchnDispatchProtocolGuid +C5149B43-AE85-4F53-9982-B94335D3A9E7,EfiRngAlgorithmSp80090Hmac256Guid +C516673C-6C71-4F0E-83B5-57FC662376EC,LibPosix +C51711E7-B4BF-404A-BFB8-0A048EF1FFE4,EfiIp4ServiceBindingProtocolGuid +C5184932-DBA5-46DB-A5BA-CC0BDA9C1435,EfiHashProtocolGuid +C522E695-93FF-4AC7-8220-F849C68C538F,AsusApmPei +C53B2402-0073-4C8C-B4ED-99F362742D24,CrbSdev +C53C63B4-39C1-4185-BC9B-0FE9722A0C60,SmrrEnableHobGuid +C5440ED5-9BA4-4ABE-BAF6-F45468481DCD,CbsSetupDxeSTXH +C54B425F-AA79-48B4-981F-998B3C4B641C,TrEEConfigFormSetGuid +C54F4B67-E527-4379-BF61-193C7A68C661,menu_none +C54FB758-5DC3-4068-893A-4E67F7CCF5D4,FjDmiFJJSpecific +C55C14F8-8ED0-48CC-9836-DDF6A3C5EA11,InstallRavenPlatformSsdt +C5653FBC-B146-4B91-8EEF-1AEEAE7A0160,ToolInitialDxe +C56EDB22-3D78-4705-A222-BDD6BD154DA0,TpmClearOnRollbackSmm +C56FB1B2-017B-4984-A3F6-3F734FFA9E33,EfiUdpProtocol +C5753963-3B84-4095-BF78-EDDAD3F9C9DD,EfiPciBusErrorSectionGuid +C57AD6B7-0515-40A8-9D21-551652854E37,EdkShell +C5847038-FF75-4074-9E4C-C36A2EB398A5,LibTime +C58B7F84-FFA7-4112-8097-C765CF7515C8,OemGetEdid +C59716EE-2D90-4B1D-9C36-16523E105689,AmdNbioIOMMUZPPei +C599195F-9B5B-4910-9310-A6103F5ED3F6,POSTWarningDxe +C5992599-D96A-47CC-9FBA-13E19F00F6FC,BBLSupportDockingDxe +C5A9B3C5-6307-43CC-8D72-9BC67EEE6570,SystemPolicyManagerDxe +C5B04B6F-07E8-4663-9345-BC72ECCBB397,FjNvramVariablesAccessReferenceDxe +C5B9C74A-6D72-4719-99AB-C59F199091EB,SemihostFs +C5D3191B-27D5-4873-8DF2-628136991A21,UserIdentifyManager +C5D5B33B-3759-4CD1-955F-0D1E7719E49E,MFGRTC +C5F25542-2A79-4A26-81BB-4EA63233B309,EdkiiNonDiscoverableNvmeDeviceGuid +C5FA0EE8-2D81-4202-A021-3DA700B3DEAE,AmdCpmPcieInitDxe +C5FB3DBD-8A3B-4C12-AE63-118DA72FEE83,AmdFabricRnPei +C6068612-B6E0-48A3-BB92-60E4A4F89EDF,UefiPciSegmentLibPciRootBridgeIo +C60AA7F6-E8D6-4956-8BA1-FE26298F5E87,EpcBiosDataGuid +C613EC78-63ED-4B93-ACD4-54B3D4CCC268,NetworkLockerDxe +C61C6982-B904-4CEF-BF1B-C63BF7CA0352,SataPeim +C61C6982-B904-4CEF-BF1B-C63BF7CA0399,UsbPeim +C61EF796-B50D-4F98-9F78-4F6F79D800D5,MemoryInit +C629036A-2EF0-4A74-9642-A9FE3884275E,AmdFchHwmDxe +C62CEB80-FB40-4A46-A5E5-C1D997C36DFC,CapsuleLoaderTriggerDxe +C62F4B20-681E-11DF-8F0D-0002A5D5C51B,PciHostBridge +C642C14C-0E9C-4AEF-94A5-A213BAA35DE0,HstiResultDxe +C65A623F-2768-4700-BE2C-1D8BA2C43998,Inside +C65AF0E1-82B3-416A-8F0A-DDD0D3098C58,DellPbaUsh +C65CFED1-8BA5-48D4-A493-9E12F17952B0,FjGabiSettingsApiItemAccessSmm +C6602CDF-E16A-4147-9B9A-0B399498722A,SystemCrisisRecoveryPei +C666A794-406D-4A51-B303-ACFB59137A05,UsbOcUpdateDxeEldorado +C66E52C0-082A-48AB-BDDE-ED60C88CC4DA,FjLanReInitDxe +C66F98CC-9840-40A6-BDC1-7B4CCC77F8C6,RtkUndiDxe +C66F98CC-9840-40A6-BDC1-7B4CCC77F8C7,RtkUsbUndiDxe +C6734411-2DDA-4632-A592-920F24D6ED21,AmiAtaPassThruInitProtocolGuid +C6760651-A38D-5F4F-AEAF-F6661549DF75,EmuBlockIo +C67CBA49-B3C6-4CBA-9671-BF2788712128,DellLegacyTcgSupport +C681ED8F-FC2E-41A4-8F3F-2C2A1961A81B,FchProm21Pei +C68C190E-F95E-4ABC-AA01-D65F344D91F9,LGImageRecovery +C68DAA4E-7AB5-41E8-A91D-5954421053F3,CbSupportDxe +C68ED8E2-9DC6-4CBD-9D94-DB65ACC5C332,EfiSmmCommunicationProtocolGuid +C694F176-570E-48C7-840E-1B30920CBA76,FjIbvBiosPasswordAbstractionSmmProtocol +C69BF28B-16C3-434F-A4A4-292BDB0F4D12,LenovoVariableDefault +C6A957E4-8303-4761-A084-92C0692D90F9,PoofAnimationState3 +C6AA1F27-5597-4802-9F63-D62836598635,SaPolicyProtocol +C6BB86C0-16F5-4535-953E-E6C7CB6E4CB6,FpgaErrorHandler +C6C9AC93-CFC8-414C-872B-D0116F076BF9,HpThermalDiagsSioSmi +C6D37AB1-ACBB-4928-A956-577BB3DBB751,DellDimmLocation +C6DF98F2-5EC0-4A94-8C11-9A9828EF03F2,WifiConnectionManagerDxe +C6E9602D-C00D-4250-B24D-FE324B8DA40B,AcerPortingDxe +C6F6CF5A-F085-401E-8402-00134B668703,FjFextPei +C70522D0-0DDB-4623-AAB7-B84DFC47EFFD,AodSmmSsp +C70522D0-0DDB-4623-AAB7-B84DFC47EFFF,AodSmmSsp +C723F288-52F9-4D80-B633-E152F930A0DC,EfiSimpleAudioOutProtocol +C7340A2F-0539-42F1-B9EB-0C35237A4923,CbsBasePeiRMB +C73413C9-405C-4F50-BA17-0DFFB913ED16,DellDockPolicy +C7351A96-9215-4026-BCBD-12D6E7DB36E9,SystemFormBrowserMetroViewDxe +C74233C1-96FD-4CB3-9453-55C9D77CE3C8,WM00WMISmmHandler +C74D1B0B-91B1-484A-A038-FE7A0847AA07,DualBiosDxe +C74E5DB2-FA96-4AE2-B399-15977FE3002D,EfiSpiHcProtocolGuid +C74F06D2-ED92-489B-879C-C0E428A22167,UefiRaid +C7542254-A8F7-40BA-9BB9-390D31977775,OCMR_PEI +C75F1B28-B273-4F0D-9838-952B70E6B9B4,UsbCardReaderSmm +C770A27F-956A-497A-8548-E06197588BF6,RecoveryOnFatNvmeDisk +C770F6C2-3278-4A57-A1DB-E177F8DB2CD7,AmdRAIDCoreDxe +C7715FBC-E2AB-4A33-840F-5DCD0198E552,SaDxeMiscConfigGuid +C7735A2F-88F5-4882-AE63-FAAC8C8B86B3,EfiVAminiPortProtocolGuid +C776AEA2-AA27-446E-975B-E0BEA9078BD9,BiosGuardPeiApRecoveryCapsule +C779F6D8-7113-4AA1-9648-EB1633C7D53B,CapsulePei +C77C3A41-61AB-4143-983E-3339280628E5,EdkiiCpuFeaturesInitDone +C77DD102-1DB4-4997-AE37-4E8C521EF567,AmiProcessTcgSetupGuid +C79DD14B-C66D-4ADD-A5A1-CBE3FDF2BD72,DisableCacheAsRamPei +C7A0C4A4-B05F-41C1-B137-F19686B302AF,SetupConfigUpdateDxeSierra +C7A7030C-C3D8-45EE-BED9-5D9E76762953,MouseDriver +C7A90676-51CC-4FFA-B5CA-69EA88D2F78D,EfiPlatformTypeOpalCityFpgaProtocol +C7AD44B9-A775-4801-B772-A964262BB92E,ModuleS3ResumePeim +C7B11F3C-89E9-445F-A972-671B8B17580D,DellSmbStrucB2Config +C7B7070B-E5A8-4B86-9110-BDCA1095F496,PeiFspHobProcessLibSample +C7C27153-E7FD-4D67-9670-CB214EEF0F0E,LEMBBRecoveryPostFlag +C7C62103-5E52-41BF-820A-2B2C21A89825,BdatDxe +C7C89169-1A42-4E5E-B34B-E6830671C9A6,AmdSb900Smm +C7CAF1C7-2D97-45CB-99D9-D89AAF8ACC11,DellSecurityVaultSmm +C7CC7BAF-73B8-42D5-9BE9-6C8D03137ED8,AsusSecureControl +C7CFEB7F-AEFD-421D-BCDF-033329AB8B4C,GetVariableHookPei +C7D35798-E4D2-4A93-B145-54889F02584B,EdkiiNonDiscoverableAhciDeviceGuid +C7D4BBCF-EB0A-4C91-BD8B-FCA99F28B011,AmiTxtPei +C7D4F4E3-DAEA-40B0-8846-F4CAF3135CE8,BiosProtectDxe +C7D7B773-68E6-4626-80F9-609C4451EB0C,FjDmiWakeCause +C7D9BAF4-DC9D-4B22-B4E7-7500EAA7B67F,SiliconDataInitPeim +C7DAF48F-4787-11E4-9077-047D7B99E097,VariableRuntimeProtectionDxe +C7DCFF6F-6F2A-4DC1-91C6-DF0BAFDBDA46,VbtMipiSharpGuid +C7DD8530-96D8-40DD-BE88-CBDF446C6474,Stibp +C7DF48CC-063E-4FD4-B775-75C00D9F19F6,SmbusDebugPei +C7E201B7-611E-4FCA-830E-7469C3B39218,FjMfgTestBatteryDxe +C7E6800D-9566-1143-81A8-B8C566AF3556,SNP +C7EA9787-CA0A-43B4-B1E5-25EF87391F8D,PchS3Support +C7EA9F94-1547-44F0-863F-563EAE79E1C0,TianoCompressSmm +C7F7A2D8-7DC9-40B5-AF51-7BB0A1FAF12E,FjAzaliaVerbTable +C7F9E27D-045A-4D33-85BD-C7D0ABA7C836,It8659 +C7FCCF43-5859-4ABE-BCB5-4C1626ED8B03,DellPeiDiagLeds +C80EA8F3-A3C9-4225-AA60-769DD4C74E43,LenovoSvpManagerDxe +C810485E-D0EC-4E98-AAB5-120C7E554428,TdtAm +C811FA38-42C8-4579-A9BB-60E94EDDFB34,AmiTseSetupGuid +C81C25C0-533B-48DF-93E5-B87807901CF6,MiscFunctionPortingPpi +C81FFCBF-BB77-400B-BC86-C9B16CF95EAE,AppleUsbNotify +C826B086-AE21-416C-9977-0D55AAE742B4,EcAuditLogPei +C828DD3F-8868-40A6-AA59-D5CA372D0937,UefiDriverAsix88179 +C82919D6-33FD-43ED-800C-635A3369D0F3,SystemDiagnosticSummaryScreenDxe +C8300EA9-869E-42DF-AEF2-5D939452A353,SetupDefaults +C8339973-A563-4561-B858-D8476F9DEFC4,Metronome +C84D9EB9-B703-4CA1-BF74-903106A37346,aDefaultDxeLate +C85171A2-9CBD-4E74-8C9B-D33384A236A3,I2cGlkToMde +C85903B6-84B5-4D78-B59D-D2D6B97580F3,PngConvertDxe +C85D06BE-5F75-48CE-A80F-1236BA3B87B1,EdkiiPerformanceMeasurementProtocol +C86181CD-B38C-49DD-A176-7DC3591816A9,DellHotKeysConfig +C8638628-5B57-47B9-BA9A-AB1F90709C3F,AmdPspDxeV2StxKrk +C866BD71-7C79-4BF1-A93B-066B830D8F9A,MpS3 +C867A8C3-5BF1-4B33-82FE-B1B49D5286EE,OEMAcpiPlatformSmi +C8714E83-895E-4192-FFFF-FFFF293630B3,XnoteRecoveryLauncher +C8786997-70D7-4445-A5A8-E5C9C8DD56C6,MasterPswd +C87DBB18-9ADD-41D5-80D7-4C8D795AD942,DellSmmEventSmm +C8858B5A-7A6A-4193-9253-CA6AB5F1EA37,DashMctpSmbusDxe +C887F4CF-4565-409B-9178-D2BF1D228DED,SioSetupUtilityDxe +C88B0B6D-0DFC-49A7-9CB4-49074B4C3A78,EfiStorageSecurityCommandProtocolGuid +C88D7B8B-2A7B-403D-A8A2-EF0A5AEE662F,OemEcRTCBackup +C89851DD-5EA0-42CE-8934-EB8EA608FBA9,LenovoSystemAcceleratorKeyDxe +C89CEC07-C4EE-440C-BFC5-A22F43372F22,DellDashConfig +C89D72CE-E21A-4C71-BA79-770EF373D6DA,BootSector +C8AB0F4E-26FE-40F1-9579-EA8D30D503A4,SystemFlashUpdateDriverDxe +C8B2ED5E-B80C-4C09-A315-3A53D2625E1A,HpPlatformDxeServices +C8B36958-00A7-4678-83EF-E5525A8CE4A4,OemFixedBootOrderIpmi +C8B64E46-9819-45AB-875D-09DFDA6D8B1B,Firewire +C8C07CBA-2F2C-416F-9519-D4F49DA65736,DlUefiUndi-X64-release +C8CA0BB8-67DA-4883-8CFC-9180CB9EEC68,OemActivation +C8CAFFF9-C6E0-4443-B96F-45FE2AD480CD,IsHdpRequiredPostFlag +C8D831A0-3576-41C8-B0A7-D94024356395,OemDisplayModeDxe +C8D85E8C-DC1C-4F8C-ADA7-58C1D107A304,EfiPeiSystemBoardPpi +C8E1EE4E-1B9D-439D-B204-328BB5973F0A,SetDevPhyConnStatus +C8E94F20-D850-4C27-BF03-A78055084E07,SystemBiosSelfHealingDxe +C8EA84CE-18AC-4BB3-9A23-FB49250F35A6,FjAudioFp +C8EEBF0E-0E10-47F7-81BD-39DB75CA939F,EfiGenericFruProtocol +C8F23B39-C95C-4318-9233-53FB3AC44592,VariableVsr +C8F6D366-DDF1-4960-9D57-82F2655A1294,AodPei +C8FF7F70-1B85-4C66-A983-69699F62E91E,N19EP_GOP +C9122295-56ED-4D4E-06A6-508D894D3E40,FspApiPerformanceGuid +C9168F11-0C60-4A8C-A41F-1B2289315F4E,EcRotEnterRecoveryPei +C91C3C17-FC74-46E5-BDBE-6F486A5A9F3C,AmiRomLayoutFfsFileGuid +C9265471-71A3-4D74-AA7A-3E6C5EC81135,AmdRasBrhServiceSmm +C92B795E-CDFC-4932-91B5-00BBB5F0C95E,FjIbvInterexchangeDataStorageProtocoDxe +C92E82A5-AD25-4800-9422-CBE8E7A30477,OemDgpuBoardIDDxe +C92F72B5-7DD0-4E15-9D2C-A52CBD30CA1E,LenovoSmpManagerDxe +C937B8BF-ECEB-4F42-907E-37A5D4C17B9D,CompalEepromDxe +C937D89B-5F9C-4A1E-B10D-8F53D7474220,AmiPspRecovery +C939F82A-3501-4657-8256-FD4C2288872F,HpErrorLoggingSmm +C93AB4BA-796E-4956-BF8A-B46EB1AFE737,MfgDoneSmm +C93BD9EF-FB79-41CA-AFA2-C9D909730C91,FjAcpiPlatformDxe +C947C2CA-C1E2-4007-BBE0-FD7C7865A548,DellNvmePwPei +C952402C-F2A8-410F-96F7-2C789BE0E0A1,LenovoTamperDxe +C95E6A28-FB95-49F2-AE01-F38166FD4524,OemServicesDriver +C95F8AB0-1BC2-417C-8377-9815F578A9EE,UsbOcUpdateDxeExpertWorkStationRP +C96C3984-429E-4FAD-8A61-C1E86BA43BF8,AmdNbioIOMMUDxe +C96C76EB-BC78-429C-9F4B-DA5178C28457,TpmNvsMm +C9737920-C2AD-41C3-B133-0F9C251B6743,PeiDebugDispatchPpiGuid +C97809C0-5F90-4466-8B38-341D7A67CF54,LenovoSmapiSmm +C9839A23-4B0E-465E-8F29-14A5010CA7DF,PerDisCptInRomPostFlag +C98AE68F-82B9-47BC-BE87-33240E110D68,DellUefiBootInfoSmm +C99E42D0-4964-4B09-B924-4A59E13E4F04,SbRunSmm +C99F80E9-4CCC-4F34-AFE7-9194BF121412,GnbSocPhoenixDxe +C99F80E9-4CCC-4F34-AFE7-9194BF123590,GnbSocRaphaelDxe +C9A3B737-8841-499E-814C-463054C7C7A3,FjPowerOverEthernet +C9A44DC1-A394-426C-8B3E-7EE532A55037,AmpI2cDriver +C9A6DE36-FDFF-4FAF-8343-85D9E3470F43,NvmeInt13 +C9B8B0B7-9C85-46E8-B343-362FBD26E8F3,MuCryptoDxe +C9BD03EA-40D6-D14E-0FFE-6B803FC3ADF4,CpuTechDxe +C9C01943-980E-DD30-A095-A411ACB3D229,WtTouchPanelDxe +C9C30DD7-91D6-4F75-BF08-846E6020F1A8,AmdNbioIOMMUZPDxe +C9C39664-96DD-4C5C-AFD7-CD657629CFB0,CpPlatFlashTokenSpace +C9C87129-DFAC-48DE-8581-7363A90E101D,UFSProvisioningTool +C9D9CE44-708D-4E27-B989-E35A33999C28,DellSmmMultiPlatform +C9D9D2A1-E586-4F2F-BF6E-99240C069EB1,RealtekWsTbt3Pxe +C9DCF469-A7C4-11D5-87DA-00062945C3B9,EfiStandardCallerId +C9E057D7-3B6D-475C-B8C2-7C955D2F58B3,gear4 +C9F1A91B-3AB2-4AEA-8B5A-374876B941A3,SDEmmcInfoSetupUtilityDxe +C9F36E6A-6884-465D-A20D-0610B65CFCD6,SyncBIOSimage +C9F5A078-1F2D-4086-A1BE-1638774FEF44,SsdtRtd3ATables +C9FAF091-57F8-A64C-A07A-445B124F0D93,FlashMapPei +CA05F74F-1E56-46A9-AF6C-DE5BBE83A37D,MemoryMarginToolHookSmmStp +CA0D6FF6-62A7-4B1F-BB90-52EECA01A99F,TCM_MADriver +CA1BCAD9-E021-4547-A1B0-5B22C7F687F4,ACPIOSFRModelStringVariableGuid +CA261A26-7718-4B9B-8A07-5178B1AE3A02,DiskIoDxe +CA2F6405-4953-4C00-9C46-D18683A9003F,SmmKbcDriver +CA3668C7-AE4E-454B-9E46-DA97AAAE0FF5,X11SmmDriver +CA37BC1F-A327-4AE9-828A-8C40D8506A17,EfiDns6ProtocolGuid +CA3B3A50-5698-4551-8B18-CEAEEF917D50,DxeDebugCmdProtocolGuid +CA3FF937-D646-4936-90E8-1B950649B389,EfiSocketPciResourceData +CA4233AD-847E-4E5D-AD3F-21CABFE5E23C,WinNtOemHookStatusCodeHandlerDxe +CA452C68-DF0C-45C9-82FB-EAE42B312946,EfiVLVTokenSpaceGuid +CA452C6A-DF0C-4DC9-82FB-EAE2AB312946,EfiQuarkNcSocIdTokenSpaceGuid +CA4853F4-E94B-42B4-8642-CDE28A7FAC2D,PeiTpmPpiGuid +CA49B5C8-E977-4612-8706-91B82CD14C87,IntelMchAcpiTables +CA4BBCF2-B43D-4D8E-984B-56A4ECBA2A40,IntelRSTWrapper +CA4D1912-C415-4686-8615-A0823D8C4F27,Cf9ResetSmm +CA515306-00CE-4032-874E-11B755FF6866,DataHubStdErrDxe +CA54F443-1EF2-4DAB-9E7E-6DB7B720B587,EfiPccardCsProtocol +CA5627C4-51BA-4DCB-AC62-C076EBD37DDB,Python +CA599759-90A7-4FE4-BC8B-4B71C350DCAC,LibGen +CA5A1928-6523-409D-A9FE-5DCC87387222,TrEEPei +CA5D7EB0-1B67-4B0B-964A-F2A861F0D640,IccOverclockingDxe +CA5E3DF0-940A-48F1-8C14-DB2FB5998B36,TdtWrapper +CA6EB4F4-F1D6-4375-97D6-18856871E1BF,UsbLanDriverSrc +CA771C80-02D9-11E4-A195-78E7D1AF36D1,HpNetworkBiosUpdateWmiSmm +CA786553-AC6A-41AA-9AB6-531630850C92,ICE30plusPEI +CA7ACEF3-1181-4AE0-95A7-0F1FD8AFD2ED,LenovoSystemKeyDescDxe +CA84408A-0929-4F11-BFED-18C7D9576C6B,PlatformInitDxe +CA886C07-ACDF-41A6-A501-CBC53DD4008D,DellPeiReportFv +CA89914D-2317-452E-B245-36C6FB77A9C6,SaSsdtAcpiTableStorageGuid +CA915DD3-4C9B-4471-ADE1-33DF66765DFD,LenovoDashSupportDxe +CA9725C0-12E5-4FAC-AD58-D9AAB03B8F11,LenovoHdpManagerDxe +CA9D537C-0B20-4F94-9283-45F4D51A748D,DellAsfBypassAbstraction +CA9D8617-D652-403B-B6C5-BA47570116AD,TxtPei +CAA3FA1C-76C4-44CE-BEC0-3E6D847AF8D4,EfiSmiServices +CAA4381E-750C-4770-B870-7A23B4E42130,EfiHashAlgorithmSha512Guid +CAB0E94C-E15F-11E3-918D-B8E8562CBAFA,EfiBootManagerPolicyConsoleGuid +CAB9347C-8CE9-4DE1-9C6F-6457AC69332B,PrepareForScheckEvent +CAC3FB95-33F5-4596-818B-68E024DDB67B,IsSecRecoveryPEI +CAC7FADF-36F8-414F-8E1C-8A80AA5C78D6,DashPldmBase +CAC94001-5611-4440-9B21-F54B700A1D34,DellSmmSystemSioProtocol +CACB3817-81E6-497E-87FF-C8FA8F24EC28,SgACPI +CAD40D6E-C871-4398-910D-2D74EE94711A,AmiTseAfterTimeOutGuid +CAD9920E-0CF5-4C6B-B92B-CC0A4E19557C,FjSysmanAmphionSmm +CADAB771-60DF-A925-19B3-0A6608DD2DA5,CCGxFwUpdateDrv +CAE0AD55-47B7-4E03-A714-95E1711CC279,BcpBootOrder +CAE2D87D-5CBC-47E7-8CAD-50377A5D0E90,PlatformErrorStrings +CAE3AA63-676F-4DA3-BD50-6CC5EDDE9AAD,EdkiiPeiNvmExpressHostControllerPpi +CAEB83C4-23AA-4311-8327-8B72DDB7041B,RcPolicyOverrideDxe +CAEE2F3B-3191-4DA0-AD10-A5C07E636CD1,LibString +CB077E14-EBD8-4AC2-986F-82F3CD4E717E,SdHostDriver +CB2337F3-CF73-4164-9B73-798BBF8928DF,TPMDxe +CB2987B9-63AE-4B91-BF43-21FF641A5D49,AmiUpdateDxePolicyCallback +CB2A97CF-3D3B-4215-B528-7B8944200E46,CcgxDiscovery +CB2C0D12-8E6A-4B12-94F4-1BC49EC460B1,AmiHstiPkgTokenSpaceGuid +CB3FD86E-38A3-4C03-9A5C-90CFA3A2AB7A,EfiExtendedSalMcaLogServicesProtocolGuid +CB494BAD-23FF-427E-8608-D7E138D3363B,ArmPlatformLibNull +CB49CE50-3A75-11DE-8A39-0800200C9A66,PerfTuneSmm +CB4B5BB5-59A6-48BA-A77B-B4E4B3D491EB,OemDxeWwan +CB4CE667-ED8D-4A66-B437-EA6A970F2E48,SmmResetSystem +CB537AA2-F727-440B-9702-ADE9D0A293F1,PlatformStage2Pei +CB5C54C0-230D-43DB-922C-24D34F8C915C,AmicsmPciBusNumXlatProtocol +CB659161-B780-4906-914A-DB57D1DD544A,EupControl +CB73C3D9-2F01-4342-AE67-04DDE5264092,SmmPlatform +CB76358C-3A21-44BF-B7C1-33F064AC4C11,DisableUSBPei +CB7A797C-57D9-4616-88B4-624213967BD7,CompalDptf +CB871572-C11A-47B5-B492-675EAFA77727,EfiDiskInfoUsbInterfaceGuid +CB8C0E4F-14F7-4F5A-8DAD-752CB0B42045,SystemStatusBarDxe +CB90F8BD-7012-407D-88A3-7D5E9E701B87,PilotIIIPc8374 +CB933912-DF8F-4305-B1F9-7B44FA11395C,AcpiPlatform +CB934658-ADA4-40E5-98CE-9B476FA108B4,DellPcdUpdateDxe +CB992535-8713-4ADE-94F2-5D32CCAB8C5E,PostIbbVerificationCollectorPei +CB9B43DD-4233-DB03-E0ED-ED89C0D09CAC,AmdSocAm4MtsDxe +CB9B939E-FB6D-48B7-9E58-90188D77189D,SgTpvAcpiS3Save +CBB2E6A2-C6F2-4D68-A75F-AE621565C736,FchSmmDiagDispatcher +CBBEE336-2682-4CD6-818B-0A0D967E5A67,EfiClpProtocol +CBBF9572-28DC-4712-AA9D-0FF6E4029BFC,AmiSystemCredentialManagement +CBC59C4A-383A-41EB-A8EE-4498AEA567E4,FlashDriver +CBC6B94E-DEAA-462C-840C-6698180DE292,QualcommDRS +CBC91F44-A4BC-4A5B-8696-703451D0B053,ReserveBootGuardFvMainHashKey +CBCA3D88-CB1E-49C3-B448-5FF287C58D40,LenovoEn25Qh32FlashPartSmm +CBD2E4D5-7068-4FF5-B462-9822B4AD8D60,VariableRuntimeDxe +CBD4418D-4239-499A-97C8-C10622F99D0D,H19MPMDxe +CBD86677-362F-4C04-9459-A741326E05CF,SeCUmaPpiGuid +CBDAF74E-D6E8-4934-BB03-27F356D4B91C,FjEarlyInitPei +CBDD2397-D2C5-415B-BD77-9630A1B7853D,EfiPeiIpmiUsbTransportPpi +CBF25110-18FF-4EE3-9735-E2477436FF3F,XnotePlatformInfoSmm +CBF36E61-59D3-11E8-8518-B05ADAEB7886,NvdimmLostPassphraserecoveryDxe +CBF486B7-D196-4C03-AFE2-33F38E64DA16,IntegratedTouch +CC043281-112F-441C-805D-6D8DB3659618,BbstableHook +CC05C4D7-87B1-4605-A83F-592FFD53F959,mFmacDriver +CC0F2ACF-8883-4DA7-8F62-39A6BDC6BD4C,OemSetupValueHookPei +CC0F8A3F-3DEA-4376-9679-5426BA0A907E,PkVar +CC17F218-E492-45A2-A1A4-16DBB1BB11C5,AmdNbioDxe +CC1BAA36-11EB-45CC-9ADC-7565E273AC70,PnpSmm +CC1FC04E-0B3D-4E0E-AED7-5898541E2683,CSMLinkerDxe +CC243581-112F-441C-815D-6D8DB3659619,A01D2DRecoveryDriver +CC276239-D6E5-41D4-AC30-36794E52B98B,FujInSmm +CC28F998-EB90-47FB-97CD-032151F6FCB9,OemSetCbsVariable +CC322E80-6A08-4E80-8BCA-01A84BA6CFE4,PciHostBridge2 +CC34A436-EC78-4330-96CB-1AD2216CF87B,InputmodulesApp +CC3CE225-D9E0-4AB1-AD66-B857C2D16D2E,FchKeithSsdt +CC42B4D3-7220-428A-9B6E-E44971D02809,DellSmmMfgPolicyProtocol +CC5263E8-9308-454A-89D0-340BD39BC98E,EfiEventNotificationTypeInitGuid +CC54F583-3F9E-4AB0-9F7C-D2C7ED1C87A5,AppleRtcRam +CC582C73-F48F-4B62-83E8-A586B4C88F84,AppleFirmwareFeatures +CC5AC8F2-EA85-48A4-8493-2021E0A30D0F,PlatformCsm +CC5D4D81-E9F5-4387-9207-D0A35D3E7575,AsusBiosDxeCrashFree +CC620D5E-FECF-49D4-B51B-461D52494669,AutoEcud +CC664EB8-3C24-4086-B6F6-34E856BCE36E,EfiWinNtPassThroughGuid +CC6E66A3-472A-4802-9B97-21420C026391,AmdCpmZeroPowerOddDxe +CC71B046-CF07-4DAE-AEAD-7046845BCD8A,LenovoVideoInitDxe +CC74AC11-6121-4EDA-A857-4D6EA9357CEE,Nct6126dTrdPeiInit +CC74C741-4A5F-4A8E-B689-D804AB4368CC,DxeNotifyEC +CC81918A-AC55-4FCD-83E6-0C1CC22937EA,WakeSourcePei +CC84D725-DA1E-46A7-9E75-4BACF1FD3902,SystemFontDxe +CC8A8528-23F3-427E-AF41-C91E3297B622,AmdFabricStxKrkDxe +CC93A70B-EC27-49C5-8B34-13931EFED6E2,EfiAlertStandardFormatProtocolGuid +CC9F5B7E-254B-4F8A-A648-034A40AEDA35,PlatformCustomizePei +CC9F6A7E-245B-4F99-B548-034B30BDDA44,FlexIoCard +CCA91175-03E3-442A-B3B8-2E4A335C1DEA,AmiHsti +CCABB74A-6077-49F7-A291-71EBB7A7036C,OA1 +CCABD229-51C4-4DE7-AE2F-3AAF71F9ECE5,SystemSetupAdvancedDxe +CCB16BA4-B0D5-401A-B047-E091B1C6467B,LEMDeviceInfoProtocol +CCB19F85-C026-4285-81E9-505BF52D2791,Cf9Reset +CCBF2786-CD6C-4308-BDFA-625870CEBF81,AmiCmosAccessPpiGuid +CCC4BC8A-0D71-4197-86D5-DD12E10A97E6,InstantOn +CCC53F6B-A03A-4ED8-839A-03D99C02B4E3,EfiNtLoadAsDllPpi +CCC5C136-ACD3-4251-9BDC-F663CD2297B7,AppleAudioDecoder +CCCACBF6-0BDD-4460-927D-D1D4F21EA6EA,DellBiosDRAMChipLocation +CCCB0C28-4B24-11D5-9A5A-0090273FC14D,GraphicsConsoleDxe +CCCC8702-BD68-45B1-8237-C7DD004CDB37,DellSmBiosStrucD2 +CCCCD383-7145-4850-A4BE-89C36A15BA15,GpioV2ControllerPei +CCCD2056-D401-4DEF-85B0-1FA11FF3B5E3,IioVvar +CCCD3CAE-170D-4E34-8766-57B9042BEBB9,EcEkKey +CCCDBAC6-7383-452D-B8AF-C5E29D7D0BFF,SystemPolicyManagerPei +CCE87321-962F-4446-93EE-C291F18612A7,OhciSmm +CCEC84CD-CDC5-4C75-8637-D4508FC79CCD,PngConvert +CCF23F50-F7C1-4F00-8E70-13643C37E8B0,TBTRetimerFirmwareUpdateDxe +CCF949FC-F831-4CEA-BFA1-C44983B99B91,AmdNbioGfxRMBDxe +CD0A2EE7-418B-47E3-89C4-65D9169EFD23,PublishMrcNormalFv +CD0A45A4-8980-4A63-9A0D-014549D283C0,FjUsbHubRTS5420 +CD167C1E-6E0B-42B3-82F6-E3E906199810,FspReadyForNotifyPhasePpi +CD1B61E8-C6B4-420D-A1C5-2A75083CB0A6,FjMasterPasswordSmm +CD1C556B-62BF-4EEC-8E73-7731F8E847B2,AmdCpmGpioInitSmm +CD2333D7-6A0A-4C76-8350-240ADA36A2C7,DxePlatformSaPolicy +CD26C70C-F69D-419C-AE25-50E844D1DAE8,RtkMAPT +CD28DACA-BDBE-481A-90AC-625C79CF234C,H19BIOSLock +CD2AC321-3EA6-4AA1-92B7-DAC13F900883,AmdCpmAudioFeatureDxe +CD2B6EB3-EA11-4848-B687-AFE57D3D1C0F,ApplePpiPlatformInfoDB +CD31F8A8-28A6-4E49-8B3E-4142BD006C41,MeUlvCheckDxe +CD361957-AFBE-425E-A358-5F5889CFFE7B,EfiHiiOldProtocol +CD3BAFB6-50FB-4FE8-8E4E-AB74D2C1A600,EnglishDxe +CD3D0A05-9E24-437C-A891-1EE053DB7638,EdkiiVariableLockProtocolGuid +CD3F92A7-9AE4-42F9-B2CC-B47A8615B85B,PcieInitPei +CD46127F-9245-4521-BB89-A6D85D68FC13,LegacyTableCompatibly +CD495FA4-8475-4ECF-9203-493C9CD5405D,EcDxeRestoreSmm +CD51358D-6E7E-45CA-B450-57C046BDFDDC,BmpConvert +CD539048-F16F-4F86-BD86-6B726BDC34F4,HpAcpiPlatform +CD541D77-6699-4B36-A31E-1AA4C5D5B946,AmiStatusCodeCpuBistData +CD554A69-EE4D-404F-855A-84A6A39755D7,AmiSriovLibNull +CD707DDE-4872-436F-B6E3-6F929184F959,BoardSpiConfigProtocolDxe +CD72881F-45B5-4FEB-98C8-313DA8117462,EfiI2cMasterProtocolGuid +CD72B362-8A6F-4699-AF55-03FD8924C506,HpRpsuDefaultsAndWmi +CD7C839D-0521-4B26-9476-9FF2CB70649A,OpromUpdateDxeNeonCityEPECB +CD84562C-6864-40A3-A081-C8D35E82B920,CspLibDxe +CD8F06A8-C30A-4A83-8C56-45D432A4BDEB,CbsBasePeiSHP +CD8FEC49-F25D-4A24-8FB8-EF9CA58067F0,SbSocRsPei +CD92B9B9-2D4C-466B-8458-95447D8E4AFE,LenovoSystemSmBiosSmm +CDB65801-494D-472E-A6A8-AFF5B76E8D1F,DellTxtConfigPei +CDBD2D34-0E33-46A8-A6E8-38AE30899FA1,EzTpmUpdIfxFwDrv +CDC0191E-1891-4119-817E-0B6A3685A511,LenovoSystemBusIsaRtcSmm +CDC11AE9-01E7-42CB-88EB-FDFFD8819893,TcgLegacy +CDC1C80D-E6D3-4A42-9229-75F3BEFCF109,PciOutOfResourceSetupPage +CDC5DDDF-E79D-41EC-A9B0-6565490DB9D3,IgdOpRegionProtocolGuid +CDD36FE6-CF3E-4B06-9241-0C8C45098049,AmdSocAm5RplDxe +CDD65692-2E98-45AD-B7EE-CBED4155DCE8,FjSystemDataPei +CDDBF370-3DA5-46D9-9D0A-BFC112EC5316,OemSsid +CDDD1FEC-7C13-473E-8AE0-7A0723ADC787,DualBiosDxe +CDE1A697-5BEB-7E4A-95D8-4078E564E70C,PngConvert +CDEA2BD3-FC25-4C1C-B97C-B31186064990,EfiBootLogoProtocolGuid +CDEB315F-C5D9-40F1-2314-60CB26262E4F,UefiSwitchMonitorDxe +CDEC3671-816E-43DC-A002-DCD645229338,I2cHostDxe +CDF0823D-0D05-40F2-A424-978BCD270156,FlexIoPortConfigDxe +CE033449-3D90-9644-862E-2D7D9AA3F06A,BinConvert +CE04E069-89C4-4B9C-89FC-4AA48E98163A,FchSmbusPei +CE063996-6C4E-4531-A18E-635EDD447A36,ShmInitPei +CE12B236-17E5-47B4-96AE-C85BBAC1E5BF,SmcAssetInfo +CE159F09-D896-4058-B5BB-1AE6EAB00E01,OemPowerModeDxe +CE19678F-3F08-4E81-A1F3-1886CA13ADA7,SiliconPolicyPeiPostMem +CE1C71E3-ECB3-4ED2-9DF4-2B38AB65B0BE,DellDiagManager +CE1F0D0A-2E92-4EBA-A171-AD89125CEE87,ValidateExtendedBiosRegionPostMem +CE2217A4-5565-4FD2-9AB2-53E18F9A50FD,SctMtlGopWorkaroundDxe +CE248B77-1179-4BC6-B324-9D2EDC4B976E,AhciControllerPei +CE25C500-D518-11E3-A146-047D7B99E097,ProjectServiceDxe +CE2B8E5E-CFA9-4F18-9AE1-ACEAB642892C,DellOA30CtrlSmm +CE345171-BA0B-11D2-8E4F-00A0C969723B,EfiDiskIoProtocolGuid +CE35B5C7-EF21-48FF-A476-3F5FAF3F98AD,PersonalityModuleDxe +CE366D33-B057-4C03-8561-CAF17738B66F,WdtAppDxe +CE3CAD4C-4743-0482-5909-F385307178C2,NvmeResetHookDxe +CE3DA938-6AD6-458A-8831-6B0A03DF6C86,Pentium4Base +CE3FA7C0-E9CA-11E2-9BF4-446D571553EB,LenovoStringDxe +CE3FBFA0-C4A2-46F6-AF38-FDD6BF409B0A,SmmSioHwmIo +CE4188D8-1D24-44E8-BCA2-2AB8F750AEC0,SetupConfigUpdateDxeHedtCRB +CE4385F8-DA0C-4E8F-9211-A7F954721D2E,FjLvdsInit +CE44C4EA-6250-4DFF-9C1D-86D3CD1E64A6,AsusVmdAiControlKeepVmdMode +CE4D553D-7FF4-4527-A38C-0411138D7B97,FjUsbTypecPwrLimitCtrlSx +CE57B167-B0E4-41E8-A897-5F4FEB781D40,EdkiiSystemFmpCapsuleDriverFvFileGuid +CE5A3D67-6831-47E0-946E-B3300D02E0C6,HpDmarDxe +CE5BB14C-DFB6-49A1-A614-77804ACBB489,AmdCpmOemUpepDxe +CE5BC14C-DFB6-49A1-A614-77804ACBB489,AmdCpmOemPTDxe +CE5E5929-C7A3-4602-AD9E-C9DAF94EBFCF,EfiIpSecConfigProtocolGuid +CE660500-824D-11E0-AC72-0002A5D5C51B,HdLcdGraphicsDxe +CE673A28-800D-4B4A-8316-2661F9B3D9C6,DimmTsInfo +CE6E807F-77C8-4237-BF25-F9C45FD18804,EfiLanDriver +CE6F86BB-B800-4C71-B2D1-3897A3BC1DAE,AmiHddSecurityInitProtocolGuid +CE76670A-55C0-484B-962E-84A2F65210A6,MEMPATCHPEI +CE7CD764-A1D9-44E5-9857-14FEFAAE96DD,PnpDxe +CE7E8F88-9D27-46C9-B633-21F8B8712071,BaseBoardPei +CE845704-1683-4D38-A4F9-7D0B50775793,EfiPlatformBootModeGuid +CE8A2C97-A09D-4DC3-9A1E-F8AB65075AFB,AmdPlatformRasBrhDxe +CE92C5B4-14B3-4AE1-A274-3FFE74A5ADC1,KEMoSetup +CEA4FF9C-D7BC-4F07-96F1-03F41F2B17AE,BaseFspDebugLibSerialPort +CEAB683C-EC56-4A2D-A906-4053FA4E9C16,EfiTemporaryRamDonePpiGuid +CEB0203C-DE91-4ECE-A95F-0217E959E191,SystemSecureFlashAuthenticationDxe +CEB409FC-FA01-4831-8BDB-7D06BE8FCC9E,PlatformG3State +CEB7FE23-21A1-4B5C-8E92-2E7B52A95076,Legacy8259 +CEB904D8-DE67-4286-8D3F-2259E6B781B8,UsbPowerShare +CED4EAC6-49F3-4C12-A597-FC8C33447691,PeimBoardInitPreMem +CED56284-CDAC-499C-9FED-69A944CE26CD,EcIoPeim +CEDF3529-7319-4530-9348-FB1211CDDFFA,OpenBmcSmbios +CEE19373-FB2A-4B8E-BEF5-B6D7731F4939,I2cBus +CEE33516-58E3-47DB-BB3F-2758B5A76C28,FirmwareVersionInfoDxe +CEE8BEEA-507A-49F4-A3D7-D1100A2008CC,SynQuacerPciCpuIo2Dxe +CEEC2EE9-BF2D-45D9-B96A-1144B062395D,UsraQuiesceLibNull +CEF05965-F399-42A0-A226-A3FE96AA944E,RedfishHi +CEF5B9A3-476D-497F-9FDC-E98143E0422C,NVRAM +CEF68C66-06AB-4FB3-A3ED-5FFA885B5725,SmbiosBoard +CEFF9D2F-F5E3-4DEF-B051-386FA007AE4D,AsusSmmCommBuffDxe +CF009B23-17B9-43EE-BB69-4393CA186B1C,LEMDeviceGuardInit +CF10171A-57F0-470A-90E0-62D95F213F9B,HpBeepDeviceDefaults +CF10F9FA-45BE-088A-0DCF-37B75CFE917C,SystemSmbiosLoaderDxe +CF28CD73-F3DE-4125-8651-61CC4D786FB2,OEMWMIDxe +CF2E24FE-ACA6-4D6E-9486-E9A55495D654,PlatformServiceRecord +CF2F5574-3C73-4D2F-976D-665CAD2E5381,ASUSDirectKeyDXE +CF316AE5-E183-4528-B351-E65D3481253B,EmbeddedDxe +CF31FAC5-C24E-11D2-85F3-00A0C93EC93B,BlockIoVendorGuid +CF3279BC-AD5A-4A13-BE80-FB7B6C17730D,StaticSkuDataDxeBigPineKey +CF368415-2CFD-4757-803F-6E273D9123EE,AcerLidPei +CF3EF6C2-F125-41A0-B3DE-73AF4143812E,FjCryptServiceDxe +CF46C339-0651-407A-8E85-D0D72731CCD5,RequestPOPOnReset +CF4915A5-B44F-4B45-A841-6CCDEA0B33D8,ApobStxHPei +CF5014F8-2EBE-4D57-AA83-D7A3607371EA,DellFlashRecoveryImage2Pei +CF569F50-DE44-4F54-B4D7-F4AE25CDA599,XenIoPciDxe +CF67DF48-F242-4D81-A88B-82832C8108CD,AcerHwSupportDxe +CF6BCADD-D4C4-4095-B2BC-417D7247890A,StaticSkuDataDxeNeonCityFPGA +CF6DC7FE-FBE5-4AFE-8A8E-E7CED473259E,SureStartTestModePlatform +CF7A379E-F788-44D4-AF65-165CE1E0ED68,SmcOptimizeDxe +CF8034BE-6768-4D8B-B739-7CCE683A9FBE,EfiPciHostBridgeResourceAllocationProtocolGuid +CF89079D-DE55-4618-8683-BCFB0D5C90BC,AsusSlp2Encrypt +CF8AC870-80E7-43CA-A2A9-A64CFBBACC94,EfiSmiServices +CF93C01F-1A16-4DFC-B8BC-9C4DAF67C104,EfiEventNotificationTypePcieGuid +CF9668F7-B0F0-4D7F-B41E-AEC794EEC7FC,LenovoSystemAcpiSmiServicesDxe2 +CFAA77CE-7208-43C3-B815-99E8D66A28BA,b57undix64 +CFAAE0D9-0C2D-4EC8-A122-F6EB5F380916,DetectErrorsDxe +CFB33810-6E87-4284-B203-A66ABE07F6E8,EfiHeciProtocolGuid +CFBCAB7B-050D-494F-A841-51BEEB73406E,USBControllerDxe +CFD3C49B-56DC-465C-B3A0-419A8B42CB60,EfiAcpiParameter +CFD5D6B3-3C21-4F15-B0E8-088F0128890D,OemInt15CallbackSmm +CFD65085-DBE1-4691-95D1-855B2CA00C69,FjIbvSfuOverrideAbstractionSmmProtocol +CFE3CBBE-4800-4EA4-8CEE-90E92285896F,FprGoodixDriver +CFE5D9E8-8AFE-4516-8CC3-96405CFAD0C8,PdrRecoveryPei +CFE5EC91-31ED-47E9-BE7D-9CCB59134B71,SiSaPreMemPolicyPpiGuid +CFEE9115-F19F-453E-A0E8-97DECD36828C,H19DisplayMsgInBlackScreen +CFEF94C4-4167-466A-8893-8779459DFA86,LenovoPlatformHiiAdvancedDxe +CFFA207A-B1FD-4265-B0A1-9ACD477545C4,AcerGnvsDxe +CFFB32F4-C2A8-48BB-A0EB-6C3CCA3FE847,ApfsJumpStart +D00752EA-A49C-40AD-A6DA-921C030C4B2F,DxeIchInitDxe +D024BCD2-59EA-48AC-A17F-B3221EC23A11,Int15GetMisc +D038747C-D00C-4980-B319-490199A47D55,FspReservedMemoryResourceHobTsegGuid +D03D30F7-0538-44DE-9568-B722BC7627C9,H19UpdateACPITables +D03F3A1D-088E-46C8-A9FB-8209770F2CE2,ChipsetPlatformLibServicesDxe +D04159DC-E15F-11E3-B261-B8E8562CBAFA,EfiBootManagerPolicyNetworkGuid +D041CFC0-7670-435A-A512-F45C923B285D,DellPeiSioEmi +D049547C-8227-44D2-8A5E-02888DE930D1,ClearPasswordReq +D05173F7-7683-4C35-843A-39B307142E95,OemFwUpdateGuid +D05ACBA9-3E18-4C80-AA97-023A22F8A946,FjAudioSpeaker +D0632C90-AFD7-4492-B186-257C63143C61,SmmBase +D06D425B-EED7-0361-AAD2-8C431409572D,BootGuardRecoveryHookPei +D0738DBA-B21F-45A4-B5AF-22CC4E72ED84,FjGabiSystemDataAccessApiSmm +D07AECE7-573D-4C47-B60C-9D9A721717D7,PeiSioHwmIo +D080F93D-C0E8-47D6-9201-6B0EF6E28E1A,RfTrustedModules +D083E94C-6560-42E4-B6D4-2DF75ADF6A2A,EfiDataHubStatusCodeRecordGuid +D0849ED1-A88C-4BA6-B1D6-AB50E280B7A9,UsbCredentialProviderGuid +D088A413-0A70-4217-BA55-9A3CB65C41B3,ExitPmAuthProtocolGuid +D0893F05-B06D-4161-B947-9BE9B85AC3A1,SnpNt32Dxe +D0927E0C-FEA5-4569-8AC0-33C8F60E5073,NvmeRstPassword +D096FB72-A964-4FE6-9FBF-FA83CCD91549,FchSmbusDxe +D0A611D5-529D-45FF-8714-374E833337D8,Npce285xFlashDxe +D0BA757A-6B67-4BA3-B138-7A15DD8CB94F,FjGabiSystemDataHandlerSmm +D0CAA91E-2DE4-4B0D-B3DC-09C67E854E34,BiosSnp16 +D0CAF5CA-3DF0-3D4F-89C5-66105356D61B,AppleBds +D0D028A3-8B17-490D-9D86-C3D00F0D7695,PrivateWmi +D0D12D8F-803C-4084-8CA8-3658D934F5F2,Ax88179UefiDriver +D0F71512-9E32-4CC9-A5A3-AD679A0667B8,FlashProtectionConfigGuid +D0FE7349-5FFB-424C-93D6-AAE9CFE4D909,SmuV12PeiCZN +D0FF5E04-1D07-491D-970E-E220A3B79611,AmdNbioGfxRVPei +D10F6F20-1EDA-4D9E-9D9B-0F1306C7A713,HpFileAccess +D1112EBF-0D82-4071-967C-E169232740BA,CpPlatIpmiTokenSpace +D1150ED7-E582-4192-84A2-71B4EBA9A7C6,AcpiPlatformDxe +D11C8E2A-3CD1-443C-AC09-63526DE7E170,SmmSupervisorBinRelease +D122882C-DA73-438B-A6B3-E07B7D18DB6F,FastBootSmi +D124DFA7-D784-C64E-8106-29411A7F59DB,MnpDxe +D1263703-D6C0-4354-A7BE-9B635EC99C4A,TpmToollessFwUpd +D13A4091-7C6D-4D0E-BDE8-5DE6F7135F35,BcmCvAPISmall +D1405D16-7AFC-4695-BB12-41459D3695A2,EfiNetworkStackSetupGuid +D14EA3F9-8BD2-49A3-A636-C6F6C08037D5,AmdPspDxeV2Ssp +D15170BE-D512-4894-B863-9D0E6FF5C561,DellSlpMarkerCtrl +D1531968-E138-4E2E-8F7E-383307169276,EzFlashInterfaceAsusSignBin +D1533719-20B1-404D-B970-CE13148DC0CD,PxeDriverRtkLan +D1578747-1A2C-4972-8D56-3C8B93ED25A5,StaticSkuDataDxeXPV +D177EC7B-5353-4E18-A044-6360AC6D467D,AmdPlatformCustomizeSmm +D178F11D-8716-418E-A131-967D2AC42843,EdkiiMicrocodePatchHob +D17F5B0B-ABEC-4C0B-9E4C-80ABFAAD0379,PTDxeInit +D1892F90-3784-410F-984B-9BEC59D8D494,AmdNbioPciePei +D18C0912-6825-4E8F-8D5A-AF7EEDB2E5BC,LpssConfigGuid +D19A26A3-17F1-48C3-8A1E-11EB0A7F6E4E,EfiPchRcVariable +D1A26C1F-ABF5-4806-BB24-68D317E071D5,AppleEpidCertificate +D1A3216F-63E5-4F31-8D30-FF53F7CABF5C,MpCpuDxe +D1A86E3F-0707-4C35-83CD-DC2C29C891A3,EdkiiNvVarStoreFormatted +D1AF503B-68B9-4FC9-AE87-DFB72F21B3F1,DellFmpMe +D1B61D55-88E1-4C14-8904-9E7CEA40AD6F,Cf9Reset +D1B7872C-E60D-4D86-932A-E9F8D46D344A,AMIProjectDXE +D1C17AA1-CAC5-400F-BE17-E2A2AE06677C,EfiKmsFormatMd4128Guid +D1C4AAF9-AAB1-4AEE-ACAC-D68AEF05F0D5,UsraLibNull +D1D63B06-137F-4F5A-8C25-28DADFA1E988,FjPasswordSkipDmi +D1E59F50-E8C3-4545-BF61-11F002233C97,TxtPeiAp +D1EE4CC5-7310-45AE-854E-4450E10EA20A,OemDisaplayTIO +D1FC3703-6591-4AE9-A795-C5628CCF5236,DellSmmNbProtocol +D201B7F4-515F-46A8-951D-9F2BE251C113,CPUDefault-PEI +D20C96A8-B9CF-4C15-9FBB-1C055517F449,CxlCedt +D20D8922-A2F8-4F80-FFFF-FFFFDC893C8D,XnotePlatformResetSmm +D21D96B4-20C6-4F30-8E82-6701485B1049,DellLomPolicy +D22C15F5-818B-4940-90EB-ABB377255643,SmbiosMisc +D22C15F5-818B-4940-90EB-ABB377255644,SmbiosPlatformInfo +D22E0A82-C256-472B-9820-F7BA7127FBE7,OtaDxeDriver +D231DB5B-4A9C-4092-A8C5-9CA0BC7D6AA6,IffsInfoProtocol +D233D6BD-F1B1-425A-BF45-5CAF2B88EDDC,WinNtOemHookStatusCodeHandlerPei +D238B630-280F-11E4-9A1E-047D7B99E097,EventInterfaceCoreDxe +D2465DFB-9AC7-4954-8C48-CC439ADA7C3C,FjIbvWakeStatusAbstractionPei +D256C663-1E0F-4704-A76A-94CEED7C16DE,FjDtPlatformSmbiosDxe +D258D6AF-2FC0-4019-9C1F-1101C3DD19B5,DxeCoreEntryPoint +D25F555A-30EF-49EE-8FB5-C76B5817CC2A,AppleBootUI +D26374A5-7716-4708-AD9F-9C4F2C02547E,IchS3Save +D26697EE-9983-48B0-8F85-7D3E66528B07,LegacyBiosDxe +D26C221E-2430-4C8A-9170-3FCB4500413F,TcgEvent2EntryHobGuid +D27FED59-ABB4-4FED-BEAD-2A878C7E4A7E,SmbiosMeasurementDxe +D2846ADB-B41B-4103-871F-E2235F4778C7,SmcPostMsgHotKey_PEI +D290465F-16B5-4579-A70B-CA1DF4FCE8DF,SDGlobalNVS +D299F352-094F-4B87-8CD2-C94F9E0A44C3,DellRecoveryPei +D29B104A-BE98-464A-9771-746B9A07DCA1,FjSysmanWatchdogBin +D2A92001-22AD-43B9-BEBC-1B152100D8CC,EfiPeiPlatformTypeWolfPassPpi +D2ABC888-AE13-4E3B-BCEE-5DE368FA4E72,MsegSmramPeim +D2B04F7C-699B-4F9A-91F3-04078B9563CB,BootOrderData +D2B2B828-0826-48A7-B3DF-983C006024F0,EfiStatusCodeRuntimeProtocolGuid +D2B6C80A-FAFE-4512-835D-50D136540AAA,MultiConfigUpdateDxe +D2BC3092-92BB-4B21-A26B-CE6F7C3E9857,AtAmUi +D2C18636-40E5-4EB5-A31B-36695FD42C87,EfiShellEnvironment2ExtGuid +D2C2B842-46B0-4466-88B8-5A8285E9CEC2,IScsiFontSupport +D2C2C0A3-1623-4BF2-9ADA-BCF81493FF7C,AX88179UsbNetDriver +D2C69B26-82E1-4A1B-AD35-ED0261B9F347,MemoryInitPei +D2CB970C-8622-46E1-9083-DB2EA20CA6E3,SystemSecureFlashBootModePei +D2DC7458-E6C1-4C8E-A32B-545269DC6361,OemPeiSetAcLossAuto +D2F785ED-95F3-4075-897D-9D9CF9C5A79D,AtaAtapiPpi +D2F8BE2B-9898-414D-A76A-20A5C8DE77E0,TouchPad_Elan +D2FF92C7-55DB-4879-9D0B-A08BCE4F4E19,StaticSkuDataDxeBlizzard +D303BB6F-7434-41FD-BC8E-0984A03C9B7D,AmdCpmAcpPowerGatingDxe +D30E0E10-519B-4E39-AD47-DC3CE266A8AE,FjGabiNvramMergeDxe +D317F29B-A325-4712-9BF1-C61954DC198C,EfiSmartCardEdgeProtocolGuid +D31D5D8B-61F3-4FC5-9CBB-7AEB6D987932,TouchDriver +D31EAA20-8436-4E34-9A06-C47C78E19F18,SIOBasicIODxe +D31F0400-7D16-4316-BF88-6065883B402B,EfiPchInfoProtocolGuid +D3231048-B7D7-46FC-80F8-2F7B229586C5,UTDMUIApp +D3269FDE-ED75-4891-BE1C-0162EF1FA5A3,FjSystemDataDriverDxe +D326D041-BD31-4C01-B5A8-628BE87F0653,EfiSmmFirmwareVolumeBlockProtocolGuid +D326F501-4D17-6E44-C840-208426F90CEC,Pca9535aPei +D32CAE03-FFFE-4F67-BBF9-7CB851C4580E,SmcFeatureSupportFlags +D3300D09-B70F-4315-9785-FE37209EFDCB,HddSecurityBdsCall +D330B893-C7FA-4BCD-B0BE-64DFE98415C2,FjRiserPowerDelivery +D33AC55B-82A6-448D-8D14-DFE0814D0792,DellSetupRollbackDxeDriver +D34BDC5E-968A-40F5-A48C-E594F45AE211,VariableAuthSmm +D34D3234-38BA-428B-9ACD-84E830A80785,AmiModulePkgTokenSpaceGuid +D34E68E9-B9BF-4924-8A06-0EA2672204DD,PciHostBridge +D358D713-7E11-43F1-9456-F5FF2EBE19A8,SbSocBrhDxe +D359DE86-0A1B-47BC-95D2-1D1F8FFF0AD8,ChipsetSvcSmm +D35EDA81-07D0-4142-9409-B07233ED2D07,CseSpiSelectPpiGuid +D362743E-CD68-4500-AA93-C596383AE31B,FjPasswordCtrlPei +D3667456-63A0-4713-B7DB-4162C196A37E,DxePostEnd +D36DDD2D-1C66-4210-B77A-2FD9F920E51F,AsusEupSmi +D3705011-BC19-4AF7-BE16-F68030378C15,EfiIntelFrameworkModulePkgTokenSpaceGuid +D3709BB4-B194-4B71-B9C0-DBD8D2DA97AD,IntelIchLegacyInterruptDxe +D3721461-FC24-443E-B486-724C9B5A2F70,MemTestDxe +D3790CB3-A890-4A5A-A42E-ECB6B140D814,UHESerial +D38D1F35-890B-43CA-BF9B-96337B86B06B,TypeADh +D38FC876-0B17-4D95-A7F8-A022ECA1CA42,MeExtMeasurement +D397728F-4C9B-9C18-9816-F9B869B00085,SataPortConfigSmm +D3987D4B-971A-435F-8CAF-4967EB627241,SerialDxe +D398E61C-2A9C-4A6D-B265-47696CF9E442,ASUSFS2 +D39A4E04-C42D-4941-BFBD-286DF48B304B,MeLockStatusSmm +D3A6CF7C-2A13-4DCD-961F-B88C85ACEB34,AmdCcxZenRvPei +D3AAD8DC-3A48-46AC-B1C7-28A9D3CF6755,WinNtThunkPPIToProtocolPei +D3AAFF0F-CB22-4792-896C-802C2E9383BA,WifiManagerApp +D3AFC39E-BC47-49D3-AFED-604C46752D0A,DellPsidPei +D3B36F2B-D551-11D4-9A46-0090273FC14D,EfiConsoleInDeviceGuid +D3B36F2C-D551-11D4-9A46-0090273FC14D,EfiConsoleOutDeviceGuid +D3B36F2D-D551-11D4-9A46-0090273FC14D,EfiStandardErrorDeviceGuid +D3B46F3B-D441-1244-9A12-0012273FC14D,EfiXenInfoGuid +D3B7F871-3F04-48D4-B9C1-5871825D00AA,GnbMatisseRouting +D3BF10C7-0D1F-4F1E-8A9C-1394024DB43A,AmdCcxVhMdnDxe +D3BFE2DE-3DAF-11DF-BA40-E3A556D89593,IffsGpt +D3C92EF3-39AA-4ECE-A1E6-DFD7A2D497D4,ODMShareMemProtocol +D3DD0586-976D-449F-9837-0392E93B7D52,DellOsProtocolAccess +D3E6E0F0-7206-40C5-B58A-05FCAD08DBC8,OemDxe +D3E8A227-E905-407E-8F8F-FED32FB2F93B,DellUsbSmmCore +D3EB600F-06EF-4837-A2A8-7C4C90BE8DA5,BctBaseSmmSTXH +D3ECC567-9FD5-44C1-86CF-5DA7A24F4B5D,EfiLpcWpc83627PolicyProtocolGuid +D3F67D2D-67CA-4FB6-9654-77E82901469C,VirtualDev +D400D1E4-A314-442B-89ED-A92E4C8197CB,EfiQuarkCapsuleGuid +D4013B06-AB7D-4B9C-89D5-6EF61F507ECA,AsrockAmdSetupDxeRN +D40B6B80-97D5-4282-BB1D-223A16918058,EfiNvdimmLabelProtocolGuid +D423E494-2DB6-4D2E-AE23-0A3D8D9D6E22,FjEPrivacyFilterSmm +D42AE6BD-1352-4BFB-909A-CA72A6EAE889,LzmaF86CustomDecompressGuid +D42DB8C5-1E95-4A2F-9742-479C1BA42192,OemDataRegionFlashDxe +D42F8F9A-9B96-4F47-B045-A8F3CD1FD9D3,SecureVariable +D432A67F-14DC-484B-B3BB-3F0291849327,EfiDiskInfoProtocolGuid +D432C4A5-D473-4067-9CF7-02CE92A3CBFD,FchProm21Dxe +D434ED39-8EDD-4FF8-91BF-4B11AFE85471,SwapAddressRangeDxe +D4395796-6F4C-4C6B-B9D1-92DAA7199A84,AmiRedFishApi +D43E3F66-1B5D-4623-975F-7F5EBEEEF02D,MtkWifiDriver +D446DA7F-F299-4911-8C91-91CCF5F8A752,SDBadgingSupport +D450A69D-D8E4-C048-8E7E-0024EB541C79,NetworkInterfacePolicyDriver +D458A654-F64C-49DB-B8D1-3821306BF1F6,BaseMemoryLibMmx +D45DAC0C-4FE8-4304-FFFF-FFFF1745BE1A,XnotePopNoiseSmm +D462AE45-FF5A-4448-A474-B986E2A0D5B1,G3WakeupDxe +D463AB1A-F04A-4EF0-AAA2-CC3D03B25AF0,DxeSioHwmIo +D4695647-7D01-4D96-AC7E-BB90EEE29EB9,H2OCryptoServicesPostMemPei +D472AB34-8E21-4343-8BFF-01ECDE292375,DellThrottlingDriver +D4787B71-A878-49C9-97CE-967DF2399AAA,SmramRomHoleK0Protocol +D47C6285-335E-4F14-9CB9-DAB565B7B44B,SmbusDebugSmm +D485A971-B6DC-4E1C-8730-C4455460A6FF,ResetDateTimePei +D487DDB4-008B-11D9-AFDC-001083FFCA4D,EfiSasDevicePathGuid +D4926BEA-00A3-40E5-A2B9-C317960F31BF,AmiPspFtpmPei +D49D2EB0-44D5-4621-9FD6-1A92C9109B99,HiiResourcesSample +D4A28A3E-DCF2-43CF-A2B7-F3572A7CAB09,EfiIobaseHob +D4A5B2FD-AD44-404A-98A8-297857E72A53,SmcOobDataReadyProtocol +D4A79A0D-B67D-4E83-8EFB-455924372934,DellTerminalPlatformPolicy +D4A86A1B-F939-4D4D-BF7F-CE404572B282,BootOrderAdjustDxe +D4A88838-EBF4-48D7-9D97-CE6789FDE0B7,CryptoPkgTest +D4B47610-BC1C-480B-BD23-CB031B7AA0A2,BiosPowerOn +D4B61940-73AB-48A5-9E26-53A4CA4A2C37,DellDiagsSmm +D4B64FCA-7C4C-48C1-976F-5287423753E4,LenovoVariableDxeProtocol +D4BECF5B-190D-46DB-92CC-3F5D74904DDA,SmmAccessDxe +D4C189D5-002A-4E6B-96C1-9C9E877D230B,SmbiosType141 +D4CA32B1-B1F2-4FF3-B475-66E7B8192A3B,AmiCpuidCksumHob +D4CA32B3-B1FE-4FF7-B073-60EDBB162233,AmiDimmSpdDataHob +D4D7C050-C273-44A0-8456-ABA6399EAF4D,LenovoResetSystemToFactoryDefaultsDxe +D4DCD37C-90A3-406E-B193-323C6AAC2428,ASUSBackup +D4E79DAE-AAFC-4382-9540-3E3FA42D4255,AmiNvmeLegacyProtocolGuid +D4E91137-43F4-4E56-B989-D3D0E7B16955,InstallHookDxe +D4EE25EA-0B48-43AE-A016-4D6E8B6C43B3,MemoryInit +D4F29055-E1FB-11D4-BD0D-0080C73C8881,EfiWinNtCpuSpeed +D4F90895-A60B-4E97-B446-2855246F8930,AmdNbioBaseRVDxe +D4F9FE6D-1696-462A-AC07-C009D1A0189A,IdeConfigSetup +D4FF05AA-3C7D-4B8A-A1EE-AA5EFA0B1742,TrustedDeviceSetup +D50234F4-6F4B-43E8-A013-3C1E33D9B9B1,EfiMemoryTypeFru +D5057FEA-A6A4-4BB0-A3A1-7E018A8105FA,FjTimestampSmm +D5063BF1-7AE6-46A9-B8D9-8E9F66E5DC06,PlatformSpiFvbSmm +D5116E4B-DAD6-4122-A096-08D339B7FA40,ProcessErrorCode +D5125E0F-1226-444F-A218-0085996ED5DA,Smbus +D5196882-A970-4510-8FB9-D7583B6906E7,LenovoVariableSmm +D521F60C-7D65-4FF2-99C6-12A296040C57,DellCommonBoardInitDxe +D5231481-174E-436F-8DF7-9A6D8A27232A,NbSspRouting +D52B0965-681A-4DC6-92C6-B20A30208598,AAFTblPEI +D52BB262-F022-49EC-86D2-7A293A7A054B,PchAcpiSmiDispatchProtocol +D52D8AD2-EA9A-470C-9E33-828FA591AB8D,AmiPeiHashInterfaceProtocolGuid +D530CEA0-DD63-11DE-8A39-0800200C9A66,MemSpd +D5367802-B873-4C0F-B544-31B7CCF5C555,CmosManagerHob +D53E4F4C-125B-4441-A3CB-72EE159533AE,AmtPetAlertDxe +D53E9F23-CF7F-4270-ADC4-05E2920471EF,AmdSmmControl +D54A91F0-4547-4380-8890-17C19937F853,DellSecureBootSmm +D54D3DBE-CE19-489F-8EDE-9FE2F7238650,RestDxe +D55319D5-6EDC-43E2-985B-F656E5B5153C,AmdFabricPhxDxe +D558DCB7-7A3E-4A38-8C46-F6CF21DFC1E6,BtPreBootDxe +D5649ACA-DA40-4C58-A4DF-8E42EB40A180,SaPolicyProtocolGuid +D56A4094-570F-4D3D-8F5F-8D8AA0B396CB,EhciPei +D56B6D73-1A7B-4015-9BB4-7B071729ED24,EdkiiSmmPerformanceMeasurementProtocol +D5710339-A467-4F76-B053-4F14C2F5C999,FjDtPlatformDiagnosticsDxe +D579766D-54C0-4A51-AA39-411E59981DF2,UsbOcUpdateDxeBlizzard +D57BC5C5-F058-4AA8-8585-B7645E1A7D25,DpfServicesSmm +D57C852E-809F-45CF-A377-D77BC0CB78EE,HddSmart +D57E86D8-A921-4083-B3DD-5AFFA92B4FE5,Pca9536Pei +D58EBCE1-AF26-488D-BE66-C164417F8C13,PciHostBridge +D5919FF6-D708-4918-87A0-1BB21B157C08,CaseOpenDxe +D5950985-8BE3-4B1C-B63F-95D15AB3B65F,SmmCpuSyncProtocol +D598FC5D-AC01-4D9A-95B5-A1D2422504A5,TouchDriver +D5A531AB-300B-4AA1-9B8A-9C6C8F0110F4,CrServiceSmm +D5B01A04-24D8-44B9-A390-888D669A1CBF,HpAmdXhciSmm +D5B06D16-2EA1-4DEF-98D0-A05D40728417,EfiWatchdogTimerDriverProtocolGuid +D5B366C7-DB85-455F-B50B-900A694E4C8C,SlingShot +D5C39D65-28B2-400A-9FBE-77E28BDD3CD5,AmdDebugDataPreserve +D5D52FED-F8A6-49AC-97AC-7291A60405A6,FsIso9660 +D5D946C7-92AB-41FB-A390-6C6239B4E413,BoardInitAdvancedPreMem +D5E4EE5F-3E0A-453C-A725-B692BB06365A,EfiExtendedSalElogServicesProtocol +D5E606EB-83DF-4E90-81E8-C3DB2F77179A,rmHwA15x2A7x3Guid +D5FC5B41-F893-48A5-96EF-375C1874D45F,WlanSuplct +D602D4E9-1F13-4E0F-8B6C-2B2FD32977D6,LEMSetFlashProtectedRange +D6047569-C508-498F-AEC1-72E77DADE7AC,AepLogWmiSmm +D6062B50-15CA-11DA-9219-001083FFCA4D,EfiAuthenticationChapRadiusGuid +D608A2C1-4331-4685-9749-F6819BAF4C04,StaticSkuDataDxeSierra +D6099B94-CD97-4CC5-8714-7F6312701A8A,VirtioGpuDxe +D60CF145-F97C-4085-A73D-8D399757DFE9,AmiCpmWrapperDxe +D60CF145-F97C-4085-A73D-8D399757DFEA,AmiCpmWrapperDxe +D610A5C5-2EC8-4FC7-B7BC-5664EBB855D2,XnoteHiddenMenuSetup +D617467B-1FF7-403F-A87D-29F61C80EE7C,AmdCpmOemInitPeim +D61B6C7A-653A-45A9-8AF3-63A8A5076639,DellHddSmart +D61DE96F-6AAA-4B7A-BF5E-DDCA9301DEDD,DellHardwareFailureLogDxe +D6207835-B7E3-4FF8-B276-CDE3E52206BC,SmbiosDataUpdateDxeLightningRidgeEXECB1 +D6294C9B-0866-4753-AAAD-7699AFC4BEE4,DefaultFixedBootOrder +D62C96E9-D7D7-4D28-B0F9-BF2CA151DDEF,IePolicyInitPei +D62E660E-6561-45DB-A838-8609BBA5FF37,Cf9Reset +D62E673F-A935-4751-9279-4C1E63ED0A4E,FchI3cDxe +D635213B-5334-46B3-AE37-8D436DD3D523,OemNvme +D639D97F-5FCB-42CB-87C2-880A86F67CF2,CbsBasePeiBRH +D6405DAC-92D7-4BB2-A9C9-CB7C749023F5,BIOSLD +D641A0F5-CB7C-4846-A380-1D01B4D9E3B9,EfiPeiCorePrivate +D6476950-2481-4CBB-8400-442542C766C8,ProcessorErrorHandler +D6494E1B-E06F-4AB5-B64D-48B25AA9EB33,SmmCpuPlatformHookLibNull +D65AEFE3-43B8-42CC-FFFF-FFFF07457063,RealtekCardReaderDxe +D65D9F72-7BCE-4F73-A673-47AF446A1A31,SmmRuntimeDxeReportStatusCodeLibFramework +D684FB08-8B0E-4CAF-8CFF-1EA386279809,HybridGraphicsSmm +D687E479-DB37-4BCE-864A-02EEF6819DF1,SystemFormBrowserSimpleTextViewDxe +D689F8C7-C354-4215-AA48-B6AD66C77EAF,LenovoN25Q032FlashPartSmm +D69240C0-DD40-4F2D-9863-4848DA6E615F,AmiTseInvalidPasswordGuid +D69A279B-58EB-45D1-A148-771BB9EB5251,EpcOsDataGuid +D6A1CD70-4B33-4994-A6EA-375F2CCC5437,EfiWheaElogFv +D6A2CB7F-6A18-4E2F-B43B-9920A733700A,DxeCore +D6A530AD-14F3-45DD-A097-FB2A7C92B726,FjSystemResetDxe +D6A9928C-3397-4DD1-818F-C664BA6DCAAF,DevUtility +D6A9A1B9-4BFD-D61E-F037-3FA4CA06E046,Lua +D6AC4AC2-8BC2-4CDD-8776-280E1469DE02,PchPolicyInitDxe +D6B51356-0C90-4EE6-B3A7-48AA74D4A77A,SkipRegionAccessDxe +D6B6547A-750E-4A3D-B61B-8703D8FA3287,DellAuxMac +D6B6DA34-917B-4511-B147-407653BF391A,FjEvtControlDxe +D6C1D55A-DB24-45CE-AE52-1E5087BE222E,AmdResetHook +D6C42CE2-391C-4345-8BFE-195632AC4558,CertificateStorageEvent +D6C589EA-DD29-49EF-97F6-1A9FE19A04E0,PwdCredentialProvider +D6C92E00-1FAB-4775-8310-3AC1D774C3CD,GenesysInit +D6C97E78-FCD7-47F5-B575-6E1940246C7C,DellCountryCodeDxeSync +D6CC7A4D-440F-4FFC-879E-176CB5558118,FchSmmDispatcher +D6D27C49-66CA-42C7-BC51-788328B5E5D0,SwSmi534D0240 +D6D2FBA6-EF60-4C38-A83E-6769814D23B0,CryptoPei +D6D47F07-1445-416C-BC8C-89C34D7CB210,HpFirstBootOptimizerDxe +D6DAB28B-E52A-4C76-B9D1-982B112C9130,EcDashControllerSmm +D6DF0817-248A-41F1-A1D3-59E537187D10,DellTcg2Smm +D6E322B7-77ED-4394-86FD-FCED3C052780,LEMRomLayoutSmm +D6E5092D-C7B2-4872-AF66-FDC0E6F95E78,EfiSystemNvDataHob +D6EB696B-7EC3-4D1B-AA28-6775744C9EB5,TSEScreenMgmtProtocolGuid +D6F37045-3DA2-4AA0-9777-1DF7D9FC61C9,iMRRaid +D6F43B1B-0F21-462B-B8B7-A033C3EB4261,BaseMemoryLibOptPei +D6F76587-98CA-43DE-9E1A-59E60D0ABE73,AplFakeCapsulePei +D700E3BC-4291-4749-87AF-432A023DE658,DellNbConfigDxe +D71863E8-A7B9-4B29-BEDA-4CDAE44E056E,DellPowerManagement +D719B2CB-3D3A-4596-A3BC-DAD00E67656F,EfiImageSecurityDatabaseGuid +D71C8BA4-4AF2-4D0D-B1BA-F2409F0C20D3,UncoreInitPeim +D71C9263-2E64-40F9-82B8-F25B27069D4F,EnePEI +D71DB106-E32D-4225-BFF4-DE6D77871761,PowerMgmtInitDoneProtocolGuid +D739F969-FB2D-4BC2-AFE7-081327D3FEDE,ActiveManagement +D74B7D80-4B7F-4A73-8A55-4B59D7DE747A,AmdResetManager +D74CC5E6-B169-456E-91D2-BE2C2D1343A6,SpiFlashLibNull +D750E6CB-811C-4436-A361-8BB7BF53B1CE,HpSystemInformationAspect +D753C57C-87D0-4636-876A-5EE0E73A6689,PlatformMilestoneHookDxe +D753C57C-87D0-4636-876A-5EE0E73A668A,BoardMilestoneHookDxe +D759C710-49EA-4D26-9F7C-DE1064876E2F,FpgaSocketHob +D75E1AFA-0A28-41B1-9DA6-765976742542,DellDiagAbstraction +D7642443-87B7-4832-9607-0E1EA81C1D86,AmiRomLayoutHob +D76E0A85-4908-4732-BE0F-BE707EF7CB37,SmbiosTpmDeviceInfo +D77A3FE1-51FE-4613-A81D-82AE24464CFD,AmiTseOemPortingVar6 +D77C900D-A1C7-41C5-B989-0C3D37FCA432,AmtWrapperDxe +D780600B-697E-43B7-9D6E-30F742891A72,OemACPIDriverSmm +D7908EC2-227A-472F-8095-6A159DD723D2,AmdNbioPcieRVDxe +D79DF6B0-EF44-43BD-9797-43E93BCF5FA8,VlanConfigFormSetGuid +D7A50E8B-FD3A-443A-81A9-C951DAC8B3FF,LenovoLoggingDxe +D7AC94AF-A498-45EC-BFA2-A56E9534618B,AmtForcePushPetVariable +D7AD636E-B997-459B-BF3F-8846897980E1,EfiHiiProtocolGuid +D7B10D4E-67E6-4C74-83E9-F9AF0ACC33CC,PchInitSmm +D7B6EBD9-6322-41C3-8F34-47974814488A,TPMNationZ +D7BD52B0-B2DC-4F08-B467-DE50D728F6BD,EfiNbMrcInfo +D7C74207-A831-4A26-B1F5-D193065CE8B6,EfiAdapterInfoMediaStateGuid +D7CA1F9B-E478-4257-9D8E-2FE2DEE978BE,OemAcpiModePei +D7D7CA47-663B-488D-AEE3-6A35DCB89E2A,SbGlobalSmiControl +D7DCC862-A2A0-4CDA-B18E-4477D2FE49E3,RadioExecSmm +D7E31ECB-0A17-4529-9B84-C529DE8E1C0E,AcpiFvi +D7E3630F-55CA-43DF-8035-F4FB0774D0D9,TmFifoDxe +D7E3D34E-1FF0-4E7A-8877-1FAAF9EB9654,CbsBaseDxeBRH +D7E5ABE9-33AB-418E-9F91-72DAE2BA8E2F,ArmScmiBaseProtocol +D7E69789-1F68-45E8-96EF-3B6407A5B2DC,EfiKmsFormatAescbc256Guid +D7E6ABC1-971B-461B-B5E4-3C3766267AD9,SbInterfaceDxe +D7EBF6B1-CB2C-4EF6-8ED5-FB673C91DBE4,IntegratedDeviceDxe +D8097F30-C9AB-4D76-8D87-890CA413657A,ElkhartLakeDxe +D8117CFC-94A6-11D4-9A3A-0090273FC14D,EfiPeiFlushInstructionCache +D8117CFE-94A6-11D4-9A3A-0090273FC14D,EfiDecompressProtocolGuid +D8117CFF-94A6-11D4-9A3A-0090273FC14D,EfiPeiPeCoffLoaderGuid +D8117D02-94A6-11D4-9A3A-0090273FC14D,EfiPeiTransferControl +D815413A-D96D-40A6-9F9F-88E09E36FA49,PsdsAcpiDxe +D81AF109-4741-4EDD-B4C4-58CFF321D7AD,FjBiosPostGpioPei +D81D1706-BE6F-4734-B2AF-F885FFDCB16D,AsixUsbEthernetDxe +D824AD37-7AB9-4817-BD53-DBAB779A3C83,DellAdvSysMgmtConfigSmm +D82A73A8-7CB5-4BC1-8FA5-60F0EE2470A7,BiosUpdatePlatformPolicySmm +D82D57AC-99F9-4C7A-B591-BBCF8A0E7FBE,PchSmbusArpDisabled +D8320405-3CED-406C-B93C-433A58C6D1FA,SecureBIOCameraSonix +D8367B27-7A08-4AC5-AD1F-C93C3E94225E,AodSmmRv +D83977DF-34C3-4A21-A104-369B8D4FA7B7,LenovoMfgBenchEventDxe +D84BEFF0-159A-4B60-9AB9-AC5C474BD3B1,AmiTseNVRAMUpdateGuid +D85A4835-5A82-4894-AC02-706F43D5978E,EdkiiConfigurationManagerProtocol +D85A4A0C-2E73-4491-92E1-DCEFC3882A68,DellPhysicalPresence +D8654609-F6F3-44E9-B8ED-20A9829818C8,DellIoExpanderSmm +D872AEFA-7C5F-4C66-8836-AA57EFF0D9F8,IconGenericExternalHardDrive +D87DFF41-21E5-44A6-978B-80786AB97229,DellPermanentDevicePolicySmm +D8803829-0373-4475-9767-461EDEA28813,CsmInt10HookSmm +D890F055-873A-4E6E-A79F-1B8DD2427FE4,AmdNbioBaseRnDxe +D893CDBA-7F65-47F5-A67A-228252F03633,DellFmpEc +D8944553-C4DD-41F4-9B30-E1397CFB267B,EfiNicIp4ConfigVariableGuid +D89A7D8B-D016-4D26-93E3-EAB6B4D3B0A2,Enter_Setup +D8A6F4A6-0E97-4A8B-A475-39F1B28B5AEC,Fv2OnFvThunk +D8AAB432-93CC-48D2-9F34-3496CAF92185,SmartFanCtrlDXE +D8AB1072-4B45-4828-837D-A4214377802E,BCLANDXE +D8B6B249-77F8-4809-ACE2-5975DA16AAF5,TouchPadDriver +D8CAC470-CB7B-11E3-856B-047D7B99E097,BootOptionInterfaceCoreDxe +D8D282C4-4478-4D75-B10B-B08F5E59B5E8,BasicDiagnostics +D8E32E50-1DD2-4F8A-93A5-2569C03D0FC1,FchSmbusPei +D8E4C555-0BB6-4C6D-94CD-36072D59DCD2,PrmConfigDxe +D8F15168-57A0-46D5-9071-2F3C23CB236D,RpmcPei +D8F8C7F6-52BB-4CB3-BA5B-0683628A2CEC,DellDesktopPowerLEDSmm +D8FA1C9B-049E-4292-A517-450A8D2242EF,FjGabiFlashCommonFdRegionCtrlDxe +D9035175-8CE2-47DE-A8B8-CC98E5E2A885,EfiPlatformInfoProtocol +D903BF23-E1DE-4DF0-8B96-73B6F2C2B797,DevFwUpd +D9072C35-EB8F-43AD-A220-34D40E2A8285,EfiSmmSpiProtocolGuid +D9117BD7-0807-4F38-B773-AD86A791EAFC,SiInitPreMemFsp +D912C7BC-F098-4367-92BA-E911083C7B0E,Udp6Dxe +D919136E-865C-4B10-B099-5D897CFEDE08,AmdCpmInitPeim +D92E9C5B-BB6C-46EE-B8E7-6B0B3D4B2BBC,AsusBiosRecoveryDxe +D933DEDE-0260-4E76-A7D9-2F9F2440E5A5,NbSmi +D9389EFA-2C9A-4696-8BB6-FC5F398D8DF3,SmmGpioControl +D93C3649-69A5-43C7-8CD3-49D41772453A,FchPromontoryPlusGpioPei +D93CE3D8-A7EB-4730-8C8E-CC466A9ECC3C,ReportStatusCodeRouterRuntimeDxe +D93D907E-EE7D-4577-833C-5AD3ADBBB8C4,DeepS3ConfigDxe +D93DE2E3-3727-4D5B-B49F-777C93A971D3,OpromUpdateDxeLightningRidgeEXECB3 +D94082B7-04E0-4586-8072-8FC562ABBBFA,IncompatiblePciDeviceSupport +D94816D9-D2EC-4BC9-963D-09D263F715C1,HousingMonitoringPei +D952A0C4-4D96-6853-DECD-058DC9DC5FCF,AmdSocAm4MtsPei +D9569195-ED94-47D2-9523-38BF2D201371,IntelPciDeviceSecurityDxe +D959E387-7B91-452C-90E0-A1DBAC90DDB8,ArmPlatformPrePiUniCore +D95D6B4F-92FA-4E78-9C48-C68C0813688E,OemLinkDellPwdLib +D965579C-7DF4-458D-A803-94D0808BC422,NCT7802YDxeInit +D9686596-5BC4-4861-82B3-176260CB1965,AMDNavi +D96A2393-8790-4BAA-9CEB-42533F016EE9,RegAccessSMM +D97435DE-E080-45FC-96BE-4A06A5C82F7F,AsusVgaDxeBs +D97435DE-E680-41FC-93BE-4A76A5C82F7F,SerialDebugInitPei +D9760FF3-3CCA-4267-80F9-7527FAFA4223,EfiMtftp6ServiceBindingProtocolGuid +D97BEDBA-E766-40F2-AC17-5FAF44A7BBF3,WiGigSmm +D985F810-69ED-4E58-FFFF-FFFF4ED8D2DC,XnoteSystemPolicyPei +D988358A-157F-43B7-9A7A-2757D663DCEB,DellStorageAgentConfigPolicy +D98E3EA3-6F39-4BE4-82CE-5A890CCB2C95,EfiStatusCodeArchProtocol +D993E866-5C8F-4DE7-BE99-453E284A43AF,WakeOnLanDxe +D995C16A-DF06-4B26-9C5B-246FC7464649,SystemAcpiSlp2Dxe +D995E954-BBC1-430F-AD91-B44DCB3C6F35,EfiPcieErrorSectionGuid +D99B0C82-9BB0-4B8D-9545-A2670375A931,AfuCapsuleOnDiskSmm +D99D0269-592D-4618-A36C-FA8007331CBC,DeviceInfoLookupDxe +D99FC054-CC38-4582-B0A6-F533678BAFA9,DellPeiPchGpioControl +D9A688C2-F1EC-4884-8262-2C6381AF254B,CsmSmiDispatcher +D9AE5A34-2096-4DED-BF11-4738B0A39FA8,DellAmdCbsApcbUpdateSmmShp +D9B07611-4ED7-38BF-B304-42116E7C966A,OSRecovery +D9BEE56E-75DC-49D9-B4D7-B534210F637A,EfiCertDbGuid +D9CD0AA0-C20F-4810-999E-D991FD0484D9,DellSmBiosStrucD9 +D9D114EF-F40B-4D48-AAA0-A3DC99C9F5BD,DebugAgentPei +D9D6BA2A-8225-469B-B36E-3B34EBE805CF,StatusCodeHandlerRuntimeDxeUsb +D9DCC5DF-4007-435E-9098-8970935504B2,PlatformDxe +D9DDCFF2-215A-480A-AA63-1DF1F5EDBC01,HddSecurityPei +D9E4F040-B4D0-4C26-8400-B1D91B756B77,IteOnlyPei +D9E9FA06-0FE0-41C3-96FB-83425A3394F8,EfiExtendedSalBaseServicesProtocolGuid +D9EA74E6-0B4D-4916-9821-EB58B86211D8,SbPcdDxe +D9EB5F72-63F5-4CC2-9FCF-BFECE18FF0B6,OemThermalPolicySMM +D9F11A26-249C-46AC-9CB5-E4F77E035C90,NetworkRecoveryNameLabel +D9F1669A-F505-48BD-A892-94B7CA903031,SignalBeforeEnterSetup +D9F5B28C-9FF1-47D6-B503-3DC23BD345FF,PchEarlyInitPeim +DA11541F-5341-4763-8386-3863943973B2,I2cInitializeDxe +DA17EC65-21E4-49AB-B8BA-1F8D026DC148,FjPortReplicatorSmm +DA1B0D11-D1A7-46C4-9DC9-F3714875C6EB,VarCheckPolicyLibMmiHandler +DA1C487A-C375-4D18-BD71-E0FA9F893998,EpsaReconnectUsbDriver +DA2122B3-454C-4321-8F43-8A610AFFEB80,PspResumeServicesSmm +DA36718F-E022-4FD8-BAD8-EF27F9E4928F,HeciInitSmm +DA389016-4D1E-4814-A13B-364F13D8DE3E,ClientronProgramGpioPei +DA3B0E29-2DA7-48A7-AE98-B21093DBBC2B,RecoveryImageReadWrite +DA3EC7A1-F6D3-4129-98B0-9494F8585006,DellLegUsbBusProtocol +DA3F7A4B-52F2-4086-B0B8-FEE95DF7A733,SmbusDxe +DA3F8F9E-8D46-4B66-A009-42C8BCAD8530,FjVgaDxe +DA451AF6-88D1-4FD7-B86E-44BC47EE1F7E,DellStorageAgentsSmm +DA465B87-A26F-4C12-B78A-0361428FA026,AssetQrCode +DA473D7F-4B31-4D63-92B7-3D905EF84B84,AmiSmmBufferValidationProtocol +DA490532-DA5F-43C9-A0CE-6A2E05919350,AfuCapsuleOnDiskDxe +DA4B2D79-FEE1-42C6-9B56-923633398AEB,BiosCapsule +DA5524A0-6030-4A66-A9E4-D26629871921,FjAlderLakeSmm +DA56B22F-8379-4F2F-B328-221C0182C6F5,NearTdpLockOc +DA571595-4D99-487C-827C-2622677D3307,EfiStatusCodeDataTypeAssert +DA5D9983-033C-4823-9349-8B1B6A798030,LenovoSystemStatusCodeGenericSmm +DA64AB9F-EC7F-4BE5-AC79-5352DCD1614D,AmdCpmOemSmm +DA6855BD-07B7-4C05-9ED8-E259FD360E22,EfiPei144FloppyBlockIoPpiGuid +DA78142B-E4A5-4833-B20B-6723007947CB,FjLanI219LmSmm +DA7CAF76-CB17-4D80-AE21-2BD3AE421C76,RuntimeAmiFlashLibCompat +DA7F03CD-037A-4A98-81EB-7E6A99A711B9,DellExtendedBatteryLifeSmm +DA806754-AF95-4E1B-ABC8-FAB569FC2B3F,DellErrorHandlerPei +DA836F8D-217F-4CA0-99C2-1CA4E16077EA,EfiHash2ServiceBindingProtocolGuid +DA8CCDF4-ED8F-4FFC-B5EF-2EF55E24932A,ShellAcpiViewHii +DA8CD7C4-1C00-49E2-803E-5214E701894C,EfiI2cEnumerateProtocolGuid +DA964524-D0E5-4C32-90D0-010021CFB2DC,PMBUSDXE +DA97681C-A9E3-4209-A9D5-F9E98152F39A,ClearChassisIntrusion +DA9F192F-BAE4-4F20-8C6C-55C1ACDE80B0,menu_checked +DAA55048-BC3F-4DD9-999B-F58ABF2BBFCC,DxePlatform +DAAF0056-87B5-4584-854C-CF207B364CEA,SwSmi534D0840 +DABA25A6-DF31-4151-81EF-627701EE4F26,EarlyDevices +DABAFA6C-F394-4DAB-835F-8012FD730766,LEMSetVariableCtl +DABF7A7B-B5FE-4A18-845D-F241D8582794,UndiFirmwareVersionDxe +DAC2B117-B5FB-4964-A312-0DCC77061B9B,Font +DAC3CB98-2295-412E-826D-FDEEA320CF31,AmiRecoveryImageHobGuid +DAC84E15-C3F5-40F1-8184-8DE8DA91FE0E,SbSocMatissePei +DAC84E15-C3F5-40F1-8184-8DE8DA91FE11,SbSocRenoirPei +DACF6769-C3D5-4EFF-A181-FA0988E1D9B4,AmdCpmModernStandbyInitDxe +DACF705C-71DF-497D-AABE-10186B2E1DDE,Recovery +DADE1003-1B31-4FE4-8557-26FCEFC78275,InjectorKext +DADE8301-CB29-4FD5-8148-56FD246C5B88,UefiApplicationEntryPoint +DAE6B815-877D-4597-A637-CFCFCCC431ED,PlatformStatusCodeHandlerDxe +DAEC02CC-92C7-47DD-AE0D-498C204253AE,HPOA3Smm +DAEEAFC8-D2A8-4D9F-B093-3438984E5FDD,AmiDeviceGuardSecBootApiGuid +DAF4BF89-CE71-4917-B522-C89D32FBC59F,SMBiosStaticData +DAF7B0E6-32DE-4619-B63A-2B9173A75B14,GetNetByName +DAFF1B62-A67A-4E11-8B57-496B572E0775,SystemLoadDefaultDxe +DB08F6CA-3048-4CD8-9B1F-20BED33ECFE7,StatusCodeSmm +DB0C8A93-57EE-4E4E-AA7D-1179234A7D63,DellRamDisk +DB1ACEF4-46A0-4A81-8E1E-4B793CEAAD68,LenovoTpmFwSwitchDxe +DB1C3561-4F9E-4748-A807-BCBE7FA92FC9,EzConfig +DB2E0816-718E-4B1A-91AF-F2286FAB08BF,FchBixbySsdt +DB33570E-910C-4669-A934-DC26BD304836,PchMctp +DB3FC2DF-7376-4A8D-82AB-9154A136A65A,UniversalPayloadPlatformBootManagerOverrideProtocol +DB41E01B-A8B0-4E15-B619-4463975B357B,SetupDataChecksumErr +DB47D7D3-FE81-11D3-9A35-0090273FC14D,EfiFileSystemVolumeLabelInfoIdGuid +DB4DB11A-0E5C-40B5-8E46-17D04486A21B,LenovoMx25L64XflashPartSmm +DB4DC31F-F307-4D6A-A347-180FD27EC10A,MsiTouchPanel +DB4E8151-57ED-4BED-8833-6751B5D1A8D7,ConnectConInEventGuid +DB551771-4449-4387-908D-F70685B1DCAF,PlatformMilestoneHookSmm +DB63592C-B8CC-44C8-918C-51F534598A5A,PchResetProtocolGuid +DB6AE46F-C20B-45AC-8E53-ED0B90015E3C,AsusQualityIntSelfBin +DB6FB49A-918C-4C11-FFFF-FFFF636503A5,XnoteSystemPolicyDxe +DB73174E-E46A-4927-9947-CF2DBEAF1681,PowerMgmtConfigGuid +DB8AF09A-34E3-4A7B-8225-8C5B0C059EB8,AppleSmc +DB941521-4EA7-4C87-A711-354DB5D6D7E6,OemSmbiosConfigDxe +DB9A1E3D-45CB-4ABB-853B-E5387FDB2E2D,EfiLegacyBiosProtocolGuid +DBA5B11B-8686-43DD-8850-854FD3D4B244,AsusFirstBootSetting +DBA6A7E3-BB57-4BE7-8AF8-D578DB7E5687,EfiTscFrequencyGuid +DBAB39F4-8FF1-45B8-B92B-107848AC07E7,CompalCMFCSmmHook +DBADD769-E86A-4819-8120-E991792C0BC1,VbtMipiAuoGuid +DBAFED06-A439-4166-B051-C1C5339BC3BA,AmdNbioIOAPICPei +DBB5F303-214D-41C4-BEA3-A1B56A42DA8B,IsaAcpiDriver +DBBF780A-1337-49A8-9B73-3902D6047BD8,H19DisplayHook +DBC461C3-B3DE-422A-B9B4-9886FD49A1E5,EfiJsonCapsuleResultTable +DBC6381F-5554-4D14-8FFD-76D787B8ACBF,IpmiProtocolGuid +DBC9FD21-FAD8-45B0-9E78-27158867CC93,BdsAllDriversConnectedProtocolGuid +DBD5B6BA-6734-4C5D-BF53-2C210D93A012,IsctSmm +DBDA3714-78BF-43FF-B30B-4BD3DBC01B54,PsmiMotBufferGuid +DBDD9682-70FA-46CE-B89C-D6AF714E51B9,LpssSmm +DBE23AA1-A342-4B97-85B6-B226F1617389,EfiPayLoadHobBasePpi +DBE23AA9-A345-4B97-85B6-B226F1617389,EfiTemporaryRamSupportPpiGuid +DBE33D2A-6B10-4E77-BEF8-C829F29C8A85,DellUsbBusDxe +DBE37563-AFEF-4B41-BDCE-B01B6D1E8690,Tpm12DeviceLibInfineonI2c +DBEA47AE-E64B-4DD9-9586-151AEC8D5C18,HpPlatformSmmServices +DBFAB6C3-6C4B-4E4F-A8FE-AD1C27D5E8BA,OFCSmmDriver +DBFF9D55-89B7-46DA-BDDF-677D3DC0241D,EfiAcpiSupportProtocolGuid +DC08D13D-EC1A-4458-B37A-C50118D7AC48,SetupAutomationSmm +DC092DB6-6F93-4C85-9615-7C8B23D48DB9,HpNetworkConfigDriver +DC14E697-775A-4C3B-A11A-EDC38E1BE3E6,AmiCsmOpromPolicyProtocolGuid +DC2AA475-F636-48BB-6D74-7F2D926C1111,LEMElockerSet +DC2AA475-F939-48BB-9D74-7F2D629C1111,LoadComputraceImage +DC2CD8BD-402C-4DC4-9BE0-0C432B07FA34,UefiFrameBufferInfoGuid +DC3641B8-2FA8-4ED3-BC1F-F9962A03454B,Mtftp4Dxe +DC38DF16-8280-49C1-B253-D7DBB301CF71,SystemNUserPasswordCredentialDxe +DC38DF16-8280-49C1-B253-D7DBB301CF78,UserCredentialPwdDxe +DC3AA475-F939-48BB-9D74-7F2D629C1111,LoadCptImage +DC3EA0B0-A144-4797-B55B-53FA242B6E1D,EfiWheaProcessorSpecificErrorSection +DC3EA0B0-A144-4797-B95B-53FA242B6E1D,EfiProcessorSpecificErrorSectionGuid +DC54B283-1A77-4CD6-83BB-FDDA469A2EC6,EdkiiPeiUfsHostControllerPpiGuid +DC571B6D-D570-4862-A95F-299B28FDC2D2,DellAdvSysMgmtConfigDxe +DC58C51B-EC67-4DB7-B8A7-881858F55913,IntelLanUefiDriverI225 +DC5FAA6B-BA33-49CD-8146-AF7D6DA39687,AcpiOemNVSInitDxe +DC66C1E2-C114-4D0C-ACC0-003F15B3F729,BctBaseSmmRN +DC68E307-6C8C-4997-B32F-3F73C381B769,DellSmmTagsProtocol +DC695BFC-F8E8-4CD3-A9E5-83B805D3FDDD,KEMhDispChipset +DC7063FC-E01D-476F-9BF3-DE010884BC53,DellSmbBbsInfo +DC7E8613-C4BB-4DB0-8462-13511357ABE2,EfiKmsFormatAesxts256Guid +DC8E20DF-8275-404A-B209-3818A3BA86A5,USBSecurityProtocol +DC90D1E2-556A-45CF-B3EF-9DE451807A17,SaInitDxe +DC92A37B-4AC5-4117-AABB-019FFC0FD06A,FpkSetup +DC952D08-C62B-41C6-BAC7-70ED054F91E5,Pkcs7VerifyDxe +DC958E14-CA7E-479C-A656-2CB95F8A169B,RpmcDxe +DC95D600-B0CA-43EC-871A-976B8A55CCE0,NvramHdrInfo +DC99D47E-6808-4F3A-A1E4-BE7A9ADC59FF,FjIbvSfuControlAbstractionDxeProtocol +DC9B795B-FFD9-44E8-A36D-6637852EB6E4,S5MaxPowerSavingsDxe +DC9CACE8-8C2E-4FE7-9E41-E18C75FE9B66,DellSmBiosStrucB2 +DCA1F451-980F-471A-8882-7A33123DFE52,MemoryIdm +DCA41C06-FD2B-41E4-BBE7-946444DB0BD9,SystemFindFvPei +DCAA4B60-408F-4BAD-99B9-B880D4EF0950,Tdt +DCB5FCE4-2116-4E7B-BB83-2FC7329261BD,NvmExpressSmm +DCBC3662-9CDA-4B52-A04C-82EB1D2348C7,EfiKmsFormatMd5128Guid +DCBE6D66-D928-4138-8041-358F35CBCF80,IsaBusDxe +DCC64575-FA7D-4B7B-B1AD-48427C97C74D,LibCtype +DCC8F917-080B-400B-A31C-036F1373F048,CertificateStorageDxe +DCCF6769-C3D5-4EFF-A181-FA0988E1D9B4,AmdCpmMsCommonInitDxe +DCCFB2EF-AAE6-48D0-8DF2-DC4D764A5A92,RTKLanMmio +DCD0BE23-9586-40F4-B643-06522CED4EDE,EfiPeiSecurity2PpiGuid +DCDADB6D-880B-4CB9-9CC0-506C3E182CB2,BackupBiosInfo +DCDD4692-88D3-4CE6-8CEF-15E0E4DA1494,Npce388nFlashDxe +DCDED170-9AAD-4E64-BDD1-F55FA86E75B1,ApobPhxDxe +DCDF614D-930E-4FDF-AFCD-F4A8A408E077,EarlyVideoDxe +DCE1B094-7DC6-45D0-9FDD-D7FC3CC3E4EF,QemuRamfbDxe +DCE5298C-1D89-4125-944A-CD04D3CA0AAA,FjSysmanTeutatesBin +DCE7D3FA-CC44-407E-AE58-90895B328915,OdmSmmGNVS +DCFA911D-26EB-469F-A220-38B7DC461220,EfiMemoryAttributesTableGuid +DCFC22C0-A513-11E3-B576-446D571553EB,HotkeyInterfaceCoreDxe +DCFD4C57-AAFD-4D92-B570-04B1212ED15E,AmdCpmOemInitDxe +DD071A16-CF16-4AD3-A01E-5B15680CDFF0,KEMhUuid +DD1BB969-BE0D-4B70-9E13-2ED2E1854240,LenovoWufuEsrtDxe +DD1C807E-BDB9-49A4-AD50-E510DC948476,FujNotInSmm +DD223EF8-6D1B-490A-A53E-BA86FAAEB778,MmcMediaDevice +DD25B790-AE79-43C2-8644-96DAB90C3636,SystemOskTriggerDxe +DD2E8F57-893F-4335-8DEA-4B5C343AE398,FjDeviceInfoIntelLan +DD32356C-434B-418E-B3F7-E7227825F78E,UsbHubEnable +DD455A69-EC75-456C-84D2-95CAE7D3C6D3,EslTcp6ServiceGuid +DD4A4648-2DE7-4665-964D-21D9EF5FB446,EfiCcFinalEventsTable +DD4DBCE0-59C2-4A4D-AB0D-358976023385,MTKWiFiGen2Dxe +DD4EA471-D8D2-4CE7-86B3-14AFECE76141,KEMrWdtSmi +DD51AB78-E55D-4413-AFAE-E592F6B5321B,AmiEventLogsDynamic +DD5B9DAE-16BB-4E28-B10C-08A3AD7E44CE,AsusWakeOnRtcS5 +DD5E92D1-DDAC-48CB-907A-882D8610E89E,SavePegConfig +DD6C613A-5A77-4B4F-A61E-3BDD2AE21D81,PerfTuneProtocol +DD73A3E6-9FDB-480E-81A6-A2D85D220B8C,DellXmlParser +DD752080-DF6C-4533-AD66-6213EE681F84,ThermalDxe +DD787473-07CE-4C63-82CE-930B33F39C09,SmmControl +DD84017E-7F52-48F9-B16E-50ED9E0DBE27,EfiSocketIioVariable +DD87502B-CBDE-48A4-A896-F521E0745CC0,AppAdapterTdx3v0 +DD915390-3B7F-428B-8DD4-C4C2FA897C63,AmdPlatformRasRsSmm +DD980BB7-9FDA-4A15-BBD2-734E4678B2B1,AmdSocAm5RplPei +DD9E7534-7762-4698-8C14-F58517A625AA,EfiSimpleTextInputExProtocolGuid +DDA33BE6-4A6B-41F2-8067-ED4FE50BEA2B,FjDfciDxe +DDABFEAC-EF63-452C-8F39-ED7FAED8265E,PpmPlatformPolicyProtocolGuid +DDADFC93-FBC5-4389-B20F-EC99E4A6AE52,SmmLibNull +DDB321DD-2D18-407D-8CC4-7F997BEB7D66,RecoveryPatch +DDB412A6-E3F3-4E9E-90A3-2A991270219C,iFfsDxePolicyInit +DDC3080A-2740-4EC2-9AA5-A0ADEFD6FF9C,EfiIioSystemProtocol +DDCBCFBA-8EEB-488A-96D6-097831A6E50B,HashLibBaseCryptoRouterPei +DDCF3616-3275-4164-98B6-FE85707FFE7D,EfiVariableInfoGuid +DDD75BF6-4CF9-4A2C-978F-A5AE656B61E5,CaseOpenPei +DDE1BC72-D45E-4209-AB85-14462D2F5074,RomImageAddress +DDE31574-3589-4FA9-BC69-1729AF6FDA4E,AmiNvramUpdateProtocolGuid +DDED691E-0495-45DB-ADFF-D68452C9A5A4,Float +DDEF12C9-944D-4757-A3EC-CCFBADA96DD2,DellFlashBios +DDFB5557-3E2E-4569-B459-BEFFE189B8B0,AmiSmbiosFlashDataProtocolGuid +DE072137-A9FC-408C-8B4D-6FD2D798BBCB,FjUsbSecurityVG2 +DE0EE9A4-3C7A-44F2-B78B-E3CCD69C3AF7,EfiExtendedSalBootServiceProtocolGuid +DE115752-A79D-4F33-8459-A9524A64FC52,SioFanMapSmm +DE13C06E-F532-49DA-A319-5F7DD0F603C2,GopFirmwareVersionDxe +DE141A05-FA40-432D-9631-5E3E990F44D5,SlotDataUpdateDxeNeonCityEPRP +DE161CFE-1E60-42A1-8CC3-EE7EF0735212,EfiTpmMpDriverProtocolGuid +DE1B74E3-4A7F-FE08-058E-AC8678F99112,ExternalUsbPortConfigSmm +DE1B74E3-4A7F-FE08-058E-AC8678F99114,UpdateMarshalString +DE1B74E3-4A7F-FE08-058E-AC8678F99115,HddSMARTCheckDxe +DE1B74E3-4A7F-FE08-058E-AC8678F99116,UpdateHardwareSignature +DE223A35-931C-4C12-8E47-73B7A65C2B7A,AmdPspRomArmor2Smm +DE23ACEE-CF55-4FB6-AA77-984AB53DE811,SaInitDxe +DE23ACEE-CF55-4FB6-AA77-984AB53DE823,PchInitDxe +DE24E0D1-FAEA-4906-9CC8-AC00BE3DFF3A,AmiIbbrOBBHobGuid +DE28BC59-6228-41BD-BDF6-A3B9ADB58DA1,FramerworkEfiFirmwareVolumeBlockProtocolGuid +DE35F257-36BF-4F71-8270-51CF5378B86C,GraphicsConfiguration +DE371F7C-DEC4-4D21-ADF1-593ABCC15882,ArmGicDxe +DE3D7A9C-A218-4891-7469-4FC0AE853298,AmdCpmPcieInitPeim +DE3E049C-A218-4891-7469-4FC0AE853298,AmdCpmGpioInitPeim +DE3E049C-A218-4891-8658-4FC0AE853298,AmdCpmDisplayFeaturePeim +DE3E049C-A218-4891-8658-5FC06A84C783,SBCbsPEIEntryPei +DE3E049C-A218-4891-8658-5FC0FA84C788,AmdProcessorInitPeim +DE3E5631-461B-B4F4-0625-61B58B8787E1,HpCmosHandleLoadDefaults +DE44408C-EAA3-4CA0-A05A-27380FC4861F,FjGabiFlashCommonDeRegionCtrlSmm +DE498C70-1EDA-466B-ABCF-DD3ABC3D24B4,DummyMSOA +DE5DE16A-75E4-42DE-86D8-30666A08EA93,DellUefiClass3ConfigPei +DE5FC8BF-06ED-4DC5-BA9D-29F711699A85,TraceHubStatusCodeHandlerRuntimeDxe +DE6DB1B8-C25A-4F4F-8EC5-DE5D27312108,OemHooksSmm +DE820DA5-69CC-4E50-B6C3-F07B27B10BC2,CNVISetupDxe +DE83EECD-2E0F-47D3-B634-556615B101DF,OemUsbConfigDxe +DE882DD5-B797-4E2C-A8BE-C6367BCB4A23,EpscHwDeviceId +DE8A5A2C-D788-47FB-A0B5-20CA8E58DFEC,DellSystemIdConfigPei +DE8D943C-187E-42C3-98D1-1F7584DF6ABD,LfcGr2BoardType +DE8F2878-36D5-498E-BA59-168C2647B335,PeiIffsTransitionStartPpi +DE98E4D5-109B-48FC-B88D-980E97D8B93A,ArmaniPei +DE9ABB5C-2F92-4352-9C56-F51BC9D5E55A,DxeFramework +DE9D58C3-4242-4FEE-A90E-C40B057CBB94,BmcSync +DEA652B0-D587-4C54-B5B4-C682E7A0AA3D,AcpiS3IdtrProfileGuid +DEB0EE00-18DF-415C-AF03-74D09B0AAD87,JedecNvDimm +DEBABF6E-49E4-4C21-8403-A1FB8F803A9D,FjSysmanAcpiStatesBin +DEC5DAA4-6781-4820-9C63-A7B0E4F1DB31,ShellLevel1HiiGuid +DEC9B486-1F16-47C7-8F68-DF1A41888BA5,UefiOvmfPkgPlatformInfo +DECC9729-74CF-42E7-8672-B94B7EF4A4C5,ApobRmbPei +DED3F743-CE2C-4BA6-92A2-FFCE2A6D72D9,PeiServicesTablePointerLibIdt +DED60489-979C-4B5A-8EE4-4068B0CC38DC,OpalPasswordPei +DED7956D-7E20-4F20-91A1-190439B04D5B,SmbiosGetFlashData +DEE3F62A-3B0F-448B-81F9-4AFD546515B9,SiliconNvsDataPei +DEEA4A6A-9308-465B-AD99-B5BDA5B55575,CompalThermalUtilitySmi +DEEB4CD1-0F01-4F61-9F39-0DEC61E909FE,RunTimeWDTDXE +DEEEA15E-4A77-4513-BA75-71D26FEF78A1,SmmIoLibSmmCpuIo2 +DEF30E37-7AEC-4F69-91A2-CF099E2729F2,PciTableInit +DEFBFC7A-CC02-4225-88AD-3C41E621785B,DellIdeDxe +DEFD645B-720F-4ED3-9B4A-A3688BF5A300,AmdMemMcsrUserPreferenceDxe +DF13AA16-B7B9-42A0-A399-00EE6C81A85A,DxeBoardInit +DF1BCAA1-9152-4357-A6B6-E5FBCFBB6B81,FchSmbusPei +DF1CCEF6-F301-4A63-9661-FC6030DCC880,SecMain +DF2AFA8D-CFD0-4F71-830E-6A0EB22A9586,AdlinkDriverPei +DF2B6949-B0AF-42B3-A70A-935D4875E480,OemRomIdVar +DF2D868E-32FC-4CF0-8E6B-FFD95D1343D0,EfiPrintProtocolGuid +DF2EC7DE-6F79-40F1-B704-7F8204E3D145,PlatformFlashDxe +DF4F6190-42B8-4CA9-BA51-7A801B565F08,b57undix64 +DF500D60-FAD2-0884-F5D6-52D8B082868F,WtSetCoreNumAndSmtDxe +DF59F831-6689-45B5-A4D9-3E660D56573E,LenovoBootOptionProtocol +DF5CD25A-8E55-46BA-8CDA-BC7DB7BF9C64,MdesStatusCodeDxe +DF636282-5EED-11DF-A9D6-B334FBA24BB0,IntelHdAudioDxe +DF639C97-21DD-48AF-A0DE-78CC2D95DC55,DefaultsManagerDxe +DF655424-0025-4D4F-82B0-6DAC258BA879,NetworkOffLineLockerProtocol +DF66196C-958F-472F-9393-717D82110AF6,AmiHashLogExtendExGuid +DF665292-79D7-40E2-BA51-F7D494628185,CpuWakeUpBufferVariable +DF6A1801-70F8-4E2A-8631-62E297565609,DxeSioEmi +DF73ABDA-7A42-4E5E-B34B-E6830671C9A6,AmdSb900SmmDisp +DF85204D-83CF-4132-B4FC-9A75F2BC874F,NonAmtNetworkControllerSmm +DF8556F0-3A61-11DE-8A39-0800200C9A66,PerfTunePei +DF874E87-FFC5-4C5D-8B1E-81EE01A6D435,SetupLoadDefaultPei +DF8DE36D-D241-4947-87F1-36F9EDE545D8,ASUSFS +DF934DA3-CD31-49FE-AF50-B3C87C79325F,PlatformDebugLibIoPort +DF939333-42FC-4B2A-A59E-BBAE8281FEEF,EdkiiBootManagerMenuFile +DF93FD41-44AE-4952-8971-41D472EAFC78,PspGetIntrusionLog +DF960F12-05CE-4E18-B926-00AFC9F31C7E,PeiSioEmi +DF9A9591-B646-4621-AF0D-18143A73289F,AppleLegacyBootFS +DF9A9FFC-A075-4867-A0B2-5E7540BB023E,AcpiSmm +DF9C0686-2B2E-49D9-94F4-A41C47AB9633,Hob +DF9DC2AA-6634-4F84-B677-532BCC6AA9AB,AmdFtpmTcg2Smm +DFA66065-B419-11D3-9A2D-0090273FC14D,EfiVT100Guid +DFB36C78-E534-4E05-9D5D-1803F36E88F2,ReportFvRecoveryPei +DFB386F7-E100-43AD-9C9A-ED90D08A5E12,EfiIpSecProtocolGuid +DFB9BF4C-3520-4A80-904E-71D5F42E866A,XmlCliCommonDxe +DFC54544-2516-47A5-B288-29F100AEFD01,HpCheckpointFlowControlCsbPrivate +DFD4B243-0430-429D-829A-CA2BAB3FE7A6,AuthenticatedBiosInterfaceSmm +DFD8D5CC-5AED-4820-A2B6-5C55E4E640EF,AcpiPlatformSmi +DFDBBEAE-7D4B-4D3F-BA01-FBF3DA708599,ThunderboltPei +DFDD9231-F5D7-4C8D-8BE8-6EAD873240F3,DellRuntimeSmbiosProtocol +DFE12086-5323-44BB-BB3D-702165FCFB61,DellHardwareSignature +DFE7EE64-D4FD-4424-BF1F-85DA524236FB,DellMfgModeDxeDriver +DFEC7540-B6ED-425C-883F-9D8F3C85384B,MemRas +DFF4BF9D-D027-4F7E-9385-C1ADB0CEF753,FjSmmAzaliaVerbTable +DFF4E6C8-234C-453E-A92D-FA505E90D539,DellDaOwnerTag +DFF5AB67-23C6-406F-99D4-F51B22044113,SmmWifiToolDriver +DFF622F8-8BA6-4715-B58B-C840C1D6FAF4,MsSysGrdTpmNvDef +DFFC7495-75AD-4354-AB0A-BDFD9046067C,AbtErasePei +E000A056-8E65-4730-A6BA-6ED08B8D289C,FjSystemResetPei +E000FC69-653B-43F5-93BC-4387957F330D,NVMEPowerSettingControl +E008B434-0E73-440C-8612-A143F6A07BCB,Recovery +E010BCCA-3A3B-4B03-BCF4-AE1F64A85C89,LenovoUserManagerPei +E01FDFD3-48C8-432C-9555-4409DDBC6C6A,AmiFlashLibDxe +E029BADD-E270-467E-9C0F-D7586C33850A,Runtime +E02FA6E3-AFF0-47BF-93D6-3BDEDF690BBC,BoardKvmNetworkStack +E0364FEE-1440-4A41-AD3E-50E0B106A83D,DellDaBfa +E03ABADF-E536-4E88-B3A0-B77F78EB34FE,CpuDxe +E03D5A07-CDCD-4AD1-A829-0B5A4AA6D62B,BiosConnectProfileLoaderDaSmm +E03E0D46-5263-4845-B0A4-58D57B3177E2,UbaConfigDatabaseProtocol +E03E6451-297A-4FE9-B1F7-639B70327C52,EnhancePeiVariable +E04095C5-F88D-4942-BEF5-3424A693A8B9,BSODSmm +E0471A15-76DC-4203-8B27-6DB4F8BA644A,UbaConfigDatabaseDxe +E048749B-68A4-40C2-9A83-DC2AB34819A8,FchSmmDispatcher +E04EFEC1-AE85-4845-999F-950ED7352F17,DisableAbtSetup +E0527711-50F7-4672-B868-6A447EF54513,PatchDevice +E052D8A6-224A-4C32-8D37-2E0AE162364D,PchSmbusDxe +E05799E5-DB4B-451C-AC87-5893DD8E4295,FchTaishanDxe +E05B0241-2F68-4DB4-8ADF-5760DE2E1570,TpmFwUpdateDxe +E062C52D-78DC-4CC5-B246-B13497A8123C,PeiDxePostCodeLibReportStatusCode +E065DDB3-8DFA-4CE0-A159-11D7B6FEA589,DellHwmIoSmm +E0744B81-9513-49CD-8CEA-E9245E7039DA,EfiSmmGpiDispatchProtocolGuid +E0746C42-D3F9-4F8B-B211-1410957B9FF5,BootOption +E07473CF-E2ED-4096-BF9F-DC64853AE80B,AmdMemFp8Dxe +E07A890D-7CC3-D042-A74B-12F117DDDF15,AppleGraphicsConsole +E0857D65-5F84-4592-AE49-33D49BA6CCF7,MeSoftStrapUpdatePei +E08CA6D5-8D02-43AE-ABB1-952CC787C933,PeiDefaultVbtGuid +E08EB66A-F063-4BB4-9D11-18F77C227BB7,HpPlatformSataPortConfigDxe +E092EDDD-0E41-4C9E-9C31-9C076FA8B5B6,ApobRsDxe +E099F1C6-F520-4050-9556-D3A2CA154529,H19VariableChangedHook +E09F355D-DAE8-4910-B14A-92780FDCF7CB,EdkiiPlatformSpecificResetNotificationPpi +E0A0C1DE-469B-4D37-62E1-F8BB8AB958AE,Pca9545aDxe +E0ADB57E-E1B6-44EC-BF2E-842874A26C83,LenovoWmaUsbDxe +E0AFD3F0-C7E8-479C-9E4C-4579DCD850F8,IntegratedVideoOptionSmm +E0AFD3F0-C7E8-479C-9E4C-4579DCD850F9,IntegratedVideoOptionDxe +E0B3E91A-4A7F-46AF-AD7E-D05F62A2EA9A,SystemOnScreenKeyboardDxe +E0B7F019-E82D-4432-9831-BC2CC4863F1F,FchHuangshanSmmInit +E0BEC4CC-8AE8-4D15-92E5-9755A08987BB,NCT3933UPEI +E0C14753-F9BE-11D2-9A0C-0090273FC14D,EfiPcAnsiGuid +E0CEA537-FDB0-4D30-8C1C-9B0359A4598F,FjNuvotonNct5581Pei +E0D172D7-1D81-4B39-90AE-FF45D5732483,CheckFspErrorInfoHobDxe +E0D1BE6F-1C43-414E-B571-73C8C3105B18,UefiDriverAsix88179 +E0D8CA17-4276-4386-BB79-48CB813D3C4F,EmbeddedTokenSpaceGuid +E0E1AB16-C482-4015-AE70-64BDFCAA89AB,DellBiosConnectAdvancedDownloadMgr +E0E1F6A1-9D4B-11E3-83C4-78E7D1AF36D1,HpNetworkBiosUpdateDriver +E0E2C90C-F1AD-4759-8EA9-5B4E770576CD,AmdNbioPcieZPDxe +E0E7D776-E7EB-4E5F-9AA8-54CF3AA64A43,PeiServicesTablePointerLibKr7 +E0ECBEC9-B193-4351-A488-36A655F22F9F,SaveMemoryConfig +E0EDAB16-C482-4015-AE70-64BDFCAA89AB,DellBiosConnectDownloadMgr +E0F2E558-993B-43A9-88C8-D5308BCEBBBE,EcStorageAgentSmm +E0FF720B-0140-43FE-9528-7A781357E42E,UsbOhciDxe +E10539B8-1C35-4B84-8593-81555D065DD5,DellDaPasswords +E10C1F46-6ECB-47A7-BA9A-1C29D074A022,AmdSocAm5PhxPei +E1136F9A-A0CF-477A-A86F-DCE8EFEC3C63,AmdSocFt6MdnDxe +E113F896-75CF-F640-817F-C85A79E8AE67,EmuThunkPpiGuid +E11D6290-CCFD-4501-B59A-CECBA0E79133,OdometerMetrics +E11FACA0-4710-4C8E-A7A2-01BAA2591B4C,FdtClientProtocolGuid +E121EC07-9C42-45EE-B0B6-FFF8EF03C521,AppleRtcRam +E12929EF-F08C-4E26-8290-281740D874DE,DisableChassisIntrusion +E12BB3A6-1EA1-4F4F-FFFF-FFFFBCE290C5,RecoveryPartitionDxe +E1319FEB-CA0D-4E73-B79C-34BA1134D79D,LVDS +E13DD38C-1B41-49F5-8D92-0839D4234AA2,AmdCpmAdaptiveS4Smm +E1404778-B848-4FFF-8351-9F78791417D9,TurboSmm +E143C542-4FC4-4DD9-99F2-75715C44E41C,IePolicyInitDxe +E1475E0C-1746-4802-862E-011C2C2D9D86,EfiRuntimeCryptProtocolGuid +E14F04FA-8706-4353-92F2-9C2424746F9F,AdvancedFormSet +E15696EF-0671-4822-AF07-FFD99A4783CC,SmuV12Pei +E15704A1-A2F5-7668-28C0-F8C8663170A6,EcFlashDxe +E159A956-3299-4EE9-9176-65181A4E5E9F,AmiIdeBusInitProtocolGuid +E15C4934-056C-466C-9ECE-FF86C0742B57,OemWorkaroundPei +E15C9DF9-FC62-47B0-869B-FFB41BC6EA90,DisplayLinkPxe +E160D276-F2F9-44A2-8EA6-8BB5C4C30307,FjThermalDxe +E1628C66-2A2D-4DC5-BD41-B20F3538AAF7,BootPicker +E16600D0-3C41-4798-B16A-0DBA67D2FC47,AmiCpuSmbios +E17F0016-E0E6-4B01-AB59-797A2699901B,AaeonHiManager +E18541CD-F755-4F73-928D-643C8A79B229,EfiNetworkInterfaceIdentifierProtocolGuid +E18A21D4-964B-4974-992A-2A2FEF11E643,WOSKDxe +E18DBA7B-AB76-43FF-8C27-50EE3373481D,CxlEndpointDriver +E18FE2D1-EF32-4C8E-895A-F02C3C38FB19,DellPropertyAccessorProtocol +E19E3D16-BC11-11E4-9CAA-C2051D5D46B0,EfiArmProcessorErrorSectionGuid +E1A21D94-4A20-4E0E-AE09-A9A21F24BB9E,EfiMeFwSkuVariable +E1AD4352-2610-4DD6-BB8F-8BB2B03383A3,LenovoSystemScsiOpromPassThruDxe +E1AEB947-940F-4635-A87F-817AB51B7261,DualDieRecoveryPei +E1AF9F5B-7CDE-4F98-91ED-5E67868282B8,AsusBbVideo +E1B26D32-414F-46DB-9AEE-420077F35DBE,AsrockAmdcpuDxe +E1B8CF4A-FE7B-4676-B4F7-50C7228282A4,AmdApcbPeiV3 +E1C1D0A9-40B1-4632-BDCC-D9D6E5295631,EfiPaddingRsaesPkcs1V1P5Guid +E1C401BB-2336-47F6-A512-4308F6F42931,BixbyEarlyLink +E1CD9D21-0FC2-438D-9703-04E66D961E57,EfiExtendedSalPalServicesProtocolGuid +E1CEE6E3-6C42-4A4F-916E-38385290A556,SnpDxe +E1CF12E4-762B-4576-A158-9B255A828AA7,gear2 +E1DB609A-D413-4791-C6EE-093D8BC047A4,AmdNbioPcieDxe +E1DC0888-C5AC-4A2C-83A5-91AD26960F31,DellTpmPpiSmm +E1E1685A-7ABC-450F-882A-4E692CC6AF7E,FpgaConfigDataDxeNeonCityFPGA +E1E4A857-C970-4075-A4DA-E9C41B69ADFC,AmiTextOutProtocolGuid +E1EB612F-1C6C-485D-9D06-650844881569,EfiSignedCapsulePkgTokenSpaceGuid +E1EDF165-6623-4B54-BD7A-A05E064206B0,FjSignon +E1F2EBA0-F7B9-4A26-8620-131221642A90,EfiPciCfgPpiInServiceTableGuid +E1F4062C-993B-4972-9A6A-3EB68AEC5403,RtkUndiDxe +E1F7F068-97E7-4B74-BF0F-626745AF9934,DxeSpiNorFlashCommBuffer +E20939BE-32D4-41BE-A150-897F85D49829,EfiMemoryOverwriteControlDataGuid +E20BE735-E059-4CD5-A927-FF7D528EC650,DescriptorUpdate +E21B0336-9B81-4743-B033-6D7405734E3C,PciDeviceInfoSetupUtilityDxe +E21F35A8-42FF-4050-82D6-93F7CDFA7073,PiSmmCommunicationSmm +E223CF65-F6CE-4122-B3AF-4BD18AFF40A1,CpuInfoProtocolGuid +E227C522-D5FE-4A53-87B1-0FBE570F98E9,ObservableProtocolGuid +E22BBCCA-516A-46A8-80E2-6745E83693BD,EdkiiSmmMemoryProfileGuid +E22F236E-5094-48FD-8018-CF46BB584539,FjSystemResetSmm +E2307DBF-199A-4298-9CF5-8749E1CA3038,LegacyUsbSmm +E230E9FB-1232-4D2C-AC1C-E38FB00EA530,BiosLockRegion +E230F9FB-12C2-4D2C-AC1C-E38F100EA530,SnapScreen +E2347FA9-FD73-4165-B15C-C4665A259E53,AmtGbeChecksum +E234A986-8946-485D-A645-C806225F0213,BiosDiags_2_0 +E23F86E1-056E-4888-B685-CFCD67C179D4,SbRun +E2406FEC-6609-4385-AB3D-4535B6C7C46D,SmmSxDispatch2OnSmmSxDispatchThunk +E2441B64-7EF4-41FE-B3A3-8CAA7F8D3017,PciPlatform +E252C258-C839-48CF-A85C-E8F4C3235BDA,OemApVariable +E2657A19-7CD8-5389-98BC-6E201BBF4F70,MonacoFont2x +E268A2D1-F8A2-4EB4-85B7-B052FEB79574,CpuInitDxe +E269AC86-6049-4509-8D16-8899DA529BBB,PeiCmosInit +E273212C-11D9-4728-B1AC-B6EE5083EED6,TbtRetimerCapsule1Dxe +E2775B47-D453-4EE3-ADA7-391A1B05AC17,PciSioSerialDxe +E28674B9-CAFE-4B29-85D4-42ACAA09BB69,UsbPxeUndiDriver3 +E287D20B-D897-4E1E-A5D9-977763936A04,EfiPchS3SupportProtocolGuid +E292BA71-812C-42B9-885D-3F0565B098C7,SyncSetupCpt +E2A5ECED-DE4C-432D-9AA0-061C33A308C8,A01DataServiceBodyDxe +E2A74738-8934-48F5-8412-99E948C8DC1B,SmbiosDmiEdit +E2AA867F-70DE-492A-B25A-77B3055024CB,CbsBaseDxePHX +E2B36190-879B-4A3D-AD8D-F2E7BBA32784,EfiCertRsa2048Sha256Guid +E2B40649-EAA4-434F-8BBC-9FA4A82E6AAE,AmdSmmControl +E2C24CB6-A555-42F9-8442-BDB2B2B8B490,HsmpBrhDxe +E2C3BC69-615C-4B5B-8E5C-A033A9C25ED6,Tcg800155PlatformIdEventHob +E2CFB356-39A9-497B-B6B1-95B9D2EB2817,DellSlpConfig +E2D5F333-D89E-4F3B-A270-7AB3C1727A57,AmdMemShpSp6Pei +E2D7B442-8413-45B8-928C-C77DEEE25D4A,FjGpioAbstractionReferencePei +E2D927F5-7219-4C06-A715-ADDEF7F2821B,OemPei +E2DD8CE7-0A31-4C3B-A774-B2881ED85682,SysInfo +E2EA6F47-E678-47FA-8C1B-02A03E825C6E,TcgMorLockSmm +E2EAE962-C492-4CA4-A11F-1A7CBB050A41,English +E2ECA273-A1C0-407E-9A5C-F10C55142196,BaseSmbusLibNull +E2F05B00-408B-4A2B-914B-F3330B312F5E,SpeakerInit +E2F66EA2-0313-4B7E-A74F-8E23A6FEB449,UfsPhyOverrideHobGuid +E3007647-798F-FF48-AC61-E0B8D1B66327,PlatformDataRegion +E305E101-913A-4A51-8E0E-B4618C5DB326,DellDxePchGpioControl +E30674E9-A7F0-4E1F-A5B6-D1052A9A7505,Pca6107Dxe +E30C62E1-8CB1-4D98-B535-436BCD5F4566,LEMSataPortOverrideProtocol +E331EA77-E196-4590-9F35-87CF021BE337,FjBiosReadyGpio +E3391FCF-E910-4E62-B216-756C850E29B9,SxDispatchNotify +E33A8FC6-128F-482E-8CD5-360172CE4314,OemModelIDPei +E33D951C-EBE8-474C-AFAA-21AC65AA768F,LEMBootModeFlagDxe +E340F951-0CD0-4E18-A0C7-2E2FC9F6B01B,FjGabiSettingsCoreAbstractionSmm +E3441740-3B41-4C90-9C9D-964056C7417D,DxePciLibEsal +E34AE77D-3314-43F6-B41C-6F19F3F1D6A8,AmdPspPeiV2Rmb +E352725A-B84A-4EBC-A994-228E19224816,SmcBMCSMI +E35A40E9-D4BE-4F4D-ABA7-22C29CAE0BE1,UefiDriverRealTek +E360BDBA-C3CE-46BE-8F37-B231E5CB9F35,FD_Drv_X64 +E364A338-2842-4F57-A7C7-CDC8CFDF6CD7,AppleEvent +E3697058-B73E-421A-BE3D-C08008D8A005,SmbiosDataUpdateDxeArcherCityModular +E369E9DE-DC16-4F58-AC7B-088EA6DD5566,CbsSetupDxeSHP +E36B2401-2251-4B13-AF67-A1B2EC561E36,DellSimulatedECSmm +E374574A-2ADF-43DB-A778-88A75FC08026,DellSmbDaTokensConfig +E3752948-B9A1-4770-90C4-DF41C38986BE,QemuVideoDxe +E378875C-3282-48A0-A9A8-B1E4E16BD513,ChassisIntrusionS3 +E37E75F7-015C-4B3D-9DE8-BE595F8B0662,Amd3rdPartyDxe +E380280C-4C35-4AA3-B961-7AE489A2B926,AmiSmbiosDynamicDataGuid +E3830347-4844-49F1-9570-18AA377B711C,AppleDiagnosticVault +E3862753-53F0-4EF2-A2A8-C04800376EAE,FchI3cHciPei +E38A1C3C-928C-4BF7-B6C1-7F0EF163FAA5,FlashDeviceLibRuntimeSmm +E38C1029-E38F-45B9-8F0D-E2E60BC9B262,DisplayEngineGuid +E38C11E3-968F-47B8-ACEF-ACC0693DB9FF,EfiIchTokenSpaceGuid +E38CB52D-A74D-45DB-A8D0-290C9B21BBF2,UserProfileManager +E391CC76-41F7-4995-8145-D416D03A2AD3,IntelGraphicsPeiDriver +E3926671-4595-4D35-8911-2941BD77E475,DellEcChipDetectPei +E3932A34-5729-4F24-9FB1-D7409B456A15,OemBadgingSupport +E3B5B05E-E4B9-4ED1-BF0F-36D4CA7FE365,MulitBoardPei +E3C604B2-5D43-46AD-A1E4-BF7D11B6AAC5,AmdCcxVhMdnSmm +E3CACF62-3062-4E1D-978E-46807AB9747D,PlatformConfigChangeGuid +E3E0E706-86E7-44A1-BF05-ECC42AE9999E,CbsBasePeiRN +E3E4048D-6C0C-43E4-AE1C-FFB579D8EF41,OpalPasswordDxe +E3E49B8D-1987-48D0-9A01-EDA179CA0BD6,XmlCliProtocol +E3E8BA35-541F-4EF1-BFB8-75F02A26CC75,HybridGraphicsPei +E3ED7C21-9DB8-47C7-8E7D-7DB97FE2063E,DellSmmCircBuff +E3F7AF0C-DB93-4A36-A516-BE4844EA56C2,AsusFtmPei +E405B445-B580-4C7F-9C1D-F226B81F74DD,BiosPowerSave +E405FE96-5A56-40BA-BC24-619C89E2D2EE,EfiBmcSmbiosProtocol +E40B55E5-20A2-41B0-A1AA-42040C98FF9D,WakeEventDxe +E40DA004-CEAB-43CD-B4A8-98497BF33987,DellDashPolicyProtocol +E41B2199-40EF-40D4-A43B-C60B981ACCDB,VariableCmosSmm +E41BE5F9-EC41-454E-B125-A50EE117CA02,AmdMemS3CzDxe +E424C009-CD92-4FEC-8029-D79D3F1CF3DE,IntelIchReset +E425CF37-E55B-43D7-B2C6-CDB9EE8D25A5,RasClvRankSparingProtocol +E42DAC01-2260-4D0B-ADF9-86D3888396FD,FjMacPei +E43176D7-B6E8-4827-B784-7FFDC4B68561,EfiRngAlgorithmRaw +E4364A7F-F825-430E-9D3A-9C9BE6817CA5,EdkiiLinuxTerm +E449F62E-A726-48D2-942B-7872BF90067D,PciSerialDxe +E44E41B5-8B58-4524-BF1D-4EE608A5983D,BoardAcpiTables +E44FC862-12DF-4D4B-9511-93802514AAF8,RomHoleReplacementProtocolSmm +E451DCBE-96A1-4729-A5CF-6B9C2CFF47FD,EfiPrimaryConsoleInDevice +E4541241-8897-411A-91F8-7D7E45837146,BaseSerialPortLibNull +E458FC74-9F13-4E0E-A81E-E32605FA7247,FlashUtilitySmmProtocol +E45CA739-88A3-48E7-87E0-9FBE6C383059,AmiSMMUserCredServices +E4673EC1-2943-492A-979E-2B3D8736015F,FjSxEnterResumeSmiSmm +E469AA26-9268-4EB0-A087-DD4CEE37404B,SecuritySelectDxe +E472DF6D-2B4F-44AC-9165-CA2FCD5AB1F5,AmiCspFlashPeiLibNull +E4735AAC-9C27-493F-86EA-9EFF43D7ADCD,VirtualKeyboardDxe +E49061CE-99A7-41D3-AB3A-36E5CFBAD63E,AtapiPassThruDxe +E49061CE-99A7-41D3-AB3A-36E5CFFEDCBA,LsiLogicPassThruDxe +E492B063-E846-4810-A968-01BC24339774,DellSmmEventProtocol +E49D33ED-513D-4634-B698-6F55AA751C1B,EfiSmbusHcProtocolGuid +E4A83242-DEEE-F12E-15FF-0102036CC3CE,OneKeyLabel +E4A88140-8E28-461D-91BC-A90FF015717C,UsbOcUpdateDxeLightningRidgeEXRP +E4A95FFC-DA1C-440F-8ACC-E3FA6B5EE4F1,DecompressFvCnvDxe +E4BD5CB1-9452-4BCA-AD8A-C3EDD770C40C,HpBatteryControl +E4BD5CB1-9452-4BCA-AD8A-C3EDD770C40D,HpDimmSpdAccess +E4BD5CB1-9452-4BCA-AD8A-C3EDD770C40E,HpThermalDiagnostic +E4BD5CB1-9452-4BCA-AD8A-C3EDD770C40F,HpSysDiagsLaunch +E4BD5CB1-9452-4BCA-AD8A-C3EDD770C410,HpSmartAdapterStatus +E4BD5CB1-9452-4BCA-AD8A-C3EDD770C411,HpDimmId +E4C5BA98-B685-4368-8D40-B80095FC0564,HpIcicleDxe +E4C9411C-1268-404C-9E90-2573EF04F43F,StaticSkuDataDxeNeonCityEPECB +E4CDF1A7-7659-491B-9079-B961E0E486FB,AmdPspPsbDisablePei +E4D359FE-B180-45D2-A6E7-4638876BC471,BiosGuard28 +E4D470CB-41D2-5308-D260-778DDAFADE13,AfterPowerLossDxe +E4D662CD-7CCB-4CB5-AECE-4EEA398FF8E4,FpgaSocketBbsPcie +E4D932F4-31C9-4075-8FA3-4030F7EB767A,SmmPlatform +E4EB2CA8-FF2C-4EA4-A6FB-3EA56E711996,WakeOnLanInit +E4ECD0B2-E277-4F2B-BECB-E4D75C9A812E,NbDxe +E4ED28FD-13C1-40C4-B55A-C5260771A2CF,DeviceManagerDxe +E4F272DA-237F-454C-8868-FCF096CF1C6C,LenovoPasswordCp +E4F61863-FE2C-4B56-A8F4-08519BC439DF,VlanConfigDxe +E4F7ED87-1ED5-4720-A57D-5BA00A727587,DdrtErrorHandler +E4F880BF-81F1-4B87-B8F5-05EF64FD6670,AcpiWsmtDxe +E503CA98-B63E-4592-9BCD-5A4452355134,SmmResourceCheckDxe +E50B6E5D-359B-4BE0-A0B0-0715A301A606,EfiPeiSelPpi +E50E8D30-1F12-4642-A79A-39870DF70361,SioSmbusAccessPei +E510B6FD-525E-A80B-B13C-0B9B1D02CD3F,AutoRecoveryPei +E512DFE4-BF44-480D-9B7A-777B0BE32775,EfiSmmBiosWriteDispatchProtocol +E515404D-8DF5-4562-BCCB-74948D328189,AmdCpmThunderboltDxe +E516ACEF-FA3C-4068-8CE4-888D62B0E497,AmiEfiCrbInfoProtocolGuid +E51CF66A-7D79-43D0-9EE8-0A2084BDEAD4,AmdRasRnDxe +E51D1B4E-68C3-41D8-956D-BA554427C3A3,PcieLaneDXE +E51F643F-5F3C-4CFD-9126-4687305F18DA,ReadyToPxeBootGuid +E5205B53-9758-44AB-A44D-DB3BE41D6742,DellNbConfigPei +E523FC7A-3DF9-4846-A801-D8CC1BE29148,PxeDriver +E53485A0-3BF3-40D2-934B-3DB0FF405737,ComputraceBds +E535D55A-A0B6-4AE6-82CC-FCAB7B5DC579,OemErpHookDxe +E53734A3-E594-4C25-B1A2-081445650F7F,SmmChildDispatcher2 +E541B773-DD11-420C-B026-DF993653F8BF,EfiSmmSwDispatchProtocolGuid +E5434B26-AEDF-43DE-8935-D1C485A912B9,EfiPeiPlatformTypeOpalCityFpgaPpi +E54A3327-A345-4068-8842-70AC0D519855,Tpm2DeviceLibDTpm +E557F408-3BC2-48CE-A9E1-40A3A90EC1C7,USBControllerPei +E5588BFF-E483-4BB2-8C43-44F3B705B413,KEMrWdtDxe +E5652F81-EC09-479C-BAFF-E756F1829016,DirtyShutdownPei +E5669E69-48A9-2F5F-684C-9289FCA737E9,RasOemDimmMap +E566B097-4378-485F-91D0-1C097C190CE2,PowerButton +E5769EA9-E706-454B-957F-AFC6DB4B8A0D,QncS3ContextInLockBoxGuid +E57A1D7C-D16A-4975-AF5B-00EBAC089FC6,StartupMenuTimeout +E5811364-BADA-4F1B-9E3A-6799C1A76DB0,DellSetupChangesMngSmm +E58809F8-FBC1-48E2-883A-A30FDC4B441E,EfiIfrFrontPageGuid +E59BCFD8-6887-4724-84DC-FEE2EDE230D0,AmdCpmPciHotPlugInitDxe +E59C7A97-7FE9-4E32-95B0-708EB58AF507,DellSmmPaidSupDevPolicyProtocol +E59CD769-5083-4F26-9094-6C919F916C4E,EdkiiAtaAtapiPolicyProtocol +E59EA6B0-B05B-4B22-8F3A-242DCBE904A2,AmdCcxVhRnDxe +E5A1333E-E1B4-4D55-CEEB-35C3EF133443,EfiFormBrowserProtocolGuid +E5AB14DA-65A8-4CF8-B4EF-0BB2D5836825,UsbKbSmm +E5B1D3B2-5E64-4972-86E1-7D38FB9D61EB,OemSmi +E5B24906-CF08-4DCD-9EE3-0D163FCA34BF,DellTcg2Dxe +E5B58DBB-7688-44B4-97BF-5F1D4B7CC8DB,EfiEapConfigurationProtocolGuid +E5B734C5-391D-46DF-B8EA-6695C979B1D8,Npce388nFlashSmm +E5CB2AC9-D35D-4430-936E-1DE332478DE7,EfiGraphicsDeviceInfoHobGuid +E5CEE945-CCF3-4A38-A9F9-881321F3FCBE,GopConfigNexPeim +E5D0875A-F647-4E16-BE4D-95024029CC44,MdesStatusCodeProtocol +E5D0BBDC-1BBC-49B7-A8B6-67AAF0A1CD9E,SystemDiagnosticSplashScreenDxe +E5D3026A-1CA5-40F0-8FB6-4B1AFA3C6EAA,AmiCmosAccessSmmProtocol +E5DAFE50-10CB-41B5-9CB5-274E1CF1A8D7,Ip6BmcLanConfig +E5DD1403-D622-C24E-8488-C71B17F5E802,EfiAdapterInformationProtocolGuid +E5E2681D-2E43-44E6-A8CF-0630E35F9D8B,BoardSpiConfigProtocolSmm +E5E2C9D9-5BF5-497E-8860-94F81A09ADE0,NvmeSmm +E5E3C886-25FA-4C0C-B390-DCA2889A3B21,AmdErrorLogDisplayShpDxe +E5E6AB4A-0D7D-4A06-A164-61E47CCE9B3B,DellAcpiPolicy +E5FD5ACD-59F8-4D0A-B3A9-22CB020A6EAA,AmdFabricZpPei +E5FF803C-DE51-4CC7-A8DB-39549815A886,DellUsbMassStorageDxe +E6012F53-7595-409A-9FAC-30E0390A2A69,DellSmbQuickSetSupportProt +E609AFBF-EA72-4D82-83CF-D7E065AC6B3B,NonAmtNetworkControllerSmm +E60A79D5-DC9B-47F1-87D3-51BF697B6121,CpuPei +E6186D9E-2797-423D-B075-970A2C5FC338,DmiArrayVarProtect +E622443C-284E-4B47-A984-FD66B482DAC0,BootManagerPolicyDxe +E629A64A-12C2-42D2-8F1F-B4A459887C28,SysTopologyReportDxe +E62F9F2F-4895-4AB5-1234-399D0D9C1234,ComputraceDxe +E633E57C-BBB1-4C6A-9F45-22C49378ADD0,BootScriptThunkHelper +E6427302-1B37-4B55-8DD5-F43A2F018DE2,AmdCpmModernStandbyInitPei +E646C3A8-C7E2-4DC2-A7F2-E32A270B0B26,LogoThunderbolt +E646CA5D-6D6B-4773-879B-8B4DA2775E09,FchImcControl +E649A8C3-F222-4E6C-3D63-92E7DFAC65A3,DatabaseManagerPei +E64ACA85-F2CF-2246-87F4-92B839CCBB78,SingleFile +E64EE5C6-6EC5-41D8-B6B9-C3D34A71FA47,OemPeiSetBixbyGpio +E65DB1AB-A93F-417D-9A46-CE2419BA72C4,StaticSkuDataDxeCLX64L +E660EA85-058E-4B55-A54B-F02F83A24707,DisplayEngine +E6667FE9-F8C3-4BC6-8748-F875C12D9BB0,RmtcHelper +E666D0B2-E277-7F2B-BECB-E7D75C9A812E,SvrNbDxe +E66B4E21-D75C-45FD-AF53-4CD5918B5FEB,SbRecoveryDeviceDxe +E6727A5E-CBCD-44C8-B37F-78BC3A0C16C8,X86EmulatorDxe +E6754707-8F1A-4546-B9C6-B136D346DBF7,DellBattPolicy +E67E927F-6140-407F-9A3E-4DBD13190F2C,IdeDeviceDetect +E68088EF-D1A4-4336-C1DB-4D3A204730A6,LcdGraphicsDxe +E683DC4F-09ED-4F22-866B-8E4046947C6C,EfiDebugSerialIoProtocol +E6891556-798F-4EC9-9E48-E190B901364C,OemCheckErrors +E68C55B8-C77B-4F66-834F-D73BFB9F29B3,AodDxe +E68DC11A-A5F4-4AC3-AA2E-29E298BFF645,BCP +E69562F2-C982-4E73-87B4-63BC79CDA110,CPLDDXE +E6A6F568-53B5-45A4-859D-43B8C6C3645B,BiosDiags +E6A7A1CE-5881-4B49-80BE-69C91811685C,Setup +E6A81BBF-873D-47FD-B6BE-61B3E5720993,PchSmiDispatchProtocol +E6AF1F7B-FC3F-46DA-A828-A3B457A44282,EfiPeiCpuIoPpiInstalledGuid +E6C079CB-3D03-4BDF-8D72-4AB7FD8D5AD3,SBSMM +E6C20B9D-0A4B-45F1-8E39-A967E28F99C4,DustFilterReminderSmm +E6C2F70A-B604-4877-85BA-DEEC89E117EB,PchInitVariableGuid +E6C7EBB7-1604-4FCB-8F87-B3A6F48730AE,OrderedCollectionTest +E6D77BB0-34D5-4726-BD29-FFFE09E26FB4,SwitchableRsteRaidDriver +E6DA0CE7-C945-4775-941C-55F74D46FA84,FjSlp20Support +E6DB4007-113B-4605-8F5F-668D7364C807,SmmInt15Service +E6DC9900-CCF6-452B-85FA-C7F1E52F0152,SlotDataUpdateDxeNeonCityEPECB +E6E9CCBF-2544-47EF-ACFD-E49A96A79F49,AmdMbistBrhPei +E6ED9B13-31AF-4C92-A561-D47B2FA994F7,FastBootHandlerDxe +E6EDCD6E-6F99-43D3-ABFA-E3E683683AB6,AsusGetOpRom +E6F014AB-CB0E-456E-8AF7-7221EDB702F7,ThinkpadAcpiNvsDataProtocol +E6F4F8F7-4992-47B2-8302-8508745E4A23,OemPir +E6F930E0-BAE5-40E6-98C9-4CD2298278E7,IconNetworkVolume +E6FEA4AA-575C-48FC-99CE-1724DBDC1FF2,ActDxe +E6FF49A0-15DF-48FD-9ACF-D7DC271B39D5,UefiCorebootModulePkgTokenSpaceGuid +E701458C-4900-4CA5-B772-3D37949F7927,StatusCodeCallbackGuid +E706CB54-84B8-40BD-832F-7FB2D5CB87B3,FileExplorerLite +E70E508F-4466-49F3-BBFB-FDF24E950DBC,LockDownConfigGuid +E71B3596-109E-4642-A432-FCF497F8DAE7,FchKeithSmmInit +E724981B-2875-4C8A-9F9A-02AEC1965016,AsusModuleToIntSmmWrapper +E72527CF-505B-4B50-99CD-A32467FA4AA4,AsfTable +E7301EDE-A5D3-4CB6-9EB8-3235F938C3CA,MeIgnitionPostMem +E7428F24-EF0C-4AE4-B521-9D247494900E,AsusOnBoardDeviceOprom +E747D8FF-1794-48C6-96D7-A419D9C60F11,DellSioPolicyConfigPei +E7488F2F-A9DD-4034-EB46-538F71DC7B9D,HpPcieRedriverPei +E74CA1E2-6E5C-4F07-9831-8367B132DB89,AmdPspDxeV2Rn +E74CCC19-BFF9-442E-9DA5-6A866262F179,DellCoreServiceHWIDNvs +E74E2F92-ED3B-435D-8A7D-BB29408E9B22,AfuCapsuleOnDiskPei +E750224E-7BCE-40AF-B5BB-47E3611EB5C2,TdxDxe +E7591211-2A96-4FD8-BB84-08387723DA26,PlatformVTdInfoSamplePei +E763F5EF-301E-6DEE-BBB7-A6EC553DCF7E,HpModernStandbySetupConfigDxe +E764500B-E398-4AB7-BBBC-99A8E683681F,MeSmbiosDxe +E767BF7F-4DB6-5B34-1011-4FBE4CA7AFD2,VlvMmioPolicyPpiGuid +E770BB69-BCB4-4D04-9E97-23FF9456FEAC,SystemAccess +E77217F1-8B8D-4973-94BD-C975794BC010,MarvellUndiDriver +E77E53A5-A5B8-45DC-BAEB-66C86F1AC811,RuntimeAcpiSmm +E7862AEE-A997-48F3-9C58-B79D340D003A,AcerLibMemBuffer +E7884BF4-51A1-485B-982A-FF89129983BC,BaseMemoryLibRepStr +E790848E-B6AB-44AB-8491-DCA50C3907C6,EfiIpmiSolStatusProtocol +E7980D88-35FC-4C20-8319-921A73C9A239,SioChip1InitDxe +E79A7050-8109-40D1-B3C0-2A3C74C40204,AGI +E7B2CD04-4B14-44C2-B748-CEAF2B664AB0,EdkiiPeiVariablePpi +E7B5B715-1183-4533-BE76-56A6D7CEB02E,AmiPeiPciEnumerationPpi +E7C35ABE-D48A-434B-BA22-0CFCC81DE631,OilBiosAssistantDxe +E7CCB2DB-C180-4B42-8604-4689A7F610AD,AmiCrbPkgTokenSpace +E7D62FEC-4994-4030-8B3F-AB4606A33350,SystemAcpiOA30Smm +E7D9CAE1-6930-46E3-BDF9-0027446E7DF2,Gpio +E7E1EFA6-7607-4A78-A7DD-43E4BD72C099,AppPkgTokenSpaceGuid +E7E96F88-017B-417C-8DC8-B84C2B877020,BaseFspWrapperApiTestLibNull +E7E9E21B-AA10-46F8-9E48-930D2D88F66B,FjSysmanAmphionSmmFjFext +E7F1DFF9-DAB6-498A-9ADF-57F344EDDF57,UfsPassThruDxe +E806424F-D425-4B1A-BC26-5F690389A15A,PlatformMeHookPpi +E807983E-D366-40C9-846A-0ED7E6022C96,DellTagsConfig +E80DE38B-6D52-48D5-8BA2-52828AEE6221,OhciDxe +E80F8135-5770-470F-AFAA-6B7B3CFB8A46,VlvInitPeimLate +E813E116-C099-4D21-9C34-A552D5E9A5D0,AmiPeiMrcDefault +E813FD31-D8CE-4DDF-8A9F-24D5CAC64FCF,AdlinkGetBoardInfo +E8145F46-B686-4068-A2FA-13A58CB38BE6,ManufacturingModeSmm +E81CC0AB-0585-8E1D-5BD9-59702FDA1FC4,OemBoardSmbios +E82F99DE-74ED-4E56-BBA1-B143FCA3F69A,DebugAgentTimerLibNull +E83C2C69-31E2-4557-A96F-0ADAB9EB7353,SmbiosDataUpdateDxeNeonCityEPECB +E847BD26-1DC5-4DE0-BF2F-254F61A5B4DA,GfxInitPei +E84AEF95-7CA6-4B2F-A398-B14D1C67A0B1,PchFlashControllerSmm +E84CF29C-191F-4EAE-96E1-F46AECEAEA0B,EfiTianoDecompressProtocol +E84D8EAE-0151-41F0-9874-2F838DB47106,PMBUSPEI +E8571188-00C1-4ED4-B14E-E38451351EC4,HddPassword +E857CAF6-C046-45DC-BE3F-EE0765FBA887,EfiS3SaveStateProtocolGuid +E859E40F-CC24-41B7-B5A5-685822AABCC6,UserApplicationBin +E862A2AA-299A-4A4B-B00A-AA7350FD6842,DellSecurityAuditDisplayDxe +E86C15A8-4D17-4E6E-AC7C-90905BA5EBE3,TransparentUnlockDXE +E883F269-3D02-4A88-9A11-E29076DCB73E,FjMfgChangeBootOrderDxe +E889C99E-EBE9-4BD7-2FCC-321610061E80,CypressCCG4Pei +E88A8180-16DA-4A1B-908C-3E517686F1FA,WifiProvisioningSmm +E88DB748-A947-46CF-AB6F-5C99B6C6C4B8,RealtekGopDriver +E8935638-7437-46BC-ADB5-3153820FD6CE,RTKUndiDxe +E894B313-54CA-4BB2-8CDD-851E8AC9027C,AmiDebugportHob +E89C977A-4547-4FBB-8E64-E1BE3CE39B34,CxlManager +E89EACF0-96F8-4CCD-89E9-968CD39F2317,BrightnessControlDxe +E8A0A79D-043F-4A36-93F2-6FA5C506E9FF,AmdPspKvm +E8A59290-A2AF-4099-B0AF-323FF9B7AB41,BeginBootButton +E8A9F123-07DF-46E2-9BF6-C593CAF06A62,HardwareHealthManagementDxe +E8C729FE-FB0A-4344-AD7E-48784116C9EF,SmmIpmiInitialize +E8C803DC-E9A9-4081-B21A-6FABA90992DA,H19SelfTestDriver +E8C887B0-6884-4933-B958-71EEBC5120DA,SECWDTDXE +E8DC00BA-411F-4D52-B925-50785436AC81,SmmSleepEvent +E8DCDF2D-0F9B-455B-90ED-A8CA5312B943,GpioV2ProtocolInitSmm +E8DDEB8B-82D7-4B6E-A2B4-D5EAEC2B8976,IrsiRegistrationRuntimeDxe +E8E1BAFB-12B0-4932-A481-DF93982C7AE4,SystemUsbHcLatchDxe +E8E2C394-A4B7-4583-8C43-CAEC15C34966,EmulatedEepromPei +E8F56FFE-919C-4CC5-BA88-65ABE14913BB,EfiEventNotificationTypeMceGuid +E8F64C63-03A3-40C9-AD3F-BC320F8505C3,PlatformFirmwareVersionInfo +E8F6A75C-3CDA-4B00-9837-8CA2A1F34EAC,SpsDxe +E8F8CCFB-E880-0361-BCD1-FE248B2A307E,SaveMemoryConfig +E8F9217A-73AD-4923-FFFF-FFFF1D270E05,XnotePlatformPolicySmm +E9008D70-2A4E-47EA-8EC4-72E25767E5EF,AmiBiosPpiFlaSManagementGuid +E904C5F2-AC68-46D6-AFDA-3A78D9F0CB8C,AmdNbioAlibDxe +E90A7B5E-37B2-43E4-B281-4C8E349045E9,ReFlashSmm +E923445E-2E1E-4642-8CB9-239320AA41E8,UsbOcUpdateDxeCLX64L +E92BAE14-3DFD-4C70-9FE6-3899F36C7846,PLEDSMM +E92C4950-A483-445A-B6A8-B7029CA910AA,PlatformStage2 +E9312938-E56B-4614-A252-CF7D2F377E26,AmiTcgPlatformPeiBeforeMem +E9357B87-3878-444A-A10D-6756B542EBE7,JpegDecoder +E938C9BE-CFC2-4A9D-A3CD-9653D8133009,AmiChipsetModulePkgTokenSpaceGuid +E9450086-16A9-4FD0-9136-BFD2FF478285,FjPcieWirelessWanSmm +E947CBDB-858A-423E-95F6-019D1814DE2A,AmdCcxZen3Pei +E94CD42A-3AAD-4EA0-9B09-945891C60CCD,DxeIoLibCpuIo +E94DB579-061B-437B-83C2-65C0AE7C14E2,LenovoAt24Rf08EepromDxe +E94F54CD-81EB-47ED-AEC3-856F5DC157A9,PiSmmCore +E954929C-5BAC-4494-B963-3B23D4A13AD2,QuiesceSupport +E9647284-02D5-4486-A34C-907F3D04BCA4,UsbS5Wakeup +E974833F-A4AE-4E39-BE37-8B6780DFAD01,Int15PanelFitting +E975314A-1464-411F-85E4-041D903CB6C4,DellSmBiosStrucFan +E98ADB03-B8B9-4AF8-BA20-26E9114CBCE5,EfiUserCredential2ProtocolGuid +E98E9C9E-DABE-4D3F-B02A-B3708BD784EB,FiopCcgFwUpdate +E9928F9F-5D3F-47BC-BFC0-F5190C69CCE5,NvmExpressSmm +E995D524-6B97-41BF-8CE3-D7C889742246,H19ReadBackDefaultData +E9987145-B05B-4787-B918-5BEB86C4AB6F,TamperEventS0Protect +E998C6D8-572B-4E18-96CC-031EA3DD558C,AmiOemCsm16BinaryGuid +E9A21859-002A-4751-8031-A0B5D13EF722,UsbPxeUndiDriver1 +E9A60F94-7A8B-45BA-9C32-3485526B5716,DellAcLossPei +E9B4B126-4E13-41F5-9E4C-9BF88B3C1B0C,KbdConfig +E9B53C0E-0491-4676-972F-9D15DD634DB3,DellBatman2Dxe +E9B60F94-7A0B-48CD-9C88-8484526C5719,DellSbConfigPei +E9B69E14-AE08-4459-8CF6-6EDD19A39DD5,AmdNbioIOMMURNPei +E9C5A905-6292-4E00-BEDD-DA6AF653138E,FjvProSupport +E9CA4775-8657-47FC-97E7-7ED65A084324,EfiHiiFontProtocolGuid +E9D7735D-06E2-47B7-B856-2A20138FAEA4,FchHuashanSmmInit +E9DB0D58-D48D-47F6-9C6E-6F40E86C7B41,PeiTpmInitializedPpiGuid +E9DD7F62-25EC-4F9D-A4AB-AAD20BF59A10,StatusCodePei +E9DEB2B3-88E4-46D2-B9A4-F60CACB918DC,SmcRiserCardPei +E9E59DF7-5D38-4097-90D5-8379E9A262EA,MsiSG +E9EC9168-1065-4F90-8C44-C1413AAAE43F,ODMAdminPasswordCheckVariable +E9F02217-2093-4470-8A54-5C2CFFE73ECB,EfiSpiSmmHcProtocolGuid +E9F05D70-9946-4AB9-A7F7-070E92C415BD,Int15BootTV +E9F4B929-EE33-4B70-8E90-17D283AF508C,LibSoftfloat +E9F8B700-7E13-4736-88DA-82624ACDECDD,SystemInventoryInfoSmm +E9FAA8A9-40B8-4C6F-8C62-CBC4D532055C,PcdRecoveryRestoreData +EA067D5D-56FD-4B00-B79A-352AFF8F2BD6,UpdateSmbiosType41 +EA0FE3E2-F515-467C-87F7-C32923DE541E,AmdLegacyInterrupt +EA1207EA-7E61-4269-B558-C38FC0B79A80,XhciPei +EA1343AE-BA6C-4059-BE74-024D36D7AA3F,LEMBootModeFlagPei +EA1D58A2-EA3D-4C14-928A-80A14545E681,WheaPlatformBoot +EA296D92-0B69-423C-8C28-33B4E0A91268,PcdDataBaseHobGuid +EA2E8235-37BD-4FFD-8571-556D4AAE3ED8,UsbTypeCSxIndicatorsSMM +EA2EC402-2FD5-475F-922C-98EAE0376312,SystemLegacyBiosDxe +EA32C776-6C14-41F4-80C6-0349E9E48AF8,FvbVariableStorageSmm +EA343100-1A37-4239-A3CB-B92240B935CF,SdioSmm +EA34FEA6-EDA4-4A3F-BE0C-9BE1859D4621,AmdMemSmbiosV2StxD5Pei +EA353BAD-99D2-4BE6-9B28-53A8E8596934,Armani_BatteryHealthControlSmm +EA382BBC-192F-4883-9F30-CFA4A558362A,OemUsbPortMapPei +EA42B5E6-5E01-4C6E-8189-C1EFA6ACFD01,LenovoProtectPBPei +EA449C41-8236-4B97-9FF9-084E4BA70020,ProgressBarEmptyMiddle +EA4B0675-1F36-4ABE-BB3A-6D60760A02A2,AmiPciPortCompatibilityProtocolGuid +EA4DAEE8-A851-4A9F-ABF4-B79FA2528291,CpuSmbiosDriver +EA5145F0-8F09-11E4-BA47-3C970E61ED65,OemNvsDxe +EA57EDAE-5294-40FF-97E8-4652E83D9F5C,FjGraphicsDxe +EA5D72C1-4455-4FF8-91A1-4352DC1EE112,gear8 +EA629472-D7C6-4C0E-8820-2B811C7EE3AF,AmiTseOemPortingVar11 +EA6363DF-207E-4544-BC9D-1C440C1DB0BC,SlotDataUpdateDxeCLX64L +EA67CA3E-1F54-436B-9788-D4EB29C34267,Early16550UartBaseAddress +EA6D974D-AD75-40ED-BCDD-FDA297AA8F8A,ChipsetLibServicesDxe +EA7BF2CC-F154-4CC4-A725-6382C701FBFE,AmdMemSmbiosV2RvDxe +EA7CA24B-DED5-4DAD-A389-BF827E8F9B38,EfiPeiFirmwareVolumeInfo2PpiGuid +EA7D60A6-1050-45E4-BEDF-BF177290D4B2,EfiEmmcBootPartitionProtocolGuid +EA7F0916-B5C8-493F-A006-565CC2041044,FspS3Notify +EA816D2C-CEE5-4F02-99B5-D3905CBBD077,EfiHiiNewProtocol +EA8D05BC-E348-4B75-BF6B-92E6B1E98068,HQDxeService +EA907DA1-4A74-80B8-A66E-BAA384223E12,DellBiosAttributes +EA94D9D6-BE8B-4BD0-9481-B04348165CFB,AmdPspSmmV2Ssp +EA9D0ED6-A18B-4052-B526-6A94F44D5170,FvbReady +EA9E92E1-22EF-4B5F-A5EE-1317B1E77B10,PhCiraHotkey +EAA006CD-3256-789B-BD20-EBABCD02583F,SecureFlashPei +EAA5A822-EACE-488B-B187-11ABC8E72E69,AmdMemS3BlackListPei +EAA96391-9BE3-4488-8AF3-B3E6EFD157D5,EmuSecPei +EAAF7109-EC2D-4A30-BF4F-621408630E4C,FlashOemHooKSmm +EAB17499-7B0C-459C-BD4A-772CFF1B80A8,FchPromontoryPlusPei +EAB5F9D8-4CEB-4EFA-87D3-FA155D317B22,MipiCam +EAB843A9-D414-41BB-87A2-6C2952DFA2EC,GpioCfgPei +EAC3AED9-692D-4C7C-A25D-3895C4F398F3,DellCustomVbeSetting +EAC9599C-2D94-4886-8F6C-D7A88B5B483A,N17MQ3Gop +EAD039A6-7390-411D-A9DE-E5294B25B897,ASUSEZFlash +EADD5061-93EF-4CCC-8450-F78A7F0820F0,Tcg2ConfigPei +EADEC90E-C2BE-4B96-A161-55236822C0BB,AdlinkBSCDxe +EAEE5615-0CFD-45FC-8769-A0D85695AF85,EdkiiNonDiscoverableEhciDeviceGuid +EAF100CB-ABF4-49E0-97E5-5E0A7750DCCB,EcSecuredTransferSmm +EAF18DB2-FBFD-4E50-8E77-AAC8191628B5,AmdSocFp8StxKrkPei +EAF59C0E-BD46-413A-9AE9-DD9F6D1A927D,SmbiosDxe +EAF9E3C1-C9CD-46DB-A5E5-5A124C832323,EdkiiSdMmcOverrideProtocol +EAFA9C29-D84E-42BF-B19A-6D9734EF4ABB,HpJpeg +EB00DB50-C654-460F-8D7A-0E444FD32B45,DebugMaskPei +EB079C68-0B05-4A53-B8D5-01C995D66A23,AmdMemPprSmmDriver +EB098808-8FC1-4FB1-AB66-26784633B745,UltraFunctionTable +EB12FD12-42EA-4A72-A05E-4EBD04618477,CbsSetupSmmSHP +EB1BF7E8-D4AB-43C6-88C4-B99175350383,Dec1515Pei +EB23F55A-7863-4AC2-8D3D-956535DE0375,EfiIncompatiblePciDeviceSupportProtocolGuid +EB317729-1FAA-4931-BF83-31EDBDF61E99,ErrorControl +EB338826-681B-4295-B356-2B364C757B09,EfiFtp4ProtocolGuid +EB346B97-975F-4A9F-8B22-F8E92BB3D569,EfiSmmCpuProtocolGuid +EB3FFEAD-45F6-4A18-AC71-C4EE97B26119,KbcPeim +EB5198EB-E7F5-45A1-9CCB-E53364BB4992,AmiSmmInfoProtocol +EB53FCAD-3071-4BAB-980C-6E4A379255F3,RealtekUefiDriver +EB5E4685-CA66-4769-B6A2-26068B001326,EfiPciDevErrorSectionGuid +EB5FC7A5-3747-4A25-90DB-631297A0A0AF,BoardInfoPeim +EB61D625-1B5D-4F45-A2A0-931EF7280B48,SmartAssetTagInfoDxe +EB66918A-7EEF-402A-842E-931D21C38AE9,EfiRtPropertiesTable +EB6B71C3-0659-4A8A-8AE1-DAD2F5192C62,BootMenuApp +EB6EEBF4-1EC3-4D69-9D82-65BF6C579B34,LenovoSecureKeySmm +EB704011-1402-11D3-8E77-00A0C969723B,EfiMtcGuid +EB740091-A494-44D7-8D96-C192F95A6394,OobTx +EB742231-AA20-4A04-A879-89D80854B266,SmbiosType11 +EB78CE7E-4107-4EF5-86CB-22E8D8AC4950,DellSmmAsfInit +EB832FD9-9089-4898-83C9-41618F5C48B9,DpHii +EB84A9E4-288F-4637-AC61-6D3966EF6179,DellRecoveryDxe +EB8DCCDA-D34D-4765-B989-ED96CA2CA8D5,OemSwSmiDispatchProtocol +EB97088E-CFDF-49C6-BE4B-D906A5B20E86,EfiAcpiSdtProtocolGuid +EB98A90A-42EE-4A36-8DCC-AFA722C9CAB3,AmiTcgPkgTokenSpaceGuid +EB9D2D2F-2D88-11D3-9A16-0090273FC14D,EfiMpsTableGuid +EB9D2D30-2D88-11D3-9A16-0090273FC14D,EfiAcpi10TableGuid +EB9D2D31-2D88-11D3-9A16-0090273FC14D,EfiSmbiosTableGuid +EB9D2D32-2D88-11D3-9A16-0090273FC14D,EfiSalSystemTableGuid +EBA4E8D2-3858-41EC-A281-2647BA9660D0,EfiDebugPortProtocolGuid +EBB2898D-2168-48C1-936C-64C86EB6424B,UsbPxeUndiDriver2 +EBB32EA2-6382-43F3-955A-39475AE6E1AB,UefiRaidPei +EBB6653C-D182-4E9B-BC73-947A291F7740,AdvBootIhisiSmm +EBBD7E6A-37D0-417A-9410-D19A59BE349F,DellBiosVersionNameDxe +EBBE2D1B-1647-4BDA-AB9A-7863E396D41A,EfiActiveBiosProtocolGuid +EBC01AF5-07A9-489E-B7CE-DC089E459B2F,EdkiiUfsHostControllerProtocolGuid +EBC065D8-BEFA-4437-BED0-9A41272102F1,RestBoot +EBC3AEAD-CC13-49B0-A678-5BED93956955,BasePlatformHookLibNull +EBD11F37-177E-4216-A98E-56C77ADCEABE,XnoteFlashCommunicationDxe +EBD705FB-FA92-46A7-B32B-7F566D944614,SP805WatchdogDxe +EBDCA8B2-8185-4AFB-9EA3-182C2DFC231A,SmmSvcCallback +EBF342FE-B1D3-4EF8-957C-8048606FF670,SetupBrowserDxe +EBF342FE-B1D3-4EF8-957C-8048606FF671,SetupBrowser +EBF8ED7C-0DD1-4787-84F1-F48D537DCACF,DriverHealthManagerDxe +EBFA847C-523B-46F4-BB7D-C51EFFD1994C,FjMrcOutputInterfaceGeminilake +EBFE50DA-14AE-4E5F-9E21-ADB76B320541,AppleMcaDumpDxe +EC02A9CA-091D-47CD-AF28-77D38DED7A53,MebxConfiguration +EC1CD13C-5656-4D2B-8532-974CC030EF1B,BiosGuardUpdateProtectRegion +EC20EB79-6C1A-4664-9A0D-D2E4CC16D664,EfiTcp6ServiceBindingProtocolGuid +EC2A6C28-2286-44ED-916B-243AB5253546,SLP20MarkerVariableGuid +EC2BD1FD-E3B0-429B-ADDF-9657935A3684,AmiSmmNvmeCommunicationGuid +EC2BEECA-E84A-445B-869B-F7A73C96F58A,LegacyRegion2Dxe +EC2E931B-3281-48A5-8107-DF8A8BED3C5D,PlatformGOPPolicyGuid +EC2EAB61-EFB5-4A80-8391-8779C1C2507A,PlatformSecureBiosSmm +EC359751-1DB5-4E8A-B2E9-7BA1FE9A9168,FmacDrv +EC35E25B-0425-4435-A34C-96D75703B893,FjEndofPeiGPIOOverride +EC386589-999F-472D-8905-CAA5332F642A,H19TextColorsHook +EC3A978D-7C4E-48FA-9ABE-6AD91CC8F811,EfiKmsProtocolGuid +EC3A9E6F-9691-4D84-B00D-3E55472807EA,AmdFabricRplPei +EC4B60B8-E4A6-4293-AD72-49C6FADD10F7,PlatformDebug +EC4EBACB-2638-416E-BE80-E5FA4B511901,UniversalPayloadPciRootBridgeInfo +EC512283-DAE2-48D7-ABB3-95C1AD78B596,NvdimmSmbusCommon +EC52188F-8DD1-4834-AADB-C66187D460EC,AmdNbioSmm +EC5A555B-6384-4C00-8625-2C1768B95B38,LenovoMeConOutReady +EC63428D-66CA-4BF9-82AE-840F6D5C2305,AmiBoardPciInitProtocolGuid +EC6654E5-150C-4185-BEBB-E8E5CF0763B5,LenovoTpmConfigSmm +EC69A5FC-83BE-43BB-87F7-4B07E314E7C0,AmiErrorDisplayFrameworkProtocol +EC761DAF-6B86-41D0-8294-350B90FC9478,SystemCapsulePolicyDxe +EC76B3B4-6821-4D4B-A0AB-D28CC27AC439,AmdSmmControl +EC7F4FA1-B217-42FC-A7F7-020C4305D5BA,EfiSmramNvsHeader +EC835DD3-FE0F-617B-A621-B350C3E13388,EfiIp6ServiceBindingProtocolGuid +EC853378-008D-4E10-BDDF-E13FEC491B23,PowerReportSmm +EC87D643-EBA4-4BB5-A1E5-3F3E36B20DA9,EfiSetupVariableGuid +EC8A3D69-6DDF-4108-9476-7337FC522136,EfiKmsFormatGeneric128Guid +EC9519B1-E788-4C45-B695-244457442D64,PeiSmmControl +EC953378-008D-4E10-BDDF-E13FEC491B23,LGPowerReportSmm +EC953378-008D-4E10-BDDF-E13FEC492C54,LGEcCommunicationSmm +EC98FF95-242C-4513-B1BC-69FA24111C58,AcpiDebugDxe +EC9C36FD-1642-4B84-91FA-919C2D066FB4,AmiPeimLoadHob +ECA08963-33A3-408C-8FDE-7E67A51F45AB,D01UsttCallback +ECA27516-306C-4E28-8C94-4E521096695E,DxeSiPolicyProtocolGuid +ECA2AE9E-7594-4901-871C-449DA1A11660,I2cDxe +ECADBBB6-B0AE-4571-94E3-313C3D27A611,AmdNbioGfxRNDxe +ECB54CD9-E5AE-4FDC-A971-E877756068F7,EfiPramConfGuid +ECB867AB-8DF4-492D-8150-A7FD1B9B5A75,AmiSmmFlashProtocolGuid +ECBCA4B6-34C3-4829-8262-5A5795C325FB,AmdRasBrhDxe +ECCBF582-EEE1-45B8-8926-067F40B3E55E,LenovoIsscPei +ECD81473-0533-4844-BC77-48F0DE27519B,DellSmBiosStrucD8 +ECDEEFD2-C596-4CB1-AFDF-6506F6C7CE2B,D01VariableLock +ECDEFE8B-F2C9-4E9E-9C0E-066F2AD36B5C,Amd3rdPartyDxe +ECEB5BA3-F44D-40A3-A21D-6CBF147FA92F,N19M_GOP +ECEBCB00-D9C8-11E4-AF3D-8CDCD426C973,HttpBootDxe +ECF149B5-BF4E-4AC8-8A8C-CE87CBAC93D3,EfiSiliconRcHobsReadyPpi +ECFD4BCE-4279-40F8-BAF2-DCB79638D41E,AmiTseOemPortingGuid1 +ED01E769-0B97-48E1-99EA-DF144BD2FF32,OememPeiSSID +ED097352-9041-445A-80B6-B29D509E8845,PchDmiTcVcPpi +ED14D1A8-9DCB-4C0F-917C-DB0BFB56BD24,KEMrCPLDDxe +ED150714-DF30-407D-B24A-4B742FD5CEA2,DuetConsoleOutConfigGuid +ED17FA2D-609A-4E8D-99F6-9C0CBBDD8C2F,TbtPei +ED1D807E-9A5F-436A-B8AA-D78ED9E7D92C,DellNumberOfPStateProtocol +ED2DE537-7823-4CB1-B687-85BA9BBEF0B4,RaidRom +ED32D533-99E6-4209-9CC0-2D72CDD998A7,EfiSmmVariableProtocolGuid +ED3F1E9D-2320-4B37-9119-E928C1E6323B,BctBaseSmmSHP +ED443008-3F06-46DB-927E-7AB2F02AF9D9,ApplePciCameraDxe +ED4F0AA6-B02B-4539-BF51-C9E114E0FE7F,DeviceFwServicePei +ED4F127B-45B0-4B44-88E9-0D7EF1BE98A0,FjSysmanYggdrasilSmmPowerOnTime +ED507E91-AAEB-4220-A2B2-1CFB4DC7223A,OemMS +ED52984E-6ED7-4445-9D5D-200C3201F51E,PlatformStage0 +ED6E0531-F715-4A3D-9B12-C1CA5EF698A2,IntelFsp2PkgTokenSpaceGuid +ED705681-1649-4BBB-8091-E36F52523761,StandbyImmediate +ED73A77B-8AB0-4272-B7B8-E25311366FBF,AddrDecode +ED769C37-F526-444A-8D70-249BEFF04948,L05UpdateSlp20 +ED815341-E67F-46C4-9DED-AA14222803C4,WakeOnLanSmm +ED888C65-2D84-4595-9086-A15A1F66DE2B,EnableLsiDecoding +ED8B5E2B-6622-4D14-9069-9BDEC54C9491,TcgPwdTseHook +ED8DCDD5-D037-4B1F-98DD-BDFDAD4DD7DD,BatteryState4 +ED8FD9DC-2097-425E-B743-64EFB99D5F0D,AmdPspDxeV2 +ED92EAE0-C31C-4824-8802-35595EFA8287,WpbtDxe +EDA2B104-7A10-4519-B0A1-EBA5C52ACFCE,AmiTseOemPortingVar1Guid +EDA39402-F375-4496-92D3-83B43CB8A76A,SmBiosMemory +EDA3DFD4-83C8-4E09-AF09-56C417FD3CC9,SetupConfigUpdateDxeEldorado +EDADEB9D-DDBA-48BD-9D22-C1C169C8C5C6,CpuMpPei +EDB396E3-2DDC-4396-BCA5-1202D3005AEA,Tcg2PhysicalPresenceDxe +EDB90543-661B-4CBD-9278-D88B4C608BE9,DellIntrusionDetectDxe +EDBEDF47-6EA3-4512-83C1-70F4769D4BDE,Capsule_A_fvi +EDBF5904-491A-4363-A56E-FF573DE56A70,EmulatedEepromDxe +EDD33148-A91F-4257-84A8-2F2976CE79AF,LGPowerReportDxe +EDD33148-A91F-4257-84A8-2F2976CE8ABE,LGEcCommunicationDxe +EDD33148-A91F-4257-84A8-3A1A76CE8ABE,LGBdsFlowDxe +EDD35E31-07B9-11D2-83A3-00A0C91FADCF,BootObjectAuthorizationParmsetGuid +EDD70CFF-6236-4FE0-A698-8436B4A3E0A8,SingleCapsuleDxe +EDEBB2D8-CB7D-4A50-B7AA-B4DFFB179A8A,MemoyConfigChanged +EDF13B99-4EF3-4C9B-9FAE-4DE2D6381906,OverrideAcpiTable +EDF52A90-A34C-47A2-832A-9308112CAE38,AmdDynamicLid +EDF704F1-2675-4019-9258-6F0F6C677D95,DellWdtFeatureSmm +EDF8DA40-AAD1-11DF-A1F4-0002A5D5C51B,PL341Dmc +EDF904D7-4109-1562-DAB9-0083159E882B,HpCommonSmbiosDxe +EDFD1E22-C6BF-4B06-A4B2-5AE050C84A37,USBControllerSmm +EDFE3817-8661-42B2-A3F6-948FA7AEA20B,DxeThunderbolt +EE003542-F156-4927-8455-F6762052E32F,SiInitDxe +EE0BFF80-2B33-4005-8EF1-3F9B23C25136,GetCpuInfo +EE0EA811-FBD9-4777-B95A-BA4F71101F74,PeiHeciPpiGuid +EE16160A-E8BE-47A6-820A-C6900DB0250A,EfiPeiMpServicesPpiGuid +EE1BB93E-54C5-4B17-9496-A20085950561,SmmUsbDispatch2OnSmmUsbDispatchThunk +EE1DF00B-B4FE-4762-A330-1E8AB4D9149D,ExtfTable +EE21FDBC-CA29-4CD8-8BDC-90070505668A,PerformanceControlSmm +EE257F8F-E710-4181-9B01-C06698454A16,AmiPlatformInfoCompressedFfsSection +EE28FF61-B960-47EB-B6BA-1F5EFBDAB442,OemTpmTypeDxe +EE2EA7C3-274A-898D-90D3-46BED34AAF61,GpioControlDxe +EE2F2CA1-911D-44AE-97D8-AB313758B025,DellMfgDefaultsDxe +EE2F45D2-5BA4-441E-8A1D-AA22DFA3B6C5,RomImageMemoryHob +EE30FD26-1524-4CA2-B56D-345830DC9CDB,LenovoFingerprintCp +EE31EE7B-07B8-48C5-8F3F-C42A700E0432,AAEONCH7511Pei +EE3A7F7F-3881-4EA2-B38F-5D9C98DB4AF1,FjSsdtDxe +EE4CD885-D104-4056-84BA-461882A72A18,PrmHii +EE4E5898-3914-4259-9D6E-DC7BD79403CF,LzmaCustomDecompressGuid +EE54D4EA-B2AD-437F-860F-1AB9685237E9,DustFilterAlertSmm +EE685731-CFF3-4EE7-9388-7E63FC5A59B0,PlatformEarlyInit +EE69C4B7-7C9B-41BB-B44B-748137E7B5BC,FjKbcSmm +EE7144BE-6454-4743-9D23-5DD8DFEA5B5B,DellSmmAcpiProtocol +EE8175EF-4C60-82AF-F5E2-8A9EF1FC0A9A,AmdRasSspSmm +EE8367C0-A1D6-4565-8F89-EF628547B722,IpSecDxe +EE847BE1-DBC2-47C7-8696-79501CC3E24E,8042EmulationProtocol +EE89F590-A816-4AC5-B3A9-1BC759B12439,VerifyFwBootGuard +EE90D8FC-6181-4B15-83C4-7D1CA0C36E2A,DramTweakerDxe +EE911B88-39E3-4F56-B94C-64FFF5B53A3B,AmdCpmABRecoveryPeim +EE993080-5197-4D4E-B63C-F1F7413E33CE,CpuDxe +EE9B8D90-C5A6-40A2-BDE2-52558D33CCA1,EfiSmmUsbDispatch2ProtocolGuid +EE9E0D09-51B9-4537-AA64-3BD74C5FBFDF,OemDPTC +EE9F26FB-D6DE-4FD3-9720-DC6CD3E337C1,CrisisMemoryInitPei +EEA190F0-962F-11E0-AA80-0800200C9A66,SctMilestoneTaskEntry +EEAE874B-64D3-4323-B582-545FB3C2EB5A,SmmBbsManagerInitNotifyProtocol +EEAF2AD6-2A6B-449E-A116-3ADD82CADE27,EcBlinkDxe +EEC25BDC-67F2-4D95-B1D5-F81B2039D11D,Enter_Setup +EEC9BC9A-2907-4D59-8B86-D1EC67DE62E1,GenericMemoryTestDxe +EECC1363-884B-4FE4-A763-B387951B6DDD,SbSocMatisseDxe +EECE5260-9E1F-4F74-9DBB-508257CBAAD1,LifeCycleState +EED54281-1C11-4358-BF5A-F64995FBF11B,FmpDxe +EED5EA31-38E2-463D-B623-2C57702B8A1C,SectionExtractionPei +EEDFD470-449A-4B15-8038-C85487AF5E4C,HpCommonFlashInfoDxe +EEE00707-6734-491B-ADB3-C168265AB5B5,DellUsbMassStorageSmm +EEE07404-26EE-43C9-9071-4E48008C4691,EfiWheaSupportProtocolGuid +EEE4417A-D34E-40B1-9483-1BF62BD113CC,SystemFirmwareDeviceDxeSmm +EEE4E585-0585-4091-A89F-CAB51F6FCF3E,FchYuntaiPei +EEECC312-FF36-4E21-9C5F-0B208CDC02FA,FjDTPMAutoConfigDriver +EEEE611D-F78F-4FB9-B868-55907F169280,PlatformInitPreMem +EEF749C2-C047-4D6E-B1BC-D36EB3A5559C,QuarkVariableLockGuid +EF02529C-A283-48CD-8D08-6A1E9C3C03D3,AmiTseOemPortingVar18 +EF074CB0-701A-4975-81C1-38F9212BD089,AmdMiniRasServiceDxe +EF0C99B6-B1D3-4025-9405-BF6A560FE0E0,SmbiosMiscDxe +EF0D2ECB-AE7B-4ED2-8848-F39290D19322,StatusCodeLoggerSmm +EF0E795C-749A-4B41-B994-7DDC6B594388,UsbOcUpdateDxeNeonCityEPRP +EF14FD78-0793-4E2B-AC6D-062847E01791,MfgModeVariableGuid +EF152FB4-7B2F-427D-BDB4-7E0A05826E64,BootFlowVariable +EF155E93-2CB4-4A72-8720-8B447A91F540,AmdSocFp6CznDxe +EF17CEE7-267D-4BFD-A257-4A6AB3EE8591,MemorySubClassDxe +EF183CE7-7ED5-4E29-BCDA-524182B4744B,AmdNbioGfxRPLDxe +EF22F8A9-267E-4840-BC32-F0CFDFDFA426,PeiSmmControlPei +EF2331AD-7010-436C-B90E-2CB3536404EF,SioSetupUtilityDxe +EF251B71-CEED-484E-82E3-3A1F34F512E2,EfiQuarkSCSocIdTokenSpaceGuid +EF2961F9-87D0-4E9E-A3B1-B14FFA8D347C,FjUsbTypeCPowerLimitDxe +EF2B91D1-1847-4D88-9115-2835A0BEFBDC,MpmPei +EF33C296-F64C-4146-AD04-347899702C84,SystemSmmUsbLegacySmm +EF3468E0-1B0A-46D7-842C-928E67EFE0B8,X11DPHPeiDriver +EF351864-16F3-4A2F-B57D-3B9B785A6248,AmdCpmSocAm4RvPei +EF398D58-9DFD-4103-BF94-78C6F4FE712F,EfiPeiResetPpiGuid +EF402953-B819-4CC2-A44C-4C9B4CFBC889,AmiTseOemPortingVar2Guid +EF48FFE8-9E24-4EB8-828D-2EC11A9DF8DD,DellGenerationIdPolicy +EF52F4D8-4B2E-4A2D-B888-DAC5421D73F7,AsfSmm +EF598499-B25E-473A-BFAF-E7E57DCE82C4,TpmErrorHobGuid +EF6619EE-F77D-4A8C-8693-D60D6AA56702,SetupSecurity +EF7BF7D6-F8FF-4A76-8247-C0D0D1CC49C0,EfiSmbiosSlotPopulationGuid +EF86A49E-CD3C-445A-878E-7A738D2C7ED2,BoardSpiBusSmm +EF95CFE1-0D3A-4869-948B-FC36A3B13901,BoardSpiBusDxe +EF96596D-F1D8-4B76-8ABE-700E03C1CA74,HspAcpifTpmSmm +EF9A3971-C1A0-4A93-BD40-5AA165F2DC3A,ConsoleOutDevicesStartedProtocol +EF9A853E-2DF3-48ED-91E5-6232668C4DB1,CbsSetupSmmPhx +EF9AEFE5-2BD3-4031-AF7D-5EFE5ABB9A0D,PeiLockPhysicalPresencePpiGuid +EF9FC172-A1B2-4693-B327-6D32FC416042,EfiHiiDatabaseProtocolGuid +EFA96432-DE33-4DD2-AEE6-328C33DF777A,EfiHashAlgorithmSha384Guid +EFB7F614-BC8B-4DDD-B09A-22079FC1512F,TbtDxe +EFC41654-87AD-461D-A5F2-D79B0C01C31A,DellWmiBiosAttribSmm +EFCB058E-8BDC-4062-8DAE-8262886C512B,Tcg2Dxe_ +EFCB2FDB-0662-4A59-A5D7-03033EA97CAE,GTSE +EFD652CC-0E99-40F0-96C0-E08C089070FC,S3Resume +EFDCAE58-13E2-4BEC-9AED-992C8DCBDD9E,FjTriggerMebxDxe +EFE67B1B-BC77-4BB9-A570-7F8DD858506D,ICE30plusPEI +EFE92A04-F5D0-4E44-8757-25B3AFA3BFFF,RSTeSataRaidEfi +EFEEF8BC-12B5-432A-B5AD-E5D5F5B33459,UsbTypeCPrivateWmiSmm +EFEFD093-0D9B-46EB-A856-48350700C908,EfiHiiImageDecoderNameJpegGuid +EFF9400A-AD95-475B-868F-C7AFC313BA72,AmiPeiCreateDummyRcHob +EFFC8F05-B526-4EB5-B36B-8CD889923C0C,LegacyRegion +EFFFCCC2-7D6A-42B1-AD6D-61B882801AFF,PxeDriver +F002485F-B0B6-4C3A-9E7B-54FABD83074D,EfiPlatformTypeLightningRidgeExecB2Protocol +F00497E3-BFA2-41A1-9D29-54C2E93721C5,EfiStandaloneSmmNonSecureBuffer +F0049EF2-FF2C-43A7-A308-B02421A3A69A,BmcSmbiosDxe +F00D1083-A096-452B-A2A9-47EAF7C4A09C,BbSecDataUpdateSmm +F00FD1CF-2FBF-4096-A882-7E7B8FD80BD5,SelfRepairApplication +F01872BF-AF48-40D2-92DB-51588466EEAB,RtkUsbUndiDxe +F019E406-8C9C-11E5-8797-001ACA00BFC4,BfbFs +F01BED57-04BC-4F3F-9660-D6F2EA228259,EfiLegacySpiFlashProtocolGuid +F02313F7-581F-4F31-B09C-C1BA2FC58713,HpDriveWipe +F02313F7-581F-4F31-B09C-C1BA2FC58714,LoadHpDriveWipeDxe +F023E844-257F-47CA-8C25-CD91C5B047F2,AmiSerialUart1 +F035B9D5-744F-4FCB-9283-BAB4FAD9FAE8,FjBeepIfNoGraphic +F035F3BD-863E-4573-A609-BB9405A8B1F7,SystemSecureVariableStorageSmm +F0384FFD-8633-452F-9010-F6B7D2EAE2F1,WinNtFirmwareVolumePei +F04C91FD-5AEB-45BD-BE71-65435904C568,AmiMultiPlatformPpi +F05976EF-83F1-4F3D-8619-F7595D41E538,EfiPrint2ProtocolGuid +F064B9E9-F12C-4456-8DD7-E073B0A667E9,RtkManagementSetup +F064C91F-188C-4F56-B7FD-30A9B86A29F3,EfiCpuTypeFru +F06509E9-9AE9-4463-A24C-D8E35E9133AA,TypeABh +F0657E90-216A-4C30-B69B-DED96267BC29,OemThermalPolicyPEI +F084FF45-F9FA-4E9E-8DFF-E2D780D22CC2,EfiCpuRasProtocol +F088BB30-DA92-4BFF-ABBC-73E42177A43D,DellSataPortNumMapPolicy +F088CD91-A046-11D2-8E42-00A0C969723B,EfiVariableStoreProtocol +F08FC315-CC4F-4D8C-B34C-B030C4E7B919,EfiCrystalRidgeSmm +F0966B41-C23F-41B9-9604-0FF7E111965A,EdkiiPlatformHasAcpi +F099D67F-71AE-4C36-B2A3-DCEB0EB2B7D8,WatchdogTimer +F0A30BC7-AF08-4556-99C4-001009C93A44,EfiSecureBootEnableDisableGuid +F0ADC5A7-F86A-45A5-9D16-37323FCD77EE,SmcPostMsgHotKey_SMM +F0B79D0F-CE2B-D148-9ACE-F204E9393CAA,Tcp4 +F0BBFCA0-684E-48B3-BAE2-6C84B89E5339,EfiPchExtendedResetProtocolGuid +F0CA1CCF-4E60-496A-890F-E78FCA1C1D6B,CheckOemOSType +F0CFE5EA-895A-4C18-BE2A-80FD85BB8299,UwbSmm +F0D7222F-FD43-4A5D-B8BF-A259C87AE3B2,FlashDeviceLibDxe +F0D8DEAA-C495-4139-B1FC-78B70168260A,DellDxeDiagLeds +F0E6A44F-7195-41C3-AC64-54F202CD0A21,SecureBootConfigDxe +F0F1588E-9028-4EB8-8031-F233B48EA0B7,PxeDummyDxe +F0F1C259-FD3A-446B-B2F2-049334D1BD23,AmdSocAm4CznPei +F0F6F006-DAB4-44B2-A7A1-0F72EEDCA716,AcpiPlatform +F0FFF864-8454-46E5-9F2B-CF14F0A41A48,WarmBootSmm +F100061D-A26E-4790-8BE3-D41F364D85A9,WmiSetupUnderOsSmm +F1039C39-9299-41FE-8799-5EAFB668EE6C,AmdRasRnApeiDxe +F103A5A5-9345-4C3F-B496-DA14F41B6269,PlatformStage1 +F109F361-370C-4D9C-B1AB-7CA2D4C8B3FF,AmiCpuInfoProtocol +F10CF621-1502-4130-A860-D300459E2C08,MEbxInvokeDxe +F10D6C2A-A2D6-4D96-A212-2B4F6005F389,LenovoSecureBootConfigDxe +F110703C-9D16-40CA-250A-2700CA534F87,DellMfgBootListConfigSmm +F1143A53-CBEB-4833-A4DC-0826E063EC08,MeRegionUpdateVolume +F11721F9-1A68-4FEB-BB25-55B6F7A1AE74,LEMProgressBarProtocol +F11757E2-1D21-47BB-9E07-04C60DA00ECA,UnexpectedIrqWA +F122A15C-C10B-4D54-8F48-60F4F06DD1AD,LegacyBiosDxe +F1297746-69D5-4013-84CC-0FEB09CCD5C3,PlatformInfoBootMsgDxe +F12DF3A4-6A2E-44BD-A3F9-2135A04E19E2,AsusEcPeiBiosReady +F12F698A-E506-4A1B-B32E-6920E55DA1C4,TpmMmioSevDecryptPei +F139BD77-7FF7-49D6-9086-D50AB26F6DD7,EfiSvSmmProtocol +F140088A-05B0-46E3-83FF-D5A69B7C7185,SioIt8669eDxe +F1448205-61B4-4624-B325-6C06BB1BC90B,SioFlexIoAcpiDxe +F149AE6A-1252-49A8-94FC-A2DDF5DCCF5D,AsusWatchDogTimerSmm +F14F7AC4-F736-4AFE-B01A-129B1FA13A5D,AplPreMemNvram +F1530049-1292-4D78-9F26-D3D59D17E5E4,LenovoEcEkKeyDXE +F1577E74-CAAB-41C8-9E26-F11EEBB6C83D,SdMmcDevice +F15B92A8-6B4C-4EA3-A380-2F352AD15417,RealTekLanDriver +F16BDBF0-3A61-11DE-8A39-0800200C9A66,PerfTuneDxe +F16F8948-F81F-4F30-91A6-8F2F0FD57882,MAPS_SIO_InterfacePei +F174D532-D257-4FE0-92A3-B664E8BBC8ED,HpCoreErrorCodeHandlerPei +F179D6C8-1FC4-4C39-AC83-F1077080D070,FjMfgDescriptorUnlockDxe +F1809E8A-ACB8-4176-8CD4-B98414D0FD0D,ApicInfoDataDxe +F18BA2F3-053D-408D-9E28-96CDA65272A8,FfsIntegrityCheckPei +F19071B5-B2F6-4A9C-B2E2-FBF56DA5B229,AmdMemChanXLatZpPei +F193C257-3CB5-4D90-A694-2E371082E116,UpdateSerial_NUM +F1946499-571B-44C3-9B9C-CC55210B0C02,H19WMIHandlerSmm +F19B5EA5-7CDF-4CB2-9C37-F1BE08AC588B,BroadcomGigabitEthernetDxe +F19E8ED6-442B-4194-AF8E-C91435E36320,SmcTpmProvisionDxe +F1A18726-FD79-4DF5-A326-E20B8CC46B06,DellBootScriptSmiHandler +F1A25221-A98B-4189-85F2-0BA226A370DA,FTP_DXE +F1ADE5E1-230A-4573-A2BC-56F949BC9C3B,UpdateDsdtCrc +F1B4C587-6E35-4FAB-B946-FAE259638660,FjGabiFlashBiosRegionCtrlDxe +F1B52F57-16A6-4922-B81D-65838458FAB4,OemMfgPorting +F1BDCEC7-31D1-4F0F-AF62-D02A44076026,LenovoN25Q032FlashPartDxe +F1BE4604-24B3-4DA5-8BBF-E87A6C046C93,CbsSetupDxeMDN +F1C50D3A-58E4-4104-9176-00CDF8BC4BB2,H2ODisplayEngineLocalTextDxe +F1CF1802-8F94-4504-AA96-CE193C57C86E,PostCodeSmm +F1DBDF29-12EA-20D1-2C48-84C3DC5C7E0D,SbSocRavenPei +F1DBDF29-A2EA-90D1-2A48-94C3DC5C7E0D,SbSocSummitPei +F1E48287-3FE1-4535-89AB-48D6C3DA2759,EfiHotKeysProtocol +F1EFB523-3D59-4888-BB71-EAA5A96628FA,SecurityStubDxe +F1F7C421-96DF-4C8A-AF91-62A3C9AED310,EfiTxtLockConfig +F1FBD629-22EA-40D1-AA48-94C3DC5C7E0D,SbSocBristolPei +F1FCD66F-8966-441E-909C-77F211AB9C3E,MERecoveryDxe +F2074EA5-B8C9-4EBC-881E-30102260703E,ACPI_FACS_MODIFY +F208336A-BFF4-4678-BA4F-342C72373C3A,FjOemIgcEsrtDxe +F20D51DA-16FD-48E6-B4D0-532B6BB8AEA6,AdlSemaWatchdogDxe +F21173FE-DF86-4B8B-AFF9-C7CB77B9C7DD,PeiIchInit +F21249FB-22FF-4D95-A1C6-CC9933F88CF7,HPD +F2191B94-DCAB-49FF-8C8F-A41FA9908D11,DeviceLayoutLoadDxe +F21DA8FA-35B6-4CD0-BB27-620D1460D361,MIPICamera_Lattice +F22FC20C-8CF4-45EB-8E06-AD4E50B95DD3,EfiHiiDriverHealthFormsetGuid +F231ED70-045A-4273-A156-C344748F083F,RtcLossOptionSmm +F235025B-85A0-4AD8-839E-A7FEDFD0CDE3,WatchRobotPei +F235025B-85A0-4AD8-839E-A7FEDFD0CDE4,PowerOnRobotPei +F238F47C-1DE9-4E8B-81B9-CC924E6B5BE5,EfiPcmciaRequestProtocol +F23C466D-D24A-46E4-A951-A58FBC5ECE7F,KEMaEeepDxe +F23FBEC1-987E-4B4B-BF47-7DDCC118DBF3,I2cEnumerateDriver +F244E34D-3643-4E3B-9DA5-8C691CBDE0EB,MeUnlock +F2458956-7449-4632-A875-8F418B74C937,CF9IoTrap +F24643C2-C622-494E-8A0D-4632579C2D5B,EfiTrEEPhysicalPresenceGuid +F26C52BA-024B-410F-B4FB-2F34573443B4,E0104X7 +F26D2D30-817A-45E0-B703-E6C8837A8821,SmbiosType24 +F26D3191-663C-4195-9285-149B43BBDA6E,SynServerSetupSmm +F2765DEC-6B41-11D5-8E71-00902707B35E,Timer +F276BDEC-6C41-21E5-9E71-00A13807B45E,RestoreMtrrDxe +F27AF9D4-39AD-4D08-856D-C115EE4AAD40,EfiPlatformTypeNeonCityFpgaProtocol +F27CF007-4AC7-4B74-B2D0-73161C241462,FjMfgNvmeIdentifyCheckDxe +F27F4D0C-70E4-413B-A537-FF39A2199AA5,CbsSetupDxeRN +F27F9354-A692-4D27-BEB5-2408C6F43B04,FjBatteryFuncsDxe +F281FC6E-F4C4-431C-962B-2F13AE7984EC,EfiSbPcieErrorLogDispatchProtocol +F282908A-A6F9-4E50-9D6C-210478F1ED46,FtBbUpdate +F282DD45-CA7B-40EC-9618-99381C08F409,OpaPlatCfg +F28AD240-3DB8-4809-B6F9-6841129FB23A,FjNvramVariablesAccessReferenceSmm +F2911DF2-7DDF-40D9-9835-AD2B1E200CEA,SystemSetupExitDxe +F29729C7-B759-4B5C-B134-07FC40AC3CD2,Raid +F2A128FF-257B-456E-9DE8-63E7C7DCDFAC,OpromStartEndProtocolGuid +F2A4A79E-89EF-4B25-A48D-A5F05C8D522C,FchKeithDxe +F2BA331A-8985-11DB-A406-0040D02B1835,EmuVirtualDisksGuid +F2BDCC96-8985-11DB-8719-0040D02B1835,EmuPhysicalDisksGuid +F2C16B9E-8985-11DB-92C8-0040D02B1835,EfiUnixFileSystem +F2C1819D-10F5-4223-9236-9B4EBF1B9AE7,Logo1394 +F2C1910E-F5C9-4B72-B243-6D59096A79F0,EfiI2cSlaveProtocolGuid +F2C8B80E-8985-11DB-93F1-0040D02B1835,EfiUnixUga +F2CC3F5B-725F-4290-9A12-B379970295FF,RtkUndiDxe +F2CC5D06-8985-11DB-BB19-0040D02B1835,EfiUnixConsole +F2D006CC-8985-11DB-A472-0040D02B1835,EfiUnixMemory +F2D3B330-8985-11DB-8AA3-0040D02B1835,EfiUnixCpuModel +F2D74E5A-8985-11DB-9705-0040D02B1835,EfiUnixCpuSpeed +F2D7FB2E-FFE7-4321-A4F5-DBB4370B963B,SubcomponentMeasureEvent +F2E23F54-8985-11DB-AC79-0040D02B1835,EfiUnixIoProtocol +F2E5E2C6-8985-11DB-A191-0040D02B1835,EfiUnixUgaIoProtocol +F2E7CE72-5657-494A-BDBA-F3DD8E1DF641,HpAcLossPei +F2E98868-8985-11DB-9A59-0040D02B1835,EfiUnixThunkProtocol +F2ED3D14-8985-11DB-B057-0040D02B1835,PeiUnixAutoscanPpi +F2F0DC30-8985-11DB-A15B-0040D02B1835,UnixFwhPpi +F2F48768-8985-11DB-B8DA-0040D02B1835,UnixPeiLoadFile +F2F830F2-8985-11DB-806B-0040D02B1835,PeiUnixThunkPpi +F2FBD108-8985-11DB-B06A-0040D02B1835,MiscSubclass +F2FD1544-9794-4A2C-992E-E5BBCF20E394,EfiSmbios3TableGuid +F3009649-36D6-4164-AA05-E72DEEA3722F,EfiCseEndofServicesProtocolGuid +F303AF22-6804-494B-A28A-A03BE7D5C742,CsmRt32Asm +F30A4091-D9DF-478B-89F2-A266C1917985,OCMR_Setup +F30AA2DB-DE37-4684-86E8-D8A861A4EE71,NonAmtNetWorkController +F30C2915-5782-4E6A-A846-05BABCE7B6A0,EfiI2cAcpiProtocolGuid +F310C41A-F0F2-49E6-8AF5-4B2F6EB495B5,LenovoSetupStartupDxeGui +F317B29B-7DC9-4114-9086-D7137EF4F118,DellTpmSmm +F31C76B9-0B55-4456-99FE-50A9C5EC116C,DellDxeSioEmi +F321A2D2-1825-4866-6215-BEEBCBF734B0,PurleyPciDxeInit +F3224A5E-17A3-47C2-A38B-481456863C74,AmiSmmNvramUpdateProtocolGuid +F328E36C-23B6-4A95-854B-32E19534CD75,SmmCommunicateHeaderGuid +F33261E7-23CB-11D5-BD5C-0080C73C8881,FrameworkEfiMpServiceProtocolGuid +F3331DE6-4A55-44E4-B767-7453F7A1A021,MicrocodeUpdate +F3358D50-72D4-46C0-9BDC-EDC1DADFB55F,DellSmmMemLibWrapper +F3410F5B-4756-488F-844D-546B5DF05A0D,FjBiosPostGpioDxe +F342BE75-274C-433C-A24D-2816F5433D50,VmwSmbios +F34C2FA0-DE88-4270-8414-961222F4521C,PeiFlashMapPpi +F34F24D7-7531-4B83-9116-BD03FCF99878,SyscfgSyncDxe +F3552032-8985-11DB-8429-0040D02B1835,RealTimeClock +F35F733F-5235-4D7B-83FA-97780CEBCB20,Ping6 +F3604610-DD52-4BED-8F76-ABC9284CD040,UltrasoundHpdCheck +F363B225-4D2C-4352-80CD-8EA4280F8DC0,OemEdidFromGop +F36FF770-A7E1-42CF-9ED2-56F0F271F44C,EfiManagedNetworkServiceBindingProtocolGuid +F3714ADF-E3C3-473B-8FCC-5C34630C45C0,ComputeHmacSha256ProtocolGuid +F3749E2C-5139-4E7A-B53A-4F5080B68B8F,PciSerialDxe +F3774E67-3F2E-4ED1-9A5D-A22EB1A073EF,FjVarstoreSyncGHO +F3794B60-8985-11DB-8E53-0040D02B1835,Cpu +F38C34DE-9C38-438C-9AF6-69F584F17EC0,PoofAnimationState4 +F38D1338-AF7A-4FB6-91DB-1A9C2183570D,WdtPpi +F38D9312-05CB-48A8-8D3E-13643D686EA3,PchInitSmm +F3982635-7706-4842-840F-6479B4865866,DellSimpleBootFlagDxe +F3A3FCA1-466F-4978-AC84-2EA70FAE2BA2,AsfSecureBootSmm +F3A4B484-9B26-4EEA-90E5-A206540CA525,EfiPciIovPlatformProtocol +F3B38282-B951-4E2A-8DF5-DE01FC527AE4,RtcWakeup +F3C6170E-8B8D-46BC-BC11-D7BEBF1F694D,TheftRecoveryDxe +F3C9667B-C50C-4E9C-A1F1-78C3B1DDF2C2,LibNetUtil +F3CC33F3-3716-4864-8606-41C0CB1C1BCE,OemPeiNbSbCustom +F3D0CC88-1BD3-4EFE-9294-423BB495F6C6,DellDaCallingInterfaceSmm +F3D301BB-F4A5-45A8-B0B7-FA999C6237AE,ShellNetwork1HiiGuid +F3E4543D-CF35-6CEF-35C4-4FE6344DFC54,EfiFormCallbackProtocolGuid +F3ED95DF-828E-41C7-BCA0-16C41965A634,TcgPpiSyncFlagGuid +F3F3BB19-6420-45C9-8819-B606A7F20E50,DellPStateControlProtocol +F3FF1468-04BA-4966-9FB2-E4A790054650,EfiCapsuleCrashLogVarGuid +F4089EBB-6FBD-43DE-AB26-93B82BA6E475,OemColorCalibrationDxe +F40C4423-455F-4567-A111-6F81133CE9BB,OledInit +F40F4ACC-4D93-4254-A4ED-C9566FB81656,PdHostInterfaceCypressDxe +F4208BAC-AE29-4C60-9DC8-9B33147B062B,DefaultSettingsSupportEfiVariable +F426C7CF-DEB9-0361-4D4E-9F298C1B896E,SavePlatformConfiguration +F429C00A-9640-46B3-9544-F8F86A28F30F,PlatformConfigChangeProtocolGuid +F42A009D-977F-4F08-9440-BCA5A3BED9AF,AmiExtPciBusProtocolGuid +F42AF0E4-182F-402B-8C8D-CB54D505328C,SmmNoBootDeviceCsm +F42F7782-012E-4C12-9956-49F94304F721,EfiConsoleControlProtocolGuid +F438A3F2-FA7F-490C-907D-2710C5B0E48A,HpPlatformWmi +F43A3770-293D-4834-8D5A-DAB72F94D5E3,DefaultsManagerSmm +F43F7EF6-6A33-427F-961B-6C4F412A977C,TraceHubPostCodeHandlerDxe +F44875AB-B9FC-4578-A280-AA335B49967C,CmosSmm +F4491BA4-7672-486F-B4D7-99899D22DA57,AmiPeimHob +F4493D0A-FDCB-4E25-9F11-6416B1514F0E,OemVerbTable +F44C00EE-1F2C-4A00-AA09-1C9F3E0800A3,EfiArpServiceBindingProtocolGuid +F45370EE-1E16-417F-AD8B-D886B4F05547,BmcRfCertDxe +F45A96A9-35DF-40CB-A0DA-C5F551CD6B21,SetupMenuSmm +F46998C9-DD30-4C64-966C-E17777B2568A,AppleSmc +F46B2EB2-E0D7-4C96-A3B1-0C61BB245C42,EdkiiSmmCryptoProtocol +F46D8EA6-4A67-4872-B0D1-D4FDEA0B692F,LenovoSvpManagerSmm +F46EE6F4-4785-43A3-923D-7F786C3C8479,LenovoStartupMenuDxe +F4731D79-537E-4505-BD52-C03F9B1F6B89,BaseTimerLibNullTemplate +F4796268-1F6E-473C-80B2-7AFC3D2AC7DC,RtcWakeUpSmm +F479E147-A125-11D4-BCFC-0080C73C8881,WinNtBlockIoDxe +F495F038-71E6-49DB-9A80-B2E98F7BA718,PeiDbgModuleLocator +F496922D-172F-4BBC-A1EB-0EEB949C3486,EfiAlternateFvBlock +F49EFBE0-4682-4471-AE65-00EFFB4770BA,LenovoSecureKeySmmProtocol +F4A48AEA-40D1-454B-B7CB-5607A993B8D9,BBSManagerSmm +F4A87592-D3AD-4336-BA00-80859FEE44AF,SmBiosOverRide +F4AC8555-3F91-4668-AC20-9577E6909DAD,DecompressFspsDxe +F4B2C007-94A1-4CD5-A710-F4141FCEBCA0,AmiTseOemTSEVarGuid +F4B427BB-BA21-4F16-BC4E-43E416AB619C,EfiArpProtocolGuid +F4C5FDD3-B99A-4229-9E0B-DB7A09E67393,LegacyUsbLan +F4C8869F-A6B4-4F6F-A3C7-2DEF22BD8225,M24Lc128Pei +F4CBB827-B4AF-4EEF-B512-F3F872F67D7A,FjWakeEventDxe +F4CCBFB7-F6E0-47FD-9DD4-10A8F150C191,EfiSmmBase2ProtocolGuid +F4CF63B9-3A14-4A9B-BCAA-926813BA75F1,TcgLegacyInstallInt1A +F4D6609F-2FB3-401A-A4E7-BDB567125629,SbFlashControllerDxe +F4DDF547-08F9-40B3-9408-2023E8DB8874,CPURDRAND +F4EA205B-7345-452C-9D62-53BA6F3B8910,FmpAuthenticationLibPkcs7 +F4EF842B-E3D1-411A-86DC-F4BF1FBA9E40,Platform_AcerPortingSmm +F4EF9D7A-98C5-4C1A-B4D9-D8D87265BE0C,PeiSdhcPpiGuid +F4F63529-281E-4040-A313-C1D6766384BE,AmiHddSecurityProtocolGuid +F5042177-1D29-45C5-BA4D-4D0EB2E88575,IT8728SioAcBack +F50707B0-7DA0-482D-B458-D23A72939959,EfiSecRev +F5089266-1AA0-4953-97D8-562F8A73B519,EfiUsbHcProtocolGuid +F508CCC1-E0DA-4A63-954C-6F0CE5CD1643,ThermalDxe +F50B86B3-132F-4998-B386-2D49DCB79250,AsusTCG2DxeSetupItem +F50E702C-8653-4CDE-BBCE-43B4D55B34B8,EfiMiscSubclassDriver +F515E82B-44D9-41D8-BA90-EAEFC7C6A668,FlashMediaReaderDxe +F51D8B66-E76A-43CF-9880-3FAE4D30F687,SmmBbsManagerProtocol +F5255151-DD1F-4BD9-A350-235200798740,UpdateDsdtByAcpiSdtDxe +F52C3858-5EF8-4D41-834E-C39EEF8A45A3,EfiSerialGpioProtocol +F537251E-54AA-4B6F-A204-4D577F6D50C8,SpiInitPei +F541796D-A62E-4954-A775-9584F61B9CDD,EfiTcgProtocolGuid +F5508F5C-88D7-426C-B1C4-198A0272405C,UpdateD01AcpiTableHdr +F5513824-BA68-0145-AED9-E0A89FAB40B9,DpcDxe +F5633D05-A7DC-4A2D-8371-A6B84278563B,FchKeithMdnSmmInit +F5699255-115A-4F7D-BB0C-658E9A1F42C6,PspfTpmLibNull +F56A8EFD-62FE-47F9-9892-D8721526FCF5,QuantaIFSmm +F56E697B-3EF8-471D-3EF8-6B6636A6F2F8,InstallWsmtDxe +F56F984F-3846-49D8-AA0A-23DE27E38386,RfAutoGen +F5701B5C-014B-4DEF-A914-A537BB49A89C,ArmaniKeyboardLayouts +F5751C02-5378-469A-8514-07562D5057A6,CheckWakeUp +F57D1C2E-3879-11DF-9118-931B1E0F29B0,VmwLogRuntimeDxe +F57DF891-1DD1-4C67-99A1-4AB2DAD9FFBC,OdmDebugSmmProtocol +F5883FC5-F8EE-4E44-B386-6021FB320C9B,ScReset +F5932638-89A4-477E-B93E-32A51284F3F8,AsusMcuPowerSavingDxe +F5985F80-CF55-46AD-8CCB-D49BF9168AC4,AmiRedfishVlan +F59A5549-B879-440C-A1F6-38AF40F2773E,PcieSataController +F5A41EC4-97AD-40F6-82EB-EE8501CD4926,AmiTlsCertificate +F5AC7057-5650-466E-B692-76A47223EFB0,AcpiSmmPlatform +F5AF6D30-2EDE-4026-8E71-74EF7F36D363,DellDfuPersistentEventDxe +F5B22FDA-B35C-4898-9F4E-40A44C47E295,FjClearsureEraseDxe +F5B423E7-C4C8-474E-B5A1-3C68AD993402,AaeonBiosInfoPei +F5BEF7C6-E153-4ABA-8340-515309F82964,ExtendODMSmm +F5C09051-2CF4-476D-8C83-7EF35BACF30A,WakeOnRtcSmm +F5C48BAE-C10D-4A76-B855-5D5B062AFE04,LOMDriver +F5D14DB5-2F0C-4611-9DDC-7C182B173A71,ProgressBarEmptyRightEndcap +F5D16B69-80C9-F8A0-C28D-ADC6F0D71370,AmdMemSmbiosV2RplPei +F5DB13F4-0D20-4F76-BCB4-B361FCE4EB72,OemQkeyDxe +F5DD1F71-C3E2-473D-84D5-341A374054AF,SystemFlashCommunicationDataProtocol +F5E655D9-02A6-46F2-9E76-B8BE8E60AB22,EfiIfrRefreshIdOpGuid +F5EF05E4-D538-4774-8F1B-E9773011E038,FspInitDonePpiGuid +F5F219D3-7006-4648-AC8D-D61DFB7BC6AD,FontPackageListGuid +F5F2AC62-6232-445C-B322-5969A083980C,MAPS_SIO_InterfaceDxe +F5F87B4F-CC3C-408D-89E3-61C59C5407C4,SataConfigGuid +F5F98F9A-7F21-4190-96DE-4C2713754BE5,DecompressFvAbtDxe +F5FF6D65-F0E5-4763-B204-8B739DF0DD1E,SystemTouchHotZoneDxe +F605503E-9870-4DA5-BE65-CCAA85004EE2,MemoryDeviceInfoDxe +F60B6782-3247-4CDC-BDB7-5CEB184686AD,SystemUsbHidParserSmm +F617B358-12CF-414A-A069-60677BDA13B3,DxeIchPlatformPolicyProtocolGuid +F617B358-12CF-414A-A069-60677BDA13B4,UsbPolicyGuid +F6304B84-7997-45E8-901D-54D0D495737F,FjIbvRestoreConfigurationDataDxe +F639D37E-02A1-4BA8-AD17-5C6C6E5E9322,CbsSetupDxe +F642A9D7-26B7-47CB-ACC8-135951AC93F8,SystemVspCmosRuntimeDxe +F6435590-2402-4E02-99FD-ABDD9DD40A6A,SaPolicyPpiGuid +F64D8B24-1F12-47A4-91AD-5EFC6136B736,LEMDiskRelatedProtocolNull +F64EFABA-D0A9-42C3-B5E8-391B48647BF1,DellGt2LegacyVideoRom +F65354B9-1FF0-46D7-A5F7-0926CB238048,MonoStatusCodePei +F655D0B3-615D-4022-9645-0D1F2E9DF78A,CompalCMFCOEMSwSmi +F65ABA32-76FD-49C6-A1C4-CD7FADF96659,AmiReportFvLibCompatibility +F65D1315-5B05-444F-ADF1-7C1F05685852,TpmVendorInfineon +F66447D4-75A6-463E-A819-077F2DDA05E9,EfiKmsFormatRsasha12048Guid +F665C81D-EFDE-4B5F-88E8-2160B748D2B4,DellVideoConfigPei +F6663081-02D1-4F52-B57C-FDAD224941D4,AmdMemSmbiosV2RvPei +F6697AC4-A776-4EE1-B643-1FEFF2B615BB,IncompatiblePciDeviceSupportDxe +F672AE85-3769-4FB8-A5A0-70B38FB0A7C4,DxeTimerLibEsal +F67FEE3A-DBE2-4228-9732-B4DD1E5FF6AF,BoardInfoSmmProtocol +F684BBB3-C802-47C5-A59B-A392ADF72AAF,FabricTopologyDump +F6937495-1F44-4A8A-8A1B-5A669F9396F6,DevConsole +F6994CBA-2351-4EBC-A2DA-20BAC2FE2CF3,SmmPciLibPciRootBridgeIo +F6A11F0E-0CBE-440C-BD85-49FB595686EA,LegacyUcrDxe +F6A59595-BB9F-415B-A7F3-DC7C09387BE6,SmBusMemoryDown +F6AB1DF9-12CD-4880-AC0F-D0DE71CF89C0,OpromUpdateDxeHedtCRB +F6BEC3FE-88FB-11E3-AE84-E73B77561C35,FastbootTransportUsbDxe +F6C5CE3D-2668-402A-952E-270786150DFB,SwSmi534D3220 +F6C73719-F34C-479C-B32F-277FCBBCFE4F,DelBootOption +F6C78BEB-21FA-4855-9325-311B6A9DAA9E,RealtekGopLoader +F6CDAAE0-B301-4202-89F6-8623E6AED26E,DellSmBiosStrucTherm +F6D35FBB-63EA-4B25-81A5-5E62B4886292,PlatformSetup +F6D74E2F-EEAC-41B7-9E7A-29B258393DB2,AmiAmdPciResourceReport +F6ECDC25-2079-475A-B0E8-F48B8FA5C20A,DellSTMicroTpmFwMgmtDxe +F6EE6DBB-D67F-4EA0-8B96-6A71B19D84AD,EdkiiStatusCodeDataTypeVariableGuid +F6F48D69-0C1E-4A3A-80DD-CC15474FF52A,DellDesktopPowerLEDDxe +F6FB3997-F4EF-4354-B9C2-4737AFED4F2F,AsusWifiRealtek +F706D0C8-F6FC-4F7A-AC98-96BA5CC43AAA,SandyBridgeGopDriver +F70A4116-FDF6-45FB-93CD-84CDDD73DFD4,EfiPeiPlatformTypeLightningRidgeExecB1Ppi +F70A6E93-82E1-4E6A-9A26-E7DE6ACE5BBB,PostScreenInfo +F7119829-314A-4E7F-8853-44AA79A7CB43,PspFactoryReset +F7162F38-6088-4842-B0ED-C143DAD39EFB,PTUpdatePCD +F7196B8E-472B-4C1D-9AB9-A69A8992F46C,LenovoVariableStoreSmmRuntimeDxe +F71AAB75-41BE-C209-A324-9B963BBDCB26,AmdRasSspDxe +F7253EE9-CC52-4234-AE8D-4CD64E8F744F,DellRecoveryMgmtPei +F737BB15-5019-4A16-9DD9-8FD34E431EAD,SmbiosDataUpdateDxeGlacier +F73938F6-B851-494F-A003-331B49408605,SataDevSleepDxe +F746D37F-F6C6-43C0-94DB-466F5F10E030,LenovoFingerprintSmm +F74D20EE-37E7-48FC-97F7-9B1047749C69,LogoDxe +F74FF9BE-90CA-4B57-B769-F606FAA52572,UnexpectedCapsuleUpdateCallback +F7503CEB-481C-4AE2-B42D-8BD684F395E1,SecureBIOCamera_Sonix +F75BD2CD-F473-4BA1-89B3-1E69EFC8BA70,ASUS_HW_FastBootDXE +F75BE584-342D-44D2-9819-36641E8D0107,GetFmpInfo +F761BD04-6E5E-4E37-94F4-4699972B243D,AmdMemStpSp6Pei +F7673C6A-9C5C-4C54-B086-C6E0B7D03DB8,AmdSmmControl +F76E0A70-B5ED-4C38-AC9A-E5F54BF16E34,DriverHealthFormSetGuid +F771B43A-A5C2-45A8-8254-CBC08250DA15,BoardInitDxe +F7731B4C-58A2-4DF4-8980-5645D39ECE58,PowerMgmtDxe +F7761FE7-CD44-481B-8C12-27124877C806,IioCfgUpdateDxeEldorado +F7763316-8C04-41D8-A87D-45B73C13C43C,BltLibSample +F7787C3F-0CD5-4536-9354-0670EE22D7FD,AmdCpmModernStandbyAcpiTableInstall +F77CB08E-6682-4DF7-82A3-BBBB52704C1F,AppleNetLoadFileDxe +F77E54A4-09ED-4C2F-A966-BE1EDC723856,FjTpmPhysicalPresenceQuerySkip +F78153D0-870D-4EEE-A684-741499C9A8CE,EistDxe +F78285FD-121E-49F4-9716-44E307656586,Python2710 +F786D3E4-B003-4C9D-96A3-A4FA84EF9603,DellDeviceCfgDrv +F788DE7A-AB18-4886-BD3E-79ED9786F1A5,AmdMemPprSmmDriverSsp +F799A761-2FC3-4240-92F1-FE457DC2FBBD,SpdPlatformInfoSmm +F7A11672-3EDB-4F77-8A1E-5E8C1E0C98E8,CsbSmartCoverSmm +F7A1EEC5-7DA5-4D80-8EDA-C28347276328,CsmInt15HookSmm +F7A1F48E-0F6A-4F12-A74D-ED6F5B6B00F2,OpromUpdateDxeLightningRidgeEXECB4 +F7AD60F8-EFA8-44A3-9113-231F399EB4C7,EfiKmsFormatMdc2128Guid +F7B0E92D-AB47-4A1D-8BDE-41E529EB5A70,H19UnlockPswd +F7B1EE00-A1B2-43DD-8F1B-815F0D1CE451,SataDevInfo +F7B87A79-A640-4AA5-8C1E-453FB26EF376,EfiPeiPlatformTypeBuchananPassPpi +F7CA7568-5A09-4D2C-8A9B-758468592AE2,AmiNvramControlProtocolGuid +F7CAAF4A-B2DD-431A-8964-375D7E71B9B1,SMBIOSTypeDAhCallingInterfaceSmm +F7CAD0AB-DFA4-40D2-8AFA-B7A8BE017031,MsiBoardEC +F7D19491-EA53-970D-5508-75ACDFA41974,SbSocBristolDxe +F7D22BCA-1BCA-5591-CC8B-1CA98F2890FE,AmiCpuS3Pei +F7D6D25E-6243-4D5C-9BA5-C2DC48F003B0,AmiFlashLibPei +F7D7F748-CCDE-481F-9B86-2EF5EDACC21D,DellVideoConfigDxe +F7D9FD14-9335-4389-80C5-334D6ABFCCED,ArmVirtPrePiUniCoreRelocatable +F7DC7A53-D789-4149-9DEC-C18F2F8CC3D3,SioPowerButtonOverrideDxe +F7DC7A53-D789-4849-9DEC-C78F2F8CC1D6,SmartCoverDxe +F7DFDECF-9C36-4D43-85A4-6D92DAFC3477,FchPromontoryGpioSmmInit +F7ECF277-CD66-4DE8-A425-1D9F899492A7,AsusFtmDxe +F7ED0F76-1F41-4527-AF2A-EECC76B8F078,ArmaniDxe +F7EEA79A-D854-4099-9AE7-D0A328E44F72,AssetIDSmmProtocol +F7FD20F4-E545-4D3B-9AB5-EADB69AF130B,DellVariableLockDownDxe +F7FDE4A6-294C-493C-B50F-9734553BB757,CapsuleX64 +F8000580-44AB-441F-86B4-DA3CA099EEBB,H19RecordLogSmm +F80156A2-1A2C-3335-982C-066C1FC37626,TbtInfo +F80697E9-7FD6-4665-8646-88E33EF71DFC,SecurityStubDxe +F80D20E9-FC95-428C-8FB2-D06FD602BE05,OemTurboModeDxe +F80E66A2-1A2C-415B-9B9C-066C1F04B626,TbtDxe +F8126429-7B88-4AD2-98C4-402CBE26F9A8,IdentityAndAuthManagerDxe +F81B1762-B783-4E64-AAE3-BE61B5A9039F,AmdNbioBaseCZDxe +F821665C-0137-4F34-A7A1-57A0BD256D62,IntelScLegacyInterrupt +F824CCBB-D8E0-4522-8AA8-65F04B463DB5,AmiPeiCpuinitPolicyPpi +F827CF46-8A8F-43F9-BD99-0E7F5206907D,FjSysmanTeutatesSmmWatchdog +F82E0BF0-95F7-41DB-9299-2D054546B3D0,IntelGopDriverRkl +F82E90F8-5C19-4128-BA8B-0EEABF7F32EF,RomHoleReplacementPostFlag +F8309A76-A48F-448C-B7B3-0D832433CE5F,EcIoSmm +F8356C42-4BA6-706F-59E9-A9B1AFF2BCD8,AmdPlatformRasSspSmm +F83AB02A-2B44-4799-A21F-85E7F2E8A32C,KEMhMfgMode +F83AF871-59F4-432F-82E6-31A532894099,ITEFwFmp +F83E3245-2127-474F-8819-974FDC139CE4,FjSysmanProtocol +F8411271-787D-4CD3-B142-88A09F93D8B4,FjFlashServiceSmm +F84B5A60-67F6-415C-9F6F-2FD94FC19B12,DellChassisConfigPei +F84CFFF4-511E-41C8-B829-519F5152F444,LegacyBiosPlatformDxe +F84D8725-5ADF-48D2-8819-1B0331AEB719,DRYPEI +F85327D0-01CF-4D27-AE88-9D20A14F55BD,Rt8152UsbUndiDxe +F8626165-6CEB-924A-BAFC-F13AB9D65728,EmuSystemConfigGuid +F866226A-EAA5-4F5A-A90A-6CFBA57C588E,SmmPerformanceProtocolGuid +F866AD0F-1FBB-4D52-813D-7EB95E2F19D4,menu_mid_right +F8673422-16DE-449C-8728-AB0361DBF9F0,LegacyInterruptHookDxe +F872A62B-3151-4F39-805E-5702CE1F7504,MsiPtpTouchPad +F8775D50-8ABD-4ADF-92AC-853E51F6C8DC,IoMmuAbsentProtocol +F87A3D1B-B0C3-44B6-B470-F4F4C09C110C,AsusQuickVgaPei +F880AAE0-E4AC-4C64-A326-82709CC241EA,UsbDbg +F8870015-6994-4B98-95A2-BD56DA91C07F,EfiMemoryMap +F88BB993-9230-4CDF-916A-7A2D3BDEE690,AppleStartupManagerPolicyDxe +F894643D-C449-42D1-8EA8-85BDD8C65BDE,EfiPeiMemoryDiscoveredPpiGuid +F895B482-1970-49A7-84F5-723978086642,DellFlashUpdate2Dxe +F8BB41A2-485E-4B9D-88CF-151E62F84DDE,DellSmbRunRom +F8BE27F2-7EC7-82FD-704E-A94BA8E63C7D,EcGpioControl2Dxe +F8BFF014-18FB-4EF9-B10C-AE22738DBEED,DxePlatformSeCPolicyGuid +F8C60DB4-D427-436E-AF93-5FCCDA0DA37B,DellThermInfoConfigSmm +F8C6FEDE-EE15-47ED-99A4-60798A3C7DC4,StaticSkuDataDxeLightningRidgeEXECB3 +F8CA70B4-6A85-4616-8BDE-3EC569644AC3,LenovoW25Q32FlashPartSmm +F8CC23A7-0F10-45AF-AA1C-0D9DD8BB3C20,DellHttpsBootManager +F8D85E52-00F9-4DE4-AEEC-0AE76BA6C210,FjGpioCoffeeLakePei +F8E21975-0899-4F58-A4BE-5525A9C6D77A,EfiHobMemoryAllocModuleGuid +F8E5058C-CCB6-4714-B220-3F7E3A640BD1,EfiUserCredentialClassPasswordGuid +F8EA63DD-3E59-462E-90E4-40ED947F60B0,AmdNbioDxe +F8F995CE-B26F-4ECF-B228-0DA5151BE710,EmbeddedUefiOkrProtocol +F8FABC29-6CAB-48EB-802D-FF2EF6A3DF87,HpCableDetect +F8FD0711-CAC1-492F-AFC6-AFF5DA4D01B1,FpkConfigUpdateNeonCityEPRP +F906769F-4AED-4A0D-8C7C-FF21B9D1051A,IntelVTdPmrPei +F909628D-4B48-42FB-BD68-0F8685E33335,CheckBIOSVersion +F9109394-E5A3-4E61-B168-DC34D534451E,DellBbsmanagerSmm +F91486CE-700E-4D85-ADB5-4ED532536A7F,NvmeInfoSmm +F91DCAB4-3639-11EE-BE56-0242AC120002,OobPprDxe +F920B52A-B421-4509-BD00-B75FD9562775,AcerCF9Hook +F921941B-708E-4BCD-98FA-525E4A9DCD55,RtkUsbUndiDriver +F9229745-981C-4E07-9FC6-789545CB8818,AcpiSupportDxe +F9268411-99AC-4F1F-B2D7-5804ED5B8E1E,OemLogoScale +F935FF1B-AFF0-40F3-B77A-B795A7A7D714,DellPhysicalPresenceSmm +F9383ECA-8566-491E-8533-ED7D2EFEA80D,SmcNVDIMMPeiDriver +F94700A3-F49F-4CD2-BF25-19E280B72E3B,SystemUsbDatabaseDxe +F94A048B-7FC4-4ABC-85A6-8616A6D3CDCE,LenovoTcgSmm +F94AB34A-8069-4A9F-AD08-9534EF37D9BE,DellMeLocalFwUpdateDxe +F95754C4-784D-4155-A05E-5C0AE2559FF8,AmdNbioBaseRVPei +F95A7CCC-4C55-4426-A7B4-DC8961950BAE,ShellLevel2HiiGuid +F962C719-6C1E-4A75-8629-38157622A906,AddressTranslationDxe +F99775D1-1A6E-4555-98F2-18398403D1B2,FjRuntimeServicesTableRt +F99C0302-9256-4050-B41D-F24B87F702D2,KeyboardLayouts +F9A66268-C49F-4D29-8D20-FC1FB04B82F4,IntelLanUefiDriverGpy215 +F9A9F8E6-C797-4FD8-9213-80C0CDC290B1,PlatformData +F9AAA8B4-B4A4-4ADC-9E28-29CAD222E15A,FjSysmanAmphion +F9B71F6A-5EB5-42D6-84FF-9E8A2389526F,DellAutoRtcResetDxe +F9CD1703-8108-45CD-9384-5B247B8CAFF5,SerialIoDxe +F9D88642-0737-49BC-81B5-6889CD57D9EA,SmbiosDxe +F9E5AA3D-9D61-48C6-8348-24DA25924211,EmulatedEepromPei +F9EF07AB-ABD0-4FE0-ABA7-BBA295024712,DellTagDxe +F9F0B131-F346-4F16-80DD-F941072B3A7D,IffsPersistentData +F9F1020C-CC31-4203-8850-EEC07A52A5B5,SecPchLibFsp +F9F5318B-D0ED-4CA8-BE91-1881CEB57F1B,AsusAcpiRam +F9FA0EAC-A5B5-40DD-BDFD-F540DFEE307D,SbRecoveryDevice +F9FA662B-8361-4DF0-A419-781EB024B2B7,LenovoTpmProvisionDxe +F9FAAF5D-E848-4537-8A75-0E3BD2DEFB6A,UsbOcUpdateDxeXPV +FA0F4B4F-D6EF-40E7-BC1B-29245CA03BC2,FvbInitilized +FA1184F7-7E5D-4E82-B30E-FEA47677A94E,I226_PXE +FA177FF7-1FC7-458D-A358-D9D62AE61CEC,PeimEntryPoint +FA1B2631-91C4-43F0-BA91-AFBFC7452087,DellEnhancedVersionDxe +FA20568B-548B-4B2B-81EF-1BA08D4A3CEC,BootScriptExecutorDxe +FA2338AD-80DF-49D0-9396-CF7145D03A76,TxtOneTouchOpProtocol +FA2ED6B0-F606-4450-B4F1-4ED34A17E076,MsiBoardDxe +FA327F24-2DE2-4B60-871A-436BC90605D4,LEMComputraceApiDxe +FA3AD693-D58A-4619-960B-8EE85C914870,PeiPciLibPciCfg2 +FA3CDE4C-87C2-427D-AEDE-7DD096C88C58,IscsiV4Private +FA4585F1-303B-4725-80E4-BB42BBD0249C,SupportURL +FA4974FC-AF1D-4E5D-BDC5-DACD6D27BAEC,AmiNvramMainRomAreaGuid +FA4F6740-B95A-43F9-90B5-78D8147C0219,LenovoSlp2Smm +FA528024-59A6-4689-BEA0-B555D87D7DBE,FpgaFvDataLibDxe +FA5A8753-A30E-4C73-9265-8FEC0AC118AE,UsbHubEnableSmi +FA68BD3F-8AD7-4D41-8CD9-2E72FB387AD7,SctMilestoneTaskDxe +FA6C7BA5-4E80-46FB-95B7-3591CA0AD41B,SmmSioEmi +FA70AFCC-3715-4D15-8699-F0DF4CAFC6D3,AmdNbioGfxRVDxe +FA735DA8-ECBD-4448-8154-91E77120D427,FjPowerButtonState +FA7E8D10-1312-4B98-9A3B-3B5B13A25DB0,PsmiHandlerBufferGuid +FA7FA216-4DB5-D8DD-64D9-FA8D539A5ACD,PiAst2500Dxe +FA8288DD-D296-4DCF-BAA0-2F56EE8C6DA9,HpBeepDeviceWmi +FA82AC30-EA3B-4FDC-9D90-C2FDFFCAFBE4,SnapScreenDxe +FA8ADDEF-38F2-43A9-BF1A-2936EFC5C0CC,ResiliencyDxe +FA8B2FAB-0032-43DA-9165-213BEAA2D967,StoreRestoreMBR +FA8F55E8-AB22-42DD-B916-7DCE39002574,TdthiProtocolFixed +FA920010-6785-4941-B6EC-498C579F160A,VirtioDeviceProtocolGuid +FA990751-0795-4D5E-AB70-A6F5A6771AC9,GopPolicy +FAA216CB-B569-4407-8C25-1A1457B51DEC,AsusAcpiSwSmi +FAAB0F29-0582-4AD1-9BB9-E693A0D99823,SioWdatDxe +FAB13F43-BF42-450E-B695-A35479A9D642,DellPowerOffPolicy +FAB5D4F4-83C0-4AAF-8480-442D11DF6CEA,VirtioScsiDxe +FAB72A4B-E67F-4951-845C-BE5D8F5AE62F,AmdCcxZen3RmbDxe +FAB7E9E1-39DD-4F2B-8408-E20E906CB6DE,HdBootDevicePathVariablGuid +FABDD96B-2DDD-4747-9612-F9E777C84A38,SetupUtility +FAC2EFAD-8511-4E34-9CAE-16A257BA9488,Capsule +FACFB110-7BFD-4EFB-873E-88B6B23B97EA,PhDefEfiVar +FAD7933A-6C21-4234-A434-0A8A0D2B0781,EfiIsaHcServiceBindingProtocolGuid +FAD8842C-7DC7-472F-A6A7-1CA1F073644F,AmdMemoryHobInfoPeim +FAD93433-76B9-4482-4567-3BEACEA9B35D,A01WMISmmCallback +FAE06C19-0F1C-47D3-832D-E3B9C25AD020,aDefaultPei +FAEA0786-FF3E-4091-A895-98E4E9114892,LegacyRegionDxe +FAF79E9F-4D40-4F02-8AC9-4B5512708F7F,BiosGuardPolicyOverride +FAFF8CA9-E515-44ED-B5F9-E2F6E5D902E3,ServerHotplugDxe +FB011592-2A97-4982-8A54-3B3F595CD59F,FchKeithPei +FB045DB2-598E-485A-BA30-5D7B1B1BD54D,AOAC +FB049119-AC72-459F-865A-641DC13C931D,OemLOGO +FB062BBC-F19D-4CF4-81FD-FAE535D44A53,WifiProfileSync +FB07B301-8B02-4952-876E-D071EECA6B53,FjBeepOnPOSTDxe +FB0F46A6-4073-413D-991A-812ABEBC3138,PlatformStatusCodeHandlerSmm +FB142B99-DF57-46CB-BC69-0BF858A734F9,SerialOverLan +FB15CB3F-D373-45A1-B9B1-0079D4E9D6B2,menu_seperator +FB257425-8C55-4DE8-8238-F53906AA5B94,IrqBoardInfoRvpDt +FB2B7D4B-B6AE-4284-8307-2D7F848C1B46,OemBootOptionPolicyDxe +FB2CE027-10E9-4F0A-A7A9-1B9D9CBD6DCC,RecoveryLedBlink +FB2EE051-A1F6-4B6C-A137-961C41F2C5DD,TPMfirmwaredriver +FB3D20EE-CB5D-45EE-BBAE-C5AAA9C0FDFA,ChipsetSvcPei +FB4ED61B-2022-428A-8715-9D8F029DDA4C,RtkUndiDxe +FB547927-DAEC-4884-A12E-94109FEDF18C,gear3 +FB5937D3-7839-4CE4-432C-D02585D222A2,CcgxFwUpdateSmm +FB62F7F0-5433-11E4-B810-402CF41D8A90,SecureEraseDxe +FB6D36A2-EF7D-4B74-99AC-80B31F6BE9B1,WheaErrorInj +FB6D9542-612D-4F45-872F-5CFF52E93DCF,EfiPeiRecoveryModulePpiGuid +FB7258BD-4097-4576-8CA5-7B2C3D85E988,CapsuleCallbackDxe +FB73FD5B-FAB5-4EE8-8E32-48035C2071AB,Smbios248 +FB7400EE-0E8F-4B9C-B677-CF3E0F27CF62,LEMEfiAtaPassThruProtocolHook +FB74A690-DE1A-4BF4-97C0-170B3535FC98,PciThunderbolt +FB76E42B-EA77-48F3-A61D-208FF0535F92,TrEEPpVendorLibNull +FB8415B7-EA7E-4E6D-9381-005C3BD1DAD7,DellEcConfigPei +FB85101D-F422-4C8C-82C4-EF4DCD05E1BF,SmcSmBios +FB8CE09B-A0DE-467E-9DC6-4465F5987676,AmdFabricSspSmm +FB925AC7-192A-9567-8586-7C6F5F710607,Cryptest +FB94D898-57D5-4624-AEE5-0551AE692E9F,KEMhTstMode +FBA14D8B-BE6F-0361-93E8-4CDF18E19EDE,ICCPolicy +FBA2AFEB-9ACE-49E0-BB82-0EB9E83BD5BE,HpAcLossSmm +FBA34BC8-4E37-451D-A7FF-5469F52064C6,UUDriver +FBA4A10E-8931-4BE0-B1EB-92A1326F64BE,AcerHwConfigDxe +FBA9DAA5-EE58-4E01-9E94-5B0EB63F851B,SpiProtectionDxe +FBAA1C41-ED48-4EAA-98AD-7A3F95B47915,InstallD01MsftDxe +FBB3F083-5787-45AF-BADC-664854100F20,FitDiagnostics +FBB4A01B-947E-4D82-B27D-1E207C070053,BaseCacheAsRamLibNull +FBC9449A-681C-4517-AB91-9072ACDEBB77,GcExt +FBDC5309-BF95-44B5-A8AE-E0593E0522BF,BackupBiosUpdate +FBDCC90A-A7A2-4D50-AF79-880A513C5387,QCAWIFI +FBE0E499-2EBE-4421-A237-B21435FB7145,VariableServiceSmm +FBF95065-427F-47B3-8077-D13C60710998,dbVar +FBFCA56B-BB36-4B78-AAAB-BE1B97EC7CCB,EdkiiXtermR6 +FBFFA123-4540-4439-A901-8899AABCDEF0,SyncMSR +FC012980-D6F9-4741-B660-32D04E269BD8,DellFmpPm +FC06B535-5E1F-4562-9F25-0A3B9ADB63C3,EfiIa32X64ErrorTypeTlbCheckGuid +FC089179-D584-4ECD-A886-96A18562D907,HpThermalDiagsDxe +FC120ED3-40E1-46DC-8C9C-AAE3CA139ACF,BasePerformanceLibNull +FC1B7640-3466-4C06-B1CC-1C935394B5C2,PchSerialGpio +FC1BCDB0-7D31-49AA-936A-A4600D9DD083,EfiCrc32GuidedSectionExtractionGuid +FC1D4706-88FB-42B0-98B0-A4B2E607EBAA,LibErr +FC22F5BD-FA25-4625-A53B-9CB485A98D87,SecureBootInitDxe +FC3269A5-5514-4279-8C56-5D23718D879F,AsusSampleSmmWrapperPkg +FC3DADEC-1E3C-49AC-9CC8-3C3597A8C85F,Smbus2HostController +FC4285A7-EBB5-45D2-8541-EBA3318FC2C2,UsbOcUpdateDxeLightningRidgeEXECB1 +FC44722E-1813-419F-9FDD-C3FB644CEC8C,DellErrorHandlerDxe +FC4707B5-BCB9-42AC-8790-E2269274FFBD,RtkUndiDxe +FC4B3B8C-2A0B-47A2-8A95-AFFA51A01593,OsInstallerMenuDxe +FC4E86EB-AAA2-4EFE-831A-1E66DB3C5970,AmdSmmControl +FC510EE7-FFDC-11D4-BD41-0080C73C8881,AprioriDxe +FC53F573-17DD-454C-B067-ECB10B7D7FC7,EfiHeciSmmProtocolGuid +FC5A38D2-E0AE-49B7-A490-A1A8BCF51D44,ColdBootLongRun +FC5C7020-1A48-4198-9BE2-EAD5ABC8CF2F,BdsDxe +FC622601-83C2-4C56-9A4D-E78642DF69B1,FjSysmanTeutatesPowerStateBin +FC637F1E-50DA-4013-924D-C531F1DFF38B,GopConfig +FC63ED62-949D-4FB0-B754-D558A6367C56,EzFlashDxe +FC6F3967-AAA8-47D7-837F-A1CD442E7572,TcpDxe +FC73690C-8D4A-4F8C-B7F5-BA241F316E28,CpuInitDxe +FC740D58-59BA-429B-99EF-627051737B76,ImageDecoder +FC740D58-59BA-429B-99EF-627051737B78,AsusImageDecoder +FC788727-C2D0-469C-BD03-5AEA03323C67,GlobeMask +FC7A2E28-EF78-4472-8B17-B8BB0024616E,UefiRaid +FC7B9F22-2AF6-4BDC-9B94-38646F1E0830,AsusIoSecInterface +FC7DD6E0-813C-434D-B4DA-3BD649E9E15A,EdkiiScoTerm +FC8377DE-A3DA-421C-A455-E111BAA679E9,AmiFchUart0Dxe +FC87501F-F707-49A2-B676-77717DD904DC,SmiCpuDecode +FC8BE767-89F1-4D6E-8099-6F021EBC87CC,AmiIrqDmaMaskVariable +FC8CFD34-4D25-478C-83F0-0309C93FFBA4,AmdCcxVhDxe +FC90EB7A-3E0A-483C-A26C-484D36593FF4,AcpiPlatform +FC9A50C1-8B3D-40D0-9912-6E26D7896CBA,AmiHeciSmm +FCA3A635-C4AF-458D-9679-F7B61480E39F,AmdGraphicsDxe +FCA6A1D3-66D3-4E38-A737-E45A58B1A5D0,OobInit +FCAA9AD2-D6C1-483E-8A24-15BE21704FAD,CablesIdm +FCABE6A7-7953-4A84-B7EC-D29E89B62E87,EmbeddedMonotonicCounter +FCAF78DB-828C-4279-A743-DFE3E9A7DB46,DellRpmcProvision +FCC0B496-192A-48B4-BE7E-7F8763DD2FB1,FjFextDxe +FCCCE259-07E1-417A-A755-E0F2CF39295E,CpuInitDxe +FCD337AB-B1D3-4EF8-957C-8048606FF670,HiiDatabaseDxe +FCD6562A-253A-40D7-87DE-28CFF25898C6,InsideHT +FCD67501-3518-491A-92CA-4EBC91E84BBE,AmdRAIDCoreDxe +FCD6E85B-4A8E-4326-A7AB-8E67229DA8E3,AmdSocFp7PhxPei +FCDC2416-D7EB-4491-B194-3EFF5DB333C0,SVI3ManagementDxe +FCDCB9C2-7987-47DF-A9A7-BE3DBA52D50C,BootOptionPolicy +FCDD2EFC-6CA8-4D0B-9D00-6F9CFA578F98,EfiCpRcPkgTokenSpace +FCDF7788-7878-11FF-CC77-88CCCC7788CC,EfiSmmRcToAptioBridge +FCE085B0-9E4C-4058-BB55-1676C77C51A1,DellPolyFuseStringPolicyDxe +FCE2733C-8804-4293-AC52-562D2D729D2A,AmiSetupFormSetVar +FCE47C4E-5ECC-4A41-B90E-0BAB09968D02,SystemSecureFlashSleepTrapSmm +FCF51E6B-527F-438D-BE6D-A6D15F0CD98B,EfiTraceHubStatusCodeHandleRuntimeDxe +FCF94301-9763-4A64-AA84-7892C4712367,IpSecDxe +FCFE7223-7291-4CE7-85BD-DEE481BB7115,AmdSocFp8PhxDxe +FD022AE6-CF36-42F8-E360-2309237257B9,AmdNbioIOMMUSSPPei +FD023012-19F4-4235-ADCF-D924DBE246FE,StaticSkuDataDxeLightningRidgeEXECB1 +FD082F6E-6391-4DBC-86C3-E33CA14F3453,HpPlatformFormsDxe +FD0C65EB-0405-4CD2-8AEE-F400EF13BAC2,NtPeiLoadFilePpiGuid +FD0F4478-0EFD-461D-BA2D-E58C45FD5F5E,EfiGetPcdInfoProtocolGuid +FD144455-591B-4E1C-80EF-295B783FC8D4,CrashLogSmm +FD225DB2-5A26-4263-8398-71C359404B85,AcerTPM +FD2340D0-3DAB-4349-A6C7-3B4F12B48EAE,EfiTlsCaCertificateGuid +FD236AE7-0791-48C4-B29E-29BDEEE1A811,SaInitPeim +FD236AE7-0791-48C4-B29E-29BDEEE1A838,PchInitPeim +FD252115-77AF-4D9D-A259-81DD98780E18,UpdateTCMFlag +FD27652D-F758-4EFC-B1A9-283EFE51F4E9,MeFwCapsulePei +FD301BA4-5E62-4679-A06F-E09AABDD2A91,EfiTdtOperationProtocolGuid +FD315206-9EFC-43AF-8845-4C7528667CAC,OemSMIEE +FD36FEE3-7B33-4C9E-836E-9AA26A9E3149,BiosAcm_Dale +FD3B3390-9E9A-4343-8E03-90F080DE9021,EcdPeiNbSbCustom +FD3B7E55-FA7B-4E07-AE1D-208B81FB0BAD,FvbRuntimeDxe +FD3F690E-B4B0-4D68-89DB-19A1A3318F90,MICROCODE +FD44820B-F1AB-41C0-AE4E-0C55556EB9BD,SMBiosFlashData +FD480A76-B134-4EF7-ADFE-B0E054639807,UsraProtocol +FD4D6227-6B16-4BA2-BA9F-E94EB89FAF8D,EsrtDxe +FD4E7631-3558-4C24-ADD3-C47EBEAB9267,HpSmmVariableProtocol +FD5D40DE-20BE-44BE-9415-A51B527AB4FA,IntelWLan6GControl +FD5FBE54-8C35-B345-8A0F-7AC8A5FD0521,EmuSnpProtocolGuid +FD724D10-6C1D-4CEB-AC39-693900669CE1,Supplicant +FD72B1B5-5391-4C6A-BDFD-9F59A7880A21,PlatformRelatedInfoGuid +FD76FF8E-665F-4AFC-AF75-724EF5A569E5,UcOnUc2Thunk +FD776D5E-A7B7-4C1C-896F-616AE444436C,MAPS_SerialPortControlDxe +FD7A24E8-B7CC-4172-9F1E-64970BE3EF62,FchTacomaDxe +FD7C4665-34BE-426B-B1F8-3AB753CE44B0,PeiBootScriptDonePpi +FD86838E-5134-4166-8C73-CC05B39073CD,IntegratedVideoOptionPei +FD8DD4C4-B748-48E3-A932-BA68DD07BB06,FchSmbusDxe +FD9175E4-943A-4885-A61B-40F639BC71D3,MAPS_SmartFanSmm +FD93F9E1-3C73-46E0-B7B8-2BBA3F718F6C,TcgSmm +FD96334B-2F26-42BE-A947-7AEFB4AF9291,IntelLanDriverPolicy +FD96DEAF-2C34-43FE-A7A8-011F8C3E9412,AfterG3InitPeim +FD98B162-41BA-4C9E-982E-023699DE02F0,DellEcPolicy3 +FDA14FA3-AFFC-469A-B7BB-34BCDD4AC096,PlatformIde +FDA82EB3-28A4-4950-84F6-3D49A73F0487,PlatformSmm +FDACDB6C-ACBC-4D87-8A59-83F539FC66FD,FanTuningDxe +FDB3B9A7-1E82-4C77-9C6C-4305C851F253,ProgClkGenPeim +FDBC2130-2A17-4830-8477-544F3669772F,DxeCpuPowerManagement +FDBE121D-3EB4-4F95-A294-B3794D177FEB,DellECZPODD +FDBEBA3C-B4C5-4F76-B80A-3D1F8DA62973,DellFlashPowerConfigSmm +FDC50ED1-ACB8-8048-8735-8098B7A13E5E,ApplePowerState +FDCB1801-A303-4430-9481-28F298C01EC9,SmcSwSmiFlashProtocol +FDCF66CC-5091-483E-BA85-DFA4472E4254,Common_LilyDxe +FDD7E3DB-96CA-4036-9F88-9FAF7A43ACA4,MfgPanicModeHandler +FDD96161-9E65-482B-B7BE-4B2F40974415,FjBootOptionDxe +FDDC2E1E-33A9-40A6-A232-21D64B3622E8,SmiVariableInstallInt15Dxe +FDE29A56-C197-4AE1-BB98-792B2F09725D,FspVariablePcd +FDEE5331-BEC6-4C6D-B82E-C5B14E91693E,PlatformSioEspiVwSmi +FDFBBFAB-BC61-4961-B917-77445641507B,TseAfterPostInvPwdPrompt +FDFBF935-656D-4EA7-9DD3-B7FB42497D78,DellSecurityAuditDisplaySmm +FDFF263D-5F68-4591-87BA-B768F445A9AF,Tcg2Dxe +FE00EAF2-BA37-4BCF-939C-4C78EA63ECDA,DellPropertyReady +FE075D44-D9F1-4DA1-AE6A-8250553CDE66,AmiTseOemPortingVar25 +FE0CD24C-B7A0-4F0D-A78C-EC3E27181AE5,AmdMtkWlanDrvCfgDxe +FE16CB8E-82CF-4F43-AAFF-A9B3B2B55443,SmbiosInterfaceCoreDxe +FE1F75AF-3647-4422-A7E1-ABD64520D904,PsrSetup +FE27AFCE-A2C8-4C30-84C5-4CE14F6B292D,SataDeviceFeaturePei +FE2B0D33-133D-4253-A97C-08F141044D85,OemRealtekWlanUndi +FE2F54A9-017D-45C2-A82D-9822BCF14CA6,FanPolicyDxe +FE31B86D-EC7C-4F24-821A-603FF8BBA568,OnBoardLanPxeDriver +FE3542FE-C1D3-4EF8-657C-8048606FF670,SetupUtility +FE3542FE-C1D3-4EF8-657C-8048606FF671,DriverSample +FE3CE4C1-905C-4085-A7A0-38DEFE4178D2,BackupHddPasswordDxe +FE40F4FE-6C15-433E-B0B4-5FD190E70DB2,ODMPEI +FE4177AA-168B-4C1C-BC5D-205C932307CB,OemKbLightSupportDxe +FE444F51-5288-46E6-B171-73C91BDE358B,DellUefiClass3ConfigSmm +FE4622E7-180F-4383-B6AF-87A18F049B4A,FirmwareVolumesInstalledPpiGuid +FE4A8890-2BD6-4DF8-A59E-301D398B5433,HeciTransportDxe +FE503FFE-497F-4A46-9AD2-FBDDD253D5B1,SensorInfoDxe +FE5B3CD5-3409-4225-9D79-5791088C02C8,RtkUndiDxe +FE5C7F1B-E256-47A8-8F1E-9478107C7875,AmtInitDxe +FE5CEA76-4F72-49E8-986F-2CD899DFFE5D,FaultTolerantWriteDxe +FE5FDD35-A0A4-456C-AF66-03137A5599FF,RaidResourcePei +FE612B72-203C-47B1-8560-A66D946EB371,setupdata +FE61BB5F-1B67-4C24-B346-73DB42E873E5,ArmHwDxe +FE6C231F-C490-41B2-8A85-826FC7764AF0,FjVariableSmm +FE6E1666-591E-4AB8-9531-2BF6433A3925,ApobRnDxe +FE6F3B89-6417-4F00-A206-EA52E7D44D3D,LenovoSmmAmtConfig +FE6F8ACD-55A6-4C6B-B448-64E659DE94B3,LegacyRegion2 +FE72846D-6C19-4237-9052-9C693CF409E3,AmdFabricSspPei +FE7D8450-446D-0F9E-FBE7-DBAFF5AF1FF0,AmdSocAm4VmrDxe +FE82B152-96C9-4A53-95DC-6E49C85087C3,ControllerDiscoveryDxe +FE9AF6AA-17F9-4A67-B009-E37579385DE5,SiliconDataInitDxe +FEA01457-E381-4135-9475-C6AFD0076C61,CryptoDxe +FEAA2E2B-53AC-4D5E-AE10-1EFD5DA4A2BA,BeagleBoardPciEmulation +FEAAA7A6-CB95-4670-B499-877FA6CA6BAE,MeudFile +FEB817B5-5006-4DAD-B3B7-B72E26FF3EC3,AsusOnBoardDevicePei +FEC445CC-2466-4DCE-9052-7400E044554F,CbsBaseDxeZP +FEC46340-CA99-49FE-BCCA-D09FA6064A4A,MrcHooksServicesPpi +FEC58211-6025-45B7-9DCF-DB21A433BB78,MmcSetPowerOffTypePei +FECCA19A-D1D3-4CDD-B477-56573F58B1A3,AmdNbioAlibRNDxe +FED6583D-2418-4760-AC96-B5E18F0A6326,SmmCorePlatformHookLibNull +FEDD6305-E2D7-4ED5-9FAA-DA080E336C22,PeiUsb2HostControllerPpiGuid +FEDE0A1B-BCA2-4A9F-BB2B-D9FD7DEC2E9F,StatusCodeRuntimeDxe +FEDF8E0C-E147-11E3-9903-B8E8562CBAFA,EfiBootManagerPolicyProtocolGuid +FEE6987C-9FF3-4971-ABC1-23697CB6ACED,A01ModifyBootInfoDxe +FEEA2404-752E-4E6E-823C-877D848CB12B,AsfSecureBootDxe +FEFEA8E3-9673-4A5D-A865-88351D2171CE,AmdDmarControlDxe +FF052503-1AF9-4AEB-83C4-C2D4CEB10CA3,PhoenixEfiSmmSwSmiProtocolGuid +FF084F98-B1D2-49F8-AA57-E7EEE7C48A12,VbtMipiPanel3Guid +FF0C09A0-76C7-4E99-8F21-2942D12E7B04,AmdOemRasBrhSmm +FF0C8745-3270-4439-B74F-3E45F8C77064,IntelGopDriver +FF0C8746-3270-4439-B74F-3E45F8C87566,gMXMsigned +FF0C8746-3270-4439-B74F-3E45F8C8A588,gMXMsignedN16M2 +FF0C8746-3270-4439-B74F-3E45F8C8A589,gMXMsignedN16E +FF0E5C5A-FA43-4593-BE3F-9D902E0359A6,FchPromontoryPlusGpioDxe +FF10945A-1EA3-4BD8-B785-B525C5E14EBB,NonAmtNetWorkController +FF11E702-8923-47CC-AD30-D9E0E240DD10,AAFTblDxe +FF189B79-F558-4B6A-8A78-6FCD2B4B0E3C,FrontPageDxe +FF1B53B2-E81C-4A37-8D64-2F0F7642D82F,CustomizeMultiLogoSmm +FF20FCDC-805A-7748-A090-6A8A37260D76,Power +FF259F16-18D1-4298-8DD2-BD87FF2894A9,PchResetPeim +FF2D54D4-5C55-4C06-8549-C3627CB8B995,EfiNbErrorLogDispatchProtocol +FF30FA10-EE1D-455D-971F-34B97D20679C,PlatformMemoryConfigurationPei +FF311042-1C7A-4769-8085-93686179E437,MeIgnitionDxe +FF391B6E-07CE-4904-BFFF-12BE96D4ACF1,FvbVariableStorageSmmRuntimeDxe +FF3E5307-9FD0-48C9-85F1-8AD56C701E01,EfiCertSha384Guid +FF3E8D8C-F7D2-472F-BE89-71928123193C,PeiSmartPowerOn +FF3EAE9F-AB18-4CAF-B2A1-6BF3FDCA3C4D,LenovoSmbiosProtocol +FF3F5786-7026-403F-9A95-47F989391294,FchSmbusPei +FF456B9C-0DC7-4682-9E92-0DE84B6E4067,PeiSmmControl +FF478412-38C3-4770-85F6-5D076C62125F,TargetDiskModeUI +FF4DDA4A-64E4-42A4-96CA-3D4F2D4311A9,AmdPlatformCustomizeDxe +FF5A0DC3-DFAC-434A-B3DF-FFD4C1EA7E41,AmiTseOemPortingVar28 +FF626DA9-17EE-4949-A8B8-B10FA0044E9F,EsrtFmpDxe +FF63C459-3400-40F9-85FF-54AD7855F5B7,DellFmpLoader +FF69F7D7-BA16-4B20-8589-EA8EC0379967,DellAmdThunderboltDxe +FF761299-D41F-4C73-8380-A24055ADF4B9,EDUDxe +FF8124DD-34D8-4CF8-9C6F-DF6FCE3A9F13,DellUserInterface3Dxe +FF917E22-A228-448D-BDAA-68EFCCDDA5D3,TxtDxe +FF97F61A-A215-46D3-8008-21CB4356042F,Wcn7851Launcher +FFA0AE14-0FD1-4169-B87D-58FB8C346556,FjLoadRtd3Table +FFBD9AD2-F1DB-4F92-A649-EB9EEDEA86B5,AmiHddSmartProtocolGuid +FFD2BE39-1D4E-4623-ACC3-30689B9EA78A,TouchPadDriver +FFD92E9C-26B0-44E3-9960-872F6C4162B6,FjCmos +FFE06BDD-6107-46A6-7BB2-5A9C7EC5275C,EfiAcpiTableProtocolGuid +FFE0FCDC-809A-4D48-A060-6A8A6A269176,EventLogsSetupPage +FFE92C5D-2D83-44E2-A4EA-294D53991DBC,HpChipsetSHUsbPortDisableSmm +FFECFFFF-923C-14D2-9E3F-22A0C969563B,EfiPerformanceProtocol +FFEE0F93-34CA-433A-B44A-18C25C1E615E,RecoveryControl +FFF12B8D-7696-4C8B-A985-2747075B4F50,EfiSystemNvDataFvGuid diff --git a/common/intel_fit.h b/common/intel_fit.h new file mode 100755 index 0000000..ba0dda2 --- /dev/null +++ b/common/intel_fit.h @@ -0,0 +1,165 @@ +/* intel_fit.h + +Copyright (c) 2015, Nikolaj Schlej. All rights reserved. +This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +*/ + +#ifndef INTEL_FIT_H +#define INTEL_FIT_H + +#include "basetypes.h" +#include "ubytearray.h" + +// Make sure we use right packing rules +#pragma pack(push, 1) + +// Memory address of a pointer to FIT, 40h back from the end of flash chip +#define INTEL_FIT_POINTER_OFFSET 0x40 + +// Entry types +// https://cdrdv2-public.intel.com/599500/Firmware-Interface-Table-BIOS-Specification-r1p4.pdf +#define INTEL_FIT_TYPE_HEADER 0x00 +#define INTEL_FIT_TYPE_MICROCODE 0x01 +#define INTEL_FIT_TYPE_STARTUP_AC_MODULE 0x02 +#define INTEL_FIT_TYPE_DIAG_AC_MODULE 0x03 +#define INTEL_FIT_TYPE_PLATFORM_BOOT_POLICY 0x04 +//#define INTEL_FIT_TYPE_INTEL_RESERVED_05 0x05 +#define INTEL_FIT_TYPE_FIT_RESET_STATE 0x06 +#define INTEL_FIT_TYPE_BIOS_STARTUP_MODULE 0x07 +#define INTEL_FIT_TYPE_TPM_POLICY 0x08 +#define INTEL_FIT_TYPE_BIOS_POLICY 0x09 +#define INTEL_FIT_TYPE_TXT_POLICY 0x0A +#define INTEL_FIT_TYPE_BOOT_GUARD_KEY_MANIFEST 0x0B +#define INTEL_FIT_TYPE_BOOT_GUARD_BOOT_POLICY 0x0C +//#define INTEL_FIT_TYPE_INTEL_RESERVED_0D 0x0D +//#define INTEL_FIT_TYPE_INTEL_RESERVED_0E 0x0E +//#define INTEL_FIT_TYPE_INTEL_RESERVED_0F 0x0F +#define INTEL_FIT_TYPE_CSE_SECURE_BOOT 0x10 +//#define INTEL_FIT_TYPE_INTEL_RESERVED_11 0x11 +//... +//#define INTEL_FIT_TYPE_INTEL_RESERVED_19 0x19 +#define INTEL_FIT_TYPE_VAB_PROVISIONING_TABLE 0x1A +#define INTEL_FIT_TYPE_VAB_KEY_MANIFEST 0x1B +#define INTEL_FIT_TYPE_VAB_IMAGE_MANIFEST 0x1C +#define INTEL_FIT_TYPE_VAB_IMAGE_HASH_DESCRIPTORS 0x1D +//#define INTEL_FIT_TYPE_INTEL_RESERVED_1E 0x1E +//... +//#define INTEL_FIT_TYPE_INTEL_RESERVED_2B 0x2B +#define INTEL_FIT_TYPE_SACM_DEBUG_RECORD 0x2C +#define INTEL_FIT_TYPE_ACM_FEATURE_POLICY 0x2D +#define INTEL_FIT_TYPE_SCRTM_ERROR_RECORD 0x2E +#define INTEL_FIT_TYPE_JMP_DEBUG_POLICY 0x2F +#define INTEL_FIT_TYPE_OEM_RESERVED_30 0x30 +//... +#define INTEL_FIT_TYPE_OEM_RESERVED_70 0x70 +//#define INTEL_FIT_TYPE_INTEL_RESERVED_71 0x71 +//... +//#define INTEL_FIT_TYPE_INTEL_RESERVED_7E 0x7E +#define INTEL_FIT_TYPE_EMPTY 0x7F + +typedef struct INTEL_FIT_ENTRY_ { + UINT64 Address; // Base address of the component, must be 16-byte aligned + UINT32 Size : 24; // Size of the component, in multiple of 16 bytes + UINT32 Reserved : 8; // Reserved, must be set to zero + UINT16 Version; // BCD, minor in lower byte, major in upper byte + UINT8 Type : 7; // FIT entries must be aranged in ascending order of Type + UINT8 ChecksumValid : 1;// Checksum must be ignored if this bit is not set + UINT8 Checksum; // checksum8 of all the bytes in the component and this field must add to zero +} INTEL_FIT_ENTRY; + +// +// FIT Header (0x00) +// +// Can be exactly one entry of this type, the first one. +// If ChecksumValid bit is set, the whole FIT table must checksum8 to zero. +// Version must be 0x0100 +#define INTEL_FIT_SIGNATURE 0x2020205F5449465FULL // '_FIT_ ' + +// +// Microcode (0x01) +// +// At least one entry is required, more is optional +// Each entry must point to a valid base address +// Microcode slots can be empty (first 4 bytes at the base address are FF FF FF FF) +// Base address must be aligned to 16 bytes +// The item at the base address must not be compressed/encoded/encrypted +// ChecksumValid bit must be 0 +// Size is not used, should be set to 0 + +// +// Startup Authenticated Code Module (0x02) +// +// Optional, required for AC boot and BootGuard +// Address must point to a valid base address +// Points to the first byte of ACM header +// One MTRR base/limit pair is used to map Startup ACM, so +// MTRR_Base must be a multiple of MTRR_Size, the can be found by the following formula +// MTTR_Size = 2^(ceil(log2(Startup_ACM_Size))), i.e. the next integer that's a full power of 2 to Startup_ACM_Size +// The whole area of [MTRR_Base; MTRR_Base + MTRR_Size) is named +// Authenticated Code Execution Area (ACEA) and should not contain any code or data that is not the Startup ACM itself +// ChecksumValid bit must be 0 +// Size is not used, should be set to 0 +// Version must be 0x0100 +#define INTEL_ACM_HARDCODED_RSA_EXPONENT 0x10001 + +// +// TPM Boot Policy (0x08) +// +// Optional, used for legacy TXT FIT boot, if used, can be only one +// Address entry is INTEL_FIT_POLICY_PTR.IndexIo if Version is 0, +// or INTEL_FIT_INDEX_IO_ADDRESS.FlatMemoryAddress if Version is 1 +// Bit 0 at the pointed address holds the TPM policy, 0 - TPM disabled, 1 - TPM enabled +// ChecksumValid bit must be 0 +// Size is not used, should be set to 0 +typedef struct INTEL_FIT_INDEX_IO_ADDRESS_ { + UINT16 IndexRegisterAddress; + UINT16 DataRegisterAddress; + UINT8 AccessWidthInBytes; // 1 => 1-byte accesses, 2 => 2-byte + UINT8 BitPosition; // Bit number, 15 => Bit15 + UINT16 Index; +} INTEL_FIT_INDEX_IO_ADDRESS; + +typedef union INTEL_FIT_POLICY_PTR_ { + UINT64 FlatMemoryAddress; + INTEL_FIT_INDEX_IO_ADDRESS IndexIo; +} INTEL_FIT_POLICY_PTR; + +#define INTEL_FIT_POLICY_VERSION_INDEX_IO 0 +#define INTEL_FIT_POLICY_VERSION_FLAT_MEMORY_ADDRESS 1 + +#define INTEL_FIT_POLICY_DISABLED 1 +#define INTEL_FIT_POLICY_ENABLED 1 + +// +// CSE SecureBoot (0x10) +// +// Optional, can be multiple, order is not important +// If present, BootGuardKeyManifest and BootGuardBootPolicy should also be present +// Reserved field further determines the subtype of this entry +// ChecksumValid bit must be 0 +// Version must be 0x0100 + +#define INTEL_FIT_CSE_SECURE_BOOT_RESERVED 0 +#define INTEL_FIT_CSE_SECURE_BOOT_KEY_HASH 1 +#define INTEL_FIT_CSE_SECURE_BOOT_CSE_MEASUREMENT_HASH 2 +#define INTEL_FIT_CSE_SECURE_BOOT_BOOT_POLICY 3 +#define INTEL_FIT_CSE_SECURE_BOOT_OTHER_BOOT_POLICY 4 +#define INTEL_FIT_CSE_SECURE_BOOT_OEM_SMIP 5 +#define INTEL_FIT_CSE_SECURE_BOOT_MRC_TRAINING_DATA 6 +#define INTEL_FIT_CSE_SECURE_BOOT_IBBL_HASH 7 +#define INTEL_FIT_CSE_SECURE_BOOT_IBB_HASH 8 +#define INTEL_FIT_CSE_SECURE_BOOT_OEM_ID 9 +#define INTEL_FIT_CSE_SECURE_BOOT_OEM_SKU_ID 10 +#define INTEL_FIT_CSE_SECURE_BOOT_BOOT_DEVICE_INDICATOR 11 // 1 => SPI, 2 => eMMC, 3 => UFS, rest => reserved +#define INTEL_FIT_CSE_SECURE_BOOT_FIT_PATCH_MANIFEST 12 +#define INTEL_FIT_CSE_SECURE_BOOT_AC_MODULE_MANIFEST 13 + +#pragma pack(pop) + +#endif // INTEL_FIT_H diff --git a/common/intel_microcode.h b/common/intel_microcode.h new file mode 100644 index 0000000..04354ce --- /dev/null +++ b/common/intel_microcode.h @@ -0,0 +1,71 @@ +/* intel_microcode.h + +Copyright (c) 2022, Nikolaj Schlej. All rights reserved. +This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +*/ + +#ifndef INTEL_MICROCODE_H +#define INTEL_MICROCODE_H + +#include "basetypes.h" +#include "ubytearray.h" + +// Make sure we use right packing rules +#pragma pack(push, 1) + +// This structure is described in Section 9.11.1 of the Intel Software Developer manual Volume 3A Part 1 +typedef struct INTEL_MICROCODE_HEADER_ { + UINT32 HeaderType; // 0x00000001 for Microcode (we do not need to support IFS yet) + UINT32 UpdateRevision; + UINT16 DateYear; // BCD + UINT8 DateDay; // BCD + UINT8 DateMonth; // BCD + UINT32 ProcessorSignature; + UINT32 Checksum; // Checksum of Update Data and Header. Used to verify the integrity of the update header and data. + // Checksum is correct when the summation of all the DWORDs (including the extended Processor Signature Table) + // that comprise the microcode update result in 00000000H. + UINT32 LoaderRevision; // 0x00000001 + UINT32 PlatformIds; // Platform Ids + UINT32 DataSize; // Specifies the size of the encrypted data in bytes, and must be a multiple of DWORDs. + // If this value is 00000000H, then the microcode update encrypted data is 2000 bytes (or 500 DWORDs). + // Sane values are less than 0x1000000 + UINT32 TotalSize; // Specifies the total size of the microcode update in bytes. + // It is the summation of the header size, the encrypted data size and the size of the optional extended signature table. + // This value is always a multiple of 1024 according to the spec, but Intel already breached it several times. + // Sane values are less than 0x1000000 + UINT32 MetadataSize; // Reserved in Microcode headers + UINT32 UpdateRevisionMin; // Minimum required version for OS Kernel Late Loading + UINT32 Reserved; // Zeroes +} INTEL_MICROCODE_HEADER; + +#define INTEL_MICROCODE_REAL_DATA_SIZE_ON_ZERO 2000 + +typedef struct INTEL_MICROCODE_EXTENDED_HEADER_ { + UINT32 EntryCount; + UINT32 Checksum; // Checksum of extended processor signature table. + // Used to verify the integrity of the extended processor signature table. + // Checksum is correct when the summation of the DWORDs that comprise the extended processor signature table results in 00000000H. + + UINT8 Reserved[12]; + // INTEL_MICROCODE_EXTENDED_HEADER_ENTRY Entries[EntryCount]; +} INTEL_MICROCODE_EXTENDED_HEADER; + +typedef struct INTEL_MICROCODE_EXTENDED_HEADER_ENTRY_ { + UINT32 ProcessorSignature; + UINT32 PlatformIds; + UINT32 Checksum; // To calculate the Checksum, substitute the Primary Processor Signature entry and the Platform Ids entry with the corresponding Extended Patch entry. + // Delete the Extended Processor Signature Table entries. + // Checksum is correct when the summation of all DWORDs that comprise the created Extended Processor Patch results in 00000000H. +} INTEL_MICROCODE_EXTENDED_HEADER_ENTRY; + +#define INTEL_MICROCODE_HEADER_VERSION_1 0x00000001 + +#pragma pack(pop) + +#endif // INTEL_MICROCODE_H diff --git a/common/kaitai/custom_decoder.h b/common/kaitai/custom_decoder.h new file mode 100644 index 0000000..6da7f5f --- /dev/null +++ b/common/kaitai/custom_decoder.h @@ -0,0 +1,16 @@ +#ifndef KAITAI_CUSTOM_DECODER_H +#define KAITAI_CUSTOM_DECODER_H + +#include + +namespace kaitai { + +class custom_decoder { +public: + virtual ~custom_decoder() {}; + virtual std::string decode(std::string src) = 0; +}; + +} + +#endif diff --git a/common/kaitai/exceptions.h b/common/kaitai/exceptions.h new file mode 100644 index 0000000..bb414dc --- /dev/null +++ b/common/kaitai/exceptions.h @@ -0,0 +1,189 @@ +#ifndef KAITAI_EXCEPTIONS_H +#define KAITAI_EXCEPTIONS_H + +#include "kaitaistream.h" + +#include +#include + +// We need to use "noexcept" in virtual destructor of our exceptions +// subclasses. Different compilers have different ideas on how to +// achieve that: C++98 compilers prefer `throw()`, C++11 and later +// use `noexcept`. We define KS_NOEXCEPT macro for that. + +#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1900) +#define KS_NOEXCEPT noexcept +#else +#define KS_NOEXCEPT throw() +#endif + +namespace kaitai { + +/** + * Common ancestor for all error originating from Kaitai Struct usage. + * Stores KSY source path, pointing to an element supposedly guilty of + * an error. + */ +class kstruct_error: public std::runtime_error { +public: + kstruct_error(const std::string what, const std::string src_path): + std::runtime_error(src_path + ": " + what), + m_src_path(src_path) + { + } + + virtual ~kstruct_error() KS_NOEXCEPT {}; + +protected: + const std::string m_src_path; +}; + +/** + * Error that occurs when default endianness should be decided with + * a switch, but nothing matches (although using endianness expression + * implies that there should be some positive result). + */ +class undecided_endianness_error: public kstruct_error { +public: + undecided_endianness_error(const std::string src_path): + kstruct_error("unable to decide on endianness for a type", src_path) + { + } + + virtual ~undecided_endianness_error() KS_NOEXCEPT {}; +}; + +/** + * Common ancestor for all validation failures. Stores pointer to + * KaitaiStream IO object which was involved in an error. + */ +class validation_failed_error: public kstruct_error { +public: + validation_failed_error(const std::string what, kstream* io, const std::string src_path): + kstruct_error("at pos " + kstream::to_string(io->pos()) + ": validation failed: " + what, src_path), + m_io(io) + { + } + +// "at pos #{io.pos}: validation failed: #{msg}" + + virtual ~validation_failed_error() KS_NOEXCEPT {}; + +protected: + kstream* m_io; +}; + +/** + * Signals validation failure: we required "actual" value to be equal to + * "expected", but it turned out that it's not. + */ +template +class validation_not_equal_error: public validation_failed_error { +public: + validation_not_equal_error(const T& expected, const T& actual, kstream* io, const std::string src_path): + validation_failed_error("not equal", io, src_path), + m_expected(expected), + m_actual(actual) + { + } + + // "not equal, expected #{expected.inspect}, but got #{actual.inspect}" + + virtual ~validation_not_equal_error() KS_NOEXCEPT {}; + +protected: + const T& m_expected; + const T& m_actual; +}; + +/** + * Signals validation failure: we required "actual" value to be greater + * than or equal to "min", but it turned out that it's not. + */ +template +class validation_less_than_error: public validation_failed_error { +public: + validation_less_than_error(const T& min, const T& actual, kstream* io, const std::string src_path): + validation_failed_error("not in range", io, src_path), + m_min(min), + m_actual(actual) + { + } + + // "not in range, min #{min.inspect}, but got #{actual.inspect}" + + virtual ~validation_less_than_error() KS_NOEXCEPT {}; + +protected: + const T& m_min; + const T& m_actual; +}; + +/** + * Signals validation failure: we required "actual" value to be less + * than or equal to "max", but it turned out that it's not. + */ +template +class validation_greater_than_error: public validation_failed_error { +public: + validation_greater_than_error(const T& max, const T& actual, kstream* io, const std::string src_path): + validation_failed_error("not in range", io, src_path), + m_max(max), + m_actual(actual) + { + } + + // "not in range, max #{max.inspect}, but got #{actual.inspect}" + + virtual ~validation_greater_than_error() KS_NOEXCEPT {}; + +protected: + const T& m_max; + const T& m_actual; +}; + +/** + * Signals validation failure: we required "actual" value to be from + * the list, but it turned out that it's not. + */ +template +class validation_not_any_of_error: public validation_failed_error { +public: + validation_not_any_of_error(const T& actual, kstream* io, const std::string src_path): + validation_failed_error("not any of the list", io, src_path), + m_actual(actual) + { + } + + // "not any of the list, got #{actual.inspect}" + + virtual ~validation_not_any_of_error() KS_NOEXCEPT {}; + +protected: + const T& m_actual; +}; + +/** + * Signals validation failure: we required "actual" value to match + * the expression, but it turned out that it doesn't. + */ +template +class validation_expr_error: public validation_failed_error { +public: + validation_expr_error(const T& actual, kstream* io, const std::string src_path): + validation_failed_error("not matching the expression", io, src_path), + m_actual(actual) + { + } + + // "not matching the expression, got #{actual.inspect}" + + virtual ~validation_expr_error() KS_NOEXCEPT {}; + +protected: + const T& m_actual; +}; + +} + +#endif diff --git a/common/kaitai/kaitaistream.cpp b/common/kaitai/kaitaistream.cpp new file mode 100644 index 0000000..212912e --- /dev/null +++ b/common/kaitai/kaitaistream.cpp @@ -0,0 +1,709 @@ +#include "kaitaistream.h" + +#define KS_STR_ENCODING_NONE + +// macOS +#if defined(__APPLE__) +#include +#include +#define bswap_16(x) OSSwapInt16(x) +#define bswap_32(x) OSSwapInt32(x) +#define bswap_64(x) OSSwapInt64(x) +#define __BYTE_ORDER BYTE_ORDER +#define __BIG_ENDIAN BIG_ENDIAN +#define __LITTLE_ENDIAN LITTLE_ENDIAN +// Windows with MS or MinGW compilers +#elif defined(_MSC_VER) || defined(__MINGW32__) +#include +#define __LITTLE_ENDIAN 1234 +#define __BIG_ENDIAN 4321 +#define __BYTE_ORDER __LITTLE_ENDIAN +#define bswap_16(x) _byteswap_ushort(x) +#define bswap_32(x) _byteswap_ulong(x) +#define bswap_64(x) _byteswap_uint64(x) +// BSD +#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) +#include +#define bswap_16(x) bswap16(x) +#define bswap_32(x) bswap32(x) +#define bswap_64(x) bswap64(x) +#elif defined(__OpenBSD__) +#include +#define bswap_16(x) swap16(x) +#define bswap_32(x) swap32(x) +#define bswap_64(x) swap64(x) +// Everything else +#else +#include +#include +#endif + +#include +#include +#include + +kaitai::kstream::kstream(std::istream *io) { + m_io = io; + init(); +} + +kaitai::kstream::kstream(const std::string &data) : m_io_str(data) { + m_io = &m_io_str; + init(); +} + +void kaitai::kstream::init() { + exceptions_enable(); + align_to_byte(); +} + +void kaitai::kstream::close() { + // m_io->close(); +} + +void kaitai::kstream::exceptions_enable() const { + m_io->exceptions( + std::istream::eofbit | + std::istream::failbit | + std::istream::badbit + ); +} + +// ======================================================================== +// Stream positioning +// ======================================================================== + +bool kaitai::kstream::is_eof() const { + if (m_bits_left > 0) { + return false; + } + char t; + m_io->exceptions(std::istream::badbit); + m_io->get(t); + if (m_io->eof()) { + m_io->clear(); + exceptions_enable(); + return true; + } else { + m_io->unget(); + exceptions_enable(); + return false; + } +} + +void kaitai::kstream::seek(uint64_t pos) { + m_io->seekg(pos); +} + +uint64_t kaitai::kstream::pos() { + return m_io->tellg(); +} + +uint64_t kaitai::kstream::size() { + std::iostream::pos_type cur_pos = m_io->tellg(); + m_io->seekg(0, std::ios::end); + std::iostream::pos_type len = m_io->tellg(); + m_io->seekg(cur_pos); + return len; +} + +// ======================================================================== +// Integer numbers +// ======================================================================== + +// ------------------------------------------------------------------------ +// Signed +// ------------------------------------------------------------------------ + +int8_t kaitai::kstream::read_s1() { + char t; + m_io->get(t); + return t; +} + +// ........................................................................ +// Big-endian +// ........................................................................ + +int16_t kaitai::kstream::read_s2be() { + int16_t t; + m_io->read(reinterpret_cast(&t), 2); +#if __BYTE_ORDER == __LITTLE_ENDIAN + t = bswap_16(t); +#endif + return t; +} + +int32_t kaitai::kstream::read_s4be() { + int32_t t; + m_io->read(reinterpret_cast(&t), 4); +#if __BYTE_ORDER == __LITTLE_ENDIAN + t = bswap_32(t); +#endif + return t; +} + +int64_t kaitai::kstream::read_s8be() { + int64_t t; + m_io->read(reinterpret_cast(&t), 8); +#if __BYTE_ORDER == __LITTLE_ENDIAN + t = bswap_64(t); +#endif + return t; +} + +// ........................................................................ +// Little-endian +// ........................................................................ + +int16_t kaitai::kstream::read_s2le() { + int16_t t; + m_io->read(reinterpret_cast(&t), 2); +#if __BYTE_ORDER == __BIG_ENDIAN + t = bswap_16(t); +#endif + return t; +} + +int32_t kaitai::kstream::read_s4le() { + int32_t t; + m_io->read(reinterpret_cast(&t), 4); +#if __BYTE_ORDER == __BIG_ENDIAN + t = bswap_32(t); +#endif + return t; +} + +int64_t kaitai::kstream::read_s8le() { + int64_t t; + m_io->read(reinterpret_cast(&t), 8); +#if __BYTE_ORDER == __BIG_ENDIAN + t = bswap_64(t); +#endif + return t; +} + +// ------------------------------------------------------------------------ +// Unsigned +// ------------------------------------------------------------------------ + +uint8_t kaitai::kstream::read_u1() { + char t; + m_io->get(t); + return t; +} + +// ........................................................................ +// Big-endian +// ........................................................................ + +uint16_t kaitai::kstream::read_u2be() { + uint16_t t; + m_io->read(reinterpret_cast(&t), 2); +#if __BYTE_ORDER == __LITTLE_ENDIAN + t = bswap_16(t); +#endif + return t; +} + +uint32_t kaitai::kstream::read_u4be() { + uint32_t t; + m_io->read(reinterpret_cast(&t), 4); +#if __BYTE_ORDER == __LITTLE_ENDIAN + t = bswap_32(t); +#endif + return t; +} + +uint64_t kaitai::kstream::read_u8be() { + uint64_t t; + m_io->read(reinterpret_cast(&t), 8); +#if __BYTE_ORDER == __LITTLE_ENDIAN + t = bswap_64(t); +#endif + return t; +} + +// ........................................................................ +// Little-endian +// ........................................................................ + +uint16_t kaitai::kstream::read_u2le() { + uint16_t t; + m_io->read(reinterpret_cast(&t), 2); +#if __BYTE_ORDER == __BIG_ENDIAN + t = bswap_16(t); +#endif + return t; +} + +uint32_t kaitai::kstream::read_u4le() { + uint32_t t; + m_io->read(reinterpret_cast(&t), 4); +#if __BYTE_ORDER == __BIG_ENDIAN + t = bswap_32(t); +#endif + return t; +} + +uint64_t kaitai::kstream::read_u8le() { + uint64_t t; + m_io->read(reinterpret_cast(&t), 8); +#if __BYTE_ORDER == __BIG_ENDIAN + t = bswap_64(t); +#endif + return t; +} + +// ======================================================================== +// Floating point numbers +// ======================================================================== + +// ........................................................................ +// Big-endian +// ........................................................................ + +/* +float kaitai::kstream::read_f4be() { + uint32_t t; + m_io->read(reinterpret_cast(&t), 4); +#if __BYTE_ORDER == __LITTLE_ENDIAN + t = bswap_32(t); +#endif + return reinterpret_cast(t); +} + +double kaitai::kstream::read_f8be() { + uint64_t t; + m_io->read(reinterpret_cast(&t), 8); +#if __BYTE_ORDER == __LITTLE_ENDIAN + t = bswap_64(t); +#endif + return reinterpret_cast(t); +} + +// ........................................................................ +// Little-endian +// ........................................................................ + +float kaitai::kstream::read_f4le() { + uint32_t t; + m_io->read(reinterpret_cast(&t), 4); +#if __BYTE_ORDER == __BIG_ENDIAN + t = bswap_32(t); +#endif + return reinterpret_cast(t); +} + +double kaitai::kstream::read_f8le() { + uint64_t t; + m_io->read(reinterpret_cast(&t), 8); +#if __BYTE_ORDER == __BIG_ENDIAN + t = bswap_64(t); +#endif + return reinterpret_cast(t); +} +*/ + +// ======================================================================== +// Unaligned bit values +// ======================================================================== + +void kaitai::kstream::align_to_byte() { + m_bits_left = 0; + m_bits = 0; +} + +uint64_t kaitai::kstream::read_bits_int_be(int n) { + uint64_t res = 0; + + int bits_needed = n - m_bits_left; + m_bits_left = -bits_needed & 7; // `-bits_needed mod 8` + + if (bits_needed > 0) { + // 1 bit => 1 byte + // 8 bits => 1 byte + // 9 bits => 2 bytes + int bytes_needed = ((bits_needed - 1) / 8) + 1; // `ceil(bits_needed / 8)` + if (bytes_needed > 8) + throw std::runtime_error("read_bits_int_be: more than 8 bytes requested"); + uint8_t buf[8]; + m_io->read(reinterpret_cast(buf), bytes_needed); + for (int i = 0; i < bytes_needed; i++) { + res = res << 8 | buf[i]; + } + + uint64_t new_bits = res; + res = res >> m_bits_left | (bits_needed < 64 ? m_bits << bits_needed : 0); // avoid undefined behavior of `x << 64` + m_bits = new_bits; // will be masked at the end of the function + } else { + res = m_bits >> -bits_needed; // shift unneeded bits out + } + + uint64_t mask = (UINT64_C(1) << m_bits_left) - 1; // `m_bits_left` is in range 0..7, so `(1 << 64)` does not have to be considered + m_bits &= mask; + + return res; +} + +// Deprecated, use read_bits_int_be() instead. +uint64_t kaitai::kstream::read_bits_int(int n) { + return read_bits_int_be(n); +} + +uint64_t kaitai::kstream::read_bits_int_le(int n) { + uint64_t res = 0; + int bits_needed = n - m_bits_left; + + if (bits_needed > 0) { + // 1 bit => 1 byte + // 8 bits => 1 byte + // 9 bits => 2 bytes + int bytes_needed = ((bits_needed - 1) / 8) + 1; // `ceil(bits_needed / 8)` + if (bytes_needed > 8) + throw std::runtime_error("read_bits_int_le: more than 8 bytes requested"); + uint8_t buf[8]; + m_io->read(reinterpret_cast(buf), bytes_needed); + for (int i = 0; i < bytes_needed; i++) { + res |= static_cast(buf[i]) << (i * 8); + } + + // NB: for bit shift operators in C++, "if the value of the right operand is + // negative or is greater or equal to the number of bits in the promoted left + // operand, the behavior is undefined." (see + // https://en.cppreference.com/w/cpp/language/operator_arithmetic#Bitwise_shift_operators) + // So we define our desired behavior here. + uint64_t new_bits = bits_needed < 64 ? res >> bits_needed : 0; + res = res << m_bits_left | m_bits; + m_bits = new_bits; + } else { + res = m_bits; + m_bits >>= n; + } + + m_bits_left = -bits_needed & 7; // `-bits_needed mod 8` + + if (n < 64) { + uint64_t mask = (UINT64_C(1) << n) - 1; + res &= mask; + } + // if `n == 64`, do nothing + return res; +} + +// ======================================================================== +// Byte arrays +// ======================================================================== + +std::string kaitai::kstream::read_bytes(std::streamsize len) { + std::vector result(len); + + // NOTE: streamsize type is signed, negative values are only *supposed* to not be used. + // http://en.cppreference.com/w/cpp/io/streamsize + if (len < 0) { + throw std::runtime_error("read_bytes: requested a negative amount"); + } + + if (len > 0) { + m_io->read(&result[0], len); + } + + return std::string(result.begin(), result.end()); +} + +std::string kaitai::kstream::read_bytes_full() { + std::iostream::pos_type p1 = m_io->tellg(); + m_io->seekg(0, std::ios::end); + std::iostream::pos_type p2 = m_io->tellg(); + size_t len = p2 - p1; + + // Note: this requires a std::string to be backed with a + // contiguous buffer. Officially, it's a only requirement since + // C++11 (C++98 and C++03 didn't have this requirement), but all + // major implementations had contiguous buffers anyway. + std::string result(len, ' '); + m_io->seekg(p1); + m_io->read(&result[0], len); + + return result; +} + +std::string kaitai::kstream::read_bytes_term(char term, bool include, bool consume, bool eos_error) { + std::string result; + std::getline(*m_io, result, term); + if (m_io->eof()) { + // encountered EOF + if (eos_error) { + throw std::runtime_error("read_bytes_term: encountered EOF"); + } + } else { + // encountered terminator + if (include) + result.push_back(term); + if (!consume) + m_io->unget(); + } + return result; +} + +std::string kaitai::kstream::ensure_fixed_contents(std::string expected) { + std::string actual = read_bytes(expected.length()); + + if (actual != expected) { + // NOTE: I think printing it outright is not best idea, it could contain non-ASCII characters + // like backspace and beeps and whatnot. It would be better to print hexlified version, and + // also to redirect it to stderr. + throw std::runtime_error("ensure_fixed_contents: actual data does not match expected data"); + } + + return actual; +} + +std::string kaitai::kstream::bytes_strip_right(std::string src, char pad_byte) { + std::size_t new_len = src.length(); + + while (new_len > 0 && src[new_len - 1] == pad_byte) + new_len--; + + return src.substr(0, new_len); +} + +std::string kaitai::kstream::bytes_terminate(std::string src, char term, bool include) { + std::size_t new_len = 0; + std::size_t max_len = src.length(); + + while (new_len < max_len && src[new_len] != term) + new_len++; + + if (include && new_len < max_len) + new_len++; + + return src.substr(0, new_len); +} + +// ======================================================================== +// Byte array processing +// ======================================================================== + +std::string kaitai::kstream::process_xor_one(std::string data, uint8_t key) { + size_t len = data.length(); + std::string result(len, ' '); + + for (size_t i = 0; i < len; i++) + result[i] = data[i] ^ key; + + return result; +} + +std::string kaitai::kstream::process_xor_many(std::string data, std::string key) { + size_t len = data.length(); + size_t kl = key.length(); + std::string result(len, ' '); + + size_t ki = 0; + for (size_t i = 0; i < len; i++) { + result[i] = data[i] ^ key[ki]; + ki++; + if (ki >= kl) + ki = 0; + } + + return result; +} + +std::string kaitai::kstream::process_rotate_left(std::string data, int amount) { + size_t len = data.length(); + std::string result(len, ' '); + + for (size_t i = 0; i < len; i++) { + uint8_t bits = data[i]; + result[i] = (bits << amount) | (bits >> (8 - amount)); + } + + return result; +} + +#ifdef KS_ZLIB +#include + +std::string kaitai::kstream::process_zlib(std::string data) { + int ret; + + unsigned char *src_ptr = reinterpret_cast(&data[0]); + std::stringstream dst_strm; + + z_stream strm; + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + + ret = inflateInit(&strm); + if (ret != Z_OK) + throw std::runtime_error("process_zlib: inflateInit error"); + + strm.next_in = src_ptr; + strm.avail_in = data.length(); + + unsigned char outbuffer[ZLIB_BUF_SIZE]; + std::string outstring; + + // get the decompressed bytes blockwise using repeated calls to inflate + do { + strm.next_out = reinterpret_cast(outbuffer); + strm.avail_out = sizeof(outbuffer); + + ret = inflate(&strm, 0); + + if (outstring.size() < strm.total_out) + outstring.append(reinterpret_cast(outbuffer), strm.total_out - outstring.size()); + } while (ret == Z_OK); + + if (ret != Z_STREAM_END) { // an error occurred that was not EOF + std::ostringstream exc_msg; + exc_msg << "process_zlib: error #" << ret << "): " << strm.msg; + throw std::runtime_error(exc_msg.str()); + } + + if (inflateEnd(&strm) != Z_OK) + throw std::runtime_error("process_zlib: inflateEnd error"); + + return outstring; +} +#endif + +// ======================================================================== +// Misc utility methods +// ======================================================================== + +int kaitai::kstream::mod(int a, int b) { + if (b <= 0) + throw std::invalid_argument("mod: divisor b <= 0"); + int r = a % b; + if (r < 0) + r += b; + return r; +} + +#include +void kaitai::kstream::unsigned_to_decimal(uint64_t number, char *buffer) { + // Implementation from https://ideone.com/nrQfA8 by Alf P. Steinbach + // (see https://www.zverovich.net/2013/09/07/integer-to-string-conversion-in-cplusplus.html#comment-1033931478) + if (number == 0) { + *buffer++ = '0'; + } else { + char *p_first = buffer; + while (number != 0) { + *buffer++ = static_cast('0' + number % 10); + number /= 10; + } + std::reverse(p_first, buffer); + } + *buffer = '\0'; +} + +std::string kaitai::kstream::reverse(std::string val) { + std::reverse(val.begin(), val.end()); + + return val; +} + +uint8_t kaitai::kstream::byte_array_min(const std::string val) { + uint8_t min = 0xff; // UINT8_MAX + std::string::const_iterator end = val.end(); + for (std::string::const_iterator it = val.begin(); it != end; ++it) { + uint8_t cur = static_cast(*it); + if (cur < min) { + min = cur; + } + } + return min; +} + +uint8_t kaitai::kstream::byte_array_max(const std::string val) { + uint8_t max = 0; // UINT8_MIN + std::string::const_iterator end = val.end(); + for (std::string::const_iterator it = val.begin(); it != end; ++it) { + uint8_t cur = static_cast(*it); + if (cur > max) { + max = cur; + } + } + return max; +} + +// ======================================================================== +// Other internal methods +// ======================================================================== + +#ifndef KS_STR_DEFAULT_ENCODING +#define KS_STR_DEFAULT_ENCODING "UTF-8" +#endif + +#ifdef KS_STR_ENCODING_ICONV + +#include +#include +#include + +std::string kaitai::kstream::bytes_to_str(std::string src, std::string src_enc) { + iconv_t cd = iconv_open(KS_STR_DEFAULT_ENCODING, src_enc.c_str()); + + if (cd == (iconv_t)-1) { + if (errno == EINVAL) { + throw std::runtime_error("bytes_to_str: invalid encoding pair conversion requested"); + } else { + throw std::runtime_error("bytes_to_str: error opening iconv"); + } + } + + size_t src_len = src.length(); + size_t src_left = src_len; + + // Start with a buffer length of double the source length. + size_t dst_len = src_len * 2; + std::string dst(dst_len, ' '); + size_t dst_left = dst_len; + + char *src_ptr = &src[0]; + char *dst_ptr = &dst[0]; + + while (true) { + size_t res = iconv(cd, &src_ptr, &src_left, &dst_ptr, &dst_left); + + if (res == (size_t)-1) { + if (errno == E2BIG) { + // dst buffer is not enough to accomodate whole string + // enlarge the buffer and try again + size_t dst_used = dst_len - dst_left; + dst_left += dst_len; + dst_len += dst_len; + dst.resize(dst_len); + + // dst.resize might have allocated destination buffer in another area + // of memory, thus our previous pointer "dst" will be invalid; re-point + // it using "dst_used". + dst_ptr = &dst[dst_used]; + } else { + throw std::runtime_error("bytes_to_str: iconv error"); + } + } else { + // conversion successful + dst.resize(dst_len - dst_left); + break; + } + } + + if (iconv_close(cd) != 0) { + throw std::runtime_error("bytes_to_str: iconv close error"); + } + + return dst; +} +#elif defined(KS_STR_ENCODING_NONE) +std::string kaitai::kstream::bytes_to_str(std::string src, std::string src_enc) { + (void)src_enc; + return src; +} +#else +#error Need to decide how to handle strings: please define one of: KS_STR_ENCODING_ICONV, KS_STR_ENCODING_NONE +#endif diff --git a/common/kaitai/kaitaistream.h b/common/kaitai/kaitaistream.h new file mode 100644 index 0000000..3a25a7d --- /dev/null +++ b/common/kaitai/kaitaistream.h @@ -0,0 +1,295 @@ +#ifndef KAITAI_STREAM_H +#define KAITAI_STREAM_H + +// Kaitai Struct runtime API version: x.y.z = 'xxxyyyzzz' decimal +#define KAITAI_STRUCT_VERSION 10000L + +#include +#include +#include +#include +#include + +namespace kaitai { + +/** + * Kaitai Stream class (kaitai::kstream) is an implementation of + * Kaitai Struct stream API + * for C++/STL. It's implemented as a wrapper over generic STL std::istream. + * + * It provides a wide variety of simple methods to read (parse) binary + * representations of primitive types, such as integer and floating + * point numbers, byte arrays and strings, and also provides stream + * positioning / navigation methods with unified cross-language and + * cross-toolkit semantics. + * + * Typically, end users won't access Kaitai Stream class manually, but would + * describe a binary structure format using .ksy language and then would use + * Kaitai Struct compiler to generate source code in desired target language. + * That code, in turn, would use this class and API to do the actual parsing + * job. + */ +class kstream { +public: + /** + * Constructs new Kaitai Stream object, wrapping a given std::istream. + * \param io istream object to use for this Kaitai Stream + */ + kstream(std::istream* io); + + /** + * Constructs new Kaitai Stream object, wrapping a given in-memory data + * buffer. + * \param data data buffer to use for this Kaitai Stream + */ + kstream(const std::string& data); + + void close(); + + /** @name Stream positioning */ + //@{ + /** + * Check if stream pointer is at the end of stream. Note that the semantics + * are different from traditional STL semantics: one does *not* need to do a + * read (which will fail) after the actual end of the stream to trigger EOF + * flag, which can be accessed after that read. It is sufficient to just be + * at the end of the stream for this method to return true. + * \return "true" if we are located at the end of the stream. + */ + bool is_eof() const; + + /** + * Set stream pointer to designated position. + * \param pos new position (offset in bytes from the beginning of the stream) + */ + void seek(uint64_t pos); + + /** + * Get current position of a stream pointer. + * \return pointer position, number of bytes from the beginning of the stream + */ + uint64_t pos(); + + /** + * Get total size of the stream in bytes. + * \return size of the stream in bytes + */ + uint64_t size(); + //@} + + /** @name Integer numbers */ + //@{ + + // ------------------------------------------------------------------------ + // Signed + // ------------------------------------------------------------------------ + + int8_t read_s1(); + + // ........................................................................ + // Big-endian + // ........................................................................ + + int16_t read_s2be(); + int32_t read_s4be(); + int64_t read_s8be(); + + // ........................................................................ + // Little-endian + // ........................................................................ + + int16_t read_s2le(); + int32_t read_s4le(); + int64_t read_s8le(); + + // ------------------------------------------------------------------------ + // Unsigned + // ------------------------------------------------------------------------ + + uint8_t read_u1(); + + // ........................................................................ + // Big-endian + // ........................................................................ + + uint16_t read_u2be(); + uint32_t read_u4be(); + uint64_t read_u8be(); + + // ........................................................................ + // Little-endian + // ........................................................................ + + uint16_t read_u2le(); + uint32_t read_u4le(); + uint64_t read_u8le(); + + //@} + + /** @name Floating point numbers */ + //@{ + + // ........................................................................ + // Big-endian + // ........................................................................ + + float read_f4be(); + double read_f8be(); + + // ........................................................................ + // Little-endian + // ........................................................................ + + float read_f4le(); + double read_f8le(); + + //@} + + /** @name Unaligned bit values */ + //@{ + + void align_to_byte(); + uint64_t read_bits_int_be(int n); + uint64_t read_bits_int(int n); + uint64_t read_bits_int_le(int n); + + //@} + + /** @name Byte arrays */ + //@{ + + std::string read_bytes(std::streamsize len); + std::string read_bytes_full(); + std::string read_bytes_term(char term, bool include, bool consume, bool eos_error); + std::string ensure_fixed_contents(std::string expected); + + static std::string bytes_strip_right(std::string src, char pad_byte); + static std::string bytes_terminate(std::string src, char term, bool include); + static std::string bytes_to_str(std::string src, std::string src_enc); + + //@} + + /** @name Byte array processing */ + //@{ + + /** + * Performs a XOR processing with given data, XORing every byte of input with a single + * given value. + * @param data data to process + * @param key value to XOR with + * @return processed data + */ + static std::string process_xor_one(std::string data, uint8_t key); + + /** + * Performs a XOR processing with given data, XORing every byte of input with a key + * array, repeating key array many times, if necessary (i.e. if data array is longer + * than key array). + * @param data data to process + * @param key array of bytes to XOR with + * @return processed data + */ + static std::string process_xor_many(std::string data, std::string key); + + /** + * Performs a circular left rotation shift for a given buffer by a given amount of bits, + * using groups of 1 bytes each time. Right circular rotation should be performed + * using this procedure with corrected amount. + * @param data source data to process + * @param amount number of bits to shift by + * @return copy of source array with requested shift applied + */ + static std::string process_rotate_left(std::string data, int amount); + +#ifdef KS_ZLIB + /** + * Performs an unpacking ("inflation") of zlib-compressed data with usual zlib headers. + * @param data data to unpack + * @return unpacked data + * @throws IOException + */ + static std::string process_zlib(std::string data); +#endif + + //@} + + /** + * Performs modulo operation between two integers: dividend `a` + * and divisor `b`. Divisor `b` is expected to be positive. The + * result is always 0 <= x <= b - 1. + */ + static int mod(int a, int b); + + /** + * Converts given integer `val` to a decimal string representation. + * Should be used in place of std::to_string() (which is available only + * since C++11) in older C++ implementations. + */ + template +// check for C++11 support - https://stackoverflow.com/a/40512515 +#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1900) + // https://stackoverflow.com/a/27913885 + typename std::enable_if< + std::is_integral::value && + // check if we don't have something too large like GCC's `__int128_t` + std::numeric_limits::max() >= 0 && + std::numeric_limits::max() <= std::numeric_limits::max(), + std::string + >::type +#else + std::string +#endif + static to_string(I val) { + // in theory, `digits10 + 3` would be enough (minus sign + leading digit + // + null terminator), but let's add a little more to be safe + char buf[std::numeric_limits::digits10 + 5]; + if (val < 0) { + buf[0] = '-'; + // get absolute value without undefined behavior (https://stackoverflow.com/a/12231604) + unsigned_to_decimal(-static_cast(val), &buf[1]); + } else { + unsigned_to_decimal(val, buf); + } + return std::string(buf); + } + + /** + * Reverses given string `val`, so that the first character becomes the + * last and the last one becomes the first. This should be used to avoid + * the need of local variables at the caller. + */ + static std::string reverse(std::string val); + + /** + * Finds the minimal byte in a byte array, treating bytes as + * unsigned values. + * @param val byte array to scan + * @return minimal byte in byte array as integer + */ + static uint8_t byte_array_min(const std::string val); + + /** + * Finds the maximal byte in a byte array, treating bytes as + * unsigned values. + * @param val byte array to scan + * @return maximal byte in byte array as integer + */ + static uint8_t byte_array_max(const std::string val); + +private: + std::istream* m_io; + std::istringstream m_io_str; + int m_bits_left; + uint64_t m_bits; + + void init(); + void exceptions_enable() const; + + static void unsigned_to_decimal(uint64_t number, char *buffer); + + static const int ZLIB_BUF_SIZE = 128 * 1024; +}; + +} + +#endif diff --git a/common/kaitai/kaitaistruct.h b/common/kaitai/kaitaistruct.h new file mode 100644 index 0000000..7b5acd6 --- /dev/null +++ b/common/kaitai/kaitaistruct.h @@ -0,0 +1,20 @@ +#ifndef KAITAI_STRUCT_H +#define KAITAI_STRUCT_H + +#include "kaitaistream.h" + +namespace kaitai { + +class kstruct { +public: + kstruct(kstream *_io) { m__io = _io; } + virtual ~kstruct() {} +protected: + kstream *m__io; +public: + kstream *_io() { return m__io; } +}; + +} + +#endif diff --git a/common/ksy/ami_nvar.ksy b/common/ksy/ami_nvar.ksy new file mode 100644 index 0000000..b90e5f2 --- /dev/null +++ b/common/ksy/ami_nvar.ksy @@ -0,0 +1,162 @@ +meta: + id: ami_nvar + title: AMI Aptio NVRAM Storage + application: AMI Aptio-based UEFI firmware + file-extension: nvar + tags: + - firmware + license: CC0-1.0 + ks-version: 0.9 + endian: le + +seq: +- id: entries + type: nvar_entry + repeat: until + repeat-until: _.signature_first != 0x4e or _io.eof + +types: + nvar_entry: + seq: + - id: invoke_offset + size: 0 + if: offset >= 0 + - id: signature_first + type: u1 + - id: signature_rest + contents: [VAR] + if: signature_first == 0x4e + - id: size + type: u2 + valid: + expr: _ > sizeof + sizeof + sizeof + if: signature_first == 0x4e + - id: next + type: b24le + if: signature_first == 0x4e + - id: attributes + type: nvar_attributes + if: signature_first == 0x4e + - id: body + type: nvar_entry_body + size: size - (sizeof + sizeof + sizeof) + if: signature_first == 0x4e + - id: invoke_end_offset + size: 0 + if: signature_first == 0x4e and end_offset >= 0 + instances: + offset: + value: _io.pos + end_offset: + value: _io.pos + + nvar_attributes: + seq: + - id: valid + type: b1 + - id: auth_write + type: b1 + - id: hw_error_record + type: b1 + - id: extended_header + type: b1 + - id: data_only + type: b1 + - id: local_guid + type: b1 + - id: ascii_name + type: b1 + - id: runtime + type: b1 + + nvar_extended_attributes: + seq: + - id: reserved_high + type: b2 + - id: time_based_auth + type: b1 + - id: auth_write + type: b1 + - id: reserved_low + type: b3 + - id: checksum + type: b1 + + ucs2_string: + seq: + - id: ucs2_chars + type: u2 + repeat: until + repeat-until: _ == 0 + + nvar_entry_body: + seq: + - id: guid_index + type: u1 + if: (not _parent.attributes.local_guid) + and (not _parent.attributes.data_only) + and (_parent.attributes.valid) + - id: guid + size: 16 + if: (_parent.attributes.local_guid) + and (not _parent.attributes.data_only) + and (_parent.attributes.valid) + - id: ascii_name + type: strz + encoding: ASCII + if: (_parent.attributes.ascii_name) + and (not _parent.attributes.data_only) + and (_parent.attributes.valid) + - id: ucs2_name + type: ucs2_string + if: (not _parent.attributes.ascii_name) + and (not _parent.attributes.data_only) + and (_parent.attributes.valid) + - id: invoke_data_start + size: 0 + if: data_start_offset >= 0 + - id: data + size-eos: true + instances: + extended_header_size_field: + pos: _io.pos - sizeof + type: u2 + if: _parent.attributes.valid + and _parent.attributes.extended_header + and _parent.size > sizeof + sizeof + sizeof + sizeof + extended_header_size: + value: '(_parent.attributes.extended_header and _parent.attributes.valid and (_parent.size > sizeof + sizeof + sizeof + sizeof)) ? (extended_header_size_field >= sizeof + sizeof ? extended_header_size_field : 0) : 0' + extended_header_attributes: + pos: _io.pos - extended_header_size + type: nvar_extended_attributes + if: _parent.attributes.valid + and _parent.attributes.extended_header + and (extended_header_size >= sizeof + sizeof) + extended_header_timestamp: + pos: _io.pos - extended_header_size + sizeof + type: u8 + if: _parent.attributes.valid + and _parent.attributes.extended_header + and (extended_header_size >= sizeof + sizeof + sizeof) + and extended_header_attributes.time_based_auth + extended_header_hash: + pos: _io.pos - extended_header_size + sizeof + sizeof + size: 32 + if: _parent.attributes.valid + and _parent.attributes.extended_header + and (extended_header_size >= sizeof + sizeof + 32 + sizeof) + and extended_header_attributes.time_based_auth + and (not _parent.attributes.data_only) + extended_header_checksum: + pos: _io.pos - sizeof - sizeof + type: u1 + if: _parent.attributes.valid + and _parent.attributes.extended_header + and (extended_header_size >= sizeof + sizeof + sizeof) + and extended_header_attributes.checksum + data_start_offset: + value: _io.pos + data_end_offset: + value: _io.pos + data_size: + value: (data_end_offset - data_start_offset) - extended_header_size diff --git a/common/ksy/apple_sysf.ksy b/common/ksy/apple_sysf.ksy new file mode 100644 index 0000000..4b6bb4f --- /dev/null +++ b/common/ksy/apple_sysf.ksy @@ -0,0 +1,58 @@ +meta: + id: apple_sysf + title: Apple System Flags store + application: Apple MacEFI-based UEFI firmware + file-extension: sysf + tags: + - firmware + license: CC0-1.0 + ks-version: 0.9 + endian: le + +seq: +- id: signature + type: u4 +- id: unknown + type: u1 +- id: unknown1 + type: u4 +- id: sysf_size + type: u2 +- id: body + type: sysf_store_body + size: sysf_size - len_sysf_store_header - sizeof +- id: crc + type: u4 + +instances: + len_sysf_store_header: + value: 11 + +types: + sysf_store_body: + seq: + - id: variables + type: sysf_variable + repeat: until + repeat-until: (_.len_name == 3 and _.name == "EOF") or _io.eof + - id: zeroes + type: u1 + repeat: eos + + sysf_variable: + seq: + - id: len_name + type: b7le + - id: invalid_flag + type: b1le + - id: name + type: strz + encoding: ascii + size: len_name + - id: len_data + type: u2 + if: name != "EOF" + - id: data + size: len_data + if: name != "EOF" + diff --git a/common/ksy/dell_dvar.ksy b/common/ksy/dell_dvar.ksy new file mode 100644 index 0000000..cdf07fa --- /dev/null +++ b/common/ksy/dell_dvar.ksy @@ -0,0 +1,91 @@ +meta: + id: dell_dvar + title: Dell DVAR Storage + application: Dell UEFI firmware + file-extension: dvar + tags: + - firmware + license: CC0-1.0 + ks-version: 0.9 + endian: le + +seq: + - id: signature + size: 4 + - id: len_store_c + type: u4 + - id: flags_c + type: u1 + - id: entries + type: dvar_entry + repeat: until + repeat-until: _.state_c == 0xFF + +instances: + len_store: + value: 0xFFFFFFFF - len_store_c + flags: + value: 0xFF - flags_c + data_offset: + value: 9 + +#TODO: find samples with different flags and types to make them flags insead of immediates + +types: + dvar_entry: + seq: + - id: state_c + type: u1 + - id: flags_c + type: u1 + if: state_c != 0xFF + - id: type_c + type: u1 + if: state_c != 0xFF + - id: attributes_c + type: u1 + if: state_c != 0xFF + - id: namespace_id_c + type: u1 + if: state_c != 0xFF and (flags == 2 or flags == 6) + - id: namespace_guid + size: 16 + if: state_c != 0xFF and flags == 6 + - id: name_id_8_c + type: u1 + if: state_c != 0xFF and type == 0 + - id: name_id_16_c + type: u2 + if: state_c != 0xFF and (type == 4 or type == 5) + - id: len_data_8_c + type: u1 + if: state_c != 0xFF and (type == 0 or type == 4) + - id: len_data_16_c + type: u2 + if: state_c != 0xFF and type == 5 + - id: data_8 + size: len_data_8 + if: state_c != 0xFF and (type == 0 or type == 4) + - id: data_16 + size: len_data_16 + if: state_c != 0xFF and type == 5 + + instances: + state: + value: 0xFF - state_c + flags: + value: 0xFF - flags_c + type: + value: 0xFF - type_c + attributes: + value: 0xFF - attributes_c + namespace_id: + value: 0xFF - namespace_id_c + name_id_8: + value: 0xFF - name_id_8_c + name_id_16: + value: 0xFFFF - name_id_16_c + len_data_8: + value: 0xFF - len_data_8_c + len_data_16: + value: 0xFFFF - len_data_16_c diff --git a/common/ksy/edk2_ftw.ksy b/common/ksy/edk2_ftw.ksy new file mode 100644 index 0000000..bed3013 --- /dev/null +++ b/common/ksy/edk2_ftw.ksy @@ -0,0 +1,37 @@ +meta: + id: edk2_ftw + title: EDK2 Fault Tolerant Write NVRAM store + application: EDK2-based UEFI firmware + file-extension: ftw + tags: + - firmware + license: CC0-1.0 + ks-version: 0.9 + endian: le + +seq: +- id: signature + size: 16 +- id: crc + type: u4 +- id: state + type: u1 +- id: reserved + size: 3 +- id: len_write_queue_32 + type: u4 +- id: len_write_queue_64 + type: u4 + if: len_write_queue_32 % 0x10 == 0 +- id: write_queue_32 + size: len_write_queue_32 + if: len_write_queue_32 % 0x10 == 0x04 +- id: write_queue_64 + size: ((len_write_queue_64.as) << 32) + len_write_queue_32 + if: len_write_queue_32 % 0x10 == 0 + +instances: + len_ftw_store_header_32: + value: 28 + len_ftw_store_header_64: + value: 32 diff --git a/common/ksy/edk2_vss.ksy b/common/ksy/edk2_vss.ksy new file mode 100644 index 0000000..8c6b5fd --- /dev/null +++ b/common/ksy/edk2_vss.ksy @@ -0,0 +1,158 @@ +meta: + id: edk2_vss + title: EDK2 VSS NVRAM store + application: EDK2-based UEFI firmware + file-extension: vss + tags: + - firmware + license: CC0-1.0 + ks-version: 0.9 + endian: le + +seq: +- id: signature + type: u4 +- id: vss_size + type: u4 + valid: + expr: _ > len_vss_store_header.as and _ < 0xFFFFFFFF +- id: format + type: u1 +- id: state + type: u1 +- id: reserved + type: u2 +- id: reserved1 + type: u4 +- id: body + type: vss_store_body + size: vss_size - len_vss_store_header +instances: + len_vss_store_header: + value: 16 + +types: + vss_store_body: + seq: + - id: variables + type: vss_variable + repeat: until + repeat-until: _.signature_first != 0xAA or _io.eof + + vss_variable_attributes: + seq: + - id: non_volatile + type: b1le + - id: boot_service + type: b1le + - id: runtime + type: b1le + - id: hw_error_record + type: b1le + - id: auth_write + type: b1le + - id: time_based_auth + type: b1le + - id: append_write + type: b1le + - id: reserved + type: b24le + - id: apple_data_checksum + type: b1le + + vss_variable: + seq: + - id: signature_first + type: u1 + - id: signature_last + type: u1 + valid: + expr: _ == 0x55 + if: signature_first == 0xAA + - id: state + type: u1 + if: signature_first == 0xAA + - id: reserved + type: u1 + if: signature_first == 0xAA + - id: attributes + type: vss_variable_attributes + if: signature_first == 0xAA +# vvv Intel legacy + - id: len_total + type: u4 + if: signature_first == 0xAA and is_intel_legacy + valid: + expr: _ >= len_intel_legacy_header.as + 4 + 1 # Header size + at least one UCS2 character for the name + UCS2 null terminator + at least one byte of data +# ^^^ Intel legacy +# Next 2 fields can be of any value for an authenticated variable due to them being a combined value of MonothonicCounter + - id: len_name + type: u4 + if: signature_first == 0xAA and not is_intel_legacy + - id: len_data + type: u4 + if: signature_first == 0xAA and not is_intel_legacy +# vvv Auth variable + - id: timestamp + size: 16 + if: signature_first == 0xAA and is_auth + - id: pubkey_index + type: u4 + if: signature_first == 0xAA and is_auth + - id: len_name_auth + type: u4 + if: signature_first == 0xAA and is_auth + valid: + expr: (_ >= 4) and (_ % 2 == 0) # UCS2 characters come in byte pairs + - id: len_data_auth + type: u4 + if: signature_first == 0xAA and is_auth + valid: + expr: _ > 0 +# ^^^ Auth variable + - id: vendor_guid + size: 16 + if: signature_first == 0xAA +# vvv Auth variable + - id: name_auth + size: len_name_auth + if: signature_first == 0xAA and is_auth + - id: data_auth + size: len_data_auth + if: signature_first == 0xAA and is_auth +# ^^^ Auth variable +# vvv Apple MacEFI + - id: apple_data_crc32 + type: u4 + if: signature_first == 0xAA and not is_intel_legacy and not is_auth and attributes.apple_data_checksum +# ^^^ Apple MacEFI +# vvv Intel legacy + - id: intel_legacy_data + size: len_total - len_intel_legacy_header + if: signature_first == 0xAA and is_intel_legacy +# ^^^ Intel legacy + - id: name + size: len_name + if: signature_first == 0xAA and not is_intel_legacy and not is_auth + valid: + expr: (len_name >= 4) and (len_name % 2 == 0) + - id: data + size: len_data + if: signature_first == 0xAA and not is_intel_legacy and not is_auth + valid: + expr: len_name > 0 + instances: + is_valid: + value: state == 0xFC or state == 0x7F or state == 0x3F + is_intel_legacy: + value: (state == 0xF8 or state == 0xFC) # Special states indicating Intel legacy variables + is_auth: + value: state != 0xF8 and state != 0xFC and ((attributes.auth_write or attributes.time_based_auth or attributes.append_write) or (len_name == 0 or len_data == 0)) + len_intel_legacy_header: + value: 28 + len_auth_header: + value: 60 + len_standard_header: + value: 32 + len_apple_header: + value: 36 diff --git a/common/ksy/edk2_vss2.ksy b/common/ksy/edk2_vss2.ksy new file mode 100644 index 0000000..bd4d149 --- /dev/null +++ b/common/ksy/edk2_vss2.ksy @@ -0,0 +1,150 @@ +meta: + id: edk2_vss2 + title: EDK2 VSS2 NVRAM variable storage + application: EDK2-based UEFI firmware + file-extension: vss2 + tags: + - firmware + license: CC0-1.0 + ks-version: 0.9 + endian: le + +seq: +- id: signature + size: 16 +- id: vss2_size + type: u4 + valid: + expr: _ > len_vss2_store_header.as and _ < 0xFFFFFFFF +- id: format + type: u1 +- id: state + type: u1 +- id: reserved + type: u2 +- id: reserved1 + type: u4 +- id: body + type: vss2_store_body + size: vss2_size - len_vss2_store_header + +instances: + len_vss2_store_header: + value: 7 * sizeof + +types: + vss2_store_body: + seq: + - id: variables + type: vss2_variable + repeat: until + repeat-until: _.signature_first != 0xAA or _io.eof + + vss2_variable_attributes: + seq: + - id: non_volatile + type: b1le + - id: boot_service + type: b1le + - id: runtime + type: b1le + - id: hw_error_record + type: b1le + - id: auth_write + type: b1le + - id: time_based_auth + type: b1le + - id: append_write + type: b1le + - id: reserved + type: b25le + + vss2_variable: + seq: + - id: invoke_offset + size: 0 + if: offset >= 0 + - id: signature_first + type: u1 + - id: signature_last + type: u1 + valid: + expr: _ == 0x55 + if: signature_first == 0xAA + - id: state + type: u1 + if: signature_first == 0xAA + - id: reserved + type: u1 + if: signature_first == 0xAA + - id: attributes + type: vss2_variable_attributes + if: signature_first == 0xAA + - id: len_name + type: u4 + if: signature_first == 0xAA + - id: len_data + type: u4 + if: signature_first == 0xAA +# vvv Auth variable + - id: timestamp + size: 16 + if: signature_first == 0xAA and is_auth + - id: pubkey_index + type: u4 + if: signature_first == 0xAA and is_auth + - id: len_name_auth + type: u4 + if: signature_first == 0xAA and is_auth + - id: len_data_auth + type: u4 + if: signature_first == 0xAA and is_auth +# ^^^ Auth variable + - id: vendor_guid + size: 16 + if: signature_first == 0xAA +# vvv Auth variable + - id: name_auth + size: len_name_auth + if: signature_first == 0xAA and is_auth + - id: data_auth + size: len_data_auth + if: signature_first == 0xAA and is_auth + - id: invoke_end_offset_auth + size: 0 + if: signature_first == 0xAA and is_auth and end_offset_auth >= 0 + - id: alignment_padding_auth + size: len_alignment_padding_auth + if: signature_first == 0xAA and is_auth +# ^^^ Auth variable + - id: name + size: len_name + if: signature_first == 0xAA and not is_auth + - id: data + size: len_data + if: signature_first == 0xAA and not is_auth + - id: invoke_end_offset + size: 0 + if: signature_first == 0xAA and not is_auth and end_offset >= 0 + - id: alignment_padding + size: len_alignment_padding + if: signature_first == 0xAA and not is_auth + instances: + offset: + value: _io.pos + end_offset: + value: _io.pos + end_offset_auth: + value: _io.pos + len_alignment_padding: + value: (((end_offset - offset)+3) & ~3) - (end_offset - offset) + len_alignment_padding_auth: + value: (((end_offset_auth - offset)+3) & ~3) - (end_offset_auth - offset) + is_valid: + value: state == 0x7F or state == 0x3F + is_auth: + value: (attributes.auth_write or attributes.time_based_auth or attributes.append_write) or (len_name == 0 or len_data == 0) + len_auth_header: + value: 60 + len_standard_header: + value: 32 diff --git a/common/ksy/insyde_fdc.ksy b/common/ksy/insyde_fdc.ksy new file mode 100644 index 0000000..2bfb0f7 --- /dev/null +++ b/common/ksy/insyde_fdc.ksy @@ -0,0 +1,23 @@ +meta: + id: insyde_fdc + title: Insyde Factory Data Copy NVRAM store + application: Insyde-based UEFI firmware + file-extension: fdc + tags: + - firmware + license: CC0-1.0 + ks-version: 0.9 + endian: le + +seq: +- id: signature + type: u4 +- id: fdc_size + type: u4 + valid: + expr: _ > len_fdc_store_header.as and _ < 0xFFFFFFFF +- id: body + size: fdc_size - len_fdc_store_header +instances: + len_fdc_store_header: + value: 0x50 diff --git a/common/ksy/insyde_fdm.ksy b/common/ksy/insyde_fdm.ksy new file mode 100644 index 0000000..50e06b4 --- /dev/null +++ b/common/ksy/insyde_fdm.ksy @@ -0,0 +1,91 @@ +meta: + id: insyde_fdm + title: Insyde Flash Device Map + application: Insyde-based UEFI firmware + file-extension: fdm + tags: + - firmware + license: CC0-1.0 + ks-version: 0.9 + endian: le + +seq: +- id: signature + type: u4 +- id: store_size + type: u4 +- id: data_offset + type: u4 +- id: entry_size + type: u4 +- id: entry_format + type: u1 +- id: revision + type: u1 +- id: num_extensions + type: u1 +- id: checksum + type: u1 +- id: fd_base_address + type: u8 +- id: extensions + type: fdm_extensions + size: num_extensions * sizeof + if: revision > 2 +- id: board_ids + type: fdm_board_ids + if: revision > 2 and extensions.extensions[1].count > 0 +#TODO: need to find a sample with revision == 4 and extensions.extensions[2].count > 0 +- id: entries + type: fdm_entries + size: store_size - data_offset + +types: + fdm_extensions: + seq: + - id: extensions + type: fdm_extension + repeat: eos + + fdm_extension: + seq: + - id: offset + type: u2 + - id: count + type: u2 + + fdm_board_ids: + seq: + - id: region_index + type: u4 + - id: num_board_ids + type: u4 + - id: board_ids + type: u8 + repeat: expr + repeat-expr: num_board_ids + + fdm_entries: + seq: + - id: entries + type: fdm_entry + repeat: eos + + fdm_entry: + seq: + - id: guid + size: 16 + - id: region_id + size: 16 + - id: region_offset + type: u8 + - id: region_size + type: u8 + - id: attributes + type: u4 + - id: hash + size: _parent._parent.entry_size - 16 - 16 - 8 - 8 - 4 + instances: + region_base: + value: _root.fd_base_address.as + region_offset.as + diff --git a/common/ksy/intel_acbp_v1.ksy b/common/ksy/intel_acbp_v1.ksy new file mode 100644 index 0000000..326a3da --- /dev/null +++ b/common/ksy/intel_acbp_v1.ksy @@ -0,0 +1,202 @@ +meta: + id: intel_acbp_v1 + title: Intel BootGuard Boot Policy v1 + application: Intel x86 firmware + file-extension: acbp_v1 + tags: + - firmware + license: CC0-1.0 + ks-version: 0.9 + endian: le + +enums: + ibb_segment_type: + 0: ibb + 1: non_ibb + + structure_ids: + 0x5f5f504243415f5f: acbp + 0x5f5f534242495f5f: ibbs + 0x5f5f41444d505f5f: pmda + 0x5f5f47534d505f5f: pmsg + +seq: +- id: structure_id + type: u8 + enum: structure_ids + valid: structure_ids::acbp +- id: version + type: u1 + valid: + expr: _ < 0x20 +- id: reserved0 + type: u1 +- id: bpm_revision + type: u1 +- id: bp_svn + type: u1 +- id: acm_svn + type: u1 +- id: reserved1 + type: u1 +- id: nem_data_size + type: u2 +- id: elements + type: acbp_element + repeat: until + repeat-until: _.header.structure_id == structure_ids::pmsg or _io.eof + +types: + acbp_element: + seq: + - id: header + type: common_header + - id: ibbs_body + type: ibbs_body + if: header.structure_id == structure_ids::ibbs + - id: pmda_body + type: pmda_body + if: header.structure_id == structure_ids::pmda + - id: pmsg_body + type: pmsg_body + if: header.structure_id == structure_ids::pmsg + - id: invalid_body + size: 0 + if: header.structure_id != structure_ids::pmsg + and header.structure_id != structure_ids::pmda + and header.structure_id != structure_ids::ibbs + valid: + expr: false + + common_header: + seq: + - id: structure_id + type: u8 + enum: structure_ids + - id: version + type: u1 + + hash: + seq: + - id: hash_algorithm_id + type: u2 + - id: len_hash + type: u2 + - id: hash + size: 32 + + ibbs_body: + seq: + - id: reserved + type: u1 + repeat: expr + repeat-expr: 3 + - id: flags + type: u4 + - id: mch_bar + type: u8 + - id: vtd_bar + type: u8 + - id: dma_protection_base0 + type: u4 + - id: dma_protection_limit0 + type: u4 + - id: dma_protection_base1 + type: u8 + - id: dma_protection_limit1 + type: u8 + - id: post_ibb_hash + type: hash + - id: ibb_entry_point + type: u4 + - id: ibb_hash + type: hash + - id: num_ibb_segments + type: u1 + - id: ibb_segments + type: ibb_segment + repeat: expr + repeat-expr: num_ibb_segments + + ibb_segment: + seq: + - id: reserved + type: u2 + - id: flags + type: u2 + - id: base + type: u4 + - id: size + type: u4 + + pmda_body: + seq: + - id: total_size + type: u2 + - id: version + type: u4 + - id: num_entries + type: u4 + - id: entries_v1 + if: version == 1 + type: pmda_entry_v1 + repeat: expr + repeat-expr: num_entries + - id: entries_v2 + if: version == 2 + type: pmda_entry_v2 + repeat: expr + repeat-expr: num_entries + + pmda_entry_v1: + seq: + - id: base + type: u4 + - id: size + type: u4 + - id: hash + size: 32 + + pmda_entry_v2: + seq: + - id: base + type: u4 + - id: size + type: u4 + - id: hash + type: hash + + pmsg_body: + seq: + - id: version + type: u1 + - id: key_id + type: u2 + - id: public_key + type: public_key + - id: sig_scheme + type: u2 + - id: signature + type: signature + + public_key: + seq: + - id: version + type: u1 + - id: size_bits + type: u2 + - id: exponent + type: u4 + - id: modulus + size: size_bits / 8 + + signature: + seq: + - id: version + type: u1 + - id: size_bits + type: u2 + - id: hash_algorithm_id + type: u2 + - id: signature + size: size_bits / 8 \ No newline at end of file diff --git a/common/ksy/intel_acbp_v2.ksy b/common/ksy/intel_acbp_v2.ksy new file mode 100644 index 0000000..ce98e54 --- /dev/null +++ b/common/ksy/intel_acbp_v2.ksy @@ -0,0 +1,223 @@ +meta: + id: intel_acbp_v2 + title: Intel BootGuard Boot Policy v2 + application: Intel x86 firmware + file-extension: acbp_v2 + tags: + - firmware + license: CC0-1.0 + ks-version: 0.9 + endian: le + +enums: + ibb_segment_type: + 0: ibb + 1: non_ibb + + structure_ids: + 0x5f5f504243415f5f: acbp + 0x5f5f534242495f5f: ibbs + 0x5f5f535458545f5f: txts + 0x5f5f535246505f5f: pfrs + 0x5f5f534443505f5f: pcds + 0x5f5f41444d505f5f: pmda + 0x5f5f47534d505f5f: pmsg + +seq: +- id: structure_id + type: u8 + enum: structure_ids + valid: structure_ids::acbp +- id: version + type: u1 + valid: + expr: _ >= 0x20 +- id: header_specific + type: u1 +- id: total_size + type: u2 + valid: 0x14 +- id: key_signature_offset + type: u2 +- id: bpm_revision + type: u1 +- id: bp_svn + type: u1 +- id: acm_svn + type: u1 +- id: reserved + type: u1 +- id: nem_data_size + type: u2 +- id: elements + type: acbp_element + repeat: until + repeat-until: _.header.total_size == 0 or _.header.structure_id == structure_ids::pmsg +- id: key_signature + type: key_signature + +types: + header: + seq: + - id: structure_id + type: u8 + enum: structure_ids + - id: version + type: u1 + - id: header_specific + type: u1 + - id: total_size + type: u2 + + hash: + seq: + - id: hash_algorithm_id + type: u2 + - id: len_hash + type: u2 + - id: hash + size: len_hash + + pmda_entry_v3: + seq: + - id: entry_id + type: u4 + - id: base + type: u4 + - id: size + type: u4 + - id: total_entry_size + type: u2 + - id: version + type: u2 + - id: hash + type: hash + + pmda_body: + seq: + - id: reserved + type: u2 + - id: total_size + type: u2 + - id: version + type: u4 + valid: 3 + - id: num_entries + type: u4 + - id: entries + type: pmda_entry_v3 + repeat: expr + repeat-expr: num_entries + + ibb_segment: + seq: + - id: reserved + type: u2 + - id: flags + type: u2 + - id: base + type: u4 + - id: size + type: u4 + + ibbs_body: + seq: + - id: reserved0 + type: u1 + - id: set_number + type: u1 + - id: reserved1 + type: u1 + - id: pbet_value + type: u1 + - id: flags + type: u4 + - id: mch_bar + type: u8 + - id: vtd_bar + type: u8 + - id: dma_protection_base0 + type: u4 + - id: dma_protection_limit0 + type: u4 + - id: dma_protection_base1 + type: u8 + - id: dma_protection_limit1 + type: u8 + - id: post_ibb_digest + type: hash + - id: ibb_entry_point + type: u4 + - id: ibb_digests_size + type: u2 + - id: num_ibb_digests + type: u2 + - id: ibb_digests + type: hash + repeat: expr + repeat-expr: num_ibb_digests + - id: obb_digest + type: hash + - id: reserved2 + type: u1 + repeat: expr + repeat-expr: 3 + - id: num_ibb_segments + type: u1 + - id: ibb_segments + type: ibb_segment + repeat: expr + repeat-expr: num_ibb_segments + + acbp_element: + seq: + - id: header + type: header + - id: ibbs_body + type: ibbs_body + if: header.structure_id == structure_ids::ibbs + and header.total_size >= sizeof
+ - id: pmda_body + type: pmda_body + if: header.structure_id == structure_ids::pmda + and header.total_size >= sizeof
+ - id: generic_body + size: header.total_size - sizeof
+ if: header.structure_id != structure_ids::ibbs + and header.structure_id != structure_ids::pmda + and header.total_size >= sizeof
+ + public_key: + seq: + - id: version + type: u1 + - id: size_bits + type: u2 + - id: exponent + type: u4 + - id: modulus + size: size_bits / 8 + + signature: + seq: + - id: version + type: u1 + - id: size_bits + type: u2 + - id: hash_algorithm_id + type: u2 + - id: signature + size: size_bits / 8 + + key_signature: + seq: + - id: version + type: u1 + - id: key_id + type: u2 + - id: public_key + type: public_key + - id: sig_scheme + type: u2 + - id: signature + type: signature \ No newline at end of file diff --git a/common/ksy/intel_acm.ksy b/common/ksy/intel_acm.ksy new file mode 100644 index 0000000..a4d8c4f --- /dev/null +++ b/common/ksy/intel_acm.ksy @@ -0,0 +1,94 @@ +meta: + id: intel_acm + title: Intel Authenticated Code Module + application: Intel x86 firmware + file-extension: acm + tags: + - executable + - firmware + license: CC0-1.0 + ks-version: 0.9 + endian: le + +enums: + module_subtype: + 0: txt + 1: startup + 3: boot_guard + + known_header_version: + 0x00000000: v0_0 + 0x00030000: v3_0 + +seq: +- id: header + type: header +- id: body + size: 4 * (header.module_size - header.header_size - header.scratch_space_size) + +types: + header: + seq: + - id: module_type + type: u2 + valid: 0x0002 + - id: module_subtype + type: u2 + enum: module_subtype + - id: header_size + type: u4 + doc: counted in 4 byte increments + - id: header_version + type: u4 + - id: chipset_id + type: u2 + - id: flags + type: u2 + - id: module_vendor + type: u4 + valid: 0x8086 + - id: date_day + type: u1 + doc: BCD + - id: date_month + type: u1 + doc: BCD + - id: date_year + type: u2 + doc: BCD + - id: module_size + type: u4 + doc: counted in 4 byte increments + - id: acm_svn + type: u2 + - id: se_svn + type: u2 + - id: code_control_flags + type: u4 + - id: error_entry_point + type: u4 + - id: gdt_max + type: u4 + - id: gdt_base + type: u4 + - id: segment_sel + type: u4 + - id: entry_point + type: u4 + - id: reserved + size: 64 + - id: key_size + type: u4 + doc: counted in 4 byte increments + - id: scratch_space_size + type: u4 + doc: counted in 4 byte increments + - id: rsa_public_key + size: (4 * key_size) + - id: rsa_exponent + type: u4 + if: header_version == 0 + - id: rsa_signature + size: (4 * key_size) + - id: scratch_space + size: (4 * scratch_space_size) diff --git a/common/ksy/intel_keym_v1.ksy b/common/ksy/intel_keym_v1.ksy new file mode 100644 index 0000000..431856d --- /dev/null +++ b/common/ksy/intel_keym_v1.ksy @@ -0,0 +1,79 @@ +meta: + id: intel_keym_v1 + title: Intel BootGuard Key Manifest v1 + application: Intel x86 firmware + file-extension: keym_v1 + tags: + - firmware + license: CC0-1.0 + ks-version: 0.9 + endian: le + +enums: + structure_ids: + 0x5f5f4d59454b5f5f: keym + +seq: +- id: structure_id + type: u8 + enum: structure_ids + valid: structure_ids::keym +- id: version + type: u1 + valid: + expr: _ < 0x20 +- id: km_version + type: u1 +- id: km_svn + type: u1 +- id: km_id + type: u1 +- id: km_hash + type: km_hash +- id: key_signature + type: key_signature + +types: + km_hash: + seq: + - id: hash_algorithm_id + type: u2 + - id: len_hash + type: u2 + - id: hash + size: len_hash + + public_key: + seq: + - id: version + type: u1 + - id: size_bits + type: u2 + - id: exponent + type: u4 + - id: modulus + size: size_bits / 8 + + signature: + seq: + - id: version + type: u1 + - id: size_bits + type: u2 + - id: hash_algorithm_id + type: u2 + - id: signature + size: size_bits / 8 + + key_signature: + seq: + - id: version + type: u1 + - id: key_id + type: u2 + - id: public_key + type: public_key + - id: sig_scheme + type: u2 + - id: signature + type: signature \ No newline at end of file diff --git a/common/ksy/intel_keym_v2.ksy b/common/ksy/intel_keym_v2.ksy new file mode 100644 index 0000000..0fd3d87 --- /dev/null +++ b/common/ksy/intel_keym_v2.ksy @@ -0,0 +1,109 @@ +meta: + id: intel_keym_v2 + title: Intel BootGuard Key Manifest v2 + application: Intel x86 firmware + file-extension: keym_v2 + tags: + - firmware + license: CC0-1.0 + ks-version: 0.9 + endian: le + +enums: + structure_ids: + 0x5f5f4d59454b5f5f: keym + + km_usage_flags: + 1: boot_policy_manifest + 2: fit_patch_manifest + 4: acm_manifest + 8: sdev + +seq: +- id: header + type: header +- id: key_signature_offset + type: u2 +- id: reserved + type: u1 + repeat: expr + repeat-expr: 3 +- id: km_version + type: u1 +- id: km_svn + type: u1 +- id: km_id + type: u1 +- id: fpf_hash_algorithm_id + type: u2 +- id: num_km_hashes + type: u2 +- id: km_hashes + type: km_hash + repeat: expr + repeat-expr: num_km_hashes +- id: key_signature + type: key_signature + +types: + header: + seq: + - id: structure_id + type: u8 + enum: structure_ids + valid: structure_ids::keym + - id: version + type: u1 + valid: + expr: _ >= 0x20 + - id: header_specific + type: u1 + - id: total_size + type: u2 + valid: 0x0 + + km_hash: + seq: + - id: usage_flags + type: u8 + - id: hash_algorithm_id + type: u2 + - id: len_hash + type: u2 + - id: hash + size: len_hash + + public_key: + seq: + - id: version + type: u1 + - id: size_bits + type: u2 + - id: exponent + type: u4 + - id: modulus + size: size_bits / 8 + + signature: + seq: + - id: version + type: u1 + - id: size_bits + type: u2 + - id: hash_algorithm_id + type: u2 + - id: signature + size: size_bits / 8 + + key_signature: + seq: + - id: version + type: u1 + - id: key_id + type: u2 + - id: public_key + type: public_key + - id: sig_scheme + type: u2 + - id: signature + type: signature \ No newline at end of file diff --git a/common/ksy/ms_slic_marker.ksy b/common/ksy/ms_slic_marker.ksy new file mode 100644 index 0000000..0ea0de1 --- /dev/null +++ b/common/ksy/ms_slic_marker.ksy @@ -0,0 +1,30 @@ +meta: + id: ms_slic_marker + title: Microsoft SLIC Marker + application: Phoenix-based UEFI firmware + file-extension: slmr + tags: + - firmware + license: CC0-1.0 + ks-version: 0.9 + endian: le + +seq: +- id: type + type: u4 +- id: len_marker + type: u4 +- id: version + type: u4 +- id: oem_id + size: 6 +- id: oem_table_id + size: 8 +- id: windows_flag + type: u8 +- id: slic_version + type: u4 +- id: reserved + size: 16 +- id: signature + size: 128 diff --git a/common/ksy/ms_slic_pubkey.ksy b/common/ksy/ms_slic_pubkey.ksy new file mode 100644 index 0000000..3c042ae --- /dev/null +++ b/common/ksy/ms_slic_pubkey.ksy @@ -0,0 +1,32 @@ +meta: + id: ms_slic_pubkey + title: Microsoft SLIC Public Key + application: Phoenix-based UEFI firmware + file-extension: slpk + tags: + - firmware + license: CC0-1.0 + ks-version: 0.9 + endian: le + +seq: +- id: type + type: u4 +- id: len_pubkey + type: u4 +- id: key_type + type: u1 +- id: version + type: u1 +- id: reserved + type: u2 +- id: algorithm + type: u4 +- id: magic + type: u4 +- id: bit_length + type: u4 +- id: exponent + type: u4 +- id: modulus + size: 128 diff --git a/common/ksy/phoenix_evsa.ksy b/common/ksy/phoenix_evsa.ksy new file mode 100644 index 0000000..11135d1 --- /dev/null +++ b/common/ksy/phoenix_evsa.ksy @@ -0,0 +1,144 @@ +meta: + id: phoenix_evsa + title: Phoenix EVSA NVRAM store + application: Phoenix-based UEFI firmware + file-extension: evsa + tags: + - firmware + license: CC0-1.0 + ks-version: 0.9 + endian: le + +seq: +- id: type + type: u1 +- id: checksum + type: u1 +- id: len_evsa_store_header + type: u2 +- id: signature + type: u4 +- id: attributes + type: u4 +- id: len_evsa_store + type: u4 +- id: reserved + type: u4 +- id: body + type: evsa_body + size: len_evsa_store - len_evsa_store_header + +types: + evsa_guid: + seq: + - id: guid_id + type: u2 + - id: guid + size: 16 + valid: + expr: _parent.len_evsa_entry == 22 + + evsa_name: + seq: + - id: var_id + type: u2 + - id: name + size: _parent.len_evsa_entry - 6 + + evsa_variable_attributes: + seq: + - id: non_volatile + type: b1le + - id: boot_service + type: b1le + - id: runtime + type: b1le + - id: hw_error_record + type: b1le + - id: auth_write + type: b1le + - id: time_based_auth + type: b1le + - id: append_write + type: b1le + - id: reserved + type: b21le + - id: extended_header + type: b1le + - id: reserved1 + type: b3le + + evsa_data: + seq: + - id: guid_id + type: u2 + - id: var_id + type: u2 + - id: attributes + type: evsa_variable_attributes + - id: len_data_ext + type: u4 + if: attributes.extended_header + - id: data + size: _parent.len_evsa_entry - 12 + if: not attributes.extended_header + - id: data_ext + size: len_data_ext + if: attributes.extended_header + + evsa_unknown: + seq: + - id: unknown + size: 0 + + evsa_entry: + seq: + - id: entry_type + type: u1 + - id: checksum + type: u1 + if: entry_type == 0xE1 + or entry_type == 0xE2 + or entry_type == 0xE3 + or entry_type == 0xED + or entry_type == 0xEE + or entry_type == 0xEF + or entry_type == 0x83 + - id: len_evsa_entry + type: u2 + if: entry_type == 0xE1 + or entry_type == 0xE2 + or entry_type == 0xE3 + or entry_type == 0xED + or entry_type == 0xEE + or entry_type == 0xEF + or entry_type == 0x83 + - id: body + type: + switch-on: entry_type + cases: + 0xED: evsa_guid + 0xE1: evsa_guid + 0xEE: evsa_name + 0xE2: evsa_name + 0xEF: evsa_data + 0xE3: evsa_data + 0x83: evsa_data + _: evsa_unknown + + evsa_body: + seq: + - id: entries + type: evsa_entry + repeat: until + repeat-until: (_.entry_type != 0xED + and _.entry_type != 0xEE + and _.entry_type != 0xEF + and _.entry_type != 0xE1 + and _.entry_type != 0xE2 + and _.entry_type != 0xE3 + and _.entry_type != 0x83) + or _io.eof + - id: free_space + type: u1 + repeat: eos diff --git a/common/ksy/phoenix_flm.ksy b/common/ksy/phoenix_flm.ksy new file mode 100644 index 0000000..a1148c4 --- /dev/null +++ b/common/ksy/phoenix_flm.ksy @@ -0,0 +1,45 @@ +meta: + id: phoenix_flm + title: Phoenix Flash Map + application: Phoenix-based UEFI firmware + file-extension: flm + tags: + - firmware + license: CC0-1.0 + ks-version: 0.9 + endian: le + +seq: +- id: signature + size: 10 +- id: num_entries + type: u2 +- id: reserved + type: u4 +- id: entries + type: flm_entry + repeat: expr + repeat-expr: num_entries + +instances: + len_flm_store_header: + value: 16 + len_flm_entry: + value: 36 + +types: + flm_entry: + seq: + - id: guid + size: 16 + - id: data_type + type: u2 + - id: entry_type + type: u2 + - id: physical_address + type: u8 + - id: size + type: u4 + - id: offset + type: u4 + diff --git a/common/me.h b/common/me.h index 60b8245..6507815 100644 --- a/common/me.h +++ b/common/me.h @@ -18,18 +18,102 @@ WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. // Make sure we use right packing rules #pragma pack(push, 1) -const UByteArray ME_VERSION_SIGNATURE("\x24\x4D\x41\x4E", 4); //$MAN -const UByteArray ME_VERSION_SIGNATURE2("\x24\x4D\x4E\x32", 4); //$MN2 - typedef struct ME_VERSION_ { - UINT32 signature; - UINT32 reserved; // Unknown for me - UINT16 major; - UINT16 minor; - UINT16 bugfix; - UINT16 build; + UINT32 Signature; + UINT32 Reserved; + UINT16 Major; + UINT16 Minor; + UINT16 Bugfix; + UINT16 Build; } ME_VERSION; +#define ME_VERSION_SIGNATURE 0x4E414D24 //$MAN +#define ME_VERSION_SIGNATURE2 0x324E4D24 //$MN2 + +// FPT +#define ME_ROM_BYPASS_VECTOR_SIZE 0x10 +#define FPT_HEADER_SIGNATURE 0x54504624 //$FPT + +// Header version 1.0 or 2.0, default +typedef struct FPT_HEADER_ { + UINT32 Signature; + UINT32 NumEntries; + UINT8 HeaderVersion; // 0x10 or 0x20 + UINT8 EntryVersion; + UINT8 HeaderLength; + UINT8 HeaderChecksum; // One bit for Redundant + UINT16 FlashCycleLife; // Maybe also TicksToAdd + UINT16 FlashCycleLimit;// Maybe also TokensToAdd + UINT32 UmaSize; // Maybe also Flags + UINT32 Flags; // Maybe also FlashLayout + UINT16 FitcMajor; + UINT16 FitcMinor; + UINT16 FitcHotfix; + UINT16 FitcBuild; +} FPT_HEADER; + +// Header version 2.1, special case +#define FPT_HEADER_VERSION_21 0x21 +typedef struct FPT_HEADER_21_ { + UINT32 Signature; + UINT32 NumEntries; + UINT8 HeaderVersion; // 0x21 + UINT8 EntryVersion; + UINT8 HeaderLength; + UINT8 Flags; // One bit for Redundant + UINT16 TicksToAdd; + UINT16 TokensToAdd; + UINT32 SPSFlags; + UINT32 HeaderCrc32; // Header + Entries sums to 0 + UINT16 FitcMajor; + UINT16 FitcMinor; + UINT16 FitcHotfix; + UINT16 FitcBuild; +} FPT_HEADER_21; + +typedef struct FPT_HEADER_ENTRY_{ + CHAR8 Name[4]; + CHAR8 Owner[4]; + UINT32 Offset; + UINT32 Size; + UINT32 Reserved[3]; + UINT8 Type : 7; + UINT8 CopyToDramCache : 1; + UINT8 Reserved1 : 7; + UINT8 BuiltWithLength1 : 1; + UINT8 BuiltWithLength2 : 1; + UINT8 Reserved2 : 7; + UINT8 EntryValid; +} FPT_HEADER_ENTRY; + +// IFWI +typedef struct IFWI_HEADER_ENTRY_ { + UINT32 Offset; + UINT32 Size; +} IFWI_HEADER_ENTRY; + +// IFWI 1.6 (ME), 2.0 (BIOS) +typedef struct IFWI_16_LAYOUT_HEADER_ { + UINT8 RomBypassVector[16]; + IFWI_HEADER_ENTRY DataPartition; + IFWI_HEADER_ENTRY BootPartition[5]; + UINT64 Checksum; +} IFWI_16_LAYOUT_HEADER; + +// IFWI 1.7 (ME) +typedef struct IFWI_17_LAYOUT_HEADER_ { + UINT8 RomBypassVector[16]; + UINT16 HeaderSize; + UINT8 Flags; + UINT8 Reserved; + UINT32 Checksum; + IFWI_HEADER_ENTRY DataPartition; + IFWI_HEADER_ENTRY BootPartition[5]; + IFWI_HEADER_ENTRY TempPage; +} IFWI_17_LAYOUT_HEADER; + +#define ME_MANIFEST_HEADER_ID 0x324E4D24 //$MN2 + // Restore previous packing rules #pragma pack(pop) diff --git a/common/meparser.cpp b/common/meparser.cpp new file mode 100755 index 0000000..aea1ae0 --- /dev/null +++ b/common/meparser.cpp @@ -0,0 +1,699 @@ +/* meparser.cpp + + Copyright (c) 2019, Nikolaj Schlej. All rights reserved. + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + */ + +#include + +#include "ffs.h" +#include "me.h" +#include "meparser.h" +#include "parsingdata.h" +#include "utility.h" + +#ifdef U_ENABLE_ME_PARSING_SUPPORT + +struct FPT_PARTITION_INFO { + FPT_HEADER_ENTRY ptEntry; + UINT8 type; + UModelIndex index; + friend bool operator< (const FPT_PARTITION_INFO & lhs, const FPT_PARTITION_INFO & rhs){ return lhs.ptEntry.Offset < rhs.ptEntry.Offset; } +}; + +struct IFWI_PARTITION_INFO { + IFWI_HEADER_ENTRY ptEntry; + UINT8 type; + UINT8 subtype; + friend bool operator< (const IFWI_PARTITION_INFO & lhs, const IFWI_PARTITION_INFO & rhs){ return lhs.ptEntry.Offset < rhs.ptEntry.Offset; } +}; + +USTATUS MeParser::parseMeRegionBody(const UModelIndex & index) +{ + // Sanity check + if (!index.isValid()) + return U_INVALID_PARAMETER; + + // Obtain ME region + UByteArray meRegion = model->body(index); + + // Check region size + if ((UINT32)meRegion.size() < ME_ROM_BYPASS_VECTOR_SIZE + sizeof(UINT32)) { + msg(usprintf("%s: ME region too small to fit ROM bypass vector", __FUNCTION__), index); + return U_INVALID_ME_PARTITION_TABLE; + } + + // Check ME signature to determine it's version + // ME v11 and older layout + if (*(UINT32*)meRegion.constData() == FPT_HEADER_SIGNATURE || *(UINT32*)(meRegion.constData() + ME_ROM_BYPASS_VECTOR_SIZE) == FPT_HEADER_SIGNATURE) { + UModelIndex ptIndex; + return parseFptRegion(meRegion, index, ptIndex); + } + + // IFWI 1.6 + // Check region size + if ((UINT32)meRegion.size() < sizeof(IFWI_16_LAYOUT_HEADER)) { + msg(usprintf("%s: ME region too small to fit IFWI 1.6 layout header", __FUNCTION__), index); + return U_INVALID_ME_PARTITION_TABLE; + } + + const IFWI_16_LAYOUT_HEADER* ifwi16Header = (const IFWI_16_LAYOUT_HEADER*)meRegion.constData(); + // Check region size + if ((UINT32)meRegion.size() < ifwi16Header->DataPartition.Offset + sizeof(UINT32)) { + msg(usprintf("%s: ME region too small to fit IFWI 1.6 data partition", __FUNCTION__), index); + return U_INVALID_ME_PARTITION_TABLE; + } + // Data partition always points to FPT header + if (*(UINT32*)(meRegion.constData() + ifwi16Header->DataPartition.Offset) == FPT_HEADER_SIGNATURE) { + UModelIndex ptIndex; + return parseIfwi16Region(meRegion, index, ptIndex); + } + + // IFWI 1.7 + if ((UINT32)meRegion.size() < sizeof(IFWI_17_LAYOUT_HEADER)) { + msg(usprintf("%s: ME region too small to fit IFWI 1.7 layout header", __FUNCTION__), index); + return U_INVALID_ME_PARTITION_TABLE; + } + + const IFWI_17_LAYOUT_HEADER* ifwi17Header = (const IFWI_17_LAYOUT_HEADER*)meRegion.constData(); + // Check region size + if ((UINT32)meRegion.size() < ifwi17Header->DataPartition.Offset + sizeof(UINT32)) { + msg(usprintf("%s: ME region too small to fit IFWI 1.7 data partition", __FUNCTION__), index); + return U_INVALID_ME_PARTITION_TABLE; + } + // Data partition always points to FPT header + if (*(UINT32*)(meRegion.constData() + ifwi17Header->DataPartition.Offset)== FPT_HEADER_SIGNATURE) { + UModelIndex ptIndex; + return parseIfwi17Region(meRegion, index, ptIndex); + } + + // Something else entirely + msg(usprintf("%s: unknown ME region format", __FUNCTION__), index); + return U_INVALID_ME_PARTITION_TABLE; +} + +USTATUS MeParser::parseFptRegion(const UByteArray & region, const UModelIndex & parent, UModelIndex & index) +{ + // Check region size + if ((UINT32)region.size() < sizeof(FPT_HEADER)) { + msg(usprintf("%s: region too small to fit the FPT partition table header", __FUNCTION__), parent); + return U_INVALID_ME_PARTITION_TABLE; + } + + // Populate partition table header + const FPT_HEADER* ptHeader = (const FPT_HEADER*)region.constData(); + UINT32 romBypassVectorSize = 0; + if (*(UINT32*)region.constData() != FPT_HEADER_SIGNATURE) { + // Adjust the header to skip ROM bypass vector + romBypassVectorSize = ME_ROM_BYPASS_VECTOR_SIZE; + ptHeader = (const FPT_HEADER*)(region.constData() + romBypassVectorSize); + } + + // Check region size again + UINT32 ptBodySize = ptHeader->NumEntries * sizeof(FPT_HEADER_ENTRY); + UINT32 ptSize = romBypassVectorSize + sizeof(FPT_HEADER) + ptBodySize; + if ((UINT32)region.size() < ptSize) { + msg(usprintf("%s: ME region too small to fit the FPT partition table", __FUNCTION__), parent); + return U_INVALID_ME_PARTITION_TABLE; + } + + // Get info + UByteArray header = region.left(romBypassVectorSize + sizeof(FPT_HEADER)); + UByteArray body = region.mid(header.size(), ptBodySize); + + UString name = UString("FPT partition table"); + UString info; + + // Special case of FPT header version 2.1 + if (ptHeader->HeaderVersion == FPT_HEADER_VERSION_21) { + const FPT_HEADER_21* ptHeader21 = (const FPT_HEADER_21*)ptHeader; + + info = usprintf("Full size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nROM bypass vector: %s\nNumber of entries: %u\nHeader version: %02Xh\nEntry version: %02Xh\n" + "Header length: %02Xh\nFlags: %Xh\nTicks to add: %04Xh\nTokens to add: %04Xh\nSPS Flags: %Xh\nFITC version: %u.%u.%u.%u\nCRC32 Checksum: %08Xh", + ptSize, ptSize, + (UINT32)header.size(), (UINT32)header.size(), + ptBodySize, ptBodySize, + (romBypassVectorSize ? "present" : "absent"), + ptHeader21->NumEntries, + ptHeader21->HeaderVersion, + ptHeader21->EntryVersion, + ptHeader21->HeaderLength, + ptHeader21->Flags, + ptHeader21->TicksToAdd, + ptHeader21->TokensToAdd, + ptHeader21->SPSFlags, + ptHeader21->FitcMajor, ptHeader21->FitcMinor, ptHeader21->FitcHotfix, ptHeader21->FitcBuild, + ptHeader21->HeaderCrc32); + // TODO: verify header crc32 + } + // Default handling for all other versions, may be too generic in some corner cases + else { + info = usprintf("Full size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nROM bypass vector: %s\nNumber of entries: %u\nHeader version: %02Xh\nEntry version: %02Xh\n" + "Header length: %02Xh\nFlash cycle life: %04Xh\nFlash cycle limit: %04Xh\nUMA size: %Xh\nFlags: %Xh\nFITC version: %u.%u.%u.%u\nChecksum: %02Xh", + ptSize, ptSize, + (UINT32)header.size(), (UINT32)header.size(), + ptBodySize, ptBodySize, + (romBypassVectorSize ? "present" : "absent"), + ptHeader->NumEntries, + ptHeader->HeaderVersion, + ptHeader->EntryVersion, + ptHeader->HeaderLength, + ptHeader->FlashCycleLife, + ptHeader->FlashCycleLimit, + ptHeader->UmaSize, + ptHeader->Flags, + ptHeader->FitcMajor, ptHeader->FitcMinor, ptHeader->FitcHotfix, ptHeader->FitcBuild, + ptHeader->HeaderChecksum); + // TODO: verify header checksum8 + } + + // Add tree item + index = model->addItem(0, Types::FptStore, 0, name, UString(), info, header, body, UByteArray(), Fixed, parent); + + // Add partition table entries + std::vector partitions; + UINT32 offset = (UINT32)header.size(); + UINT32 numEntries = ptHeader->NumEntries; + const FPT_HEADER_ENTRY* firstPtEntry = (const FPT_HEADER_ENTRY*)(region.constData() + offset); + for (UINT32 i = 0; i < numEntries; i++) { + // Populate entry header + const FPT_HEADER_ENTRY* ptEntry = firstPtEntry + i; + + // Get info + name = visibleAsciiOrHex((UINT8*)ptEntry->Name, 4); + info = usprintf("Full size: %Xh (%u)\nPartition offset: %Xh\nPartition length: %Xh\nPartition type: %02Xh", + (UINT32)sizeof(FPT_HEADER_ENTRY), (UINT32)sizeof(FPT_HEADER_ENTRY), + ptEntry->Offset, + ptEntry->Size, + ptEntry->Type); + + // Add tree item + const UINT8 type = (ptEntry->Offset != 0 && ptEntry->Offset != 0xFFFFFFFF && ptEntry->Size != 0 && ptEntry->EntryValid != 0xFF) ? Subtypes::ValidFptEntry : Subtypes::InvalidFptEntry; + UModelIndex entryIndex = model->addItem(offset, Types::FptEntry, type, name, UString(), info, UByteArray(), UByteArray((const char*)ptEntry, sizeof(FPT_HEADER_ENTRY)), UByteArray(), Fixed, index); + + // Adjust offset + offset += sizeof(FPT_HEADER_ENTRY); + + // Add valid partitions + if (type == Subtypes::ValidFptEntry) { // Skip absent and invalid partitions + // Add to partitions vector + FPT_PARTITION_INFO partition = {}; + partition.type = Types::FptPartition; + partition.ptEntry = *ptEntry; + partition.index = entryIndex; + partitions.push_back(partition); + } + } + // Check for empty set of partitions + if (partitions.empty()) { + // Add a single padding partition in this case + FPT_PARTITION_INFO padding = {}; + padding.ptEntry.Offset = offset; + padding.ptEntry.Size = (UINT32)(region.size() - padding.ptEntry.Offset); + padding.type = Types::Padding; + partitions.push_back(padding); + } + +make_partition_table_consistent: + if (partitions.empty()) { + return U_INVALID_ME_PARTITION_TABLE; + } + // Sort partitions by offset + std::sort(partitions.begin(), partitions.end()); + + // Check for intersections and paddings between partitions + FPT_PARTITION_INFO padding = {}; + + // Check intersection with the partition table header + if (partitions.front().ptEntry.Offset < ptSize) { + msg(usprintf("%s: ME partition has intersection with ME partition table, skipped", __FUNCTION__), + partitions.front().index); + partitions.erase(partitions.begin()); + goto make_partition_table_consistent; + } + // Check for padding between partition table and the first partition + else if (partitions.front().ptEntry.Offset > ptSize) { + padding.ptEntry.Offset = ptSize; + padding.ptEntry.Size = partitions.front().ptEntry.Offset - ptSize; + padding.type = Types::Padding; + partitions.insert(partitions.begin(), padding); + } + // Check for intersections/paddings between partitions + for (size_t i = 1; i < partitions.size(); i++) { + UINT32 previousPartitionEnd = partitions[i - 1].ptEntry.Offset + partitions[i - 1].ptEntry.Size; + + // Check that current region is fully present in the image + if ((UINT32)partitions[i].ptEntry.Offset + (UINT32)partitions[i].ptEntry.Size > (UINT32)region.size()) { + if ((UINT32)partitions[i].ptEntry.Offset >= (UINT32)region.size()) { + msg(usprintf("%s: FPT partition is located outside of the opened image, skipped", __FUNCTION__), partitions[i].index); + partitions.erase(partitions.begin() + i); + goto make_partition_table_consistent; + } + else { + msg(usprintf("%s: FPT partition can't fit into the region, truncated", __FUNCTION__), partitions[i].index); + partitions[i].ptEntry.Size = (UINT32)region.size() - (UINT32)partitions[i].ptEntry.Offset; + } + } + + // Check for intersection with previous partition + if (partitions[i].ptEntry.Offset < previousPartitionEnd) { + // Check if current partition is located inside previous one + if (partitions[i].ptEntry.Offset + partitions[i].ptEntry.Size <= previousPartitionEnd) { + msg(usprintf("%s: FPT partition is located inside another FPT partition, skipped", __FUNCTION__), + partitions[i].index); + partitions.erase(partitions.begin() + i); + goto make_partition_table_consistent; + } + else { + msg(usprintf("%s: FPT partition intersects with previous one, skipped", __FUNCTION__), + partitions[i].index); + partitions.erase(partitions.begin() + i); + goto make_partition_table_consistent; + } + } + + // Check for padding between current and previous partitions + else if (partitions[i].ptEntry.Offset > previousPartitionEnd) { + padding.ptEntry.Offset = previousPartitionEnd; + padding.ptEntry.Size = partitions[i].ptEntry.Offset - previousPartitionEnd; + padding.type = Types::Padding; + std::vector::iterator iter = partitions.begin(); + std::advance(iter, i); + partitions.insert(iter, padding); + } + } + // Check for padding after the last region + if ((UINT32)partitions.back().ptEntry.Offset + (UINT32)partitions.back().ptEntry.Size < (UINT32)region.size()) { + padding.ptEntry.Offset = partitions.back().ptEntry.Offset + partitions.back().ptEntry.Size; + padding.ptEntry.Size = (UINT32)(region.size() - padding.ptEntry.Offset); + padding.type = Types::Padding; + partitions.push_back(padding); + } + + // Partition map is consistent + for (size_t i = 0; i < partitions.size(); i++) { + UByteArray partition = region.mid(partitions[i].ptEntry.Offset, partitions[i].ptEntry.Size); + if (partitions[i].type == Types::FptPartition) { + UModelIndex partitionIndex; + // Get info + name = visibleAsciiOrHex((UINT8*) partitions[i].ptEntry.Name, 4); + info = usprintf("Full size: %Xh (%u)\nPartition type: %02Xh\n", + (UINT32)partition.size(), (UINT32)partition.size(), + partitions[i].ptEntry.Type); + + // Add tree item + UINT8 type = Subtypes::CodeFptPartition + partitions[i].ptEntry.Type; + partitionIndex = model->addItem(partitions[i].ptEntry.Offset, Types::FptPartition, type, name, UString(), info, UByteArray(), partition, UByteArray(), Fixed, parent); + if (type == Subtypes::CodeFptPartition && partition.size() >= (int) sizeof(UINT32) && readUnaligned((const UINT32*)partition.constData()) == CPD_SIGNATURE) { + // Parse code partition contents + UModelIndex cpdIndex; + ffsParser->parseCpdRegion(partition, partitions[i].ptEntry.Offset, partitionIndex, cpdIndex); + } + } + else if (partitions[i].type == Types::Padding) { + // Get info + name = UString("Padding"); + info = usprintf("Full size: %Xh (%u)", (UINT32)partition.size(), (UINT32)partition.size()); + + // Add tree item + model->addItem(partitions[i].ptEntry.Offset, Types::Padding, getPaddingType(partition), name, UString(), info, UByteArray(), partition, UByteArray(), Fixed, parent); + } + } + + return U_SUCCESS; +} + +USTATUS MeParser::parseIfwi16Region(const UByteArray & region, const UModelIndex & parent, UModelIndex & index) +{ + // Check region size again + if ((UINT32)region.size() < sizeof(IFWI_16_LAYOUT_HEADER)) { + msg(usprintf("%s: ME region too small to fit IFWI 1.6 layout header", __FUNCTION__), parent); + return U_INVALID_ME_PARTITION_TABLE; + } + + const IFWI_16_LAYOUT_HEADER* ifwiHeader = (const IFWI_16_LAYOUT_HEADER*)region.constData(); + + // Add header + UINT32 ptSize = sizeof(IFWI_16_LAYOUT_HEADER); + UByteArray header = region.left(ptSize); + + UString name = UString("IFWI 1.6 header"); + UString info = usprintf("Full size: %Xh (%u)\n" + "Data partition offset: %Xh\nData partition size: %Xh\n" + "Boot1 partition offset: %Xh\nBoot1 partition size: %Xh\n" + "Boot2 partition offset: %Xh\nBoot2 partition size: %Xh\n" + "Boot3 partition offset: %Xh\nBoot3 partition size: %Xh\n" + "Boot4 partition offset: %Xh\nBoot4 partition size: %Xh\n" + "Boot5 partition offset: %Xh\nBoot5 partition size: %Xh\n" + "Checksum: %" PRIX64 "h", + (UINT32)header.size(), (UINT32)header.size(), + ifwiHeader->DataPartition.Offset, ifwiHeader->DataPartition.Size, + ifwiHeader->BootPartition[0].Offset, ifwiHeader->BootPartition[0].Size, + ifwiHeader->BootPartition[1].Offset, ifwiHeader->BootPartition[1].Size, + ifwiHeader->BootPartition[2].Offset, ifwiHeader->BootPartition[2].Size, + ifwiHeader->BootPartition[3].Offset, ifwiHeader->BootPartition[3].Size, + ifwiHeader->BootPartition[4].Offset, ifwiHeader->BootPartition[4].Size, + ifwiHeader->Checksum); + // Add tree item + index = model->addItem(0, Types::IfwiHeader, 0, name, UString(), info, UByteArray(), header, UByteArray(), Fixed, parent); + + std::vector partitions; + // Add data partition + { + IFWI_PARTITION_INFO partition = {}; + partition.type = Types::IfwiPartition; + partition.subtype = Subtypes::DataIfwiPartition; + partition.ptEntry = ifwiHeader->DataPartition; + partitions.push_back(partition); + } + // Add boot partitions + for (UINT8 i = 0 ; i < 5; i++) { + if (ifwiHeader->BootPartition[i].Offset != 0 && ifwiHeader->BootPartition[i].Offset != 0xFFFFFFFF) { + IFWI_PARTITION_INFO partition = {}; + partition.type = Types::IfwiPartition; + partition.subtype = Subtypes::BootIfwiPartition; + partition.ptEntry = ifwiHeader->BootPartition[i]; + partitions.push_back(partition); + } + } + +make_partition_table_consistent: + if (partitions.empty()) { + return U_INVALID_ME_PARTITION_TABLE; + } + // Sort partitions by offset + std::sort(partitions.begin(), partitions.end()); + + // Check for intersections and paddings between partitions + IFWI_PARTITION_INFO padding = {}; + + // Check intersection with the partition table header + if (partitions.front().ptEntry.Offset < ptSize) { + msg(usprintf("%s: IFWI partition has intersection with IFWI layout header, skipped", __FUNCTION__), index); + partitions.erase(partitions.begin()); + goto make_partition_table_consistent; + } + // Check for padding between partition table and the first partition + else if (partitions.front().ptEntry.Offset > ptSize) { + padding.ptEntry.Offset = ptSize; + padding.ptEntry.Size = partitions.front().ptEntry.Offset - ptSize; + padding.type = Types::Padding; + partitions.insert(partitions.begin(), padding); + } + // Check for intersections/paddings between partitions + for (size_t i = 1; i < partitions.size(); i++) { + UINT32 previousPartitionEnd = partitions[i - 1].ptEntry.Offset + partitions[i - 1].ptEntry.Size; + + // Check that current region is fully present in the image + if ((UINT32)partitions[i].ptEntry.Offset + (UINT32)partitions[i].ptEntry.Size > (UINT32)region.size()) { + if ((UINT32)partitions[i].ptEntry.Offset >= (UINT32)region.size()) { + msg(usprintf("%s: IFWI partition is located outside of the opened image, skipped", __FUNCTION__), index); + partitions.erase(partitions.begin() + i); + goto make_partition_table_consistent; + } + else { + msg(usprintf("%s: IFWI partition can't fit into the region, truncated", __FUNCTION__), index); + partitions[i].ptEntry.Size = (UINT32)region.size() - (UINT32)partitions[i].ptEntry.Offset; + } + } + + // Check for intersection with previous partition + if (partitions[i].ptEntry.Offset < previousPartitionEnd) { + // Check if current partition is located inside previous one + if (partitions[i].ptEntry.Offset + partitions[i].ptEntry.Size <= previousPartitionEnd) { + msg(usprintf("%s: IFWI partition is located inside another IFWI partition, skipped", __FUNCTION__), index); + partitions.erase(partitions.begin() + i); + goto make_partition_table_consistent; + } + else { + msg(usprintf("%s: IFWI partition intersects with previous one, skipped", __FUNCTION__), index); + partitions.erase(partitions.begin() + i); + goto make_partition_table_consistent; + } + } + + // Check for padding between current and previous partitions + else if (partitions[i].ptEntry.Offset > previousPartitionEnd) { + padding.ptEntry.Offset = previousPartitionEnd; + padding.ptEntry.Size = partitions[i].ptEntry.Offset - previousPartitionEnd; + padding.type = Types::Padding; + std::vector::iterator iter = partitions.begin(); + std::advance(iter, i); + partitions.insert(iter, padding); + } + } + // Check for padding after the last region + if ((UINT32)partitions.back().ptEntry.Offset + (UINT32)partitions.back().ptEntry.Size < (UINT32)region.size()) { + padding.ptEntry.Offset = partitions.back().ptEntry.Offset + partitions.back().ptEntry.Size; + padding.ptEntry.Size = (UINT32)(region.size() - padding.ptEntry.Offset); + padding.type = Types::Padding; + partitions.push_back(padding); + } + + // Partition map is consistent + for (size_t i = 0; i < partitions.size(); i++) { + UByteArray partition = region.mid(partitions[i].ptEntry.Offset, partitions[i].ptEntry.Size); + if (partitions[i].type == Types::IfwiPartition) { + UModelIndex partitionIndex; + if (partitions[i].subtype == Subtypes::DataIfwiPartition) { + name = "Data partition"; + } + else if (partitions[i].subtype == Subtypes::BootIfwiPartition) { + name = "Boot partition"; + } + + // Get info + info = usprintf("Full size: %Xh (%u)\n", (UINT32)partition.size(), (UINT32)partition.size()); + + // Add tree item + partitionIndex = model->addItem(partitions[i].ptEntry.Offset, partitions[i].type, partitions[i].subtype, name, UString(), info, UByteArray(), partition, UByteArray(), Fixed, parent); + + // Parse partition further + if (partitions[i].subtype == Subtypes::DataIfwiPartition) { + UModelIndex dataPartitionFptRegionIndex; + parseFptRegion(partition, partitionIndex, dataPartitionFptRegionIndex); + } + else if (partitions[i].subtype == Subtypes::BootIfwiPartition) { + // Parse code partition contents + UModelIndex bootPartitionBpdtRegionIndex; + ffsParser->parseBpdtRegion(partition, 0, 0, partitionIndex, bootPartitionBpdtRegionIndex); + } + } + else if (partitions[i].type == Types::Padding) { + // Get info + name = UString("Padding"); + info = usprintf("Full size: %Xh (%u)", (UINT32)partition.size(), (UINT32)partition.size()); + + // Add tree item + model->addItem(partitions[i].ptEntry.Offset, Types::Padding, getPaddingType(partition), name, UString(), info, UByteArray(), partition, UByteArray(), Fixed, parent); + } + } + + return U_SUCCESS; +} + +USTATUS MeParser::parseIfwi17Region(const UByteArray & region, const UModelIndex & parent, UModelIndex & index) +{ + // Check region size again + if ((UINT32)region.size() < sizeof(IFWI_17_LAYOUT_HEADER)) { + msg(usprintf("%s: ME region too small to fit IFWI 1.7 layout header", __FUNCTION__), parent); + return U_INVALID_ME_PARTITION_TABLE; + } + + const IFWI_17_LAYOUT_HEADER* ifwiHeader = (const IFWI_17_LAYOUT_HEADER*)region.constData(); + // TODO: add check for HeaderSize to be 0x40 + + // Add header + UINT32 ptSize = sizeof(IFWI_17_LAYOUT_HEADER); + UByteArray header = region.left(ptSize); + + UString name = UString("IFWI 1.7 header"); + UString info = usprintf("Full size: %Xh (%u)\n" + "Flags: %02Xh\n" + "Reserved: %02Xh\n" + "Checksum: %Xh\n" + "Data partition offset: %Xh\nData partition size: %Xh\n" + "Boot1 partition offset: %Xh\nBoot1 partition size: %Xh\n" + "Boot2 partition offset: %Xh\nBoot2 partition size: %Xh\n" + "Boot3 partition offset: %Xh\nBoot3 partition size: %Xh\n" + "Boot4 partition offset: %Xh\nBoot4 partition size: %Xh\n" + "Boot5 partition offset: %Xh\nBoot5 partition size: %Xh\n" + "Temp page offset: %Xh\nTemp page size: %Xh\n", + (UINT32)header.size(), (UINT32)header.size(), + ifwiHeader->Flags, + ifwiHeader->Reserved, + ifwiHeader->Checksum, + ifwiHeader->DataPartition.Offset, ifwiHeader->DataPartition.Size, + ifwiHeader->BootPartition[0].Offset, ifwiHeader->BootPartition[0].Size, + ifwiHeader->BootPartition[1].Offset, ifwiHeader->BootPartition[1].Size, + ifwiHeader->BootPartition[2].Offset, ifwiHeader->BootPartition[2].Size, + ifwiHeader->BootPartition[3].Offset, ifwiHeader->BootPartition[3].Size, + ifwiHeader->BootPartition[4].Offset, ifwiHeader->BootPartition[4].Size, + ifwiHeader->TempPage.Offset, ifwiHeader->TempPage.Size); + // Add tree item + index = model->addItem(0, Types::IfwiHeader, 0, name, UString(), info, UByteArray(), header, UByteArray(), Fixed, parent); + + std::vector partitions; + // Add data partition + { + IFWI_PARTITION_INFO partition = {}; + partition.type = Types::IfwiPartition; + partition.subtype = Subtypes::DataIfwiPartition; + partition.ptEntry = ifwiHeader->DataPartition; + partitions.push_back(partition); + } + // Add boot partitions + for (UINT8 i = 0 ; i < 5; i++) { + if (ifwiHeader->BootPartition[i].Offset != 0 && ifwiHeader->BootPartition[i].Offset != 0xFFFFFFFF) { + IFWI_PARTITION_INFO partition = {}; + partition.type = Types::IfwiPartition; + partition.subtype = Subtypes::BootIfwiPartition; + partition.ptEntry = ifwiHeader->BootPartition[i]; + partitions.push_back(partition); + } + } + // Add temp page + if (ifwiHeader->TempPage.Offset != 0 && ifwiHeader->TempPage.Offset != 0xFFFFFFFF) { + IFWI_PARTITION_INFO partition = {}; + partition.type = Types::IfwiPartition; + partition.subtype = Subtypes::DataPadding; + partition.ptEntry = ifwiHeader->TempPage; + partitions.push_back(partition); + } + +make_partition_table_consistent: + if (partitions.empty()) { + return U_INVALID_ME_PARTITION_TABLE; + } + // Sort partitions by offset + std::sort(partitions.begin(), partitions.end()); + + // Check for intersections and paddings between partitions + IFWI_PARTITION_INFO padding = {}; + + // Check intersection with the partition table header + if (partitions.front().ptEntry.Offset < ptSize) { + msg(usprintf("%s: IFWI partition has intersection with IFWI layout header, skipped", __FUNCTION__), index); + partitions.erase(partitions.begin()); + goto make_partition_table_consistent; + } + // Check for padding between partition table and the first partition + else if (partitions.front().ptEntry.Offset > ptSize) { + padding.ptEntry.Offset = ptSize; + padding.ptEntry.Size = partitions.front().ptEntry.Offset - ptSize; + padding.type = Types::Padding; + partitions.insert(partitions.begin(), padding); + } + // Check for intersections/paddings between partitions + for (size_t i = 1; i < partitions.size(); i++) { + UINT32 previousPartitionEnd = partitions[i - 1].ptEntry.Offset + partitions[i - 1].ptEntry.Size; + + // Check that current region is fully present in the image + if ((UINT32)partitions[i].ptEntry.Offset + (UINT32)partitions[i].ptEntry.Size > (UINT32)region.size()) { + if ((UINT32)partitions[i].ptEntry.Offset >= (UINT32)region.size()) { + msg(usprintf("%s: IFWI partition is located outside of the opened image, skipped", __FUNCTION__), index); + partitions.erase(partitions.begin() + i); + goto make_partition_table_consistent; + } + else { + msg(usprintf("%s: IFWI partition can't fit into the region, truncated", __FUNCTION__), index); + partitions[i].ptEntry.Size = (UINT32)region.size() - (UINT32)partitions[i].ptEntry.Offset; + } + } + + // Check for intersection with previous partition + if (partitions[i].ptEntry.Offset < previousPartitionEnd) { + // Check if current partition is located inside previous one + if (partitions[i].ptEntry.Offset + partitions[i].ptEntry.Size <= previousPartitionEnd) { + msg(usprintf("%s: IFWI partition is located inside another IFWI partition, skipped", __FUNCTION__), index); + partitions.erase(partitions.begin() + i); + goto make_partition_table_consistent; + } + else { + msg(usprintf("%s: IFWI partition intersects with previous one, skipped", __FUNCTION__), index); + partitions.erase(partitions.begin() + i); + goto make_partition_table_consistent; + } + } + + // Check for padding between current and previous partitions + else if (partitions[i].ptEntry.Offset > previousPartitionEnd) { + padding.ptEntry.Offset = previousPartitionEnd; + padding.ptEntry.Size = partitions[i].ptEntry.Offset - previousPartitionEnd; + padding.type = Types::Padding; + std::vector::iterator iter = partitions.begin(); + std::advance(iter, i); + partitions.insert(iter, padding); + } + } + // Check for padding after the last region + if ((UINT32)partitions.back().ptEntry.Offset + (UINT32)partitions.back().ptEntry.Size < (UINT32)region.size()) { + padding.ptEntry.Offset = partitions.back().ptEntry.Offset + partitions.back().ptEntry.Size; + padding.ptEntry.Size = (UINT32)(region.size() - padding.ptEntry.Offset); + padding.type = Types::Padding; + partitions.push_back(padding); + } + + // Partition map is consistent + for (size_t i = 0; i < partitions.size(); i++) { + UByteArray partition = region.mid(partitions[i].ptEntry.Offset, partitions[i].ptEntry.Size); + if (partitions[i].type == Types::IfwiPartition) { + UModelIndex partitionIndex; + if (partitions[i].subtype == Subtypes::DataIfwiPartition) { + name = "Data partition"; + + } + else if (partitions[i].subtype == Subtypes::BootIfwiPartition){ + name = "Boot partition"; + } + else { + name = "Temp page"; + } + + // Get info + info = usprintf("Full size: %Xh (%u)\n", (UINT32)partition.size(), (UINT32)partition.size()); + + // Add tree item + partitionIndex = model->addItem(partitions[i].ptEntry.Offset, partitions[i].type, partitions[i].subtype, name, UString(), info, UByteArray(), partition, UByteArray(), Fixed, parent); + + // Parse partition further + if (partitions[i].subtype == Subtypes::DataIfwiPartition) { + UModelIndex dataPartitionFptRegionIndex; + parseFptRegion(partition, partitionIndex, dataPartitionFptRegionIndex); + } + else if (partitions[i].subtype == Subtypes::BootIfwiPartition) { + // Parse code partition contents + UModelIndex bootPartitionRegionIndex; + if (*(UINT32*)partition.constData() == FPT_HEADER_SIGNATURE) { + // Parse as FptRegion + parseFptRegion(partition, partitionIndex, bootPartitionRegionIndex); + } + else { + // Parse as BpdtRegion + ffsParser->parseBpdtRegion(partition, 0, 0, partitionIndex, bootPartitionRegionIndex); + } + } + } + else if (partitions[i].type == Types::Padding) { + // Get info + name = UString("Padding"); + info = usprintf("Full size: %Xh (%u)", (UINT32)partition.size(), (UINT32)partition.size()); + + // Add tree item + model->addItem(partitions[i].ptEntry.Offset, Types::Padding, getPaddingType(partition), name, UString(), info, UByteArray(), partition, UByteArray(), Fixed, parent); + } + } + + return U_SUCCESS; +} + +#endif // U_ENABLE_ME_PARSING_SUPPORT + diff --git a/common/meparser.h b/common/meparser.h new file mode 100755 index 0000000..db26505 --- /dev/null +++ b/common/meparser.h @@ -0,0 +1,73 @@ +/* meparser.h + +Copyright (c) 2016, Nikolaj Schlej. All rights reserved. + +This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php. + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +*/ + +#ifndef MEPARSER_H +#define MEPARSER_H + +#include + +#include "basetypes.h" +#include "ustring.h" +#include "ubytearray.h" +#include "treemodel.h" +#include "ffsparser.h" + +#include "digest/sha2.h" + +#ifdef U_ENABLE_ME_PARSING_SUPPORT +class MeParser +{ +public: + // Default constructor and destructor + MeParser(TreeModel* treeModel, FfsParser* parser) : model(treeModel), ffsParser(parser) {} + ~MeParser() {} + + // Returns messages + std::vector > getMessages() const { return messagesVector; } + // Clears messages + void clearMessages() { messagesVector.clear(); } + + // ME parsing + USTATUS parseMeRegionBody(const UModelIndex & index); +private: + TreeModel *model; + FfsParser *ffsParser; + std::vector > messagesVector; + + void msg(const UString message, const UModelIndex index = UModelIndex()) { + messagesVector.push_back(std::pair(message, index)); + } + + USTATUS parseFptRegion(const UByteArray & region, const UModelIndex & parent, UModelIndex & index); + USTATUS parseIfwi16Region(const UByteArray & region, const UModelIndex & parent, UModelIndex & index); + USTATUS parseIfwi17Region(const UByteArray & region, const UModelIndex & parent, UModelIndex & index); +}; +#else +class MeParser +{ +public: + // Default constructor and destructor + MeParser(TreeModel* treeModel, FfsParser* parser) { U_UNUSED_PARAMETER(treeModel); U_UNUSED_PARAMETER(parser); } + ~MeParser() {} + + // Returns messages + std::vector > getMessages() const { return std::vector >(); } + // Clears messages + void clearMessages() {} + + // ME parsing + USTATUS parseMeRegionBody(const UModelIndex & index) { U_UNUSED_PARAMETER(index); return U_SUCCESS; } +}; +#endif // U_ENABLE_ME_PARSING_SUPPORT +#endif // MEPARSER_H diff --git a/common/meson.build b/common/meson.build new file mode 100644 index 0000000..7ca986d --- /dev/null +++ b/common/meson.build @@ -0,0 +1,64 @@ +lzma = static_library('lzma', + sources: [ + 'LZMA/LzmaDecompress.c', + 'LZMA/SDK/C/Bra86.c', + 'LZMA/SDK/C/LzmaDec.c', + 'Tiano/EfiTianoDecompress.c', + ], +) + +bstrlib = static_library('bstrlib', + sources: [ + 'bstrlib/bstrlib.c', + 'bstrlib/bstrwrap.cpp', + ], +) + +uefitoolcommon = static_library('uefitoolcommon', + sources: [ + 'guiddatabase.cpp', + 'types.cpp', + 'descriptor.cpp', + 'filesystem.cpp', + 'ffs.cpp', + 'nvram.cpp', + 'nvramparser.cpp', + 'meparser.cpp', + 'fitparser.cpp', + 'ffsparser.cpp', + 'ffsreport.cpp', + 'peimage.cpp', + 'treeitem.cpp', + 'treemodel.cpp', + 'utility.cpp', + 'ustring.cpp', + 'generated/ami_nvar.cpp', + 'generated/apple_sysf.cpp', + 'generated/dell_dvar.cpp', + 'generated/edk2_vss.cpp', + 'generated/edk2_vss2.cpp', + 'generated/edk2_ftw.cpp', + 'generated/insyde_fdc.cpp', + 'generated/insyde_fdm.cpp', + 'generated/ms_slic_marker.cpp', + 'generated/ms_slic_pubkey.cpp', + 'generated/phoenix_flm.cpp', + 'generated/phoenix_evsa.cpp', + 'generated/intel_acbp_v1.cpp', + 'generated/intel_acbp_v2.cpp', + 'generated/intel_keym_v1.cpp', + 'generated/intel_keym_v2.cpp', + 'generated/intel_acm.cpp', + 'kaitai/kaitaistream.cpp', + 'digest/sha1.c', + 'digest/sha256.c', + 'digest/sha512.c', + 'digest/sm3.c', + ], + cpp_args: [ + '-DU_ENABLE_NVRAM_PARSING_SUPPORT', + '-DU_ENABLE_ME_PARSING_SUPPORT', + '-DU_ENABLE_FIT_PARSING_SUPPORT', + '-DU_ENABLE_GUID_DATABASE_SUPPORT', + ], +) diff --git a/common/nvram.cpp b/common/nvram.cpp index d34af8b..dff01d1 100644 --- a/common/nvram.cpp +++ b/common/nvram.cpp @@ -1,23 +1,85 @@ /* nvram.cpp -Copyright (c) 2016, Nikolaj Schlej. All rights reserved. - -This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php. - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -*/ + Copyright (c) 2016, Nikolaj Schlej. All rights reserved. + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + */ #include "nvram.h" +#include "ubytearray.h" + +// +// GUIDs mentioned in by nvram.h +// +extern const UByteArray ZERO_GUID // 00000000-0000-0000-0000-000000000000 +("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16); +extern const UByteArray NVRAM_NVAR_STORE_FILE_GUID // CEF5B9A3-476D-497F-9FDC-E98143E0422C +("\xA3\xB9\xF5\xCE\x6D\x47\x7F\x49\x9F\xDC\xE9\x81\x43\xE0\x42\x2C", 16); +extern const UByteArray NVRAM_NVAR_EXTERNAL_DEFAULTS_FILE_GUID // 9221315B-30BB-46B5-813E-1B1BF4712BD3 +("\x5B\x31\x21\x92\xBB\x30\xB5\x46\x81\x3E\x1B\x1B\xF4\x71\x2B\xD3", 16); +extern const UByteArray NVRAM_NVAR_PEI_EXTERNAL_DEFAULTS_FILE_GUID // 77D3DC50-D42B-4916-AC80-8F469035D150 +("\x50\xDC\xD3\x77\x2B\xD4\x16\x49\xAC\x80\x8F\x46\x90\x35\xD1\x50", 16); +extern const UByteArray NVRAM_NVAR_BB_DEFAULTS_FILE_GUID // AF516361-B4C5-436E-A7E3-A149A31B1461 +("\x61\x63\x51\xAF\xC5\xB4\x6E\x43\xA7\xE3\xA1\x49\xA3\x1B\x14\x61", 16); +extern const UByteArray NVRAM_MAIN_STORE_VOLUME_GUID // FFF12B8D-7696-4C8B-A985-2747075B4F50 +("\x8D\x2B\xF1\xFF\x96\x76\x8B\x4C\xA9\x85\x27\x47\x07\x5B\x4F\x50", 16); +extern const UByteArray NVRAM_ADDITIONAL_STORE_VOLUME_GUID // 00504624-8A59-4EEB-BD0F-6B36E96128E0 +("\x24\x46\x50\x00\x59\x8A\xEB\x4E\xBD\x0F\x6B\x36\xE9\x61\x28\xE0", 16); +extern const UByteArray NVRAM_VSS2_AUTH_VAR_KEY_DATABASE_GUID // AAF32C78-947B-439A-A180-2E144EC37792 +("\x78\x2C\xF3\xAA\x7B\x94\x9A\x43\xA1\x80\x2E\x14\x4E\xC3\x77\x92"); +extern const UByteArray NVRAM_VSS2_STORE_GUID // DDCF3617-3275-4164-98B6-FE85707FFE7D +("\x17\x36\xCF\xDD\x75\x32\x64\x41\x98\xB6\xFE\x85\x70\x7F\xFE\x7D"); +extern const UByteArray NVRAM_FDC_STORE_GUID // DDCF3616-3275-4164-98B6-FE85707FFE7D +("\x16\x36\xCF\xDD\x75\x32\x64\x41\x98\xB6\xFE\x85\x70\x7F\xFE\x7D"); +extern const UByteArray EDKII_WORKING_BLOCK_SIGNATURE_GUID // 9E58292B-7C68-497D-0ACE6500FD9F1B95 +("\x2B\x29\x58\x9E\x68\x7C\x7D\x49\x0A\xCE\x65\x00\xFD\x9F\x1B\x95", 16); +extern const UByteArray VSS2_WORKING_BLOCK_SIGNATURE_GUID // 9E58292B-7C68-497D-A0CE6500FD9F1B95 +("\x2B\x29\x58\x9E\x68\x7C\x7D\x49\xA0\xCE\x65\x00\xFD\x9F\x1B\x95", 16); +extern const UByteArray NVRAM_PHOENIX_FLASH_MAP_VOLUME_HEADER // B091E7D2-05A0-4198-94F0-74B7B8C55459 +("\xD2\xE7\x91\xB0\xA0\x05\x98\x41\x94\xF0\x74\xB7\xB8\xC5\x54\x59", 16); +extern const UByteArray NVRAM_PHOENIX_FLASH_MAP_MICROCODES_GUID // FD3F690E-B4B0-4D68-89DB-19A1A3318F90 +("\x0E\x69\x3F\xFD\xB0\xB4\x68\x4D\x89\xDB\x19\xA1\xA3\x31\x8F\x90", 16); +extern const UByteArray NVRAM_PHOENIX_FLASH_MAP_CMDB_GUID // 46310243-7B03-4132-BE44-2243FACA7CDD +("\x43\x02\x31\x46\x03\x7B\x32\x41\xBE\x44\x22\x43\xFA\xCA\x7C\xDD", 16); +extern const UByteArray NVRAM_PHOENIX_FLASH_MAP_PUBKEY1_GUID // 1B2C4952-D778-4B64-BDA1-15A36F5FA545 +("\x52\x49\x2C\x1B\x78\xD7\x64\x4B\xBD\xA1\x15\xA3\x6F\x5F\xA5\x45", 16); +extern const UByteArray NVRAM_PHOENIX_FLASH_MAP_MARKER1_GUID // 127C1C4E-9135-46E3-B006-F9808B0559A5 +("\x4E\x1C\x7C\x12\x35\x91\xE3\x46\xB0\x06\xF9\x80\x8B\x05\x59\xA5", 16); +extern const UByteArray NVRAM_PHOENIX_FLASH_MAP_PUBKEY2_GUID // 7CE75114-8272-45AF-B536-761BD38852CE +("\x14\x51\xE7\x7C\x72\x82\xAF\x45\xB5\x36\x76\x1B\xD3\x88\x52\xCE", 16); +extern const UByteArray NVRAM_PHOENIX_FLASH_MAP_MARKER2_GUID // 071A3DBE-CFF4-4B73-83F0-598C13DCFDD5 +("\xBE\x3D\x1A\x07\xF4\xCF\x73\x4B\x83\xF0\x59\x8C\x13\xDC\xFD\xD5", 16); +extern const UByteArray NVRAM_PHOENIX_FLASH_MAP_EVSA1_GUID // FACFB110-7BFD-4EFB-873E-88B6B23B97EA +("\x10\xB1\xCF\xFA\xFD\x7B\xFB\x4E\x87\x3E\x88\xB6\xB2\x3B\x97\xEA", 16); +extern const UByteArray NVRAM_PHOENIX_FLASH_MAP_EVSA2_GUID // E68DC11A-A5F4-4AC3-AA2E-29E298BFF645 +("\x1A\xC1\x8D\xE6\xF4\xA5\xC3\x4A\xAA\x2E\x29\xE2\x98\xBF\xF6\x45", 16); +extern const UByteArray NVRAM_PHOENIX_FLASH_MAP_EVSA3_GUID // 4B3828AE-0ACE-45B6-8CDB-DAFC28BBF8C5 +("\xAE\x28\x38\x4B\xCE\x0A\xB6\x45\x8C\xDB\xDA\xFC\x28\xBB\xF8\xC5", 16); +extern const UByteArray NVRAM_PHOENIX_FLASH_MAP_EVSA4_GUID // C22E6B8A-8159-49A3-B353-E84B79DF19C0 +("\x8A\x6B\x2E\xC2\x59\x81\xA3\x49\xB3\x53\xE8\x4B\x79\xDF\x19\xC0", 16); +extern const UByteArray NVRAM_PHOENIX_FLASH_MAP_EVSA5_GUID // B6B5FAB9-75C4-4AAE-8314-7FFFA7156EAA +("\xB9\xFA\xB5\xB6\xC4\x75\xAE\x4A\x83\x14\x7F\xFF\xA7\x15\x6E\xAA", 16); +extern const UByteArray NVRAM_PHOENIX_FLASH_MAP_EVSA6_GUID // 919B9699-8DD0-4376-AA0B-0E54CCA47D8F +("\x99\x96\x9B\x91\xD0\x8D\x76\x43\xAA\x0B\x0E\x54\xCC\xA4\x7D\x8F", 16); +extern const UByteArray NVRAM_PHOENIX_FLASH_MAP_EVSA7_GUID // 58A90A52-929F-44F8-AC35-A7E1AB18AC91 +("\x52\x0A\xA9\x58\x9F\x92\xF8\x44\xAC\x35\xA7\xE1\xAB\x18\xAC\x91", 16); +extern const UByteArray NVRAM_PHOENIX_FLASH_MAP_SELF_GUID // 8CB71915-531F-4AF5-82BF-A09140817BAA +("\x15\x19\xB7\x8C\x1F\x53\xF5\x4A\x82\xBF\xA0\x91\x40\x81\x7B\xAA", 16); + +extern const UByteArray NVRAM_PHOENIX_FLASH_MAP_SIGNATURE +("\x5F\x46\x4C\x41\x53\x48\x5F\x4D\x41\x50", 10); UString nvarAttributesToUString(const UINT8 attributes) { - if (attributes == 0x00 || attributes == 0xFF) + if (attributes == 0x00 || attributes == 0xFF) return UString(); - + UString str; if (attributes & NVRAM_NVAR_ENTRY_RUNTIME) str += UString(", Runtime"); if (attributes & NVRAM_NVAR_ENTRY_ASCII_NAME) str += UString(", AsciiName"); @@ -39,7 +101,7 @@ UString nvarExtendedAttributesToUString(const UINT8 attributes) if (attributes & NVRAM_NVAR_ENTRY_EXT_AUTH_WRITE) str += UString(", AuthWrite"); if (attributes & NVRAM_NVAR_ENTRY_EXT_TIME_BASED) str += UString(", TimeBasedAuthWrite"); if (attributes & NVRAM_NVAR_ENTRY_EXT_UNKNOWN_MASK) str += UString(", Unknown"); - + str.remove(0, 2); // Remove first comma and space return str; } @@ -56,7 +118,7 @@ extern UString vssAttributesToUString(const UINT32 attributes) if (attributes & NVRAM_VSS_VARIABLE_APPEND_WRITE) str += UString(", AppendWrite"); if (attributes & NVRAM_VSS_VARIABLE_APPLE_DATA_CHECKSUM) str += UString(", AppleChecksum"); if (attributes & NVRAM_VSS_VARIABLE_UNKNOWN_MASK) str += UString(", Unknown"); - + str.remove(0, 2); // Remove first comma and space return str; } @@ -73,7 +135,7 @@ UString evsaAttributesToUString(const UINT32 attributes) if (attributes & NVRAM_EVSA_DATA_APPEND_WRITE) str += UString(", AppendWrite"); if (attributes & NVRAM_EVSA_DATA_EXTENDED_HEADER) str += UString(", ExtendedHeader"); if (attributes & NVRAM_EVSA_DATA_UNKNOWN_MASK) str += UString(", Unknown"); - + str.remove(0, 2); // Remove first comma and space return str; } @@ -81,24 +143,24 @@ UString evsaAttributesToUString(const UINT32 attributes) UString efiTimeToUString(const EFI_TIME & time) { return usprintf("%04u-%02u-%02uT%02u:%02u:%02u.%u", - time.Year, - time.Month, - time.Day, - time.Hour, - time.Minute, - time.Second, - time.Nanosecond); + time.Year, + time.Month, + time.Day, + time.Hour, + time.Minute, + time.Second, + time.Nanosecond); } -UString flashMapGuidToUString(const EFI_GUID & guid) +UString phoenixFlashMapGuidToUString(const EFI_GUID & guid) { const UByteArray baGuid((const char*)&guid, sizeof(EFI_GUID)); if (baGuid == NVRAM_PHOENIX_FLASH_MAP_VOLUME_HEADER) return UString("Volume header"); if (baGuid == NVRAM_PHOENIX_FLASH_MAP_MICROCODES_GUID) return UString("Microcodes"); if (baGuid == NVRAM_PHOENIX_FLASH_MAP_CMDB_GUID) return UString("CMDB"); - if (baGuid == NVRAM_PHOENIX_FLASH_MAP_PUBKEY1_GUID + if (baGuid == NVRAM_PHOENIX_FLASH_MAP_PUBKEY1_GUID || baGuid == NVRAM_PHOENIX_FLASH_MAP_PUBKEY2_GUID) return UString("SLIC pubkey"); - if (baGuid == NVRAM_PHOENIX_FLASH_MAP_MARKER1_GUID + if (baGuid == NVRAM_PHOENIX_FLASH_MAP_MARKER1_GUID || baGuid == NVRAM_PHOENIX_FLASH_MAP_MARKER2_GUID) return UString("SLIC marker"); if (baGuid == NVRAM_PHOENIX_FLASH_MAP_EVSA1_GUID || baGuid == NVRAM_PHOENIX_FLASH_MAP_EVSA2_GUID @@ -108,6 +170,7 @@ UString flashMapGuidToUString(const EFI_GUID & guid) || baGuid == NVRAM_PHOENIX_FLASH_MAP_EVSA6_GUID || baGuid == NVRAM_PHOENIX_FLASH_MAP_EVSA7_GUID) return UString("EVSA store"); if (baGuid == NVRAM_PHOENIX_FLASH_MAP_SELF_GUID) return UString("Flash map"); - return UString(); + if (baGuid == ZERO_GUID) return UString(); + return UString("Unknown"); } diff --git a/common/nvram.h b/common/nvram.h old mode 100644 new mode 100755 index 7a26f74..aadc20a --- a/common/nvram.h +++ b/common/nvram.h @@ -15,9 +15,10 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #ifndef NVRAM_H #define NVRAM_H +#include "basetypes.h" +#include "ffs.h" #include "ubytearray.h" #include "ustring.h" -#include "basetypes.h" // Make sure we use right packing rules #pragma pack(push, 1) @@ -25,14 +26,10 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. // // NVAR store and entry // - -// CEF5B9A3-476D-497F-9FDC-E98143E0422C -const UByteArray NVRAM_NVAR_STORE_FILE_GUID -("\xA3\xB9\xF5\xCE\x6D\x47\x7F\x49\x9F\xDC\xE9\x81\x43\xE0\x42\x2C", 16); - -// 9221315B-30BB-46B5-813E-1B1BF4712BD3 -const UByteArray NVRAM_NVAR_EXTERNAL_DEFAULTS_FILE_GUID -("\x5B\x31\x21\x92\xBB\x30\xB5\x46\x81\x3E\x1B\x1B\xF4\x71\x2B\xD3", 16); +extern const UByteArray NVRAM_NVAR_STORE_FILE_GUID; // CEF5B9A3-476D-497F-9FDC-E98143E0422C +extern const UByteArray NVRAM_NVAR_EXTERNAL_DEFAULTS_FILE_GUID; // 9221315B-30BB-46B5-813E-1B1BF4712BD3 +extern const UByteArray NVRAM_NVAR_PEI_EXTERNAL_DEFAULTS_FILE_GUID; // 77D3DC50-D42B-4916-AC80-8F469035D150 +extern const UByteArray NVRAM_NVAR_BB_DEFAULTS_FILE_GUID; // AF516361-B4C5-436E-A7E3-A149A31B1461 extern UString nvarAttributesToUString(const UINT8 attributes); extern UString nvarExtendedAttributesToUString(const UINT8 attributes); @@ -41,7 +38,7 @@ extern UString efiTimeToUString(const EFI_TIME & time); typedef struct NVAR_ENTRY_HEADER_ { UINT32 Signature; // NVAR UINT16 Size; // Size of the entry including header - UINT32 Next : 24; // Offset to the next entry in a list, or empty if latest in the list + UINT32 Next : 24; // Offset to the next entry in a list, or empty if the latest in the list UINT32 Attributes : 8; // Attributes } NVAR_ENTRY_HEADER; @@ -49,37 +46,30 @@ typedef struct NVAR_ENTRY_HEADER_ { #define NVRAM_NVAR_ENTRY_SIGNATURE 0x5241564E // Attributes -#define NVRAM_NVAR_ENTRY_RUNTIME 0x01 -#define NVRAM_NVAR_ENTRY_ASCII_NAME 0x02 -#define NVRAM_NVAR_ENTRY_GUID 0x04 -#define NVRAM_NVAR_ENTRY_DATA_ONLY 0x08 -#define NVRAM_NVAR_ENTRY_EXT_HEADER 0x10 -#define NVRAM_NVAR_ENTRY_HW_ERROR_RECORD 0x20 -#define NVRAM_NVAR_ENTRY_AUTH_WRITE 0x40 -#define NVRAM_NVAR_ENTRY_VALID 0x80 +#define NVRAM_NVAR_ENTRY_RUNTIME 0x01 +#define NVRAM_NVAR_ENTRY_ASCII_NAME 0x02 +#define NVRAM_NVAR_ENTRY_GUID 0x04 +#define NVRAM_NVAR_ENTRY_DATA_ONLY 0x08 +#define NVRAM_NVAR_ENTRY_EXT_HEADER 0x10 +#define NVRAM_NVAR_ENTRY_HW_ERROR_RECORD 0x20 +#define NVRAM_NVAR_ENTRY_AUTH_WRITE 0x40 +#define NVRAM_NVAR_ENTRY_VALID 0x80 // Extended attributes #define NVRAM_NVAR_ENTRY_EXT_CHECKSUM 0x01 #define NVRAM_NVAR_ENTRY_EXT_AUTH_WRITE 0x10 #define NVRAM_NVAR_ENTRY_EXT_TIME_BASED 0x20 #define NVRAM_NVAR_ENTRY_EXT_UNKNOWN_MASK 0xCE + // // TianoCore VSS store and variables // - -// FFF12B8D-7696-4C8B-A985-2747075B4F50 -const UByteArray NVRAM_MAIN_STORE_VOLUME_GUID -("\x8D\x2B\xF1\xFF\x96\x76\x8B\x4C\xA9\x85\x27\x47\x07\x5B\x4F\x50", 16); - -// 00504624-8A59-4EEB-BD0F-6B36E96128E0 -const UByteArray NVRAM_ADDITIONAL_STORE_VOLUME_GUID -("\x24\x46\x50\x00\x59\x8A\xEB\x4E\xBD\x0F\x6B\x36\xE9\x61\x28\xE0", 16); +extern const UByteArray NVRAM_MAIN_STORE_VOLUME_GUID; // FFF12B8D-7696-4C8B-A985-2747075B4F50 +extern const UByteArray NVRAM_ADDITIONAL_STORE_VOLUME_GUID; // 00504624-8A59-4EEB-BD0F-6B36E96128E0 #define NVRAM_VSS_STORE_SIGNATURE 0x53535624 // $VSS #define NVRAM_APPLE_SVS_STORE_SIGNATURE 0x53565324 // $SVS -#define NVRAM_APPLE_FSYS_STORE_SIGNATURE 0x73797346 // Fsys -#define NVRAM_APPLE_GAID_STORE_SIGNATURE 0x64696147 // Gaid -#define NVRAM_VSS_VARIABLE_START_ID 0x55AA +#define NVRAM_APPLE_NSS_STORE_SIGNATURE 0x53534E24 // $NSS // Variable store header flags #define NVRAM_VSS_VARIABLE_STORE_FORMATTED 0x5a @@ -93,30 +83,40 @@ const UByteArray NVRAM_ADDITIONAL_STORE_VOLUME_GUID // Variable store header typedef struct VSS_VARIABLE_STORE_HEADER_ { - UINT32 Signature; // $VSS signature - UINT32 Size; // Size of variable store, including store header - UINT8 Format; // Store format state - UINT8 State; // Store health state - UINT16 Unknown; // Used in Apple $SVS varstores - UINT32 : 32; + UINT32 Signature; // Signature + UINT32 Size; // Size of variable store, including store header + UINT8 Format; // Store format state + UINT8 State; // Store health state + UINT16 Reserved; // Used in Apple $SVS varstores + UINT32 Reserved1; // Reserved } VSS_VARIABLE_STORE_HEADER; // Normal variable header typedef struct VSS_VARIABLE_HEADER_ { UINT16 StartId; // Variable start marker AA55 UINT8 State; // Variable state - UINT8 : 8; + UINT8 Reserved; UINT32 Attributes; // Variable attributes UINT32 NameSize; // Size of variable name, stored as null-terminated UCS2 string UINT32 DataSize; // Size of variable data without header and name EFI_GUID VendorGuid; // Variable vendor GUID } VSS_VARIABLE_HEADER; +// Intel variable header +typedef struct VSS_INTEL_VARIABLE_HEADER_ { + UINT16 StartId; // Variable start marker AA55 + UINT8 State; // Variable state + UINT8 Reserved; + UINT32 Attributes; // Variable attributes + UINT32 TotalSize; // Size of variable including header + EFI_GUID VendorGuid; // Variable vendor GUID +} VSS_INTEL_VARIABLE_HEADER; + // Apple variation of normal variable header, with one new field typedef struct VSS_APPLE_VARIABLE_HEADER_ { UINT16 StartId; // Variable start marker AA55 UINT8 State; // Variable state - UINT8 : 8; + UINT8 Reserved; UINT32 Attributes; // Variable attributes UINT32 NameSize; // Size of variable name, stored as null-terminated UCS2 string UINT32 DataSize; // Size of variable data without header and name @@ -127,8 +127,8 @@ typedef struct VSS_APPLE_VARIABLE_HEADER_ { // Authenticated variable header, used for SecureBoot vars typedef struct VSS_AUTH_VARIABLE_HEADER_ { UINT16 StartId; // Variable start marker AA55 - UINT8 State; // Variable state - UINT8 : 8; + UINT8 State; // Variable state + UINT8 Reserved; UINT32 Attributes; // Variable attributes UINT64 MonotonicCounter; // Monotonic counter against replay attack EFI_TIME Timestamp; // Time stamp against replay attack @@ -139,11 +139,12 @@ typedef struct VSS_AUTH_VARIABLE_HEADER_ { } VSS_AUTH_VARIABLE_HEADER; // VSS variable states -#define NVRAM_VSS_VARIABLE_IN_DELETED_TRANSITION 0xfe // Variable is in obsolete transistion -#define NVRAM_VSS_VARIABLE_DELETED 0xfd // Variable is obsolete -#define NVRAM_VSS_VARIABLE_HEADER_VALID 0x7f // Variable has valid header -#define NVRAM_VSS_VARIABLE_ADDED 0x3f // Variable has been completely added -#define NVRAM_VSS_IS_VARIABLE_STATE(_c, _Mask) (BOOLEAN) (((~_c) & (~_Mask)) != 0) +#define NVRAM_VSS_VARIABLE_IN_DELETED_TRANSITION 0xfe // Variable is in obsolete transistion +#define NVRAM_VSS_VARIABLE_DELETED 0xfd // Variable is obsolete +#define NVRAM_VSS_VARIABLE_HEADER_VALID 0x7f // Variable has valid header +#define NVRAM_VSS_VARIABLE_ADDED 0x3f // Variable has been completely added +#define NVRAM_VSS_INTEL_VARIABLE_VALID 0xfc // Intel special variable valid +#define NVRAM_VSS_INTEL_VARIABLE_INVALID 0xf8 // Intel special variable invalid // VSS variable attributes #define NVRAM_VSS_VARIABLE_NON_VOLATILE 0x00000001 @@ -159,34 +160,46 @@ typedef struct VSS_AUTH_VARIABLE_HEADER_ { extern UString vssAttributesToUString(const UINT32 attributes); // -// _FDC region +// VSS2 variables // +extern const UByteArray NVRAM_VSS2_AUTH_VAR_KEY_DATABASE_GUID; // AAF32C78-947B-439A-A180-2E144EC37792 +extern const UByteArray NVRAM_VSS2_STORE_GUID; // DDCF3617-3275-4164-98B6-FE85707FFE7D +extern const UByteArray NVRAM_FDC_STORE_GUID; // DDCF3616-3275-4164-98B6-FE85707FFE7D -#define NVRAM_FDC_VOLUME_SIGNATURE 0x4344465F +// Variable store header +typedef struct VSS2_VARIABLE_STORE_HEADER_ { + EFI_GUID Signature; // VSS2 Store Guid + UINT32 Size; // Size of variable store, including store header + UINT8 Format; // Store format state + UINT8 State; // Store health state + UINT16 Reserved; + UINT32 Reserved1; +} VSS2_VARIABLE_STORE_HEADER; -typedef struct FDC_VOLUME_HEADER_ { +// VSS2 entries are 4-bytes aligned in VSS2 stores + +// +// Insyde Factory Data Copy store +// +#define INSYDE_FDC_STORE_SIGNATURE 0x4344465F + +typedef struct INSYDE_FDC_STORE_HEADER_ { UINT32 Signature; //_FDC signature UINT32 Size; // Size of the whole region - //EFI_FIRMWARE_VOLUME_HEADER VolumeHeader; - //EFI_FV_BLOCK_MAP_ENTRY FvBlockMap[2]; - //VSS_VARIABLE_STORE_HEADER VssHeader; -} FDC_VOLUME_HEADER; + EFI_FIRMWARE_VOLUME_HEADER VolumeHeader; + EFI_FV_BLOCK_MAP_ENTRY FvBlockMap[2]; +} INSYDE_FDC_STORE_HEADER; // // FTW block // #define EFI_FAULT_TOLERANT_WORKING_BLOCK_VALID 0x1 #define EFI_FAULT_TOLERANT_WORKING_BLOCK_INVALID 0x2 - -// 9E58292B-7C68-497D-0ACE6500FD9F1B95 -const UByteArray EDKII_WORKING_BLOCK_SIGNATURE_GUID -("\x2B\x29\x58\x9E\x68\x7C\x7D\x49\x0A\xCE\x65\x00\xFD\x9F\x1B\x95", 16); - -#define NVRAM_MAIN_STORE_VOLUME_GUID_DATA1 0xFFF12B8D -#define EDKII_WORKING_BLOCK_SIGNATURE_GUID_DATA1 0x9E58292B +extern const UByteArray EDKII_WORKING_BLOCK_SIGNATURE_GUID; // 9E58292B-7C68-497D-0ACE-6500FD9F1B95 +extern const UByteArray VSS2_WORKING_BLOCK_SIGNATURE_GUID; // 9E58292B-7C68-497D-A0CE-6500FD9F1B95 typedef struct EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER32_ { - EFI_GUID Signature; // NVRAM_MAIN_STORE_VOLUME_GUID + EFI_GUID Signature; UINT32 Crc; // Crc32 of the header with empty Crc and State fields UINT8 State; UINT8 Reserved[3]; @@ -195,7 +208,7 @@ typedef struct EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER32_ { } EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER32; typedef struct EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER64_ { - EFI_GUID Signature; // NVRAM_MAIN_STORE_VOLUME_GUID or EDKII_WORKING_BLOCK_SIGNATURE_GUID + EFI_GUID Signature; UINT32 Crc; // Crc32 of the header with empty Crc and State fields UINT8 State; UINT8 Reserved[3]; @@ -204,17 +217,18 @@ typedef struct EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER64_ { } EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER64; // -// Apple Fsys store +// Apple System Flags store // - -typedef struct APPLE_FSYS_STORE_HEADER_ { +#define NVRAM_APPLE_SYSF_STORE_SIGNATURE 0x73797346 // Fsys +#define NVRAM_APPLE_DIAG_STORE_SIGNATURE 0x64696147 // Gaid +typedef struct APPLE_SYSF_STORE_HEADER_ { UINT32 Signature; // Fsys or Gaid signature - UINT8 Unknown0; // Still unknown + UINT8 Unknown; // Still unknown UINT32 Unknown1; // Still unknown UINT16 Size; // Size of variable store -} APPLE_FSYS_STORE_HEADER; +} APPLE_SYSF_STORE_HEADER; -// Apple Fsys entry format +// Apple SysF entry format // UINT8 NameLength; // CHAR8 Name[]; // UINT16 DataLength; @@ -249,7 +263,7 @@ typedef struct EVSA_STORE_ENTRY_ { UINT32 Signature; // EVSA signature UINT32 Attributes; UINT32 StoreSize; - UINT32 : 32; + UINT32 Reserved; } EVSA_STORE_ENTRY; typedef struct EVSA_GUID_ENTRY_ { @@ -297,18 +311,13 @@ extern UString evsaAttributesToUString(const UINT32 attributes); // // Phoenix SCT Flash Map // - -#define NVRAM_PHOENIX_FLASH_MAP_SIGNATURE_PART1 0x414C465F #define NVRAM_PHOENIX_FLASH_MAP_SIGNATURE_LENGTH 10 - -// _FLASH_MAP -const UByteArray NVRAM_PHOENIX_FLASH_MAP_SIGNATURE -("\x5F\x46\x4C\x41\x53\x48\x5F\x4D\x41\x50", 10); +extern const UByteArray NVRAM_PHOENIX_FLASH_MAP_SIGNATURE; // _FLASH_MAP typedef struct PHOENIX_FLASH_MAP_HEADER_ { UINT8 Signature[10]; // _FLASH_MAP signature UINT16 NumEntries; // Number of entries in the map - UINT32 : 32; // Reserved field + UINT32 Reserved; // Reserved field } PHOENIX_FLASH_MAP_HEADER; typedef struct PHOENIX_FLASH_MAP_ENTRY_ { @@ -319,76 +328,32 @@ typedef struct PHOENIX_FLASH_MAP_ENTRY_ { UINT32 Size; UINT32 Offset; } PHOENIX_FLASH_MAP_ENTRY; +#define NVRAM_PHOENIX_FLASH_MAP_TOTAL_SIZE 0x1000 +#define NVRAM_PHOENIX_FLASH_MAP_MAX_ENTRIES 113 +#define NVRAM_PHOENIX_FLASH_MAP_ENTRY_DATA_TYPE_VOLUME 0x0000 +#define NVRAM_PHOENIX_FLASH_MAP_ENTRY_DATA_TYPE_DATA_BLOCK 0x0001 -#define NVRAM_PHOENIX_FLASH_MAP_ENTRY_TYPE_VOLUME 0x0000 -#define NVRAM_PHOENIX_FLASH_MAP_ENTRY_TYPE_DATA_BLOCK 0x0001 +extern UString phoenixFlashMapGuidToUString(const EFI_GUID & guid); -extern UString flashMapGuidToUString(const EFI_GUID & guid); - -// B091E7D2-05A0-4198-94F0-74B7B8C55459 -const UByteArray NVRAM_PHOENIX_FLASH_MAP_VOLUME_HEADER -("\xD2\xE7\x91\xB0\xA0\x05\x98\x41\x94\xF0\x74\xB7\xB8\xC5\x54\x59", 16); - -// FD3F690E-B4B0-4D68-89DB-19A1A3318F90 -const UByteArray NVRAM_PHOENIX_FLASH_MAP_MICROCODES_GUID -("\x0E\x69\x3F\xFD\xB0\xB4\x68\x4D\x89\xDB\x19\xA1\xA3\x31\x8F\x90", 16); - -// 46310243-7B03-4132-BE44-2243FACA7CDD -const UByteArray NVRAM_PHOENIX_FLASH_MAP_CMDB_GUID -("\x43\x02\x31\x46\x03\x7B\x32\x41\xBE\x44\x22\x43\xFA\xCA\x7C\xDD", 16); - -// 1B2C4952-D778-4B64-BDA1-15A36F5FA545 -const UByteArray NVRAM_PHOENIX_FLASH_MAP_PUBKEY1_GUID -("\x52\x49\x2C\x1B\x78\xD7\x64\x4B\xBD\xA1\x15\xA3\x6F\x5F\xA5\x45", 16); - -// 127C1C4E-9135-46E3-B006-F9808B0559A5 -const UByteArray NVRAM_PHOENIX_FLASH_MAP_MARKER1_GUID -("\x4E\x1C\x7C\x12\x35\x91\xE3\x46\xB0\x06\xF9\x80\x8B\x05\x59\xA5", 16); - -// 7CE75114-8272-45AF-B536-761BD38852CE -const UByteArray NVRAM_PHOENIX_FLASH_MAP_PUBKEY2_GUID -("\x14\x51\xE7\x7C\x72\x82\xAF\x45\xB5\x36\x76\x1B\xD3\x88\x52\xCE", 16); - -// 071A3DBE-CFF4-4B73-83F0-598C13DCFDD5 -const UByteArray NVRAM_PHOENIX_FLASH_MAP_MARKER2_GUID -("\xBE\x3D\x1A\x07\xF4\xCF\x73\x4B\x83\xF0\x59\x8C\x13\xDC\xFD\xD5", 16); - -// FACFB110-7BFD-4EFB-873E-88B6B23B97EA -const UByteArray NVRAM_PHOENIX_FLASH_MAP_EVSA1_GUID -("\x10\xB1\xCF\xFA\xFD\x7B\xFB\x4E\x87\x3E\x88\xB6\xB2\x3B\x97\xEA", 16); - -// E68DC11A-A5F4-4AC3-AA2E-29E298BFF645 -const UByteArray NVRAM_PHOENIX_FLASH_MAP_EVSA2_GUID -("\x1A\xC1\x8D\xE6\xF4\xA5\xC3\x4A\xAA\x2E\x29\xE2\x98\xBF\xF6\x45", 16); - -// 4B3828AE-0ACE-45B6-8CDB-DAFC28BBF8C5 -const UByteArray NVRAM_PHOENIX_FLASH_MAP_EVSA3_GUID -("\xAE\x28\x38\x4B\xCE\x0A\xB6\x45\x8C\xDB\xDA\xFC\x28\xBB\xF8\xC5", 16); - -// C22E6B8A-8159-49A3-B353-E84B79DF19C0 -const UByteArray NVRAM_PHOENIX_FLASH_MAP_EVSA4_GUID -("\x8A\x6B\x2E\xC2\x59\x81\xA3\x49\xB3\x53\xE8\x4B\x79\xDF\x19\xC0", 16); - -// B6B5FAB9-75C4-4AAE-8314-7FFFA7156EAA -const UByteArray NVRAM_PHOENIX_FLASH_MAP_EVSA5_GUID -("\xB9\xFA\xB5\xB6\xC4\x75\xAE\x4A\x83\x14\x7F\xFF\xA7\x15\x6E\xAA", 16); - -// 919B9699-8DD0-4376-AA0B-0E54CCA47D8F -const UByteArray NVRAM_PHOENIX_FLASH_MAP_EVSA6_GUID -("\x99\x96\x9B\x91\xD0\x8D\x76\x43\xAA\x0B\x0E\x54\xCC\xA4\x7D\x8F", 16); - -// 58A90A52-929F-44F8-AC35-A7E1AB18AC91 -const UByteArray NVRAM_PHOENIX_FLASH_MAP_EVSA7_GUID -("\x52\x0A\xA9\x58\x9F\x92\xF8\x44\xAC\x35\xA7\xE1\xAB\x18\xAC\x91", 16); - -// 8CB71915-531F-4AF5-82BF-A09140817BAA -const UByteArray NVRAM_PHOENIX_FLASH_MAP_SELF_GUID -("\x15\x19\xB7\x8C\x1F\x53\xF5\x4A\x82\xBF\xA0\x91\x40\x81\x7B\xAA", 16); +extern const UByteArray NVRAM_PHOENIX_FLASH_MAP_VOLUME_HEADER; // B091E7D2-05A0-4198-94F0-74B7B8C55459 +extern const UByteArray NVRAM_PHOENIX_FLASH_MAP_MICROCODES_GUID; // FD3F690E-B4B0-4D68-89DB-19A1A3318F90 +extern const UByteArray NVRAM_PHOENIX_FLASH_MAP_CMDB_GUID; // 46310243-7B03-4132-BE44-2243FACA7CDD +extern const UByteArray NVRAM_PHOENIX_FLASH_MAP_PUBKEY1_GUID; // 1B2C4952-D778-4B64-BDA1-15A36F5FA545 +extern const UByteArray NVRAM_PHOENIX_FLASH_MAP_MARKER1_GUID; // 127C1C4E-9135-46E3-B006-F9808B0559A5 +extern const UByteArray NVRAM_PHOENIX_FLASH_MAP_PUBKEY2_GUID; // 7CE75114-8272-45AF-B536-761BD38852CE +extern const UByteArray NVRAM_PHOENIX_FLASH_MAP_MARKER2_GUID; // 071A3DBE-CFF4-4B73-83F0-598C13DCFDD5 +extern const UByteArray NVRAM_PHOENIX_FLASH_MAP_EVSA1_GUID; // FACFB110-7BFD-4EFB-873E-88B6B23B97EA +extern const UByteArray NVRAM_PHOENIX_FLASH_MAP_EVSA2_GUID; // E68DC11A-A5F4-4AC3-AA2E-29E298BFF645 +extern const UByteArray NVRAM_PHOENIX_FLASH_MAP_EVSA3_GUID; // 4B3828AE-0ACE-45B6-8CDB-DAFC28BBF8C5 +extern const UByteArray NVRAM_PHOENIX_FLASH_MAP_EVSA4_GUID; // C22E6B8A-8159-49A3-B353-E84B79DF19C0 +extern const UByteArray NVRAM_PHOENIX_FLASH_MAP_EVSA5_GUID; // B6B5FAB9-75C4-4AAE-8314-7FFFA7156EAA +extern const UByteArray NVRAM_PHOENIX_FLASH_MAP_EVSA6_GUID; // 919B9699-8DD0-4376-AA0B-0E54CCA47D8F +extern const UByteArray NVRAM_PHOENIX_FLASH_MAP_EVSA7_GUID; // 58A90A52-929F-44F8-AC35-A7E1AB18AC91 +extern const UByteArray NVRAM_PHOENIX_FLASH_MAP_SELF_GUID; // 8CB71915-531F-4AF5-82BF-A09140817BAA // // SLIC pubkey and marker // - typedef struct OEM_ACTIVATION_PUBKEY_ { UINT32 Type; // 0 UINT32 Size; // 0x9C @@ -417,15 +382,13 @@ typedef struct OEM_ACTIVATION_MARKER_ { UINT8 Signature[128]; } OEM_ACTIVATION_MARKER; -#define OEM_ACTIVATION_MARKER_TYPE 0x00000001 -#define OEM_ACTIVATION_MARKER_WINDOWS_FLAG_PART1 0x444E4957 -#define OEM_ACTIVATION_MARKER_WINDOWS_FLAG 0x2053574F444E4957UL -#define OEM_ACTIVATION_MARKER_RESERVED_BYTE 0x00 +#define OEM_ACTIVATION_MARKER_TYPE 0x00000001 +#define OEM_ACTIVATION_MARKER_WINDOWS_FLAG 0x2053574F444E4957UL // WINDOWS +#define OEM_ACTIVATION_MARKER_RESERVED_BYTE 0x00 // // Phoenix CMDB, no londer used, requires no parsing // - typedef struct PHOENIX_CMDB_HEADER_ { UINT32 Signature; // CMDB signature UINT32 HeaderSize; // Size of this header @@ -436,7 +399,10 @@ typedef struct PHOENIX_CMDB_HEADER_ { } PHOENIX_CMDB_HEADER; #define NVRAM_PHOENIX_CMDB_HEADER_SIGNATURE 0x42444D43 -#define NVRAM_PHOENIX_CMDB_SIZE 0x100; +#define NVRAM_PHOENIX_CMDB_SIZE 0x100 + +// Zero GUID +extern const UByteArray ZERO_GUID; // Restore previous packing rules #pragma pack(pop) diff --git a/common/nvramparser.cpp b/common/nvramparser.cpp new file mode 100644 index 0000000..765c289 --- /dev/null +++ b/common/nvramparser.cpp @@ -0,0 +1,1541 @@ +/* nvramparser.cpp + + Copyright (c) 2016, Nikolaj Schlej. All rights reserved. + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + */ + +#ifdef U_ENABLE_NVRAM_PARSING_SUPPORT +#include + +#include "nvramparser.h" +#include "parsingdata.h" +#include "ustring.h" +#include "utility.h" +#include "nvram.h" +#include "ffs.h" +#include "intel_microcode.h" + +#include "umemstream.h" +#include "kaitai/kaitaistream.h" +#include "generated/ami_nvar.h" +#include "generated/apple_sysf.h" +#include "generated/edk2_vss.h" +#include "generated/edk2_vss2.h" +#include "generated/edk2_ftw.h" +#include "generated/insyde_fdc.h" +#include "generated/ms_slic_pubkey.h" +#include "generated/ms_slic_marker.h" +#include "generated/phoenix_flm.h" +#include "generated/phoenix_evsa.h" + +#ifndef MIN +#define MIN(x, y) (((x) < (y)) ? (x) : (y)) +#endif + +USTATUS NvramParser::parseNvarStore(const UModelIndex & index) +{ + // Sanity check + if (!index.isValid()) + return U_INVALID_PARAMETER; + + UByteArray nvar = model->body(index); + + // Nothing to parse in an empty store + if (nvar.isEmpty()) + return U_SUCCESS; + + // Obtain required fields from parsing data + UINT8 emptyByte = 0xFF; + if (model->hasEmptyParsingData(index) == false) { + UByteArray data = model->parsingData(index); + const VOLUME_PARSING_DATA* pdata = (const VOLUME_PARSING_DATA*)data.constData(); + emptyByte = pdata->emptyByte; + } + + try { + const UINT32 localOffset = (UINT32)model->header(index).size(); + umemstream is(nvar.constData(), nvar.size()); + kaitai::kstream ks(&is); + ami_nvar_t parsed(&ks); + + UINT16 guidsInStore = 0; + UINT32 currentEntryIndex = 0; + for (const auto & entry : *parsed.entries()) { + UINT8 subtype = Subtypes::FullNvarEntry; + UString name; + UString text; + UString info; + UString guid; + UByteArray header; + UByteArray body; + UByteArray tail; + + // This is a terminating entry, needs special processing + if (entry->_is_null_signature_rest()) { + UINT32 guidAreaSize = guidsInStore * sizeof(EFI_GUID); + UINT32 unparsedSize = (UINT32)nvar.size() - entry->offset() - guidAreaSize; + + // Check if the data left is a free space or a padding + UByteArray padding = nvar.mid(entry->offset(), unparsedSize); + + // Get info + UString info = usprintf("Full size: %Xh (%u)", (UINT32)padding.size(), (UINT32)padding.size()); + + if ((UINT32)padding.count(emptyByte) == unparsedSize) { // Free space + // Add tree item + model->addItem(localOffset + entry->offset(), Types::FreeSpace, 0, UString("Free space"), UString(), info, UByteArray(), padding, UByteArray(), Fixed, index); + } + else { + // Nothing is parsed yet, but the file is not empty + if (entry->offset() == 0) { + msg(usprintf("%s: file can't be parsed as NVAR variable store", __FUNCTION__), index); + return U_SUCCESS; + } + + // Add tree item + model->addItem(localOffset + entry->offset(), Types::Padding, getPaddingType(padding), UString("Padding"), UString(), info, UByteArray(), padding, UByteArray(), Fixed, index); + } + + // Add GUID store area + UByteArray guidArea = nvar.right(guidAreaSize); + // Get info + name = UString("GUID store"); + info = usprintf("Full size: %Xh (%u)\nGUIDs in store: %u", + (UINT32)guidArea.size(), (UINT32)guidArea.size(), + guidsInStore); + // Add tree item + model->addItem((UINT32)(localOffset + entry->offset() + padding.size()), Types::NvarGuidStore, 0, name, UString(), info, UByteArray(), guidArea, UByteArray(), Fixed, index); + + return U_SUCCESS; + } + + // This is a normal entry + const auto entry_body = entry->body(); + + // Set default next to predefined last value + NVAR_ENTRY_PARSING_DATA pdata = {}; + pdata.emptyByte = emptyByte; + pdata.next = 0xFFFFFF; + pdata.isValid = TRUE; + + // Check for invalid entry + if (!entry->attributes()->valid()) { + subtype = Subtypes::InvalidNvarEntry; + name = UString("Invalid"); + pdata.isValid = FALSE; + goto processing_done; + } + + // Check for link entry + if (entry->next() != 0xFFFFFF) { + subtype = Subtypes::LinkNvarEntry; + pdata.next = (UINT32)entry->next(); + } + + // Check for data-only entry (nameless and GUIDless entry or link) + if (entry->attributes()->data_only()) { + // Search backwards for a previous entry with a link to this variable + UModelIndex prevEntryIndex; + if (currentEntryIndex > 0) { + for (UINT32 i = currentEntryIndex - 1; i > 0; i--) { + const auto & previousEntry = parsed.entries()->at(i); + + if (previousEntry == entry) + break; + + if ((UINT32)previousEntry->next() + (UINT32)previousEntry->offset() == (UINT32)entry->offset()) { // Previous link is present and valid + prevEntryIndex = index.model()->index(i, 0, index); + // Make sure that we are linking to a valid entry + NVAR_ENTRY_PARSING_DATA pd = readUnaligned((NVAR_ENTRY_PARSING_DATA*)model->parsingData(prevEntryIndex).constData()); + if (!pd.isValid) { + prevEntryIndex = UModelIndex(); + } + break; + } + } + } + // Check if the link is valid + if (prevEntryIndex.isValid()) { + // Use the name and text of the previous entry + name = model->name(prevEntryIndex); + text = model->text(prevEntryIndex); + + if (entry->next() == 0xFFFFFF) + subtype = Subtypes::DataNvarEntry; + } + else { + subtype = Subtypes::InvalidLinkNvarEntry; + name = UString("InvalidLink"); + pdata.isValid = FALSE; + } + goto processing_done; + } + + // Obtain text + if (!entry_body->_is_null_ascii_name()) { + text = entry_body->ascii_name().c_str(); + } + else if (!entry_body->_is_null_ucs2_name()) { + UByteArray temp; + for (const auto & ch : *entry_body->ucs2_name()->ucs2_chars()) { + temp += UByteArray((const char*)&ch, sizeof(ch)); + } + text = uFromUcs2(temp.constData()); + } + + // Obtain GUID + if (!entry_body->_is_null_guid()) { // GUID is stored in the entry itself + const EFI_GUID g = readUnaligned((EFI_GUID*)entry_body->guid().c_str()); + name = guidToUString(g); + guid = guidToUString(g, false); + } + else { // GUID is stored in GUID store at the end of the NVAR store + // Grow the GUID store if needed + if (guidsInStore < entry_body->guid_index() + 1) + guidsInStore = entry_body->guid_index() + 1; + + // The list begins at the end of the store and goes backwards + const EFI_GUID g = readUnaligned((EFI_GUID*)(nvar.constData() + nvar.size()) - (entry_body->guid_index() + 1)); + name = guidToUString(g); + guid = guidToUString(g, false); + } + +processing_done: + // This feels hacky, but I haven't found a way to ask Kaitai for raw bytes + header = nvar.mid(entry->offset(), sizeof(NVAR_ENTRY_HEADER) + entry_body->data_start_offset()); + body = nvar.mid(entry->offset() + sizeof(NVAR_ENTRY_HEADER) + entry_body->data_start_offset(), entry_body->data_size()); + tail = nvar.mid(entry->end_offset() - entry_body->extended_header_size(), entry_body->extended_header_size()); + + // Add GUID info for valid entries + if (!guid.isEmpty()) + info += UString("Variable GUID: ") + guid + "\n"; + + // Add GUID index information + if (!entry_body->_is_null_guid_index()) + info += usprintf("GUID index: %u\n", entry_body->guid_index()); + + // Add header, body and extended data info + info += usprintf("Full size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nTail size: %Xh (%u)", + entry->size(), entry->size(), + (UINT32)header.size(), (UINT32)header.size(), + (UINT32)body.size(), (UINT32)body.size(), + (UINT32)tail.size(), (UINT32)tail.size()); + + // Add attributes info + const NVAR_ENTRY_HEADER entryHeader = readUnaligned((NVAR_ENTRY_HEADER*)header.constData()); + info += usprintf("\nAttributes: %02Xh", entryHeader.Attributes); + + // Translate attributes to text + if (entryHeader.Attributes != 0x00 && entryHeader.Attributes != 0xFF) + info += UString(" (") + nvarAttributesToUString(entryHeader.Attributes) + UString(")"); + + // Add next node info + if (entry->next() != 0xFFFFFF) + info += usprintf("\nNext node at offset: %Xh", localOffset + entry->offset() + (UINT32)entry->next()); + + // Add extended header info + if (entry_body->extended_header_size() > 0) { + info += usprintf("\nExtended header size: %Xh (%u)", + entry_body->extended_header_size(), entry_body->extended_header_size()); + + const UINT8 extendedAttributes = *tail.constData(); + info += usprintf("\nExtended attributes: %02Xh (", extendedAttributes) + nvarExtendedAttributesToUString(extendedAttributes) + UString(")"); + + // Add checksum + if (!entry_body->_is_null_extended_header_checksum()) { + UINT8 calculatedChecksum = 0; + UByteArray wholeBody = body + tail; + + // Include entry body + UINT8* start = (UINT8*)wholeBody.constData(); + for (UINT8* p = start; p < start + wholeBody.size(); p++) { + calculatedChecksum += *p; + } + // Include entry size and flags + start = (UINT8*)&entryHeader.Size; + for (UINT8*p = start; p < start + sizeof(UINT16); p++) { + calculatedChecksum += *p; + } + // Include entry attributes + calculatedChecksum += entryHeader.Attributes; + info += usprintf("\nChecksum: %02Xh, ", entry_body->extended_header_checksum()) + + (calculatedChecksum ? usprintf(", invalid, should be %02Xh", 0x100 - calculatedChecksum) : UString(", valid")); + } + + // Add timestamp + if (!entry_body->_is_null_extended_header_timestamp()) + info += usprintf("\nTimestamp: %" PRIX64 "h", entry_body->extended_header_timestamp()); + + // Add hash + if (!entry_body->_is_null_extended_header_hash()) { + UByteArray hash = UByteArray(entry_body->extended_header_hash().c_str(), entry_body->extended_header_hash().size()); + info += UString("\nHash: ") + UString(hash.toHex().constData()); + } + } + + // Add tree item + UModelIndex varIndex = model->addItem(localOffset + entry->offset(), Types::NvarEntry, subtype, name, text, info, header, body, tail, Fixed, index); + currentEntryIndex++; + + // Set parsing data + model->setParsingData(varIndex, UByteArray((const char*)&pdata, sizeof(pdata))); + + // Try parsing the entry data as NVAR storage if it begins with NVAR signature + if ((subtype == Subtypes::DataNvarEntry || subtype == Subtypes::FullNvarEntry) + && body.size() >= 4 && readUnaligned((const UINT32*)body.constData()) == NVRAM_NVAR_ENTRY_SIGNATURE) + (void)parseNvarStore(varIndex); + } + } + catch (...) { + return U_INVALID_STORE; + } + + return U_SUCCESS; +} + +USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index,const UINT32 fdcStoreSizeOverride) +{ + // Sanity check + if (!index.isValid()) + return U_INVALID_PARAMETER; + + // Obtain required fields from parsing data + UINT8 emptyByte = 0xFF; + if (model->hasEmptyParsingData(index) == false) { + UByteArray data = model->parsingData(index); + const VOLUME_PARSING_DATA* pdata = (const VOLUME_PARSING_DATA*)data.constData(); + emptyByte = pdata->emptyByte; + } + + // Get local offset + const UINT32 localOffset = (UINT32)model->header(index).size(); + + // Get item data + UByteArray volumeBody = model->body(index); + const UINT32 volumeBodySize = (UINT32)volumeBody.size(); + + // Iterate over all bytes inside the volume body, trying to parse every next byte offset by one of the known parsers + UByteArray outerPadding; + UINT32 previousStoreEndOffset = 0; + for (UINT32 storeOffset = 0; + storeOffset < volumeBodySize; + storeOffset++) { + UString name, text, info; + UByteArray header, body; + + // VSS + try { + if (volumeBodySize - storeOffset < sizeof(VSS_VARIABLE_STORE_HEADER)) { + // No need to parse further, the rest of the volume is too small + goto not_vss; + } + + // Perform initial sanity check + const VSS_VARIABLE_STORE_HEADER* storeHeader = (const VSS_VARIABLE_STORE_HEADER*)(volumeBody.constData() + storeOffset); + if ((storeHeader->Signature != NVRAM_VSS_STORE_SIGNATURE + && storeHeader->Signature != NVRAM_APPLE_SVS_STORE_SIGNATURE + && storeHeader->Signature != NVRAM_APPLE_NSS_STORE_SIGNATURE) + || storeHeader->Format != NVRAM_VSS_VARIABLE_STORE_FORMATTED) { + // No need to parse further, not a VSS store + goto not_vss; + } + UINT32 storeSize = MIN(volumeBodySize - storeOffset, storeHeader->Size); //TODO: consider this check to become hard bail as it was before + + // This copy is required for possible FDC workaround + UByteArray vss = volumeBody.mid(storeOffset, storeSize); + + // Check if we are here to parse a special case of FDC store with size override + UINT32 originalStoreSize = 0; + bool fdcHeaderSizeOverrideRequired = (fdcStoreSizeOverride > 0 && storeHeader->Signature == NVRAM_VSS_STORE_SIGNATURE && storeHeader->Size == 0xFFFFFFFF); + if (fdcHeaderSizeOverrideRequired) { + VSS_VARIABLE_STORE_HEADER* vssHeader = (VSS_VARIABLE_STORE_HEADER*)vss.data(); + originalStoreSize = vssHeader->Size; + vssHeader->Size = fdcStoreSizeOverride; + } + + // Try parsing VSS store candidate + umemstream is(vss.constData(), vss.size()); + kaitai::kstream ks(&is); + edk2_vss_t parsed(&ks); + + // Restore original store size, if needed + if (fdcHeaderSizeOverrideRequired) { + VSS_VARIABLE_STORE_HEADER* vssHeader = (VSS_VARIABLE_STORE_HEADER*)vss.data(); + vssHeader->Size = originalStoreSize; + } + + // VSS store at current offset parsed correctly + // Check if we need to add a padding before it + if (!outerPadding.isEmpty()) { + UString info = usprintf("Full size: %Xh (%u)", (UINT32)outerPadding.size(), (UINT32)outerPadding.size()); + model->addItem(localOffset + previousStoreEndOffset, Types::Padding, getPaddingType(outerPadding), UString("Padding"), UString(), info, UByteArray(), outerPadding, UByteArray(), Fixed, index); + outerPadding.clear(); + } + + // Construct header and body + header = vss.left(parsed.len_vss_store_header()); + body = vss.mid(header.size(), storeSize - header.size()); + + // Add info + if (parsed.signature() == NVRAM_APPLE_SVS_STORE_SIGNATURE) { + name = UString("Apple SVS store"); + } + else if (parsed.signature() == NVRAM_APPLE_NSS_STORE_SIGNATURE) { + name = UString("Apple NSS store"); + } + else { + name = UString("VSS store"); + } + + info = usprintf("Signature: %Xh (", parsed.signature()) + fourCC(parsed.signature()) + UString(")\n"); + info += usprintf("Full size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nFormat: %02Xh\nState: %02Xh\nReserved: %02Xh\nReserved1: %04Xh", + storeSize , storeSize, + (UINT32)header.size(), (UINT32)header.size(), + (UINT32)body.size(), (UINT32)body.size(), + parsed.format(), + parsed.state(), + parsed.reserved(), + parsed.reserved1()); + + // Add header tree item + UModelIndex headerIndex = model->addItem(localOffset + storeOffset, Types::VssStore, 0, name, UString(), info, header, body, UByteArray(), Fixed, index); + + // Add variables + UINT32 entryOffset = parsed.len_vss_store_header(); + for (const auto & variable : *parsed.body()->variables()) { + UINT8 subtype; + + // This is the terminating entry, needs special processing + if (variable->_is_null_signature_last()) { + // Add free space or padding after all variables, if needed + if (entryOffset < storeSize) { + UByteArray freeSpace = vss.mid(entryOffset, storeSize - entryOffset); + // Add info + info = usprintf("Full size: %Xh (%u)", (UINT32)freeSpace.size(), (UINT32)freeSpace.size()); + + // Check that remaining unparsed bytes are actually empty + if (freeSpace.count(emptyByte) == freeSpace.size()) { // Free space + // Add tree item + model->addItem(entryOffset, Types::FreeSpace, 0, UString("Free space"), UString(), info, UByteArray(), freeSpace, UByteArray(), Fixed, headerIndex); + } + else { + // Add tree item + model->addItem(entryOffset, Types::Padding, getPaddingType(freeSpace), UString("Padding"), UString(), info, UByteArray(), freeSpace, UByteArray(), Fixed, headerIndex); + } + } + break; + } + + // This is a normal entry + UINT32 variableSize; + if (variable->is_intel_legacy()) { // Intel legacy + subtype = Subtypes::IntelVssEntry; + // Needs some additional parsing of variable->intel_legacy_data to separate the name from the value + text = uFromUcs2(variable->intel_legacy_data().c_str()); + UINT32 textLengthInBytes = (UINT32)text.length()*2+2; + header = vss.mid(entryOffset, variable->len_intel_legacy_header() + textLengthInBytes); + body = vss.mid(entryOffset + header.size(), variable->len_total() - variable->len_intel_legacy_header() - textLengthInBytes); + variableSize = (UINT32)(header.size() + body.size()); + const EFI_GUID variableGuid = readUnaligned((const EFI_GUID*)(variable->vendor_guid().c_str())); + name = guidToUString(variableGuid); + info = UString("Variable GUID: ") + guidToUString(variableGuid, false) + "\n"; + } + else if (variable->is_auth()) { // Authenticated + subtype = Subtypes::AuthVssEntry; + header = vss.mid(entryOffset, variable->len_auth_header() + variable->len_name_auth()); + body = vss.mid(entryOffset + header.size(), variable->len_data_auth()); + variableSize = (UINT32)(header.size() + body.size()); + const EFI_GUID variableGuid = readUnaligned((const EFI_GUID*)(variable->vendor_guid().c_str())); + name = guidToUString(variableGuid); + text = uFromUcs2(variable->name_auth().c_str()); + info = UString("Variable GUID: ") + guidToUString(variableGuid, false) + "\n"; + } + else if (!variable->_is_null_apple_data_crc32()) { // Apple CRC32 + subtype = Subtypes::AppleVssEntry; + header = vss.mid(entryOffset, variable->len_apple_header() + variable->len_name()); + body = vss.mid(entryOffset + header.size(), variable->len_data()); + variableSize = (UINT32)(header.size() + body.size()); + const EFI_GUID variableGuid = readUnaligned((const EFI_GUID*)(variable->vendor_guid().c_str())); + name = guidToUString(variableGuid); + text = uFromUcs2(variable->name().c_str()); + info = UString("Variable GUID: ") + guidToUString(variableGuid, false) + "\n"; + } + else { // Standard + subtype = Subtypes::StandardVssEntry; + header = vss.mid(entryOffset, variable->len_standard_header() + variable->len_name()); + body = vss.mid(entryOffset + header.size(), variable->len_data()); + variableSize = (UINT32)(header.size() + body.size()); + const EFI_GUID variableGuid = readUnaligned((const EFI_GUID*)(variable->vendor_guid().c_str())); + name = guidToUString(variableGuid); + text = uFromUcs2(variable->name().c_str()); + info = UString("Variable GUID: ") + guidToUString(variableGuid, false) + "\n"; + } + + // Override variable type to Invalid, if needed + if (!variable->is_valid()) { + subtype = Subtypes::InvalidVssEntry; + name = UString("Invalid"); + text.clear(); + } + + const UINT32 variableAttributes = variable->attributes()->non_volatile() + + (variable->attributes()->boot_service() << 1) + + (variable->attributes()->runtime() << 2) + + (variable->attributes()->hw_error_record() << 3) + + (variable->attributes()->auth_write() << 4) + + (variable->attributes()->time_based_auth() << 5) + + (variable->attributes()->append_write() << 6) + + (UINT32)(variable->attributes()->reserved() << 7) + + (UINT32)(variable->attributes()->apple_data_checksum() << 31); + + // Add generic info + info += usprintf("Full size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nState: %02Xh\nReserved: %02Xh\nAttributes: %08Xh (", + variableSize, variableSize, + (UINT32)header.size(), (UINT32)header.size(), + (UINT32)body.size(), (UINT32)body.size(), + variable->state(), + variable->reserved(), + variableAttributes) + vssAttributesToUString(variableAttributes) + UString(")"); + + // Add specific info + if (variable->is_auth()) { + UINT64 monotonicCounter = (UINT64)variable->len_name() + ((UINT64)variable->len_data() << 32); + info += usprintf("\nMonotonic counter: %" PRIX64 "h\nTimestamp: ", monotonicCounter) + efiTimeToUString(*(const EFI_TIME*)variable->timestamp().c_str()) + + usprintf("\nPubKey index: %u", variable->pubkey_index()); + } + else if (!variable->_is_null_apple_data_crc32()) { + // Calculate CRC32 of the variable data + UINT32 calculatedCrc32 = (UINT32)crc32(0, (const UINT8*)body.constData(), (uInt)body.size()); + + info += usprintf("\nData checksum: %08Xh", variable->apple_data_crc32()) + + (variable->apple_data_crc32() != calculatedCrc32 ? usprintf(", invalid, should be %08Xh", calculatedCrc32) : UString(", valid")); + } + + // Add tree item + model->addItem(entryOffset, Types::VssEntry, subtype, name, text, info, header, body, UByteArray(), Fixed, headerIndex); + + entryOffset += variableSize; + } + + storeOffset += storeSize - 1; + previousStoreEndOffset = storeOffset + 1; + continue; + } catch (...) { + // Parsing failed, try something else + } +not_vss: + // VSS2 + try { + if (volumeBodySize - storeOffset < sizeof(VSS2_VARIABLE_STORE_HEADER)) { + // No need to parse further, the rest of the volume is too small + goto not_vss2; + } + + // Perform initial sanity check + const VSS2_VARIABLE_STORE_HEADER* storeHeader = (const VSS2_VARIABLE_STORE_HEADER*)(volumeBody.constData() + storeOffset); + UByteArray guid = UByteArray((const char*)&storeHeader->Signature, sizeof(EFI_GUID)); + + if ((guid != NVRAM_VSS2_AUTH_VAR_KEY_DATABASE_GUID + && guid != NVRAM_VSS2_STORE_GUID + && guid != NVRAM_FDC_STORE_GUID) + || storeHeader->Format != NVRAM_VSS_VARIABLE_STORE_FORMATTED) { + // No need to parse further, not a VSS2 store + goto not_vss2; + } + UINT32 storeSize = MIN(volumeBodySize - storeOffset, storeHeader->Size); + + // This copy is required for possible FDC workaround + UByteArray vss2 = volumeBody.mid(storeOffset, storeSize); + + // Check if we are here to parse a special case of FDC store with size override + UINT32 originalStoreSize = 0; + bool fdcHeaderSizeOverrideRequired = (fdcStoreSizeOverride > 0 && guid == NVRAM_FDC_STORE_GUID && storeHeader->Size == 0xFFFFFFFF); + if (fdcHeaderSizeOverrideRequired) { + VSS2_VARIABLE_STORE_HEADER* vss2Header = (VSS2_VARIABLE_STORE_HEADER*)vss2.data(); + originalStoreSize = vss2Header->Size; + vss2Header->Size = fdcStoreSizeOverride; + } + + // Try parsing VSS store candidate + umemstream is(vss2.constData(), vss2.size()); + kaitai::kstream ks(&is); + edk2_vss2_t parsed(&ks); + + // Restore original store size, if needed + if (fdcHeaderSizeOverrideRequired) { + VSS2_VARIABLE_STORE_HEADER* vss2Header = (VSS2_VARIABLE_STORE_HEADER*)vss2.data(); + vss2Header->Size = originalStoreSize; + } + + // VSS2 store at current offset parsed correctly + // Check if we need to add a padding before it + if (!outerPadding.isEmpty()) { + info = usprintf("Full size: %Xh (%u)", (UINT32)outerPadding.size(), (UINT32)outerPadding.size()); + model->addItem(localOffset + previousStoreEndOffset, Types::Padding, getPaddingType(outerPadding), UString("Padding"), UString(), info, UByteArray(), outerPadding, UByteArray(), Fixed, index); + outerPadding.clear(); + } + + // Construct header and body + header = vss2.left(parsed.len_vss2_store_header()); + body = vss2.mid(header.size(), storeSize - header.size()); + + // Add info + name = UString("VSS2 store"); + if (guid == NVRAM_VSS2_AUTH_VAR_KEY_DATABASE_GUID) { + info = UString("Signature: AAF32C78-947B-439A-A180-2E144EC37792\n"); + } + else if (guid == NVRAM_FDC_STORE_GUID) { + info = UString("Signature: DDCF3616-3275-4164-98B6-FE85707FFE7D\n"); + } + else { + info = UString("Signature: DDCF3617-3275-4164-98B6-FE85707FFE7D\n"); + } + + info += usprintf("Full size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nFormat: %02Xh\nState: %02Xh\nReserved: %02Xh\nReserved1: %04Xh", + storeSize, storeSize, + (UINT32)header.size(), (UINT32)header.size(), + (UINT32)body.size(), (UINT32)body.size(), + parsed.format(), + parsed.state(), + parsed.reserved(), + parsed.reserved1()); + + // Add header tree item + UModelIndex headerIndex = model->addItem(localOffset + storeOffset, Types::Vss2Store, 0, name, UString(), info, header, body, UByteArray(), Fixed, index); + + // Add variables + UINT32 entryOffset = parsed.len_vss2_store_header(); + for (const auto & variable : *parsed.body()->variables()) { + UINT8 subtype; + + // This is the terminating entry, needs special processing + if (variable->_is_null_signature_last()) { + // Add free space or padding after all variables, if needed + if (entryOffset < storeSize) { + UByteArray freeSpace = vss2.mid(entryOffset, storeSize - entryOffset); + // Add info + info = usprintf("Full size: %Xh (%u)", (UINT32)freeSpace.size(), (UINT32)freeSpace.size()); + + // Check that remaining unparsed bytes are actually empty + if (freeSpace.count(emptyByte) == freeSpace.size()) { // Free space + // Add tree item + model->addItem(entryOffset, Types::FreeSpace, 0, UString("Free space"), UString(), info, UByteArray(), freeSpace, UByteArray(), Fixed, headerIndex); + } + else { + // Add tree item + model->addItem(entryOffset, Types::Padding, getPaddingType(freeSpace), UString("Padding"), UString(), info, UByteArray(), freeSpace, UByteArray(), Fixed, headerIndex); + } + } + break; + } + + // This is a normal entry + UINT32 variableSize; + UINT32 alignmentSize; + if (variable->is_auth()) { // Authenticated + subtype = Subtypes::AuthVssEntry; + header = vss2.mid(entryOffset, variable->len_auth_header() + variable->len_name_auth()); + body = vss2.mid(entryOffset + header.size(), variable->len_data_auth()); + variableSize = (UINT32)(header.size() + body.size()); + alignmentSize = variable->len_alignment_padding_auth(); + const EFI_GUID variableGuid = readUnaligned((const EFI_GUID*)(variable->vendor_guid().c_str())); + name = guidToUString(variableGuid); + text = uFromUcs2(variable->name_auth().c_str()); + info = UString("Variable GUID: ") + guidToUString(variableGuid, false) + "\n"; + } + else { // Standard + subtype = Subtypes::StandardVssEntry; + header = vss2.mid(entryOffset, variable->len_standard_header() + variable->len_name()); + body = vss2.mid(entryOffset + header.size(), variable->len_data()); + variableSize = (UINT32)(header.size() + body.size()); + alignmentSize = variable->len_alignment_padding(); + const EFI_GUID variableGuid = readUnaligned((const EFI_GUID*)(variable->vendor_guid().c_str())); + name = guidToUString(variableGuid); + text = uFromUcs2(variable->name().c_str()); + info = UString("Variable GUID: ") + guidToUString(variableGuid, false) + "\n"; + } + + // Override variable type to Invalid if needed + if (!variable->is_valid()) { + subtype = Subtypes::InvalidVssEntry; + name = UString("Invalid"); + text.clear(); + } + + const UINT32 variableAttributes = variable->attributes()->non_volatile() + + (variable->attributes()->boot_service() << 1) + + (variable->attributes()->runtime() << 2) + + (variable->attributes()->hw_error_record() << 3) + + (variable->attributes()->auth_write() << 4) + + (variable->attributes()->time_based_auth() << 5) + + (variable->attributes()->append_write() << 6) + + (UINT32)(variable->attributes()->reserved() << 7); + + // Add generic info + info += usprintf("Full size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nState: %02Xh\nReserved: %02Xh\nAttributes: %08Xh (", + variableSize, variableSize, + (UINT32)header.size(), (UINT32)header.size(), + (UINT32)body.size(), (UINT32)body.size(), + variable->state(), + variable->reserved(), + variableAttributes) + vssAttributesToUString(variableAttributes) + UString(")"); + + // Add specific info + if (variable->is_auth()) { + UINT64 monotonicCounter = (UINT64)variable->len_name() + ((UINT64)variable->len_data() << 32); + info += usprintf("\nMonotonic counter: %" PRIX64 "h\nTimestamp: ", monotonicCounter) + efiTimeToUString(*(const EFI_TIME*)variable->timestamp().c_str()) + + usprintf("\nPubKey index: %u", variable->pubkey_index()); + } + + // Add tree item + model->addItem(entryOffset, Types::VssEntry, subtype, name, text, info, header, body, UByteArray(), Fixed, headerIndex); + + entryOffset += (variableSize + alignmentSize); + } + + storeOffset += storeSize - 1; + previousStoreEndOffset = storeOffset + 1; + continue; + } catch (...) { + // Parsing failed, try something else + } +not_vss2: + // Do not try any other parsers if we are here for FDC store parsing + if (fdcStoreSizeOverride != 0) { + continue; + } + + // FTW + try { + if (volumeBodySize - storeOffset < sizeof(EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER32)) { + // No need to parse further, the rest of the volume is too small + goto not_ftw; + } + // Perform initial sanity check + const EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER32* storeHeader = (const EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER32*)(volumeBody.constData() + storeOffset); + UByteArray guid = UByteArray((const char*)&storeHeader->Signature, sizeof(EFI_GUID)); + if (guid != NVRAM_MAIN_STORE_VOLUME_GUID + && guid != EDKII_WORKING_BLOCK_SIGNATURE_GUID + && guid != VSS2_WORKING_BLOCK_SIGNATURE_GUID) { + // No need to parse further, not a FTW store + goto not_ftw; + } + // Determine store size + UINT32 storeSize; + if (storeHeader->WriteQueueSize % 0x10 == 4) { + storeSize = sizeof(EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER32) + storeHeader->WriteQueueSize; + } + else if (storeHeader->WriteQueueSize % 0x10 == 0) { + const EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER64* storeHeader64 = (const EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER64*)(volumeBody.constData() + storeOffset); + storeSize = (UINT32)(sizeof(EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER64) + storeHeader64->WriteQueueSize); + } + else { + // No need to parse further, unknown FTW store size + msg(usprintf("%s: can not determine FTW store size for candidate at base %08Xh", __FUNCTION__, model->base(index) + localOffset + storeOffset), index); + goto not_ftw; + } + storeSize = MIN(volumeBodySize - storeOffset, storeSize); + + umemstream is(volumeBody.constData() + storeOffset, storeSize); + kaitai::kstream ks(&is); + edk2_ftw_t parsed(&ks); + + // Construct header and calculate header checksum + UINT32 headerSize; + UINT32 calculatedCrc; + if (parsed._is_null_len_write_queue_64()) { + headerSize = sizeof(EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER32); + header = volumeBody.mid(storeOffset, headerSize); + + // Check block header checksum + UByteArray crcHeader = header; + EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER32* crcFtwBlockHeader = (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER32*)crcHeader.data(); + crcFtwBlockHeader->Crc = emptyByte ? 0xFFFFFFFF : 0; + crcFtwBlockHeader->State = emptyByte ? 0xFF : 0; + calculatedCrc = (UINT32)crc32(0, (const UINT8*)crcFtwBlockHeader, (UINT32)headerSize); + } + else { + headerSize = sizeof(EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER64); + header = volumeBody.mid(storeOffset, headerSize); + + // Check block header checksum + UByteArray crcHeader = header; + EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER64* crcFtwBlockHeader = (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER64*)crcHeader.data(); + crcFtwBlockHeader->Crc = emptyByte ? 0xFFFFFFFF : 0; + crcFtwBlockHeader->State = emptyByte ? 0xFF : 0; + calculatedCrc = (UINT32)crc32(0, (const UINT8*)crcFtwBlockHeader, (UINT32)headerSize); + } + + // FTW store at current offset parsed correctly + // Check if we need to add a padding before it + if (!outerPadding.isEmpty()) { + UString info = usprintf("Full size: %Xh (%u)", (UINT32)outerPadding.size(), (UINT32)outerPadding.size()); + model->addItem(localOffset + previousStoreEndOffset, Types::Padding, getPaddingType(outerPadding), UString("Padding"), UString(), info, UByteArray(), outerPadding, UByteArray(), Fixed, index); + outerPadding.clear(); + } + + // Construct body + body = volumeBody.mid(storeOffset + header.size(), storeSize - header.size()); + + // Add info + name = UString("FTW store"); + info = UString("Signature: ") + guidToUString(*(const EFI_GUID*)guid.constData(), false); + info += usprintf("\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nState: %02Xh\nHeader CRC32: %08Xh", + (UINT32)storeSize, (UINT32)storeSize, + (UINT32)header.size(), (UINT32)header.size(), + (UINT32)body.size(), (UINT32)body.size(), + parsed.state(), + parsed.crc()) + (parsed.crc() != calculatedCrc ? usprintf(", invalid, should be %08Xh", calculatedCrc) : UString(", valid")); + + // Add header tree item + model->addItem(localOffset + storeOffset, Types::FtwStore, 0, name, UString(), info, header, body, UByteArray(), Fixed, index); + + storeOffset += storeSize - 1; + previousStoreEndOffset = storeOffset + 1; + continue; + } catch (...) { + // Parsing failed, try something else + } +not_ftw: + // Insyde FDC + try { + if (volumeBodySize - storeOffset < sizeof(INSYDE_FDC_STORE_HEADER)) { + // No need to parse further, the rest of the volume is too small + goto not_fdc; + } + // Perform initial sanity check + const INSYDE_FDC_STORE_HEADER* storeHeader = (const INSYDE_FDC_STORE_HEADER*)(volumeBody.constData() + storeOffset); + if (storeHeader->Signature != INSYDE_FDC_STORE_SIGNATURE) { + // No need to parse further, not a FDC store + goto not_fdc; + } + UINT32 storeSize = MIN(volumeBodySize - storeOffset, storeHeader->Size); + + umemstream is(volumeBody.constData() + storeOffset, storeSize); + kaitai::kstream ks(&is); + insyde_fdc_t parsed(&ks); + + // Insyde FDC store at current offset parsed correctly + // Check if we need to add a padding before it + if (!outerPadding.isEmpty()) { + UString info = usprintf("Full size: %Xh (%u)", (UINT32)outerPadding.size(), (UINT32)outerPadding.size()); + model->addItem(localOffset + previousStoreEndOffset, Types::Padding, getPaddingType(outerPadding), UString("Padding"), UString(), info, UByteArray(), outerPadding, UByteArray(), Fixed, index); + outerPadding.clear(); + } + + // Construct header and body + header = volumeBody.mid(storeOffset, sizeof(INSYDE_FDC_STORE_HEADER)); + body = volumeBody.mid(storeOffset + header.size(), storeSize - header.size()); + + // Add info + name = UString("Insyde FDC store"); + info = usprintf("Signature: _FDC\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)", + storeSize, storeSize, + (UINT32)header.size(), (UINT32)header.size(), + (UINT32)body.size(), (UINT32)body.size()); + + // Add header tree item + UModelIndex headerIndex = model->addItem(localOffset + storeOffset, Types::FdcStore, 0, name, UString(), info, header, body, UByteArray(), Fixed, index); + + // Parse FDC body as normal VSS/VSS2 storage with size override + parseNvramVolumeBody(headerIndex, (UINT32)body.size()); + + storeOffset += storeSize - 1; + previousStoreEndOffset = storeOffset + 1; + continue; + } catch (...) { + // Parsing failed, try something else + } +not_fdc: + // Apple SysF + try { + if (volumeBodySize - storeOffset < sizeof(APPLE_SYSF_STORE_HEADER)) { + // No need to parse further, the rest of the volume is too small + goto not_sysf; + } + // Perform initial sanity check + const APPLE_SYSF_STORE_HEADER* storeHeader = (const APPLE_SYSF_STORE_HEADER*)(volumeBody.constData() + storeOffset); + if (storeHeader->Signature != NVRAM_APPLE_SYSF_STORE_SIGNATURE + && storeHeader->Signature != NVRAM_APPLE_DIAG_STORE_SIGNATURE) { + // No need to parse further, not a SysF/Diag store + goto not_sysf; + } + UINT32 storeSize = MIN(volumeBodySize - storeOffset, storeHeader->Size); + + umemstream is(volumeBody.constData() + storeOffset, storeSize); + kaitai::kstream ks(&is); + apple_sysf_t parsed(&ks); + + // Apple SysF/Diag store at current offset parsed correctly + // Check if we need to add a padding before it + if (!outerPadding.isEmpty()) { + info = usprintf("Full size: %Xh (%u)", (UINT32)outerPadding.size(), (UINT32)outerPadding.size()); + model->addItem(localOffset + previousStoreEndOffset, Types::Padding, getPaddingType(outerPadding), UString("Padding"), UString(), info, UByteArray(), outerPadding, UByteArray(), Fixed, index); + outerPadding.clear(); + } + + // Construct header and body + header = volumeBody.mid(storeOffset, sizeof(APPLE_SYSF_STORE_HEADER)); + body = volumeBody.mid(storeOffset + header.size(), storeSize - header.size()); + + // Check store checksum + UINT32 calculatedCrc = (UINT32)crc32(0, (const UINT8*)(volumeBody.constData() + storeOffset), storeSize - sizeof(UINT32)); + + // Add info + if (storeHeader->Signature == NVRAM_APPLE_SYSF_STORE_SIGNATURE) { + name = UString("Apple SysF store"); + info = UString("Signature: Fsys\n"); + } + else { + name = UString("Apple Diag store"); + info = UString("Signature: Gaid\n"); + } + info += usprintf("Full size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nUnknown: %02Xh\nUnknown1: %08Xh\nCRC32: %08Xh", + storeSize, storeSize, + (UINT32)header.size(), (UINT32)header.size(), + (UINT32)body.size(), (UINT32)body.size(), + parsed.unknown(), + parsed.unknown1(), + parsed.crc()) + (parsed.crc() != calculatedCrc ? usprintf(", invalid, should be %08Xh", calculatedCrc) : UString(", valid")); + + // Add header tree item + UModelIndex headerIndex = model->addItem(localOffset + storeOffset, Types::SysFStore, 0, name, UString(), info, header, body, UByteArray(), Fixed, index); + + // Add variables + UINT32 entryOffset = sizeof(APPLE_SYSF_STORE_HEADER); + for (const auto & variable : *parsed.body()->variables()) { + UINT8 subtype; + + if (variable->invalid_flag()) { + subtype = Subtypes::InvalidSysFEntry; + name = UString("Invalid"); + } + else { + subtype = Subtypes::NormalSysFEntry; + name = usprintf("%s", variable->name().c_str()); + } + + if (variable->len_name() == 3 && variable->name() == "EOF") { + header = volumeBody.mid(storeOffset + entryOffset, 4); + body.clear(); + } + else { + header = volumeBody.mid(storeOffset + entryOffset, sizeof(UINT8) + (UINT32)variable->len_name() + sizeof(UINT16)); + body = volumeBody.mid(storeOffset + entryOffset + header.size(), (UINT32)variable->len_data()); + } + // Add generic info + UINT32 variableSize = (UINT32)header.size() + (UINT32)body.size(); + info = usprintf("Full size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\n", + variableSize, variableSize, + (UINT32)header.size(), (UINT32)header.size(), + (UINT32)body.size(), (UINT32)body.size()); + + // Add tree item + model->addItem(entryOffset, Types::SysFEntry, subtype, name, UString(), info, header, body, UByteArray(), Fixed, headerIndex); + + entryOffset += variableSize; + } + + // Add free space or padding after all variables, if needed + if (entryOffset < storeSize) { + UByteArray freeSpace = volumeBody.mid(storeOffset + entryOffset, storeSize - entryOffset); + // Add info + info = usprintf("Full size: %Xh (%u)", (UINT32)freeSpace.size(), (UINT32)freeSpace.size()); + + // Check that remaining unparsed bytes are actually zeroes + if (freeSpace.count('\x00') == freeSpace.size() - 4) { // Free space, 4 last bytes are always CRC32 + // Add tree item + model->addItem(entryOffset, Types::FreeSpace, 0, UString("Free space"), UString(), info, UByteArray(), freeSpace, UByteArray(), Fixed, headerIndex); + } + else { + // Add tree item + model->addItem(entryOffset, Types::Padding, getPaddingType(freeSpace), UString("Padding"), UString(), info, UByteArray(), freeSpace, UByteArray(), Fixed, headerIndex); + } + } + + storeOffset += storeSize - 1; + previousStoreEndOffset = storeOffset + 1; + continue; + } catch (...) { + // Parsing failed, try something else + } +not_sysf: + // Phoenix Flash Map + try { + if (volumeBodySize - storeOffset < sizeof(PHOENIX_FLASH_MAP_HEADER)) { + // No need to parse further, the rest of the volume is too small + goto not_flm; + } + // Perform initial sanity check + const PHOENIX_FLASH_MAP_HEADER* storeHeader = (const PHOENIX_FLASH_MAP_HEADER*)(volumeBody.constData() + storeOffset); + if (UByteArray((const char*)storeHeader->Signature, NVRAM_PHOENIX_FLASH_MAP_SIGNATURE_LENGTH) != NVRAM_PHOENIX_FLASH_MAP_SIGNATURE + || storeHeader->NumEntries > NVRAM_PHOENIX_FLASH_MAP_MAX_ENTRIES) { + // No need to parse further, not a Phoenix Flash Map + goto not_flm; + } + UINT32 storeSize = sizeof(PHOENIX_FLASH_MAP_HEADER) + storeHeader->NumEntries * sizeof(PHOENIX_FLASH_MAP_ENTRY); + + umemstream is(volumeBody.constData() + storeOffset, storeSize); + kaitai::kstream ks(&is); + phoenix_flm_t parsed(&ks); + + // Phoenix FlashMap store at current offset parsed correctly + // Check if we need to add a padding before it + if (!outerPadding.isEmpty()) { + info = usprintf("Full size: %Xh (%u)", (UINT32)outerPadding.size(), (UINT32)outerPadding.size()); + model->addItem(localOffset + previousStoreEndOffset, Types::Padding, getPaddingType(outerPadding), UString("Padding"), UString(), info, UByteArray(), outerPadding, UByteArray(), Fixed, index); + outerPadding.clear(); + } + + // Construct header and body + header = volumeBody.left(storeOffset + sizeof(PHOENIX_FLASH_MAP_HEADER)); + body = volumeBody.mid(storeOffset + header.size(), storeSize - header.size()); + + // Add info + name = UString("Phoenix SCT flash map"); + info = usprintf("Signature: _FLASH_MAP\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nEntries: %u\nReserved: %08Xh", + storeSize, storeSize, + (UINT32)header.size(), (UINT32)header.size(), + (UINT32)body.size(), (UINT32)body.size(), + parsed.num_entries(), + parsed.reserved()); + + // Add header tree item + UModelIndex headerIndex = model->addItem(localOffset + storeOffset, Types::PhoenixFlashMapStore, 0, name, UString(), info, header, body, UByteArray(), Fixed, index); + + // Add entries + UINT32 entryOffset = sizeof(PHOENIX_FLASH_MAP_HEADER); + for (const auto & entry : *parsed.entries()) { + UINT8 subtype; + + if (entry->data_type() == NVRAM_PHOENIX_FLASH_MAP_ENTRY_DATA_TYPE_VOLUME) { + subtype = Subtypes::VolumeFlashMapEntry; + } + else if (entry->data_type() == NVRAM_PHOENIX_FLASH_MAP_ENTRY_DATA_TYPE_DATA_BLOCK) { + subtype = Subtypes::DataFlashMapEntry; + } + else { + subtype = Subtypes::UnknownFlashMapEntry; + } + + const EFI_GUID guid = readUnaligned((const EFI_GUID*)entry->guid().c_str()); + name = guidToUString(guid); + text = phoenixFlashMapGuidToUString(guid); + header = volumeBody.mid(storeOffset + entryOffset, sizeof(PHOENIX_FLASH_MAP_ENTRY)); + + // Add info + UINT32 entrySize = (UINT32)header.size(); + info = usprintf("Full size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: 0h (0)\nData type: %04Xh\nEntry type: %04Xh\nSize: %08Xh\nOffset: %08Xh\nPhysical address: %" PRIX64 "h", + entrySize, entrySize, + (UINT32)header.size(), (UINT32)header.size(), + entry->data_type(), + entry->entry_type(), + entry->size(), + entry->offset(), + entry->physical_address()); + + // Add tree item + model->addItem(entryOffset, Types::PhoenixFlashMapEntry, subtype, name, text, info, header, UByteArray(), UByteArray(), Fixed, headerIndex); + + entryOffset += entrySize; + } + + storeOffset += storeSize - 1; + previousStoreEndOffset = storeOffset + 1; + continue; + } catch (...) { + // Parsing failed, try something else + } +not_flm: + // Phoenix EVSA store + try { + if (volumeBodySize - storeOffset < sizeof(EVSA_STORE_ENTRY)) { + // No need to parse further, the rest of the volume is too small + goto not_evsa; + } + // Perform initial sanity check + const EVSA_STORE_ENTRY* storeHeader = (const EVSA_STORE_ENTRY*)(volumeBody.constData() + storeOffset); + if (storeHeader->Signature != NVRAM_EVSA_STORE_SIGNATURE + || storeHeader->Header.Type != NVRAM_EVSA_ENTRY_TYPE_STORE + || storeHeader->Header.Size != sizeof(EVSA_STORE_ENTRY)) { + // No need to parse further, not a EVSA store + goto not_evsa; + } + UINT32 storeSize = MIN(volumeBodySize - storeOffset, storeHeader->StoreSize); + + umemstream is(volumeBody.constData() + storeOffset, storeSize); + kaitai::kstream ks(&is); + phoenix_evsa_t parsed(&ks); + + // Phoenix EVSA store at current offset parsed correctly + // Check if we need to add a padding before it + if (!outerPadding.isEmpty()) { + info = usprintf("Full size: %Xh (%u)", (UINT32)outerPadding.size(), (UINT32)outerPadding.size()); + model->addItem(localOffset + previousStoreEndOffset, Types::Padding, getPaddingType(outerPadding), UString("Padding"), UString(), info, UByteArray(), outerPadding, UByteArray(), Fixed, index); + outerPadding.clear(); + } + + // Construct header and body + header = volumeBody.mid(storeOffset, sizeof(EVSA_STORE_ENTRY)); + body = volumeBody.mid(storeOffset + header.size(), storeSize - header.size()); + + // Calculate header checksum + UINT8 calculated = calculateChecksum8(((const UINT8*)storeHeader) + 2, storeHeader->Header.Size - 2); + + // Add info + name = UString("Phoenix EVSA store"); + info = usprintf("Signature: EVSA\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nAttributes: %08Xh\nReserved: %08Xh\nChecksum: %02Xh", + storeSize, storeSize, + (UINT32)header.size(), (UINT32)header.size(), + (UINT32)body.size(), (UINT32)body.size(), + parsed.attributes(), + parsed.reserved(), + parsed.checksum()) + + (parsed.checksum() != calculated ? usprintf(", invalid, should be %02Xh", calculated) : UString(", valid")); + + // Add header tree item + UModelIndex headerIndex = model->addItem(localOffset + storeOffset, Types::EvsaStore, 0, name, UString(), info, header, body, UByteArray(), Fixed, index); + + // Add entries + std::map guidMap; + std::map nameMap; + UINT32 entryOffset = parsed.len_evsa_store_header(); + for (const auto & entry : *parsed.body()->entries()) { + UINT8 subtype; + UINT32 entrySize; + + // This is the terminating entry, needs special processing + if (entry->_is_null_checksum()) { + // Add free space or padding after all variables, if needed + if (entryOffset < storeSize) { + UByteArray freeSpace = volumeBody.mid(storeOffset + entryOffset, storeSize - entryOffset); + // Add info + info = usprintf("Full size: %Xh (%u)", (UINT32)freeSpace.size(), (UINT32)freeSpace.size()); + + // Check that remaining unparsed bytes are actually empty + if (freeSpace.count(emptyByte) == freeSpace.size()) { // Free space + // Add tree item + model->addItem(entryOffset, Types::FreeSpace, 0, UString("Free space"), UString(), info, UByteArray(), freeSpace, UByteArray(), Fixed, headerIndex); + } + else { + // Add tree item + model->addItem(entryOffset, Types::Padding, getPaddingType(freeSpace), UString("Padding"), UString(), info, UByteArray(), freeSpace, UByteArray(), Fixed, headerIndex); + } + } + break; + } + + const EVSA_ENTRY_HEADER* entryHeader = (const EVSA_ENTRY_HEADER*)(volumeBody.constData() + storeOffset + entryOffset); + calculated = calculateChecksum8(((const UINT8*)entryHeader) + 2, entryHeader->Size - 2); + + // GUID entry + if (entry->entry_type() == NVRAM_EVSA_ENTRY_TYPE_GUID1 || entry->entry_type() == NVRAM_EVSA_ENTRY_TYPE_GUID2) { + const phoenix_evsa_t::evsa_guid_t* guidEntry = (const phoenix_evsa_t::evsa_guid_t*)(entry->body()); + header = volumeBody.mid(storeOffset + entryOffset, sizeof(EVSA_GUID_ENTRY)); + body = volumeBody.mid(storeOffset + entryOffset + sizeof(EVSA_GUID_ENTRY), entry->len_evsa_entry() - header.size()); + entrySize = (UINT32)(header.size() + body.size()); + EFI_GUID guid = *(const EFI_GUID*)(guidEntry->guid().c_str()); + name = guidToUString(guid); + info = UString("GUID: ") + guidToUString(guid, false) + + usprintf("\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nType: %02Xh\nChecksum: %02Xh", + entrySize, entrySize, + (UINT32)header.size(), (UINT32)header.size(), + (UINT32)body.size(), (UINT32)body.size(), + entry->entry_type(), + entry->checksum()) + + (entry->checksum() != calculated ? usprintf(", invalid, should be %02Xh", calculated) : UString(", valid")) + + usprintf("\nGuidId: %04Xh", guidEntry->guid_id()); + subtype = Subtypes::GuidEvsaEntry; + guidMap.insert(std::pair(guidEntry->guid_id(), guid)); + } + // Name entry + else if (entry->entry_type() == NVRAM_EVSA_ENTRY_TYPE_NAME1 || entry->entry_type() == NVRAM_EVSA_ENTRY_TYPE_NAME2) { + const phoenix_evsa_t::evsa_name_t* nameEntry = (const phoenix_evsa_t::evsa_name_t*)(entry->body()); + header = volumeBody.mid(storeOffset + entryOffset, sizeof(EVSA_NAME_ENTRY)); + body = volumeBody.mid(storeOffset + entryOffset + sizeof(EVSA_NAME_ENTRY), entry->len_evsa_entry() - header.size()); + entrySize = (UINT32)(header.size() + body.size()); + name = uFromUcs2(body.constData()); + info = UString("Name: ") + name + + usprintf("\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nType: %02Xh\nChecksum: %02Xh", + entrySize, entrySize, + (UINT32)header.size(), (UINT32)header.size(), + (UINT32)body.size(), (UINT32)body.size(), + entry->entry_type(), + entry->checksum()) + + (entry->checksum() != calculated ? usprintf(", invalid, should be %02Xh", calculated) : UString(", valid")) + + usprintf("\nVarId: %04Xh", nameEntry->var_id()); + subtype = Subtypes::NameEvsaEntry; + nameMap.insert(std::pair(nameEntry->var_id(), name)); + } + // Data entry + else if (entry->entry_type() == NVRAM_EVSA_ENTRY_TYPE_DATA1 + || entry->entry_type() == NVRAM_EVSA_ENTRY_TYPE_DATA2 + || entry->entry_type() == NVRAM_EVSA_ENTRY_TYPE_DATA_INVALID) { + phoenix_evsa_t::evsa_data_t* dataEntry = (phoenix_evsa_t::evsa_data_t*)(entry->body()); + if (dataEntry->_is_null_len_data_ext()) { + header = volumeBody.mid(storeOffset + entryOffset, sizeof(EVSA_DATA_ENTRY)); + body = volumeBody.mid(storeOffset + entryOffset + sizeof(EVSA_DATA_ENTRY), entry->len_evsa_entry() - header.size()); + } + else { + header = volumeBody.mid(storeOffset + entryOffset, sizeof(EVSA_DATA_ENTRY_EXTENDED)); + body = volumeBody.mid(storeOffset + entryOffset + sizeof(EVSA_DATA_ENTRY_EXTENDED), dataEntry->len_data_ext()); + } + entrySize = (UINT32)(header.size() + body.size()); + name = UString("Data"); + subtype = Subtypes::DataEvsaEntry; + + const UINT32 attributes = dataEntry->attributes()->non_volatile() + + (dataEntry->attributes()->boot_service() << 1) + + (dataEntry->attributes()->runtime() << 2) + + (dataEntry->attributes()->hw_error_record() << 3) + + (dataEntry->attributes()->auth_write() << 4) + + (dataEntry->attributes()->time_based_auth() << 5) + + (dataEntry->attributes()->append_write() << 6) + + (UINT32)(dataEntry->attributes()->reserved() << 7) + + (dataEntry->attributes()->extended_header() << 28) + + (UINT32)(dataEntry->attributes()->reserved1() << 29); + + info = usprintf("Full size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nType: %02Xh\nChecksum: %02Xh", + entrySize, entrySize, + (UINT32)header.size(), (UINT32)header.size(), + (UINT32)body.size(), (UINT32)body.size(), + entry->entry_type(), + entry->checksum()) + + (entry->checksum() != calculated ? usprintf(", invalid, should be %02Xh", calculated) : UString(", valid")) + + usprintf("\nVarId: %04Xh\nGuidId: %04Xh\nAttributes: %08Xh (", + dataEntry->var_id(), + dataEntry->guid_id(), + attributes) + + evsaAttributesToUString(attributes) + UString(")"); + } + + // Add tree item + model->addItem(entryOffset, Types::EvsaEntry, subtype, name, text, info, header, body, UByteArray(), Fixed, headerIndex); + + entryOffset += entrySize; + } + + // Reparse all data variables to detect invalid ones and assign name and test to valid ones + for (int i = 0; i < model->rowCount(headerIndex); i++) { + UModelIndex current = headerIndex.model()->index(i, 0, headerIndex); + + if (model->subtype(current) == Subtypes::DataEvsaEntry) { + UByteArray header = model->header(current); + const EVSA_DATA_ENTRY* dataHeader = (const EVSA_DATA_ENTRY*)header.constData(); + UString guid; + if (guidMap.count(dataHeader->GuidId)) + guid = guidToUString(guidMap[dataHeader->GuidId], false); + UString name; + if (nameMap.count(dataHeader->VarId)) + name = nameMap[dataHeader->VarId]; + + // Check for variable validity + if (guid.isEmpty() && name.isEmpty()) { // Both name and guid aren't found + model->setSubtype(current, Subtypes::InvalidEvsaEntry); + model->setName(current, UString("Invalid")); + model->setText(current, UString()); + msg(usprintf("%s: data variable with invalid GuidId and invalid VarId", __FUNCTION__), current); + } + else if (guid.isEmpty()) { // Guid not found + model->setSubtype(current, Subtypes::InvalidEvsaEntry); + model->setName(current, UString("Invalid")); + model->setText(current, UString()); + msg(usprintf("%s: data variable with invalid GuidId", __FUNCTION__), current); + } + else if (name.isEmpty()) { // Name not found + model->setSubtype(current, Subtypes::InvalidEvsaEntry); + model->setName(current, UString("Invalid")); + model->setText(current, UString()); + msg(usprintf("%s: data variable with invalid VarId", __FUNCTION__), current); + } + else { // Variable is OK, rename it + if (dataHeader->Header.Type == NVRAM_EVSA_ENTRY_TYPE_DATA_INVALID) { + model->setSubtype(current, Subtypes::InvalidEvsaEntry); + model->setName(current, UString("Invalid")); + model->setText(current, UString()); + } + else { + model->setName(current, guid); + model->setText(current, name); + model->addInfo(current, UString("GUID: ") + guid + UString("\nName: ") + name + "\n", false); + } + } + } + } + + storeOffset += storeSize - 1; + previousStoreEndOffset = storeOffset + 1; + continue; + } catch (...) { + // Parsing failed, try something else + } + not_evsa: + // Phoenix CMDB store + try { + if (volumeBodySize - storeOffset < NVRAM_PHOENIX_CMDB_SIZE) { + // No need to parse further, the rest of the volume is too small + goto not_cmdb; + } + // Perform initial sanity check + const PHOENIX_CMDB_HEADER* storeHeader = (const PHOENIX_CMDB_HEADER*)(volumeBody.constData() + storeOffset); + if (storeHeader->Signature != NVRAM_PHOENIX_CMDB_HEADER_SIGNATURE) { + // No need to parse further, not a Phoenix CMDB store + goto not_cmdb; + } + UINT32 storeSize = NVRAM_PHOENIX_CMDB_SIZE; + + // CMDB store at current offset parsed correctly + // Check if we need to add a padding before it + if (!outerPadding.isEmpty()) { + info = usprintf("Full size: %Xh (%u)", (UINT32)outerPadding.size(), (UINT32)outerPadding.size()); + model->addItem(localOffset + previousStoreEndOffset, Types::Padding, getPaddingType(outerPadding), UString("Padding"), UString(), info, UByteArray(), outerPadding, UByteArray(), Fixed, index); + outerPadding.clear(); + } + + // Construct header and body + header = volumeBody.mid(storeOffset, storeHeader->TotalSize); + body = volumeBody.mid(storeOffset + header.size(), storeSize - header.size()); + + // Add info + name = UString("Phoenix CMDB store"); + info = usprintf("Signature: CMDB\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)", + storeSize, storeSize, + (UINT32)header.size(), (UINT32)header.size(), + (UINT32)body.size(), (UINT32)body.size()); + + // Add tree item + model->addItem(localOffset + storeOffset, Types::CmdbStore, 0, name, UString(), info, header, body, UByteArray(), Fixed, index); + + storeOffset += storeSize - 1; + previousStoreEndOffset = storeOffset + 1; + continue; + } catch (...) { + // Parsing failed, try something else + } +not_cmdb: + // SLIC PubKey + try { + if (volumeBodySize - storeOffset < sizeof(OEM_ACTIVATION_PUBKEY)) { + // No need to parse further, the rest of the volume is too small + goto not_pubkey; + } + // Perform initial sanity check + const OEM_ACTIVATION_PUBKEY* storeHeader = (const OEM_ACTIVATION_PUBKEY*)(volumeBody.constData() + storeOffset); + if (storeHeader->Magic != OEM_ACTIVATION_PUBKEY_MAGIC + || storeHeader->Type != OEM_ACTIVATION_PUBKEY_TYPE + || storeHeader->Size != sizeof(OEM_ACTIVATION_PUBKEY)) { + // No need to parse further, not a SLIC PubKey + goto not_pubkey; + } + UINT32 storeSize = sizeof(OEM_ACTIVATION_PUBKEY); + + umemstream is(volumeBody.constData() + storeOffset, storeSize); + kaitai::kstream ks(&is); + ms_slic_pubkey_t parsed(&ks); + + // SLIC PubKey at current offset parsed correctly + // Check if we need to add a padding before it + if (!outerPadding.isEmpty()) { + info = usprintf("Full size: %Xh (%u)", (UINT32)outerPadding.size(), (UINT32)outerPadding.size()); + model->addItem(localOffset + previousStoreEndOffset, Types::Padding, getPaddingType(outerPadding), UString("Padding"), UString(), info, UByteArray(), outerPadding, UByteArray(), Fixed, index); + outerPadding.clear(); + } + + // Construct header + header = volumeBody.mid(storeOffset, storeSize); + + // Add info + name = UString("SLIC pubkey"); + info = usprintf("Type: 0h\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: 0h (0)\n" + "Key type: %02Xh\nVersion: %02Xh\nAlgorithm: %08Xh\nMagic: RSA1\nBit length: %08Xh\nExponent: %08Xh", + parsed.len_pubkey(), parsed.len_pubkey(), + parsed.len_pubkey(), parsed.len_pubkey(), + parsed.key_type(), + parsed.version(), + parsed.algorithm(), + parsed.bit_length(), + parsed.exponent()); + + // Add tree item + model->addItem(localOffset + storeOffset, Types::SlicData, Subtypes::PubkeySlicData, name, UString(), info, header, UByteArray(), UByteArray(), Fixed, index); + + storeOffset += storeSize - 1; + previousStoreEndOffset = storeOffset + 1; + continue; + } catch (...) { + // Parsing failed, try something else + } +not_pubkey: + // SLIC marker + try { + if (volumeBodySize - storeOffset < sizeof(OEM_ACTIVATION_MARKER)) { + // No need to parse further, the rest of the volume is too small + goto not_marker; + } + // Perform initial sanity check + const OEM_ACTIVATION_MARKER* storeHeader = (const OEM_ACTIVATION_MARKER*)(volumeBody.constData() + storeOffset); + if (storeHeader->WindowsFlag != OEM_ACTIVATION_MARKER_WINDOWS_FLAG + || storeHeader->Type != OEM_ACTIVATION_MARKER_TYPE + || storeHeader->Size != sizeof(OEM_ACTIVATION_MARKER)) { + // No need to parse further, not a SLIC marker + goto not_marker; + } + // Check reserved bytes + for (UINT8 i = 0; i < sizeof(storeHeader->Reserved); i++) { + if (storeHeader->Reserved[i] != OEM_ACTIVATION_MARKER_RESERVED_BYTE) { + // No need to parse further, not a SLIC marker + goto not_marker; + } + } + UINT32 storeSize = sizeof(OEM_ACTIVATION_MARKER); + + umemstream is(volumeBody.constData() + storeOffset, storeSize); + kaitai::kstream ks(&is); + ms_slic_marker_t parsed(&ks); + + // SLIC marker at current offset parsed correctly + // Check if we need to add a padding before it + if (!outerPadding.isEmpty()) { + info = usprintf("Full size: %Xh (%u)", (UINT32)outerPadding.size(), (UINT32)outerPadding.size()); + model->addItem(localOffset + previousStoreEndOffset, Types::Padding, getPaddingType(outerPadding), UString("Padding"), UString(), info, UByteArray(), outerPadding, UByteArray(), Fixed, index); + outerPadding.clear(); + } + + // Construct header + header = volumeBody.mid(storeOffset, storeSize); + + // Add info + name = UString("SLIC marker"); + info = usprintf("Type: 1h\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: 0h (0)\n" + "Version: %08Xh\nOEM ID: %s\nOEM table ID: %s\nWindows flag: WINDOWS \nSLIC version: %08Xh", + parsed.len_marker(), parsed.len_marker(), + parsed.len_marker(), parsed.len_marker(), + parsed.version(), + parsed.oem_id().c_str(), + parsed.oem_table_id().c_str(), + parsed.slic_version()); + + // Add tree item + model->addItem(localOffset + storeOffset, Types::SlicData, Subtypes::MarkerSlicData, name, UString(), info, header, UByteArray(), UByteArray(), Fixed, index); + + storeOffset += storeSize - 1; + previousStoreEndOffset = storeOffset + 1; + continue; + } catch (...) { + // Parsing failed, try something else + } +not_marker: + // Intel uCode + try { + // Check data size + if (volumeBodySize - storeOffset < sizeof(INTEL_MICROCODE_HEADER)) { + goto not_ucode; + } + + const UINT32 currentUint32 = readUnaligned((const UINT32*)(volumeBody.constData() + storeOffset)); + if (currentUint32 != INTEL_MICROCODE_HEADER_VERSION_1) { + goto not_ucode; + } + + // Check microcode header candidate + const INTEL_MICROCODE_HEADER* ucodeHeader = (const INTEL_MICROCODE_HEADER*)(volumeBody.constData() + storeOffset); + if (FALSE == ffsParser->microcodeHeaderValid(ucodeHeader)) { + goto not_ucode; + } + + // Check candidate size + if (ucodeHeader->TotalSize == 0) { + goto not_ucode; + } + + // We still have enough data left to fit the whole TotalSize + UINT32 storeSize = ucodeHeader->TotalSize; + if (volumeBodySize - storeOffset < storeSize) { + goto not_ucode; + } + + // All checks passed, microcode found + // Check if we need to add a padding before it + if (!outerPadding.isEmpty()) { + info = usprintf("Full size: %Xh (%u)", (UINT32)outerPadding.size(), (UINT32)outerPadding.size()); + model->addItem(localOffset + previousStoreEndOffset, Types::Padding, getPaddingType(outerPadding), UString("Padding"), UString(), info, UByteArray(), outerPadding, UByteArray(), Fixed, index); + outerPadding.clear(); + } + + // Parse microcode header + UByteArray ucode = volumeBody.mid(storeOffset); + UModelIndex ucodeIndex; + if (U_SUCCESS != ffsParser->parseIntelMicrocodeHeader(ucode, localOffset + storeOffset, index, ucodeIndex)) { + goto not_ucode; + } + + storeOffset += storeSize - 1; + previousStoreEndOffset = storeOffset + 1; + continue; + } catch (...) { + // Parsing failed, try something else + } +not_ucode: + // FFS volume + try { + // Check data size + if (volumeBodySize - storeOffset < sizeof(EFI_FIRMWARE_VOLUME_HEADER)) { + goto not_ffs_volume; + } + + // Check volume header candidate + const EFI_FIRMWARE_VOLUME_HEADER* volumeHeader = (const EFI_FIRMWARE_VOLUME_HEADER*)(volumeBody.constData() + storeOffset); + if (volumeHeader->Signature != EFI_FV_SIGNATURE) { + goto not_ffs_volume; + } + + // All checks passed, volume found + UByteArray volume = volumeBody.mid(storeOffset); + UModelIndex volumeIndex; + if (U_SUCCESS != ffsParser->parseVolumeHeader(volume, localOffset + storeOffset, index, volumeIndex)) { + goto not_ffs_volume; + } + + (VOID)ffsParser->parseVolumeBody(volumeIndex); + UINT32 storeSize = (UINT32)(model->header(volumeIndex).size() + model->body(volumeIndex).size()); + + storeOffset += storeSize - 1; + previousStoreEndOffset = storeOffset + 1; + continue; + } catch (...) { + // Parsing failed, try something else + } +not_ffs_volume: + // Padding + if (storeOffset < volumeBodySize) { + outerPadding += volumeBody[storeOffset]; + } + } + + // Add padding at the very end + if (!outerPadding.isEmpty()) { + // Add info + UString info = usprintf("Full size: %Xh (%u)", (UINT32)outerPadding.size(), (UINT32)outerPadding.size()); + + // Check that remaining unparsed bytes are actually empty + if (outerPadding.count(emptyByte) == outerPadding.size()) { + // Add tree item + model->addItem(localOffset + previousStoreEndOffset, Types::FreeSpace, 0, UString("Free space"), UString(), info, UByteArray(), outerPadding, UByteArray(), Fixed, index); + } + else { + // Add tree item + model->addItem(localOffset + previousStoreEndOffset, Types::Padding, getPaddingType(outerPadding), UString("Padding"), UString(), info, UByteArray(), outerPadding, UByteArray(), Fixed, index); + } + } + + return U_SUCCESS; +} +#endif // U_ENABLE_NVRAM_PARSING_SUPPORT diff --git a/common/nvramparser.h b/common/nvramparser.h new file mode 100644 index 0000000..a64e795 --- /dev/null +++ b/common/nvramparser.h @@ -0,0 +1,69 @@ +/* nvramparser.h + +Copyright (c) 2016, Nikolaj Schlej. All rights reserved. + +This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php. + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +*/ + +#ifndef NVRAMPARSER_H +#define NVRAMPARSER_H + +#include + +#include "basetypes.h" +#include "ustring.h" +#include "ubytearray.h" +#include "treemodel.h" +#include "ffsparser.h" + +#ifdef U_ENABLE_NVRAM_PARSING_SUPPORT +class NvramParser +{ +public: + // Default constructor and destructor + NvramParser(TreeModel* treeModel, FfsParser* parser) : model(treeModel), ffsParser(parser) {} + ~NvramParser() {} + + // Returns messages + std::vector > getMessages() const { return messagesVector; } + // Clears messages + void clearMessages() { messagesVector.clear(); } + + // NVRAM parsing + USTATUS parseNvramVolumeBody(const UModelIndex & index, const UINT32 fdcStoreSizeOverride = 0); + USTATUS parseNvarStore(const UModelIndex & index); + +private: + TreeModel *model; + FfsParser *ffsParser; + std::vector > messagesVector; + void msg(const UString & message, const UModelIndex & index = UModelIndex()) { + messagesVector.push_back(std::pair(message, index)); + }; +}; +#else +class NvramParser +{ +public: + // Default constructor and destructor + NvramParser(TreeModel* treeModel, FfsParser* parser) { U_UNUSED_PARAMETER(treeModel); U_UNUSED_PARAMETER(parser); } + ~NvramParser() {} + + // Returns messages + std::vector > getMessages() const { return std::vector >(); } + // Clears messages + void clearMessages() {} + + // NVRAM parsing + USTATUS parseNvramVolumeBody(const UModelIndex &) { return U_SUCCESS; } + USTATUS parseNvarStore(const UModelIndex &) { return U_SUCCESS; } +}; +#endif // U_ENABLE_NVRAM_PARSING_SUPPORT +#endif // NVRAMPARSER_H diff --git a/common/parsingdata.h b/common/parsingdata.h index b52870d..e920fc8 100644 --- a/common/parsingdata.h +++ b/common/parsingdata.h @@ -22,62 +22,48 @@ routines without the need of backward traversal typedef struct VOLUME_PARSING_DATA_ { EFI_GUID extendedHeaderGuid; UINT32 alignment; + UINT32 usedSpace; + BOOLEAN hasValidUsedSpace; + UINT8 ffsVersion; + UINT8 emptyByte; UINT8 revision; BOOLEAN hasExtendedHeader; BOOLEAN hasAppleCrc32; - BOOLEAN hasAppleFSO; BOOLEAN isWeakAligned; + BOOLEAN requiresSectionAlignmentQuirk; } VOLUME_PARSING_DATA; typedef struct FILE_PARSING_DATA_ { + UINT8 emptyByte; EFI_GUID guid; } FILE_PARSING_DATA; -typedef struct COMPRESSED_SECTION_PARSING_DATA_ { - UINT32 uncompressedSize; - UINT8 compressionType; - UINT8 algorithm; -} COMPRESSED_SECTION_PARSING_DATA; - typedef struct GUIDED_SECTION_PARSING_DATA_ { EFI_GUID guid; + UINT32 dictionarySize; } GUIDED_SECTION_PARSING_DATA; typedef struct FREEFORM_GUIDED_SECTION_PARSING_DATA_ { EFI_GUID guid; } FREEFORM_GUIDED_SECTION_PARSING_DATA; +typedef struct COMPRESSED_SECTION_PARSING_DATA_ { + UINT32 uncompressedSize; + UINT8 compressionType; + UINT8 algorithm; + UINT32 dictionarySize; +} COMPRESSED_SECTION_PARSING_DATA; + typedef struct TE_IMAGE_SECTION_PARSING_DATA_ { - UINT32 imageBase; - UINT32 adjustedImageBase; - UINT8 imageBaseType; + UINT32 originalImageBase; + UINT32 adjustedImageBase; + UINT8 imageBaseType; } TE_IMAGE_SECTION_PARSING_DATA; -typedef struct SECTION_PARSING_DATA_ { - union { - COMPRESSED_SECTION_PARSING_DATA compressed; - GUIDED_SECTION_PARSING_DATA guidDefined; - FREEFORM_GUIDED_SECTION_PARSING_DATA freeformSubtypeGuid; - TE_IMAGE_SECTION_PARSING_DATA teImage; - }; -} SECTION_PARSING_DATA; - typedef struct NVAR_ENTRY_PARSING_DATA_ { - UINT32 next; + UINT8 emptyByte; BOOLEAN isValid; + UINT32 next; } NVAR_ENTRY_PARSING_DATA; -typedef struct PARSING_DATA_ { - UINT8 emptyByte; - UINT8 ffsVersion; - UINT32 offset; - UINT32 address; - union { - VOLUME_PARSING_DATA volume; - FILE_PARSING_DATA file; - SECTION_PARSING_DATA section; - NVAR_ENTRY_PARSING_DATA nvar; - }; -} PARSING_DATA; - -#endif // NVRAM_H +#endif // PARSINGDATA_H diff --git a/common/peimage.cpp b/common/peimage.cpp index 534d0c8..7feb30b 100644 --- a/common/peimage.cpp +++ b/common/peimage.cpp @@ -1,35 +1,35 @@ /* peimage.cpp - -Copyright (c) 2015, Nikolaj Schlej. All rights reserved. -This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php. - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -*/ + + Copyright (c) 2015, Nikolaj Schlej. All rights reserved. + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + */ #include "peimage.h" UString machineTypeToUString(UINT16 machineType) { switch (machineType) { - case EFI_IMAGE_FILE_MACHINE_AMD64: return UString("x86-64"); - case EFI_IMAGE_FILE_MACHINE_ARM: return UString("ARM"); - case EFI_IMAGE_FILE_MACHINE_ARMNT: return UString("ARMv7"); - case EFI_IMAGE_FILE_MACHINE_APPLE_ARM: return UString("Apple ARM"); - case EFI_IMAGE_FILE_MACHINE_AARCH64: return UString("AARCH64"); - case EFI_IMAGE_FILE_MACHINE_EBC: return UString("EBC"); - case EFI_IMAGE_FILE_MACHINE_I386: return UString("x86"); - case EFI_IMAGE_FILE_MACHINE_IA64: return UString("IA64"); - case EFI_IMAGE_FILE_MACHINE_POWERPC: return UString("PowerPC"); - case EFI_IMAGE_FILE_MACHINE_POWERPCFP: return UString("PowerPC FP"); - case EFI_IMAGE_FILE_MACHINE_THUMB: return UString("ARM Thumb"); - case EFI_IMAGE_FILE_MACHINE_RISCV32: return UString("RISC-V 32-bit"); - case EFI_IMAGE_FILE_MACHINE_RISCV64: return UString("RISC-V 64-bit"); - case EFI_IMAGE_FILE_MACHINE_RISCV128: return UString("RISC-V 128-bit"); - default: return usprintf("Unknown (%04Xh)", machineType); + case EFI_IMAGE_FILE_MACHINE_AMD64: return UString("x86-64"); + case EFI_IMAGE_FILE_MACHINE_ARM: return UString("ARM"); + case EFI_IMAGE_FILE_MACHINE_ARMNT: return UString("ARMv7"); + case EFI_IMAGE_FILE_MACHINE_APPLE_ARM: return UString("Apple ARM"); + case EFI_IMAGE_FILE_MACHINE_AARCH64: return UString("AArch64"); + case EFI_IMAGE_FILE_MACHINE_EBC: return UString("EBC"); + case EFI_IMAGE_FILE_MACHINE_I386: return UString("x86"); + case EFI_IMAGE_FILE_MACHINE_IA64: return UString("IA64"); + case EFI_IMAGE_FILE_MACHINE_POWERPC: return UString("PowerPC"); + case EFI_IMAGE_FILE_MACHINE_POWERPCFP: return UString("PowerPC FP"); + case EFI_IMAGE_FILE_MACHINE_THUMB: return UString("ARM Thumb"); + case EFI_IMAGE_FILE_MACHINE_RISCV32: return UString("RISC-V 32-bit"); + case EFI_IMAGE_FILE_MACHINE_RISCV64: return UString("RISC-V 64-bit"); + case EFI_IMAGE_FILE_MACHINE_RISCV128: return UString("RISC-V 128-bit"); } -} \ No newline at end of file + return usprintf("Unknown %04Xh", machineType); +} diff --git a/common/peimage.h b/common/peimage.h index 6c14d9c..4525989 100644 --- a/common/peimage.h +++ b/common/peimage.h @@ -16,8 +16,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #ifndef PEIMAGE_H #define PEIMAGE_H -#include "ustring.h" #include "basetypes.h" +#include "ustring.h" extern UString machineTypeToUString(UINT16 machineType); @@ -45,7 +45,7 @@ extern UString machineTypeToUString(UINT16 machineType); #define EFI_IMAGE_FILE_MACHINE_IA64 0x0200 // Itanium #define EFI_IMAGE_FILE_MACHINE_EBC 0x0ebc // EFI Byte Code #define EFI_IMAGE_FILE_MACHINE_AMD64 0x8664 // x86-64 -#define EFI_IMAGE_FILE_MACHINE_AARCH64 0xaa64 // ARMv8 in 64-bit mode +#define EFI_IMAGE_FILE_MACHINE_AARCH64 0xaa64 // ARMv8 in 64-bit mode #define EFI_IMAGE_FILE_MACHINE_RISCV32 0x5032 // RISC-V 32-bit #define EFI_IMAGE_FILE_MACHINE_RISCV64 0x5064 // RISC-V 64-bit #define EFI_IMAGE_FILE_MACHINE_RISCV128 0x5128 // RISC-V 128-bit @@ -586,8 +586,8 @@ typedef struct { } EFI_IMAGE_THUNK_DATA; #define EFI_IMAGE_ORDINAL_FLAG 0x80000000 // Flag for PE32. -#define EFI_IMAGE_SNAP_BY_ORDINAL(Ordinal) ((Ordinal & EFI_IMAGE_ORDINAL_FLAG) != 0) -#define EFI_IMAGE_ORDINAL(Ordinal) (Ordinal & 0xffff) +#define EFI_IMAGE_SNAP_BY_ORDINAL(Ordinal) (((Ordinal) & EFI_IMAGE_ORDINAL_FLAG) != 0) +#define EFI_IMAGE_ORDINAL(Ordinal) ((Ordinal) & 0xffff) // // Import Directory Table diff --git a/common/treeitem.cpp b/common/treeitem.cpp index ce65a0b..3939c0b 100644 --- a/common/treeitem.cpp +++ b/common/treeitem.cpp @@ -1,37 +1,38 @@ /* treeitem.cpp - -Copyright (c) 2015, Nikolaj Schlej. All rights reserved. -This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -*/ + + Copyright (c) 2015, Nikolaj Schlej. All rights reserved. + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + */ #include "treeitem.h" #include "types.h" -TreeItem::TreeItem(const UINT8 type, const UINT8 subtype, - const UString & name, const UString & text, const UString & info, - const UByteArray & header, const UByteArray & body, const UByteArray & tail, - const bool fixed, const bool compressed, const UByteArray & parsingData, - TreeItem *parent) : - itemAction(Actions::NoAction), - itemType(type), - itemSubtype(subtype), - itemName(name), - itemText(text), - itemInfo(info), - itemHeader(header), - itemBody(body), - itemTail(tail), - itemParsingData(parsingData), - itemFixed(fixed), - itemCompressed(compressed), - parentItem(parent) +TreeItem::TreeItem(const UINT32 offset, const UINT8 type, const UINT8 subtype, + const UString & name, const UString & text, const UString & info, + const UByteArray & header, const UByteArray & body, const UByteArray & tail, + const bool fixed, const bool compressed, + TreeItem *parent) : +itemOffset(offset), +itemAction(Actions::NoAction), +itemType(type), +itemSubtype(subtype), +itemMarking(0), +itemName(name), +itemText(text), +itemInfo(info), +itemHeader(header), +itemBody(body), +itemTail(tail), +itemFixed(fixed), +itemCompressed(compressed), +parentItem(parent) { } @@ -65,18 +66,18 @@ UString TreeItem::data(int column) const { switch (column) { - case 0: // Name - return itemName; - case 1: // Action - return actionTypeToUString(itemAction); - case 2: // Type - return itemTypeToUString(itemType); - case 3: // Subtype - return itemSubtypeToUString(itemType, itemSubtype); - case 4: // Text - return itemText; - default: - return UString(); + case 0: // Name + return itemName; + case 1: // Action + return actionTypeToUString(itemAction); + case 2: // Type + return itemTypeToUString(itemType); + case 3: // Subtype + return itemSubtypeToUString(itemType, itemSubtype); + case 4: // Text + return itemText; + default: + return UString(); } } @@ -93,8 +94,8 @@ int TreeItem::row() const } TreeItem* TreeItem::child(int row) -{ - std::list::iterator child = childItems.begin(); - std::advance(child, row); - return *child; -} \ No newline at end of file +{ + std::list::iterator child = childItems.begin(); + std::advance(child, row); + return *child; +} diff --git a/common/treeitem.h b/common/treeitem.h index b4971b8..0baf3e1 100644 --- a/common/treeitem.h +++ b/common/treeitem.h @@ -17,16 +17,16 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include #include +#include "basetypes.h" #include "ubytearray.h" #include "ustring.h" -#include "basetypes.h" class TreeItem { public: - TreeItem(const UINT8 type, const UINT8 subtype, const UString &name, const UString &text, const UString &info, + TreeItem(const UINT32 offset, const UINT8 type, const UINT8 subtype, const UString &name, const UString &text, const UString &info, const UByteArray & header, const UByteArray & body, const UByteArray & tail, - const bool fixed, const bool compressed, const UByteArray & parsingData, + const bool fixed, const bool compressed, TreeItem *parent = 0); ~TreeItem(); // Non-trivial implementation in CPP file @@ -38,15 +38,15 @@ public: // Model support operations TreeItem *child(int row); // Non-trivial implementation in CPP file - int childCount() const {return childItems.size(); } + int childCount() const {return (int)childItems.size(); } int columnCount() const { return 5; } UString data(int column) const; // Non-trivial implementation in CPP file int row() const; // Non-trivial implementation in CPP file TreeItem *parent() { return parentItem; } // Getters and setters for item parameters - UString name() const { return itemName; } - void setName(const UString &text) { itemName = text; } + UINT32 offset() const { return itemOffset; } + void setOffset(const UINT32 offset) { itemOffset = offset; } UINT8 type() const { return itemType; } void setType(const UINT8 type) { itemType = type; } @@ -54,6 +54,9 @@ public: UINT8 subtype() const { return itemSubtype; } void setSubtype(const UINT8 subtype) { itemSubtype = subtype; } + UString name() const { return itemName; } + void setName(const UString &text) { itemName = text; } + UString text() const { return itemText; } void setText(const UString &text) { itemText = text; } @@ -66,10 +69,6 @@ public: UByteArray tail() const { return itemTail; }; bool hasEmptyTail() const { return itemTail.isEmpty(); } - UByteArray parsingData() const { return itemParsingData; } - bool hasEmptyParsingData() const { return itemParsingData.isEmpty(); } - void setParsingData(const UByteArray & data) { itemParsingData = data; } - UString info() const { return itemInfo; } void addInfo(const UString &info, const bool append) { if (append) itemInfo += info; else itemInfo = info + itemInfo; } void setInfo(const UString &info) { itemInfo = info; } @@ -83,20 +82,34 @@ public: bool compressed() const { return itemCompressed; } void setCompressed(const bool compressed) { itemCompressed = compressed; } + UByteArray parsingData() const { return itemParsingData; }; + bool hasEmptyParsingData() const { return itemParsingData.isEmpty(); } + void setParsingData(const UByteArray & pdata) { itemParsingData = pdata; } + + UByteArray uncompressedData() const { return itemUncompressedData; }; + bool hasEmptyUncompressedData() const { return itemUncompressedData.isEmpty(); } + void setUncompressedData(const UByteArray & ucdata) { itemUncompressedData = ucdata; } + + UINT8 marking() const { return itemMarking; } + void setMarking(const UINT8 marking) { itemMarking = marking; } + private: std::list childItems; + UINT32 itemOffset; UINT8 itemAction; UINT8 itemType; UINT8 itemSubtype; + UINT8 itemMarking; UString itemName; UString itemText; UString itemInfo; UByteArray itemHeader; UByteArray itemBody; UByteArray itemTail; - UByteArray itemParsingData; bool itemFixed; bool itemCompressed; + UByteArray itemParsingData; + UByteArray itemUncompressedData; TreeItem* parentItem; }; diff --git a/common/treemodel.cpp b/common/treemodel.cpp index 8ec8450..8fcc0bd 100644 --- a/common/treemodel.cpp +++ b/common/treemodel.cpp @@ -1,63 +1,70 @@ /* treemodel.cpp + + Copyright (c) 2015, Nikolaj Schlej. All rights reserved. + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + */ -Copyright (c) 2015, Nikolaj Schlej. All rights reserved. -This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -*/ - -#include "treeitem.h" #include "treemodel.h" +#include "stack" + #if defined(QT_CORE_LIB) QVariant TreeModel::data(const UModelIndex &index, int role) const { if (!index.isValid()) return QVariant(); - - if (role != Qt::DisplayRole && role != Qt::UserRole) - return QVariant(); - + TreeItem *item = static_cast(index.internalPointer()); - - if (role == Qt::DisplayRole) - return (const char*)item->data(index.column()).toLocal8Bit(); - else - return (const char*)item->info().toLocal8Bit(); + + if (role == Qt::DisplayRole) { + return item->data(index.column()).toLocal8Bit(); + } +#if defined (QT_GUI_LIB) + else if (role == Qt::BackgroundRole) { + if (markingEnabledFlag && marking(index) != BootGuardMarking::None) { + switch (marking(index)) { + case BootGuardMarking::BootGuardFullyInRange: return QBrush((Qt::GlobalColor)(markingDarkModeFlag ? Qt::darkRed : Qt::red )); break; + case BootGuardMarking::VendorFullyInRange: return QBrush((Qt::GlobalColor)(markingDarkModeFlag ? Qt::darkCyan : Qt::cyan )); break; + case BootGuardMarking::PartiallyInRange: return QBrush((Qt::GlobalColor)(markingDarkModeFlag ? Qt::darkYellow : Qt::yellow)); break; + } + } + } +#endif + else if (role == Qt::UserRole) { + return item->info().toLocal8Bit(); + } + + return QVariant(); } Qt::ItemFlags TreeModel::flags(const UModelIndex &index) const { if (!index.isValid()) - return 0; - + return Qt::NoItemFlags; + return Qt::ItemIsEnabled | Qt::ItemIsSelectable; } QVariant TreeModel::headerData(int section, Qt::Orientation orientation, - int role) const + int role) const { if (orientation == Qt::Horizontal && role == Qt::DisplayRole) { - switch (section) - { - case 0: - return tr("Name"); - case 1: - return tr("Action"); - case 2: - return tr("Type"); - case 3: - return tr("Subtype"); - case 4: - return tr("Text"); + switch (section) { + case 0: return tr("Name"); + case 1: return tr("Action"); + case 2: return tr("Type"); + case 3: return tr("Subtype"); + case 4: return tr("Text"); } } - + return QVariant(); } #else @@ -65,12 +72,12 @@ UString TreeModel::data(const UModelIndex &index, int role) const { if (!index.isValid()) return UString(); - + if (role != 0 && role != 0x0100) return UString(); - + TreeItem *item = static_cast(index.internalPointer()); - + if (role == 0) return item->data(index.column()); else @@ -78,24 +85,19 @@ UString TreeModel::data(const UModelIndex &index, int role) const } UString TreeModel::headerData(int section, int orientation, - int role) const + int role) const { if (orientation == 1 && role == 0) { switch (section) { - case 0: - return UString("Name"); - case 1: - return UString("Action"); - case 2: - return UString("Type"); - case 3: - return UString("Subtype"); - case 4: - return UString("Text"); + case 0: return UString("Name"); + case 1: return UString("Action"); + case 2: return UString("Type"); + case 3: return UString("Subtype"); + case 4: return UString("Text"); } } - + return UString(); } #endif @@ -112,14 +114,14 @@ UModelIndex TreeModel::index(int row, int column, const UModelIndex &parent) con { if (!hasIndex(row, column, parent)) return UModelIndex(); - + TreeItem *parentItem; - + if (!parent.isValid()) parentItem = rootItem; else parentItem = static_cast(parent.internalPointer()); - + TreeItem *childItem = parentItem->child(row); if (childItem) return createIndex(row, column, childItem); @@ -131,16 +133,16 @@ UModelIndex TreeModel::parent(const UModelIndex &index) const { if (!index.isValid()) return UModelIndex(); - + TreeItem *childItem = static_cast(index.internalPointer()); if (childItem == rootItem) return UModelIndex(); - + TreeItem *parentItem = childItem->parent(); - + if (parentItem == rootItem) return UModelIndex(); - + return createIndex(parentItem->row(), 0, parentItem); } @@ -149,15 +151,37 @@ int TreeModel::rowCount(const UModelIndex &parent) const TreeItem *parentItem; if (parent.column() > 0) return 0; - + if (!parent.isValid()) parentItem = rootItem; else parentItem = static_cast(parent.internalPointer()); - + return parentItem->childCount(); } +UINT32 TreeModel::base(const UModelIndex ¤t) const +{ + // Rewrite this as loop if we ever see an image that is too deep for this naive implementation + if (!current.isValid()) + return 0; + + UModelIndex parent = current.parent(); + if (!parent.isValid()) + return offset(current); + else { + return offset(current) + base(parent); + } +} + +UINT32 TreeModel::offset(const UModelIndex &index) const +{ + if (!index.isValid()) + return 0; + TreeItem *item = static_cast(index.internalPointer()); + return item->offset(); +} + UINT8 TreeModel::type(const UModelIndex &index) const { if (!index.isValid()) @@ -174,6 +198,14 @@ UINT8 TreeModel::subtype(const UModelIndex &index) const return item->subtype(); } +UINT8 TreeModel::marking(const UModelIndex &index) const +{ + if (!index.isValid()) + return 0; + TreeItem *item = static_cast(index.internalPointer()); + return item->marking(); +} + UByteArray TreeModel::header(const UModelIndex &index) const { if (!index.isValid()) @@ -222,22 +254,6 @@ bool TreeModel::hasEmptyTail(const UModelIndex &index) const return item->hasEmptyTail(); } -UByteArray TreeModel::parsingData(const UModelIndex &index) const -{ - if (!index.isValid()) - return UByteArray(); - TreeItem *item = static_cast(index.internalPointer()); - return item->parsingData(); -} - -bool TreeModel::hasEmptyParsingData(const UModelIndex &index) const -{ - if (!index.isValid()) - return true; - TreeItem *item = static_cast(index.internalPointer()); - return item->hasEmptyParsingData(); -} - UString TreeModel::name(const UModelIndex &index) const { if (!index.isValid()) @@ -290,23 +306,24 @@ void TreeModel::setFixed(const UModelIndex &index, const bool fixed) { if (!index.isValid()) return; - + TreeItem *item = static_cast(index.internalPointer()); item->setFixed(fixed); - + if (!item->parent()) return; - + if (fixed) { + // Special handling for uncompressed to compressed boundary if (item->compressed() && item->parent()->compressed() == FALSE) { item->setFixed(item->parent()->fixed()); return; } - - if (item->parent()->type() != Types::Root) - item->parent()->setFixed(fixed); + + // Propagate fixed flag until root + setFixed(index.parent(), true); } - + emit dataChanged(index, index); } @@ -314,19 +331,63 @@ void TreeModel::setCompressed(const UModelIndex &index, const bool compressed) { if (!index.isValid()) return; - + TreeItem *item = static_cast(index.internalPointer()); item->setCompressed(compressed); - + emit dataChanged(index, index); } +void TreeModel::TreeModel::setMarkingEnabled(const bool enabled) +{ + markingEnabledFlag = enabled; + + emit dataChanged(UModelIndex(), UModelIndex()); +} + +void TreeModel::TreeModel::setMarkingDarkMode(const bool enabled) +{ + markingDarkModeFlag = enabled; + + emit dataChanged(UModelIndex(), UModelIndex()); +} + +void TreeModel::setMarking(const UModelIndex &index, const UINT8 marking) +{ + if (!index.isValid()) + return; + + TreeItem *item = static_cast(index.internalPointer()); + item->setMarking(marking); + + emit dataChanged(index, index); +} + +void TreeModel::setOffset(const UModelIndex &index, const UINT32 offset) +{ + if (!index.isValid()) + return; + + TreeItem *item = static_cast(index.internalPointer()); + item->setOffset(offset); + emit dataChanged(index, index); +} + +void TreeModel::setType(const UModelIndex &index, const UINT8 data) +{ + if (!index.isValid()) + return; + + TreeItem *item = static_cast(index.internalPointer()); + item->setType(data); + emit dataChanged(index, index); +} void TreeModel::setSubtype(const UModelIndex & index, const UINT8 subtype) { if (!index.isValid()) return; - + TreeItem *item = static_cast(index.internalPointer()); item->setSubtype(subtype); emit dataChanged(index, index); @@ -336,27 +397,17 @@ void TreeModel::setName(const UModelIndex &index, const UString &data) { if (!index.isValid()) return; - + TreeItem *item = static_cast(index.internalPointer()); item->setName(data); emit dataChanged(index, index); } -void TreeModel::setType(const UModelIndex &index, const UINT8 data) -{ - if (!index.isValid()) - return; - - TreeItem *item = static_cast(index.internalPointer()); - item->setType(data); - emit dataChanged(index, index); -} - void TreeModel::setText(const UModelIndex &index, const UString &data) { if (!index.isValid()) return; - + TreeItem *item = static_cast(index.internalPointer()); item->setText(data); emit dataChanged(index, index); @@ -366,7 +417,7 @@ void TreeModel::setInfo(const UModelIndex &index, const UString &data) { if (!index.isValid()) return; - + TreeItem *item = static_cast(index.internalPointer()); item->setInfo(data); emit dataChanged(index, index); @@ -376,7 +427,7 @@ void TreeModel::addInfo(const UModelIndex &index, const UString &data, const boo { if (!index.isValid()) return; - + TreeItem *item = static_cast(index.internalPointer()); item->addInfo(data, append); emit dataChanged(index, index); @@ -386,32 +437,78 @@ void TreeModel::setAction(const UModelIndex &index, const UINT8 action) { if (!index.isValid()) return; - + TreeItem *item = static_cast(index.internalPointer()); item->setAction(action); emit dataChanged(index, index); } +UByteArray TreeModel::parsingData(const UModelIndex &index) const +{ + if (!index.isValid()) + return UByteArray(); + + TreeItem *item = static_cast(index.internalPointer()); + return item->parsingData(); +} + +bool TreeModel::hasEmptyParsingData(const UModelIndex &index) const +{ + if (!index.isValid()) + return true; + + TreeItem *item = static_cast(index.internalPointer()); + return item->hasEmptyParsingData(); +} + void TreeModel::setParsingData(const UModelIndex &index, const UByteArray &data) { if (!index.isValid()) return; - + TreeItem *item = static_cast(index.internalPointer()); item->setParsingData(data); emit dataChanged(this->index(0, 0), index); } -UModelIndex TreeModel::addItem(const UINT8 type, const UINT8 subtype, - const UString & name, const UString & text, const UString & info, - const UByteArray & header, const UByteArray & body, const UByteArray & tail, - const bool fixed, const UByteArray & parsingData, - const UModelIndex & parent, const UINT8 mode) +UByteArray TreeModel::uncompressedData(const UModelIndex &index) const +{ + if (!index.isValid()) + return UByteArray(); + + TreeItem *item = static_cast(index.internalPointer()); + return item->uncompressedData(); +} + +bool TreeModel::hasEmptyUncompressedData(const UModelIndex &index) const +{ + if (!index.isValid()) + return true; + + TreeItem *item = static_cast(index.internalPointer()); + return item->hasEmptyUncompressedData(); +} + +void TreeModel::setUncompressedData(const UModelIndex &index, const UByteArray &data) +{ + if (!index.isValid()) + return; + + TreeItem *item = static_cast(index.internalPointer()); + item->setUncompressedData(data); + emit dataChanged(this->index(0, 0), index); +} + +UModelIndex TreeModel::addItem(const UINT32 offset, const UINT8 type, const UINT8 subtype, + const UString & name, const UString & text, const UString & info, + const UByteArray & header, const UByteArray & body, const UByteArray & tail, + const ItemFixedState fixed, + const UModelIndex & parent, const UINT8 mode) { TreeItem *item = 0; TreeItem *parentItem = 0; int parentColumn = 0; - + if (!parent.isValid()) parentItem = rootItem; else @@ -426,9 +523,9 @@ UModelIndex TreeModel::addItem(const UINT8 type, const UINT8 subtype, parentColumn = parent.column(); } } - - TreeItem *newItem = new TreeItem(type, subtype, name, text, info, header, body, tail, fixed, this->compressed(parent), parsingData, parentItem); - + + TreeItem *newItem = new TreeItem(offset, type, subtype, name, text, info, header, body, tail, Movable, this->compressed(parent), parentItem); + if (mode == CREATE_MODE_APPEND) { emit layoutAboutToBeChanged(); parentItem->appendChild(newItem); @@ -449,28 +546,69 @@ UModelIndex TreeModel::addItem(const UINT8 type, const UINT8 subtype, delete newItem; return UModelIndex(); } - + emit layoutChanged(); - + UModelIndex created = createIndex(newItem->row(), parentColumn, newItem); - setFixed(created, fixed); // Non-trivial logic requires additional call + setFixed(created, (bool)fixed); // Non-trivial logic requires additional call return created; } UModelIndex TreeModel::findParentOfType(const UModelIndex& index, UINT8 type) const { - if (!index.isValid()) + if (!index.isValid() || !index.parent().isValid()) return UModelIndex(); - + TreeItem *item; - UModelIndex parent = index; - + UModelIndex parent = index.parent(); + for (item = static_cast(parent.internalPointer()); - item != NULL && item != rootItem && item->type() != type; - item = static_cast(parent.internalPointer())) - parent = parent.parent(); + item != NULL && item != rootItem && item->type() != type; + item = static_cast(parent.internalPointer())) + parent = parent.parent(); if (item != NULL && item != rootItem) return parent; - + return UModelIndex(); -} \ No newline at end of file +} + +UModelIndex TreeModel::findLastParentOfType(const UModelIndex& index, UINT8 type) const +{ + if (!index.isValid()) + return UModelIndex(); + + UModelIndex lastParentOfType = findParentOfType(index, type); + + if (!lastParentOfType.isValid()) + return UModelIndex(); + + UModelIndex currentParentOfType = findParentOfType(lastParentOfType, type); + while (currentParentOfType.isValid()) { + lastParentOfType = currentParentOfType; + currentParentOfType = findParentOfType(lastParentOfType, type); + } + + return lastParentOfType; +} + +UModelIndex TreeModel::findByBase(UINT32 base) const +{ + UModelIndex parentIndex = index(0,0); + +goDeeper: + int n = rowCount(parentIndex); + for (int i = 0; i < n; i++) { + UModelIndex currentIndex = parentIndex.model()->index(i, 0, parentIndex); + + UINT32 currentBase = this->base(currentIndex); + UINT32 fullSize = (UINT32)(header(currentIndex).size() + body(currentIndex).size() + tail(currentIndex).size()); + if ((compressed(currentIndex) == false || (compressed(currentIndex) == true && compressed(currentIndex.parent()) == false)) // Base is meaningful only for true uncompressed items + && currentBase <= base && base < currentBase + fullSize) { // Base must be in range [currentBase, currentBase + fullSize) + // Found a better candidate + parentIndex = currentIndex; + goto goDeeper; + } + } + + return (parentIndex == index(0, 0) ? UModelIndex() : parentIndex); +} diff --git a/common/treemodel.h b/common/treemodel.h index 84ee141..0d6b5ac 100644 --- a/common/treemodel.h +++ b/common/treemodel.h @@ -1,6 +1,6 @@ /* treemodel.h -Copyright (c) 2015, Nikolaj Schlej. All rights reserved. +Copyright (c) 2016, Nikolaj Schlej. All rights reserved. This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -14,12 +14,27 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #ifndef TREEMODEL_H #define TREEMODEL_H +enum ItemFixedState { + Movable, + Fixed +}; + +enum BootGuardMarking { + None = 0, // Needs to be zero + PartiallyInRange, + BootGuardFullyInRange, + VendorFullyInRange +}; + #if defined(QT_CORE_LIB) // Use Qt classes #include #include #include #include +#if defined(QT_GUI_LIB) +#include +#endif #include "ustring.h" #include "ubytearray.h" @@ -29,7 +44,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #define UModelIndex QModelIndex #else -// Use own implementation +// Use own implementation #include "ustring.h" #include "ubytearray.h" #include "basetypes.h" @@ -78,17 +93,18 @@ private: #if defined(QT_CORE_LIB) class TreeModel : public QAbstractItemModel { - Q_OBJECT private: TreeItem *rootItem; + bool markingEnabledFlag; + bool markingDarkModeFlag; public: QVariant data(const UModelIndex &index, int role) const; Qt::ItemFlags flags(const UModelIndex &index) const; QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; - TreeModel(QObject *parent = 0) : QAbstractItemModel(parent) { - rootItem = new TreeItem(Types::Root, 0, UString(), UString(), UString(), UByteArray(), UByteArray(), UByteArray(), TRUE, FALSE, UByteArray()); + TreeModel(QObject *parent = 0) : QAbstractItemModel(parent), markingEnabledFlag(true), markingDarkModeFlag(false) { + rootItem = new TreeItem(0, Types::Root, 0, UString(), UString(), UString(), UByteArray(), UByteArray(), UByteArray(), true, false); } #else @@ -98,6 +114,9 @@ class TreeModel { private: TreeItem *rootItem; + bool markingEnabledFlag; + bool markingDarkModeFlag; + void dataChanged(const UModelIndex &, const UModelIndex &) {} void layoutAboutToBeChanged() {} void layoutChanged() {} @@ -106,8 +125,8 @@ public: UString data(const UModelIndex &index, int role) const; UString headerData(int section, int orientation, int role = 0) const; - TreeModel() { - rootItem = new TreeItem(Types::Root, 0, UString(), UString(), UString(), UByteArray(), UByteArray(), UByteArray(), TRUE, FALSE, UByteArray()); + TreeModel() : markingEnabledFlag(false), markingDarkModeFlag(false) { + rootItem = new TreeItem(0, Types::Root, 0, UString(), UString(), UString(), UByteArray(), UByteArray(), UByteArray(), true, false); } bool hasIndex(int row, int column, const UModelIndex &parent = UModelIndex()) const { @@ -119,52 +138,79 @@ public: UModelIndex createIndex(int row, int column, void *data) const { return UModelIndex(row, column, data, this); } #endif - ~TreeModel() { delete rootItem; } - UModelIndex index(int row, int column, - const UModelIndex &parent = UModelIndex()) const; + bool markingEnabled() { return markingEnabledFlag; } + void setMarkingEnabled(const bool enabled); + + bool markingDarkMode() { return markingDarkModeFlag; } + void setMarkingDarkMode(const bool enabled); + + UModelIndex index(int row, int column, const UModelIndex &parent = UModelIndex()) const; UModelIndex parent(const UModelIndex &index) const; int rowCount(const UModelIndex &parent = UModelIndex()) const; int columnCount(const UModelIndex &parent = UModelIndex()) const; + UINT8 action(const UModelIndex &index) const; void setAction(const UModelIndex &index, const UINT8 action); + + UINT32 base(const UModelIndex &index) const; + UINT32 offset(const UModelIndex &index) const; + void setOffset(const UModelIndex &index, const UINT32 offset); + + UINT8 type(const UModelIndex &index) const; void setType(const UModelIndex &index, const UINT8 type); + + UINT8 subtype(const UModelIndex &index) const; void setSubtype(const UModelIndex &index, const UINT8 subtype); + + UString name(const UModelIndex &index) const; void setName(const UModelIndex &index, const UString &name); + + UString text(const UModelIndex &index) const; void setText(const UModelIndex &index, const UString &text); + + UString info(const UModelIndex &index) const; void setInfo(const UModelIndex &index, const UString &info); - void addInfo(const UModelIndex &index, const UString &info, const bool append = TRUE); - void setParsingData(const UModelIndex &index, const UByteArray &data); + void addInfo(const UModelIndex &index, const UString &info, const bool append = true); + + bool fixed(const UModelIndex &index) const; void setFixed(const UModelIndex &index, const bool fixed); + + bool compressed(const UModelIndex &index) const; void setCompressed(const UModelIndex &index, const bool compressed); - UString name(const UModelIndex &index) const; - UString text(const UModelIndex &index) const; - UString info(const UModelIndex &index) const; - UINT8 type(const UModelIndex &index) const; - UINT8 subtype(const UModelIndex &index) const; + UByteArray uncompressedData(const UModelIndex &index) const; + bool hasEmptyUncompressedData(const UModelIndex &index) const; + void setUncompressedData(const UModelIndex &index, const UByteArray &ucdata); + + UINT8 marking(const UModelIndex &index) const; + void setMarking(const UModelIndex &index, const UINT8 marking); + UByteArray header(const UModelIndex &index) const; bool hasEmptyHeader(const UModelIndex &index) const; + UByteArray body(const UModelIndex &index) const; bool hasEmptyBody(const UModelIndex &index) const; + UByteArray tail(const UModelIndex &index) const; bool hasEmptyTail(const UModelIndex &index) const; + UByteArray parsingData(const UModelIndex &index) const; bool hasEmptyParsingData(const UModelIndex &index) const; - UINT8 action(const UModelIndex &index) const; - bool fixed(const UModelIndex &index) const; - bool compressed(const UModelIndex &index) const; + void setParsingData(const UModelIndex &index, const UByteArray &pdata); - UModelIndex addItem(const UINT8 type, const UINT8 subtype, + UModelIndex addItem(const UINT32 offset, const UINT8 type, const UINT8 subtype, const UString & name, const UString & text, const UString & info, const UByteArray & header, const UByteArray & body, const UByteArray & tail, - const bool fixed, const UByteArray & parsingData = UByteArray(), + const ItemFixedState fixed, const UModelIndex & parent = UModelIndex(), const UINT8 mode = CREATE_MODE_APPEND); UModelIndex findParentOfType(const UModelIndex & index, UINT8 type) const; + UModelIndex findLastParentOfType(const UModelIndex & index, UINT8 type) const; + UModelIndex findByBase(UINT32 base) const; }; #if defined(QT_CORE_LIB) diff --git a/common/types.cpp b/common/types.cpp old mode 100644 new mode 100755 index 4f503d7..3ee9ed1 --- a/common/types.cpp +++ b/common/types.cpp @@ -1,182 +1,288 @@ /* types.cpp - -Copyright (c) 2016, Nikolaj Schlej. All rights reserved. -This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -*/ + + Copyright (c) 2016, Nikolaj Schlej. All rights reserved. + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + */ #include "ustring.h" #include "types.h" #include "ffs.h" -#include "fit.h" +#include "intel_fit.h" UString regionTypeToUString(const UINT8 type) { switch (type) { - case Subtypes::DescriptorRegion: return UString("Descriptor"); - case Subtypes::BiosRegion: return UString("BIOS"); - case Subtypes::MeRegion: return UString("ME"); - case Subtypes::GbeRegion: return UString("GbE"); - case Subtypes::PdrRegion: return UString("PDR"); - case Subtypes::Reserved1Region: return UString("Reserved1"); - case Subtypes::Reserved2Region: return UString("Reserved2"); - case Subtypes::Reserved3Region: return UString("Reserved3"); - case Subtypes::EcRegion: return UString("EC"); - case Subtypes::Reserved4Region: return UString("Reserved4"); + case Subtypes::DescriptorRegion: return UString("Descriptor"); + case Subtypes::BiosRegion: return UString("BIOS"); + case Subtypes::MeRegion: return UString("ME"); + case Subtypes::GbeRegion: return UString("GbE"); + case Subtypes::PdrRegion: return UString("PDR"); + case Subtypes::DevExp1Region: return UString("DevExp1"); + case Subtypes::Bios2Region: return UString("BIOS2"); + case Subtypes::MicrocodeRegion: return UString("Microcode"); + case Subtypes::EcRegion: return UString("EC"); + case Subtypes::DevExp2Region: return UString("DevExp2"); + case Subtypes::IeRegion: return UString("IE"); + case Subtypes::Tgbe1Region: return UString("10GbE1"); + case Subtypes::Tgbe2Region: return UString("10GbE2"); + case Subtypes::Reserved1Region: return UString("Reserved1"); + case Subtypes::Reserved2Region: return UString("Reserved2"); + case Subtypes::PttRegion: return UString("PTT"); }; - - return UString("Unknown"); + + return usprintf("Unknown %02Xh", type); } UString itemTypeToUString(const UINT8 type) { switch (type) { - case Types::Root: return UString("Root"); - case Types::Image: return UString("Image"); - case Types::Capsule: return UString("Capsule"); - case Types::Region: return UString("Region"); - case Types::Volume: return UString("Volume"); - case Types::Padding: return UString("Padding"); - case Types::File: return UString("File"); - case Types::Section: return UString("Section"); - case Types::FreeSpace: return UString("Free space"); - case Types::VssStore: return UString("VSS store"); - case Types::FtwStore: return UString("FTW store"); - case Types::FdcStore: return UString("FDC store"); - case Types::FsysStore: return UString("Fsys store"); - case Types::EvsaStore: return UString("EVSA store"); - case Types::CmdbStore: return UString("CMDB store"); - case Types::FlashMapStore: return UString("FlashMap store"); - case Types::NvarEntry: return UString("NVAR entry"); - case Types::VssEntry: return UString("VSS entry"); - case Types::FsysEntry: return UString("Fsys entry"); - case Types::EvsaEntry: return UString("EVSA entry"); - case Types::FlashMapEntry: return UString("FlashMap entry"); - case Types::Microcode: return UString("Microcode"); - case Types::SlicData: return UString("SLIC data"); + case Types::Root: return UString("Root"); + case Types::Image: return UString("Image"); + case Types::Capsule: return UString("Capsule"); + case Types::Region: return UString("Region"); + case Types::Volume: return UString("Volume"); + case Types::Padding: return UString("Padding"); + case Types::File: return UString("File"); + case Types::Section: return UString("Section"); + case Types::FreeSpace: return UString("Free space"); + case Types::VssStore: return UString("VSS store"); + case Types::Vss2Store: return UString("VSS2 store"); + case Types::FtwStore: return UString("FTW store"); + case Types::FdcStore: return UString("FDC store"); + case Types::SysFStore: return UString("SysF store"); + case Types::EvsaStore: return UString("EVSA store"); + case Types::CmdbStore: return UString("CMDB store"); + case Types::PhoenixFlashMapStore: return UString("FlashMap store"); + case Types::InsydeFlashDeviceMapStore: return UString("FlashDeviceMap store"); + case Types::DellDvarStore: return UString("DVAR store"); + case Types::NvarGuidStore: return UString("NVAR GUID store"); + case Types::NvarEntry: return UString("NVAR entry"); + case Types::VssEntry: return UString("VSS entry"); + case Types::SysFEntry: return UString("SysF entry"); + case Types::EvsaEntry: return UString("EVSA entry"); + case Types::PhoenixFlashMapEntry: return UString("FlashMap entry"); + case Types::InsydeFlashDeviceMapEntry: return UString("FlashDeviceMap entry"); + case Types::DellDvarEntry: return UString("DVAR entry"); + case Types::Microcode: return UString("Microcode"); + case Types::SlicData: return UString("SLIC data"); + case Types::FptStore: return UString("FPT store"); + case Types::FptEntry: return UString("FPT entry"); + case Types::IfwiHeader: return UString("IFWI header"); + case Types::IfwiPartition: return UString("IFWI partition"); + case Types::FptPartition: return UString("FPT partition"); + case Types::BpdtStore: return UString("BPDT store"); + case Types::BpdtEntry: return UString("BPDT entry"); + case Types::BpdtPartition: return UString("BPDT partition"); + case Types::CpdStore: return UString("CPD store"); + case Types::CpdEntry: return UString("CPD entry"); + case Types::CpdPartition: return UString("CPD partition"); + case Types::CpdExtension: return UString("CPD extension"); + case Types::CpdSpiEntry: return UString("CPD SPI entry"); + case Types::StartupApDataEntry: return UString("Startup AP data"); } - - return UString("Unknown"); + + return usprintf("Unknown %02Xh", type); } UString itemSubtypeToUString(const UINT8 type, const UINT8 subtype) { switch (type) { - case Types::Root: - case Types::FreeSpace: - case Types::VssStore: - case Types::FdcStore: - case Types::FsysStore: - case Types::EvsaStore: - case Types::FtwStore: - case Types::FlashMapStore: - case Types::CmdbStore: - case Types::FsysEntry: - case Types::SlicData: return UString(); - case Types::Image: - if (subtype == Subtypes::IntelImage) return UString("Intel"); - if (subtype == Subtypes::UefiImage) return UString("UEFI"); - break; - case Types::Padding: - if (subtype == Subtypes::ZeroPadding) return UString("Empty (0x00)"); - if (subtype == Subtypes::OnePadding) return UString("Empty (0xFF)"); - if (subtype == Subtypes::DataPadding) return UString("Non-empty"); - break; - case Types::Volume: - if (subtype == Subtypes::UnknownVolume) return UString("Unknown"); - if (subtype == Subtypes::Ffs2Volume) return UString("FFSv2"); - if (subtype == Subtypes::Ffs3Volume) return UString("FFSv3"); - if (subtype == Subtypes::NvramVolume) return UString("NVRAM"); - break; - case Types::Capsule: - if (subtype == Subtypes::AptioSignedCapsule) return UString("Aptio signed"); - if (subtype == Subtypes::AptioUnsignedCapsule) return UString("Aptio unsigned"); - if (subtype == Subtypes::UefiCapsule) return UString("UEFI 2.0"); - if (subtype == Subtypes::ToshibaCapsule) return UString("Toshiba"); - break; - case Types::Region: return regionTypeToUString(subtype); - case Types::File: return fileTypeToUString(subtype); - case Types::Section: return sectionTypeToUString(subtype); - case Types::NvarEntry: - if (subtype == Subtypes::InvalidNvarEntry) return UString("Invalid"); - if (subtype == Subtypes::InvalidLinkNvarEntry) return UString("Invalid link"); - if (subtype == Subtypes::LinkNvarEntry) return UString("Link"); - if (subtype == Subtypes::DataNvarEntry) return UString("Data"); - if (subtype == Subtypes::FullNvarEntry) return UString("Full"); - break; - case Types::VssEntry: - if (subtype == Subtypes::InvalidVssEntry) return UString("Invalid"); - if (subtype == Subtypes::StandardVssEntry) return UString("Standard"); - if (subtype == Subtypes::AppleVssEntry) return UString("Apple"); - if (subtype == Subtypes::AuthVssEntry) return UString("Auth"); - break; - case Types::EvsaEntry: - if (subtype == Subtypes::InvalidEvsaEntry) return UString("Invalid"); - if (subtype == Subtypes::UnknownEvsaEntry) return UString("Unknown"); - if (subtype == Subtypes::GuidEvsaEntry) return UString("GUID"); - if (subtype == Subtypes::NameEvsaEntry) return UString("Name"); - if (subtype == Subtypes::DataEvsaEntry) return UString("Data"); - break; - case Types::FlashMapEntry: - if (subtype == Subtypes::VolumeFlashMapEntry) return UString("Volume"); - if (subtype == Subtypes::DataFlashMapEntry) return UString("Data"); - break; - case Types::Microcode: - if (subtype == Subtypes::IntelMicrocode) return UString("Intel"); - if (subtype == Subtypes::AmdMicrocode) return UString("AMD"); - break; + case Types::Image: + if (subtype == Subtypes::IntelImage) return UString("Intel"); + else if (subtype == Subtypes::UefiImage) return UString("UEFI"); + break; + case Types::Padding: + if (subtype == Subtypes::ZeroPadding) return UString("Empty (0x00)"); + else if (subtype == Subtypes::OnePadding) return UString("Empty (0xFF)"); + else if (subtype == Subtypes::DataPadding) return UString("Non-empty"); + break; + case Types::Volume: + if (subtype == Subtypes::UnknownVolume) return UString("Unknown"); + else if (subtype == Subtypes::Ffs2Volume) return UString("FFSv2"); + else if (subtype == Subtypes::Ffs3Volume) return UString("FFSv3"); + else if (subtype == Subtypes::NvramVolume) return UString("NVRAM"); + else if (subtype == Subtypes::MicrocodeVolume) return UString("Microcode"); + break; + case Types::Capsule: + if (subtype == Subtypes::AptioSignedCapsule) return UString("Aptio signed"); + else if (subtype == Subtypes::AptioUnsignedCapsule) return UString("Aptio unsigned"); + else if (subtype == Subtypes::UefiCapsule) return UString("UEFI 2.0"); + else if (subtype == Subtypes::ToshibaCapsule) return UString("Toshiba"); + break; + case Types::Region: return regionTypeToUString(subtype); + case Types::File: return fileTypeToUString(subtype); + case Types::Section: return sectionTypeToUString(subtype); + case Types::NvarEntry: + if (subtype == Subtypes::InvalidNvarEntry) return UString("Invalid"); + else if (subtype == Subtypes::InvalidLinkNvarEntry) return UString("Invalid link"); + else if (subtype == Subtypes::LinkNvarEntry) return UString("Link"); + else if (subtype == Subtypes::DataNvarEntry) return UString("Data"); + else if (subtype == Subtypes::FullNvarEntry) return UString("Full"); + break; + case Types::VssEntry: + if (subtype == Subtypes::InvalidVssEntry) return UString("Invalid"); + else if (subtype == Subtypes::StandardVssEntry) return UString("Standard"); + else if (subtype == Subtypes::AppleVssEntry) return UString("Apple"); + else if (subtype == Subtypes::AuthVssEntry) return UString("Auth"); + else if (subtype == Subtypes::IntelVssEntry) return UString("Intel"); + break; + case Types::SysFEntry: + if (subtype == Subtypes::InvalidSysFEntry) return UString("Invalid"); + else if (subtype == Subtypes::NormalSysFEntry) return UString("Normal"); + break; + case Types::EvsaEntry: + if (subtype == Subtypes::InvalidEvsaEntry) return UString("Invalid"); + else if (subtype == Subtypes::UnknownEvsaEntry) return UString("Unknown"); + else if (subtype == Subtypes::GuidEvsaEntry) return UString("GUID"); + else if (subtype == Subtypes::NameEvsaEntry) return UString("Name"); + else if (subtype == Subtypes::DataEvsaEntry) return UString("Data"); + break; + case Types::PhoenixFlashMapEntry: + if (subtype == Subtypes::VolumeFlashMapEntry) return UString("Volume"); + else if (subtype == Subtypes::DataFlashMapEntry) return UString("Data"); + else if (subtype == Subtypes::UnknownFlashMapEntry) return UString("Unknown"); + break; + case Types::DellDvarEntry: + if (subtype == Subtypes::InvalidDvarEntry) return UString("Invalid"); + else if (subtype == Subtypes::NamespaceGuidDvarEntry) return UString("NamespaceGuid"); + else if (subtype == Subtypes::NameIdDvarEntry) return UString("NameId"); + else if (subtype == Subtypes::UnknownDvarEntry) return UString("Unknown"); + break; + case Types::Microcode: + if (subtype == Subtypes::IntelMicrocode) return UString("Intel"); + else if (subtype == Subtypes::AmdMicrocode) return UString("AMD"); + break; + case Types::FptEntry: + if (subtype == Subtypes::ValidFptEntry) return UString("Valid"); + else if (subtype == Subtypes::InvalidFptEntry) return UString("Invalid"); + break; + case Types::FptPartition: + if (subtype == Subtypes::CodeFptPartition) return UString("Code"); + else if (subtype == Subtypes::DataFptPartition) return UString("Data"); + else if (subtype == Subtypes::GlutFptPartition) return UString("GLUT"); + break; + case Types::IfwiPartition: + if (subtype == Subtypes::BootIfwiPartition) return UString("Boot"); + else if (subtype == Subtypes::DataIfwiPartition) return UString("Data"); + break; + case Types::CpdPartition: + if (subtype == Subtypes::ManifestCpdPartition) return UString("Manifest"); + else if (subtype == Subtypes::MetadataCpdPartition) return UString("Metadata"); + else if (subtype == Subtypes::KeyCpdPartition) return UString("Key"); + else if (subtype == Subtypes::CodeCpdPartition) return UString("Code"); + break; + case Types::StartupApDataEntry: + if (subtype == Subtypes::x86128kStartupApDataEntry) return UString("X86 128K"); + break; } - - return UString("Unknown"); + + return UString(); } UString compressionTypeToUString(const UINT8 algorithm) { switch (algorithm) { - case COMPRESSION_ALGORITHM_NONE: return UString("None"); - case COMPRESSION_ALGORITHM_EFI11: return UString("EFI 1.1"); - case COMPRESSION_ALGORITHM_TIANO: return UString("Tiano"); - case COMPRESSION_ALGORITHM_UNDECIDED: return UString("Undecided Tiano/EFI 1.1"); - case COMPRESSION_ALGORITHM_LZMA: return UString("LZMA"); - case COMPRESSION_ALGORITHM_IMLZMA: return UString("Intel modified LZMA"); + case COMPRESSION_ALGORITHM_NONE: return UString("None"); + case COMPRESSION_ALGORITHM_EFI11: return UString("EFI 1.1"); + case COMPRESSION_ALGORITHM_TIANO: return UString("Tiano"); + case COMPRESSION_ALGORITHM_UNDECIDED: return UString("Undecided Tiano/EFI 1.1"); + case COMPRESSION_ALGORITHM_LZMA: return UString("LZMA"); + case COMPRESSION_ALGORITHM_LZMA_INTEL_LEGACY: return UString("Intel legacy LZMA"); + case COMPRESSION_ALGORITHM_LZMAF86: return UString("LZMAF86"); + case COMPRESSION_ALGORITHM_GZIP: return UString("GZip"); + case COMPRESSION_ALGORITHM_ZLIB: return UString("Zlib"); } - - return UString("Unknown"); + + return usprintf("Unknown %02Xh", algorithm); } UString actionTypeToUString(const UINT8 action) { switch (action) { - case Actions::NoAction: return UString(); - case Actions::Create: return UString("Create"); - case Actions::Insert: return UString("Insert"); - case Actions::Replace: return UString("Replace"); - case Actions::Remove: return UString("Remove"); - case Actions::Rebuild: return UString("Rebuild"); - case Actions::Rebase: return UString("Rebase"); + case Actions::NoAction: return UString(); + case Actions::Create: return UString("Create"); + case Actions::Insert: return UString("Insert"); + case Actions::Replace: return UString("Replace"); + case Actions::Remove: return UString("Remove"); + case Actions::Rebuild: return UString("Rebuild"); + case Actions::Rebase: return UString("Rebase"); } - - return UString("Unknown"); + + return usprintf("Unknown %02Xh", action); } UString fitEntryTypeToUString(const UINT8 type) { switch (type & 0x7F) { - case FIT_TYPE_HEADER: return ("FIT Header"); - case FIT_TYPE_MICROCODE: return ("Microcode"); - case FIT_TYPE_BIOS_AC_MODULE: return ("BIOS ACM"); - case FIT_TYPE_BIOS_INIT_MODULE: return ("BIOS Init"); - case FIT_TYPE_TPM_POLICY: return ("TPM Policy"); - case FIT_TYPE_BIOS_POLICY_DATA: return ("BIOS Policy Data"); - case FIT_TYPE_TXT_CONF_POLICY: return ("TXT Configuration Policy"); - case FIT_TYPE_AC_KEY_MANIFEST: return ("BootGuard Key Manifest"); - case FIT_TYPE_AC_BOOT_POLICY: return ("BootGuard Boot Policy"); - case FIT_TYPE_EMPTY: return ("Empty"); - default: return ("Unknown"); + case INTEL_FIT_TYPE_HEADER: return UString("FIT Header"); + case INTEL_FIT_TYPE_MICROCODE: return UString("Microcode"); + case INTEL_FIT_TYPE_STARTUP_AC_MODULE: return UString("Startup ACM"); + case INTEL_FIT_TYPE_DIAG_AC_MODULE: return UString("Diagnostic ACM"); + case INTEL_FIT_TYPE_PLATFORM_BOOT_POLICY: return UString("Platform Boot Policy"); + case INTEL_FIT_TYPE_FIT_RESET_STATE: return UString("FIT Reset State"); + case INTEL_FIT_TYPE_BIOS_STARTUP_MODULE: return UString("BIOS Startup Module"); + case INTEL_FIT_TYPE_TPM_POLICY: return UString("TPM Policy"); + case INTEL_FIT_TYPE_BIOS_POLICY: return UString("BIOS Policy"); + case INTEL_FIT_TYPE_TXT_POLICY: return UString("TXT Policy"); + case INTEL_FIT_TYPE_BOOT_GUARD_KEY_MANIFEST: return UString("BootGuard Key Manifest"); + case INTEL_FIT_TYPE_BOOT_GUARD_BOOT_POLICY: return UString("BootGuard Boot Policy"); + case INTEL_FIT_TYPE_CSE_SECURE_BOOT: return UString("CSE SecureBoot Settings"); + case INTEL_FIT_TYPE_VAB_PROVISIONING_TABLE: return UString("VAB Provisioning Table"); + case INTEL_FIT_TYPE_VAB_KEY_MANIFEST: return UString("VAB Key Manifest"); + case INTEL_FIT_TYPE_VAB_IMAGE_MANIFEST: return UString("VAB Image Manifest"); + case INTEL_FIT_TYPE_VAB_IMAGE_HASH_DESCRIPTORS: return UString("VAB Image Hash Descriptors"); + case INTEL_FIT_TYPE_SACM_DEBUG_RECORD: return UString("SACM Debug Record"); + case INTEL_FIT_TYPE_ACM_FEATURE_POLICY: return UString("ACM Feature Policy"); + case INTEL_FIT_TYPE_SCRTM_ERROR_RECORD: return UString("SCRTM Error Record"); + case INTEL_FIT_TYPE_JMP_DEBUG_POLICY: return UString("JMP Debug Policy"); + case INTEL_FIT_TYPE_EMPTY: return UString("Empty"); } -} \ No newline at end of file + + return usprintf("Unknown %02Xh", (type & 0x7F)); +} + +UString hashTypeToUString(const UINT16 algorithm_id) +{ + switch (algorithm_id) { + case TCG_HASH_ALGORITHM_ID_SHA1: return UString("SHA1"); + case TCG_HASH_ALGORITHM_ID_SHA256: return UString("SHA256"); + case TCG_HASH_ALGORITHM_ID_SHA384: return UString("SHA384"); + case TCG_HASH_ALGORITHM_ID_SHA512: return UString("SHA512"); + case TCG_HASH_ALGORITHM_ID_NULL: return UString("NULL"); + case TCG_HASH_ALGORITHM_ID_SM3: return UString("SM3"); + } + + return usprintf("Unknown %04Xh", algorithm_id); +} + +UString insydeFlashDeviceMapEntryTypeGuidToUString(const EFI_GUID & guid) +{ + const UByteArray baGuid((const char*)&guid, sizeof(EFI_GUID)); + if (baGuid == INSYDE_FLASH_MAP_REGION_BOOT_FV_GUID) return UString("Boot Firmare Volume"); + if (baGuid == INSYDE_FLASH_MAP_REGION_BVDT_GUID) return UString("BIOS Version Data Table"); + if (baGuid == INSYDE_FLASH_MAP_REGION_EC_GUID) return UString("EC Firmware"); + if (baGuid == INSYDE_FLASH_MAP_REGION_FTW_BACKUP_GUID) return UString("FTW Backup"); + if (baGuid == INSYDE_FLASH_MAP_REGION_FTW_STATE_GUID) return UString("FTW State"); + if (baGuid == INSYDE_FLASH_MAP_REGION_FV_GUID) return UString("Firmare Volume"); + if (baGuid == INSYDE_FLASH_MAP_REGION_FLASH_DEVICE_MAP_GUID) return UString("Flash Device Map"); + if (baGuid == INSYDE_FLASH_MAP_REGION_LOGO_GUID) return UString("Logo"); + if (baGuid == INSYDE_FLASH_MAP_REGION_MICROCODE_GUID) return UString("Microcode"); + if (baGuid == INSYDE_FLASH_MAP_REGION_MSDM_TABLE_GUID) return UString("MSDM Table"); + if (baGuid == INSYDE_FLASH_MAP_REGION_MULTI_CONFIG_GUID) return UString("MultiConfig"); + if (baGuid == INSYDE_FLASH_MAP_REGION_VAR_DEFAULT_GUID) return UString("Variable Defaults"); + if (baGuid == INSYDE_FLASH_MAP_REGION_SMBIOS_UPDATE_GUID) return UString("SMBIOS Update"); + if (baGuid == INSYDE_FLASH_MAP_REGION_VAR_GUID) return UString("Variables"); + if (baGuid == INSYDE_FLASH_MAP_REGION_UNKNOWN_GUID) return UString("Unknown"); + if (baGuid == INSYDE_FLASH_MAP_REGION_UNUSED_GUID) return UString("Unused"); + if (baGuid == INSYDE_FLASH_MAP_REGION_USB_OPTION_ROM_GUID) return UString("USB Option ROM"); + if (baGuid == INSYDE_FLASH_MAP_REGION_DXE_FV_GUID) return UString("DXE Firmare Volume"); + if (baGuid == INSYDE_FLASH_MAP_REGION_PEI_FV_GUID) return UString("PEI Firmare Volume"); + if (baGuid == INSYDE_FLASH_MAP_REGION_UNSIGNED_FV_GUID) return UString("Unsigned Firmare Volume"); + return guidToUString(guid); +} diff --git a/common/types.h b/common/types.h old mode 100644 new mode 100755 index 8480dbe..e82d4bd --- a/common/types.h +++ b/common/types.h @@ -27,7 +27,7 @@ namespace Actions Replace, Remove, Rebuild, - Rebase + Rebase, }; } @@ -44,40 +44,61 @@ namespace Types { Section, FreeSpace, VssStore, + Vss2Store, FtwStore, FdcStore, - FsysStore, + SysFStore, EvsaStore, - FlashMapStore, + PhoenixFlashMapStore, + InsydeFlashDeviceMapStore, + DellDvarStore, CmdbStore, + NvarGuidStore, NvarEntry, VssEntry, - FsysEntry, + SysFEntry, EvsaEntry, - FlashMapEntry, + PhoenixFlashMapEntry, + InsydeFlashDeviceMapEntry, + DellDvarEntry, Microcode, SlicData, + IfwiHeader, + IfwiPartition, + FptStore, + FptEntry, + FptPartition, + BpdtStore, + BpdtEntry, + BpdtPartition, + CpdStore, + CpdEntry, + CpdPartition, + CpdExtension, + CpdSpiEntry, + StartupApDataEntry, }; } namespace Subtypes { enum ImageSubtypes{ IntelImage = 90, - UefiImage + UefiImage, }; enum CapsuleSubtypes { AptioSignedCapsule = 100, AptioUnsignedCapsule, UefiCapsule, - ToshibaCapsule + ToshibaCapsule, }; enum VolumeSubtypes { UnknownVolume = 110, Ffs2Volume, Ffs3Volume, - NvramVolume + NvramVolume, + MicrocodeVolume, }; enum RegionSubtypes { @@ -86,17 +107,23 @@ namespace Subtypes { MeRegion, GbeRegion, PdrRegion, + DevExp1Region, + Bios2Region, + MicrocodeRegion, + EcRegion, + DevExp2Region, + IeRegion, + Tgbe1Region, + Tgbe2Region, Reserved1Region, Reserved2Region, - Reserved3Region, - EcRegion, - Reserved4Region + PttRegion, }; enum PaddingSubtypes { ZeroPadding = 120, OnePadding, - DataPadding + DataPadding, }; enum NvarEntrySubtypes { @@ -104,18 +131,24 @@ namespace Subtypes { InvalidLinkNvarEntry, LinkNvarEntry, DataNvarEntry, - FullNvarEntry + FullNvarEntry, }; enum VssEntrySubtypes { InvalidVssEntry = 140, StandardVssEntry, AppleVssEntry, - AuthVssEntry + AuthVssEntry, + IntelVssEntry, }; + enum SysFEntrySubtypes { + InvalidSysFEntry = 150, + NormalSysFEntry, + }; + enum EvsaEntrySubtypes { - InvalidEvsaEntry = 150, + InvalidEvsaEntry = 160, UnknownEvsaEntry, GuidEvsaEntry, NameEvsaEntry, @@ -123,20 +156,56 @@ namespace Subtypes { }; enum FlashMapEntrySubtypes { - VolumeFlashMapEntry = 160, - DataFlashMapEntry + VolumeFlashMapEntry = 170, + DataFlashMapEntry, + UnknownFlashMapEntry, + }; + + enum DvarEntrySubtypes { + InvalidDvarEntry = 180, + NamespaceGuidDvarEntry, + NameIdDvarEntry, + UnknownDvarEntry }; enum MicrocodeSubtypes { - IntelMicrocode = 170, - AmdMicrocode + IntelMicrocode = 190, + AmdMicrocode, }; enum SlicDataSubtypes { - PubkeySlicData = 180, - MarkerSlicData + PubkeySlicData = 200, + MarkerSlicData, }; -}; + + // ME-specific + enum IfwiPartitionSubtypes { + DataIfwiPartition = 210, + BootIfwiPartition, + }; + + enum FptEntrySubtypes { + ValidFptEntry = 220, + InvalidFptEntry, + }; + + enum FptPartitionSubtypes { + CodeFptPartition = 230, + DataFptPartition, + GlutFptPartition, + }; + + enum CpdPartitionSubtypes { + ManifestCpdPartition = 240, + MetadataCpdPartition, + KeyCpdPartition, + CodeCpdPartition, + }; + + enum StartupApDataEntrySubtypes { + x86128kStartupApDataEntry = 250, + }; +} // *ToUString conversion routines extern UString actionTypeToUString(const UINT8 action); @@ -145,5 +214,7 @@ extern UString itemSubtypeToUString(const UINT8 type, const UINT8 subtype); extern UString compressionTypeToUString(const UINT8 algorithm); extern UString regionTypeToUString(const UINT8 type); extern UString fitEntryTypeToUString(const UINT8 type); +extern UString hashTypeToUString(const UINT16 digest_agorithm_id); +extern UString insydeFlashDeviceMapEntryTypeGuidToUString(const EFI_GUID & guid); #endif // TYPES_H diff --git a/common/ubytearray.h b/common/ubytearray.h index 82a6ff3..1623403 100644 --- a/common/ubytearray.h +++ b/common/ubytearray.h @@ -32,6 +32,7 @@ public: UByteArray(const std::basic_string & bs) : d(bs) {} UByteArray(const std::vector & bc) : d(bc.data(), bc.size()) {} UByteArray(const char* bytes, int32_t size) : d(bytes, size) {} + UByteArray(const size_t n, char c) : d(n, c) {} ~UByteArray() {} bool isEmpty() const { return d.length() == 0; } @@ -41,22 +42,34 @@ public: const char* constData() const { return d.c_str(); } void clear() { d.clear(); } - int32_t size() const { return d.size(); } - int32_t count(char ch) const { return std::count(d.begin(), d.end(), ch); } + UByteArray toUpper() { std::basic_string s = d; std::transform(s.begin(), s.end(), s.begin(), ::toupper); return UByteArray(s); } + uint32_t toUInt(bool* ok = NULL, const uint8_t base = 10) { return (uint32_t)strtoul(d.c_str(), NULL, base); } + + int32_t size() const { return (int32_t)d.size(); } + int32_t count(char ch) const { return (int32_t)std::count(d.begin(), d.end(), ch); } char at(uint32_t i) const { return d.at(i); } char operator[](uint32_t i) const { return d[i]; } char& operator[](uint32_t i) { return d[i]; } bool startsWith(const UByteArray & ba) const { return 0 == d.find(ba.d, 0); } - int indexOf(const UByteArray & ba, int from = 0) const { return d.find(ba.d, from); } - int lastIndexOf(const UByteArray & ba, int from = 0) const { return d.rfind(ba.d, from); } + int indexOf(const UByteArray & ba, int from = 0) const { return (int)d.find(ba.d, from); } + int lastIndexOf(const UByteArray & ba, int from = 0) const { + size_t old_index = d.npos; + size_t index = d.find(ba.d, from); + while (index != d.npos) { + old_index = index; + index = d.find(ba.d, index + 1); + } + return (int)old_index; + } UByteArray left(int32_t len) const { return d.substr(0, len); } - UByteArray right(int32_t len) const { return d.substr(d.size() - 1 - len, len); }; - UByteArray mid(int32_t pos, int32_t len = -1) const { return d.substr(pos, len); }; + UByteArray right(int32_t len) const { return d.substr(d.size() - len, len); } + UByteArray mid(int32_t pos, int32_t len = -1) const { return d.substr(pos, len); } UByteArray & operator=(const UByteArray & ba) { d = ba.d; return *this; } UByteArray & operator+=(const UByteArray & ba) { d += ba.d; return *this; } + UByteArray & operator+=(const char c) { d += c; return *this; } bool operator== (const UByteArray & ba) const { return d == ba.d; } bool operator!= (const UByteArray & ba) const { return d != ba.d; } inline void swap(UByteArray &other) { std::swap(d, other.d); } @@ -65,15 +78,19 @@ public: for (int32_t i = 0; i < size(); i++) { uint8_t low = d[i] & 0x0F; uint8_t high = (d[i] & 0xF0) >> 4; - low += (low < 10 ? '0' : 'a'); - high += (high < 10 ? '0' : 'a'); - hex[2*i] = low; - hex[2*i + 1] = high; + low += (low < 10 ? '0' : 'a' - 10); + high += (high < 10 ? '0' : 'a' - 10); + hex[2*i] = high; + hex[2*i + 1] = low; } - std::reverse(hex.begin(), hex.end()); return UByteArray(hex); } + std::basic_string::iterator begin() {return d.begin();} + std::basic_string::iterator end() {return d.end();} + std::basic_string::const_iterator begin() const {return d.begin();} + std::basic_string::const_iterator end() const {return d.end();} + private: std::basic_string d; }; @@ -84,4 +101,5 @@ inline const UByteArray operator+(const UByteArray &a1, const UByteArray &a2) } #endif // QT_CORE_LIB -#endif // UBYTEARRAY_H \ No newline at end of file +#endif // UBYTEARRAY_H + diff --git a/common/umemstream.h b/common/umemstream.h new file mode 100644 index 0000000..243b5c2 --- /dev/null +++ b/common/umemstream.h @@ -0,0 +1,58 @@ +/* umemstream.h + + Copyright (c) 2023, Nikolaj Schlej. All rights reserved. + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + */ + +#ifndef UMEMSTREAM_H +#define UMEMSTREAM_H + +#include + +// NOTE: this implementation is certainly not a valid replacement to std::stringstream +// NOTE: because it only supports getting through the buffer once +// NOTE: however, we already do it this way, so it's enough for practical purposes + +class umembuf : public std::streambuf { +public: + umembuf(const char *p, size_t l) { + setg((char*)p, (char*)p, (char*)p + l); + } + + pos_type seekoff(off_type off, std::ios_base::seekdir dir, std::ios_base::openmode which = std::ios_base::in) override + { + (void)which; + if (dir == std::ios_base::cur) + gbump((int)off); + else if (dir == std::ios_base::end) + setg(eback(), egptr() + off, egptr()); + else if (dir == std::ios_base::beg) + setg(eback(), eback() + off, egptr()); + return gptr() - eback(); + } + + pos_type seekpos(pos_type sp, std::ios_base::openmode which) override + { + return seekoff(sp - pos_type(off_type(0)), std::ios_base::beg, which); + } +}; + +class umemstream : public std::istream { +public: + umemstream(const char *p, size_t l) : std::istream(&buffer_), + buffer_(p, l) { + rdbuf(&buffer_); + } + +private: + umembuf buffer_; +}; + +#endif // UMEMSTREAM_H diff --git a/common/ustring.cpp b/common/ustring.cpp index 6591d26..2493a41 100644 --- a/common/ustring.cpp +++ b/common/ustring.cpp @@ -1,25 +1,29 @@ /* ustring.cpp - -Copyright (c) 2016, Nikolaj Schlej. All rights reserved. -This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -*/ + + Copyright (c) 2016, Nikolaj Schlej. All rights reserved. + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + */ #include "ustring.h" +#include +#include #include #if defined(QT_CORE_LIB) -UString usprintf(const char* fmt, ...) +UString usprintf(const char* fmt, ...) { UString msg; va_list vl; va_start(vl, fmt); - msg.vsprintf(fmt, vl); + + msg = msg.vasprintf(fmt, vl); + va_end(vl); return msg; }; @@ -35,16 +39,16 @@ UString urepeated(char c, int len) #else #ifdef BSTRLIB_NOVSNP /* This is just a hack. If you are using a system without a vsnprintf, it is -not recommended that bformat be used at all. */ + not recommended that bformat be used at all. */ #define exvsnprintf(r,b,n,f,a) {vsprintf (b,f,a); r = -1;} #define START_VSNBUFF (256) #else -#if defined (__GNUC__) && !defined (__PPC__) +#if defined (__GNUC__) && !defined (__PPC__) && !defined(__WIN32__) /* Something is making gcc complain about this prototype not being here, so -I've just gone ahead and put it in. */ + I've just gone ahead and put it in. */ extern "C" { - extern int vsnprintf(char *buf, size_t count, const char *format, va_list arg); +extern int vsnprintf(char *buf, size_t count, const char *format, va_list arg); } #endif @@ -62,12 +66,12 @@ UString usprintf(const char* fmt, ...) bstring b; va_list arglist; int r, n; - + if (fmt == NULL) { msg = ""; } else { - + if ((b = bfromcstr("")) == NULL) { msg = ""; } @@ -78,14 +82,14 @@ UString usprintf(const char* fmt, ...) b = bformat(""); break; } - + va_start(arglist, fmt); exvsnprintf(r, (char *)b->data, n + 1, fmt, arglist); va_end(arglist); - + b->data[n] = '\0'; b->slen = (int)(strlen)((char *)b->data); - + if (b->slen < n) break; if (r > n) n = r; else n += n; } @@ -93,7 +97,7 @@ UString usprintf(const char* fmt, ...) bdestroy(b); } } - + return msg; } @@ -102,3 +106,17 @@ UString urepeated(char c, int len) return UString(c, len); } #endif + +UString uFromUcs2(const char* str, size_t max_len) +{ + // Naive implementation assuming that only ASCII LE part of UCS2 is used, str may not be aligned. + UString msg; + const char *str8 = str; + size_t rest = (max_len == 0) ? SIZE_MAX : max_len; + while (str8[0] && rest) { + msg += str8[0]; + str8 += 2; + rest--; + } + return msg; +} diff --git a/common/ustring.h b/common/ustring.h index f304db6..c143df4 100644 --- a/common/ustring.h +++ b/common/ustring.h @@ -21,11 +21,18 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #else // Use Bstrlib #define BSTRLIB_DOESNT_THROW_EXCEPTIONS -#include "../bstrlib/bstrwrap.h" +#include "bstrlib/bstrwrap.h" #define UString CBString #endif // QT_CORE_LIB -UString usprintf(const char* fmt, ...); +#if defined(__clang__) || defined(__GNUC__) +#define ATTRIBUTE_FORMAT_(t,f,a) __attribute__((format(t, f, a))) +#else +#define ATTRIBUTE_FORMAT_(t,f,a) +#endif + +UString usprintf(const char* fmt, ...) ATTRIBUTE_FORMAT_(printf, 1, 2); UString urepeated(char c, int len); +UString uFromUcs2(const char* str, size_t max_len = 0); #endif // USTRING_H diff --git a/common/utility.cpp b/common/utility.cpp old mode 100644 new mode 100755 index a678200..612f3da --- a/common/utility.cpp +++ b/common/utility.cpp @@ -1,15 +1,19 @@ /* utility.cpp + + Copyright (c) 2016, Nikolaj Schlej. All rights reserved. + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + */ -Copyright (c) 2016, Nikolaj Schlej. All rights reserved. -This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -*/ +#include +#include +#include #include "treemodel.h" #include "utility.h" @@ -19,29 +23,43 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include "LZMA/LzmaCompress.h" #include "LZMA/LzmaDecompress.h" -// Returns either new parsing data instance or obtains it from index -PARSING_DATA parsingDataFromUModelIndex(const UModelIndex & index) +// Returns bytes as string when all bytes are ascii visible, hex representation otherwise +UString visibleAsciiOrHex(UINT8* bytes, UINT32 length) { - if (index.isValid()) { - TreeModel* model = (TreeModel*)index.model(); - if (!model->hasEmptyParsingData(index)) - return *(PARSING_DATA*)model->parsingData(index).data(); + bool ascii = true; + UString asciiString; + UString hexString; + + for (UINT32 i = 0; i < length; i++) { + hexString += usprintf("%02X", bytes[i]); + + if (ascii && i > 0 && bytes[i] == '\x00') { // Check for the rest of the buffer being zeroes, and make the whole previous string visible, if so + for (UINT32 j = i + 1; j < length; j++) { + if (bytes[j] != '\x00') { + ascii = false; + break; + } + } + + if (ascii) { + // No need to continue iterating over every symbol, we did it already + break; + } + } + else if (bytes[i] < '\x20' || bytes[i] > '\x7E') { // Explicit ascii codes to avoid locale dependency + ascii = false; + } + + if (ascii) { + asciiString += usprintf("%c", bytes[i]); + } } - - PARSING_DATA data; - data.offset = 0; - data.address = 0; - data.ffsVersion = 0; // Unknown by default - data.emptyByte = 0xFF; // Default value for SPI flash - - // Type-specific parts remain unitialized - return data; -} - -// Converts parsing data to byte array -UByteArray parsingDataToUByteArray(const PARSING_DATA & pdata) -{ - return UByteArray((const char*)&pdata, sizeof(PARSING_DATA)); + + if (ascii) { + return asciiString; + } + + return hexString; } // Returns unique name string based for tree item @@ -49,162 +67,136 @@ UString uniqueItemName(const UModelIndex & index) { // Sanity check if (!index.isValid()) - return UString("Invalid index"); - + return UString("InvalidIndex"); + // Get model from index const TreeModel* model = (const TreeModel*)index.model(); - - // Get data from parsing data - PARSING_DATA pdata = parsingDataFromUModelIndex(index); // Construct the name UString itemName = model->name(index); UString itemText = model->text(index); - + // Default name UString name = itemName; switch (model->type(index)) { - case Types::Volume: - if (pdata.volume.hasExtendedHeader) name = guidToUString(pdata.volume.extendedHeaderGuid); - break; - case Types::NvarEntry: - case Types::VssEntry: - case Types::FsysEntry: - case Types::EvsaEntry: - case Types::FlashMapEntry: - case Types::File: - name = itemText.isEmpty() ? itemName : itemName + '_' + itemText; - break; - case Types::Section: { - // Get parent file name - UModelIndex fileIndex = model->findParentOfType(index, Types::File); - UString fileText = model->text(fileIndex); - name = fileText.isEmpty() ? model->name(fileIndex) : model->name(fileIndex) + '_' + fileText; + case Types::NvarEntry: + case Types::VssEntry: + case Types::SysFEntry: + case Types::EvsaEntry: + case Types::PhoenixFlashMapEntry: + case Types::InsydeFlashDeviceMapEntry: + case Types::File: + name = itemText.isEmpty() ? itemName : itemName + '_' + itemText; + break; + case Types::Section: { + // Get parent file name + UModelIndex fileIndex = model->findParentOfType(index, Types::File); + UString fileText = model->text(fileIndex); + name = fileText.isEmpty() ? model->name(fileIndex) : model->name(fileIndex) + '_' + fileText; + + // Special case of GUIDed sections + if (model->subtype(index) == EFI_SECTION_GUID_DEFINED || model->subtype(index) == EFI_SECTION_FREEFORM_SUBTYPE_GUID) { + name = model->name(index) +'_' + name; + } } break; } - + + // Populate subtypeString UString subtypeString = itemSubtypeToUString(model->type(index), model->subtype(index)); + + // Create final name name = itemTypeToUString(model->type(index)) - + (subtypeString.length() ? ('_' + subtypeString) : UString()) - + '_' + name; - - name.findreplace(' ', '_'); - name.findreplace('/', '_'); - name.findreplace('-', '_'); - + + (subtypeString.length() ? ('_' + subtypeString) : UString()) + + '_' + name; + + fixFileName(name, true); + return name; } -// Returns text representation of error code -UString errorCodeToUString(UINT8 errorCode) +// Makes the name usable as a file name +void fixFileName(UString &name, bool replaceSpaces) { - switch (errorCode) { - case U_SUCCESS: return UString("Success"); - case U_NOT_IMPLEMENTED: return UString("Not implemented"); - case U_INVALID_PARAMETER: return UString("Function called with invalid parameter"); - case U_BUFFER_TOO_SMALL: return UString("Buffer too small"); - case U_OUT_OF_RESOURCES: return UString("Out of resources"); - case U_OUT_OF_MEMORY: return UString("Out of memory"); - case U_FILE_OPEN: return UString("File can't be opened"); - case U_FILE_READ: return UString("File can't be read"); - case U_FILE_WRITE: return UString("File can't be written"); - case U_ITEM_NOT_FOUND: return UString("Item not found"); - case U_UNKNOWN_ITEM_TYPE: return UString("Unknown item type"); - case U_INVALID_FLASH_DESCRIPTOR: return UString("Invalid flash descriptor"); - case U_INVALID_REGION: return UString("Invalid region"); - case U_EMPTY_REGION: return UString("Empty region"); - case U_BIOS_REGION_NOT_FOUND: return UString("BIOS region not found"); - case U_VOLUMES_NOT_FOUND: return UString("UEFI volumes not found"); - case U_INVALID_VOLUME: return UString("Invalid UEFI volume"); - case U_VOLUME_REVISION_NOT_SUPPORTED: return UString("Volume revision not supported"); - //case U_VOLUME_GROW_FAILED: return UString("Volume grow failed"); - case U_UNKNOWN_FFS: return UString("Unknown file system"); - case U_INVALID_FILE: return UString("Invalid file"); - case U_INVALID_SECTION: return UString("Invalid section"); - case U_UNKNOWN_SECTION: return UString("Unknown section"); - case U_STANDARD_COMPRESSION_FAILED: return UString("Standard compression failed"); - case U_CUSTOMIZED_COMPRESSION_FAILED: return UString("Customized compression failed"); - case U_STANDARD_DECOMPRESSION_FAILED: return UString("Standard decompression failed"); - case U_CUSTOMIZED_DECOMPRESSION_FAILED: return UString("Customized decompression failed"); - case U_UNKNOWN_COMPRESSION_TYPE: return UString("Unknown compression type"); - case U_UNKNOWN_EXTRACT_MODE: return UString("Unknown extract mode"); - case U_UNKNOWN_REPLACE_MODE: return UString("Unknown replace mode"); - //case U_UNKNOWN_INSERT_MODE: return UString("Unknown insert mode"); - case U_UNKNOWN_IMAGE_TYPE: return UString("Unknown executable image type"); - case U_UNKNOWN_PE_OPTIONAL_HEADER_TYPE: return UString("Unknown PE optional header type"); - case U_UNKNOWN_RELOCATION_TYPE: return UString("Unknown relocation type"); - //case U_GENERIC_CALL_NOT_SUPPORTED: return UString("Generic call not supported"); - //case U_VOLUME_BASE_NOT_FOUND: return UString("Volume base address not found"); - //case U_PEI_CORE_ENTRY_POINT_NOT_FOUND: return UString("PEI core entry point not found"); - case U_COMPLEX_BLOCK_MAP: return UString("Block map structure too complex for correct analysis"); - case U_DIR_ALREADY_EXIST: return UString("Directory already exists"); - case U_DIR_CREATE: return UString("Directory can't be created"); - case U_DIR_CHANGE: return UString("Change directory failed"); - //case U_UNKNOWN_PATCH_TYPE: return UString("Unknown patch type"); - //case U_PATCH_OFFSET_OUT_OF_BOUNDS: return UString("Patch offset out of bounds"); - //case U_INVALID_SYMBOL: return UString("Invalid symbol"); - //case U_NOTHING_TO_PATCH: return UString("Nothing to patch"); - case U_DEPEX_PARSE_FAILED: return UString("Dependency expression parsing failed"); - case U_TRUNCATED_IMAGE: return UString("Image is truncated"); - case U_INVALID_CAPSULE: return UString("Invalid capsule"); - case U_STORES_NOT_FOUND: return UString("Stores not found"); - default: return usprintf("Unknown error %02X", errorCode); + // Replace some symbols with underscores for compatibility + const char table[] = { + '/', // Banned in *nix and Windows + '<', '>', ':', '\"', '\\', '|', '?', '*', // Banned in Windows + }; + int nameLength = (int)name.length(); // Note: Qt uses int for whatever reason. + for (int i = 0; i < nameLength; i++) { + if ( + name[i] < (char)0x20 || // ASCII control characters, banned in Windows, hard to work with in *nix + name[i] > (char)0x7f || // high ASCII characters + (replaceSpaces && name[i] == ' ') // Provides better readability + ) { + name[i] = '_'; + continue; + } + for (size_t j = 0; j < sizeof(table); j++) { + if (name[i] == table[j]) { + name[i] = '_'; + break; + } + } + } + if (!nameLength) { + name = "_"; } } -// CRC32 implementation -UINT32 crc32(UINT32 initial, const UINT8* buffer, const UINT32 length) +// Returns text representation of error code +UString errorCodeToUString(USTATUS errorCode) { - static const UINT32 crcTable[256] = { - 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, - 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, - 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, - 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, - 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, - 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C, - 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 0x26D930AC, - 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, - 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, - 0xB6662D3D, 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, - 0x9FBFE4A5, 0xE8B8D433, 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, - 0x086D3D2D, 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, - 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, - 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, 0x4DB26158, 0x3AB551CE, - 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, - 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, - 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, - 0xCE61E49F, 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, - 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, - 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, - 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, 0xF00F9344, 0x8708A3D2, 0x1E01F268, - 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, - 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, - 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, - 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, - 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, - 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, - 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, - 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, - 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242, - 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, 0x88085AE6, - 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, - 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, - 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, - 0x47B2CF7F, 0x30B5FFE9, 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, - 0xCDD70693, 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, - 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D }; - - // Accumulate crc32 for buffer - UINT32 crc32 = initial ^ 0xFFFFFFFF; - for (UINT32 i = 0; i < length; i++) { - crc32 = (crc32 >> 8) ^ crcTable[(crc32 ^ buffer[i]) & 0xFF]; + // TODO: improve + switch (errorCode) { + case U_SUCCESS: return UString("Success"); + case U_NOT_IMPLEMENTED: return UString("Not implemented"); + case U_INVALID_PARAMETER: return UString("Function called with invalid parameter"); + case U_BUFFER_TOO_SMALL: return UString("Buffer too small"); + case U_OUT_OF_RESOURCES: return UString("Out of resources"); + case U_OUT_OF_MEMORY: return UString("Out of memory"); + case U_FILE_OPEN: return UString("File can't be opened"); + case U_FILE_READ: return UString("File can't be read"); + case U_FILE_WRITE: return UString("File can't be written"); + case U_ITEM_NOT_FOUND: return UString("Item not found"); + case U_UNKNOWN_ITEM_TYPE: return UString("Unknown item type"); + case U_INVALID_FLASH_DESCRIPTOR: return UString("Invalid flash descriptor"); + case U_INVALID_REGION: return UString("Invalid region"); + case U_EMPTY_REGION: return UString("Empty region"); + case U_BIOS_REGION_NOT_FOUND: return UString("BIOS region not found"); + case U_VOLUMES_NOT_FOUND: return UString("UEFI volumes not found"); + case U_INVALID_VOLUME: return UString("Invalid UEFI volume"); + case U_VOLUME_REVISION_NOT_SUPPORTED: return UString("Volume revision not supported"); + case U_UNKNOWN_FFS: return UString("Unknown file system"); + case U_INVALID_FILE: return UString("Invalid file"); + case U_INVALID_SECTION: return UString("Invalid section"); + case U_UNKNOWN_SECTION: return UString("Unknown section"); + case U_STANDARD_COMPRESSION_FAILED: return UString("Standard compression failed"); + case U_CUSTOMIZED_COMPRESSION_FAILED: return UString("Customized compression failed"); + case U_STANDARD_DECOMPRESSION_FAILED: return UString("Standard decompression failed"); + case U_CUSTOMIZED_DECOMPRESSION_FAILED: return UString("Customized decompression failed"); + case U_UNKNOWN_COMPRESSION_TYPE: return UString("Unknown compression type"); + case U_UNKNOWN_EXTRACT_MODE: return UString("Unknown extract mode"); + case U_UNKNOWN_REPLACE_MODE: return UString("Unknown replace mode"); + case U_UNKNOWN_IMAGE_TYPE: return UString("Unknown executable image type"); + case U_UNKNOWN_PE_OPTIONAL_HEADER_TYPE: return UString("Unknown PE optional header type"); + case U_UNKNOWN_RELOCATION_TYPE: return UString("Unknown relocation type"); + case U_COMPLEX_BLOCK_MAP: return UString("Block map structure too complex for correct analysis"); + case U_DIR_ALREADY_EXIST: return UString("Directory already exists"); + case U_DIR_CREATE: return UString("Directory can't be created"); + case U_DIR_CHANGE: return UString("Change directory failed"); + case U_DEPEX_PARSE_FAILED: return UString("Dependency expression parsing failed"); + case U_TRUNCATED_IMAGE: return UString("Image is truncated"); + case U_INVALID_CAPSULE: return UString("Invalid capsule"); + case U_STORES_NOT_FOUND: return UString("Stores not found"); + case U_INVALID_STORE_SIZE: return UString("Invalid store size"); + case U_INVALID_STORE: return UString("Invalid store"); + default: return usprintf("Unknown error %02lX", errorCode); } - - return(crc32 ^ 0xFFFFFFFF); } // Compression routines -USTATUS decompress(const UByteArray & compressedData, UINT8 & algorithm, UByteArray & decompressedData, UByteArray & efiDecompressedData) +USTATUS decompress(const UByteArray & compressedData, const UINT8 compressionType, UINT8 & algorithm, UINT32 & dictionarySize, UByteArray & decompressedData, UByteArray & efiDecompressedData) { const UINT8* data; UINT32 dataSize; @@ -214,135 +206,191 @@ USTATUS decompress(const UByteArray & compressedData, UINT8 & algorithm, UByteAr UINT8* scratch; UINT32 scratchSize = 0; const EFI_TIANO_HEADER* header; - - switch (algorithm) + + // For all but LZMA dictionary size is 0 + dictionarySize = 0; + + switch (compressionType) { - case EFI_NOT_COMPRESSED: - decompressedData = compressedData; - algorithm = COMPRESSION_ALGORITHM_NONE; - return U_SUCCESS; - case EFI_STANDARD_COMPRESSION: { - // Set default algorithm to unknown - algorithm = COMPRESSION_ALGORITHM_UNKNOWN; - - // Get buffer sizes - data = (UINT8*)compressedData.data(); - dataSize = compressedData.size(); - - // Check header to be valid - header = (const EFI_TIANO_HEADER*)data; - if (header->CompSize + sizeof(EFI_TIANO_HEADER) != dataSize) - return U_STANDARD_DECOMPRESSION_FAILED; - - // Get info function is the same for both algorithms - if (U_SUCCESS != EfiTianoGetInfo(data, dataSize, &decompressedSize, &scratchSize)) - return U_STANDARD_DECOMPRESSION_FAILED; - - // Allocate memory - decompressed = (UINT8*)malloc(decompressedSize); - efiDecompressed = (UINT8*)malloc(decompressedSize); - scratch = (UINT8*)malloc(scratchSize); - if (!decompressed || !efiDecompressed || !scratch) { - if (decompressed) free(decompressed); - if (efiDecompressed) free(efiDecompressed); - if (scratch) free(scratch); - return U_STANDARD_DECOMPRESSION_FAILED; + case EFI_NOT_COMPRESSED: { + decompressedData = compressedData; + algorithm = COMPRESSION_ALGORITHM_NONE; + return U_SUCCESS; } - - // Decompress section data using both algorithms - USTATUS result = U_SUCCESS; - // Try Tiano - USTATUS TianoResult = TianoDecompress(data, dataSize, decompressed, decompressedSize, scratch, scratchSize); - // Try EFI 1.1 - USTATUS EfiResult = EfiDecompress(data, dataSize, efiDecompressed, decompressedSize, scratch, scratchSize); - - if (EfiResult == U_SUCCESS && TianoResult == U_SUCCESS) { // Both decompressions are OK - algorithm = COMPRESSION_ALGORITHM_UNDECIDED; - decompressedData = UByteArray((const char*)decompressed, decompressedSize); - efiDecompressedData = UByteArray((const char*)efiDecompressed, decompressedSize); - } - else if (TianoResult == U_SUCCESS) { // Only Tiano is OK - algorithm = COMPRESSION_ALGORITHM_TIANO; - decompressedData = UByteArray((const char*)decompressed, decompressedSize); - } - else if (EfiResult == U_SUCCESS) { // Only EFI 1.1 is OK - algorithm = COMPRESSION_ALGORITHM_EFI11; - decompressedData = UByteArray((const char*)efiDecompressed, decompressedSize); - } - else { // Both decompressions failed - result = U_STANDARD_DECOMPRESSION_FAILED; - } - - free(decompressed); - free(efiDecompressed); - free(scratch); - return result; - } - case EFI_CUSTOMIZED_COMPRESSION: - // Set default algorithm to unknown - algorithm = COMPRESSION_ALGORITHM_UNKNOWN; - - // Get buffer sizes - data = (const UINT8*)compressedData.constData(); - dataSize = compressedData.size(); - - // Get info - if (U_SUCCESS != LzmaGetInfo(data, dataSize, &decompressedSize)) - return U_CUSTOMIZED_DECOMPRESSION_FAILED; - - // Allocate memory - decompressed = (UINT8*)malloc(decompressedSize); - if (!decompressed) { - return U_STANDARD_DECOMPRESSION_FAILED; - } - - // Decompress section data - if (U_SUCCESS != LzmaDecompress(data, dataSize, decompressed)) { - // Intel modified LZMA workaround - // Decompress section data once again - data += sizeof(UINT32); - - // Get info again - if (U_SUCCESS != LzmaGetInfo(data, dataSize, &decompressedSize)) { + case EFI_STANDARD_COMPRESSION: { + // Set default algorithm to unknown + algorithm = COMPRESSION_ALGORITHM_UNKNOWN; + + // Get buffer sizes + data = (UINT8*)compressedData.data(); + dataSize = (UINT32)compressedData.size(); + + // Check header to be valid + header = (const EFI_TIANO_HEADER*)data; + if (header->CompSize + sizeof(EFI_TIANO_HEADER) != dataSize) + return U_STANDARD_DECOMPRESSION_FAILED; + + // Get info function is the same for both algorithms + if (U_SUCCESS != EfiTianoGetInfo(data, dataSize, &decompressedSize, &scratchSize)) + return U_STANDARD_DECOMPRESSION_FAILED; + + // Allocate memory + decompressed = (UINT8*)malloc(decompressedSize); + efiDecompressed = (UINT8*)malloc(decompressedSize); + scratch = (UINT8*)malloc(scratchSize); + if (!decompressed || !efiDecompressed || !scratch) { free(decompressed); - return U_CUSTOMIZED_DECOMPRESSION_FAILED; + free(efiDecompressed); + free(scratch); + return U_STANDARD_DECOMPRESSION_FAILED; } - - // Decompress section data again + + // Decompress section data using both algorithms + USTATUS result = U_SUCCESS; + // Try Tiano + USTATUS TianoResult = TianoDecompress(data, dataSize, decompressed, decompressedSize, scratch, scratchSize); + // Try EFI 1.1 + USTATUS EfiResult = EfiDecompress(data, dataSize, efiDecompressed, decompressedSize, scratch, scratchSize); + + if (decompressedSize > INT32_MAX) { + result = U_STANDARD_DECOMPRESSION_FAILED; + } + else if (EfiResult == U_SUCCESS && TianoResult == U_SUCCESS) { // Both decompressions are OK + algorithm = COMPRESSION_ALGORITHM_UNDECIDED; + decompressedData = UByteArray((const char*)decompressed, (int)decompressedSize); + efiDecompressedData = UByteArray((const char*)efiDecompressed, (int)decompressedSize); + } + else if (TianoResult == U_SUCCESS) { // Only Tiano is OK + algorithm = COMPRESSION_ALGORITHM_TIANO; + decompressedData = UByteArray((const char*)decompressed, (int)decompressedSize); + } + else if (EfiResult == U_SUCCESS) { // Only EFI 1.1 is OK + algorithm = COMPRESSION_ALGORITHM_EFI11; + decompressedData = UByteArray((const char*)efiDecompressed, (int)decompressedSize); + } + else { // Both decompressions failed + result = U_STANDARD_DECOMPRESSION_FAILED; + } + + free(decompressed); + free(efiDecompressed); + free(scratch); + return result; + } + case EFI_CUSTOMIZED_COMPRESSION: { + // Set default algorithm to unknown + algorithm = COMPRESSION_ALGORITHM_UNKNOWN; + + // Get buffer sizes + data = (const UINT8*)compressedData.constData(); + dataSize = (UINT32)compressedData.size(); + + // Get info as normal LZMA section + if (U_SUCCESS != LzmaGetInfo(data, dataSize, &decompressedSize)) { + // Get info as Intel legacy LZMA section + data += sizeof(UINT32); + if (U_SUCCESS != LzmaGetInfo(data, dataSize, &decompressedSize)) { + return U_CUSTOMIZED_DECOMPRESSION_FAILED; + } + else { + algorithm = COMPRESSION_ALGORITHM_LZMA_INTEL_LEGACY; + } + } + else { + algorithm = COMPRESSION_ALGORITHM_LZMA; + } + + // Allocate memory + decompressed = (UINT8*)malloc(decompressedSize); + if (!decompressed) { + return U_OUT_OF_MEMORY; + } + + // Decompress section data if (U_SUCCESS != LzmaDecompress(data, dataSize, decompressed)) { free(decompressed); return U_CUSTOMIZED_DECOMPRESSION_FAILED; } - else { - algorithm = COMPRESSION_ALGORITHM_IMLZMA; - decompressedData = UByteArray((const char*)decompressed, decompressedSize); + + if (decompressedSize > INT32_MAX) { + free(decompressed); + return U_CUSTOMIZED_DECOMPRESSION_FAILED; } + + dictionarySize = readUnaligned((UINT32*)(data + 1)); // LZMA dictionary size is stored in bytes 1-4 of LZMA properties header + decompressedData = UByteArray((const char*)decompressed, (int)decompressedSize); + free(decompressed); + return U_SUCCESS; } - else { - algorithm = COMPRESSION_ALGORITHM_LZMA; - decompressedData = UByteArray((const char*)decompressed, decompressedSize); + case EFI_CUSTOMIZED_COMPRESSION_LZMAF86: { + // Set default algorithm to unknown + algorithm = COMPRESSION_ALGORITHM_UNKNOWN; + + // Get buffer sizes + data = (const UINT8*)compressedData.constData(); + dataSize = (UINT32)compressedData.size(); + + // Get info as normal LZMA section + if (U_SUCCESS != LzmaGetInfo(data, dataSize, &decompressedSize)) { + return U_CUSTOMIZED_DECOMPRESSION_FAILED; + } + algorithm = COMPRESSION_ALGORITHM_LZMAF86; + + // Allocate memory + decompressed = (UINT8*)malloc(decompressedSize); + if (!decompressed) { + return U_OUT_OF_MEMORY; + } + + // Decompress section data + if (U_SUCCESS != LzmaDecompress(data, dataSize, decompressed)) { + free(decompressed); + return U_CUSTOMIZED_DECOMPRESSION_FAILED; + } + + if (decompressedSize > INT32_MAX) { + free(decompressed); + return U_CUSTOMIZED_DECOMPRESSION_FAILED; + } + + // TODO: need to correctly handle non-x86 architecture of the FW image + // After LZMA decompression, the data need to be converted to the raw data. + UINT32 state = 0; + z7_BranchConvSt_X86_Dec(decompressed, decompressedSize, 0, &state); + + dictionarySize = readUnaligned((UINT32*)(data + 1)); // LZMA dictionary size is stored in bytes 1-4 of LZMA properties header + decompressedData = UByteArray((const char*)decompressed, (int)decompressedSize); + free(decompressed); + return U_SUCCESS; + } + default: { + algorithm = COMPRESSION_ALGORITHM_UNKNOWN; + return U_UNKNOWN_COMPRESSION_TYPE; } - - free(decompressed); - return U_SUCCESS; - default: - algorithm = COMPRESSION_ALGORITHM_UNKNOWN; - return U_UNKNOWN_COMPRESSION_TYPE; } } +// 8bit sum calculation routine +UINT8 calculateSum8(const UINT8* buffer, UINT32 bufferSize) +{ + if (!buffer) + return 0; + + UINT8 counter = 0; + + while (bufferSize--) + counter += buffer[bufferSize]; + + return counter; +} + // 8bit checksum calculation routine UINT8 calculateChecksum8(const UINT8* buffer, UINT32 bufferSize) { if (!buffer) return 0; - - UINT8 counter = 0; - - while (bufferSize--) - counter += buffer[bufferSize]; - - return (UINT8)(0x100 - counter); + + return (UINT8)(0x100U - calculateSum8(buffer, bufferSize)); } // 16bit checksum calculation routine @@ -350,15 +398,186 @@ UINT16 calculateChecksum16(const UINT16* buffer, UINT32 bufferSize) { if (!buffer) return 0; - + UINT16 counter = 0; UINT32 index = 0; - + bufferSize /= sizeof(UINT16); - + for (; index < bufferSize; index++) { counter = (UINT16)(counter + buffer[index]); } - + return (UINT16)(0x10000 - counter); -} \ No newline at end of file +} + +// 32bit checksum calculation routine +UINT32 calculateChecksum32(const UINT32* buffer, UINT32 bufferSize) +{ + if (!buffer) + return 0; + + UINT32 counter = 0; + UINT32 index = 0; + + bufferSize /= sizeof(UINT32); + + for (; index < bufferSize; index++) { + counter = (UINT32)(counter + buffer[index]); + } + + return (UINT32)(0x100000000ULL - counter); +} + +// Get padding type for a given padding +UINT8 getPaddingType(const UByteArray & padding) +{ + if (padding.count('\x00') == padding.size()) + return Subtypes::ZeroPadding; + if (padding.count('\xFF') == padding.size()) + return Subtypes::OnePadding; + return Subtypes::DataPadding; +} + +static inline int char2hex(char c) +{ + if (c >= '0' && c <= '9') + return c - '0'; + if (c >= 'A' && c <= 'F') + return c - 'A' + 10; + if (c == '.') + return -2; + return -1; +} + +INTN findPattern(const UINT8 *pattern, const UINT8 *patternMask, UINTN patternSize, + const UINT8 *data, UINTN dataSize, UINTN dataOff) +{ + if (patternSize == 0 || dataSize == 0 || dataOff >= dataSize || dataSize - dataOff < patternSize) + return -1; + + while (dataOff + patternSize <= dataSize) { + bool matches = true; + for (UINTN i = 0; i < patternSize; i++) { + if ((data[dataOff + i] & patternMask[i]) != pattern[i]) { + matches = false; + break; + } + } + + if (matches) + return static_cast(dataOff); + + dataOff++; + } + + return -1; +} + +bool makePattern(const CHAR8 *textPattern, std::vector &pattern, std::vector &patternMask) +{ + UINTN len = std::strlen(textPattern); + + if (len == 0 || len % 2 != 0) + return false; + + len /= 2; + + pattern.resize(len); + patternMask.resize(len); + + for (UINTN i = 0; i < len; i++) { + int v1 = char2hex(std::toupper(textPattern[i * 2])); + int v2 = char2hex(std::toupper(textPattern[i * 2 + 1])); + + if (v1 == -1 || v2 == -1) + return false; + + if (v1 != -2) { + patternMask[i] = 0xF0; + pattern[i] = static_cast(v1) << 4; + } + + if (v2 != -2) { + patternMask[i] |= 0x0F; + pattern[i] |= static_cast(v2); + } + } + + return true; +} + +USTATUS gzipDecompress(const UByteArray & input, UByteArray & output) +{ + output.clear(); + + if (input.size() == 0) + return U_SUCCESS; + + z_stream stream = {}; + stream.next_in = (z_const Bytef *)input.data(); + stream.avail_in = (uInt)input.size(); + stream.zalloc = Z_NULL; + stream.zfree = Z_NULL; + stream.opaque = Z_NULL; + + // 15 for the maximum history buffer, 16 for gzip only input + int ret = inflateInit2(&stream, 15U | 16U); + if (ret != Z_OK) + return U_GZIP_DECOMPRESSION_FAILED; + + while (ret == Z_OK) { + Bytef out[0x1000] = {}; + stream.next_out = out; + stream.avail_out = sizeof(out); + + ret = inflate(&stream, Z_NO_FLUSH); + if ((ret == Z_OK || ret == Z_STREAM_END) && stream.avail_out != sizeof(out)) + output += UByteArray((char *)out, sizeof(out) - stream.avail_out); + } + + inflateEnd(&stream); + return ret == Z_STREAM_END ? U_SUCCESS : U_GZIP_DECOMPRESSION_FAILED; +} + +USTATUS zlibDecompress(const UByteArray& input, UByteArray& output) +{ + output.clear(); + + if (input.size() == 0) + return U_SUCCESS; + + z_stream stream = {}; + stream.next_in = (z_const Bytef*)input.data(); + stream.avail_in = (uInt)input.size(); + stream.zalloc = Z_NULL; + stream.zfree = Z_NULL; + stream.opaque = Z_NULL; + + // 15 for the maximum history buffer + int ret = inflateInit2(&stream, 15U); + if (ret != Z_OK) + return U_ZLIB_DECOMPRESSION_FAILED; + + while (ret == Z_OK) { + Bytef out[0x1000] = {}; + stream.next_out = out; + stream.avail_out = sizeof(out); + + ret = inflate(&stream, Z_NO_FLUSH); + if ((ret == Z_OK || ret == Z_STREAM_END) && stream.avail_out != sizeof(out)) + output += UByteArray((char*)out, sizeof(out) - stream.avail_out); + } + + inflateEnd(&stream); + return ret == Z_STREAM_END ? U_SUCCESS : U_ZLIB_DECOMPRESSION_FAILED; +} + +UString fourCC(const UINT32 value) +{ + const UINT8 byte0 = (const UINT8)(value & 0xFF); + const UINT8 byte1 = (const UINT8)((value & 0xFF00) >> 8); + const UINT8 byte2 = (const UINT8)((value & 0xFF0000) >> 16); + const UINT8 byte3 = (const UINT8)((value & 0xFF000000) >> 24); + return usprintf("%c%c%c%c", byte0, byte1, byte2, byte3); +} diff --git a/common/utility.h b/common/utility.h old mode 100644 new mode 100755 index dcde3e5..505d217 --- a/common/utility.h +++ b/common/utility.h @@ -14,31 +14,41 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #ifndef UTILITY_H #define UTILITY_H +#include + +#include "../common/zlib/zlib.h" + +#include "basetypes.h" #include "ustring.h" #include "treemodel.h" -#include "basetypes.h" #include "parsingdata.h" -// Returns either new parsing data instance or obtains it from index -PARSING_DATA parsingDataFromUModelIndex(const UModelIndex & index); +// Returns text representation of 4CC value +UString fourCC(const UINT32 value); -// Converts parsing data to byte array -UByteArray parsingDataToUByteArray(const PARSING_DATA & pdata); +// Returns bytes as string when all bytes are ascii visible, hex representation otherwise +UString visibleAsciiOrHex(UINT8* bytes, UINT32 length); -// Returns unique name string based for tree item +// Returns unique name for tree item UString uniqueItemName(const UModelIndex & index); +// Makes the name usable as a file name +void fixFileName(UString &name, bool replaceSpaces); + // Converts error code to UString -UString errorCodeToUString(UINT8 errorCode); +UString errorCodeToUString(USTATUS errorCode); -// Decompression routine -USTATUS decompress(const UByteArray & compressed, UINT8 & algorithm, UByteArray & decompressed, UByteArray & efiDecompressed); +// EFI/Tiano/LZMA decompression routine +USTATUS decompress(const UByteArray & compressed, const UINT8 compressionType, UINT8 & algorithm, UINT32 & dictionarySize, UByteArray & decompressed, UByteArray & efiDecompressed); -// Compression routine -//USTATUS compress(const UByteArray & decompressed, UByteArray & compressed, const UINT8 & algorithm); +// GZIP decompression routine +USTATUS gzipDecompress(const UByteArray & compressed, UByteArray & decompressed); -// CRC32 calculation routine -UINT32 crc32(UINT32 initial, const UINT8* buffer, const UINT32 length); +// ZLIB decompression routine +USTATUS zlibDecompress(const UByteArray& compressed, UByteArray& decompressed); + +// 8bit sum calculation routine +UINT8 calculateSum8(const UINT8* buffer, UINT32 bufferSize); // 8bit checksum calculation routine UINT8 calculateChecksum8(const UINT8* buffer, UINT32 bufferSize); @@ -46,4 +56,25 @@ UINT8 calculateChecksum8(const UINT8* buffer, UINT32 bufferSize); // 16bit checksum calculation routine UINT16 calculateChecksum16(const UINT16* buffer, UINT32 bufferSize); +// 32bit checksum calculation routine +UINT32 calculateChecksum32(const UINT32* buffer, UINT32 bufferSize); + +// Return padding type from it's contents +UINT8 getPaddingType(const UByteArray & padding); + +// Make pattern from a hexstring with an assumption of . being any char +bool makePattern(const CHAR8 *textPattern, std::vector &pattern, std::vector &patternMask); + +// Find pattern in a binary blob +INTN findPattern(const UINT8 *pattern, const UINT8 *patternMask, UINTN patternSize, + const UINT8 *data, UINTN dataSize, UINTN dataOff); + +// Safely dereferences misaligned pointers +template +inline T readUnaligned(const T *v) { + T tmp = {}; + memcpy(reinterpret_cast(&tmp), reinterpret_cast(v), sizeof(T)); + return tmp; +} + #endif // UTILITY_H diff --git a/common/zlib/ChangeLog b/common/zlib/ChangeLog new file mode 100644 index 0000000..b801a10 --- /dev/null +++ b/common/zlib/ChangeLog @@ -0,0 +1,1618 @@ + + ChangeLog file for zlib + +Changes in 1.3.1 (22 Jan 2024) +- Reject overflows of zip header fields in minizip +- Fix bug in inflateSync() for data held in bit buffer +- Add LIT_MEM define to use more memory for a small deflate speedup +- Fix decision on the emission of Zip64 end records in minizip +- Add bounds checking to ERR_MSG() macro, used by zError() +- Neutralize zip file traversal attacks in miniunz +- Fix a bug in ZLIB_DEBUG compiles in check_match() +- Various portability and appearance improvements + +Changes in 1.3 (18 Aug 2023) +- Remove K&R function definitions and zlib2ansi +- Fix bug in deflateBound() for level 0 and memLevel 9 +- Fix bug when gzungetc() is used immediately after gzopen() +- Fix bug when using gzflush() with a very small buffer +- Fix crash when gzsetparams() attempted for transparent write +- Fix test/example.c to work with FORCE_STORED +- Rewrite of zran in examples (see zran.c version history) +- Fix minizip to allow it to open an empty zip file +- Fix reading disk number start on zip64 files in minizip +- Fix logic error in minizip argument processing +- Add minizip testing to Makefile +- Read multiple bytes instead of byte-by-byte in minizip unzip.c +- Add memory sanitizer to configure (--memory) +- Various portability improvements +- Various documentation improvements +- Various spelling and typo corrections + +Changes in 1.2.13 (13 Oct 2022) +- Fix configure issue that discarded provided CC definition +- Correct incorrect inputs provided to the CRC functions +- Repair prototypes and exporting of new CRC functions +- Fix inflateBack to detect invalid input with distances too far +- Have infback() deliver all of the available output up to any error +- Fix a bug when getting a gzip header extra field with inflate() +- Fix bug in block type selection when Z_FIXED used +- Tighten deflateBound bounds +- Remove deleted assembler code references +- Various portability and appearance improvements + +Changes in 1.2.12 (27 Mar 2022) +- Cygwin does not have _wopen(), so do not create gzopen_w() there +- Permit a deflateParams() parameter change as soon as possible +- Limit hash table inserts after switch from stored deflate +- Fix bug when window full in deflate_stored() +- Fix CLEAR_HASH macro to be usable as a single statement +- Avoid a conversion error in gzseek when off_t type too small +- Have Makefile return non-zero error code on test failure +- Avoid some conversion warnings in gzread.c and gzwrite.c +- Update use of errno for newer Windows CE versions +- Small speedup to inflate [psumbera] +- Return an error if the gzputs string length can't fit in an int +- Add address checking in clang to -w option of configure +- Don't compute check value for raw inflate if asked to validate +- Handle case where inflateSync used when header never processed +- Avoid the use of ptrdiff_t +- Avoid an undefined behavior of memcpy() in gzappend() +- Avoid undefined behaviors of memcpy() in gz*printf() +- Avoid an undefined behavior of memcpy() in _tr_stored_block() +- Make the names in functions declarations identical to definitions +- Remove old assembler code in which bugs have manifested +- Fix deflateEnd() to not report an error at start of raw deflate +- Add legal disclaimer to README +- Emphasize the need to continue decompressing gzip members +- Correct the initialization requirements for deflateInit2() +- Fix a bug that can crash deflate on some input when using Z_FIXED +- Assure that the number of bits for deflatePrime() is valid +- Use a structure to make globals in enough.c evident +- Use a macro for the printf format of big_t in enough.c +- Clean up code style in enough.c, update version +- Use inline function instead of macro for index in enough.c +- Clarify that prefix codes are counted in enough.c +- Show all the codes for the maximum tables size in enough.c +- Add gznorm.c example, which normalizes gzip files +- Fix the zran.c example to work on a multiple-member gzip file +- Add tables for crc32_combine(), to speed it up by a factor of 200 +- Add crc32_combine_gen() and crc32_combine_op() for fast combines +- Speed up software CRC-32 computation by a factor of 1.5 to 3 +- Use atomic test and set, if available, for dynamic CRC tables +- Don't bother computing check value after successful inflateSync() +- Correct comment in crc32.c +- Add use of the ARMv8 crc32 instructions when requested +- Use ARM crc32 instructions if the ARM architecture has them +- Explicitly note that the 32-bit check values are 32 bits +- Avoid adding empty gzip member after gzflush with Z_FINISH +- Fix memory leak on error in gzlog.c +- Fix error in comment on the polynomial representation of a byte +- Clarify gz* function interfaces, referring to parameter names +- Change macro name in inflate.c to avoid collision in VxWorks +- Correct typo in blast.c +- Improve portability of contrib/minizip +- Fix indentation in minizip's zip.c +- Replace black/white with allow/block. (theresa-m) +- minizip warning fix if MAXU32 already defined. (gvollant) +- Fix unztell64() in minizip to work past 4GB. (Daniël Hörchner) +- Clean up minizip to reduce warnings for testing +- Add fallthrough comments for gcc +- Eliminate use of ULL constants +- Separate out address sanitizing from warnings in configure +- Remove destructive aspects of make distclean +- Check for cc masquerading as gcc or clang in configure +- Fix crc32.c to compile local functions only if used + +Changes in 1.2.11 (15 Jan 2017) +- Fix deflate stored bug when pulling last block from window +- Permit immediate deflateParams changes before any deflate input + +Changes in 1.2.10 (2 Jan 2017) +- Avoid warnings on snprintf() return value +- Fix bug in deflate_stored() for zero-length input +- Fix bug in gzwrite.c that produced corrupt gzip files +- Remove files to be installed before copying them in Makefile.in +- Add warnings when compiling with assembler code + +Changes in 1.2.9 (31 Dec 2016) +- Fix contrib/minizip to permit unzipping with desktop API [Zouzou] +- Improve contrib/blast to return unused bytes +- Assure that gzoffset() is correct when appending +- Improve compress() and uncompress() to support large lengths +- Fix bug in test/example.c where error code not saved +- Remedy Coverity warning [Randers-Pehrson] +- Improve speed of gzprintf() in transparent mode +- Fix inflateInit2() bug when windowBits is 16 or 32 +- Change DEBUG macro to ZLIB_DEBUG +- Avoid uninitialized access by gzclose_w() +- Allow building zlib outside of the source directory +- Fix bug that accepted invalid zlib header when windowBits is zero +- Fix gzseek() problem on MinGW due to buggy _lseeki64 there +- Loop on write() calls in gzwrite.c in case of non-blocking I/O +- Add --warn (-w) option to ./configure for more compiler warnings +- Reject a window size of 256 bytes if not using the zlib wrapper +- Fix bug when level 0 used with Z_HUFFMAN or Z_RLE +- Add --debug (-d) option to ./configure to define ZLIB_DEBUG +- Fix bugs in creating a very large gzip header +- Add uncompress2() function, which returns the input size used +- Assure that deflateParams() will not switch functions mid-block +- Dramatically speed up deflation for level 0 (storing) +- Add gzfread(), duplicating the interface of fread() +- Add gzfwrite(), duplicating the interface of fwrite() +- Add deflateGetDictionary() function +- Use snprintf() for later versions of Microsoft C +- Fix *Init macros to use z_ prefix when requested +- Replace as400 with os400 for OS/400 support [Monnerat] +- Add crc32_z() and adler32_z() functions with size_t lengths +- Update Visual Studio project files [AraHaan] + +Changes in 1.2.8 (28 Apr 2013) +- Update contrib/minizip/iowin32.c for Windows RT [Vollant] +- Do not force Z_CONST for C++ +- Clean up contrib/vstudio [Roß] +- Correct spelling error in zlib.h +- Fix mixed line endings in contrib/vstudio + +Changes in 1.2.7.3 (13 Apr 2013) +- Fix version numbers and DLL names in contrib/vstudio/*/zlib.rc + +Changes in 1.2.7.2 (13 Apr 2013) +- Change check for a four-byte type back to hexadecimal +- Fix typo in win32/Makefile.msc +- Add casts in gzwrite.c for pointer differences + +Changes in 1.2.7.1 (24 Mar 2013) +- Replace use of unsafe string functions with snprintf if available +- Avoid including stddef.h on Windows for Z_SOLO compile [Niessink] +- Fix gzgetc undefine when Z_PREFIX set [Turk] +- Eliminate use of mktemp in Makefile (not always available) +- Fix bug in 'F' mode for gzopen() +- Add inflateGetDictionary() function +- Correct comment in deflate.h +- Use _snprintf for snprintf in Microsoft C +- On Darwin, only use /usr/bin/libtool if libtool is not Apple +- Delete "--version" file if created by "ar --version" [Richard G.] +- Fix configure check for veracity of compiler error return codes +- Fix CMake compilation of static lib for MSVC2010 x64 +- Remove unused variable in infback9.c +- Fix argument checks in gzlog_compress() and gzlog_write() +- Clean up the usage of z_const and respect const usage within zlib +- Clean up examples/gzlog.[ch] comparisons of different types +- Avoid shift equal to bits in type (caused endless loop) +- Fix uninitialized value bug in gzputc() introduced by const patches +- Fix memory allocation error in examples/zran.c [Nor] +- Fix bug where gzopen(), gzclose() would write an empty file +- Fix bug in gzclose() when gzwrite() runs out of memory +- Check for input buffer malloc failure in examples/gzappend.c +- Add note to contrib/blast to use binary mode in stdio +- Fix comparisons of differently signed integers in contrib/blast +- Check for invalid code length codes in contrib/puff +- Fix serious but very rare decompression bug in inftrees.c +- Update inflateBack() comments, since inflate() can be faster +- Use underscored I/O function names for WINAPI_FAMILY +- Add _tr_flush_bits to the external symbols prefixed by --zprefix +- Add contrib/vstudio/vc10 pre-build step for static only +- Quote --version-script argument in CMakeLists.txt +- Don't specify --version-script on Apple platforms in CMakeLists.txt +- Fix casting error in contrib/testzlib/testzlib.c +- Fix types in contrib/minizip to match result of get_crc_table() +- Simplify contrib/vstudio/vc10 with 'd' suffix +- Add TOP support to win32/Makefile.msc +- Support i686 and amd64 assembler builds in CMakeLists.txt +- Fix typos in the use of _LARGEFILE64_SOURCE in zconf.h +- Add vc11 and vc12 build files to contrib/vstudio +- Add gzvprintf() as an undocumented function in zlib +- Fix configure for Sun shell +- Remove runtime check in configure for four-byte integer type +- Add casts and consts to ease user conversion to C++ +- Add man pages for minizip and miniunzip +- In Makefile uninstall, don't rm if preceding cd fails +- Do not return Z_BUF_ERROR if deflateParam() has nothing to write + +Changes in 1.2.7 (2 May 2012) +- Replace use of memmove() with a simple copy for portability +- Test for existence of strerror +- Restore gzgetc_ for backward compatibility with 1.2.6 +- Fix build with non-GNU make on Solaris +- Require gcc 4.0 or later on Mac OS X to use the hidden attribute +- Include unistd.h for Watcom C +- Use __WATCOMC__ instead of __WATCOM__ +- Do not use the visibility attribute if NO_VIZ defined +- Improve the detection of no hidden visibility attribute +- Avoid using __int64 for gcc or solo compilation +- Cast to char * in gzprintf to avoid warnings [Zinser] +- Fix make_vms.com for VAX [Zinser] +- Don't use library or built-in byte swaps +- Simplify test and use of gcc hidden attribute +- Fix bug in gzclose_w() when gzwrite() fails to allocate memory +- Add "x" (O_EXCL) and "e" (O_CLOEXEC) modes support to gzopen() +- Fix bug in test/minigzip.c for configure --solo +- Fix contrib/vstudio project link errors [Mohanathas] +- Add ability to choose the builder in make_vms.com [Schweda] +- Add DESTDIR support to mingw32 win32/Makefile.gcc +- Fix comments in win32/Makefile.gcc for proper usage +- Allow overriding the default install locations for cmake +- Generate and install the pkg-config file with cmake +- Build both a static and a shared version of zlib with cmake +- Include version symbols for cmake builds +- If using cmake with MSVC, add the source directory to the includes +- Remove unneeded EXTRA_CFLAGS from win32/Makefile.gcc [Truta] +- Move obsolete emx makefile to old [Truta] +- Allow the use of -Wundef when compiling or using zlib +- Avoid the use of the -u option with mktemp +- Improve inflate() documentation on the use of Z_FINISH +- Recognize clang as gcc +- Add gzopen_w() in Windows for wide character path names +- Rename zconf.h in CMakeLists.txt to move it out of the way +- Add source directory in CMakeLists.txt for building examples +- Look in build directory for zlib.pc in CMakeLists.txt +- Remove gzflags from zlibvc.def in vc9 and vc10 +- Fix contrib/minizip compilation in the MinGW environment +- Update ./configure for Solaris, support --64 [Mooney] +- Remove -R. from Solaris shared build (possible security issue) +- Avoid race condition for parallel make (-j) running example +- Fix type mismatch between get_crc_table() and crc_table +- Fix parsing of version with "-" in CMakeLists.txt [Snider, Ziegler] +- Fix the path to zlib.map in CMakeLists.txt +- Force the native libtool in Mac OS X to avoid GNU libtool [Beebe] +- Add instructions to win32/Makefile.gcc for shared install [Torri] + +Changes in 1.2.6.1 (12 Feb 2012) +- Avoid the use of the Objective-C reserved name "id" +- Include io.h in gzguts.h for Microsoft compilers +- Fix problem with ./configure --prefix and gzgetc macro +- Include gz_header definition when compiling zlib solo +- Put gzflags() functionality back in zutil.c +- Avoid library header include in crc32.c for Z_SOLO +- Use name in GCC_CLASSIC as C compiler for coverage testing, if set +- Minor cleanup in contrib/minizip/zip.c [Vollant] +- Update make_vms.com [Zinser] +- Remove unnecessary gzgetc_ function +- Use optimized byte swap operations for Microsoft and GNU [Snyder] +- Fix minor typo in zlib.h comments [Rzesniowiecki] + +Changes in 1.2.6 (29 Jan 2012) +- Update the Pascal interface in contrib/pascal +- Fix function numbers for gzgetc_ in zlibvc.def files +- Fix configure.ac for contrib/minizip [Schiffer] +- Fix large-entry detection in minizip on 64-bit systems [Schiffer] +- Have ./configure use the compiler return code for error indication +- Fix CMakeLists.txt for cross compilation [McClure] +- Fix contrib/minizip/zip.c for 64-bit architectures [Dalsnes] +- Fix compilation of contrib/minizip on FreeBSD [Marquez] +- Correct suggested usages in win32/Makefile.msc [Shachar, Horvath] +- Include io.h for Turbo C / Borland C on all platforms [Truta] +- Make version explicit in contrib/minizip/configure.ac [Bosmans] +- Avoid warning for no encryption in contrib/minizip/zip.c [Vollant] +- Minor cleanup up contrib/minizip/unzip.c [Vollant] +- Fix bug when compiling minizip with C++ [Vollant] +- Protect for long name and extra fields in contrib/minizip [Vollant] +- Avoid some warnings in contrib/minizip [Vollant] +- Add -I../.. -L../.. to CFLAGS for minizip and miniunzip +- Add missing libs to minizip linker command +- Add support for VPATH builds in contrib/minizip +- Add an --enable-demos option to contrib/minizip/configure +- Add the generation of configure.log by ./configure +- Exit when required parameters not provided to win32/Makefile.gcc +- Have gzputc return the character written instead of the argument +- Use the -m option on ldconfig for BSD systems [Tobias] +- Correct in zlib.map when deflateResetKeep was added + +Changes in 1.2.5.3 (15 Jan 2012) +- Restore gzgetc function for binary compatibility +- Do not use _lseeki64 under Borland C++ [Truta] +- Update win32/Makefile.msc to build test/*.c [Truta] +- Remove old/visualc6 given CMakefile and other alternatives +- Update AS400 build files and documentation [Monnerat] +- Update win32/Makefile.gcc to build test/*.c [Truta] +- Permit stronger flushes after Z_BLOCK flushes +- Avoid extraneous empty blocks when doing empty flushes +- Permit Z_NULL arguments to deflatePending +- Allow deflatePrime() to insert bits in the middle of a stream +- Remove second empty static block for Z_PARTIAL_FLUSH +- Write out all of the available bits when using Z_BLOCK +- Insert the first two strings in the hash table after a flush + +Changes in 1.2.5.2 (17 Dec 2011) +- fix ld error: unable to find version dependency 'ZLIB_1.2.5' +- use relative symlinks for shared libs +- Avoid searching past window for Z_RLE strategy +- Assure that high-water mark initialization is always applied in deflate +- Add assertions to fill_window() in deflate.c to match comments +- Update python link in README +- Correct spelling error in gzread.c +- Fix bug in gzgets() for a concatenated empty gzip stream +- Correct error in comment for gz_make() +- Change gzread() and related to ignore junk after gzip streams +- Allow gzread() and related to continue after gzclearerr() +- Allow gzrewind() and gzseek() after a premature end-of-file +- Simplify gzseek() now that raw after gzip is ignored +- Change gzgetc() to a macro for speed (~40% speedup in testing) +- Fix gzclose() to return the actual error last encountered +- Always add large file support for windows +- Include zconf.h for windows large file support +- Include zconf.h.cmakein for windows large file support +- Update zconf.h.cmakein on make distclean +- Merge vestigial vsnprintf determination from zutil.h to gzguts.h +- Clarify how gzopen() appends in zlib.h comments +- Correct documentation of gzdirect() since junk at end now ignored +- Add a transparent write mode to gzopen() when 'T' is in the mode +- Update python link in zlib man page +- Get inffixed.h and MAKEFIXED result to match +- Add a ./config --solo option to make zlib subset with no library use +- Add undocumented inflateResetKeep() function for CAB file decoding +- Add --cover option to ./configure for gcc coverage testing +- Add #define ZLIB_CONST option to use const in the z_stream interface +- Add comment to gzdopen() in zlib.h to use dup() when using fileno() +- Note behavior of uncompress() to provide as much data as it can +- Add files in contrib/minizip to aid in building libminizip +- Split off AR options in Makefile.in and configure +- Change ON macro to Z_ARG to avoid application conflicts +- Facilitate compilation with Borland C++ for pragmas and vsnprintf +- Include io.h for Turbo C / Borland C++ +- Move example.c and minigzip.c to test/ +- Simplify incomplete code table filling in inflate_table() +- Remove code from inflate.c and infback.c that is impossible to execute +- Test the inflate code with full coverage +- Allow deflateSetDictionary, inflateSetDictionary at any time (in raw) +- Add deflateResetKeep and fix inflateResetKeep to retain dictionary +- Fix gzwrite.c to accommodate reduced memory zlib compilation +- Have inflate() with Z_FINISH avoid the allocation of a window +- Do not set strm->adler when doing raw inflate +- Fix gzeof() to behave just like feof() when read is not past end of file +- Fix bug in gzread.c when end-of-file is reached +- Avoid use of Z_BUF_ERROR in gz* functions except for premature EOF +- Document gzread() capability to read concurrently written files +- Remove hard-coding of resource compiler in CMakeLists.txt [Blammo] + +Changes in 1.2.5.1 (10 Sep 2011) +- Update FAQ entry on shared builds (#13) +- Avoid symbolic argument to chmod in Makefile.in +- Fix bug and add consts in contrib/puff [Oberhumer] +- Update contrib/puff/zeros.raw test file to have all block types +- Add full coverage test for puff in contrib/puff/Makefile +- Fix static-only-build install in Makefile.in +- Fix bug in unzGetCurrentFileInfo() in contrib/minizip [Kuno] +- Add libz.a dependency to shared in Makefile.in for parallel builds +- Spell out "number" (instead of "nb") in zlib.h for total_in, total_out +- Replace $(...) with `...` in configure for non-bash sh [Bowler] +- Add darwin* to Darwin* and solaris* to SunOS\ 5* in configure [Groffen] +- Add solaris* to Linux* in configure to allow gcc use [Groffen] +- Add *bsd* to Linux* case in configure [Bar-Lev] +- Add inffast.obj to dependencies in win32/Makefile.msc +- Correct spelling error in deflate.h [Kohler] +- Change libzdll.a again to libz.dll.a (!) in win32/Makefile.gcc +- Add test to configure for GNU C looking for gcc in output of $cc -v +- Add zlib.pc generation to win32/Makefile.gcc [Weigelt] +- Fix bug in zlib.h for _FILE_OFFSET_BITS set and _LARGEFILE64_SOURCE not +- Add comment in zlib.h that adler32_combine with len2 < 0 makes no sense +- Make NO_DIVIDE option in adler32.c much faster (thanks to John Reiser) +- Make stronger test in zconf.h to include unistd.h for LFS +- Apply Darwin patches for 64-bit file offsets to contrib/minizip [Slack] +- Fix zlib.h LFS support when Z_PREFIX used +- Add updated as400 support (removed from old) [Monnerat] +- Avoid deflate sensitivity to volatile input data +- Avoid division in adler32_combine for NO_DIVIDE +- Clarify the use of Z_FINISH with deflateBound() amount of space +- Set binary for output file in puff.c +- Use u4 type for crc_table to avoid conversion warnings +- Apply casts in zlib.h to avoid conversion warnings +- Add OF to prototypes for adler32_combine_ and crc32_combine_ [Miller] +- Improve inflateSync() documentation to note indeterminacy +- Add deflatePending() function to return the amount of pending output +- Correct the spelling of "specification" in FAQ [Randers-Pehrson] +- Add a check in configure for stdarg.h, use for gzprintf() +- Check that pointers fit in ints when gzprint() compiled old style +- Add dummy name before $(SHAREDLIBV) in Makefile [Bar-Lev, Bowler] +- Delete line in configure that adds -L. libz.a to LDFLAGS [Weigelt] +- Add debug records in assembler code [Londer] +- Update RFC references to use http://tools.ietf.org/html/... [Li] +- Add --archs option, use of libtool to configure for Mac OS X [Borstel] + +Changes in 1.2.5 (19 Apr 2010) +- Disable visibility attribute in win32/Makefile.gcc [Bar-Lev] +- Default to libdir as sharedlibdir in configure [Nieder] +- Update copyright dates on modified source files +- Update trees.c to be able to generate modified trees.h +- Exit configure for MinGW, suggesting win32/Makefile.gcc +- Check for NULL path in gz_open [Homurlu] + +Changes in 1.2.4.5 (18 Apr 2010) +- Set sharedlibdir in configure [Torok] +- Set LDFLAGS in Makefile.in [Bar-Lev] +- Avoid mkdir objs race condition in Makefile.in [Bowler] +- Add ZLIB_INTERNAL in front of internal inter-module functions and arrays +- Define ZLIB_INTERNAL to hide internal functions and arrays for GNU C +- Don't use hidden attribute when it is a warning generator (e.g. Solaris) + +Changes in 1.2.4.4 (18 Apr 2010) +- Fix CROSS_PREFIX executable testing, CHOST extract, mingw* [Torok] +- Undefine _LARGEFILE64_SOURCE in zconf.h if it is zero, but not if empty +- Try to use bash or ksh regardless of functionality of /bin/sh +- Fix configure incompatibility with NetBSD sh +- Remove attempt to run under bash or ksh since have better NetBSD fix +- Fix win32/Makefile.gcc for MinGW [Bar-Lev] +- Add diagnostic messages when using CROSS_PREFIX in configure +- Added --sharedlibdir option to configure [Weigelt] +- Use hidden visibility attribute when available [Frysinger] + +Changes in 1.2.4.3 (10 Apr 2010) +- Only use CROSS_PREFIX in configure for ar and ranlib if they exist +- Use CROSS_PREFIX for nm [Bar-Lev] +- Assume _LARGEFILE64_SOURCE defined is equivalent to true +- Avoid use of undefined symbols in #if with && and || +- Make *64 prototypes in gzguts.h consistent with functions +- Add -shared load option for MinGW in configure [Bowler] +- Move z_off64_t to public interface, use instead of off64_t +- Remove ! from shell test in configure (not portable to Solaris) +- Change +0 macro tests to -0 for possibly increased portability + +Changes in 1.2.4.2 (9 Apr 2010) +- Add consistent carriage returns to readme.txt's in masmx86 and masmx64 +- Really provide prototypes for *64 functions when building without LFS +- Only define unlink() in minigzip.c if unistd.h not included +- Update README to point to contrib/vstudio project files +- Move projects/vc6 to old/ and remove projects/ +- Include stdlib.h in minigzip.c for setmode() definition under WinCE +- Clean up assembler builds in win32/Makefile.msc [Rowe] +- Include sys/types.h for Microsoft for off_t definition +- Fix memory leak on error in gz_open() +- Symbolize nm as $NM in configure [Weigelt] +- Use TEST_LDSHARED instead of LDSHARED to link test programs [Weigelt] +- Add +0 to _FILE_OFFSET_BITS and _LFS64_LARGEFILE in case not defined +- Fix bug in gzeof() to take into account unused input data +- Avoid initialization of structures with variables in puff.c +- Updated win32/README-WIN32.txt [Rowe] + +Changes in 1.2.4.1 (28 Mar 2010) +- Remove the use of [a-z] constructs for sed in configure [gentoo 310225] +- Remove $(SHAREDLIB) from LIBS in Makefile.in [Creech] +- Restore "for debugging" comment on sprintf() in gzlib.c +- Remove fdopen for MVS from gzguts.h +- Put new README-WIN32.txt in win32 [Rowe] +- Add check for shell to configure and invoke another shell if needed +- Fix big fat stinking bug in gzseek() on uncompressed files +- Remove vestigial F_OPEN64 define in zutil.h +- Set and check the value of _LARGEFILE_SOURCE and _LARGEFILE64_SOURCE +- Avoid errors on non-LFS systems when applications define LFS macros +- Set EXE to ".exe" in configure for MINGW [Kahle] +- Match crc32() in crc32.c exactly to the prototype in zlib.h [Sherrill] +- Add prefix for cross-compilation in win32/makefile.gcc [Bar-Lev] +- Add DLL install in win32/makefile.gcc [Bar-Lev] +- Allow Linux* or linux* from uname in configure [Bar-Lev] +- Allow ldconfig to be redefined in configure and Makefile.in [Bar-Lev] +- Add cross-compilation prefixes to configure [Bar-Lev] +- Match type exactly in gz_load() invocation in gzread.c +- Match type exactly of zcalloc() in zutil.c to zlib.h alloc_func +- Provide prototypes for *64 functions when building zlib without LFS +- Don't use -lc when linking shared library on MinGW +- Remove errno.h check in configure and vestigial errno code in zutil.h + +Changes in 1.2.4 (14 Mar 2010) +- Fix VER3 extraction in configure for no fourth subversion +- Update zlib.3, add docs to Makefile.in to make .pdf out of it +- Add zlib.3.pdf to distribution +- Don't set error code in gzerror() if passed pointer is NULL +- Apply destination directory fixes to CMakeLists.txt [Lowman] +- Move #cmakedefine's to a new zconf.in.cmakein +- Restore zconf.h for builds that don't use configure or cmake +- Add distclean to dummy Makefile for convenience +- Update and improve INDEX, README, and FAQ +- Update CMakeLists.txt for the return of zconf.h [Lowman] +- Update contrib/vstudio/vc9 and vc10 [Vollant] +- Change libz.dll.a back to libzdll.a in win32/Makefile.gcc +- Apply license and readme changes to contrib/asm686 [Raiter] +- Check file name lengths and add -c option in minigzip.c [Li] +- Update contrib/amd64 and contrib/masmx86/ [Vollant] +- Avoid use of "eof" parameter in trees.c to not shadow library variable +- Update make_vms.com for removal of zlibdefs.h [Zinser] +- Update assembler code and vstudio projects in contrib [Vollant] +- Remove outdated assembler code contrib/masm686 and contrib/asm586 +- Remove old vc7 and vc8 from contrib/vstudio +- Update win32/Makefile.msc, add ZLIB_VER_SUBREVISION [Rowe] +- Fix memory leaks in gzclose_r() and gzclose_w(), file leak in gz_open() +- Add contrib/gcc_gvmat64 for longest_match and inflate_fast [Vollant] +- Remove *64 functions from win32/zlib.def (they're not 64-bit yet) +- Fix bug in void-returning vsprintf() case in gzwrite.c +- Fix name change from inflate.h in contrib/inflate86/inffas86.c +- Check if temporary file exists before removing in make_vms.com [Zinser] +- Fix make install and uninstall for --static option +- Fix usage of _MSC_VER in gzguts.h and zutil.h [Truta] +- Update readme.txt in contrib/masmx64 and masmx86 to assemble + +Changes in 1.2.3.9 (21 Feb 2010) +- Expunge gzio.c +- Move as400 build information to old +- Fix updates in contrib/minizip and contrib/vstudio +- Add const to vsnprintf test in configure to avoid warnings [Weigelt] +- Delete zconf.h (made by configure) [Weigelt] +- Change zconf.in.h to zconf.h.in per convention [Weigelt] +- Check for NULL buf in gzgets() +- Return empty string for gzgets() with len == 1 (like fgets()) +- Fix description of gzgets() in zlib.h for end-of-file, NULL return +- Update minizip to 1.1 [Vollant] +- Avoid MSVC loss of data warnings in gzread.c, gzwrite.c +- Note in zlib.h that gzerror() should be used to distinguish from EOF +- Remove use of snprintf() from gzlib.c +- Fix bug in gzseek() +- Update contrib/vstudio, adding vc9 and vc10 [Kuno, Vollant] +- Fix zconf.h generation in CMakeLists.txt [Lowman] +- Improve comments in zconf.h where modified by configure + +Changes in 1.2.3.8 (13 Feb 2010) +- Clean up text files (tabs, trailing whitespace, etc.) [Oberhumer] +- Use z_off64_t in gz_zero() and gz_skip() to match state->skip +- Avoid comparison problem when sizeof(int) == sizeof(z_off64_t) +- Revert to Makefile.in from 1.2.3.6 (live with the clutter) +- Fix missing error return in gzflush(), add zlib.h note +- Add *64 functions to zlib.map [Levin] +- Fix signed/unsigned comparison in gz_comp() +- Use SFLAGS when testing shared linking in configure +- Add --64 option to ./configure to use -m64 with gcc +- Fix ./configure --help to correctly name options +- Have make fail if a test fails [Levin] +- Avoid buffer overrun in contrib/masmx64/gvmat64.asm [Simpson] +- Remove assembler object files from contrib + +Changes in 1.2.3.7 (24 Jan 2010) +- Always gzopen() with O_LARGEFILE if available +- Fix gzdirect() to work immediately after gzopen() or gzdopen() +- Make gzdirect() more precise when the state changes while reading +- Improve zlib.h documentation in many places +- Catch memory allocation failure in gz_open() +- Complete close operation if seek forward in gzclose_w() fails +- Return Z_ERRNO from gzclose_r() if close() fails +- Return Z_STREAM_ERROR instead of EOF for gzclose() being passed NULL +- Return zero for gzwrite() errors to match zlib.h description +- Return -1 on gzputs() error to match zlib.h description +- Add zconf.in.h to allow recovery from configure modification [Weigelt] +- Fix static library permissions in Makefile.in [Weigelt] +- Avoid warnings in configure tests that hide functionality [Weigelt] +- Add *BSD and DragonFly to Linux case in configure [gentoo 123571] +- Change libzdll.a to libz.dll.a in win32/Makefile.gcc [gentoo 288212] +- Avoid access of uninitialized data for first inflateReset2 call [Gomes] +- Keep object files in subdirectories to reduce the clutter somewhat +- Remove default Makefile and zlibdefs.h, add dummy Makefile +- Add new external functions to Z_PREFIX, remove duplicates, z_z_ -> z_ +- Remove zlibdefs.h completely -- modify zconf.h instead + +Changes in 1.2.3.6 (17 Jan 2010) +- Avoid void * arithmetic in gzread.c and gzwrite.c +- Make compilers happier with const char * for gz_error message +- Avoid unused parameter warning in inflate.c +- Avoid signed-unsigned comparison warning in inflate.c +- Indent #pragma's for traditional C +- Fix usage of strwinerror() in glib.c, change to gz_strwinerror() +- Correct email address in configure for system options +- Update make_vms.com and add make_vms.com to contrib/minizip [Zinser] +- Update zlib.map [Brown] +- Fix Makefile.in for Solaris 10 make of example64 and minizip64 [Torok] +- Apply various fixes to CMakeLists.txt [Lowman] +- Add checks on len in gzread() and gzwrite() +- Add error message for no more room for gzungetc() +- Remove zlib version check in gzwrite() +- Defer compression of gzprintf() result until need to +- Use snprintf() in gzdopen() if available +- Remove USE_MMAP configuration determination (only used by minigzip) +- Remove examples/pigz.c (available separately) +- Update examples/gun.c to 1.6 + +Changes in 1.2.3.5 (8 Jan 2010) +- Add space after #if in zutil.h for some compilers +- Fix relatively harmless bug in deflate_fast() [Exarevsky] +- Fix same problem in deflate_slow() +- Add $(SHAREDLIBV) to LIBS in Makefile.in [Brown] +- Add deflate_rle() for faster Z_RLE strategy run-length encoding +- Add deflate_huff() for faster Z_HUFFMAN_ONLY encoding +- Change name of "write" variable in inffast.c to avoid library collisions +- Fix premature EOF from gzread() in gzio.c [Brown] +- Use zlib header window size if windowBits is 0 in inflateInit2() +- Remove compressBound() call in deflate.c to avoid linking compress.o +- Replace use of errno in gz* with functions, support WinCE [Alves] +- Provide alternative to perror() in minigzip.c for WinCE [Alves] +- Don't use _vsnprintf on later versions of MSVC [Lowman] +- Add CMake build script and input file [Lowman] +- Update contrib/minizip to 1.1 [Svensson, Vollant] +- Moved nintendods directory from contrib to root +- Replace gzio.c with a new set of routines with the same functionality +- Add gzbuffer(), gzoffset(), gzclose_r(), gzclose_w() as part of above +- Update contrib/minizip to 1.1b +- Change gzeof() to return 0 on error instead of -1 to agree with zlib.h + +Changes in 1.2.3.4 (21 Dec 2009) +- Use old school .SUFFIXES in Makefile.in for FreeBSD compatibility +- Update comments in configure and Makefile.in for default --shared +- Fix test -z's in configure [Marquess] +- Build examplesh and minigzipsh when not testing +- Change NULL's to Z_NULL's in deflate.c and in comments in zlib.h +- Import LDFLAGS from the environment in configure +- Fix configure to populate SFLAGS with discovered CFLAGS options +- Adapt make_vms.com to the new Makefile.in [Zinser] +- Add zlib2ansi script for C++ compilation [Marquess] +- Add _FILE_OFFSET_BITS=64 test to make test (when applicable) +- Add AMD64 assembler code for longest match to contrib [Teterin] +- Include options from $SFLAGS when doing $LDSHARED +- Simplify 64-bit file support by introducing z_off64_t type +- Make shared object files in objs directory to work around old Sun cc +- Use only three-part version number for Darwin shared compiles +- Add rc option to ar in Makefile.in for when ./configure not run +- Add -WI,-rpath,. to LDFLAGS for OSF 1 V4* +- Set LD_LIBRARYN32_PATH for SGI IRIX shared compile +- Protect against _FILE_OFFSET_BITS being defined when compiling zlib +- Rename Makefile.in targets allstatic to static and allshared to shared +- Fix static and shared Makefile.in targets to be independent +- Correct error return bug in gz_open() by setting state [Brown] +- Put spaces before ;;'s in configure for better sh compatibility +- Add pigz.c (parallel implementation of gzip) to examples/ +- Correct constant in crc32.c to UL [Leventhal] +- Reject negative lengths in crc32_combine() +- Add inflateReset2() function to work like inflateEnd()/inflateInit2() +- Include sys/types.h for _LARGEFILE64_SOURCE [Brown] +- Correct typo in doc/algorithm.txt [Janik] +- Fix bug in adler32_combine() [Zhu] +- Catch missing-end-of-block-code error in all inflates and in puff + Assures that random input to inflate eventually results in an error +- Added enough.c (calculation of ENOUGH for inftrees.h) to examples/ +- Update ENOUGH and its usage to reflect discovered bounds +- Fix gzerror() error report on empty input file [Brown] +- Add ush casts in trees.c to avoid pedantic runtime errors +- Fix typo in zlib.h uncompress() description [Reiss] +- Correct inflate() comments with regard to automatic header detection +- Remove deprecation comment on Z_PARTIAL_FLUSH (it stays) +- Put new version of gzlog (2.0) in examples with interruption recovery +- Add puff compile option to permit invalid distance-too-far streams +- Add puff TEST command options, ability to read piped input +- Prototype the *64 functions in zlib.h when _FILE_OFFSET_BITS == 64, but + _LARGEFILE64_SOURCE not defined +- Fix Z_FULL_FLUSH to truly erase the past by resetting s->strstart +- Fix deflateSetDictionary() to use all 32K for output consistency +- Remove extraneous #define MIN_LOOKAHEAD in deflate.c (in deflate.h) +- Clear bytes after deflate lookahead to avoid use of uninitialized data +- Change a limit in inftrees.c to be more transparent to Coverity Prevent +- Update win32/zlib.def with exported symbols from zlib.h +- Correct spelling errors in zlib.h [Willem, Sobrado] +- Allow Z_BLOCK for deflate() to force a new block +- Allow negative bits in inflatePrime() to delete existing bit buffer +- Add Z_TREES flush option to inflate() to return at end of trees +- Add inflateMark() to return current state information for random access +- Add Makefile for NintendoDS to contrib [Costa] +- Add -w in configure compile tests to avoid spurious warnings [Beucler] +- Fix typos in zlib.h comments for deflateSetDictionary() +- Fix EOF detection in transparent gzread() [Maier] + +Changes in 1.2.3.3 (2 October 2006) +- Make --shared the default for configure, add a --static option +- Add compile option to permit invalid distance-too-far streams +- Add inflateUndermine() function which is required to enable above +- Remove use of "this" variable name for C++ compatibility [Marquess] +- Add testing of shared library in make test, if shared library built +- Use ftello() and fseeko() if available instead of ftell() and fseek() +- Provide two versions of all functions that use the z_off_t type for + binary compatibility -- a normal version and a 64-bit offset version, + per the Large File Support Extension when _LARGEFILE64_SOURCE is + defined; use the 64-bit versions by default when _FILE_OFFSET_BITS + is defined to be 64 +- Add a --uname= option to configure to perhaps help with cross-compiling + +Changes in 1.2.3.2 (3 September 2006) +- Turn off silly Borland warnings [Hay] +- Use off64_t and define _LARGEFILE64_SOURCE when present +- Fix missing dependency on inffixed.h in Makefile.in +- Rig configure --shared to build both shared and static [Teredesai, Truta] +- Remove zconf.in.h and instead create a new zlibdefs.h file +- Fix contrib/minizip/unzip.c non-encrypted after encrypted [Vollant] +- Add treebuild.xml (see http://treebuild.metux.de/) [Weigelt] + +Changes in 1.2.3.1 (16 August 2006) +- Add watcom directory with OpenWatcom make files [Daniel] +- Remove #undef of FAR in zconf.in.h for MVS [Fedtke] +- Update make_vms.com [Zinser] +- Use -fPIC for shared build in configure [Teredesai, Nicholson] +- Use only major version number for libz.so on IRIX and OSF1 [Reinholdtsen] +- Use fdopen() (not _fdopen()) for Interix in zutil.h [Bäck] +- Add some FAQ entries about the contrib directory +- Update the MVS question in the FAQ +- Avoid extraneous reads after EOF in gzio.c [Brown] +- Correct spelling of "successfully" in gzio.c [Randers-Pehrson] +- Add comments to zlib.h about gzerror() usage [Brown] +- Set extra flags in gzip header in gzopen() like deflate() does +- Make configure options more compatible with double-dash conventions + [Weigelt] +- Clean up compilation under Solaris SunStudio cc [Rowe, Reinholdtsen] +- Fix uninstall target in Makefile.in [Truta] +- Add pkgconfig support [Weigelt] +- Use $(DESTDIR) macro in Makefile.in [Reinholdtsen, Weigelt] +- Replace set_data_type() with a more accurate detect_data_type() in + trees.c, according to the txtvsbin.txt document [Truta] +- Swap the order of #include and #include "zlib.h" in + gzio.c, example.c and minigzip.c [Truta] +- Shut up annoying VS2005 warnings about standard C deprecation [Rowe, + Truta] (where?) +- Fix target "clean" from win32/Makefile.bor [Truta] +- Create .pdb and .manifest files in win32/makefile.msc [Ziegler, Rowe] +- Update zlib www home address in win32/DLL_FAQ.txt [Truta] +- Update contrib/masmx86/inffas32.asm for VS2005 [Vollant, Van Wassenhove] +- Enable browse info in the "Debug" and "ASM Debug" configurations in + the Visual C++ 6 project, and set (non-ASM) "Debug" as default [Truta] +- Add pkgconfig support [Weigelt] +- Add ZLIB_VER_MAJOR, ZLIB_VER_MINOR and ZLIB_VER_REVISION in zlib.h, + for use in win32/zlib1.rc [Polushin, Rowe, Truta] +- Add a document that explains the new text detection scheme to + doc/txtvsbin.txt [Truta] +- Add rfc1950.txt, rfc1951.txt and rfc1952.txt to doc/ [Truta] +- Move algorithm.txt into doc/ [Truta] +- Synchronize FAQ with website +- Fix compressBound(), was low for some pathological cases [Fearnley] +- Take into account wrapper variations in deflateBound() +- Set examples/zpipe.c input and output to binary mode for Windows +- Update examples/zlib_how.html with new zpipe.c (also web site) +- Fix some warnings in examples/gzlog.c and examples/zran.c (it seems + that gcc became pickier in 4.0) +- Add zlib.map for Linux: "All symbols from zlib-1.1.4 remain + un-versioned, the patch adds versioning only for symbols introduced in + zlib-1.2.0 or later. It also declares as local those symbols which are + not designed to be exported." [Levin] +- Update Z_PREFIX list in zconf.in.h, add --zprefix option to configure +- Do not initialize global static by default in trees.c, add a response + NO_INIT_GLOBAL_POINTERS to initialize them if needed [Marquess] +- Don't use strerror() in gzio.c under WinCE [Yakimov] +- Don't use errno.h in zutil.h under WinCE [Yakimov] +- Move arguments for AR to its usage to allow replacing ar [Marot] +- Add HAVE_VISIBILITY_PRAGMA in zconf.in.h for Mozilla [Randers-Pehrson] +- Improve inflateInit() and inflateInit2() documentation +- Fix structure size comment in inflate.h +- Change configure help option from --h* to --help [Santos] + +Changes in 1.2.3 (18 July 2005) +- Apply security vulnerability fixes to contrib/infback9 as well +- Clean up some text files (carriage returns, trailing space) +- Update testzlib, vstudio, masmx64, and masmx86 in contrib [Vollant] + +Changes in 1.2.2.4 (11 July 2005) +- Add inflatePrime() function for starting inflation at bit boundary +- Avoid some Visual C warnings in deflate.c +- Avoid more silly Visual C warnings in inflate.c and inftrees.c for 64-bit + compile +- Fix some spelling errors in comments [Betts] +- Correct inflateInit2() error return documentation in zlib.h +- Add zran.c example of compressed data random access to examples + directory, shows use of inflatePrime() +- Fix cast for assignments to strm->state in inflate.c and infback.c +- Fix zlibCompileFlags() in zutil.c to use 1L for long shifts [Oberhumer] +- Move declarations of gf2 functions to right place in crc32.c [Oberhumer] +- Add cast in trees.c t avoid a warning [Oberhumer] +- Avoid some warnings in fitblk.c, gun.c, gzjoin.c in examples [Oberhumer] +- Update make_vms.com [Zinser] +- Initialize state->write in inflateReset() since copied in inflate_fast() +- Be more strict on incomplete code sets in inflate_table() and increase + ENOUGH and MAXD -- this repairs a possible security vulnerability for + invalid inflate input. Thanks to Tavis Ormandy and Markus Oberhumer for + discovering the vulnerability and providing test cases +- Add ia64 support to configure for HP-UX [Smith] +- Add error return to gzread() for format or i/o error [Levin] +- Use malloc.h for OS/2 [Necasek] + +Changes in 1.2.2.3 (27 May 2005) +- Replace 1U constants in inflate.c and inftrees.c for 64-bit compile +- Typecast fread() return values in gzio.c [Vollant] +- Remove trailing space in minigzip.c outmode (VC++ can't deal with it) +- Fix crc check bug in gzread() after gzungetc() [Heiner] +- Add the deflateTune() function to adjust internal compression parameters +- Add a fast gzip decompressor, gun.c, to examples (use of inflateBack) +- Remove an incorrect assertion in examples/zpipe.c +- Add C++ wrapper in infback9.h [Donais] +- Fix bug in inflateCopy() when decoding fixed codes +- Note in zlib.h how much deflateSetDictionary() actually uses +- Remove USE_DICT_HEAD in deflate.c (would mess up inflate if used) +- Add _WIN32_WCE to define WIN32 in zconf.in.h [Spencer] +- Don't include stderr.h or errno.h for _WIN32_WCE in zutil.h [Spencer] +- Add gzdirect() function to indicate transparent reads +- Update contrib/minizip [Vollant] +- Fix compilation of deflate.c when both ASMV and FASTEST [Oberhumer] +- Add casts in crc32.c to avoid warnings [Oberhumer] +- Add contrib/masmx64 [Vollant] +- Update contrib/asm586, asm686, masmx86, testzlib, vstudio [Vollant] + +Changes in 1.2.2.2 (30 December 2004) +- Replace structure assignments in deflate.c and inflate.c with zmemcpy to + avoid implicit memcpy calls (portability for no-library compilation) +- Increase sprintf() buffer size in gzdopen() to allow for large numbers +- Add INFLATE_STRICT to check distances against zlib header +- Improve WinCE errno handling and comments [Chang] +- Remove comment about no gzip header processing in FAQ +- Add Z_FIXED strategy option to deflateInit2() to force fixed trees +- Add updated make_vms.com [Coghlan], update README +- Create a new "examples" directory, move gzappend.c there, add zpipe.c, + fitblk.c, gzlog.[ch], gzjoin.c, and zlib_how.html +- Add FAQ entry and comments in deflate.c on uninitialized memory access +- Add Solaris 9 make options in configure [Gilbert] +- Allow strerror() usage in gzio.c for STDC +- Fix DecompressBuf in contrib/delphi/ZLib.pas [ManChesTer] +- Update contrib/masmx86/inffas32.asm and gvmat32.asm [Vollant] +- Use z_off_t for adler32_combine() and crc32_combine() lengths +- Make adler32() much faster for small len +- Use OS_CODE in deflate() default gzip header + +Changes in 1.2.2.1 (31 October 2004) +- Allow inflateSetDictionary() call for raw inflate +- Fix inflate header crc check bug for file names and comments +- Add deflateSetHeader() and gz_header structure for custom gzip headers +- Add inflateGetheader() to retrieve gzip headers +- Add crc32_combine() and adler32_combine() functions +- Add alloc_func, free_func, in_func, out_func to Z_PREFIX list +- Use zstreamp consistently in zlib.h (inflate_back functions) +- Remove GUNZIP condition from definition of inflate_mode in inflate.h + and in contrib/inflate86/inffast.S [Truta, Anderson] +- Add support for AMD64 in contrib/inflate86/inffas86.c [Anderson] +- Update projects/README.projects and projects/visualc6 [Truta] +- Update win32/DLL_FAQ.txt [Truta] +- Avoid warning under NO_GZCOMPRESS in gzio.c; fix typo [Truta] +- Deprecate Z_ASCII; use Z_TEXT instead [Truta] +- Use a new algorithm for setting strm->data_type in trees.c [Truta] +- Do not define an exit() prototype in zutil.c unless DEBUG defined +- Remove prototype of exit() from zutil.c, example.c, minigzip.c [Truta] +- Add comment in zlib.h for Z_NO_FLUSH parameter to deflate() +- Fix Darwin build version identification [Peterson] + +Changes in 1.2.2 (3 October 2004) +- Update zlib.h comments on gzip in-memory processing +- Set adler to 1 in inflateReset() to support Java test suite [Walles] +- Add contrib/dotzlib [Ravn] +- Update win32/DLL_FAQ.txt [Truta] +- Update contrib/minizip [Vollant] +- Move contrib/visual-basic.txt to old/ [Truta] +- Fix assembler builds in projects/visualc6/ [Truta] + +Changes in 1.2.1.2 (9 September 2004) +- Update INDEX file +- Fix trees.c to update strm->data_type (no one ever noticed!) +- Fix bug in error case in inflate.c, infback.c, and infback9.c [Brown] +- Add "volatile" to crc table flag declaration (for DYNAMIC_CRC_TABLE) +- Add limited multitasking protection to DYNAMIC_CRC_TABLE +- Add NO_vsnprintf for VMS in zutil.h [Mozilla] +- Don't declare strerror() under VMS [Mozilla] +- Add comment to DYNAMIC_CRC_TABLE to use get_crc_table() to initialize +- Update contrib/ada [Anisimkov] +- Update contrib/minizip [Vollant] +- Fix configure to not hardcode directories for Darwin [Peterson] +- Fix gzio.c to not return error on empty files [Brown] +- Fix indentation; update version in contrib/delphi/ZLib.pas and + contrib/pascal/zlibpas.pas [Truta] +- Update mkasm.bat in contrib/masmx86 [Truta] +- Update contrib/untgz [Truta] +- Add projects/README.projects [Truta] +- Add project for MS Visual C++ 6.0 in projects/visualc6 [Cadieux, Truta] +- Update win32/DLL_FAQ.txt [Truta] +- Update list of Z_PREFIX symbols in zconf.h [Randers-Pehrson, Truta] +- Remove an unnecessary assignment to curr in inftrees.c [Truta] +- Add OS/2 to exe builds in configure [Poltorak] +- Remove err dummy parameter in zlib.h [Kientzle] + +Changes in 1.2.1.1 (9 January 2004) +- Update email address in README +- Several FAQ updates +- Fix a big fat bug in inftrees.c that prevented decoding valid + dynamic blocks with only literals and no distance codes -- + Thanks to "Hot Emu" for the bug report and sample file +- Add a note to puff.c on no distance codes case + +Changes in 1.2.1 (17 November 2003) +- Remove a tab in contrib/gzappend/gzappend.c +- Update some interfaces in contrib for new zlib functions +- Update zlib version number in some contrib entries +- Add Windows CE definition for ptrdiff_t in zutil.h [Mai, Truta] +- Support shared libraries on Hurd and KFreeBSD [Brown] +- Fix error in NO_DIVIDE option of adler32.c + +Changes in 1.2.0.8 (4 November 2003) +- Update version in contrib/delphi/ZLib.pas and contrib/pascal/zlibpas.pas +- Add experimental NO_DIVIDE #define in adler32.c + - Possibly faster on some processors (let me know if it is) +- Correct Z_BLOCK to not return on first inflate call if no wrap +- Fix strm->data_type on inflate() return to correctly indicate EOB +- Add deflatePrime() function for appending in the middle of a byte +- Add contrib/gzappend for an example of appending to a stream +- Update win32/DLL_FAQ.txt [Truta] +- Delete Turbo C comment in README [Truta] +- Improve some indentation in zconf.h [Truta] +- Fix infinite loop on bad input in configure script [Church] +- Fix gzeof() for concatenated gzip files [Johnson] +- Add example to contrib/visual-basic.txt [Michael B.] +- Add -p to mkdir's in Makefile.in [vda] +- Fix configure to properly detect presence or lack of printf functions +- Add AS400 support [Monnerat] +- Add a little Cygwin support [Wilson] + +Changes in 1.2.0.7 (21 September 2003) +- Correct some debug formats in contrib/infback9 +- Cast a type in a debug statement in trees.c +- Change search and replace delimiter in configure from % to # [Beebe] +- Update contrib/untgz to 0.2 with various fixes [Truta] +- Add build support for Amiga [Nikl] +- Remove some directories in old that have been updated to 1.2 +- Add dylib building for Mac OS X in configure and Makefile.in +- Remove old distribution stuff from Makefile +- Update README to point to DLL_FAQ.txt, and add comment on Mac OS X +- Update links in README + +Changes in 1.2.0.6 (13 September 2003) +- Minor FAQ updates +- Update contrib/minizip to 1.00 [Vollant] +- Remove test of gz functions in example.c when GZ_COMPRESS defined [Truta] +- Update POSTINC comment for 68060 [Nikl] +- Add contrib/infback9 with deflate64 decoding (unsupported) +- For MVS define NO_vsnprintf and undefine FAR [van Burik] +- Add pragma for fdopen on MVS [van Burik] + +Changes in 1.2.0.5 (8 September 2003) +- Add OF to inflateBackEnd() declaration in zlib.h +- Remember start when using gzdopen in the middle of a file +- Use internal off_t counters in gz* functions to properly handle seeks +- Perform more rigorous check for distance-too-far in inffast.c +- Add Z_BLOCK flush option to return from inflate at block boundary +- Set strm->data_type on return from inflate + - Indicate bits unused, if at block boundary, and if in last block +- Replace size_t with ptrdiff_t in crc32.c, and check for correct size +- Add condition so old NO_DEFLATE define still works for compatibility +- FAQ update regarding the Windows DLL [Truta] +- INDEX update: add qnx entry, remove aix entry [Truta] +- Install zlib.3 into mandir [Wilson] +- Move contrib/zlib_dll_FAQ.txt to win32/DLL_FAQ.txt; update [Truta] +- Adapt the zlib interface to the new DLL convention guidelines [Truta] +- Introduce ZLIB_WINAPI macro to allow the export of functions using + the WINAPI calling convention, for Visual Basic [Vollant, Truta] +- Update msdos and win32 scripts and makefiles [Truta] +- Export symbols by name, not by ordinal, in win32/zlib.def [Truta] +- Add contrib/ada [Anisimkov] +- Move asm files from contrib/vstudio/vc70_32 to contrib/asm386 [Truta] +- Rename contrib/asm386 to contrib/masmx86 [Truta, Vollant] +- Add contrib/masm686 [Truta] +- Fix offsets in contrib/inflate86 and contrib/masmx86/inffas32.asm + [Truta, Vollant] +- Update contrib/delphi; rename to contrib/pascal; add example [Truta] +- Remove contrib/delphi2; add a new contrib/delphi [Truta] +- Avoid inclusion of the nonstandard in contrib/iostream, + and fix some method prototypes [Truta] +- Fix the ZCR_SEED2 constant to avoid warnings in contrib/minizip + [Truta] +- Avoid the use of backslash (\) in contrib/minizip [Vollant] +- Fix file time handling in contrib/untgz; update makefiles [Truta] +- Update contrib/vstudio/vc70_32 to comply with the new DLL guidelines + [Vollant] +- Remove contrib/vstudio/vc15_16 [Vollant] +- Rename contrib/vstudio/vc70_32 to contrib/vstudio/vc7 [Truta] +- Update README.contrib [Truta] +- Invert the assignment order of match_head and s->prev[...] in + INSERT_STRING [Truta] +- Compare TOO_FAR with 32767 instead of 32768, to avoid 16-bit warnings + [Truta] +- Compare function pointers with 0, not with NULL or Z_NULL [Truta] +- Fix prototype of syncsearch in inflate.c [Truta] +- Introduce ASMINF macro to be enabled when using an ASM implementation + of inflate_fast [Truta] +- Change NO_DEFLATE to NO_GZCOMPRESS [Truta] +- Modify test_gzio in example.c to take a single file name as a + parameter [Truta] +- Exit the example.c program if gzopen fails [Truta] +- Add type casts around strlen in example.c [Truta] +- Remove casting to sizeof in minigzip.c; give a proper type + to the variable compared with SUFFIX_LEN [Truta] +- Update definitions of STDC and STDC99 in zconf.h [Truta] +- Synchronize zconf.h with the new Windows DLL interface [Truta] +- Use SYS16BIT instead of __32BIT__ to distinguish between + 16- and 32-bit platforms [Truta] +- Use far memory allocators in small 16-bit memory models for + Turbo C [Truta] +- Add info about the use of ASMV, ASMINF and ZLIB_WINAPI in + zlibCompileFlags [Truta] +- Cygwin has vsnprintf [Wilson] +- In Windows16, OS_CODE is 0, as in MSDOS [Truta] +- In Cygwin, OS_CODE is 3 (Unix), not 11 (Windows32) [Wilson] + +Changes in 1.2.0.4 (10 August 2003) +- Minor FAQ updates +- Be more strict when checking inflateInit2's windowBits parameter +- Change NO_GUNZIP compile option to NO_GZIP to cover deflate as well +- Add gzip wrapper option to deflateInit2 using windowBits +- Add updated QNX rule in configure and qnx directory [Bonnefoy] +- Make inflate distance-too-far checks more rigorous +- Clean up FAR usage in inflate +- Add casting to sizeof() in gzio.c and minigzip.c + +Changes in 1.2.0.3 (19 July 2003) +- Fix silly error in gzungetc() implementation [Vollant] +- Update contrib/minizip and contrib/vstudio [Vollant] +- Fix printf format in example.c +- Correct cdecl support in zconf.in.h [Anisimkov] +- Minor FAQ updates + +Changes in 1.2.0.2 (13 July 2003) +- Add ZLIB_VERNUM in zlib.h for numerical preprocessor comparisons +- Attempt to avoid warnings in crc32.c for pointer-int conversion +- Add AIX to configure, remove aix directory [Bakker] +- Add some casts to minigzip.c +- Improve checking after insecure sprintf() or vsprintf() calls +- Remove #elif's from crc32.c +- Change leave label to inf_leave in inflate.c and infback.c to avoid + library conflicts +- Remove inflate gzip decoding by default--only enable gzip decoding by + special request for stricter backward compatibility +- Add zlibCompileFlags() function to return compilation information +- More typecasting in deflate.c to avoid warnings +- Remove leading underscore from _Capital #defines [Truta] +- Fix configure to link shared library when testing +- Add some Windows CE target adjustments [Mai] +- Remove #define ZLIB_DLL in zconf.h [Vollant] +- Add zlib.3 [Rodgers] +- Update RFC URL in deflate.c and algorithm.txt [Mai] +- Add zlib_dll_FAQ.txt to contrib [Truta] +- Add UL to some constants [Truta] +- Update minizip and vstudio [Vollant] +- Remove vestigial NEED_DUMMY_RETURN from zconf.in.h +- Expand use of NO_DUMMY_DECL to avoid all dummy structures +- Added iostream3 to contrib [Schwardt] +- Replace rewind() with fseek() for WinCE [Truta] +- Improve setting of zlib format compression level flags + - Report 0 for huffman and rle strategies and for level == 0 or 1 + - Report 2 only for level == 6 +- Only deal with 64K limit when necessary at compile time [Truta] +- Allow TOO_FAR check to be turned off at compile time [Truta] +- Add gzclearerr() function [Souza] +- Add gzungetc() function + +Changes in 1.2.0.1 (17 March 2003) +- Add Z_RLE strategy for run-length encoding [Truta] + - When Z_RLE requested, restrict matches to distance one + - Update zlib.h, minigzip.c, gzopen(), gzdopen() for Z_RLE +- Correct FASTEST compilation to allow level == 0 +- Clean up what gets compiled for FASTEST +- Incorporate changes to zconf.in.h [Vollant] + - Refine detection of Turbo C need for dummy returns + - Refine ZLIB_DLL compilation + - Include additional header file on VMS for off_t typedef +- Try to use _vsnprintf where it supplants vsprintf [Vollant] +- Add some casts in inffast.c +- Enhance comments in zlib.h on what happens if gzprintf() tries to + write more than 4095 bytes before compression +- Remove unused state from inflateBackEnd() +- Remove exit(0) from minigzip.c, example.c +- Get rid of all those darn tabs +- Add "check" target to Makefile.in that does the same thing as "test" +- Add "mostlyclean" and "maintainer-clean" targets to Makefile.in +- Update contrib/inflate86 [Anderson] +- Update contrib/testzlib, contrib/vstudio, contrib/minizip [Vollant] +- Add msdos and win32 directories with makefiles [Truta] +- More additions and improvements to the FAQ + +Changes in 1.2.0 (9 March 2003) +- New and improved inflate code + - About 20% faster + - Does not allocate 32K window unless and until needed + - Automatically detects and decompresses gzip streams + - Raw inflate no longer needs an extra dummy byte at end + - Added inflateBack functions using a callback interface--even faster + than inflate, useful for file utilities (gzip, zip) + - Added inflateCopy() function to record state for random access on + externally generated deflate streams (e.g. in gzip files) + - More readable code (I hope) +- New and improved crc32() + - About 50% faster, thanks to suggestions from Rodney Brown +- Add deflateBound() and compressBound() functions +- Fix memory leak in deflateInit2() +- Permit setting dictionary for raw deflate (for parallel deflate) +- Fix const declaration for gzwrite() +- Check for some malloc() failures in gzio.c +- Fix bug in gzopen() on single-byte file 0x1f +- Fix bug in gzread() on concatenated file with 0x1f at end of buffer + and next buffer doesn't start with 0x8b +- Fix uncompress() to return Z_DATA_ERROR on truncated input +- Free memory at end of example.c +- Remove MAX #define in trees.c (conflicted with some libraries) +- Fix static const's in deflate.c, gzio.c, and zutil.[ch] +- Declare malloc() and free() in gzio.c if STDC not defined +- Use malloc() instead of calloc() in zutil.c if int big enough +- Define STDC for AIX +- Add aix/ with approach for compiling shared library on AIX +- Add HP-UX support for shared libraries in configure +- Add OpenUNIX support for shared libraries in configure +- Use $cc instead of gcc to build shared library +- Make prefix directory if needed when installing +- Correct Macintosh avoidance of typedef Byte in zconf.h +- Correct Turbo C memory allocation when under Linux +- Use libz.a instead of -lz in Makefile (assure use of compiled library) +- Update configure to check for snprintf or vsnprintf functions and their + return value, warn during make if using an insecure function +- Fix configure problem with compile-time knowledge of HAVE_UNISTD_H that + is lost when library is used--resolution is to build new zconf.h +- Documentation improvements (in zlib.h): + - Document raw deflate and inflate + - Update RFCs URL + - Point out that zlib and gzip formats are different + - Note that Z_BUF_ERROR is not fatal + - Document string limit for gzprintf() and possible buffer overflow + - Note requirement on avail_out when flushing + - Note permitted values of flush parameter of inflate() +- Add some FAQs (and even answers) to the FAQ +- Add contrib/inflate86/ for x86 faster inflate +- Add contrib/blast/ for PKWare Data Compression Library decompression +- Add contrib/puff/ simple inflate for deflate format description + +Changes in 1.1.4 (11 March 2002) +- ZFREE was repeated on same allocation on some error conditions + This creates a security problem described in + http://www.zlib.org/advisory-2002-03-11.txt +- Returned incorrect error (Z_MEM_ERROR) on some invalid data +- Avoid accesses before window for invalid distances with inflate window + less than 32K +- force windowBits > 8 to avoid a bug in the encoder for a window size + of 256 bytes. (A complete fix will be available in 1.1.5) + +Changes in 1.1.3 (9 July 1998) +- fix "an inflate input buffer bug that shows up on rare but persistent + occasions" (Mark) +- fix gzread and gztell for concatenated .gz files (Didier Le Botlan) +- fix gzseek(..., SEEK_SET) in write mode +- fix crc check after a gzeek (Frank Faubert) +- fix miniunzip when the last entry in a zip file is itself a zip file + (J Lillge) +- add contrib/asm586 and contrib/asm686 (Brian Raiter) + See http://www.muppetlabs.com/~breadbox/software/assembly.html +- add support for Delphi 3 in contrib/delphi (Bob Dellaca) +- add support for C++Builder 3 and Delphi 3 in contrib/delphi2 (Davide Moretti) +- do not exit prematurely in untgz if 0 at start of block (Magnus Holmgren) +- use macro EXTERN instead of extern to support DLL for BeOS (Sander Stoks) +- added a FAQ file + +- Support gzdopen on Mac with Metrowerks (Jason Linhart) +- Do not redefine Byte on Mac (Brad Pettit & Jason Linhart) +- define SEEK_END too if SEEK_SET is not defined (Albert Chin-A-Young) +- avoid some warnings with Borland C (Tom Tanner) +- fix a problem in contrib/minizip/zip.c for 16-bit MSDOS (Gilles Vollant) +- emulate utime() for WIN32 in contrib/untgz (Gilles Vollant) +- allow several arguments to configure (Tim Mooney, Frodo Looijaard) +- use libdir and includedir in Makefile.in (Tim Mooney) +- support shared libraries on OSF1 V4 (Tim Mooney) +- remove so_locations in "make clean" (Tim Mooney) +- fix maketree.c compilation error (Glenn, Mark) +- Python interface to zlib now in Python 1.5 (Jeremy Hylton) +- new Makefile.riscos (Rich Walker) +- initialize static descriptors in trees.c for embedded targets (Nick Smith) +- use "foo-gz" in example.c for RISCOS and VMS (Nick Smith) +- add the OS/2 files in Makefile.in too (Andrew Zabolotny) +- fix fdopen and halloc macros for Microsoft C 6.0 (Tom Lane) +- fix maketree.c to allow clean compilation of inffixed.h (Mark) +- fix parameter check in deflateCopy (Gunther Nikl) +- cleanup trees.c, use compressed_len only in debug mode (Christian Spieler) +- Many portability patches by Christian Spieler: + . zutil.c, zutil.h: added "const" for zmem* + . Make_vms.com: fixed some typos + . Make_vms.com: msdos/Makefile.*: removed zutil.h from some dependency lists + . msdos/Makefile.msc: remove "default rtl link library" info from obj files + . msdos/Makefile.*: use model-dependent name for the built zlib library + . msdos/Makefile.emx, nt/Makefile.emx, nt/Makefile.gcc: + new makefiles, for emx (DOS/OS2), emx&rsxnt and mingw32 (Windows 9x / NT) +- use define instead of typedef for Bytef also for MSC small/medium (Tom Lane) +- replace __far with _far for better portability (Christian Spieler, Tom Lane) +- fix test for errno.h in configure (Tim Newsham) + +Changes in 1.1.2 (19 March 98) +- added contrib/minzip, mini zip and unzip based on zlib (Gilles Vollant) + See http://www.winimage.com/zLibDll/unzip.html +- preinitialize the inflate tables for fixed codes, to make the code + completely thread safe (Mark) +- some simplifications and slight speed-up to the inflate code (Mark) +- fix gzeof on non-compressed files (Allan Schrum) +- add -std1 option in configure for OSF1 to fix gzprintf (Martin Mokrejs) +- use default value of 4K for Z_BUFSIZE for 16-bit MSDOS (Tim Wegner + Glenn) +- added os2/Makefile.def and os2/zlib.def (Andrew Zabolotny) +- add shared lib support for UNIX_SV4.2MP (MATSUURA Takanori) +- do not wrap extern "C" around system includes (Tom Lane) +- mention zlib binding for TCL in README (Andreas Kupries) +- added amiga/Makefile.pup for Amiga powerUP SAS/C PPC (Andreas Kleinert) +- allow "make install prefix=..." even after configure (Glenn Randers-Pehrson) +- allow "configure --prefix $HOME" (Tim Mooney) +- remove warnings in example.c and gzio.c (Glenn Randers-Pehrson) +- move Makefile.sas to amiga/Makefile.sas + +Changes in 1.1.1 (27 Feb 98) +- fix macros _tr_tally_* in deflate.h for debug mode (Glenn Randers-Pehrson) +- remove block truncation heuristic which had very marginal effect for zlib + (smaller lit_bufsize than in gzip 1.2.4) and degraded a little the + compression ratio on some files. This also allows inlining _tr_tally for + matches in deflate_slow +- added msdos/Makefile.w32 for WIN32 Microsoft Visual C++ (Bob Frazier) + +Changes in 1.1.0 (24 Feb 98) +- do not return STREAM_END prematurely in inflate (John Bowler) +- revert to the zlib 1.0.8 inflate to avoid the gcc 2.8.0 bug (Jeremy Buhler) +- compile with -DFASTEST to get compression code optimized for speed only +- in minigzip, try mmap'ing the input file first (Miguel Albrecht) +- increase size of I/O buffers in minigzip.c and gzio.c (not a big gain + on Sun but significant on HP) + +- add a pointer to experimental unzip library in README (Gilles Vollant) +- initialize variable gcc in configure (Chris Herborth) + +Changes in 1.0.9 (17 Feb 1998) +- added gzputs and gzgets functions +- do not clear eof flag in gzseek (Mark Diekhans) +- fix gzseek for files in transparent mode (Mark Diekhans) +- do not assume that vsprintf returns the number of bytes written (Jens Krinke) +- replace EXPORT with ZEXPORT to avoid conflict with other programs +- added compress2 in zconf.h, zlib.def, zlib.dnt +- new asm code from Gilles Vollant in contrib/asm386 +- simplify the inflate code (Mark): + . Replace ZALLOC's in huft_build() with single ZALLOC in inflate_blocks_new() + . ZALLOC the length list in inflate_trees_fixed() instead of using stack + . ZALLOC the value area for huft_build() instead of using stack + . Simplify Z_FINISH check in inflate() + +- Avoid gcc 2.8.0 comparison bug a little differently than zlib 1.0.8 +- in inftrees.c, avoid cc -O bug on HP (Farshid Elahi) +- in zconf.h move the ZLIB_DLL stuff earlier to avoid problems with + the declaration of FAR (Gilles Vollant) +- install libz.so* with mode 755 (executable) instead of 644 (Marc Lehmann) +- read_buf buf parameter of type Bytef* instead of charf* +- zmemcpy parameters are of type Bytef*, not charf* (Joseph Strout) +- do not redeclare unlink in minigzip.c for WIN32 (John Bowler) +- fix check for presence of directories in "make install" (Ian Willis) + +Changes in 1.0.8 (27 Jan 1998) +- fixed offsets in contrib/asm386/gvmat32.asm (Gilles Vollant) +- fix gzgetc and gzputc for big endian systems (Markus Oberhumer) +- added compress2() to allow setting the compression level +- include sys/types.h to get off_t on some systems (Marc Lehmann & QingLong) +- use constant arrays for the static trees in trees.c instead of computing + them at run time (thanks to Ken Raeburn for this suggestion). To create + trees.h, compile with GEN_TREES_H and run "make test" +- check return code of example in "make test" and display result +- pass minigzip command line options to file_compress +- simplifying code of inflateSync to avoid gcc 2.8 bug + +- support CC="gcc -Wall" in configure -s (QingLong) +- avoid a flush caused by ftell in gzopen for write mode (Ken Raeburn) +- fix test for shared library support to avoid compiler warnings +- zlib.lib -> zlib.dll in msdos/zlib.rc (Gilles Vollant) +- check for TARGET_OS_MAC in addition to MACOS (Brad Pettit) +- do not use fdopen for Metrowerks on Mac (Brad Pettit)) +- add checks for gzputc and gzputc in example.c +- avoid warnings in gzio.c and deflate.c (Andreas Kleinert) +- use const for the CRC table (Ken Raeburn) +- fixed "make uninstall" for shared libraries +- use Tracev instead of Trace in infblock.c +- in example.c use correct compressed length for test_sync +- suppress +vnocompatwarnings in configure for HPUX (not always supported) + +Changes in 1.0.7 (20 Jan 1998) +- fix gzseek which was broken in write mode +- return error for gzseek to negative absolute position +- fix configure for Linux (Chun-Chung Chen) +- increase stack space for MSC (Tim Wegner) +- get_crc_table and inflateSyncPoint are EXPORTed (Gilles Vollant) +- define EXPORTVA for gzprintf (Gilles Vollant) +- added man page zlib.3 (Rick Rodgers) +- for contrib/untgz, fix makedir() and improve Makefile + +- check gzseek in write mode in example.c +- allocate extra buffer for seeks only if gzseek is actually called +- avoid signed/unsigned comparisons (Tim Wegner, Gilles Vollant) +- add inflateSyncPoint in zconf.h +- fix list of exported functions in nt/zlib.dnt and mdsos/zlib.def + +Changes in 1.0.6 (19 Jan 1998) +- add functions gzprintf, gzputc, gzgetc, gztell, gzeof, gzseek, gzrewind and + gzsetparams (thanks to Roland Giersig and Kevin Ruland for some of this code) +- Fix a deflate bug occurring only with compression level 0 (thanks to + Andy Buckler for finding this one) +- In minigzip, pass transparently also the first byte for .Z files +- return Z_BUF_ERROR instead of Z_OK if output buffer full in uncompress() +- check Z_FINISH in inflate (thanks to Marc Schluper) +- Implement deflateCopy (thanks to Adam Costello) +- make static libraries by default in configure, add --shared option +- move MSDOS or Windows specific files to directory msdos +- suppress the notion of partial flush to simplify the interface + (but the symbol Z_PARTIAL_FLUSH is kept for compatibility with 1.0.4) +- suppress history buffer provided by application to simplify the interface + (this feature was not implemented anyway in 1.0.4) +- next_in and avail_in must be initialized before calling inflateInit or + inflateInit2 +- add EXPORT in all exported functions (for Windows DLL) +- added Makefile.nt (thanks to Stephen Williams) +- added the unsupported "contrib" directory: + contrib/asm386/ by Gilles Vollant + 386 asm code replacing longest_match() + contrib/iostream/ by Kevin Ruland + A C++ I/O streams interface to the zlib gz* functions + contrib/iostream2/ by Tyge Løvset + Another C++ I/O streams interface + contrib/untgz/ by "Pedro A. Aranda Guti\irrez" + A very simple tar.gz file extractor using zlib + contrib/visual-basic.txt by Carlos Rios + How to use compress(), uncompress() and the gz* functions from VB +- pass params -f (filtered data), -h (huffman only), -1 to -9 (compression + level) in minigzip (thanks to Tom Lane) + +- use const for rommable constants in deflate +- added test for gzseek and gztell in example.c +- add undocumented function inflateSyncPoint() (hack for Paul Mackerras) +- add undocumented function zError to convert error code to string + (for Tim Smithers) +- Allow compilation of gzio with -DNO_DEFLATE to avoid the compression code +- Use default memcpy for Symantec MSDOS compiler +- Add EXPORT keyword for check_func (needed for Windows DLL) +- add current directory to LD_LIBRARY_PATH for "make test" +- create also a link for libz.so.1 +- added support for FUJITSU UXP/DS (thanks to Toshiaki Nomura) +- use $(SHAREDLIB) instead of libz.so in Makefile.in (for HPUX) +- added -soname for Linux in configure (Chun-Chung Chen, +- assign numbers to the exported functions in zlib.def (for Windows DLL) +- add advice in zlib.h for best usage of deflateSetDictionary +- work around compiler bug on Atari (cast Z_NULL in call of s->checkfn) +- allow compilation with ANSI keywords only enabled for TurboC in large model +- avoid "versionString"[0] (Borland bug) +- add NEED_DUMMY_RETURN for Borland +- use variable z_verbose for tracing in debug mode (L. Peter Deutsch) +- allow compilation with CC +- defined STDC for OS/2 (David Charlap) +- limit external names to 8 chars for MVS (Thomas Lund) +- in minigzip.c, use static buffers only for 16-bit systems +- fix suffix check for "minigzip -d foo.gz" +- do not return an error for the 2nd of two consecutive gzflush() (Felix Lee) +- use _fdopen instead of fdopen for MSC >= 6.0 (Thomas Fanslau) +- added makelcc.bat for lcc-win32 (Tom St Denis) +- in Makefile.dj2, use copy and del instead of install and rm (Frank Donahoe) +- Avoid expanded $Id$. Use "rcs -kb" or "cvs admin -kb" to avoid Id expansion +- check for unistd.h in configure (for off_t) +- remove useless check parameter in inflate_blocks_free +- avoid useless assignment of s->check to itself in inflate_blocks_new +- do not flush twice in gzclose (thanks to Ken Raeburn) +- rename FOPEN as F_OPEN to avoid clash with /usr/include/sys/file.h +- use NO_ERRNO_H instead of enumeration of operating systems with errno.h +- work around buggy fclose on pipes for HP/UX +- support zlib DLL with BORLAND C++ 5.0 (thanks to Glenn Randers-Pehrson) +- fix configure if CC is already equal to gcc + +Changes in 1.0.5 (3 Jan 98) +- Fix inflate to terminate gracefully when fed corrupted or invalid data +- Use const for rommable constants in inflate +- Eliminate memory leaks on error conditions in inflate +- Removed some vestigial code in inflate +- Update web address in README + +Changes in 1.0.4 (24 Jul 96) +- In very rare conditions, deflate(s, Z_FINISH) could fail to produce an EOF + bit, so the decompressor could decompress all the correct data but went + on to attempt decompressing extra garbage data. This affected minigzip too +- zlibVersion and gzerror return const char* (needed for DLL) +- port to RISCOS (no fdopen, no multiple dots, no unlink, no fileno) +- use z_error only for DEBUG (avoid problem with DLLs) + +Changes in 1.0.3 (2 Jul 96) +- use z_streamp instead of z_stream *, which is now a far pointer in MSDOS + small and medium models; this makes the library incompatible with previous + versions for these models. (No effect in large model or on other systems.) +- return OK instead of BUF_ERROR if previous deflate call returned with + avail_out as zero but there is nothing to do +- added memcmp for non STDC compilers +- define NO_DUMMY_DECL for more Mac compilers (.h files merged incorrectly) +- define __32BIT__ if __386__ or i386 is defined (pb. with Watcom and SCO) +- better check for 16-bit mode MSC (avoids problem with Symantec) + +Changes in 1.0.2 (23 May 96) +- added Windows DLL support +- added a function zlibVersion (for the DLL support) +- fixed declarations using Bytef in infutil.c (pb with MSDOS medium model) +- Bytef is define's instead of typedef'd only for Borland C +- avoid reading uninitialized memory in example.c +- mention in README that the zlib format is now RFC1950 +- updated Makefile.dj2 +- added algorithm.doc + +Changes in 1.0.1 (20 May 96) [1.0 skipped to avoid confusion] +- fix array overlay in deflate.c which sometimes caused bad compressed data +- fix inflate bug with empty stored block +- fix MSDOS medium model which was broken in 0.99 +- fix deflateParams() which could generate bad compressed data +- Bytef is define'd instead of typedef'ed (work around Borland bug) +- added an INDEX file +- new makefiles for DJGPP (Makefile.dj2), 32-bit Borland (Makefile.b32), + Watcom (Makefile.wat), Amiga SAS/C (Makefile.sas) +- speed up adler32 for modern machines without auto-increment +- added -ansi for IRIX in configure +- static_init_done in trees.c is an int +- define unlink as delete for VMS +- fix configure for QNX +- add configure branch for SCO and HPUX +- avoid many warnings (unused variables, dead assignments, etc...) +- no fdopen for BeOS +- fix the Watcom fix for 32 bit mode (define FAR as empty) +- removed redefinition of Byte for MKWERKS +- work around an MWKERKS bug (incorrect merge of all .h files) + +Changes in 0.99 (27 Jan 96) +- allow preset dictionary shared between compressor and decompressor +- allow compression level 0 (no compression) +- add deflateParams in zlib.h: allow dynamic change of compression level + and compression strategy +- test large buffers and deflateParams in example.c +- add optional "configure" to build zlib as a shared library +- suppress Makefile.qnx, use configure instead +- fixed deflate for 64-bit systems (detected on Cray) +- fixed inflate_blocks for 64-bit systems (detected on Alpha) +- declare Z_DEFLATED in zlib.h (possible parameter for deflateInit2) +- always return Z_BUF_ERROR when deflate() has nothing to do +- deflateInit and inflateInit are now macros to allow version checking +- prefix all global functions and types with z_ with -DZ_PREFIX +- make falloc completely reentrant (inftrees.c) +- fixed very unlikely race condition in ct_static_init +- free in reverse order of allocation to help memory manager +- use zlib-1.0/* instead of zlib/* inside the tar.gz +- make zlib warning-free with "gcc -O3 -Wall -Wwrite-strings -Wpointer-arith + -Wconversion -Wstrict-prototypes -Wmissing-prototypes" +- allow gzread on concatenated .gz files +- deflateEnd now returns Z_DATA_ERROR if it was premature +- deflate is finally (?) fully deterministic (no matches beyond end of input) +- Document Z_SYNC_FLUSH +- add uninstall in Makefile +- Check for __cpluplus in zlib.h +- Better test in ct_align for partial flush +- avoid harmless warnings for Borland C++ +- initialize hash_head in deflate.c +- avoid warning on fdopen (gzio.c) for HP cc -Aa +- include stdlib.h for STDC compilers +- include errno.h for Cray +- ignore error if ranlib doesn't exist +- call ranlib twice for NeXTSTEP +- use exec_prefix instead of prefix for libz.a +- renamed ct_* as _tr_* to avoid conflict with applications +- clear z->msg in inflateInit2 before any error return +- initialize opaque in example.c, gzio.c, deflate.c and inflate.c +- fixed typo in zconf.h (_GNUC__ => __GNUC__) +- check for WIN32 in zconf.h and zutil.c (avoid farmalloc in 32-bit mode) +- fix typo in Make_vms.com (f$trnlnm -> f$getsyi) +- in fcalloc, normalize pointer if size > 65520 bytes +- don't use special fcalloc for 32 bit Borland C++ +- use STDC instead of __GO32__ to avoid redeclaring exit, calloc, etc. +- use Z_BINARY instead of BINARY +- document that gzclose after gzdopen will close the file +- allow "a" as mode in gzopen +- fix error checking in gzread +- allow skipping .gz extra-field on pipes +- added reference to Perl interface in README +- put the crc table in FAR data (I dislike more and more the medium model :) +- added get_crc_table +- added a dimension to all arrays (Borland C can't count) +- workaround Borland C bug in declaration of inflate_codes_new & inflate_fast +- guard against multiple inclusion of *.h (for precompiled header on Mac) +- Watcom C pretends to be Microsoft C small model even in 32 bit mode +- don't use unsized arrays to avoid silly warnings by Visual C++: + warning C4746: 'inflate_mask' : unsized array treated as '__far' + (what's wrong with far data in far model?) +- define enum out of inflate_blocks_state to allow compilation with C++ + +Changes in 0.95 (16 Aug 95) +- fix MSDOS small and medium model (now easier to adapt to any compiler) +- inlined send_bits +- fix the final (:-) bug for deflate with flush (output was correct but + not completely flushed in rare occasions) +- default window size is same for compression and decompression + (it's now sufficient to set MAX_WBITS in zconf.h) +- voidp -> voidpf and voidnp -> voidp (for consistency with other + typedefs and because voidnp was not near in large model) + +Changes in 0.94 (13 Aug 95) +- support MSDOS medium model +- fix deflate with flush (could sometimes generate bad output) +- fix deflateReset (zlib header was incorrectly suppressed) +- added support for VMS +- allow a compression level in gzopen() +- gzflush now calls fflush +- For deflate with flush, flush even if no more input is provided +- rename libgz.a as libz.a +- avoid complex expression in infcodes.c triggering Turbo C bug +- work around a problem with gcc on Alpha (in INSERT_STRING) +- don't use inline functions (problem with some gcc versions) +- allow renaming of Byte, uInt, etc... with #define +- avoid warning about (unused) pointer before start of array in deflate.c +- avoid various warnings in gzio.c, example.c, infblock.c, adler32.c, zutil.c +- avoid reserved word 'new' in trees.c + +Changes in 0.93 (25 June 95) +- temporarily disable inline functions +- make deflate deterministic +- give enough lookahead for PARTIAL_FLUSH +- Set binary mode for stdin/stdout in minigzip.c for OS/2 +- don't even use signed char in inflate (not portable enough) +- fix inflate memory leak for segmented architectures + +Changes in 0.92 (3 May 95) +- don't assume that char is signed (problem on SGI) +- Clear bit buffer when starting a stored block +- no memcpy on Pyramid +- suppressed inftest.c +- optimized fill_window, put longest_match inline for gcc +- optimized inflate on stored blocks +- untabify all sources to simplify patches + +Changes in 0.91 (2 May 95) +- Default MEM_LEVEL is 8 (not 9 for Unix) as documented in zlib.h +- Document the memory requirements in zconf.h +- added "make install" +- fix sync search logic in inflateSync +- deflate(Z_FULL_FLUSH) now works even if output buffer too short +- after inflateSync, don't scare people with just "lo world" +- added support for DJGPP + +Changes in 0.9 (1 May 95) +- don't assume that zalloc clears the allocated memory (the TurboC bug + was Mark's bug after all :) +- let again gzread copy uncompressed data unchanged (was working in 0.71) +- deflate(Z_FULL_FLUSH), inflateReset and inflateSync are now fully implemented +- added a test of inflateSync in example.c +- moved MAX_WBITS to zconf.h because users might want to change that +- document explicitly that zalloc(64K) on MSDOS must return a normalized + pointer (zero offset) +- added Makefiles for Microsoft C, Turbo C, Borland C++ +- faster crc32() + +Changes in 0.8 (29 April 95) +- added fast inflate (inffast.c) +- deflate(Z_FINISH) now returns Z_STREAM_END when done. Warning: this + is incompatible with previous versions of zlib which returned Z_OK +- work around a TurboC compiler bug (bad code for b << 0, see infutil.h) + (actually that was not a compiler bug, see 0.81 above) +- gzread no longer reads one extra byte in certain cases +- In gzio destroy(), don't reference a freed structure +- avoid many warnings for MSDOS +- avoid the ERROR symbol which is used by MS Windows + +Changes in 0.71 (14 April 95) +- Fixed more MSDOS compilation problems :( There is still a bug with + TurboC large model + +Changes in 0.7 (14 April 95) +- Added full inflate support +- Simplified the crc32() interface. The pre- and post-conditioning + (one's complement) is now done inside crc32(). WARNING: this is + incompatible with previous versions; see zlib.h for the new usage + +Changes in 0.61 (12 April 95) +- workaround for a bug in TurboC. example and minigzip now work on MSDOS + +Changes in 0.6 (11 April 95) +- added minigzip.c +- added gzdopen to reopen a file descriptor as gzFile +- added transparent reading of non-gziped files in gzread +- fixed bug in gzread (don't read crc as data) +- fixed bug in destroy (gzio.c) (don't return Z_STREAM_END for gzclose) +- don't allocate big arrays in the stack (for MSDOS) +- fix some MSDOS compilation problems + +Changes in 0.5: +- do real compression in deflate.c. Z_PARTIAL_FLUSH is supported but + not yet Z_FULL_FLUSH +- support decompression but only in a single step (forced Z_FINISH) +- added opaque object for zalloc and zfree +- added deflateReset and inflateReset +- added a variable zlib_version for consistency checking +- renamed the 'filter' parameter of deflateInit2 as 'strategy' + Added Z_FILTERED and Z_HUFFMAN_ONLY constants + +Changes in 0.4: +- avoid "zip" everywhere, use zlib instead of ziplib +- suppress Z_BLOCK_FLUSH, interpret Z_PARTIAL_FLUSH as block flush + if compression method == 8 +- added adler32 and crc32 +- renamed deflateOptions as deflateInit2, call one or the other but not both +- added the method parameter for deflateInit2 +- added inflateInit2 +- simplified considerably deflateInit and inflateInit by not supporting + user-provided history buffer. This is supported only in deflateInit2 + and inflateInit2 + +Changes in 0.3: +- prefix all macro names with Z_ +- use Z_FINISH instead of deflateEnd to finish compression +- added Z_HUFFMAN_ONLY +- added gzerror() diff --git a/common/zlib/LICENSE b/common/zlib/LICENSE new file mode 100644 index 0000000..ab8ee6f --- /dev/null +++ b/common/zlib/LICENSE @@ -0,0 +1,22 @@ +Copyright notice: + + (C) 1995-2022 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu diff --git a/common/zlib/README b/common/zlib/README new file mode 100644 index 0000000..c5f9175 --- /dev/null +++ b/common/zlib/README @@ -0,0 +1,117 @@ +ZLIB DATA COMPRESSION LIBRARY + +zlib 1.3.1 is a general purpose data compression library. All the code is +thread safe. The data format used by the zlib library is described by RFCs +(Request for Comments) 1950 to 1952 in the files +http://tools.ietf.org/html/rfc1950 (zlib format), rfc1951 (deflate format) and +rfc1952 (gzip format). + +All functions of the compression library are documented in the file zlib.h +(volunteer to write man pages welcome, contact zlib@gzip.org). A usage example +of the library is given in the file test/example.c which also tests that +the library is working correctly. Another example is given in the file +test/minigzip.c. The compression library itself is composed of all source +files in the root directory. + +To compile all files and run the test program, follow the instructions given at +the top of Makefile.in. In short "./configure; make test", and if that goes +well, "make install" should work for most flavors of Unix. For Windows, use +one of the special makefiles in win32/ or contrib/vstudio/ . For VMS, use +make_vms.com. + +Questions about zlib should be sent to , or to Gilles Vollant + for the Windows DLL version. The zlib home page is +http://zlib.net/ . Before reporting a problem, please check this site to +verify that you have the latest version of zlib; otherwise get the latest +version and check whether the problem still exists or not. + +PLEASE read the zlib FAQ http://zlib.net/zlib_faq.html before asking for help. + +Mark Nelson wrote an article about zlib for the Jan. 1997 +issue of Dr. Dobb's Journal; a copy of the article is available at +https://marknelson.us/posts/1997/01/01/zlib-engine.html . + +The changes made in version 1.3.1 are documented in the file ChangeLog. + +Unsupported third party contributions are provided in directory contrib/ . + +zlib is available in Java using the java.util.zip package. Follow the API +Documentation link at: https://docs.oracle.com/search/?q=java.util.zip . + +A Perl interface to zlib and bzip2 written by Paul Marquess +can be found at https://github.com/pmqs/IO-Compress . + +A Python interface to zlib written by A.M. Kuchling is +available in Python 1.5 and later versions, see +http://docs.python.org/library/zlib.html . + +zlib is built into tcl: http://wiki.tcl.tk/4610 . + +An experimental package to read and write files in .zip format, written on top +of zlib by Gilles Vollant , is available in the +contrib/minizip directory of zlib. + + +Notes for some targets: + +- For Windows DLL versions, please see win32/DLL_FAQ.txt + +- For 64-bit Irix, deflate.c must be compiled without any optimization. With + -O, one libpng test fails. The test works in 32 bit mode (with the -n32 + compiler flag). The compiler bug has been reported to SGI. + +- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1 it works + when compiled with cc. + +- On Digital Unix 4.0D (formerly OSF/1) on AlphaServer, the cc option -std1 is + necessary to get gzprintf working correctly. This is done by configure. + +- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works with + other compilers. Use "make test" to check your compiler. + +- gzdopen is not supported on RISCOS or BEOS. + +- For PalmOs, see http://palmzlib.sourceforge.net/ + + +Acknowledgments: + + The deflate format used by zlib was defined by Phil Katz. The deflate and + zlib specifications were written by L. Peter Deutsch. Thanks to all the + people who reported problems and suggested various improvements in zlib; they + are too numerous to cite here. + +Copyright notice: + + (C) 1995-2024 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + +If you use the zlib library in a product, we would appreciate *not* receiving +lengthy legal documents to sign. The sources are provided for free but without +warranty of any kind. The library has been entirely written by Jean-loup +Gailly and Mark Adler; it does not include third-party code. We make all +contributions to and distributions of this project solely in our personal +capacity, and are not conveying any rights to any intellectual property of +any third parties. + +If you redistribute modified sources, we would appreciate that you include in +the file ChangeLog history information documenting your changes. Please read +the FAQ for more information on the distribution of modified source versions. diff --git a/common/zlib/adler32.c b/common/zlib/adler32.c new file mode 100755 index 0000000..04b81d2 --- /dev/null +++ b/common/zlib/adler32.c @@ -0,0 +1,164 @@ +/* adler32.c -- compute the Adler-32 checksum of a data stream + * Copyright (C) 1995-2011, 2016 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#include "zutil.h" + +#define BASE 65521U /* largest prime smaller than 65536 */ +#define NMAX 5552 +/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ + +#define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;} +#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); +#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); +#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); +#define DO16(buf) DO8(buf,0); DO8(buf,8); + +/* use NO_DIVIDE if your processor does not do division in hardware -- + try it both ways to see which is faster */ +#ifdef NO_DIVIDE +/* note that this assumes BASE is 65521, where 65536 % 65521 == 15 + (thank you to John Reiser for pointing this out) */ +# define CHOP(a) \ + do { \ + unsigned long tmp = a >> 16; \ + a &= 0xffffUL; \ + a += (tmp << 4) - tmp; \ + } while (0) +# define MOD28(a) \ + do { \ + CHOP(a); \ + if (a >= BASE) a -= BASE; \ + } while (0) +# define MOD(a) \ + do { \ + CHOP(a); \ + MOD28(a); \ + } while (0) +# define MOD63(a) \ + do { /* this assumes a is not negative */ \ + z_off64_t tmp = a >> 32; \ + a &= 0xffffffffL; \ + a += (tmp << 8) - (tmp << 5) + tmp; \ + tmp = a >> 16; \ + a &= 0xffffL; \ + a += (tmp << 4) - tmp; \ + tmp = a >> 16; \ + a &= 0xffffL; \ + a += (tmp << 4) - tmp; \ + if (a >= BASE) a -= BASE; \ + } while (0) +#else +# define MOD(a) a %= BASE +# define MOD28(a) a %= BASE +# define MOD63(a) a %= BASE +#endif + +/* ========================================================================= */ +uLong ZEXPORT adler32_z(uLong adler, const Bytef *buf, z_size_t len) { + unsigned long sum2; + unsigned n; + + /* split Adler-32 into component sums */ + sum2 = (adler >> 16) & 0xffff; + adler &= 0xffff; + + /* in case user likes doing a byte at a time, keep it fast */ + if (len == 1) { + adler += buf[0]; + if (adler >= BASE) + adler -= BASE; + sum2 += adler; + if (sum2 >= BASE) + sum2 -= BASE; + return adler | (sum2 << 16); + } + + /* initial Adler-32 value (deferred check for len == 1 speed) */ + if (buf == Z_NULL) + return 1L; + + /* in case short lengths are provided, keep it somewhat fast */ + if (len < 16) { + while (len--) { + adler += *buf++; + sum2 += adler; + } + if (adler >= BASE) + adler -= BASE; + MOD28(sum2); /* only added so many BASE's */ + return adler | (sum2 << 16); + } + + /* do length NMAX blocks -- requires just one modulo operation */ + while (len >= NMAX) { + len -= NMAX; + n = NMAX / 16; /* NMAX is divisible by 16 */ + do { + DO16(buf); /* 16 sums unrolled */ + buf += 16; + } while (--n); + MOD(adler); + MOD(sum2); + } + + /* do remaining bytes (less than NMAX, still just one modulo) */ + if (len) { /* avoid modulos if none remaining */ + while (len >= 16) { + len -= 16; + DO16(buf); + buf += 16; + } + while (len--) { + adler += *buf++; + sum2 += adler; + } + MOD(adler); + MOD(sum2); + } + + /* return recombined sums */ + return adler | (sum2 << 16); +} + +/* ========================================================================= */ +uLong ZEXPORT adler32(uLong adler, const Bytef *buf, uInt len) { + return adler32_z(adler, buf, len); +} + +/* ========================================================================= */ +local uLong adler32_combine_(uLong adler1, uLong adler2, z_off64_t len2) { + unsigned long sum1; + unsigned long sum2; + unsigned rem; + + /* for negative len, return invalid adler32 as a clue for debugging */ + if (len2 < 0) + return 0xffffffffUL; + + /* the derivation of this formula is left as an exercise for the reader */ + MOD63(len2); /* assumes len2 >= 0 */ + rem = (unsigned)len2; + sum1 = adler1 & 0xffff; + sum2 = rem * sum1; + MOD(sum2); + sum1 += (adler2 & 0xffff) + BASE - 1; + sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem; + if (sum1 >= BASE) sum1 -= BASE; + if (sum1 >= BASE) sum1 -= BASE; + if (sum2 >= ((unsigned long)BASE << 1)) sum2 -= ((unsigned long)BASE << 1); + if (sum2 >= BASE) sum2 -= BASE; + return sum1 | (sum2 << 16); +} + +/* ========================================================================= */ +uLong ZEXPORT adler32_combine(uLong adler1, uLong adler2, z_off_t len2) { + return adler32_combine_(adler1, adler2, len2); +} + +uLong ZEXPORT adler32_combine64(uLong adler1, uLong adler2, z_off64_t len2) { + return adler32_combine_(adler1, adler2, len2); +} diff --git a/common/zlib/compress.c b/common/zlib/compress.c new file mode 100755 index 0000000..f43bacf --- /dev/null +++ b/common/zlib/compress.c @@ -0,0 +1,75 @@ +/* compress.c -- compress a memory buffer + * Copyright (C) 1995-2005, 2014, 2016 Jean-loup Gailly, Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#define ZLIB_INTERNAL +#include "zlib.h" + +/* =========================================================================== + Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least 0.1% larger than sourceLen plus + 12 bytes. Upon exit, destLen is the actual size of the compressed buffer. + + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, + Z_STREAM_ERROR if the level parameter is invalid. +*/ +int ZEXPORT compress2(Bytef *dest, uLongf *destLen, const Bytef *source, + uLong sourceLen, int level) { + z_stream stream; + int err; + const uInt max = (uInt)-1; + uLong left; + + left = *destLen; + *destLen = 0; + + stream.zalloc = (alloc_func)0; + stream.zfree = (free_func)0; + stream.opaque = (voidpf)0; + + err = deflateInit(&stream, level); + if (err != Z_OK) return err; + + stream.next_out = dest; + stream.avail_out = 0; + stream.next_in = (z_const Bytef *)source; + stream.avail_in = 0; + + do { + if (stream.avail_out == 0) { + stream.avail_out = left > (uLong)max ? max : (uInt)left; + left -= stream.avail_out; + } + if (stream.avail_in == 0) { + stream.avail_in = sourceLen > (uLong)max ? max : (uInt)sourceLen; + sourceLen -= stream.avail_in; + } + err = deflate(&stream, sourceLen ? Z_NO_FLUSH : Z_FINISH); + } while (err == Z_OK); + + *destLen = stream.total_out; + deflateEnd(&stream); + return err == Z_STREAM_END ? Z_OK : err; +} + +/* =========================================================================== + */ +int ZEXPORT compress(Bytef *dest, uLongf *destLen, const Bytef *source, + uLong sourceLen) { + return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION); +} + +/* =========================================================================== + If the default memLevel or windowBits for deflateInit() is changed, then + this function needs to be updated. + */ +uLong ZEXPORT compressBound(uLong sourceLen) { + return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + + (sourceLen >> 25) + 13; +} diff --git a/common/zlib/crc32.c b/common/zlib/crc32.c new file mode 100644 index 0000000..6c38f5c --- /dev/null +++ b/common/zlib/crc32.c @@ -0,0 +1,1049 @@ +/* crc32.c -- compute the CRC-32 of a data stream + * Copyright (C) 1995-2022 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + * + * This interleaved implementation of a CRC makes use of pipelined multiple + * arithmetic-logic units, commonly found in modern CPU cores. It is due to + * Kadatch and Jenkins (2010). See doc/crc-doc.1.0.pdf in this distribution. + */ + +/* @(#) $Id$ */ + +/* + Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore + protection on the static variables used to control the first-use generation + of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should + first call get_crc_table() to initialize the tables before allowing more than + one thread to use crc32(). + + MAKECRCH can be #defined to write out crc32.h. A main() routine is also + produced, so that this one source file can be compiled to an executable. + */ + +#ifdef MAKECRCH +# include +# ifndef DYNAMIC_CRC_TABLE +# define DYNAMIC_CRC_TABLE +# endif /* !DYNAMIC_CRC_TABLE */ +#endif /* MAKECRCH */ + +#include "zutil.h" /* for Z_U4, Z_U8, z_crc_t, and FAR definitions */ + + /* + A CRC of a message is computed on N braids of words in the message, where + each word consists of W bytes (4 or 8). If N is 3, for example, then three + running sparse CRCs are calculated respectively on each braid, at these + indices in the array of words: 0, 3, 6, ..., 1, 4, 7, ..., and 2, 5, 8, ... + This is done starting at a word boundary, and continues until as many blocks + of N * W bytes as are available have been processed. The results are combined + into a single CRC at the end. For this code, N must be in the range 1..6 and + W must be 4 or 8. The upper limit on N can be increased if desired by adding + more #if blocks, extending the patterns apparent in the code. In addition, + crc32.h would need to be regenerated, if the maximum N value is increased. + + N and W are chosen empirically by benchmarking the execution time on a given + processor. The choices for N and W below were based on testing on Intel Kaby + Lake i7, AMD Ryzen 7, ARM Cortex-A57, Sparc64-VII, PowerPC POWER9, and MIPS64 + Octeon II processors. The Intel, AMD, and ARM processors were all fastest + with N=5, W=8. The Sparc, PowerPC, and MIPS64 were all fastest at N=5, W=4. + They were all tested with either gcc or clang, all using the -O3 optimization + level. Your mileage may vary. + */ + +/* Define N */ +#ifdef Z_TESTN +# define N Z_TESTN +#else +# define N 5 +#endif +#if N < 1 || N > 6 +# error N must be in 1..6 +#endif + +/* + z_crc_t must be at least 32 bits. z_word_t must be at least as long as + z_crc_t. It is assumed here that z_word_t is either 32 bits or 64 bits, and + that bytes are eight bits. + */ + +/* + Define W and the associated z_word_t type. If W is not defined, then a + braided calculation is not used, and the associated tables and code are not + compiled. + */ +#ifdef Z_TESTW +# if Z_TESTW-1 != -1 +# define W Z_TESTW +# endif +#else +# ifdef MAKECRCH +# define W 8 /* required for MAKECRCH */ +# else +# if defined(__x86_64__) || defined(__aarch64__) +# define W 8 +# else +# define W 4 +# endif +# endif +#endif +#ifdef W +# if W == 8 && defined(Z_U8) + typedef Z_U8 z_word_t; +# elif defined(Z_U4) +# undef W +# define W 4 + typedef Z_U4 z_word_t; +# else +# undef W +# endif +#endif + +/* If available, use the ARM processor CRC32 instruction. */ +#if defined(__aarch64__) && defined(__ARM_FEATURE_CRC32) && W == 8 +# define ARMCRC32 +#endif + +#if defined(W) && (!defined(ARMCRC32) || defined(DYNAMIC_CRC_TABLE)) +/* + Swap the bytes in a z_word_t to convert between little and big endian. Any + self-respecting compiler will optimize this to a single machine byte-swap + instruction, if one is available. This assumes that word_t is either 32 bits + or 64 bits. + */ +local z_word_t byte_swap(z_word_t word) { +# if W == 8 + return + (word & 0xff00000000000000) >> 56 | + (word & 0xff000000000000) >> 40 | + (word & 0xff0000000000) >> 24 | + (word & 0xff00000000) >> 8 | + (word & 0xff000000) << 8 | + (word & 0xff0000) << 24 | + (word & 0xff00) << 40 | + (word & 0xff) << 56; +# else /* W == 4 */ + return + (word & 0xff000000) >> 24 | + (word & 0xff0000) >> 8 | + (word & 0xff00) << 8 | + (word & 0xff) << 24; +# endif +} +#endif + +#ifdef DYNAMIC_CRC_TABLE +/* ========================================================================= + * Table of powers of x for combining CRC-32s, filled in by make_crc_table() + * below. + */ + local z_crc_t FAR x2n_table[32]; +#else +/* ========================================================================= + * Tables for byte-wise and braided CRC-32 calculations, and a table of powers + * of x for combining CRC-32s, all made by make_crc_table(). + */ +# include "crc32.h" +#endif + +/* CRC polynomial. */ +#define POLY 0xedb88320 /* p(x) reflected, with x^32 implied */ + +/* + Return a(x) multiplied by b(x) modulo p(x), where p(x) is the CRC polynomial, + reflected. For speed, this requires that a not be zero. + */ +local z_crc_t multmodp(z_crc_t a, z_crc_t b) { + z_crc_t m, p; + + m = (z_crc_t)1 << 31; + p = 0; + for (;;) { + if (a & m) { + p ^= b; + if ((a & (m - 1)) == 0) + break; + } + m >>= 1; + b = b & 1 ? (b >> 1) ^ POLY : b >> 1; + } + return p; +} + +/* + Return x^(n * 2^k) modulo p(x). Requires that x2n_table[] has been + initialized. + */ +local z_crc_t x2nmodp(z_off64_t n, unsigned k) { + z_crc_t p; + + p = (z_crc_t)1 << 31; /* x^0 == 1 */ + while (n) { + if (n & 1) + p = multmodp(x2n_table[k & 31], p); + n >>= 1; + k++; + } + return p; +} + +#ifdef DYNAMIC_CRC_TABLE +/* ========================================================================= + * Build the tables for byte-wise and braided CRC-32 calculations, and a table + * of powers of x for combining CRC-32s. + */ +local z_crc_t FAR crc_table[256]; +#ifdef W + local z_word_t FAR crc_big_table[256]; + local z_crc_t FAR crc_braid_table[W][256]; + local z_word_t FAR crc_braid_big_table[W][256]; + local void braid(z_crc_t [][256], z_word_t [][256], int, int); +#endif +#ifdef MAKECRCH + local void write_table(FILE *, const z_crc_t FAR *, int); + local void write_table32hi(FILE *, const z_word_t FAR *, int); + local void write_table64(FILE *, const z_word_t FAR *, int); +#endif /* MAKECRCH */ + +/* + Define a once() function depending on the availability of atomics. If this is + compiled with DYNAMIC_CRC_TABLE defined, and if CRCs will be computed in + multiple threads, and if atomics are not available, then get_crc_table() must + be called to initialize the tables and must return before any threads are + allowed to compute or combine CRCs. + */ + +/* Definition of once functionality. */ +typedef struct once_s once_t; + +/* Check for the availability of atomics. */ +#if defined(__STDC__) && __STDC_VERSION__ >= 201112L && \ + !defined(__STDC_NO_ATOMICS__) + +#include + +/* Structure for once(), which must be initialized with ONCE_INIT. */ +struct once_s { + atomic_flag begun; + atomic_int done; +}; +#define ONCE_INIT {ATOMIC_FLAG_INIT, 0} + +/* + Run the provided init() function exactly once, even if multiple threads + invoke once() at the same time. The state must be a once_t initialized with + ONCE_INIT. + */ +local void once(once_t *state, void (*init)(void)) { + if (!atomic_load(&state->done)) { + if (atomic_flag_test_and_set(&state->begun)) + while (!atomic_load(&state->done)) + ; + else { + init(); + atomic_store(&state->done, 1); + } + } +} + +#else /* no atomics */ + +/* Structure for once(), which must be initialized with ONCE_INIT. */ +struct once_s { + volatile int begun; + volatile int done; +}; +#define ONCE_INIT {0, 0} + +/* Test and set. Alas, not atomic, but tries to minimize the period of + vulnerability. */ +local int test_and_set(int volatile *flag) { + int was; + + was = *flag; + *flag = 1; + return was; +} + +/* Run the provided init() function once. This is not thread-safe. */ +local void once(once_t *state, void (*init)(void)) { + if (!state->done) { + if (test_and_set(&state->begun)) + while (!state->done) + ; + else { + init(); + state->done = 1; + } + } +} + +#endif + +/* State for once(). */ +local once_t made = ONCE_INIT; + +/* + Generate tables for a byte-wise 32-bit CRC calculation on the polynomial: + x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. + + Polynomials over GF(2) are represented in binary, one bit per coefficient, + with the lowest powers in the most significant bit. Then adding polynomials + is just exclusive-or, and multiplying a polynomial by x is a right shift by + one. If we call the above polynomial p, and represent a byte as the + polynomial q, also with the lowest power in the most significant bit (so the + byte 0xb1 is the polynomial x^7+x^3+x^2+1), then the CRC is (q*x^32) mod p, + where a mod b means the remainder after dividing a by b. + + This calculation is done using the shift-register method of multiplying and + taking the remainder. The register is initialized to zero, and for each + incoming bit, x^32 is added mod p to the register if the bit is a one (where + x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by x + (which is shifting right by one and adding x^32 mod p if the bit shifted out + is a one). We start with the highest power (least significant bit) of q and + repeat for all eight bits of q. + + The table is simply the CRC of all possible eight bit values. This is all the + information needed to generate CRCs on data a byte at a time for all + combinations of CRC register values and incoming bytes. + */ + +local void make_crc_table(void) { + unsigned i, j, n; + z_crc_t p; + + /* initialize the CRC of bytes tables */ + for (i = 0; i < 256; i++) { + p = i; + for (j = 0; j < 8; j++) + p = p & 1 ? (p >> 1) ^ POLY : p >> 1; + crc_table[i] = p; +#ifdef W + crc_big_table[i] = byte_swap(p); +#endif + } + + /* initialize the x^2^n mod p(x) table */ + p = (z_crc_t)1 << 30; /* x^1 */ + x2n_table[0] = p; + for (n = 1; n < 32; n++) + x2n_table[n] = p = multmodp(p, p); + +#ifdef W + /* initialize the braiding tables -- needs x2n_table[] */ + braid(crc_braid_table, crc_braid_big_table, N, W); +#endif + +#ifdef MAKECRCH + { + /* + The crc32.h header file contains tables for both 32-bit and 64-bit + z_word_t's, and so requires a 64-bit type be available. In that case, + z_word_t must be defined to be 64-bits. This code then also generates + and writes out the tables for the case that z_word_t is 32 bits. + */ +#if !defined(W) || W != 8 +# error Need a 64-bit integer type in order to generate crc32.h. +#endif + FILE *out; + int k, n; + z_crc_t ltl[8][256]; + z_word_t big[8][256]; + + out = fopen("crc32.h", "w"); + if (out == NULL) return; + + /* write out little-endian CRC table to crc32.h */ + fprintf(out, + "/* crc32.h -- tables for rapid CRC calculation\n" + " * Generated automatically by crc32.c\n */\n" + "\n" + "local const z_crc_t FAR crc_table[] = {\n" + " "); + write_table(out, crc_table, 256); + fprintf(out, + "};\n"); + + /* write out big-endian CRC table for 64-bit z_word_t to crc32.h */ + fprintf(out, + "\n" + "#ifdef W\n" + "\n" + "#if W == 8\n" + "\n" + "local const z_word_t FAR crc_big_table[] = {\n" + " "); + write_table64(out, crc_big_table, 256); + fprintf(out, + "};\n"); + + /* write out big-endian CRC table for 32-bit z_word_t to crc32.h */ + fprintf(out, + "\n" + "#else /* W == 4 */\n" + "\n" + "local const z_word_t FAR crc_big_table[] = {\n" + " "); + write_table32hi(out, crc_big_table, 256); + fprintf(out, + "};\n" + "\n" + "#endif\n"); + + /* write out braid tables for each value of N */ + for (n = 1; n <= 6; n++) { + fprintf(out, + "\n" + "#if N == %d\n", n); + + /* compute braid tables for this N and 64-bit word_t */ + braid(ltl, big, n, 8); + + /* write out braid tables for 64-bit z_word_t to crc32.h */ + fprintf(out, + "\n" + "#if W == 8\n" + "\n" + "local const z_crc_t FAR crc_braid_table[][256] = {\n"); + for (k = 0; k < 8; k++) { + fprintf(out, " {"); + write_table(out, ltl[k], 256); + fprintf(out, "}%s", k < 7 ? ",\n" : ""); + } + fprintf(out, + "};\n" + "\n" + "local const z_word_t FAR crc_braid_big_table[][256] = {\n"); + for (k = 0; k < 8; k++) { + fprintf(out, " {"); + write_table64(out, big[k], 256); + fprintf(out, "}%s", k < 7 ? ",\n" : ""); + } + fprintf(out, + "};\n"); + + /* compute braid tables for this N and 32-bit word_t */ + braid(ltl, big, n, 4); + + /* write out braid tables for 32-bit z_word_t to crc32.h */ + fprintf(out, + "\n" + "#else /* W == 4 */\n" + "\n" + "local const z_crc_t FAR crc_braid_table[][256] = {\n"); + for (k = 0; k < 4; k++) { + fprintf(out, " {"); + write_table(out, ltl[k], 256); + fprintf(out, "}%s", k < 3 ? ",\n" : ""); + } + fprintf(out, + "};\n" + "\n" + "local const z_word_t FAR crc_braid_big_table[][256] = {\n"); + for (k = 0; k < 4; k++) { + fprintf(out, " {"); + write_table32hi(out, big[k], 256); + fprintf(out, "}%s", k < 3 ? ",\n" : ""); + } + fprintf(out, + "};\n" + "\n" + "#endif\n" + "\n" + "#endif\n"); + } + fprintf(out, + "\n" + "#endif\n"); + + /* write out zeros operator table to crc32.h */ + fprintf(out, + "\n" + "local const z_crc_t FAR x2n_table[] = {\n" + " "); + write_table(out, x2n_table, 32); + fprintf(out, + "};\n"); + fclose(out); + } +#endif /* MAKECRCH */ +} + +#ifdef MAKECRCH + +/* + Write the 32-bit values in table[0..k-1] to out, five per line in + hexadecimal separated by commas. + */ +local void write_table(FILE *out, const z_crc_t FAR *table, int k) { + int n; + + for (n = 0; n < k; n++) + fprintf(out, "%s0x%08lx%s", n == 0 || n % 5 ? "" : " ", + (unsigned long)(table[n]), + n == k - 1 ? "" : (n % 5 == 4 ? ",\n" : ", ")); +} + +/* + Write the high 32-bits of each value in table[0..k-1] to out, five per line + in hexadecimal separated by commas. + */ +local void write_table32hi(FILE *out, const z_word_t FAR *table, int k) { + int n; + + for (n = 0; n < k; n++) + fprintf(out, "%s0x%08lx%s", n == 0 || n % 5 ? "" : " ", + (unsigned long)(table[n] >> 32), + n == k - 1 ? "" : (n % 5 == 4 ? ",\n" : ", ")); +} + +/* + Write the 64-bit values in table[0..k-1] to out, three per line in + hexadecimal separated by commas. This assumes that if there is a 64-bit + type, then there is also a long long integer type, and it is at least 64 + bits. If not, then the type cast and format string can be adjusted + accordingly. + */ +local void write_table64(FILE *out, const z_word_t FAR *table, int k) { + int n; + + for (n = 0; n < k; n++) + fprintf(out, "%s0x%016llx%s", n == 0 || n % 3 ? "" : " ", + (unsigned long long)(table[n]), + n == k - 1 ? "" : (n % 3 == 2 ? ",\n" : ", ")); +} + +/* Actually do the deed. */ +int main(void) { + make_crc_table(); + return 0; +} + +#endif /* MAKECRCH */ + +#ifdef W +/* + Generate the little and big-endian braid tables for the given n and z_word_t + size w. Each array must have room for w blocks of 256 elements. + */ +local void braid(z_crc_t ltl[][256], z_word_t big[][256], int n, int w) { + int k; + z_crc_t i, p, q; + for (k = 0; k < w; k++) { + p = x2nmodp((n * w + 3 - k) << 3, 0); + ltl[k][0] = 0; + big[w - 1 - k][0] = 0; + for (i = 1; i < 256; i++) { + ltl[k][i] = q = multmodp(i << 24, p); + big[w - 1 - k][i] = byte_swap(q); + } + } +} +#endif + +#endif /* DYNAMIC_CRC_TABLE */ + +/* ========================================================================= + * This function can be used by asm versions of crc32(), and to force the + * generation of the CRC tables in a threaded application. + */ +const z_crc_t FAR * ZEXPORT get_crc_table(void) { +#ifdef DYNAMIC_CRC_TABLE + once(&made, make_crc_table); +#endif /* DYNAMIC_CRC_TABLE */ + return (const z_crc_t FAR *)crc_table; +} + +/* ========================================================================= + * Use ARM machine instructions if available. This will compute the CRC about + * ten times faster than the braided calculation. This code does not check for + * the presence of the CRC instruction at run time. __ARM_FEATURE_CRC32 will + * only be defined if the compilation specifies an ARM processor architecture + * that has the instructions. For example, compiling with -march=armv8.1-a or + * -march=armv8-a+crc, or -march=native if the compile machine has the crc32 + * instructions. + */ +#ifdef ARMCRC32 + +/* + Constants empirically determined to maximize speed. These values are from + measurements on a Cortex-A57. Your mileage may vary. + */ +#define Z_BATCH 3990 /* number of words in a batch */ +#define Z_BATCH_ZEROS 0xa10d3d0c /* computed from Z_BATCH = 3990 */ +#define Z_BATCH_MIN 800 /* fewest words in a final batch */ + +unsigned long ZEXPORT crc32_z(unsigned long crc, const unsigned char FAR *buf, + z_size_t len) { + z_crc_t val; + z_word_t crc1, crc2; + const z_word_t *word; + z_word_t val0, val1, val2; + z_size_t last, last2, i; + z_size_t num; + + /* Return initial CRC, if requested. */ + if (buf == Z_NULL) return 0; + +#ifdef DYNAMIC_CRC_TABLE + once(&made, make_crc_table); +#endif /* DYNAMIC_CRC_TABLE */ + + /* Pre-condition the CRC */ + crc = (~crc) & 0xffffffff; + + /* Compute the CRC up to a word boundary. */ + while (len && ((z_size_t)buf & 7) != 0) { + len--; + val = *buf++; + __asm__ volatile("crc32b %w0, %w0, %w1" : "+r"(crc) : "r"(val)); + } + + /* Prepare to compute the CRC on full 64-bit words word[0..num-1]. */ + word = (z_word_t const *)buf; + num = len >> 3; + len &= 7; + + /* Do three interleaved CRCs to realize the throughput of one crc32x + instruction per cycle. Each CRC is calculated on Z_BATCH words. The + three CRCs are combined into a single CRC after each set of batches. */ + while (num >= 3 * Z_BATCH) { + crc1 = 0; + crc2 = 0; + for (i = 0; i < Z_BATCH; i++) { + val0 = word[i]; + val1 = word[i + Z_BATCH]; + val2 = word[i + 2 * Z_BATCH]; + __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc) : "r"(val0)); + __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc1) : "r"(val1)); + __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc2) : "r"(val2)); + } + word += 3 * Z_BATCH; + num -= 3 * Z_BATCH; + crc = multmodp(Z_BATCH_ZEROS, crc) ^ crc1; + crc = multmodp(Z_BATCH_ZEROS, crc) ^ crc2; + } + + /* Do one last smaller batch with the remaining words, if there are enough + to pay for the combination of CRCs. */ + last = num / 3; + if (last >= Z_BATCH_MIN) { + last2 = last << 1; + crc1 = 0; + crc2 = 0; + for (i = 0; i < last; i++) { + val0 = word[i]; + val1 = word[i + last]; + val2 = word[i + last2]; + __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc) : "r"(val0)); + __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc1) : "r"(val1)); + __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc2) : "r"(val2)); + } + word += 3 * last; + num -= 3 * last; + val = x2nmodp(last, 6); + crc = multmodp(val, crc) ^ crc1; + crc = multmodp(val, crc) ^ crc2; + } + + /* Compute the CRC on any remaining words. */ + for (i = 0; i < num; i++) { + val0 = word[i]; + __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc) : "r"(val0)); + } + word += num; + + /* Complete the CRC on any remaining bytes. */ + buf = (const unsigned char FAR *)word; + while (len) { + len--; + val = *buf++; + __asm__ volatile("crc32b %w0, %w0, %w1" : "+r"(crc) : "r"(val)); + } + + /* Return the CRC, post-conditioned. */ + return crc ^ 0xffffffff; +} + +#else + +#ifdef W + +/* + Return the CRC of the W bytes in the word_t data, taking the + least-significant byte of the word as the first byte of data, without any pre + or post conditioning. This is used to combine the CRCs of each braid. + */ +local z_crc_t crc_word(z_word_t data) { + int k; + for (k = 0; k < W; k++) + data = (data >> 8) ^ crc_table[data & 0xff]; + return (z_crc_t)data; +} + +local z_word_t crc_word_big(z_word_t data) { + int k; + for (k = 0; k < W; k++) + data = (data << 8) ^ + crc_big_table[(data >> ((W - 1) << 3)) & 0xff]; + return data; +} + +#endif + +/* ========================================================================= */ +unsigned long ZEXPORT crc32_z(unsigned long crc, const unsigned char FAR *buf, + z_size_t len) { + /* Return initial CRC, if requested. */ + if (buf == Z_NULL) return 0; + +#ifdef DYNAMIC_CRC_TABLE + once(&made, make_crc_table); +#endif /* DYNAMIC_CRC_TABLE */ + + /* Pre-condition the CRC */ + crc = (~crc) & 0xffffffff; + +#ifdef W + + /* If provided enough bytes, do a braided CRC calculation. */ + if (len >= N * W + W - 1) { + z_size_t blks; + z_word_t const *words; + unsigned endian; + int k; + + /* Compute the CRC up to a z_word_t boundary. */ + while (len && ((z_size_t)buf & (W - 1)) != 0) { + len--; + crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; + } + + /* Compute the CRC on as many N z_word_t blocks as are available. */ + blks = len / (N * W); + len -= blks * N * W; + words = (z_word_t const *)buf; + + /* Do endian check at execution time instead of compile time, since ARM + processors can change the endianness at execution time. If the + compiler knows what the endianness will be, it can optimize out the + check and the unused branch. */ + endian = 1; + if (*(unsigned char *)&endian) { + /* Little endian. */ + + z_crc_t crc0; + z_word_t word0; +#if N > 1 + z_crc_t crc1; + z_word_t word1; +#if N > 2 + z_crc_t crc2; + z_word_t word2; +#if N > 3 + z_crc_t crc3; + z_word_t word3; +#if N > 4 + z_crc_t crc4; + z_word_t word4; +#if N > 5 + z_crc_t crc5; + z_word_t word5; +#endif +#endif +#endif +#endif +#endif + + /* Initialize the CRC for each braid. */ + crc0 = crc; +#if N > 1 + crc1 = 0; +#if N > 2 + crc2 = 0; +#if N > 3 + crc3 = 0; +#if N > 4 + crc4 = 0; +#if N > 5 + crc5 = 0; +#endif +#endif +#endif +#endif +#endif + + /* + Process the first blks-1 blocks, computing the CRCs on each braid + independently. + */ + while (--blks) { + /* Load the word for each braid into registers. */ + word0 = crc0 ^ words[0]; +#if N > 1 + word1 = crc1 ^ words[1]; +#if N > 2 + word2 = crc2 ^ words[2]; +#if N > 3 + word3 = crc3 ^ words[3]; +#if N > 4 + word4 = crc4 ^ words[4]; +#if N > 5 + word5 = crc5 ^ words[5]; +#endif +#endif +#endif +#endif +#endif + words += N; + + /* Compute and update the CRC for each word. The loop should + get unrolled. */ + crc0 = crc_braid_table[0][word0 & 0xff]; +#if N > 1 + crc1 = crc_braid_table[0][word1 & 0xff]; +#if N > 2 + crc2 = crc_braid_table[0][word2 & 0xff]; +#if N > 3 + crc3 = crc_braid_table[0][word3 & 0xff]; +#if N > 4 + crc4 = crc_braid_table[0][word4 & 0xff]; +#if N > 5 + crc5 = crc_braid_table[0][word5 & 0xff]; +#endif +#endif +#endif +#endif +#endif + for (k = 1; k < W; k++) { + crc0 ^= crc_braid_table[k][(word0 >> (k << 3)) & 0xff]; +#if N > 1 + crc1 ^= crc_braid_table[k][(word1 >> (k << 3)) & 0xff]; +#if N > 2 + crc2 ^= crc_braid_table[k][(word2 >> (k << 3)) & 0xff]; +#if N > 3 + crc3 ^= crc_braid_table[k][(word3 >> (k << 3)) & 0xff]; +#if N > 4 + crc4 ^= crc_braid_table[k][(word4 >> (k << 3)) & 0xff]; +#if N > 5 + crc5 ^= crc_braid_table[k][(word5 >> (k << 3)) & 0xff]; +#endif +#endif +#endif +#endif +#endif + } + } + + /* + Process the last block, combining the CRCs of the N braids at the + same time. + */ + crc = crc_word(crc0 ^ words[0]); +#if N > 1 + crc = crc_word(crc1 ^ words[1] ^ crc); +#if N > 2 + crc = crc_word(crc2 ^ words[2] ^ crc); +#if N > 3 + crc = crc_word(crc3 ^ words[3] ^ crc); +#if N > 4 + crc = crc_word(crc4 ^ words[4] ^ crc); +#if N > 5 + crc = crc_word(crc5 ^ words[5] ^ crc); +#endif +#endif +#endif +#endif +#endif + words += N; + } + else { + /* Big endian. */ + + z_word_t crc0, word0, comb; +#if N > 1 + z_word_t crc1, word1; +#if N > 2 + z_word_t crc2, word2; +#if N > 3 + z_word_t crc3, word3; +#if N > 4 + z_word_t crc4, word4; +#if N > 5 + z_word_t crc5, word5; +#endif +#endif +#endif +#endif +#endif + + /* Initialize the CRC for each braid. */ + crc0 = byte_swap(crc); +#if N > 1 + crc1 = 0; +#if N > 2 + crc2 = 0; +#if N > 3 + crc3 = 0; +#if N > 4 + crc4 = 0; +#if N > 5 + crc5 = 0; +#endif +#endif +#endif +#endif +#endif + + /* + Process the first blks-1 blocks, computing the CRCs on each braid + independently. + */ + while (--blks) { + /* Load the word for each braid into registers. */ + word0 = crc0 ^ words[0]; +#if N > 1 + word1 = crc1 ^ words[1]; +#if N > 2 + word2 = crc2 ^ words[2]; +#if N > 3 + word3 = crc3 ^ words[3]; +#if N > 4 + word4 = crc4 ^ words[4]; +#if N > 5 + word5 = crc5 ^ words[5]; +#endif +#endif +#endif +#endif +#endif + words += N; + + /* Compute and update the CRC for each word. The loop should + get unrolled. */ + crc0 = crc_braid_big_table[0][word0 & 0xff]; +#if N > 1 + crc1 = crc_braid_big_table[0][word1 & 0xff]; +#if N > 2 + crc2 = crc_braid_big_table[0][word2 & 0xff]; +#if N > 3 + crc3 = crc_braid_big_table[0][word3 & 0xff]; +#if N > 4 + crc4 = crc_braid_big_table[0][word4 & 0xff]; +#if N > 5 + crc5 = crc_braid_big_table[0][word5 & 0xff]; +#endif +#endif +#endif +#endif +#endif + for (k = 1; k < W; k++) { + crc0 ^= crc_braid_big_table[k][(word0 >> (k << 3)) & 0xff]; +#if N > 1 + crc1 ^= crc_braid_big_table[k][(word1 >> (k << 3)) & 0xff]; +#if N > 2 + crc2 ^= crc_braid_big_table[k][(word2 >> (k << 3)) & 0xff]; +#if N > 3 + crc3 ^= crc_braid_big_table[k][(word3 >> (k << 3)) & 0xff]; +#if N > 4 + crc4 ^= crc_braid_big_table[k][(word4 >> (k << 3)) & 0xff]; +#if N > 5 + crc5 ^= crc_braid_big_table[k][(word5 >> (k << 3)) & 0xff]; +#endif +#endif +#endif +#endif +#endif + } + } + + /* + Process the last block, combining the CRCs of the N braids at the + same time. + */ + comb = crc_word_big(crc0 ^ words[0]); +#if N > 1 + comb = crc_word_big(crc1 ^ words[1] ^ comb); +#if N > 2 + comb = crc_word_big(crc2 ^ words[2] ^ comb); +#if N > 3 + comb = crc_word_big(crc3 ^ words[3] ^ comb); +#if N > 4 + comb = crc_word_big(crc4 ^ words[4] ^ comb); +#if N > 5 + comb = crc_word_big(crc5 ^ words[5] ^ comb); +#endif +#endif +#endif +#endif +#endif + words += N; + crc = byte_swap(comb); + } + + /* + Update the pointer to the remaining bytes to process. + */ + buf = (unsigned char const *)words; + } + +#endif /* W */ + + /* Complete the computation of the CRC on any remaining bytes. */ + while (len >= 8) { + len -= 8; + crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; + crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; + crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; + crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; + crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; + crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; + crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; + crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; + } + while (len) { + len--; + crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; + } + + /* Return the CRC, post-conditioned. */ + return crc ^ 0xffffffff; +} + +#endif + +/* ========================================================================= */ +unsigned long ZEXPORT crc32(unsigned long crc, const unsigned char FAR *buf, + uInt len) { + return crc32_z(crc, buf, len); +} + +/* ========================================================================= */ +uLong ZEXPORT crc32_combine64(uLong crc1, uLong crc2, z_off64_t len2) { +#ifdef DYNAMIC_CRC_TABLE + once(&made, make_crc_table); +#endif /* DYNAMIC_CRC_TABLE */ + return multmodp(x2nmodp(len2, 3), crc1) ^ (crc2 & 0xffffffff); +} + +/* ========================================================================= */ +uLong ZEXPORT crc32_combine(uLong crc1, uLong crc2, z_off_t len2) { + return crc32_combine64(crc1, crc2, (z_off64_t)len2); +} + +/* ========================================================================= */ +uLong ZEXPORT crc32_combine_gen64(z_off64_t len2) { +#ifdef DYNAMIC_CRC_TABLE + once(&made, make_crc_table); +#endif /* DYNAMIC_CRC_TABLE */ + return x2nmodp(len2, 3); +} + +/* ========================================================================= */ +uLong ZEXPORT crc32_combine_gen(z_off_t len2) { + return crc32_combine_gen64((z_off64_t)len2); +} + +/* ========================================================================= */ +uLong ZEXPORT crc32_combine_op(uLong crc1, uLong crc2, uLong op) { + return multmodp(op, crc1) ^ (crc2 & 0xffffffff); +} diff --git a/common/zlib/crc32.h b/common/zlib/crc32.h new file mode 100644 index 0000000..137df68 --- /dev/null +++ b/common/zlib/crc32.h @@ -0,0 +1,9446 @@ +/* crc32.h -- tables for rapid CRC calculation + * Generated automatically by crc32.c + */ + +local const z_crc_t FAR crc_table[] = { + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, + 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, + 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, + 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, + 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, + 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, + 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, + 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, + 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, + 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, + 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, + 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, + 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, + 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, + 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, + 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, + 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, + 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, + 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, + 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, + 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, + 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, + 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, + 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, + 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, + 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, + 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, + 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, + 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, + 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, + 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, + 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, + 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, + 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, + 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, + 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, + 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, + 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, + 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, + 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, + 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, + 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, + 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, + 0x2d02ef8d}; + +#ifdef W + +#if W == 8 + +local const z_word_t FAR crc_big_table[] = { + 0x0000000000000000, 0x9630077700000000, 0x2c610eee00000000, + 0xba51099900000000, 0x19c46d0700000000, 0x8ff46a7000000000, + 0x35a563e900000000, 0xa395649e00000000, 0x3288db0e00000000, + 0xa4b8dc7900000000, 0x1ee9d5e000000000, 0x88d9d29700000000, + 0x2b4cb60900000000, 0xbd7cb17e00000000, 0x072db8e700000000, + 0x911dbf9000000000, 0x6410b71d00000000, 0xf220b06a00000000, + 0x4871b9f300000000, 0xde41be8400000000, 0x7dd4da1a00000000, + 0xebe4dd6d00000000, 0x51b5d4f400000000, 0xc785d38300000000, + 0x56986c1300000000, 0xc0a86b6400000000, 0x7af962fd00000000, + 0xecc9658a00000000, 0x4f5c011400000000, 0xd96c066300000000, + 0x633d0ffa00000000, 0xf50d088d00000000, 0xc8206e3b00000000, + 0x5e10694c00000000, 0xe44160d500000000, 0x727167a200000000, + 0xd1e4033c00000000, 0x47d4044b00000000, 0xfd850dd200000000, + 0x6bb50aa500000000, 0xfaa8b53500000000, 0x6c98b24200000000, + 0xd6c9bbdb00000000, 0x40f9bcac00000000, 0xe36cd83200000000, + 0x755cdf4500000000, 0xcf0dd6dc00000000, 0x593dd1ab00000000, + 0xac30d92600000000, 0x3a00de5100000000, 0x8051d7c800000000, + 0x1661d0bf00000000, 0xb5f4b42100000000, 0x23c4b35600000000, + 0x9995bacf00000000, 0x0fa5bdb800000000, 0x9eb8022800000000, + 0x0888055f00000000, 0xb2d90cc600000000, 0x24e90bb100000000, + 0x877c6f2f00000000, 0x114c685800000000, 0xab1d61c100000000, + 0x3d2d66b600000000, 0x9041dc7600000000, 0x0671db0100000000, + 0xbc20d29800000000, 0x2a10d5ef00000000, 0x8985b17100000000, + 0x1fb5b60600000000, 0xa5e4bf9f00000000, 0x33d4b8e800000000, + 0xa2c9077800000000, 0x34f9000f00000000, 0x8ea8099600000000, + 0x18980ee100000000, 0xbb0d6a7f00000000, 0x2d3d6d0800000000, + 0x976c649100000000, 0x015c63e600000000, 0xf4516b6b00000000, + 0x62616c1c00000000, 0xd830658500000000, 0x4e0062f200000000, + 0xed95066c00000000, 0x7ba5011b00000000, 0xc1f4088200000000, + 0x57c40ff500000000, 0xc6d9b06500000000, 0x50e9b71200000000, + 0xeab8be8b00000000, 0x7c88b9fc00000000, 0xdf1ddd6200000000, + 0x492dda1500000000, 0xf37cd38c00000000, 0x654cd4fb00000000, + 0x5861b24d00000000, 0xce51b53a00000000, 0x7400bca300000000, + 0xe230bbd400000000, 0x41a5df4a00000000, 0xd795d83d00000000, + 0x6dc4d1a400000000, 0xfbf4d6d300000000, 0x6ae9694300000000, + 0xfcd96e3400000000, 0x468867ad00000000, 0xd0b860da00000000, + 0x732d044400000000, 0xe51d033300000000, 0x5f4c0aaa00000000, + 0xc97c0ddd00000000, 0x3c71055000000000, 0xaa41022700000000, + 0x10100bbe00000000, 0x86200cc900000000, 0x25b5685700000000, + 0xb3856f2000000000, 0x09d466b900000000, 0x9fe461ce00000000, + 0x0ef9de5e00000000, 0x98c9d92900000000, 0x2298d0b000000000, + 0xb4a8d7c700000000, 0x173db35900000000, 0x810db42e00000000, + 0x3b5cbdb700000000, 0xad6cbac000000000, 0x2083b8ed00000000, + 0xb6b3bf9a00000000, 0x0ce2b60300000000, 0x9ad2b17400000000, + 0x3947d5ea00000000, 0xaf77d29d00000000, 0x1526db0400000000, + 0x8316dc7300000000, 0x120b63e300000000, 0x843b649400000000, + 0x3e6a6d0d00000000, 0xa85a6a7a00000000, 0x0bcf0ee400000000, + 0x9dff099300000000, 0x27ae000a00000000, 0xb19e077d00000000, + 0x44930ff000000000, 0xd2a3088700000000, 0x68f2011e00000000, + 0xfec2066900000000, 0x5d5762f700000000, 0xcb67658000000000, + 0x71366c1900000000, 0xe7066b6e00000000, 0x761bd4fe00000000, + 0xe02bd38900000000, 0x5a7ada1000000000, 0xcc4add6700000000, + 0x6fdfb9f900000000, 0xf9efbe8e00000000, 0x43beb71700000000, + 0xd58eb06000000000, 0xe8a3d6d600000000, 0x7e93d1a100000000, + 0xc4c2d83800000000, 0x52f2df4f00000000, 0xf167bbd100000000, + 0x6757bca600000000, 0xdd06b53f00000000, 0x4b36b24800000000, + 0xda2b0dd800000000, 0x4c1b0aaf00000000, 0xf64a033600000000, + 0x607a044100000000, 0xc3ef60df00000000, 0x55df67a800000000, + 0xef8e6e3100000000, 0x79be694600000000, 0x8cb361cb00000000, + 0x1a8366bc00000000, 0xa0d26f2500000000, 0x36e2685200000000, + 0x95770ccc00000000, 0x03470bbb00000000, 0xb916022200000000, + 0x2f26055500000000, 0xbe3bbac500000000, 0x280bbdb200000000, + 0x925ab42b00000000, 0x046ab35c00000000, 0xa7ffd7c200000000, + 0x31cfd0b500000000, 0x8b9ed92c00000000, 0x1daede5b00000000, + 0xb0c2649b00000000, 0x26f263ec00000000, 0x9ca36a7500000000, + 0x0a936d0200000000, 0xa906099c00000000, 0x3f360eeb00000000, + 0x8567077200000000, 0x1357000500000000, 0x824abf9500000000, + 0x147ab8e200000000, 0xae2bb17b00000000, 0x381bb60c00000000, + 0x9b8ed29200000000, 0x0dbed5e500000000, 0xb7efdc7c00000000, + 0x21dfdb0b00000000, 0xd4d2d38600000000, 0x42e2d4f100000000, + 0xf8b3dd6800000000, 0x6e83da1f00000000, 0xcd16be8100000000, + 0x5b26b9f600000000, 0xe177b06f00000000, 0x7747b71800000000, + 0xe65a088800000000, 0x706a0fff00000000, 0xca3b066600000000, + 0x5c0b011100000000, 0xff9e658f00000000, 0x69ae62f800000000, + 0xd3ff6b6100000000, 0x45cf6c1600000000, 0x78e20aa000000000, + 0xeed20dd700000000, 0x5483044e00000000, 0xc2b3033900000000, + 0x612667a700000000, 0xf71660d000000000, 0x4d47694900000000, + 0xdb776e3e00000000, 0x4a6ad1ae00000000, 0xdc5ad6d900000000, + 0x660bdf4000000000, 0xf03bd83700000000, 0x53aebca900000000, + 0xc59ebbde00000000, 0x7fcfb24700000000, 0xe9ffb53000000000, + 0x1cf2bdbd00000000, 0x8ac2baca00000000, 0x3093b35300000000, + 0xa6a3b42400000000, 0x0536d0ba00000000, 0x9306d7cd00000000, + 0x2957de5400000000, 0xbf67d92300000000, 0x2e7a66b300000000, + 0xb84a61c400000000, 0x021b685d00000000, 0x942b6f2a00000000, + 0x37be0bb400000000, 0xa18e0cc300000000, 0x1bdf055a00000000, + 0x8def022d00000000}; + +#else /* W == 4 */ + +local const z_word_t FAR crc_big_table[] = { + 0x00000000, 0x96300777, 0x2c610eee, 0xba510999, 0x19c46d07, + 0x8ff46a70, 0x35a563e9, 0xa395649e, 0x3288db0e, 0xa4b8dc79, + 0x1ee9d5e0, 0x88d9d297, 0x2b4cb609, 0xbd7cb17e, 0x072db8e7, + 0x911dbf90, 0x6410b71d, 0xf220b06a, 0x4871b9f3, 0xde41be84, + 0x7dd4da1a, 0xebe4dd6d, 0x51b5d4f4, 0xc785d383, 0x56986c13, + 0xc0a86b64, 0x7af962fd, 0xecc9658a, 0x4f5c0114, 0xd96c0663, + 0x633d0ffa, 0xf50d088d, 0xc8206e3b, 0x5e10694c, 0xe44160d5, + 0x727167a2, 0xd1e4033c, 0x47d4044b, 0xfd850dd2, 0x6bb50aa5, + 0xfaa8b535, 0x6c98b242, 0xd6c9bbdb, 0x40f9bcac, 0xe36cd832, + 0x755cdf45, 0xcf0dd6dc, 0x593dd1ab, 0xac30d926, 0x3a00de51, + 0x8051d7c8, 0x1661d0bf, 0xb5f4b421, 0x23c4b356, 0x9995bacf, + 0x0fa5bdb8, 0x9eb80228, 0x0888055f, 0xb2d90cc6, 0x24e90bb1, + 0x877c6f2f, 0x114c6858, 0xab1d61c1, 0x3d2d66b6, 0x9041dc76, + 0x0671db01, 0xbc20d298, 0x2a10d5ef, 0x8985b171, 0x1fb5b606, + 0xa5e4bf9f, 0x33d4b8e8, 0xa2c90778, 0x34f9000f, 0x8ea80996, + 0x18980ee1, 0xbb0d6a7f, 0x2d3d6d08, 0x976c6491, 0x015c63e6, + 0xf4516b6b, 0x62616c1c, 0xd8306585, 0x4e0062f2, 0xed95066c, + 0x7ba5011b, 0xc1f40882, 0x57c40ff5, 0xc6d9b065, 0x50e9b712, + 0xeab8be8b, 0x7c88b9fc, 0xdf1ddd62, 0x492dda15, 0xf37cd38c, + 0x654cd4fb, 0x5861b24d, 0xce51b53a, 0x7400bca3, 0xe230bbd4, + 0x41a5df4a, 0xd795d83d, 0x6dc4d1a4, 0xfbf4d6d3, 0x6ae96943, + 0xfcd96e34, 0x468867ad, 0xd0b860da, 0x732d0444, 0xe51d0333, + 0x5f4c0aaa, 0xc97c0ddd, 0x3c710550, 0xaa410227, 0x10100bbe, + 0x86200cc9, 0x25b56857, 0xb3856f20, 0x09d466b9, 0x9fe461ce, + 0x0ef9de5e, 0x98c9d929, 0x2298d0b0, 0xb4a8d7c7, 0x173db359, + 0x810db42e, 0x3b5cbdb7, 0xad6cbac0, 0x2083b8ed, 0xb6b3bf9a, + 0x0ce2b603, 0x9ad2b174, 0x3947d5ea, 0xaf77d29d, 0x1526db04, + 0x8316dc73, 0x120b63e3, 0x843b6494, 0x3e6a6d0d, 0xa85a6a7a, + 0x0bcf0ee4, 0x9dff0993, 0x27ae000a, 0xb19e077d, 0x44930ff0, + 0xd2a30887, 0x68f2011e, 0xfec20669, 0x5d5762f7, 0xcb676580, + 0x71366c19, 0xe7066b6e, 0x761bd4fe, 0xe02bd389, 0x5a7ada10, + 0xcc4add67, 0x6fdfb9f9, 0xf9efbe8e, 0x43beb717, 0xd58eb060, + 0xe8a3d6d6, 0x7e93d1a1, 0xc4c2d838, 0x52f2df4f, 0xf167bbd1, + 0x6757bca6, 0xdd06b53f, 0x4b36b248, 0xda2b0dd8, 0x4c1b0aaf, + 0xf64a0336, 0x607a0441, 0xc3ef60df, 0x55df67a8, 0xef8e6e31, + 0x79be6946, 0x8cb361cb, 0x1a8366bc, 0xa0d26f25, 0x36e26852, + 0x95770ccc, 0x03470bbb, 0xb9160222, 0x2f260555, 0xbe3bbac5, + 0x280bbdb2, 0x925ab42b, 0x046ab35c, 0xa7ffd7c2, 0x31cfd0b5, + 0x8b9ed92c, 0x1daede5b, 0xb0c2649b, 0x26f263ec, 0x9ca36a75, + 0x0a936d02, 0xa906099c, 0x3f360eeb, 0x85670772, 0x13570005, + 0x824abf95, 0x147ab8e2, 0xae2bb17b, 0x381bb60c, 0x9b8ed292, + 0x0dbed5e5, 0xb7efdc7c, 0x21dfdb0b, 0xd4d2d386, 0x42e2d4f1, + 0xf8b3dd68, 0x6e83da1f, 0xcd16be81, 0x5b26b9f6, 0xe177b06f, + 0x7747b718, 0xe65a0888, 0x706a0fff, 0xca3b0666, 0x5c0b0111, + 0xff9e658f, 0x69ae62f8, 0xd3ff6b61, 0x45cf6c16, 0x78e20aa0, + 0xeed20dd7, 0x5483044e, 0xc2b30339, 0x612667a7, 0xf71660d0, + 0x4d476949, 0xdb776e3e, 0x4a6ad1ae, 0xdc5ad6d9, 0x660bdf40, + 0xf03bd837, 0x53aebca9, 0xc59ebbde, 0x7fcfb247, 0xe9ffb530, + 0x1cf2bdbd, 0x8ac2baca, 0x3093b353, 0xa6a3b424, 0x0536d0ba, + 0x9306d7cd, 0x2957de54, 0xbf67d923, 0x2e7a66b3, 0xb84a61c4, + 0x021b685d, 0x942b6f2a, 0x37be0bb4, 0xa18e0cc3, 0x1bdf055a, + 0x8def022d}; + +#endif + +#if N == 1 + +#if W == 8 + +local const z_crc_t FAR crc_braid_table[][256] = { + {0x00000000, 0xccaa009e, 0x4225077d, 0x8e8f07e3, 0x844a0efa, + 0x48e00e64, 0xc66f0987, 0x0ac50919, 0xd3e51bb5, 0x1f4f1b2b, + 0x91c01cc8, 0x5d6a1c56, 0x57af154f, 0x9b0515d1, 0x158a1232, + 0xd92012ac, 0x7cbb312b, 0xb01131b5, 0x3e9e3656, 0xf23436c8, + 0xf8f13fd1, 0x345b3f4f, 0xbad438ac, 0x767e3832, 0xaf5e2a9e, + 0x63f42a00, 0xed7b2de3, 0x21d12d7d, 0x2b142464, 0xe7be24fa, + 0x69312319, 0xa59b2387, 0xf9766256, 0x35dc62c8, 0xbb53652b, + 0x77f965b5, 0x7d3c6cac, 0xb1966c32, 0x3f196bd1, 0xf3b36b4f, + 0x2a9379e3, 0xe639797d, 0x68b67e9e, 0xa41c7e00, 0xaed97719, + 0x62737787, 0xecfc7064, 0x205670fa, 0x85cd537d, 0x496753e3, + 0xc7e85400, 0x0b42549e, 0x01875d87, 0xcd2d5d19, 0x43a25afa, + 0x8f085a64, 0x562848c8, 0x9a824856, 0x140d4fb5, 0xd8a74f2b, + 0xd2624632, 0x1ec846ac, 0x9047414f, 0x5ced41d1, 0x299dc2ed, + 0xe537c273, 0x6bb8c590, 0xa712c50e, 0xadd7cc17, 0x617dcc89, + 0xeff2cb6a, 0x2358cbf4, 0xfa78d958, 0x36d2d9c6, 0xb85dde25, + 0x74f7debb, 0x7e32d7a2, 0xb298d73c, 0x3c17d0df, 0xf0bdd041, + 0x5526f3c6, 0x998cf358, 0x1703f4bb, 0xdba9f425, 0xd16cfd3c, + 0x1dc6fda2, 0x9349fa41, 0x5fe3fadf, 0x86c3e873, 0x4a69e8ed, + 0xc4e6ef0e, 0x084cef90, 0x0289e689, 0xce23e617, 0x40ace1f4, + 0x8c06e16a, 0xd0eba0bb, 0x1c41a025, 0x92cea7c6, 0x5e64a758, + 0x54a1ae41, 0x980baedf, 0x1684a93c, 0xda2ea9a2, 0x030ebb0e, + 0xcfa4bb90, 0x412bbc73, 0x8d81bced, 0x8744b5f4, 0x4beeb56a, + 0xc561b289, 0x09cbb217, 0xac509190, 0x60fa910e, 0xee7596ed, + 0x22df9673, 0x281a9f6a, 0xe4b09ff4, 0x6a3f9817, 0xa6959889, + 0x7fb58a25, 0xb31f8abb, 0x3d908d58, 0xf13a8dc6, 0xfbff84df, + 0x37558441, 0xb9da83a2, 0x7570833c, 0x533b85da, 0x9f918544, + 0x111e82a7, 0xddb48239, 0xd7718b20, 0x1bdb8bbe, 0x95548c5d, + 0x59fe8cc3, 0x80de9e6f, 0x4c749ef1, 0xc2fb9912, 0x0e51998c, + 0x04949095, 0xc83e900b, 0x46b197e8, 0x8a1b9776, 0x2f80b4f1, + 0xe32ab46f, 0x6da5b38c, 0xa10fb312, 0xabcaba0b, 0x6760ba95, + 0xe9efbd76, 0x2545bde8, 0xfc65af44, 0x30cfafda, 0xbe40a839, + 0x72eaa8a7, 0x782fa1be, 0xb485a120, 0x3a0aa6c3, 0xf6a0a65d, + 0xaa4de78c, 0x66e7e712, 0xe868e0f1, 0x24c2e06f, 0x2e07e976, + 0xe2ade9e8, 0x6c22ee0b, 0xa088ee95, 0x79a8fc39, 0xb502fca7, + 0x3b8dfb44, 0xf727fbda, 0xfde2f2c3, 0x3148f25d, 0xbfc7f5be, + 0x736df520, 0xd6f6d6a7, 0x1a5cd639, 0x94d3d1da, 0x5879d144, + 0x52bcd85d, 0x9e16d8c3, 0x1099df20, 0xdc33dfbe, 0x0513cd12, + 0xc9b9cd8c, 0x4736ca6f, 0x8b9ccaf1, 0x8159c3e8, 0x4df3c376, + 0xc37cc495, 0x0fd6c40b, 0x7aa64737, 0xb60c47a9, 0x3883404a, + 0xf42940d4, 0xfeec49cd, 0x32464953, 0xbcc94eb0, 0x70634e2e, + 0xa9435c82, 0x65e95c1c, 0xeb665bff, 0x27cc5b61, 0x2d095278, + 0xe1a352e6, 0x6f2c5505, 0xa386559b, 0x061d761c, 0xcab77682, + 0x44387161, 0x889271ff, 0x825778e6, 0x4efd7878, 0xc0727f9b, + 0x0cd87f05, 0xd5f86da9, 0x19526d37, 0x97dd6ad4, 0x5b776a4a, + 0x51b26353, 0x9d1863cd, 0x1397642e, 0xdf3d64b0, 0x83d02561, + 0x4f7a25ff, 0xc1f5221c, 0x0d5f2282, 0x079a2b9b, 0xcb302b05, + 0x45bf2ce6, 0x89152c78, 0x50353ed4, 0x9c9f3e4a, 0x121039a9, + 0xdeba3937, 0xd47f302e, 0x18d530b0, 0x965a3753, 0x5af037cd, + 0xff6b144a, 0x33c114d4, 0xbd4e1337, 0x71e413a9, 0x7b211ab0, + 0xb78b1a2e, 0x39041dcd, 0xf5ae1d53, 0x2c8e0fff, 0xe0240f61, + 0x6eab0882, 0xa201081c, 0xa8c40105, 0x646e019b, 0xeae10678, + 0x264b06e6}, + {0x00000000, 0xa6770bb4, 0x979f1129, 0x31e81a9d, 0xf44f2413, + 0x52382fa7, 0x63d0353a, 0xc5a73e8e, 0x33ef4e67, 0x959845d3, + 0xa4705f4e, 0x020754fa, 0xc7a06a74, 0x61d761c0, 0x503f7b5d, + 0xf64870e9, 0x67de9cce, 0xc1a9977a, 0xf0418de7, 0x56368653, + 0x9391b8dd, 0x35e6b369, 0x040ea9f4, 0xa279a240, 0x5431d2a9, + 0xf246d91d, 0xc3aec380, 0x65d9c834, 0xa07ef6ba, 0x0609fd0e, + 0x37e1e793, 0x9196ec27, 0xcfbd399c, 0x69ca3228, 0x582228b5, + 0xfe552301, 0x3bf21d8f, 0x9d85163b, 0xac6d0ca6, 0x0a1a0712, + 0xfc5277fb, 0x5a257c4f, 0x6bcd66d2, 0xcdba6d66, 0x081d53e8, + 0xae6a585c, 0x9f8242c1, 0x39f54975, 0xa863a552, 0x0e14aee6, + 0x3ffcb47b, 0x998bbfcf, 0x5c2c8141, 0xfa5b8af5, 0xcbb39068, + 0x6dc49bdc, 0x9b8ceb35, 0x3dfbe081, 0x0c13fa1c, 0xaa64f1a8, + 0x6fc3cf26, 0xc9b4c492, 0xf85cde0f, 0x5e2bd5bb, 0x440b7579, + 0xe27c7ecd, 0xd3946450, 0x75e36fe4, 0xb044516a, 0x16335ade, + 0x27db4043, 0x81ac4bf7, 0x77e43b1e, 0xd19330aa, 0xe07b2a37, + 0x460c2183, 0x83ab1f0d, 0x25dc14b9, 0x14340e24, 0xb2430590, + 0x23d5e9b7, 0x85a2e203, 0xb44af89e, 0x123df32a, 0xd79acda4, + 0x71edc610, 0x4005dc8d, 0xe672d739, 0x103aa7d0, 0xb64dac64, + 0x87a5b6f9, 0x21d2bd4d, 0xe47583c3, 0x42028877, 0x73ea92ea, + 0xd59d995e, 0x8bb64ce5, 0x2dc14751, 0x1c295dcc, 0xba5e5678, + 0x7ff968f6, 0xd98e6342, 0xe86679df, 0x4e11726b, 0xb8590282, + 0x1e2e0936, 0x2fc613ab, 0x89b1181f, 0x4c162691, 0xea612d25, + 0xdb8937b8, 0x7dfe3c0c, 0xec68d02b, 0x4a1fdb9f, 0x7bf7c102, + 0xdd80cab6, 0x1827f438, 0xbe50ff8c, 0x8fb8e511, 0x29cfeea5, + 0xdf879e4c, 0x79f095f8, 0x48188f65, 0xee6f84d1, 0x2bc8ba5f, + 0x8dbfb1eb, 0xbc57ab76, 0x1a20a0c2, 0x8816eaf2, 0x2e61e146, + 0x1f89fbdb, 0xb9fef06f, 0x7c59cee1, 0xda2ec555, 0xebc6dfc8, + 0x4db1d47c, 0xbbf9a495, 0x1d8eaf21, 0x2c66b5bc, 0x8a11be08, + 0x4fb68086, 0xe9c18b32, 0xd82991af, 0x7e5e9a1b, 0xefc8763c, + 0x49bf7d88, 0x78576715, 0xde206ca1, 0x1b87522f, 0xbdf0599b, + 0x8c184306, 0x2a6f48b2, 0xdc27385b, 0x7a5033ef, 0x4bb82972, + 0xedcf22c6, 0x28681c48, 0x8e1f17fc, 0xbff70d61, 0x198006d5, + 0x47abd36e, 0xe1dcd8da, 0xd034c247, 0x7643c9f3, 0xb3e4f77d, + 0x1593fcc9, 0x247be654, 0x820cede0, 0x74449d09, 0xd23396bd, + 0xe3db8c20, 0x45ac8794, 0x800bb91a, 0x267cb2ae, 0x1794a833, + 0xb1e3a387, 0x20754fa0, 0x86024414, 0xb7ea5e89, 0x119d553d, + 0xd43a6bb3, 0x724d6007, 0x43a57a9a, 0xe5d2712e, 0x139a01c7, + 0xb5ed0a73, 0x840510ee, 0x22721b5a, 0xe7d525d4, 0x41a22e60, + 0x704a34fd, 0xd63d3f49, 0xcc1d9f8b, 0x6a6a943f, 0x5b828ea2, + 0xfdf58516, 0x3852bb98, 0x9e25b02c, 0xafcdaab1, 0x09baa105, + 0xfff2d1ec, 0x5985da58, 0x686dc0c5, 0xce1acb71, 0x0bbdf5ff, + 0xadcafe4b, 0x9c22e4d6, 0x3a55ef62, 0xabc30345, 0x0db408f1, + 0x3c5c126c, 0x9a2b19d8, 0x5f8c2756, 0xf9fb2ce2, 0xc813367f, + 0x6e643dcb, 0x982c4d22, 0x3e5b4696, 0x0fb35c0b, 0xa9c457bf, + 0x6c636931, 0xca146285, 0xfbfc7818, 0x5d8b73ac, 0x03a0a617, + 0xa5d7ada3, 0x943fb73e, 0x3248bc8a, 0xf7ef8204, 0x519889b0, + 0x6070932d, 0xc6079899, 0x304fe870, 0x9638e3c4, 0xa7d0f959, + 0x01a7f2ed, 0xc400cc63, 0x6277c7d7, 0x539fdd4a, 0xf5e8d6fe, + 0x647e3ad9, 0xc209316d, 0xf3e12bf0, 0x55962044, 0x90311eca, + 0x3646157e, 0x07ae0fe3, 0xa1d90457, 0x579174be, 0xf1e67f0a, + 0xc00e6597, 0x66796e23, 0xa3de50ad, 0x05a95b19, 0x34414184, + 0x92364a30}, + {0x00000000, 0xcb5cd3a5, 0x4dc8a10b, 0x869472ae, 0x9b914216, + 0x50cd91b3, 0xd659e31d, 0x1d0530b8, 0xec53826d, 0x270f51c8, + 0xa19b2366, 0x6ac7f0c3, 0x77c2c07b, 0xbc9e13de, 0x3a0a6170, + 0xf156b2d5, 0x03d6029b, 0xc88ad13e, 0x4e1ea390, 0x85427035, + 0x9847408d, 0x531b9328, 0xd58fe186, 0x1ed33223, 0xef8580f6, + 0x24d95353, 0xa24d21fd, 0x6911f258, 0x7414c2e0, 0xbf481145, + 0x39dc63eb, 0xf280b04e, 0x07ac0536, 0xccf0d693, 0x4a64a43d, + 0x81387798, 0x9c3d4720, 0x57619485, 0xd1f5e62b, 0x1aa9358e, + 0xebff875b, 0x20a354fe, 0xa6372650, 0x6d6bf5f5, 0x706ec54d, + 0xbb3216e8, 0x3da66446, 0xf6fab7e3, 0x047a07ad, 0xcf26d408, + 0x49b2a6a6, 0x82ee7503, 0x9feb45bb, 0x54b7961e, 0xd223e4b0, + 0x197f3715, 0xe82985c0, 0x23755665, 0xa5e124cb, 0x6ebdf76e, + 0x73b8c7d6, 0xb8e41473, 0x3e7066dd, 0xf52cb578, 0x0f580a6c, + 0xc404d9c9, 0x4290ab67, 0x89cc78c2, 0x94c9487a, 0x5f959bdf, + 0xd901e971, 0x125d3ad4, 0xe30b8801, 0x28575ba4, 0xaec3290a, + 0x659ffaaf, 0x789aca17, 0xb3c619b2, 0x35526b1c, 0xfe0eb8b9, + 0x0c8e08f7, 0xc7d2db52, 0x4146a9fc, 0x8a1a7a59, 0x971f4ae1, + 0x5c439944, 0xdad7ebea, 0x118b384f, 0xe0dd8a9a, 0x2b81593f, + 0xad152b91, 0x6649f834, 0x7b4cc88c, 0xb0101b29, 0x36846987, + 0xfdd8ba22, 0x08f40f5a, 0xc3a8dcff, 0x453cae51, 0x8e607df4, + 0x93654d4c, 0x58399ee9, 0xdeadec47, 0x15f13fe2, 0xe4a78d37, + 0x2ffb5e92, 0xa96f2c3c, 0x6233ff99, 0x7f36cf21, 0xb46a1c84, + 0x32fe6e2a, 0xf9a2bd8f, 0x0b220dc1, 0xc07ede64, 0x46eaacca, + 0x8db67f6f, 0x90b34fd7, 0x5bef9c72, 0xdd7beedc, 0x16273d79, + 0xe7718fac, 0x2c2d5c09, 0xaab92ea7, 0x61e5fd02, 0x7ce0cdba, + 0xb7bc1e1f, 0x31286cb1, 0xfa74bf14, 0x1eb014d8, 0xd5ecc77d, + 0x5378b5d3, 0x98246676, 0x852156ce, 0x4e7d856b, 0xc8e9f7c5, + 0x03b52460, 0xf2e396b5, 0x39bf4510, 0xbf2b37be, 0x7477e41b, + 0x6972d4a3, 0xa22e0706, 0x24ba75a8, 0xefe6a60d, 0x1d661643, + 0xd63ac5e6, 0x50aeb748, 0x9bf264ed, 0x86f75455, 0x4dab87f0, + 0xcb3ff55e, 0x006326fb, 0xf135942e, 0x3a69478b, 0xbcfd3525, + 0x77a1e680, 0x6aa4d638, 0xa1f8059d, 0x276c7733, 0xec30a496, + 0x191c11ee, 0xd240c24b, 0x54d4b0e5, 0x9f886340, 0x828d53f8, + 0x49d1805d, 0xcf45f2f3, 0x04192156, 0xf54f9383, 0x3e134026, + 0xb8873288, 0x73dbe12d, 0x6eded195, 0xa5820230, 0x2316709e, + 0xe84aa33b, 0x1aca1375, 0xd196c0d0, 0x5702b27e, 0x9c5e61db, + 0x815b5163, 0x4a0782c6, 0xcc93f068, 0x07cf23cd, 0xf6999118, + 0x3dc542bd, 0xbb513013, 0x700de3b6, 0x6d08d30e, 0xa65400ab, + 0x20c07205, 0xeb9ca1a0, 0x11e81eb4, 0xdab4cd11, 0x5c20bfbf, + 0x977c6c1a, 0x8a795ca2, 0x41258f07, 0xc7b1fda9, 0x0ced2e0c, + 0xfdbb9cd9, 0x36e74f7c, 0xb0733dd2, 0x7b2fee77, 0x662adecf, + 0xad760d6a, 0x2be27fc4, 0xe0beac61, 0x123e1c2f, 0xd962cf8a, + 0x5ff6bd24, 0x94aa6e81, 0x89af5e39, 0x42f38d9c, 0xc467ff32, + 0x0f3b2c97, 0xfe6d9e42, 0x35314de7, 0xb3a53f49, 0x78f9ecec, + 0x65fcdc54, 0xaea00ff1, 0x28347d5f, 0xe368aefa, 0x16441b82, + 0xdd18c827, 0x5b8cba89, 0x90d0692c, 0x8dd55994, 0x46898a31, + 0xc01df89f, 0x0b412b3a, 0xfa1799ef, 0x314b4a4a, 0xb7df38e4, + 0x7c83eb41, 0x6186dbf9, 0xaada085c, 0x2c4e7af2, 0xe712a957, + 0x15921919, 0xdececabc, 0x585ab812, 0x93066bb7, 0x8e035b0f, + 0x455f88aa, 0xc3cbfa04, 0x089729a1, 0xf9c19b74, 0x329d48d1, + 0xb4093a7f, 0x7f55e9da, 0x6250d962, 0xa90c0ac7, 0x2f987869, + 0xe4c4abcc}, + {0x00000000, 0x3d6029b0, 0x7ac05360, 0x47a07ad0, 0xf580a6c0, + 0xc8e08f70, 0x8f40f5a0, 0xb220dc10, 0x30704bc1, 0x0d106271, + 0x4ab018a1, 0x77d03111, 0xc5f0ed01, 0xf890c4b1, 0xbf30be61, + 0x825097d1, 0x60e09782, 0x5d80be32, 0x1a20c4e2, 0x2740ed52, + 0x95603142, 0xa80018f2, 0xefa06222, 0xd2c04b92, 0x5090dc43, + 0x6df0f5f3, 0x2a508f23, 0x1730a693, 0xa5107a83, 0x98705333, + 0xdfd029e3, 0xe2b00053, 0xc1c12f04, 0xfca106b4, 0xbb017c64, + 0x866155d4, 0x344189c4, 0x0921a074, 0x4e81daa4, 0x73e1f314, + 0xf1b164c5, 0xccd14d75, 0x8b7137a5, 0xb6111e15, 0x0431c205, + 0x3951ebb5, 0x7ef19165, 0x4391b8d5, 0xa121b886, 0x9c419136, + 0xdbe1ebe6, 0xe681c256, 0x54a11e46, 0x69c137f6, 0x2e614d26, + 0x13016496, 0x9151f347, 0xac31daf7, 0xeb91a027, 0xd6f18997, + 0x64d15587, 0x59b17c37, 0x1e1106e7, 0x23712f57, 0x58f35849, + 0x659371f9, 0x22330b29, 0x1f532299, 0xad73fe89, 0x9013d739, + 0xd7b3ade9, 0xead38459, 0x68831388, 0x55e33a38, 0x124340e8, + 0x2f236958, 0x9d03b548, 0xa0639cf8, 0xe7c3e628, 0xdaa3cf98, + 0x3813cfcb, 0x0573e67b, 0x42d39cab, 0x7fb3b51b, 0xcd93690b, + 0xf0f340bb, 0xb7533a6b, 0x8a3313db, 0x0863840a, 0x3503adba, + 0x72a3d76a, 0x4fc3feda, 0xfde322ca, 0xc0830b7a, 0x872371aa, + 0xba43581a, 0x9932774d, 0xa4525efd, 0xe3f2242d, 0xde920d9d, + 0x6cb2d18d, 0x51d2f83d, 0x167282ed, 0x2b12ab5d, 0xa9423c8c, + 0x9422153c, 0xd3826fec, 0xeee2465c, 0x5cc29a4c, 0x61a2b3fc, + 0x2602c92c, 0x1b62e09c, 0xf9d2e0cf, 0xc4b2c97f, 0x8312b3af, + 0xbe729a1f, 0x0c52460f, 0x31326fbf, 0x7692156f, 0x4bf23cdf, + 0xc9a2ab0e, 0xf4c282be, 0xb362f86e, 0x8e02d1de, 0x3c220dce, + 0x0142247e, 0x46e25eae, 0x7b82771e, 0xb1e6b092, 0x8c869922, + 0xcb26e3f2, 0xf646ca42, 0x44661652, 0x79063fe2, 0x3ea64532, + 0x03c66c82, 0x8196fb53, 0xbcf6d2e3, 0xfb56a833, 0xc6368183, + 0x74165d93, 0x49767423, 0x0ed60ef3, 0x33b62743, 0xd1062710, + 0xec660ea0, 0xabc67470, 0x96a65dc0, 0x248681d0, 0x19e6a860, + 0x5e46d2b0, 0x6326fb00, 0xe1766cd1, 0xdc164561, 0x9bb63fb1, + 0xa6d61601, 0x14f6ca11, 0x2996e3a1, 0x6e369971, 0x5356b0c1, + 0x70279f96, 0x4d47b626, 0x0ae7ccf6, 0x3787e546, 0x85a73956, + 0xb8c710e6, 0xff676a36, 0xc2074386, 0x4057d457, 0x7d37fde7, + 0x3a978737, 0x07f7ae87, 0xb5d77297, 0x88b75b27, 0xcf1721f7, + 0xf2770847, 0x10c70814, 0x2da721a4, 0x6a075b74, 0x576772c4, + 0xe547aed4, 0xd8278764, 0x9f87fdb4, 0xa2e7d404, 0x20b743d5, + 0x1dd76a65, 0x5a7710b5, 0x67173905, 0xd537e515, 0xe857cca5, + 0xaff7b675, 0x92979fc5, 0xe915e8db, 0xd475c16b, 0x93d5bbbb, + 0xaeb5920b, 0x1c954e1b, 0x21f567ab, 0x66551d7b, 0x5b3534cb, + 0xd965a31a, 0xe4058aaa, 0xa3a5f07a, 0x9ec5d9ca, 0x2ce505da, + 0x11852c6a, 0x562556ba, 0x6b457f0a, 0x89f57f59, 0xb49556e9, + 0xf3352c39, 0xce550589, 0x7c75d999, 0x4115f029, 0x06b58af9, + 0x3bd5a349, 0xb9853498, 0x84e51d28, 0xc34567f8, 0xfe254e48, + 0x4c059258, 0x7165bbe8, 0x36c5c138, 0x0ba5e888, 0x28d4c7df, + 0x15b4ee6f, 0x521494bf, 0x6f74bd0f, 0xdd54611f, 0xe03448af, + 0xa794327f, 0x9af41bcf, 0x18a48c1e, 0x25c4a5ae, 0x6264df7e, + 0x5f04f6ce, 0xed242ade, 0xd044036e, 0x97e479be, 0xaa84500e, + 0x4834505d, 0x755479ed, 0x32f4033d, 0x0f942a8d, 0xbdb4f69d, + 0x80d4df2d, 0xc774a5fd, 0xfa148c4d, 0x78441b9c, 0x4524322c, + 0x028448fc, 0x3fe4614c, 0x8dc4bd5c, 0xb0a494ec, 0xf704ee3c, + 0xca64c78c}, + {0x00000000, 0xb8bc6765, 0xaa09c88b, 0x12b5afee, 0x8f629757, + 0x37def032, 0x256b5fdc, 0x9dd738b9, 0xc5b428ef, 0x7d084f8a, + 0x6fbde064, 0xd7018701, 0x4ad6bfb8, 0xf26ad8dd, 0xe0df7733, + 0x58631056, 0x5019579f, 0xe8a530fa, 0xfa109f14, 0x42acf871, + 0xdf7bc0c8, 0x67c7a7ad, 0x75720843, 0xcdce6f26, 0x95ad7f70, + 0x2d111815, 0x3fa4b7fb, 0x8718d09e, 0x1acfe827, 0xa2738f42, + 0xb0c620ac, 0x087a47c9, 0xa032af3e, 0x188ec85b, 0x0a3b67b5, + 0xb28700d0, 0x2f503869, 0x97ec5f0c, 0x8559f0e2, 0x3de59787, + 0x658687d1, 0xdd3ae0b4, 0xcf8f4f5a, 0x7733283f, 0xeae41086, + 0x525877e3, 0x40edd80d, 0xf851bf68, 0xf02bf8a1, 0x48979fc4, + 0x5a22302a, 0xe29e574f, 0x7f496ff6, 0xc7f50893, 0xd540a77d, + 0x6dfcc018, 0x359fd04e, 0x8d23b72b, 0x9f9618c5, 0x272a7fa0, + 0xbafd4719, 0x0241207c, 0x10f48f92, 0xa848e8f7, 0x9b14583d, + 0x23a83f58, 0x311d90b6, 0x89a1f7d3, 0x1476cf6a, 0xaccaa80f, + 0xbe7f07e1, 0x06c36084, 0x5ea070d2, 0xe61c17b7, 0xf4a9b859, + 0x4c15df3c, 0xd1c2e785, 0x697e80e0, 0x7bcb2f0e, 0xc377486b, + 0xcb0d0fa2, 0x73b168c7, 0x6104c729, 0xd9b8a04c, 0x446f98f5, + 0xfcd3ff90, 0xee66507e, 0x56da371b, 0x0eb9274d, 0xb6054028, + 0xa4b0efc6, 0x1c0c88a3, 0x81dbb01a, 0x3967d77f, 0x2bd27891, + 0x936e1ff4, 0x3b26f703, 0x839a9066, 0x912f3f88, 0x299358ed, + 0xb4446054, 0x0cf80731, 0x1e4da8df, 0xa6f1cfba, 0xfe92dfec, + 0x462eb889, 0x549b1767, 0xec277002, 0x71f048bb, 0xc94c2fde, + 0xdbf98030, 0x6345e755, 0x6b3fa09c, 0xd383c7f9, 0xc1366817, + 0x798a0f72, 0xe45d37cb, 0x5ce150ae, 0x4e54ff40, 0xf6e89825, + 0xae8b8873, 0x1637ef16, 0x048240f8, 0xbc3e279d, 0x21e91f24, + 0x99557841, 0x8be0d7af, 0x335cb0ca, 0xed59b63b, 0x55e5d15e, + 0x47507eb0, 0xffec19d5, 0x623b216c, 0xda874609, 0xc832e9e7, + 0x708e8e82, 0x28ed9ed4, 0x9051f9b1, 0x82e4565f, 0x3a58313a, + 0xa78f0983, 0x1f336ee6, 0x0d86c108, 0xb53aa66d, 0xbd40e1a4, + 0x05fc86c1, 0x1749292f, 0xaff54e4a, 0x322276f3, 0x8a9e1196, + 0x982bbe78, 0x2097d91d, 0x78f4c94b, 0xc048ae2e, 0xd2fd01c0, + 0x6a4166a5, 0xf7965e1c, 0x4f2a3979, 0x5d9f9697, 0xe523f1f2, + 0x4d6b1905, 0xf5d77e60, 0xe762d18e, 0x5fdeb6eb, 0xc2098e52, + 0x7ab5e937, 0x680046d9, 0xd0bc21bc, 0x88df31ea, 0x3063568f, + 0x22d6f961, 0x9a6a9e04, 0x07bda6bd, 0xbf01c1d8, 0xadb46e36, + 0x15080953, 0x1d724e9a, 0xa5ce29ff, 0xb77b8611, 0x0fc7e174, + 0x9210d9cd, 0x2aacbea8, 0x38191146, 0x80a57623, 0xd8c66675, + 0x607a0110, 0x72cfaefe, 0xca73c99b, 0x57a4f122, 0xef189647, + 0xfdad39a9, 0x45115ecc, 0x764dee06, 0xcef18963, 0xdc44268d, + 0x64f841e8, 0xf92f7951, 0x41931e34, 0x5326b1da, 0xeb9ad6bf, + 0xb3f9c6e9, 0x0b45a18c, 0x19f00e62, 0xa14c6907, 0x3c9b51be, + 0x842736db, 0x96929935, 0x2e2efe50, 0x2654b999, 0x9ee8defc, + 0x8c5d7112, 0x34e11677, 0xa9362ece, 0x118a49ab, 0x033fe645, + 0xbb838120, 0xe3e09176, 0x5b5cf613, 0x49e959fd, 0xf1553e98, + 0x6c820621, 0xd43e6144, 0xc68bceaa, 0x7e37a9cf, 0xd67f4138, + 0x6ec3265d, 0x7c7689b3, 0xc4caeed6, 0x591dd66f, 0xe1a1b10a, + 0xf3141ee4, 0x4ba87981, 0x13cb69d7, 0xab770eb2, 0xb9c2a15c, + 0x017ec639, 0x9ca9fe80, 0x241599e5, 0x36a0360b, 0x8e1c516e, + 0x866616a7, 0x3eda71c2, 0x2c6fde2c, 0x94d3b949, 0x090481f0, + 0xb1b8e695, 0xa30d497b, 0x1bb12e1e, 0x43d23e48, 0xfb6e592d, + 0xe9dbf6c3, 0x516791a6, 0xccb0a91f, 0x740cce7a, 0x66b96194, + 0xde0506f1}, + {0x00000000, 0x01c26a37, 0x0384d46e, 0x0246be59, 0x0709a8dc, + 0x06cbc2eb, 0x048d7cb2, 0x054f1685, 0x0e1351b8, 0x0fd13b8f, + 0x0d9785d6, 0x0c55efe1, 0x091af964, 0x08d89353, 0x0a9e2d0a, + 0x0b5c473d, 0x1c26a370, 0x1de4c947, 0x1fa2771e, 0x1e601d29, + 0x1b2f0bac, 0x1aed619b, 0x18abdfc2, 0x1969b5f5, 0x1235f2c8, + 0x13f798ff, 0x11b126a6, 0x10734c91, 0x153c5a14, 0x14fe3023, + 0x16b88e7a, 0x177ae44d, 0x384d46e0, 0x398f2cd7, 0x3bc9928e, + 0x3a0bf8b9, 0x3f44ee3c, 0x3e86840b, 0x3cc03a52, 0x3d025065, + 0x365e1758, 0x379c7d6f, 0x35dac336, 0x3418a901, 0x3157bf84, + 0x3095d5b3, 0x32d36bea, 0x331101dd, 0x246be590, 0x25a98fa7, + 0x27ef31fe, 0x262d5bc9, 0x23624d4c, 0x22a0277b, 0x20e69922, + 0x2124f315, 0x2a78b428, 0x2bbade1f, 0x29fc6046, 0x283e0a71, + 0x2d711cf4, 0x2cb376c3, 0x2ef5c89a, 0x2f37a2ad, 0x709a8dc0, + 0x7158e7f7, 0x731e59ae, 0x72dc3399, 0x7793251c, 0x76514f2b, + 0x7417f172, 0x75d59b45, 0x7e89dc78, 0x7f4bb64f, 0x7d0d0816, + 0x7ccf6221, 0x798074a4, 0x78421e93, 0x7a04a0ca, 0x7bc6cafd, + 0x6cbc2eb0, 0x6d7e4487, 0x6f38fade, 0x6efa90e9, 0x6bb5866c, + 0x6a77ec5b, 0x68315202, 0x69f33835, 0x62af7f08, 0x636d153f, + 0x612bab66, 0x60e9c151, 0x65a6d7d4, 0x6464bde3, 0x662203ba, + 0x67e0698d, 0x48d7cb20, 0x4915a117, 0x4b531f4e, 0x4a917579, + 0x4fde63fc, 0x4e1c09cb, 0x4c5ab792, 0x4d98dda5, 0x46c49a98, + 0x4706f0af, 0x45404ef6, 0x448224c1, 0x41cd3244, 0x400f5873, + 0x4249e62a, 0x438b8c1d, 0x54f16850, 0x55330267, 0x5775bc3e, + 0x56b7d609, 0x53f8c08c, 0x523aaabb, 0x507c14e2, 0x51be7ed5, + 0x5ae239e8, 0x5b2053df, 0x5966ed86, 0x58a487b1, 0x5deb9134, + 0x5c29fb03, 0x5e6f455a, 0x5fad2f6d, 0xe1351b80, 0xe0f771b7, + 0xe2b1cfee, 0xe373a5d9, 0xe63cb35c, 0xe7fed96b, 0xe5b86732, + 0xe47a0d05, 0xef264a38, 0xeee4200f, 0xeca29e56, 0xed60f461, + 0xe82fe2e4, 0xe9ed88d3, 0xebab368a, 0xea695cbd, 0xfd13b8f0, + 0xfcd1d2c7, 0xfe976c9e, 0xff5506a9, 0xfa1a102c, 0xfbd87a1b, + 0xf99ec442, 0xf85cae75, 0xf300e948, 0xf2c2837f, 0xf0843d26, + 0xf1465711, 0xf4094194, 0xf5cb2ba3, 0xf78d95fa, 0xf64fffcd, + 0xd9785d60, 0xd8ba3757, 0xdafc890e, 0xdb3ee339, 0xde71f5bc, + 0xdfb39f8b, 0xddf521d2, 0xdc374be5, 0xd76b0cd8, 0xd6a966ef, + 0xd4efd8b6, 0xd52db281, 0xd062a404, 0xd1a0ce33, 0xd3e6706a, + 0xd2241a5d, 0xc55efe10, 0xc49c9427, 0xc6da2a7e, 0xc7184049, + 0xc25756cc, 0xc3953cfb, 0xc1d382a2, 0xc011e895, 0xcb4dafa8, + 0xca8fc59f, 0xc8c97bc6, 0xc90b11f1, 0xcc440774, 0xcd866d43, + 0xcfc0d31a, 0xce02b92d, 0x91af9640, 0x906dfc77, 0x922b422e, + 0x93e92819, 0x96a63e9c, 0x976454ab, 0x9522eaf2, 0x94e080c5, + 0x9fbcc7f8, 0x9e7eadcf, 0x9c381396, 0x9dfa79a1, 0x98b56f24, + 0x99770513, 0x9b31bb4a, 0x9af3d17d, 0x8d893530, 0x8c4b5f07, + 0x8e0de15e, 0x8fcf8b69, 0x8a809dec, 0x8b42f7db, 0x89044982, + 0x88c623b5, 0x839a6488, 0x82580ebf, 0x801eb0e6, 0x81dcdad1, + 0x8493cc54, 0x8551a663, 0x8717183a, 0x86d5720d, 0xa9e2d0a0, + 0xa820ba97, 0xaa6604ce, 0xaba46ef9, 0xaeeb787c, 0xaf29124b, + 0xad6fac12, 0xacadc625, 0xa7f18118, 0xa633eb2f, 0xa4755576, + 0xa5b73f41, 0xa0f829c4, 0xa13a43f3, 0xa37cfdaa, 0xa2be979d, + 0xb5c473d0, 0xb40619e7, 0xb640a7be, 0xb782cd89, 0xb2cddb0c, + 0xb30fb13b, 0xb1490f62, 0xb08b6555, 0xbbd72268, 0xba15485f, + 0xb853f606, 0xb9919c31, 0xbcde8ab4, 0xbd1ce083, 0xbf5a5eda, + 0xbe9834ed}, + {0x00000000, 0x191b3141, 0x32366282, 0x2b2d53c3, 0x646cc504, + 0x7d77f445, 0x565aa786, 0x4f4196c7, 0xc8d98a08, 0xd1c2bb49, + 0xfaefe88a, 0xe3f4d9cb, 0xacb54f0c, 0xb5ae7e4d, 0x9e832d8e, + 0x87981ccf, 0x4ac21251, 0x53d92310, 0x78f470d3, 0x61ef4192, + 0x2eaed755, 0x37b5e614, 0x1c98b5d7, 0x05838496, 0x821b9859, + 0x9b00a918, 0xb02dfadb, 0xa936cb9a, 0xe6775d5d, 0xff6c6c1c, + 0xd4413fdf, 0xcd5a0e9e, 0x958424a2, 0x8c9f15e3, 0xa7b24620, + 0xbea97761, 0xf1e8e1a6, 0xe8f3d0e7, 0xc3de8324, 0xdac5b265, + 0x5d5daeaa, 0x44469feb, 0x6f6bcc28, 0x7670fd69, 0x39316bae, + 0x202a5aef, 0x0b07092c, 0x121c386d, 0xdf4636f3, 0xc65d07b2, + 0xed705471, 0xf46b6530, 0xbb2af3f7, 0xa231c2b6, 0x891c9175, + 0x9007a034, 0x179fbcfb, 0x0e848dba, 0x25a9de79, 0x3cb2ef38, + 0x73f379ff, 0x6ae848be, 0x41c51b7d, 0x58de2a3c, 0xf0794f05, + 0xe9627e44, 0xc24f2d87, 0xdb541cc6, 0x94158a01, 0x8d0ebb40, + 0xa623e883, 0xbf38d9c2, 0x38a0c50d, 0x21bbf44c, 0x0a96a78f, + 0x138d96ce, 0x5ccc0009, 0x45d73148, 0x6efa628b, 0x77e153ca, + 0xbabb5d54, 0xa3a06c15, 0x888d3fd6, 0x91960e97, 0xded79850, + 0xc7cca911, 0xece1fad2, 0xf5facb93, 0x7262d75c, 0x6b79e61d, + 0x4054b5de, 0x594f849f, 0x160e1258, 0x0f152319, 0x243870da, + 0x3d23419b, 0x65fd6ba7, 0x7ce65ae6, 0x57cb0925, 0x4ed03864, + 0x0191aea3, 0x188a9fe2, 0x33a7cc21, 0x2abcfd60, 0xad24e1af, + 0xb43fd0ee, 0x9f12832d, 0x8609b26c, 0xc94824ab, 0xd05315ea, + 0xfb7e4629, 0xe2657768, 0x2f3f79f6, 0x362448b7, 0x1d091b74, + 0x04122a35, 0x4b53bcf2, 0x52488db3, 0x7965de70, 0x607eef31, + 0xe7e6f3fe, 0xfefdc2bf, 0xd5d0917c, 0xcccba03d, 0x838a36fa, + 0x9a9107bb, 0xb1bc5478, 0xa8a76539, 0x3b83984b, 0x2298a90a, + 0x09b5fac9, 0x10aecb88, 0x5fef5d4f, 0x46f46c0e, 0x6dd93fcd, + 0x74c20e8c, 0xf35a1243, 0xea412302, 0xc16c70c1, 0xd8774180, + 0x9736d747, 0x8e2de606, 0xa500b5c5, 0xbc1b8484, 0x71418a1a, + 0x685abb5b, 0x4377e898, 0x5a6cd9d9, 0x152d4f1e, 0x0c367e5f, + 0x271b2d9c, 0x3e001cdd, 0xb9980012, 0xa0833153, 0x8bae6290, + 0x92b553d1, 0xddf4c516, 0xc4eff457, 0xefc2a794, 0xf6d996d5, + 0xae07bce9, 0xb71c8da8, 0x9c31de6b, 0x852aef2a, 0xca6b79ed, + 0xd37048ac, 0xf85d1b6f, 0xe1462a2e, 0x66de36e1, 0x7fc507a0, + 0x54e85463, 0x4df36522, 0x02b2f3e5, 0x1ba9c2a4, 0x30849167, + 0x299fa026, 0xe4c5aeb8, 0xfdde9ff9, 0xd6f3cc3a, 0xcfe8fd7b, + 0x80a96bbc, 0x99b25afd, 0xb29f093e, 0xab84387f, 0x2c1c24b0, + 0x350715f1, 0x1e2a4632, 0x07317773, 0x4870e1b4, 0x516bd0f5, + 0x7a468336, 0x635db277, 0xcbfad74e, 0xd2e1e60f, 0xf9ccb5cc, + 0xe0d7848d, 0xaf96124a, 0xb68d230b, 0x9da070c8, 0x84bb4189, + 0x03235d46, 0x1a386c07, 0x31153fc4, 0x280e0e85, 0x674f9842, + 0x7e54a903, 0x5579fac0, 0x4c62cb81, 0x8138c51f, 0x9823f45e, + 0xb30ea79d, 0xaa1596dc, 0xe554001b, 0xfc4f315a, 0xd7626299, + 0xce7953d8, 0x49e14f17, 0x50fa7e56, 0x7bd72d95, 0x62cc1cd4, + 0x2d8d8a13, 0x3496bb52, 0x1fbbe891, 0x06a0d9d0, 0x5e7ef3ec, + 0x4765c2ad, 0x6c48916e, 0x7553a02f, 0x3a1236e8, 0x230907a9, + 0x0824546a, 0x113f652b, 0x96a779e4, 0x8fbc48a5, 0xa4911b66, + 0xbd8a2a27, 0xf2cbbce0, 0xebd08da1, 0xc0fdde62, 0xd9e6ef23, + 0x14bce1bd, 0x0da7d0fc, 0x268a833f, 0x3f91b27e, 0x70d024b9, + 0x69cb15f8, 0x42e6463b, 0x5bfd777a, 0xdc656bb5, 0xc57e5af4, + 0xee530937, 0xf7483876, 0xb809aeb1, 0xa1129ff0, 0x8a3fcc33, + 0x9324fd72}, + {0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, + 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, + 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, + 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, + 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, + 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, + 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, + 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, + 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, + 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, + 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, + 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, + 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, + 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, + 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, + 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, + 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, + 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, + 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, + 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, + 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, + 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, + 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, + 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, + 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, + 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, + 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, + 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, + 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, + 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, + 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, + 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, + 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, + 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, + 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, + 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, + 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, + 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, + 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, + 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, + 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, + 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, + 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, + 0x2d02ef8d}}; + +local const z_word_t FAR crc_braid_big_table[][256] = { + {0x0000000000000000, 0x9630077700000000, 0x2c610eee00000000, + 0xba51099900000000, 0x19c46d0700000000, 0x8ff46a7000000000, + 0x35a563e900000000, 0xa395649e00000000, 0x3288db0e00000000, + 0xa4b8dc7900000000, 0x1ee9d5e000000000, 0x88d9d29700000000, + 0x2b4cb60900000000, 0xbd7cb17e00000000, 0x072db8e700000000, + 0x911dbf9000000000, 0x6410b71d00000000, 0xf220b06a00000000, + 0x4871b9f300000000, 0xde41be8400000000, 0x7dd4da1a00000000, + 0xebe4dd6d00000000, 0x51b5d4f400000000, 0xc785d38300000000, + 0x56986c1300000000, 0xc0a86b6400000000, 0x7af962fd00000000, + 0xecc9658a00000000, 0x4f5c011400000000, 0xd96c066300000000, + 0x633d0ffa00000000, 0xf50d088d00000000, 0xc8206e3b00000000, + 0x5e10694c00000000, 0xe44160d500000000, 0x727167a200000000, + 0xd1e4033c00000000, 0x47d4044b00000000, 0xfd850dd200000000, + 0x6bb50aa500000000, 0xfaa8b53500000000, 0x6c98b24200000000, + 0xd6c9bbdb00000000, 0x40f9bcac00000000, 0xe36cd83200000000, + 0x755cdf4500000000, 0xcf0dd6dc00000000, 0x593dd1ab00000000, + 0xac30d92600000000, 0x3a00de5100000000, 0x8051d7c800000000, + 0x1661d0bf00000000, 0xb5f4b42100000000, 0x23c4b35600000000, + 0x9995bacf00000000, 0x0fa5bdb800000000, 0x9eb8022800000000, + 0x0888055f00000000, 0xb2d90cc600000000, 0x24e90bb100000000, + 0x877c6f2f00000000, 0x114c685800000000, 0xab1d61c100000000, + 0x3d2d66b600000000, 0x9041dc7600000000, 0x0671db0100000000, + 0xbc20d29800000000, 0x2a10d5ef00000000, 0x8985b17100000000, + 0x1fb5b60600000000, 0xa5e4bf9f00000000, 0x33d4b8e800000000, + 0xa2c9077800000000, 0x34f9000f00000000, 0x8ea8099600000000, + 0x18980ee100000000, 0xbb0d6a7f00000000, 0x2d3d6d0800000000, + 0x976c649100000000, 0x015c63e600000000, 0xf4516b6b00000000, + 0x62616c1c00000000, 0xd830658500000000, 0x4e0062f200000000, + 0xed95066c00000000, 0x7ba5011b00000000, 0xc1f4088200000000, + 0x57c40ff500000000, 0xc6d9b06500000000, 0x50e9b71200000000, + 0xeab8be8b00000000, 0x7c88b9fc00000000, 0xdf1ddd6200000000, + 0x492dda1500000000, 0xf37cd38c00000000, 0x654cd4fb00000000, + 0x5861b24d00000000, 0xce51b53a00000000, 0x7400bca300000000, + 0xe230bbd400000000, 0x41a5df4a00000000, 0xd795d83d00000000, + 0x6dc4d1a400000000, 0xfbf4d6d300000000, 0x6ae9694300000000, + 0xfcd96e3400000000, 0x468867ad00000000, 0xd0b860da00000000, + 0x732d044400000000, 0xe51d033300000000, 0x5f4c0aaa00000000, + 0xc97c0ddd00000000, 0x3c71055000000000, 0xaa41022700000000, + 0x10100bbe00000000, 0x86200cc900000000, 0x25b5685700000000, + 0xb3856f2000000000, 0x09d466b900000000, 0x9fe461ce00000000, + 0x0ef9de5e00000000, 0x98c9d92900000000, 0x2298d0b000000000, + 0xb4a8d7c700000000, 0x173db35900000000, 0x810db42e00000000, + 0x3b5cbdb700000000, 0xad6cbac000000000, 0x2083b8ed00000000, + 0xb6b3bf9a00000000, 0x0ce2b60300000000, 0x9ad2b17400000000, + 0x3947d5ea00000000, 0xaf77d29d00000000, 0x1526db0400000000, + 0x8316dc7300000000, 0x120b63e300000000, 0x843b649400000000, + 0x3e6a6d0d00000000, 0xa85a6a7a00000000, 0x0bcf0ee400000000, + 0x9dff099300000000, 0x27ae000a00000000, 0xb19e077d00000000, + 0x44930ff000000000, 0xd2a3088700000000, 0x68f2011e00000000, + 0xfec2066900000000, 0x5d5762f700000000, 0xcb67658000000000, + 0x71366c1900000000, 0xe7066b6e00000000, 0x761bd4fe00000000, + 0xe02bd38900000000, 0x5a7ada1000000000, 0xcc4add6700000000, + 0x6fdfb9f900000000, 0xf9efbe8e00000000, 0x43beb71700000000, + 0xd58eb06000000000, 0xe8a3d6d600000000, 0x7e93d1a100000000, + 0xc4c2d83800000000, 0x52f2df4f00000000, 0xf167bbd100000000, + 0x6757bca600000000, 0xdd06b53f00000000, 0x4b36b24800000000, + 0xda2b0dd800000000, 0x4c1b0aaf00000000, 0xf64a033600000000, + 0x607a044100000000, 0xc3ef60df00000000, 0x55df67a800000000, + 0xef8e6e3100000000, 0x79be694600000000, 0x8cb361cb00000000, + 0x1a8366bc00000000, 0xa0d26f2500000000, 0x36e2685200000000, + 0x95770ccc00000000, 0x03470bbb00000000, 0xb916022200000000, + 0x2f26055500000000, 0xbe3bbac500000000, 0x280bbdb200000000, + 0x925ab42b00000000, 0x046ab35c00000000, 0xa7ffd7c200000000, + 0x31cfd0b500000000, 0x8b9ed92c00000000, 0x1daede5b00000000, + 0xb0c2649b00000000, 0x26f263ec00000000, 0x9ca36a7500000000, + 0x0a936d0200000000, 0xa906099c00000000, 0x3f360eeb00000000, + 0x8567077200000000, 0x1357000500000000, 0x824abf9500000000, + 0x147ab8e200000000, 0xae2bb17b00000000, 0x381bb60c00000000, + 0x9b8ed29200000000, 0x0dbed5e500000000, 0xb7efdc7c00000000, + 0x21dfdb0b00000000, 0xd4d2d38600000000, 0x42e2d4f100000000, + 0xf8b3dd6800000000, 0x6e83da1f00000000, 0xcd16be8100000000, + 0x5b26b9f600000000, 0xe177b06f00000000, 0x7747b71800000000, + 0xe65a088800000000, 0x706a0fff00000000, 0xca3b066600000000, + 0x5c0b011100000000, 0xff9e658f00000000, 0x69ae62f800000000, + 0xd3ff6b6100000000, 0x45cf6c1600000000, 0x78e20aa000000000, + 0xeed20dd700000000, 0x5483044e00000000, 0xc2b3033900000000, + 0x612667a700000000, 0xf71660d000000000, 0x4d47694900000000, + 0xdb776e3e00000000, 0x4a6ad1ae00000000, 0xdc5ad6d900000000, + 0x660bdf4000000000, 0xf03bd83700000000, 0x53aebca900000000, + 0xc59ebbde00000000, 0x7fcfb24700000000, 0xe9ffb53000000000, + 0x1cf2bdbd00000000, 0x8ac2baca00000000, 0x3093b35300000000, + 0xa6a3b42400000000, 0x0536d0ba00000000, 0x9306d7cd00000000, + 0x2957de5400000000, 0xbf67d92300000000, 0x2e7a66b300000000, + 0xb84a61c400000000, 0x021b685d00000000, 0x942b6f2a00000000, + 0x37be0bb400000000, 0xa18e0cc300000000, 0x1bdf055a00000000, + 0x8def022d00000000}, + {0x0000000000000000, 0x41311b1900000000, 0x8262363200000000, + 0xc3532d2b00000000, 0x04c56c6400000000, 0x45f4777d00000000, + 0x86a75a5600000000, 0xc796414f00000000, 0x088ad9c800000000, + 0x49bbc2d100000000, 0x8ae8effa00000000, 0xcbd9f4e300000000, + 0x0c4fb5ac00000000, 0x4d7eaeb500000000, 0x8e2d839e00000000, + 0xcf1c988700000000, 0x5112c24a00000000, 0x1023d95300000000, + 0xd370f47800000000, 0x9241ef6100000000, 0x55d7ae2e00000000, + 0x14e6b53700000000, 0xd7b5981c00000000, 0x9684830500000000, + 0x59981b8200000000, 0x18a9009b00000000, 0xdbfa2db000000000, + 0x9acb36a900000000, 0x5d5d77e600000000, 0x1c6c6cff00000000, + 0xdf3f41d400000000, 0x9e0e5acd00000000, 0xa224849500000000, + 0xe3159f8c00000000, 0x2046b2a700000000, 0x6177a9be00000000, + 0xa6e1e8f100000000, 0xe7d0f3e800000000, 0x2483dec300000000, + 0x65b2c5da00000000, 0xaaae5d5d00000000, 0xeb9f464400000000, + 0x28cc6b6f00000000, 0x69fd707600000000, 0xae6b313900000000, + 0xef5a2a2000000000, 0x2c09070b00000000, 0x6d381c1200000000, + 0xf33646df00000000, 0xb2075dc600000000, 0x715470ed00000000, + 0x30656bf400000000, 0xf7f32abb00000000, 0xb6c231a200000000, + 0x75911c8900000000, 0x34a0079000000000, 0xfbbc9f1700000000, + 0xba8d840e00000000, 0x79dea92500000000, 0x38efb23c00000000, + 0xff79f37300000000, 0xbe48e86a00000000, 0x7d1bc54100000000, + 0x3c2ade5800000000, 0x054f79f000000000, 0x447e62e900000000, + 0x872d4fc200000000, 0xc61c54db00000000, 0x018a159400000000, + 0x40bb0e8d00000000, 0x83e823a600000000, 0xc2d938bf00000000, + 0x0dc5a03800000000, 0x4cf4bb2100000000, 0x8fa7960a00000000, + 0xce968d1300000000, 0x0900cc5c00000000, 0x4831d74500000000, + 0x8b62fa6e00000000, 0xca53e17700000000, 0x545dbbba00000000, + 0x156ca0a300000000, 0xd63f8d8800000000, 0x970e969100000000, + 0x5098d7de00000000, 0x11a9ccc700000000, 0xd2fae1ec00000000, + 0x93cbfaf500000000, 0x5cd7627200000000, 0x1de6796b00000000, + 0xdeb5544000000000, 0x9f844f5900000000, 0x58120e1600000000, + 0x1923150f00000000, 0xda70382400000000, 0x9b41233d00000000, + 0xa76bfd6500000000, 0xe65ae67c00000000, 0x2509cb5700000000, + 0x6438d04e00000000, 0xa3ae910100000000, 0xe29f8a1800000000, + 0x21cca73300000000, 0x60fdbc2a00000000, 0xafe124ad00000000, + 0xeed03fb400000000, 0x2d83129f00000000, 0x6cb2098600000000, + 0xab2448c900000000, 0xea1553d000000000, 0x29467efb00000000, + 0x687765e200000000, 0xf6793f2f00000000, 0xb748243600000000, + 0x741b091d00000000, 0x352a120400000000, 0xf2bc534b00000000, + 0xb38d485200000000, 0x70de657900000000, 0x31ef7e6000000000, + 0xfef3e6e700000000, 0xbfc2fdfe00000000, 0x7c91d0d500000000, + 0x3da0cbcc00000000, 0xfa368a8300000000, 0xbb07919a00000000, + 0x7854bcb100000000, 0x3965a7a800000000, 0x4b98833b00000000, + 0x0aa9982200000000, 0xc9fab50900000000, 0x88cbae1000000000, + 0x4f5def5f00000000, 0x0e6cf44600000000, 0xcd3fd96d00000000, + 0x8c0ec27400000000, 0x43125af300000000, 0x022341ea00000000, + 0xc1706cc100000000, 0x804177d800000000, 0x47d7369700000000, + 0x06e62d8e00000000, 0xc5b500a500000000, 0x84841bbc00000000, + 0x1a8a417100000000, 0x5bbb5a6800000000, 0x98e8774300000000, + 0xd9d96c5a00000000, 0x1e4f2d1500000000, 0x5f7e360c00000000, + 0x9c2d1b2700000000, 0xdd1c003e00000000, 0x120098b900000000, + 0x533183a000000000, 0x9062ae8b00000000, 0xd153b59200000000, + 0x16c5f4dd00000000, 0x57f4efc400000000, 0x94a7c2ef00000000, + 0xd596d9f600000000, 0xe9bc07ae00000000, 0xa88d1cb700000000, + 0x6bde319c00000000, 0x2aef2a8500000000, 0xed796bca00000000, + 0xac4870d300000000, 0x6f1b5df800000000, 0x2e2a46e100000000, + 0xe136de6600000000, 0xa007c57f00000000, 0x6354e85400000000, + 0x2265f34d00000000, 0xe5f3b20200000000, 0xa4c2a91b00000000, + 0x6791843000000000, 0x26a09f2900000000, 0xb8aec5e400000000, + 0xf99fdefd00000000, 0x3accf3d600000000, 0x7bfde8cf00000000, + 0xbc6ba98000000000, 0xfd5ab29900000000, 0x3e099fb200000000, + 0x7f3884ab00000000, 0xb0241c2c00000000, 0xf115073500000000, + 0x32462a1e00000000, 0x7377310700000000, 0xb4e1704800000000, + 0xf5d06b5100000000, 0x3683467a00000000, 0x77b25d6300000000, + 0x4ed7facb00000000, 0x0fe6e1d200000000, 0xccb5ccf900000000, + 0x8d84d7e000000000, 0x4a1296af00000000, 0x0b238db600000000, + 0xc870a09d00000000, 0x8941bb8400000000, 0x465d230300000000, + 0x076c381a00000000, 0xc43f153100000000, 0x850e0e2800000000, + 0x42984f6700000000, 0x03a9547e00000000, 0xc0fa795500000000, + 0x81cb624c00000000, 0x1fc5388100000000, 0x5ef4239800000000, + 0x9da70eb300000000, 0xdc9615aa00000000, 0x1b0054e500000000, + 0x5a314ffc00000000, 0x996262d700000000, 0xd85379ce00000000, + 0x174fe14900000000, 0x567efa5000000000, 0x952dd77b00000000, + 0xd41ccc6200000000, 0x138a8d2d00000000, 0x52bb963400000000, + 0x91e8bb1f00000000, 0xd0d9a00600000000, 0xecf37e5e00000000, + 0xadc2654700000000, 0x6e91486c00000000, 0x2fa0537500000000, + 0xe836123a00000000, 0xa907092300000000, 0x6a54240800000000, + 0x2b653f1100000000, 0xe479a79600000000, 0xa548bc8f00000000, + 0x661b91a400000000, 0x272a8abd00000000, 0xe0bccbf200000000, + 0xa18dd0eb00000000, 0x62defdc000000000, 0x23efe6d900000000, + 0xbde1bc1400000000, 0xfcd0a70d00000000, 0x3f838a2600000000, + 0x7eb2913f00000000, 0xb924d07000000000, 0xf815cb6900000000, + 0x3b46e64200000000, 0x7a77fd5b00000000, 0xb56b65dc00000000, + 0xf45a7ec500000000, 0x370953ee00000000, 0x763848f700000000, + 0xb1ae09b800000000, 0xf09f12a100000000, 0x33cc3f8a00000000, + 0x72fd249300000000}, + {0x0000000000000000, 0x376ac20100000000, 0x6ed4840300000000, + 0x59be460200000000, 0xdca8090700000000, 0xebc2cb0600000000, + 0xb27c8d0400000000, 0x85164f0500000000, 0xb851130e00000000, + 0x8f3bd10f00000000, 0xd685970d00000000, 0xe1ef550c00000000, + 0x64f91a0900000000, 0x5393d80800000000, 0x0a2d9e0a00000000, + 0x3d475c0b00000000, 0x70a3261c00000000, 0x47c9e41d00000000, + 0x1e77a21f00000000, 0x291d601e00000000, 0xac0b2f1b00000000, + 0x9b61ed1a00000000, 0xc2dfab1800000000, 0xf5b5691900000000, + 0xc8f2351200000000, 0xff98f71300000000, 0xa626b11100000000, + 0x914c731000000000, 0x145a3c1500000000, 0x2330fe1400000000, + 0x7a8eb81600000000, 0x4de47a1700000000, 0xe0464d3800000000, + 0xd72c8f3900000000, 0x8e92c93b00000000, 0xb9f80b3a00000000, + 0x3cee443f00000000, 0x0b84863e00000000, 0x523ac03c00000000, + 0x6550023d00000000, 0x58175e3600000000, 0x6f7d9c3700000000, + 0x36c3da3500000000, 0x01a9183400000000, 0x84bf573100000000, + 0xb3d5953000000000, 0xea6bd33200000000, 0xdd01113300000000, + 0x90e56b2400000000, 0xa78fa92500000000, 0xfe31ef2700000000, + 0xc95b2d2600000000, 0x4c4d622300000000, 0x7b27a02200000000, + 0x2299e62000000000, 0x15f3242100000000, 0x28b4782a00000000, + 0x1fdeba2b00000000, 0x4660fc2900000000, 0x710a3e2800000000, + 0xf41c712d00000000, 0xc376b32c00000000, 0x9ac8f52e00000000, + 0xada2372f00000000, 0xc08d9a7000000000, 0xf7e7587100000000, + 0xae591e7300000000, 0x9933dc7200000000, 0x1c25937700000000, + 0x2b4f517600000000, 0x72f1177400000000, 0x459bd57500000000, + 0x78dc897e00000000, 0x4fb64b7f00000000, 0x16080d7d00000000, + 0x2162cf7c00000000, 0xa474807900000000, 0x931e427800000000, + 0xcaa0047a00000000, 0xfdcac67b00000000, 0xb02ebc6c00000000, + 0x87447e6d00000000, 0xdefa386f00000000, 0xe990fa6e00000000, + 0x6c86b56b00000000, 0x5bec776a00000000, 0x0252316800000000, + 0x3538f36900000000, 0x087faf6200000000, 0x3f156d6300000000, + 0x66ab2b6100000000, 0x51c1e96000000000, 0xd4d7a66500000000, + 0xe3bd646400000000, 0xba03226600000000, 0x8d69e06700000000, + 0x20cbd74800000000, 0x17a1154900000000, 0x4e1f534b00000000, + 0x7975914a00000000, 0xfc63de4f00000000, 0xcb091c4e00000000, + 0x92b75a4c00000000, 0xa5dd984d00000000, 0x989ac44600000000, + 0xaff0064700000000, 0xf64e404500000000, 0xc124824400000000, + 0x4432cd4100000000, 0x73580f4000000000, 0x2ae6494200000000, + 0x1d8c8b4300000000, 0x5068f15400000000, 0x6702335500000000, + 0x3ebc755700000000, 0x09d6b75600000000, 0x8cc0f85300000000, + 0xbbaa3a5200000000, 0xe2147c5000000000, 0xd57ebe5100000000, + 0xe839e25a00000000, 0xdf53205b00000000, 0x86ed665900000000, + 0xb187a45800000000, 0x3491eb5d00000000, 0x03fb295c00000000, + 0x5a456f5e00000000, 0x6d2fad5f00000000, 0x801b35e100000000, + 0xb771f7e000000000, 0xeecfb1e200000000, 0xd9a573e300000000, + 0x5cb33ce600000000, 0x6bd9fee700000000, 0x3267b8e500000000, + 0x050d7ae400000000, 0x384a26ef00000000, 0x0f20e4ee00000000, + 0x569ea2ec00000000, 0x61f460ed00000000, 0xe4e22fe800000000, + 0xd388ede900000000, 0x8a36abeb00000000, 0xbd5c69ea00000000, + 0xf0b813fd00000000, 0xc7d2d1fc00000000, 0x9e6c97fe00000000, + 0xa90655ff00000000, 0x2c101afa00000000, 0x1b7ad8fb00000000, + 0x42c49ef900000000, 0x75ae5cf800000000, 0x48e900f300000000, + 0x7f83c2f200000000, 0x263d84f000000000, 0x115746f100000000, + 0x944109f400000000, 0xa32bcbf500000000, 0xfa958df700000000, + 0xcdff4ff600000000, 0x605d78d900000000, 0x5737bad800000000, + 0x0e89fcda00000000, 0x39e33edb00000000, 0xbcf571de00000000, + 0x8b9fb3df00000000, 0xd221f5dd00000000, 0xe54b37dc00000000, + 0xd80c6bd700000000, 0xef66a9d600000000, 0xb6d8efd400000000, + 0x81b22dd500000000, 0x04a462d000000000, 0x33cea0d100000000, + 0x6a70e6d300000000, 0x5d1a24d200000000, 0x10fe5ec500000000, + 0x27949cc400000000, 0x7e2adac600000000, 0x494018c700000000, + 0xcc5657c200000000, 0xfb3c95c300000000, 0xa282d3c100000000, + 0x95e811c000000000, 0xa8af4dcb00000000, 0x9fc58fca00000000, + 0xc67bc9c800000000, 0xf1110bc900000000, 0x740744cc00000000, + 0x436d86cd00000000, 0x1ad3c0cf00000000, 0x2db902ce00000000, + 0x4096af9100000000, 0x77fc6d9000000000, 0x2e422b9200000000, + 0x1928e99300000000, 0x9c3ea69600000000, 0xab54649700000000, + 0xf2ea229500000000, 0xc580e09400000000, 0xf8c7bc9f00000000, + 0xcfad7e9e00000000, 0x9613389c00000000, 0xa179fa9d00000000, + 0x246fb59800000000, 0x1305779900000000, 0x4abb319b00000000, + 0x7dd1f39a00000000, 0x3035898d00000000, 0x075f4b8c00000000, + 0x5ee10d8e00000000, 0x698bcf8f00000000, 0xec9d808a00000000, + 0xdbf7428b00000000, 0x8249048900000000, 0xb523c68800000000, + 0x88649a8300000000, 0xbf0e588200000000, 0xe6b01e8000000000, + 0xd1dadc8100000000, 0x54cc938400000000, 0x63a6518500000000, + 0x3a18178700000000, 0x0d72d58600000000, 0xa0d0e2a900000000, + 0x97ba20a800000000, 0xce0466aa00000000, 0xf96ea4ab00000000, + 0x7c78ebae00000000, 0x4b1229af00000000, 0x12ac6fad00000000, + 0x25c6adac00000000, 0x1881f1a700000000, 0x2feb33a600000000, + 0x765575a400000000, 0x413fb7a500000000, 0xc429f8a000000000, + 0xf3433aa100000000, 0xaafd7ca300000000, 0x9d97bea200000000, + 0xd073c4b500000000, 0xe71906b400000000, 0xbea740b600000000, + 0x89cd82b700000000, 0x0cdbcdb200000000, 0x3bb10fb300000000, + 0x620f49b100000000, 0x55658bb000000000, 0x6822d7bb00000000, + 0x5f4815ba00000000, 0x06f653b800000000, 0x319c91b900000000, + 0xb48adebc00000000, 0x83e01cbd00000000, 0xda5e5abf00000000, + 0xed3498be00000000}, + {0x0000000000000000, 0x6567bcb800000000, 0x8bc809aa00000000, + 0xeeafb51200000000, 0x5797628f00000000, 0x32f0de3700000000, + 0xdc5f6b2500000000, 0xb938d79d00000000, 0xef28b4c500000000, + 0x8a4f087d00000000, 0x64e0bd6f00000000, 0x018701d700000000, + 0xb8bfd64a00000000, 0xddd86af200000000, 0x3377dfe000000000, + 0x5610635800000000, 0x9f57195000000000, 0xfa30a5e800000000, + 0x149f10fa00000000, 0x71f8ac4200000000, 0xc8c07bdf00000000, + 0xada7c76700000000, 0x4308727500000000, 0x266fcecd00000000, + 0x707fad9500000000, 0x1518112d00000000, 0xfbb7a43f00000000, + 0x9ed0188700000000, 0x27e8cf1a00000000, 0x428f73a200000000, + 0xac20c6b000000000, 0xc9477a0800000000, 0x3eaf32a000000000, + 0x5bc88e1800000000, 0xb5673b0a00000000, 0xd00087b200000000, + 0x6938502f00000000, 0x0c5fec9700000000, 0xe2f0598500000000, + 0x8797e53d00000000, 0xd187866500000000, 0xb4e03add00000000, + 0x5a4f8fcf00000000, 0x3f28337700000000, 0x8610e4ea00000000, + 0xe377585200000000, 0x0dd8ed4000000000, 0x68bf51f800000000, + 0xa1f82bf000000000, 0xc49f974800000000, 0x2a30225a00000000, + 0x4f579ee200000000, 0xf66f497f00000000, 0x9308f5c700000000, + 0x7da740d500000000, 0x18c0fc6d00000000, 0x4ed09f3500000000, + 0x2bb7238d00000000, 0xc518969f00000000, 0xa07f2a2700000000, + 0x1947fdba00000000, 0x7c20410200000000, 0x928ff41000000000, + 0xf7e848a800000000, 0x3d58149b00000000, 0x583fa82300000000, + 0xb6901d3100000000, 0xd3f7a18900000000, 0x6acf761400000000, + 0x0fa8caac00000000, 0xe1077fbe00000000, 0x8460c30600000000, + 0xd270a05e00000000, 0xb7171ce600000000, 0x59b8a9f400000000, + 0x3cdf154c00000000, 0x85e7c2d100000000, 0xe0807e6900000000, + 0x0e2fcb7b00000000, 0x6b4877c300000000, 0xa20f0dcb00000000, + 0xc768b17300000000, 0x29c7046100000000, 0x4ca0b8d900000000, + 0xf5986f4400000000, 0x90ffd3fc00000000, 0x7e5066ee00000000, + 0x1b37da5600000000, 0x4d27b90e00000000, 0x284005b600000000, + 0xc6efb0a400000000, 0xa3880c1c00000000, 0x1ab0db8100000000, + 0x7fd7673900000000, 0x9178d22b00000000, 0xf41f6e9300000000, + 0x03f7263b00000000, 0x66909a8300000000, 0x883f2f9100000000, + 0xed58932900000000, 0x546044b400000000, 0x3107f80c00000000, + 0xdfa84d1e00000000, 0xbacff1a600000000, 0xecdf92fe00000000, + 0x89b82e4600000000, 0x67179b5400000000, 0x027027ec00000000, + 0xbb48f07100000000, 0xde2f4cc900000000, 0x3080f9db00000000, + 0x55e7456300000000, 0x9ca03f6b00000000, 0xf9c783d300000000, + 0x176836c100000000, 0x720f8a7900000000, 0xcb375de400000000, + 0xae50e15c00000000, 0x40ff544e00000000, 0x2598e8f600000000, + 0x73888bae00000000, 0x16ef371600000000, 0xf840820400000000, + 0x9d273ebc00000000, 0x241fe92100000000, 0x4178559900000000, + 0xafd7e08b00000000, 0xcab05c3300000000, 0x3bb659ed00000000, + 0x5ed1e55500000000, 0xb07e504700000000, 0xd519ecff00000000, + 0x6c213b6200000000, 0x094687da00000000, 0xe7e932c800000000, + 0x828e8e7000000000, 0xd49eed2800000000, 0xb1f9519000000000, + 0x5f56e48200000000, 0x3a31583a00000000, 0x83098fa700000000, + 0xe66e331f00000000, 0x08c1860d00000000, 0x6da63ab500000000, + 0xa4e140bd00000000, 0xc186fc0500000000, 0x2f29491700000000, + 0x4a4ef5af00000000, 0xf376223200000000, 0x96119e8a00000000, + 0x78be2b9800000000, 0x1dd9972000000000, 0x4bc9f47800000000, + 0x2eae48c000000000, 0xc001fdd200000000, 0xa566416a00000000, + 0x1c5e96f700000000, 0x79392a4f00000000, 0x97969f5d00000000, + 0xf2f123e500000000, 0x05196b4d00000000, 0x607ed7f500000000, + 0x8ed162e700000000, 0xebb6de5f00000000, 0x528e09c200000000, + 0x37e9b57a00000000, 0xd946006800000000, 0xbc21bcd000000000, + 0xea31df8800000000, 0x8f56633000000000, 0x61f9d62200000000, + 0x049e6a9a00000000, 0xbda6bd0700000000, 0xd8c101bf00000000, + 0x366eb4ad00000000, 0x5309081500000000, 0x9a4e721d00000000, + 0xff29cea500000000, 0x11867bb700000000, 0x74e1c70f00000000, + 0xcdd9109200000000, 0xa8beac2a00000000, 0x4611193800000000, + 0x2376a58000000000, 0x7566c6d800000000, 0x10017a6000000000, + 0xfeaecf7200000000, 0x9bc973ca00000000, 0x22f1a45700000000, + 0x479618ef00000000, 0xa939adfd00000000, 0xcc5e114500000000, + 0x06ee4d7600000000, 0x6389f1ce00000000, 0x8d2644dc00000000, + 0xe841f86400000000, 0x51792ff900000000, 0x341e934100000000, + 0xdab1265300000000, 0xbfd69aeb00000000, 0xe9c6f9b300000000, + 0x8ca1450b00000000, 0x620ef01900000000, 0x07694ca100000000, + 0xbe519b3c00000000, 0xdb36278400000000, 0x3599929600000000, + 0x50fe2e2e00000000, 0x99b9542600000000, 0xfcdee89e00000000, + 0x12715d8c00000000, 0x7716e13400000000, 0xce2e36a900000000, + 0xab498a1100000000, 0x45e63f0300000000, 0x208183bb00000000, + 0x7691e0e300000000, 0x13f65c5b00000000, 0xfd59e94900000000, + 0x983e55f100000000, 0x2106826c00000000, 0x44613ed400000000, + 0xaace8bc600000000, 0xcfa9377e00000000, 0x38417fd600000000, + 0x5d26c36e00000000, 0xb389767c00000000, 0xd6eecac400000000, + 0x6fd61d5900000000, 0x0ab1a1e100000000, 0xe41e14f300000000, + 0x8179a84b00000000, 0xd769cb1300000000, 0xb20e77ab00000000, + 0x5ca1c2b900000000, 0x39c67e0100000000, 0x80fea99c00000000, + 0xe599152400000000, 0x0b36a03600000000, 0x6e511c8e00000000, + 0xa716668600000000, 0xc271da3e00000000, 0x2cde6f2c00000000, + 0x49b9d39400000000, 0xf081040900000000, 0x95e6b8b100000000, + 0x7b490da300000000, 0x1e2eb11b00000000, 0x483ed24300000000, + 0x2d596efb00000000, 0xc3f6dbe900000000, 0xa691675100000000, + 0x1fa9b0cc00000000, 0x7ace0c7400000000, 0x9461b96600000000, + 0xf10605de00000000}, + {0x0000000000000000, 0xb029603d00000000, 0x6053c07a00000000, + 0xd07aa04700000000, 0xc0a680f500000000, 0x708fe0c800000000, + 0xa0f5408f00000000, 0x10dc20b200000000, 0xc14b703000000000, + 0x7162100d00000000, 0xa118b04a00000000, 0x1131d07700000000, + 0x01edf0c500000000, 0xb1c490f800000000, 0x61be30bf00000000, + 0xd197508200000000, 0x8297e06000000000, 0x32be805d00000000, + 0xe2c4201a00000000, 0x52ed402700000000, 0x4231609500000000, + 0xf21800a800000000, 0x2262a0ef00000000, 0x924bc0d200000000, + 0x43dc905000000000, 0xf3f5f06d00000000, 0x238f502a00000000, + 0x93a6301700000000, 0x837a10a500000000, 0x3353709800000000, + 0xe329d0df00000000, 0x5300b0e200000000, 0x042fc1c100000000, + 0xb406a1fc00000000, 0x647c01bb00000000, 0xd455618600000000, + 0xc489413400000000, 0x74a0210900000000, 0xa4da814e00000000, + 0x14f3e17300000000, 0xc564b1f100000000, 0x754dd1cc00000000, + 0xa537718b00000000, 0x151e11b600000000, 0x05c2310400000000, + 0xb5eb513900000000, 0x6591f17e00000000, 0xd5b8914300000000, + 0x86b821a100000000, 0x3691419c00000000, 0xe6ebe1db00000000, + 0x56c281e600000000, 0x461ea15400000000, 0xf637c16900000000, + 0x264d612e00000000, 0x9664011300000000, 0x47f3519100000000, + 0xf7da31ac00000000, 0x27a091eb00000000, 0x9789f1d600000000, + 0x8755d16400000000, 0x377cb15900000000, 0xe706111e00000000, + 0x572f712300000000, 0x4958f35800000000, 0xf971936500000000, + 0x290b332200000000, 0x9922531f00000000, 0x89fe73ad00000000, + 0x39d7139000000000, 0xe9adb3d700000000, 0x5984d3ea00000000, + 0x8813836800000000, 0x383ae35500000000, 0xe840431200000000, + 0x5869232f00000000, 0x48b5039d00000000, 0xf89c63a000000000, + 0x28e6c3e700000000, 0x98cfa3da00000000, 0xcbcf133800000000, + 0x7be6730500000000, 0xab9cd34200000000, 0x1bb5b37f00000000, + 0x0b6993cd00000000, 0xbb40f3f000000000, 0x6b3a53b700000000, + 0xdb13338a00000000, 0x0a84630800000000, 0xbaad033500000000, + 0x6ad7a37200000000, 0xdafec34f00000000, 0xca22e3fd00000000, + 0x7a0b83c000000000, 0xaa71238700000000, 0x1a5843ba00000000, + 0x4d77329900000000, 0xfd5e52a400000000, 0x2d24f2e300000000, + 0x9d0d92de00000000, 0x8dd1b26c00000000, 0x3df8d25100000000, + 0xed82721600000000, 0x5dab122b00000000, 0x8c3c42a900000000, + 0x3c15229400000000, 0xec6f82d300000000, 0x5c46e2ee00000000, + 0x4c9ac25c00000000, 0xfcb3a26100000000, 0x2cc9022600000000, + 0x9ce0621b00000000, 0xcfe0d2f900000000, 0x7fc9b2c400000000, + 0xafb3128300000000, 0x1f9a72be00000000, 0x0f46520c00000000, + 0xbf6f323100000000, 0x6f15927600000000, 0xdf3cf24b00000000, + 0x0eaba2c900000000, 0xbe82c2f400000000, 0x6ef862b300000000, + 0xded1028e00000000, 0xce0d223c00000000, 0x7e24420100000000, + 0xae5ee24600000000, 0x1e77827b00000000, 0x92b0e6b100000000, + 0x2299868c00000000, 0xf2e326cb00000000, 0x42ca46f600000000, + 0x5216664400000000, 0xe23f067900000000, 0x3245a63e00000000, + 0x826cc60300000000, 0x53fb968100000000, 0xe3d2f6bc00000000, + 0x33a856fb00000000, 0x838136c600000000, 0x935d167400000000, + 0x2374764900000000, 0xf30ed60e00000000, 0x4327b63300000000, + 0x102706d100000000, 0xa00e66ec00000000, 0x7074c6ab00000000, + 0xc05da69600000000, 0xd081862400000000, 0x60a8e61900000000, + 0xb0d2465e00000000, 0x00fb266300000000, 0xd16c76e100000000, + 0x614516dc00000000, 0xb13fb69b00000000, 0x0116d6a600000000, + 0x11caf61400000000, 0xa1e3962900000000, 0x7199366e00000000, + 0xc1b0565300000000, 0x969f277000000000, 0x26b6474d00000000, + 0xf6cce70a00000000, 0x46e5873700000000, 0x5639a78500000000, + 0xe610c7b800000000, 0x366a67ff00000000, 0x864307c200000000, + 0x57d4574000000000, 0xe7fd377d00000000, 0x3787973a00000000, + 0x87aef70700000000, 0x9772d7b500000000, 0x275bb78800000000, + 0xf72117cf00000000, 0x470877f200000000, 0x1408c71000000000, + 0xa421a72d00000000, 0x745b076a00000000, 0xc472675700000000, + 0xd4ae47e500000000, 0x648727d800000000, 0xb4fd879f00000000, + 0x04d4e7a200000000, 0xd543b72000000000, 0x656ad71d00000000, + 0xb510775a00000000, 0x0539176700000000, 0x15e537d500000000, + 0xa5cc57e800000000, 0x75b6f7af00000000, 0xc59f979200000000, + 0xdbe815e900000000, 0x6bc175d400000000, 0xbbbbd59300000000, + 0x0b92b5ae00000000, 0x1b4e951c00000000, 0xab67f52100000000, + 0x7b1d556600000000, 0xcb34355b00000000, 0x1aa365d900000000, + 0xaa8a05e400000000, 0x7af0a5a300000000, 0xcad9c59e00000000, + 0xda05e52c00000000, 0x6a2c851100000000, 0xba56255600000000, + 0x0a7f456b00000000, 0x597ff58900000000, 0xe95695b400000000, + 0x392c35f300000000, 0x890555ce00000000, 0x99d9757c00000000, + 0x29f0154100000000, 0xf98ab50600000000, 0x49a3d53b00000000, + 0x983485b900000000, 0x281de58400000000, 0xf86745c300000000, + 0x484e25fe00000000, 0x5892054c00000000, 0xe8bb657100000000, + 0x38c1c53600000000, 0x88e8a50b00000000, 0xdfc7d42800000000, + 0x6feeb41500000000, 0xbf94145200000000, 0x0fbd746f00000000, + 0x1f6154dd00000000, 0xaf4834e000000000, 0x7f3294a700000000, + 0xcf1bf49a00000000, 0x1e8ca41800000000, 0xaea5c42500000000, + 0x7edf646200000000, 0xcef6045f00000000, 0xde2a24ed00000000, + 0x6e0344d000000000, 0xbe79e49700000000, 0x0e5084aa00000000, + 0x5d50344800000000, 0xed79547500000000, 0x3d03f43200000000, + 0x8d2a940f00000000, 0x9df6b4bd00000000, 0x2ddfd48000000000, + 0xfda574c700000000, 0x4d8c14fa00000000, 0x9c1b447800000000, + 0x2c32244500000000, 0xfc48840200000000, 0x4c61e43f00000000, + 0x5cbdc48d00000000, 0xec94a4b000000000, 0x3cee04f700000000, + 0x8cc764ca00000000}, + {0x0000000000000000, 0xa5d35ccb00000000, 0x0ba1c84d00000000, + 0xae72948600000000, 0x1642919b00000000, 0xb391cd5000000000, + 0x1de359d600000000, 0xb830051d00000000, 0x6d8253ec00000000, + 0xc8510f2700000000, 0x66239ba100000000, 0xc3f0c76a00000000, + 0x7bc0c27700000000, 0xde139ebc00000000, 0x70610a3a00000000, + 0xd5b256f100000000, 0x9b02d60300000000, 0x3ed18ac800000000, + 0x90a31e4e00000000, 0x3570428500000000, 0x8d40479800000000, + 0x28931b5300000000, 0x86e18fd500000000, 0x2332d31e00000000, + 0xf68085ef00000000, 0x5353d92400000000, 0xfd214da200000000, + 0x58f2116900000000, 0xe0c2147400000000, 0x451148bf00000000, + 0xeb63dc3900000000, 0x4eb080f200000000, 0x3605ac0700000000, + 0x93d6f0cc00000000, 0x3da4644a00000000, 0x9877388100000000, + 0x20473d9c00000000, 0x8594615700000000, 0x2be6f5d100000000, + 0x8e35a91a00000000, 0x5b87ffeb00000000, 0xfe54a32000000000, + 0x502637a600000000, 0xf5f56b6d00000000, 0x4dc56e7000000000, + 0xe81632bb00000000, 0x4664a63d00000000, 0xe3b7faf600000000, + 0xad077a0400000000, 0x08d426cf00000000, 0xa6a6b24900000000, + 0x0375ee8200000000, 0xbb45eb9f00000000, 0x1e96b75400000000, + 0xb0e423d200000000, 0x15377f1900000000, 0xc08529e800000000, + 0x6556752300000000, 0xcb24e1a500000000, 0x6ef7bd6e00000000, + 0xd6c7b87300000000, 0x7314e4b800000000, 0xdd66703e00000000, + 0x78b52cf500000000, 0x6c0a580f00000000, 0xc9d904c400000000, + 0x67ab904200000000, 0xc278cc8900000000, 0x7a48c99400000000, + 0xdf9b955f00000000, 0x71e901d900000000, 0xd43a5d1200000000, + 0x01880be300000000, 0xa45b572800000000, 0x0a29c3ae00000000, + 0xaffa9f6500000000, 0x17ca9a7800000000, 0xb219c6b300000000, + 0x1c6b523500000000, 0xb9b80efe00000000, 0xf7088e0c00000000, + 0x52dbd2c700000000, 0xfca9464100000000, 0x597a1a8a00000000, + 0xe14a1f9700000000, 0x4499435c00000000, 0xeaebd7da00000000, + 0x4f388b1100000000, 0x9a8adde000000000, 0x3f59812b00000000, + 0x912b15ad00000000, 0x34f8496600000000, 0x8cc84c7b00000000, + 0x291b10b000000000, 0x8769843600000000, 0x22bad8fd00000000, + 0x5a0ff40800000000, 0xffdca8c300000000, 0x51ae3c4500000000, + 0xf47d608e00000000, 0x4c4d659300000000, 0xe99e395800000000, + 0x47ecadde00000000, 0xe23ff11500000000, 0x378da7e400000000, + 0x925efb2f00000000, 0x3c2c6fa900000000, 0x99ff336200000000, + 0x21cf367f00000000, 0x841c6ab400000000, 0x2a6efe3200000000, + 0x8fbda2f900000000, 0xc10d220b00000000, 0x64de7ec000000000, + 0xcaacea4600000000, 0x6f7fb68d00000000, 0xd74fb39000000000, + 0x729cef5b00000000, 0xdcee7bdd00000000, 0x793d271600000000, + 0xac8f71e700000000, 0x095c2d2c00000000, 0xa72eb9aa00000000, + 0x02fde56100000000, 0xbacde07c00000000, 0x1f1ebcb700000000, + 0xb16c283100000000, 0x14bf74fa00000000, 0xd814b01e00000000, + 0x7dc7ecd500000000, 0xd3b5785300000000, 0x7666249800000000, + 0xce56218500000000, 0x6b857d4e00000000, 0xc5f7e9c800000000, + 0x6024b50300000000, 0xb596e3f200000000, 0x1045bf3900000000, + 0xbe372bbf00000000, 0x1be4777400000000, 0xa3d4726900000000, + 0x06072ea200000000, 0xa875ba2400000000, 0x0da6e6ef00000000, + 0x4316661d00000000, 0xe6c53ad600000000, 0x48b7ae5000000000, + 0xed64f29b00000000, 0x5554f78600000000, 0xf087ab4d00000000, + 0x5ef53fcb00000000, 0xfb26630000000000, 0x2e9435f100000000, + 0x8b47693a00000000, 0x2535fdbc00000000, 0x80e6a17700000000, + 0x38d6a46a00000000, 0x9d05f8a100000000, 0x33776c2700000000, + 0x96a430ec00000000, 0xee111c1900000000, 0x4bc240d200000000, + 0xe5b0d45400000000, 0x4063889f00000000, 0xf8538d8200000000, + 0x5d80d14900000000, 0xf3f245cf00000000, 0x5621190400000000, + 0x83934ff500000000, 0x2640133e00000000, 0x883287b800000000, + 0x2de1db7300000000, 0x95d1de6e00000000, 0x300282a500000000, + 0x9e70162300000000, 0x3ba34ae800000000, 0x7513ca1a00000000, + 0xd0c096d100000000, 0x7eb2025700000000, 0xdb615e9c00000000, + 0x63515b8100000000, 0xc682074a00000000, 0x68f093cc00000000, + 0xcd23cf0700000000, 0x189199f600000000, 0xbd42c53d00000000, + 0x133051bb00000000, 0xb6e30d7000000000, 0x0ed3086d00000000, + 0xab0054a600000000, 0x0572c02000000000, 0xa0a19ceb00000000, + 0xb41ee81100000000, 0x11cdb4da00000000, 0xbfbf205c00000000, + 0x1a6c7c9700000000, 0xa25c798a00000000, 0x078f254100000000, + 0xa9fdb1c700000000, 0x0c2eed0c00000000, 0xd99cbbfd00000000, + 0x7c4fe73600000000, 0xd23d73b000000000, 0x77ee2f7b00000000, + 0xcfde2a6600000000, 0x6a0d76ad00000000, 0xc47fe22b00000000, + 0x61acbee000000000, 0x2f1c3e1200000000, 0x8acf62d900000000, + 0x24bdf65f00000000, 0x816eaa9400000000, 0x395eaf8900000000, + 0x9c8df34200000000, 0x32ff67c400000000, 0x972c3b0f00000000, + 0x429e6dfe00000000, 0xe74d313500000000, 0x493fa5b300000000, + 0xececf97800000000, 0x54dcfc6500000000, 0xf10fa0ae00000000, + 0x5f7d342800000000, 0xfaae68e300000000, 0x821b441600000000, + 0x27c818dd00000000, 0x89ba8c5b00000000, 0x2c69d09000000000, + 0x9459d58d00000000, 0x318a894600000000, 0x9ff81dc000000000, + 0x3a2b410b00000000, 0xef9917fa00000000, 0x4a4a4b3100000000, + 0xe438dfb700000000, 0x41eb837c00000000, 0xf9db866100000000, + 0x5c08daaa00000000, 0xf27a4e2c00000000, 0x57a912e700000000, + 0x1919921500000000, 0xbccacede00000000, 0x12b85a5800000000, + 0xb76b069300000000, 0x0f5b038e00000000, 0xaa885f4500000000, + 0x04facbc300000000, 0xa129970800000000, 0x749bc1f900000000, + 0xd1489d3200000000, 0x7f3a09b400000000, 0xdae9557f00000000, + 0x62d9506200000000, 0xc70a0ca900000000, 0x6978982f00000000, + 0xccabc4e400000000}, + {0x0000000000000000, 0xb40b77a600000000, 0x29119f9700000000, + 0x9d1ae83100000000, 0x13244ff400000000, 0xa72f385200000000, + 0x3a35d06300000000, 0x8e3ea7c500000000, 0x674eef3300000000, + 0xd345989500000000, 0x4e5f70a400000000, 0xfa54070200000000, + 0x746aa0c700000000, 0xc061d76100000000, 0x5d7b3f5000000000, + 0xe97048f600000000, 0xce9cde6700000000, 0x7a97a9c100000000, + 0xe78d41f000000000, 0x5386365600000000, 0xddb8919300000000, + 0x69b3e63500000000, 0xf4a90e0400000000, 0x40a279a200000000, + 0xa9d2315400000000, 0x1dd946f200000000, 0x80c3aec300000000, + 0x34c8d96500000000, 0xbaf67ea000000000, 0x0efd090600000000, + 0x93e7e13700000000, 0x27ec969100000000, 0x9c39bdcf00000000, + 0x2832ca6900000000, 0xb528225800000000, 0x012355fe00000000, + 0x8f1df23b00000000, 0x3b16859d00000000, 0xa60c6dac00000000, + 0x12071a0a00000000, 0xfb7752fc00000000, 0x4f7c255a00000000, + 0xd266cd6b00000000, 0x666dbacd00000000, 0xe8531d0800000000, + 0x5c586aae00000000, 0xc142829f00000000, 0x7549f53900000000, + 0x52a563a800000000, 0xe6ae140e00000000, 0x7bb4fc3f00000000, + 0xcfbf8b9900000000, 0x41812c5c00000000, 0xf58a5bfa00000000, + 0x6890b3cb00000000, 0xdc9bc46d00000000, 0x35eb8c9b00000000, + 0x81e0fb3d00000000, 0x1cfa130c00000000, 0xa8f164aa00000000, + 0x26cfc36f00000000, 0x92c4b4c900000000, 0x0fde5cf800000000, + 0xbbd52b5e00000000, 0x79750b4400000000, 0xcd7e7ce200000000, + 0x506494d300000000, 0xe46fe37500000000, 0x6a5144b000000000, + 0xde5a331600000000, 0x4340db2700000000, 0xf74bac8100000000, + 0x1e3be47700000000, 0xaa3093d100000000, 0x372a7be000000000, + 0x83210c4600000000, 0x0d1fab8300000000, 0xb914dc2500000000, + 0x240e341400000000, 0x900543b200000000, 0xb7e9d52300000000, + 0x03e2a28500000000, 0x9ef84ab400000000, 0x2af33d1200000000, + 0xa4cd9ad700000000, 0x10c6ed7100000000, 0x8ddc054000000000, + 0x39d772e600000000, 0xd0a73a1000000000, 0x64ac4db600000000, + 0xf9b6a58700000000, 0x4dbdd22100000000, 0xc38375e400000000, + 0x7788024200000000, 0xea92ea7300000000, 0x5e999dd500000000, + 0xe54cb68b00000000, 0x5147c12d00000000, 0xcc5d291c00000000, + 0x78565eba00000000, 0xf668f97f00000000, 0x42638ed900000000, + 0xdf7966e800000000, 0x6b72114e00000000, 0x820259b800000000, + 0x36092e1e00000000, 0xab13c62f00000000, 0x1f18b18900000000, + 0x9126164c00000000, 0x252d61ea00000000, 0xb83789db00000000, + 0x0c3cfe7d00000000, 0x2bd068ec00000000, 0x9fdb1f4a00000000, + 0x02c1f77b00000000, 0xb6ca80dd00000000, 0x38f4271800000000, + 0x8cff50be00000000, 0x11e5b88f00000000, 0xa5eecf2900000000, + 0x4c9e87df00000000, 0xf895f07900000000, 0x658f184800000000, + 0xd1846fee00000000, 0x5fbac82b00000000, 0xebb1bf8d00000000, + 0x76ab57bc00000000, 0xc2a0201a00000000, 0xf2ea168800000000, + 0x46e1612e00000000, 0xdbfb891f00000000, 0x6ff0feb900000000, + 0xe1ce597c00000000, 0x55c52eda00000000, 0xc8dfc6eb00000000, + 0x7cd4b14d00000000, 0x95a4f9bb00000000, 0x21af8e1d00000000, + 0xbcb5662c00000000, 0x08be118a00000000, 0x8680b64f00000000, + 0x328bc1e900000000, 0xaf9129d800000000, 0x1b9a5e7e00000000, + 0x3c76c8ef00000000, 0x887dbf4900000000, 0x1567577800000000, + 0xa16c20de00000000, 0x2f52871b00000000, 0x9b59f0bd00000000, + 0x0643188c00000000, 0xb2486f2a00000000, 0x5b3827dc00000000, + 0xef33507a00000000, 0x7229b84b00000000, 0xc622cfed00000000, + 0x481c682800000000, 0xfc171f8e00000000, 0x610df7bf00000000, + 0xd506801900000000, 0x6ed3ab4700000000, 0xdad8dce100000000, + 0x47c234d000000000, 0xf3c9437600000000, 0x7df7e4b300000000, + 0xc9fc931500000000, 0x54e67b2400000000, 0xe0ed0c8200000000, + 0x099d447400000000, 0xbd9633d200000000, 0x208cdbe300000000, + 0x9487ac4500000000, 0x1ab90b8000000000, 0xaeb27c2600000000, + 0x33a8941700000000, 0x87a3e3b100000000, 0xa04f752000000000, + 0x1444028600000000, 0x895eeab700000000, 0x3d559d1100000000, + 0xb36b3ad400000000, 0x07604d7200000000, 0x9a7aa54300000000, + 0x2e71d2e500000000, 0xc7019a1300000000, 0x730aedb500000000, + 0xee10058400000000, 0x5a1b722200000000, 0xd425d5e700000000, + 0x602ea24100000000, 0xfd344a7000000000, 0x493f3dd600000000, + 0x8b9f1dcc00000000, 0x3f946a6a00000000, 0xa28e825b00000000, + 0x1685f5fd00000000, 0x98bb523800000000, 0x2cb0259e00000000, + 0xb1aacdaf00000000, 0x05a1ba0900000000, 0xecd1f2ff00000000, + 0x58da855900000000, 0xc5c06d6800000000, 0x71cb1ace00000000, + 0xfff5bd0b00000000, 0x4bfecaad00000000, 0xd6e4229c00000000, + 0x62ef553a00000000, 0x4503c3ab00000000, 0xf108b40d00000000, + 0x6c125c3c00000000, 0xd8192b9a00000000, 0x56278c5f00000000, + 0xe22cfbf900000000, 0x7f3613c800000000, 0xcb3d646e00000000, + 0x224d2c9800000000, 0x96465b3e00000000, 0x0b5cb30f00000000, + 0xbf57c4a900000000, 0x3169636c00000000, 0x856214ca00000000, + 0x1878fcfb00000000, 0xac738b5d00000000, 0x17a6a00300000000, + 0xa3add7a500000000, 0x3eb73f9400000000, 0x8abc483200000000, + 0x0482eff700000000, 0xb089985100000000, 0x2d93706000000000, + 0x999807c600000000, 0x70e84f3000000000, 0xc4e3389600000000, + 0x59f9d0a700000000, 0xedf2a70100000000, 0x63cc00c400000000, + 0xd7c7776200000000, 0x4add9f5300000000, 0xfed6e8f500000000, + 0xd93a7e6400000000, 0x6d3109c200000000, 0xf02be1f300000000, + 0x4420965500000000, 0xca1e319000000000, 0x7e15463600000000, + 0xe30fae0700000000, 0x5704d9a100000000, 0xbe74915700000000, + 0x0a7fe6f100000000, 0x97650ec000000000, 0x236e796600000000, + 0xad50dea300000000, 0x195ba90500000000, 0x8441413400000000, + 0x304a369200000000}, + {0x0000000000000000, 0x9e00aacc00000000, 0x7d07254200000000, + 0xe3078f8e00000000, 0xfa0e4a8400000000, 0x640ee04800000000, + 0x87096fc600000000, 0x1909c50a00000000, 0xb51be5d300000000, + 0x2b1b4f1f00000000, 0xc81cc09100000000, 0x561c6a5d00000000, + 0x4f15af5700000000, 0xd115059b00000000, 0x32128a1500000000, + 0xac1220d900000000, 0x2b31bb7c00000000, 0xb53111b000000000, + 0x56369e3e00000000, 0xc83634f200000000, 0xd13ff1f800000000, + 0x4f3f5b3400000000, 0xac38d4ba00000000, 0x32387e7600000000, + 0x9e2a5eaf00000000, 0x002af46300000000, 0xe32d7bed00000000, + 0x7d2dd12100000000, 0x6424142b00000000, 0xfa24bee700000000, + 0x1923316900000000, 0x87239ba500000000, 0x566276f900000000, + 0xc862dc3500000000, 0x2b6553bb00000000, 0xb565f97700000000, + 0xac6c3c7d00000000, 0x326c96b100000000, 0xd16b193f00000000, + 0x4f6bb3f300000000, 0xe379932a00000000, 0x7d7939e600000000, + 0x9e7eb66800000000, 0x007e1ca400000000, 0x1977d9ae00000000, + 0x8777736200000000, 0x6470fcec00000000, 0xfa70562000000000, + 0x7d53cd8500000000, 0xe353674900000000, 0x0054e8c700000000, + 0x9e54420b00000000, 0x875d870100000000, 0x195d2dcd00000000, + 0xfa5aa24300000000, 0x645a088f00000000, 0xc848285600000000, + 0x5648829a00000000, 0xb54f0d1400000000, 0x2b4fa7d800000000, + 0x324662d200000000, 0xac46c81e00000000, 0x4f41479000000000, + 0xd141ed5c00000000, 0xedc29d2900000000, 0x73c237e500000000, + 0x90c5b86b00000000, 0x0ec512a700000000, 0x17ccd7ad00000000, + 0x89cc7d6100000000, 0x6acbf2ef00000000, 0xf4cb582300000000, + 0x58d978fa00000000, 0xc6d9d23600000000, 0x25de5db800000000, + 0xbbdef77400000000, 0xa2d7327e00000000, 0x3cd798b200000000, + 0xdfd0173c00000000, 0x41d0bdf000000000, 0xc6f3265500000000, + 0x58f38c9900000000, 0xbbf4031700000000, 0x25f4a9db00000000, + 0x3cfd6cd100000000, 0xa2fdc61d00000000, 0x41fa499300000000, + 0xdffae35f00000000, 0x73e8c38600000000, 0xede8694a00000000, + 0x0eefe6c400000000, 0x90ef4c0800000000, 0x89e6890200000000, + 0x17e623ce00000000, 0xf4e1ac4000000000, 0x6ae1068c00000000, + 0xbba0ebd000000000, 0x25a0411c00000000, 0xc6a7ce9200000000, + 0x58a7645e00000000, 0x41aea15400000000, 0xdfae0b9800000000, + 0x3ca9841600000000, 0xa2a92eda00000000, 0x0ebb0e0300000000, + 0x90bba4cf00000000, 0x73bc2b4100000000, 0xedbc818d00000000, + 0xf4b5448700000000, 0x6ab5ee4b00000000, 0x89b261c500000000, + 0x17b2cb0900000000, 0x909150ac00000000, 0x0e91fa6000000000, + 0xed9675ee00000000, 0x7396df2200000000, 0x6a9f1a2800000000, + 0xf49fb0e400000000, 0x17983f6a00000000, 0x899895a600000000, + 0x258ab57f00000000, 0xbb8a1fb300000000, 0x588d903d00000000, + 0xc68d3af100000000, 0xdf84fffb00000000, 0x4184553700000000, + 0xa283dab900000000, 0x3c83707500000000, 0xda853b5300000000, + 0x4485919f00000000, 0xa7821e1100000000, 0x3982b4dd00000000, + 0x208b71d700000000, 0xbe8bdb1b00000000, 0x5d8c549500000000, + 0xc38cfe5900000000, 0x6f9ede8000000000, 0xf19e744c00000000, + 0x1299fbc200000000, 0x8c99510e00000000, 0x9590940400000000, + 0x0b903ec800000000, 0xe897b14600000000, 0x76971b8a00000000, + 0xf1b4802f00000000, 0x6fb42ae300000000, 0x8cb3a56d00000000, + 0x12b30fa100000000, 0x0bbacaab00000000, 0x95ba606700000000, + 0x76bdefe900000000, 0xe8bd452500000000, 0x44af65fc00000000, + 0xdaafcf3000000000, 0x39a840be00000000, 0xa7a8ea7200000000, + 0xbea12f7800000000, 0x20a185b400000000, 0xc3a60a3a00000000, + 0x5da6a0f600000000, 0x8ce74daa00000000, 0x12e7e76600000000, + 0xf1e068e800000000, 0x6fe0c22400000000, 0x76e9072e00000000, + 0xe8e9ade200000000, 0x0bee226c00000000, 0x95ee88a000000000, + 0x39fca87900000000, 0xa7fc02b500000000, 0x44fb8d3b00000000, + 0xdafb27f700000000, 0xc3f2e2fd00000000, 0x5df2483100000000, + 0xbef5c7bf00000000, 0x20f56d7300000000, 0xa7d6f6d600000000, + 0x39d65c1a00000000, 0xdad1d39400000000, 0x44d1795800000000, + 0x5dd8bc5200000000, 0xc3d8169e00000000, 0x20df991000000000, + 0xbedf33dc00000000, 0x12cd130500000000, 0x8ccdb9c900000000, + 0x6fca364700000000, 0xf1ca9c8b00000000, 0xe8c3598100000000, + 0x76c3f34d00000000, 0x95c47cc300000000, 0x0bc4d60f00000000, + 0x3747a67a00000000, 0xa9470cb600000000, 0x4a40833800000000, + 0xd44029f400000000, 0xcd49ecfe00000000, 0x5349463200000000, + 0xb04ec9bc00000000, 0x2e4e637000000000, 0x825c43a900000000, + 0x1c5ce96500000000, 0xff5b66eb00000000, 0x615bcc2700000000, + 0x7852092d00000000, 0xe652a3e100000000, 0x05552c6f00000000, + 0x9b5586a300000000, 0x1c761d0600000000, 0x8276b7ca00000000, + 0x6171384400000000, 0xff71928800000000, 0xe678578200000000, + 0x7878fd4e00000000, 0x9b7f72c000000000, 0x057fd80c00000000, + 0xa96df8d500000000, 0x376d521900000000, 0xd46add9700000000, + 0x4a6a775b00000000, 0x5363b25100000000, 0xcd63189d00000000, + 0x2e64971300000000, 0xb0643ddf00000000, 0x6125d08300000000, + 0xff257a4f00000000, 0x1c22f5c100000000, 0x82225f0d00000000, + 0x9b2b9a0700000000, 0x052b30cb00000000, 0xe62cbf4500000000, + 0x782c158900000000, 0xd43e355000000000, 0x4a3e9f9c00000000, + 0xa939101200000000, 0x3739bade00000000, 0x2e307fd400000000, + 0xb030d51800000000, 0x53375a9600000000, 0xcd37f05a00000000, + 0x4a146bff00000000, 0xd414c13300000000, 0x37134ebd00000000, + 0xa913e47100000000, 0xb01a217b00000000, 0x2e1a8bb700000000, + 0xcd1d043900000000, 0x531daef500000000, 0xff0f8e2c00000000, + 0x610f24e000000000, 0x8208ab6e00000000, 0x1c0801a200000000, + 0x0501c4a800000000, 0x9b016e6400000000, 0x7806e1ea00000000, + 0xe6064b2600000000}}; + +#else /* W == 4 */ + +local const z_crc_t FAR crc_braid_table[][256] = { + {0x00000000, 0xb8bc6765, 0xaa09c88b, 0x12b5afee, 0x8f629757, + 0x37def032, 0x256b5fdc, 0x9dd738b9, 0xc5b428ef, 0x7d084f8a, + 0x6fbde064, 0xd7018701, 0x4ad6bfb8, 0xf26ad8dd, 0xe0df7733, + 0x58631056, 0x5019579f, 0xe8a530fa, 0xfa109f14, 0x42acf871, + 0xdf7bc0c8, 0x67c7a7ad, 0x75720843, 0xcdce6f26, 0x95ad7f70, + 0x2d111815, 0x3fa4b7fb, 0x8718d09e, 0x1acfe827, 0xa2738f42, + 0xb0c620ac, 0x087a47c9, 0xa032af3e, 0x188ec85b, 0x0a3b67b5, + 0xb28700d0, 0x2f503869, 0x97ec5f0c, 0x8559f0e2, 0x3de59787, + 0x658687d1, 0xdd3ae0b4, 0xcf8f4f5a, 0x7733283f, 0xeae41086, + 0x525877e3, 0x40edd80d, 0xf851bf68, 0xf02bf8a1, 0x48979fc4, + 0x5a22302a, 0xe29e574f, 0x7f496ff6, 0xc7f50893, 0xd540a77d, + 0x6dfcc018, 0x359fd04e, 0x8d23b72b, 0x9f9618c5, 0x272a7fa0, + 0xbafd4719, 0x0241207c, 0x10f48f92, 0xa848e8f7, 0x9b14583d, + 0x23a83f58, 0x311d90b6, 0x89a1f7d3, 0x1476cf6a, 0xaccaa80f, + 0xbe7f07e1, 0x06c36084, 0x5ea070d2, 0xe61c17b7, 0xf4a9b859, + 0x4c15df3c, 0xd1c2e785, 0x697e80e0, 0x7bcb2f0e, 0xc377486b, + 0xcb0d0fa2, 0x73b168c7, 0x6104c729, 0xd9b8a04c, 0x446f98f5, + 0xfcd3ff90, 0xee66507e, 0x56da371b, 0x0eb9274d, 0xb6054028, + 0xa4b0efc6, 0x1c0c88a3, 0x81dbb01a, 0x3967d77f, 0x2bd27891, + 0x936e1ff4, 0x3b26f703, 0x839a9066, 0x912f3f88, 0x299358ed, + 0xb4446054, 0x0cf80731, 0x1e4da8df, 0xa6f1cfba, 0xfe92dfec, + 0x462eb889, 0x549b1767, 0xec277002, 0x71f048bb, 0xc94c2fde, + 0xdbf98030, 0x6345e755, 0x6b3fa09c, 0xd383c7f9, 0xc1366817, + 0x798a0f72, 0xe45d37cb, 0x5ce150ae, 0x4e54ff40, 0xf6e89825, + 0xae8b8873, 0x1637ef16, 0x048240f8, 0xbc3e279d, 0x21e91f24, + 0x99557841, 0x8be0d7af, 0x335cb0ca, 0xed59b63b, 0x55e5d15e, + 0x47507eb0, 0xffec19d5, 0x623b216c, 0xda874609, 0xc832e9e7, + 0x708e8e82, 0x28ed9ed4, 0x9051f9b1, 0x82e4565f, 0x3a58313a, + 0xa78f0983, 0x1f336ee6, 0x0d86c108, 0xb53aa66d, 0xbd40e1a4, + 0x05fc86c1, 0x1749292f, 0xaff54e4a, 0x322276f3, 0x8a9e1196, + 0x982bbe78, 0x2097d91d, 0x78f4c94b, 0xc048ae2e, 0xd2fd01c0, + 0x6a4166a5, 0xf7965e1c, 0x4f2a3979, 0x5d9f9697, 0xe523f1f2, + 0x4d6b1905, 0xf5d77e60, 0xe762d18e, 0x5fdeb6eb, 0xc2098e52, + 0x7ab5e937, 0x680046d9, 0xd0bc21bc, 0x88df31ea, 0x3063568f, + 0x22d6f961, 0x9a6a9e04, 0x07bda6bd, 0xbf01c1d8, 0xadb46e36, + 0x15080953, 0x1d724e9a, 0xa5ce29ff, 0xb77b8611, 0x0fc7e174, + 0x9210d9cd, 0x2aacbea8, 0x38191146, 0x80a57623, 0xd8c66675, + 0x607a0110, 0x72cfaefe, 0xca73c99b, 0x57a4f122, 0xef189647, + 0xfdad39a9, 0x45115ecc, 0x764dee06, 0xcef18963, 0xdc44268d, + 0x64f841e8, 0xf92f7951, 0x41931e34, 0x5326b1da, 0xeb9ad6bf, + 0xb3f9c6e9, 0x0b45a18c, 0x19f00e62, 0xa14c6907, 0x3c9b51be, + 0x842736db, 0x96929935, 0x2e2efe50, 0x2654b999, 0x9ee8defc, + 0x8c5d7112, 0x34e11677, 0xa9362ece, 0x118a49ab, 0x033fe645, + 0xbb838120, 0xe3e09176, 0x5b5cf613, 0x49e959fd, 0xf1553e98, + 0x6c820621, 0xd43e6144, 0xc68bceaa, 0x7e37a9cf, 0xd67f4138, + 0x6ec3265d, 0x7c7689b3, 0xc4caeed6, 0x591dd66f, 0xe1a1b10a, + 0xf3141ee4, 0x4ba87981, 0x13cb69d7, 0xab770eb2, 0xb9c2a15c, + 0x017ec639, 0x9ca9fe80, 0x241599e5, 0x36a0360b, 0x8e1c516e, + 0x866616a7, 0x3eda71c2, 0x2c6fde2c, 0x94d3b949, 0x090481f0, + 0xb1b8e695, 0xa30d497b, 0x1bb12e1e, 0x43d23e48, 0xfb6e592d, + 0xe9dbf6c3, 0x516791a6, 0xccb0a91f, 0x740cce7a, 0x66b96194, + 0xde0506f1}, + {0x00000000, 0x01c26a37, 0x0384d46e, 0x0246be59, 0x0709a8dc, + 0x06cbc2eb, 0x048d7cb2, 0x054f1685, 0x0e1351b8, 0x0fd13b8f, + 0x0d9785d6, 0x0c55efe1, 0x091af964, 0x08d89353, 0x0a9e2d0a, + 0x0b5c473d, 0x1c26a370, 0x1de4c947, 0x1fa2771e, 0x1e601d29, + 0x1b2f0bac, 0x1aed619b, 0x18abdfc2, 0x1969b5f5, 0x1235f2c8, + 0x13f798ff, 0x11b126a6, 0x10734c91, 0x153c5a14, 0x14fe3023, + 0x16b88e7a, 0x177ae44d, 0x384d46e0, 0x398f2cd7, 0x3bc9928e, + 0x3a0bf8b9, 0x3f44ee3c, 0x3e86840b, 0x3cc03a52, 0x3d025065, + 0x365e1758, 0x379c7d6f, 0x35dac336, 0x3418a901, 0x3157bf84, + 0x3095d5b3, 0x32d36bea, 0x331101dd, 0x246be590, 0x25a98fa7, + 0x27ef31fe, 0x262d5bc9, 0x23624d4c, 0x22a0277b, 0x20e69922, + 0x2124f315, 0x2a78b428, 0x2bbade1f, 0x29fc6046, 0x283e0a71, + 0x2d711cf4, 0x2cb376c3, 0x2ef5c89a, 0x2f37a2ad, 0x709a8dc0, + 0x7158e7f7, 0x731e59ae, 0x72dc3399, 0x7793251c, 0x76514f2b, + 0x7417f172, 0x75d59b45, 0x7e89dc78, 0x7f4bb64f, 0x7d0d0816, + 0x7ccf6221, 0x798074a4, 0x78421e93, 0x7a04a0ca, 0x7bc6cafd, + 0x6cbc2eb0, 0x6d7e4487, 0x6f38fade, 0x6efa90e9, 0x6bb5866c, + 0x6a77ec5b, 0x68315202, 0x69f33835, 0x62af7f08, 0x636d153f, + 0x612bab66, 0x60e9c151, 0x65a6d7d4, 0x6464bde3, 0x662203ba, + 0x67e0698d, 0x48d7cb20, 0x4915a117, 0x4b531f4e, 0x4a917579, + 0x4fde63fc, 0x4e1c09cb, 0x4c5ab792, 0x4d98dda5, 0x46c49a98, + 0x4706f0af, 0x45404ef6, 0x448224c1, 0x41cd3244, 0x400f5873, + 0x4249e62a, 0x438b8c1d, 0x54f16850, 0x55330267, 0x5775bc3e, + 0x56b7d609, 0x53f8c08c, 0x523aaabb, 0x507c14e2, 0x51be7ed5, + 0x5ae239e8, 0x5b2053df, 0x5966ed86, 0x58a487b1, 0x5deb9134, + 0x5c29fb03, 0x5e6f455a, 0x5fad2f6d, 0xe1351b80, 0xe0f771b7, + 0xe2b1cfee, 0xe373a5d9, 0xe63cb35c, 0xe7fed96b, 0xe5b86732, + 0xe47a0d05, 0xef264a38, 0xeee4200f, 0xeca29e56, 0xed60f461, + 0xe82fe2e4, 0xe9ed88d3, 0xebab368a, 0xea695cbd, 0xfd13b8f0, + 0xfcd1d2c7, 0xfe976c9e, 0xff5506a9, 0xfa1a102c, 0xfbd87a1b, + 0xf99ec442, 0xf85cae75, 0xf300e948, 0xf2c2837f, 0xf0843d26, + 0xf1465711, 0xf4094194, 0xf5cb2ba3, 0xf78d95fa, 0xf64fffcd, + 0xd9785d60, 0xd8ba3757, 0xdafc890e, 0xdb3ee339, 0xde71f5bc, + 0xdfb39f8b, 0xddf521d2, 0xdc374be5, 0xd76b0cd8, 0xd6a966ef, + 0xd4efd8b6, 0xd52db281, 0xd062a404, 0xd1a0ce33, 0xd3e6706a, + 0xd2241a5d, 0xc55efe10, 0xc49c9427, 0xc6da2a7e, 0xc7184049, + 0xc25756cc, 0xc3953cfb, 0xc1d382a2, 0xc011e895, 0xcb4dafa8, + 0xca8fc59f, 0xc8c97bc6, 0xc90b11f1, 0xcc440774, 0xcd866d43, + 0xcfc0d31a, 0xce02b92d, 0x91af9640, 0x906dfc77, 0x922b422e, + 0x93e92819, 0x96a63e9c, 0x976454ab, 0x9522eaf2, 0x94e080c5, + 0x9fbcc7f8, 0x9e7eadcf, 0x9c381396, 0x9dfa79a1, 0x98b56f24, + 0x99770513, 0x9b31bb4a, 0x9af3d17d, 0x8d893530, 0x8c4b5f07, + 0x8e0de15e, 0x8fcf8b69, 0x8a809dec, 0x8b42f7db, 0x89044982, + 0x88c623b5, 0x839a6488, 0x82580ebf, 0x801eb0e6, 0x81dcdad1, + 0x8493cc54, 0x8551a663, 0x8717183a, 0x86d5720d, 0xa9e2d0a0, + 0xa820ba97, 0xaa6604ce, 0xaba46ef9, 0xaeeb787c, 0xaf29124b, + 0xad6fac12, 0xacadc625, 0xa7f18118, 0xa633eb2f, 0xa4755576, + 0xa5b73f41, 0xa0f829c4, 0xa13a43f3, 0xa37cfdaa, 0xa2be979d, + 0xb5c473d0, 0xb40619e7, 0xb640a7be, 0xb782cd89, 0xb2cddb0c, + 0xb30fb13b, 0xb1490f62, 0xb08b6555, 0xbbd72268, 0xba15485f, + 0xb853f606, 0xb9919c31, 0xbcde8ab4, 0xbd1ce083, 0xbf5a5eda, + 0xbe9834ed}, + {0x00000000, 0x191b3141, 0x32366282, 0x2b2d53c3, 0x646cc504, + 0x7d77f445, 0x565aa786, 0x4f4196c7, 0xc8d98a08, 0xd1c2bb49, + 0xfaefe88a, 0xe3f4d9cb, 0xacb54f0c, 0xb5ae7e4d, 0x9e832d8e, + 0x87981ccf, 0x4ac21251, 0x53d92310, 0x78f470d3, 0x61ef4192, + 0x2eaed755, 0x37b5e614, 0x1c98b5d7, 0x05838496, 0x821b9859, + 0x9b00a918, 0xb02dfadb, 0xa936cb9a, 0xe6775d5d, 0xff6c6c1c, + 0xd4413fdf, 0xcd5a0e9e, 0x958424a2, 0x8c9f15e3, 0xa7b24620, + 0xbea97761, 0xf1e8e1a6, 0xe8f3d0e7, 0xc3de8324, 0xdac5b265, + 0x5d5daeaa, 0x44469feb, 0x6f6bcc28, 0x7670fd69, 0x39316bae, + 0x202a5aef, 0x0b07092c, 0x121c386d, 0xdf4636f3, 0xc65d07b2, + 0xed705471, 0xf46b6530, 0xbb2af3f7, 0xa231c2b6, 0x891c9175, + 0x9007a034, 0x179fbcfb, 0x0e848dba, 0x25a9de79, 0x3cb2ef38, + 0x73f379ff, 0x6ae848be, 0x41c51b7d, 0x58de2a3c, 0xf0794f05, + 0xe9627e44, 0xc24f2d87, 0xdb541cc6, 0x94158a01, 0x8d0ebb40, + 0xa623e883, 0xbf38d9c2, 0x38a0c50d, 0x21bbf44c, 0x0a96a78f, + 0x138d96ce, 0x5ccc0009, 0x45d73148, 0x6efa628b, 0x77e153ca, + 0xbabb5d54, 0xa3a06c15, 0x888d3fd6, 0x91960e97, 0xded79850, + 0xc7cca911, 0xece1fad2, 0xf5facb93, 0x7262d75c, 0x6b79e61d, + 0x4054b5de, 0x594f849f, 0x160e1258, 0x0f152319, 0x243870da, + 0x3d23419b, 0x65fd6ba7, 0x7ce65ae6, 0x57cb0925, 0x4ed03864, + 0x0191aea3, 0x188a9fe2, 0x33a7cc21, 0x2abcfd60, 0xad24e1af, + 0xb43fd0ee, 0x9f12832d, 0x8609b26c, 0xc94824ab, 0xd05315ea, + 0xfb7e4629, 0xe2657768, 0x2f3f79f6, 0x362448b7, 0x1d091b74, + 0x04122a35, 0x4b53bcf2, 0x52488db3, 0x7965de70, 0x607eef31, + 0xe7e6f3fe, 0xfefdc2bf, 0xd5d0917c, 0xcccba03d, 0x838a36fa, + 0x9a9107bb, 0xb1bc5478, 0xa8a76539, 0x3b83984b, 0x2298a90a, + 0x09b5fac9, 0x10aecb88, 0x5fef5d4f, 0x46f46c0e, 0x6dd93fcd, + 0x74c20e8c, 0xf35a1243, 0xea412302, 0xc16c70c1, 0xd8774180, + 0x9736d747, 0x8e2de606, 0xa500b5c5, 0xbc1b8484, 0x71418a1a, + 0x685abb5b, 0x4377e898, 0x5a6cd9d9, 0x152d4f1e, 0x0c367e5f, + 0x271b2d9c, 0x3e001cdd, 0xb9980012, 0xa0833153, 0x8bae6290, + 0x92b553d1, 0xddf4c516, 0xc4eff457, 0xefc2a794, 0xf6d996d5, + 0xae07bce9, 0xb71c8da8, 0x9c31de6b, 0x852aef2a, 0xca6b79ed, + 0xd37048ac, 0xf85d1b6f, 0xe1462a2e, 0x66de36e1, 0x7fc507a0, + 0x54e85463, 0x4df36522, 0x02b2f3e5, 0x1ba9c2a4, 0x30849167, + 0x299fa026, 0xe4c5aeb8, 0xfdde9ff9, 0xd6f3cc3a, 0xcfe8fd7b, + 0x80a96bbc, 0x99b25afd, 0xb29f093e, 0xab84387f, 0x2c1c24b0, + 0x350715f1, 0x1e2a4632, 0x07317773, 0x4870e1b4, 0x516bd0f5, + 0x7a468336, 0x635db277, 0xcbfad74e, 0xd2e1e60f, 0xf9ccb5cc, + 0xe0d7848d, 0xaf96124a, 0xb68d230b, 0x9da070c8, 0x84bb4189, + 0x03235d46, 0x1a386c07, 0x31153fc4, 0x280e0e85, 0x674f9842, + 0x7e54a903, 0x5579fac0, 0x4c62cb81, 0x8138c51f, 0x9823f45e, + 0xb30ea79d, 0xaa1596dc, 0xe554001b, 0xfc4f315a, 0xd7626299, + 0xce7953d8, 0x49e14f17, 0x50fa7e56, 0x7bd72d95, 0x62cc1cd4, + 0x2d8d8a13, 0x3496bb52, 0x1fbbe891, 0x06a0d9d0, 0x5e7ef3ec, + 0x4765c2ad, 0x6c48916e, 0x7553a02f, 0x3a1236e8, 0x230907a9, + 0x0824546a, 0x113f652b, 0x96a779e4, 0x8fbc48a5, 0xa4911b66, + 0xbd8a2a27, 0xf2cbbce0, 0xebd08da1, 0xc0fdde62, 0xd9e6ef23, + 0x14bce1bd, 0x0da7d0fc, 0x268a833f, 0x3f91b27e, 0x70d024b9, + 0x69cb15f8, 0x42e6463b, 0x5bfd777a, 0xdc656bb5, 0xc57e5af4, + 0xee530937, 0xf7483876, 0xb809aeb1, 0xa1129ff0, 0x8a3fcc33, + 0x9324fd72}, + {0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, + 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, + 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, + 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, + 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, + 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, + 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, + 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, + 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, + 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, + 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, + 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, + 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, + 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, + 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, + 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, + 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, + 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, + 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, + 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, + 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, + 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, + 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, + 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, + 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, + 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, + 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, + 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, + 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, + 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, + 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, + 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, + 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, + 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, + 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, + 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, + 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, + 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, + 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, + 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, + 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, + 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, + 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, + 0x2d02ef8d}}; + +local const z_word_t FAR crc_braid_big_table[][256] = { + {0x00000000, 0x96300777, 0x2c610eee, 0xba510999, 0x19c46d07, + 0x8ff46a70, 0x35a563e9, 0xa395649e, 0x3288db0e, 0xa4b8dc79, + 0x1ee9d5e0, 0x88d9d297, 0x2b4cb609, 0xbd7cb17e, 0x072db8e7, + 0x911dbf90, 0x6410b71d, 0xf220b06a, 0x4871b9f3, 0xde41be84, + 0x7dd4da1a, 0xebe4dd6d, 0x51b5d4f4, 0xc785d383, 0x56986c13, + 0xc0a86b64, 0x7af962fd, 0xecc9658a, 0x4f5c0114, 0xd96c0663, + 0x633d0ffa, 0xf50d088d, 0xc8206e3b, 0x5e10694c, 0xe44160d5, + 0x727167a2, 0xd1e4033c, 0x47d4044b, 0xfd850dd2, 0x6bb50aa5, + 0xfaa8b535, 0x6c98b242, 0xd6c9bbdb, 0x40f9bcac, 0xe36cd832, + 0x755cdf45, 0xcf0dd6dc, 0x593dd1ab, 0xac30d926, 0x3a00de51, + 0x8051d7c8, 0x1661d0bf, 0xb5f4b421, 0x23c4b356, 0x9995bacf, + 0x0fa5bdb8, 0x9eb80228, 0x0888055f, 0xb2d90cc6, 0x24e90bb1, + 0x877c6f2f, 0x114c6858, 0xab1d61c1, 0x3d2d66b6, 0x9041dc76, + 0x0671db01, 0xbc20d298, 0x2a10d5ef, 0x8985b171, 0x1fb5b606, + 0xa5e4bf9f, 0x33d4b8e8, 0xa2c90778, 0x34f9000f, 0x8ea80996, + 0x18980ee1, 0xbb0d6a7f, 0x2d3d6d08, 0x976c6491, 0x015c63e6, + 0xf4516b6b, 0x62616c1c, 0xd8306585, 0x4e0062f2, 0xed95066c, + 0x7ba5011b, 0xc1f40882, 0x57c40ff5, 0xc6d9b065, 0x50e9b712, + 0xeab8be8b, 0x7c88b9fc, 0xdf1ddd62, 0x492dda15, 0xf37cd38c, + 0x654cd4fb, 0x5861b24d, 0xce51b53a, 0x7400bca3, 0xe230bbd4, + 0x41a5df4a, 0xd795d83d, 0x6dc4d1a4, 0xfbf4d6d3, 0x6ae96943, + 0xfcd96e34, 0x468867ad, 0xd0b860da, 0x732d0444, 0xe51d0333, + 0x5f4c0aaa, 0xc97c0ddd, 0x3c710550, 0xaa410227, 0x10100bbe, + 0x86200cc9, 0x25b56857, 0xb3856f20, 0x09d466b9, 0x9fe461ce, + 0x0ef9de5e, 0x98c9d929, 0x2298d0b0, 0xb4a8d7c7, 0x173db359, + 0x810db42e, 0x3b5cbdb7, 0xad6cbac0, 0x2083b8ed, 0xb6b3bf9a, + 0x0ce2b603, 0x9ad2b174, 0x3947d5ea, 0xaf77d29d, 0x1526db04, + 0x8316dc73, 0x120b63e3, 0x843b6494, 0x3e6a6d0d, 0xa85a6a7a, + 0x0bcf0ee4, 0x9dff0993, 0x27ae000a, 0xb19e077d, 0x44930ff0, + 0xd2a30887, 0x68f2011e, 0xfec20669, 0x5d5762f7, 0xcb676580, + 0x71366c19, 0xe7066b6e, 0x761bd4fe, 0xe02bd389, 0x5a7ada10, + 0xcc4add67, 0x6fdfb9f9, 0xf9efbe8e, 0x43beb717, 0xd58eb060, + 0xe8a3d6d6, 0x7e93d1a1, 0xc4c2d838, 0x52f2df4f, 0xf167bbd1, + 0x6757bca6, 0xdd06b53f, 0x4b36b248, 0xda2b0dd8, 0x4c1b0aaf, + 0xf64a0336, 0x607a0441, 0xc3ef60df, 0x55df67a8, 0xef8e6e31, + 0x79be6946, 0x8cb361cb, 0x1a8366bc, 0xa0d26f25, 0x36e26852, + 0x95770ccc, 0x03470bbb, 0xb9160222, 0x2f260555, 0xbe3bbac5, + 0x280bbdb2, 0x925ab42b, 0x046ab35c, 0xa7ffd7c2, 0x31cfd0b5, + 0x8b9ed92c, 0x1daede5b, 0xb0c2649b, 0x26f263ec, 0x9ca36a75, + 0x0a936d02, 0xa906099c, 0x3f360eeb, 0x85670772, 0x13570005, + 0x824abf95, 0x147ab8e2, 0xae2bb17b, 0x381bb60c, 0x9b8ed292, + 0x0dbed5e5, 0xb7efdc7c, 0x21dfdb0b, 0xd4d2d386, 0x42e2d4f1, + 0xf8b3dd68, 0x6e83da1f, 0xcd16be81, 0x5b26b9f6, 0xe177b06f, + 0x7747b718, 0xe65a0888, 0x706a0fff, 0xca3b0666, 0x5c0b0111, + 0xff9e658f, 0x69ae62f8, 0xd3ff6b61, 0x45cf6c16, 0x78e20aa0, + 0xeed20dd7, 0x5483044e, 0xc2b30339, 0x612667a7, 0xf71660d0, + 0x4d476949, 0xdb776e3e, 0x4a6ad1ae, 0xdc5ad6d9, 0x660bdf40, + 0xf03bd837, 0x53aebca9, 0xc59ebbde, 0x7fcfb247, 0xe9ffb530, + 0x1cf2bdbd, 0x8ac2baca, 0x3093b353, 0xa6a3b424, 0x0536d0ba, + 0x9306d7cd, 0x2957de54, 0xbf67d923, 0x2e7a66b3, 0xb84a61c4, + 0x021b685d, 0x942b6f2a, 0x37be0bb4, 0xa18e0cc3, 0x1bdf055a, + 0x8def022d}, + {0x00000000, 0x41311b19, 0x82623632, 0xc3532d2b, 0x04c56c64, + 0x45f4777d, 0x86a75a56, 0xc796414f, 0x088ad9c8, 0x49bbc2d1, + 0x8ae8effa, 0xcbd9f4e3, 0x0c4fb5ac, 0x4d7eaeb5, 0x8e2d839e, + 0xcf1c9887, 0x5112c24a, 0x1023d953, 0xd370f478, 0x9241ef61, + 0x55d7ae2e, 0x14e6b537, 0xd7b5981c, 0x96848305, 0x59981b82, + 0x18a9009b, 0xdbfa2db0, 0x9acb36a9, 0x5d5d77e6, 0x1c6c6cff, + 0xdf3f41d4, 0x9e0e5acd, 0xa2248495, 0xe3159f8c, 0x2046b2a7, + 0x6177a9be, 0xa6e1e8f1, 0xe7d0f3e8, 0x2483dec3, 0x65b2c5da, + 0xaaae5d5d, 0xeb9f4644, 0x28cc6b6f, 0x69fd7076, 0xae6b3139, + 0xef5a2a20, 0x2c09070b, 0x6d381c12, 0xf33646df, 0xb2075dc6, + 0x715470ed, 0x30656bf4, 0xf7f32abb, 0xb6c231a2, 0x75911c89, + 0x34a00790, 0xfbbc9f17, 0xba8d840e, 0x79dea925, 0x38efb23c, + 0xff79f373, 0xbe48e86a, 0x7d1bc541, 0x3c2ade58, 0x054f79f0, + 0x447e62e9, 0x872d4fc2, 0xc61c54db, 0x018a1594, 0x40bb0e8d, + 0x83e823a6, 0xc2d938bf, 0x0dc5a038, 0x4cf4bb21, 0x8fa7960a, + 0xce968d13, 0x0900cc5c, 0x4831d745, 0x8b62fa6e, 0xca53e177, + 0x545dbbba, 0x156ca0a3, 0xd63f8d88, 0x970e9691, 0x5098d7de, + 0x11a9ccc7, 0xd2fae1ec, 0x93cbfaf5, 0x5cd76272, 0x1de6796b, + 0xdeb55440, 0x9f844f59, 0x58120e16, 0x1923150f, 0xda703824, + 0x9b41233d, 0xa76bfd65, 0xe65ae67c, 0x2509cb57, 0x6438d04e, + 0xa3ae9101, 0xe29f8a18, 0x21cca733, 0x60fdbc2a, 0xafe124ad, + 0xeed03fb4, 0x2d83129f, 0x6cb20986, 0xab2448c9, 0xea1553d0, + 0x29467efb, 0x687765e2, 0xf6793f2f, 0xb7482436, 0x741b091d, + 0x352a1204, 0xf2bc534b, 0xb38d4852, 0x70de6579, 0x31ef7e60, + 0xfef3e6e7, 0xbfc2fdfe, 0x7c91d0d5, 0x3da0cbcc, 0xfa368a83, + 0xbb07919a, 0x7854bcb1, 0x3965a7a8, 0x4b98833b, 0x0aa99822, + 0xc9fab509, 0x88cbae10, 0x4f5def5f, 0x0e6cf446, 0xcd3fd96d, + 0x8c0ec274, 0x43125af3, 0x022341ea, 0xc1706cc1, 0x804177d8, + 0x47d73697, 0x06e62d8e, 0xc5b500a5, 0x84841bbc, 0x1a8a4171, + 0x5bbb5a68, 0x98e87743, 0xd9d96c5a, 0x1e4f2d15, 0x5f7e360c, + 0x9c2d1b27, 0xdd1c003e, 0x120098b9, 0x533183a0, 0x9062ae8b, + 0xd153b592, 0x16c5f4dd, 0x57f4efc4, 0x94a7c2ef, 0xd596d9f6, + 0xe9bc07ae, 0xa88d1cb7, 0x6bde319c, 0x2aef2a85, 0xed796bca, + 0xac4870d3, 0x6f1b5df8, 0x2e2a46e1, 0xe136de66, 0xa007c57f, + 0x6354e854, 0x2265f34d, 0xe5f3b202, 0xa4c2a91b, 0x67918430, + 0x26a09f29, 0xb8aec5e4, 0xf99fdefd, 0x3accf3d6, 0x7bfde8cf, + 0xbc6ba980, 0xfd5ab299, 0x3e099fb2, 0x7f3884ab, 0xb0241c2c, + 0xf1150735, 0x32462a1e, 0x73773107, 0xb4e17048, 0xf5d06b51, + 0x3683467a, 0x77b25d63, 0x4ed7facb, 0x0fe6e1d2, 0xccb5ccf9, + 0x8d84d7e0, 0x4a1296af, 0x0b238db6, 0xc870a09d, 0x8941bb84, + 0x465d2303, 0x076c381a, 0xc43f1531, 0x850e0e28, 0x42984f67, + 0x03a9547e, 0xc0fa7955, 0x81cb624c, 0x1fc53881, 0x5ef42398, + 0x9da70eb3, 0xdc9615aa, 0x1b0054e5, 0x5a314ffc, 0x996262d7, + 0xd85379ce, 0x174fe149, 0x567efa50, 0x952dd77b, 0xd41ccc62, + 0x138a8d2d, 0x52bb9634, 0x91e8bb1f, 0xd0d9a006, 0xecf37e5e, + 0xadc26547, 0x6e91486c, 0x2fa05375, 0xe836123a, 0xa9070923, + 0x6a542408, 0x2b653f11, 0xe479a796, 0xa548bc8f, 0x661b91a4, + 0x272a8abd, 0xe0bccbf2, 0xa18dd0eb, 0x62defdc0, 0x23efe6d9, + 0xbde1bc14, 0xfcd0a70d, 0x3f838a26, 0x7eb2913f, 0xb924d070, + 0xf815cb69, 0x3b46e642, 0x7a77fd5b, 0xb56b65dc, 0xf45a7ec5, + 0x370953ee, 0x763848f7, 0xb1ae09b8, 0xf09f12a1, 0x33cc3f8a, + 0x72fd2493}, + {0x00000000, 0x376ac201, 0x6ed48403, 0x59be4602, 0xdca80907, + 0xebc2cb06, 0xb27c8d04, 0x85164f05, 0xb851130e, 0x8f3bd10f, + 0xd685970d, 0xe1ef550c, 0x64f91a09, 0x5393d808, 0x0a2d9e0a, + 0x3d475c0b, 0x70a3261c, 0x47c9e41d, 0x1e77a21f, 0x291d601e, + 0xac0b2f1b, 0x9b61ed1a, 0xc2dfab18, 0xf5b56919, 0xc8f23512, + 0xff98f713, 0xa626b111, 0x914c7310, 0x145a3c15, 0x2330fe14, + 0x7a8eb816, 0x4de47a17, 0xe0464d38, 0xd72c8f39, 0x8e92c93b, + 0xb9f80b3a, 0x3cee443f, 0x0b84863e, 0x523ac03c, 0x6550023d, + 0x58175e36, 0x6f7d9c37, 0x36c3da35, 0x01a91834, 0x84bf5731, + 0xb3d59530, 0xea6bd332, 0xdd011133, 0x90e56b24, 0xa78fa925, + 0xfe31ef27, 0xc95b2d26, 0x4c4d6223, 0x7b27a022, 0x2299e620, + 0x15f32421, 0x28b4782a, 0x1fdeba2b, 0x4660fc29, 0x710a3e28, + 0xf41c712d, 0xc376b32c, 0x9ac8f52e, 0xada2372f, 0xc08d9a70, + 0xf7e75871, 0xae591e73, 0x9933dc72, 0x1c259377, 0x2b4f5176, + 0x72f11774, 0x459bd575, 0x78dc897e, 0x4fb64b7f, 0x16080d7d, + 0x2162cf7c, 0xa4748079, 0x931e4278, 0xcaa0047a, 0xfdcac67b, + 0xb02ebc6c, 0x87447e6d, 0xdefa386f, 0xe990fa6e, 0x6c86b56b, + 0x5bec776a, 0x02523168, 0x3538f369, 0x087faf62, 0x3f156d63, + 0x66ab2b61, 0x51c1e960, 0xd4d7a665, 0xe3bd6464, 0xba032266, + 0x8d69e067, 0x20cbd748, 0x17a11549, 0x4e1f534b, 0x7975914a, + 0xfc63de4f, 0xcb091c4e, 0x92b75a4c, 0xa5dd984d, 0x989ac446, + 0xaff00647, 0xf64e4045, 0xc1248244, 0x4432cd41, 0x73580f40, + 0x2ae64942, 0x1d8c8b43, 0x5068f154, 0x67023355, 0x3ebc7557, + 0x09d6b756, 0x8cc0f853, 0xbbaa3a52, 0xe2147c50, 0xd57ebe51, + 0xe839e25a, 0xdf53205b, 0x86ed6659, 0xb187a458, 0x3491eb5d, + 0x03fb295c, 0x5a456f5e, 0x6d2fad5f, 0x801b35e1, 0xb771f7e0, + 0xeecfb1e2, 0xd9a573e3, 0x5cb33ce6, 0x6bd9fee7, 0x3267b8e5, + 0x050d7ae4, 0x384a26ef, 0x0f20e4ee, 0x569ea2ec, 0x61f460ed, + 0xe4e22fe8, 0xd388ede9, 0x8a36abeb, 0xbd5c69ea, 0xf0b813fd, + 0xc7d2d1fc, 0x9e6c97fe, 0xa90655ff, 0x2c101afa, 0x1b7ad8fb, + 0x42c49ef9, 0x75ae5cf8, 0x48e900f3, 0x7f83c2f2, 0x263d84f0, + 0x115746f1, 0x944109f4, 0xa32bcbf5, 0xfa958df7, 0xcdff4ff6, + 0x605d78d9, 0x5737bad8, 0x0e89fcda, 0x39e33edb, 0xbcf571de, + 0x8b9fb3df, 0xd221f5dd, 0xe54b37dc, 0xd80c6bd7, 0xef66a9d6, + 0xb6d8efd4, 0x81b22dd5, 0x04a462d0, 0x33cea0d1, 0x6a70e6d3, + 0x5d1a24d2, 0x10fe5ec5, 0x27949cc4, 0x7e2adac6, 0x494018c7, + 0xcc5657c2, 0xfb3c95c3, 0xa282d3c1, 0x95e811c0, 0xa8af4dcb, + 0x9fc58fca, 0xc67bc9c8, 0xf1110bc9, 0x740744cc, 0x436d86cd, + 0x1ad3c0cf, 0x2db902ce, 0x4096af91, 0x77fc6d90, 0x2e422b92, + 0x1928e993, 0x9c3ea696, 0xab546497, 0xf2ea2295, 0xc580e094, + 0xf8c7bc9f, 0xcfad7e9e, 0x9613389c, 0xa179fa9d, 0x246fb598, + 0x13057799, 0x4abb319b, 0x7dd1f39a, 0x3035898d, 0x075f4b8c, + 0x5ee10d8e, 0x698bcf8f, 0xec9d808a, 0xdbf7428b, 0x82490489, + 0xb523c688, 0x88649a83, 0xbf0e5882, 0xe6b01e80, 0xd1dadc81, + 0x54cc9384, 0x63a65185, 0x3a181787, 0x0d72d586, 0xa0d0e2a9, + 0x97ba20a8, 0xce0466aa, 0xf96ea4ab, 0x7c78ebae, 0x4b1229af, + 0x12ac6fad, 0x25c6adac, 0x1881f1a7, 0x2feb33a6, 0x765575a4, + 0x413fb7a5, 0xc429f8a0, 0xf3433aa1, 0xaafd7ca3, 0x9d97bea2, + 0xd073c4b5, 0xe71906b4, 0xbea740b6, 0x89cd82b7, 0x0cdbcdb2, + 0x3bb10fb3, 0x620f49b1, 0x55658bb0, 0x6822d7bb, 0x5f4815ba, + 0x06f653b8, 0x319c91b9, 0xb48adebc, 0x83e01cbd, 0xda5e5abf, + 0xed3498be}, + {0x00000000, 0x6567bcb8, 0x8bc809aa, 0xeeafb512, 0x5797628f, + 0x32f0de37, 0xdc5f6b25, 0xb938d79d, 0xef28b4c5, 0x8a4f087d, + 0x64e0bd6f, 0x018701d7, 0xb8bfd64a, 0xddd86af2, 0x3377dfe0, + 0x56106358, 0x9f571950, 0xfa30a5e8, 0x149f10fa, 0x71f8ac42, + 0xc8c07bdf, 0xada7c767, 0x43087275, 0x266fcecd, 0x707fad95, + 0x1518112d, 0xfbb7a43f, 0x9ed01887, 0x27e8cf1a, 0x428f73a2, + 0xac20c6b0, 0xc9477a08, 0x3eaf32a0, 0x5bc88e18, 0xb5673b0a, + 0xd00087b2, 0x6938502f, 0x0c5fec97, 0xe2f05985, 0x8797e53d, + 0xd1878665, 0xb4e03add, 0x5a4f8fcf, 0x3f283377, 0x8610e4ea, + 0xe3775852, 0x0dd8ed40, 0x68bf51f8, 0xa1f82bf0, 0xc49f9748, + 0x2a30225a, 0x4f579ee2, 0xf66f497f, 0x9308f5c7, 0x7da740d5, + 0x18c0fc6d, 0x4ed09f35, 0x2bb7238d, 0xc518969f, 0xa07f2a27, + 0x1947fdba, 0x7c204102, 0x928ff410, 0xf7e848a8, 0x3d58149b, + 0x583fa823, 0xb6901d31, 0xd3f7a189, 0x6acf7614, 0x0fa8caac, + 0xe1077fbe, 0x8460c306, 0xd270a05e, 0xb7171ce6, 0x59b8a9f4, + 0x3cdf154c, 0x85e7c2d1, 0xe0807e69, 0x0e2fcb7b, 0x6b4877c3, + 0xa20f0dcb, 0xc768b173, 0x29c70461, 0x4ca0b8d9, 0xf5986f44, + 0x90ffd3fc, 0x7e5066ee, 0x1b37da56, 0x4d27b90e, 0x284005b6, + 0xc6efb0a4, 0xa3880c1c, 0x1ab0db81, 0x7fd76739, 0x9178d22b, + 0xf41f6e93, 0x03f7263b, 0x66909a83, 0x883f2f91, 0xed589329, + 0x546044b4, 0x3107f80c, 0xdfa84d1e, 0xbacff1a6, 0xecdf92fe, + 0x89b82e46, 0x67179b54, 0x027027ec, 0xbb48f071, 0xde2f4cc9, + 0x3080f9db, 0x55e74563, 0x9ca03f6b, 0xf9c783d3, 0x176836c1, + 0x720f8a79, 0xcb375de4, 0xae50e15c, 0x40ff544e, 0x2598e8f6, + 0x73888bae, 0x16ef3716, 0xf8408204, 0x9d273ebc, 0x241fe921, + 0x41785599, 0xafd7e08b, 0xcab05c33, 0x3bb659ed, 0x5ed1e555, + 0xb07e5047, 0xd519ecff, 0x6c213b62, 0x094687da, 0xe7e932c8, + 0x828e8e70, 0xd49eed28, 0xb1f95190, 0x5f56e482, 0x3a31583a, + 0x83098fa7, 0xe66e331f, 0x08c1860d, 0x6da63ab5, 0xa4e140bd, + 0xc186fc05, 0x2f294917, 0x4a4ef5af, 0xf3762232, 0x96119e8a, + 0x78be2b98, 0x1dd99720, 0x4bc9f478, 0x2eae48c0, 0xc001fdd2, + 0xa566416a, 0x1c5e96f7, 0x79392a4f, 0x97969f5d, 0xf2f123e5, + 0x05196b4d, 0x607ed7f5, 0x8ed162e7, 0xebb6de5f, 0x528e09c2, + 0x37e9b57a, 0xd9460068, 0xbc21bcd0, 0xea31df88, 0x8f566330, + 0x61f9d622, 0x049e6a9a, 0xbda6bd07, 0xd8c101bf, 0x366eb4ad, + 0x53090815, 0x9a4e721d, 0xff29cea5, 0x11867bb7, 0x74e1c70f, + 0xcdd91092, 0xa8beac2a, 0x46111938, 0x2376a580, 0x7566c6d8, + 0x10017a60, 0xfeaecf72, 0x9bc973ca, 0x22f1a457, 0x479618ef, + 0xa939adfd, 0xcc5e1145, 0x06ee4d76, 0x6389f1ce, 0x8d2644dc, + 0xe841f864, 0x51792ff9, 0x341e9341, 0xdab12653, 0xbfd69aeb, + 0xe9c6f9b3, 0x8ca1450b, 0x620ef019, 0x07694ca1, 0xbe519b3c, + 0xdb362784, 0x35999296, 0x50fe2e2e, 0x99b95426, 0xfcdee89e, + 0x12715d8c, 0x7716e134, 0xce2e36a9, 0xab498a11, 0x45e63f03, + 0x208183bb, 0x7691e0e3, 0x13f65c5b, 0xfd59e949, 0x983e55f1, + 0x2106826c, 0x44613ed4, 0xaace8bc6, 0xcfa9377e, 0x38417fd6, + 0x5d26c36e, 0xb389767c, 0xd6eecac4, 0x6fd61d59, 0x0ab1a1e1, + 0xe41e14f3, 0x8179a84b, 0xd769cb13, 0xb20e77ab, 0x5ca1c2b9, + 0x39c67e01, 0x80fea99c, 0xe5991524, 0x0b36a036, 0x6e511c8e, + 0xa7166686, 0xc271da3e, 0x2cde6f2c, 0x49b9d394, 0xf0810409, + 0x95e6b8b1, 0x7b490da3, 0x1e2eb11b, 0x483ed243, 0x2d596efb, + 0xc3f6dbe9, 0xa6916751, 0x1fa9b0cc, 0x7ace0c74, 0x9461b966, + 0xf10605de}}; + +#endif + +#endif + +#if N == 2 + +#if W == 8 + +local const z_crc_t FAR crc_braid_table[][256] = { + {0x00000000, 0xae689191, 0x87a02563, 0x29c8b4f2, 0xd4314c87, + 0x7a59dd16, 0x539169e4, 0xfdf9f875, 0x73139f4f, 0xdd7b0ede, + 0xf4b3ba2c, 0x5adb2bbd, 0xa722d3c8, 0x094a4259, 0x2082f6ab, + 0x8eea673a, 0xe6273e9e, 0x484faf0f, 0x61871bfd, 0xcfef8a6c, + 0x32167219, 0x9c7ee388, 0xb5b6577a, 0x1bdec6eb, 0x9534a1d1, + 0x3b5c3040, 0x129484b2, 0xbcfc1523, 0x4105ed56, 0xef6d7cc7, + 0xc6a5c835, 0x68cd59a4, 0x173f7b7d, 0xb957eaec, 0x909f5e1e, + 0x3ef7cf8f, 0xc30e37fa, 0x6d66a66b, 0x44ae1299, 0xeac68308, + 0x642ce432, 0xca4475a3, 0xe38cc151, 0x4de450c0, 0xb01da8b5, + 0x1e753924, 0x37bd8dd6, 0x99d51c47, 0xf11845e3, 0x5f70d472, + 0x76b86080, 0xd8d0f111, 0x25290964, 0x8b4198f5, 0xa2892c07, + 0x0ce1bd96, 0x820bdaac, 0x2c634b3d, 0x05abffcf, 0xabc36e5e, + 0x563a962b, 0xf85207ba, 0xd19ab348, 0x7ff222d9, 0x2e7ef6fa, + 0x8016676b, 0xa9ded399, 0x07b64208, 0xfa4fba7d, 0x54272bec, + 0x7def9f1e, 0xd3870e8f, 0x5d6d69b5, 0xf305f824, 0xdacd4cd6, + 0x74a5dd47, 0x895c2532, 0x2734b4a3, 0x0efc0051, 0xa09491c0, + 0xc859c864, 0x663159f5, 0x4ff9ed07, 0xe1917c96, 0x1c6884e3, + 0xb2001572, 0x9bc8a180, 0x35a03011, 0xbb4a572b, 0x1522c6ba, + 0x3cea7248, 0x9282e3d9, 0x6f7b1bac, 0xc1138a3d, 0xe8db3ecf, + 0x46b3af5e, 0x39418d87, 0x97291c16, 0xbee1a8e4, 0x10893975, + 0xed70c100, 0x43185091, 0x6ad0e463, 0xc4b875f2, 0x4a5212c8, + 0xe43a8359, 0xcdf237ab, 0x639aa63a, 0x9e635e4f, 0x300bcfde, + 0x19c37b2c, 0xb7abeabd, 0xdf66b319, 0x710e2288, 0x58c6967a, + 0xf6ae07eb, 0x0b57ff9e, 0xa53f6e0f, 0x8cf7dafd, 0x229f4b6c, + 0xac752c56, 0x021dbdc7, 0x2bd50935, 0x85bd98a4, 0x784460d1, + 0xd62cf140, 0xffe445b2, 0x518cd423, 0x5cfdedf4, 0xf2957c65, + 0xdb5dc897, 0x75355906, 0x88cca173, 0x26a430e2, 0x0f6c8410, + 0xa1041581, 0x2fee72bb, 0x8186e32a, 0xa84e57d8, 0x0626c649, + 0xfbdf3e3c, 0x55b7afad, 0x7c7f1b5f, 0xd2178ace, 0xbadad36a, + 0x14b242fb, 0x3d7af609, 0x93126798, 0x6eeb9fed, 0xc0830e7c, + 0xe94bba8e, 0x47232b1f, 0xc9c94c25, 0x67a1ddb4, 0x4e696946, + 0xe001f8d7, 0x1df800a2, 0xb3909133, 0x9a5825c1, 0x3430b450, + 0x4bc29689, 0xe5aa0718, 0xcc62b3ea, 0x620a227b, 0x9ff3da0e, + 0x319b4b9f, 0x1853ff6d, 0xb63b6efc, 0x38d109c6, 0x96b99857, + 0xbf712ca5, 0x1119bd34, 0xece04541, 0x4288d4d0, 0x6b406022, + 0xc528f1b3, 0xade5a817, 0x038d3986, 0x2a458d74, 0x842d1ce5, + 0x79d4e490, 0xd7bc7501, 0xfe74c1f3, 0x501c5062, 0xdef63758, + 0x709ea6c9, 0x5956123b, 0xf73e83aa, 0x0ac77bdf, 0xa4afea4e, + 0x8d675ebc, 0x230fcf2d, 0x72831b0e, 0xdceb8a9f, 0xf5233e6d, + 0x5b4baffc, 0xa6b25789, 0x08dac618, 0x211272ea, 0x8f7ae37b, + 0x01908441, 0xaff815d0, 0x8630a122, 0x285830b3, 0xd5a1c8c6, + 0x7bc95957, 0x5201eda5, 0xfc697c34, 0x94a42590, 0x3accb401, + 0x130400f3, 0xbd6c9162, 0x40956917, 0xeefdf886, 0xc7354c74, + 0x695ddde5, 0xe7b7badf, 0x49df2b4e, 0x60179fbc, 0xce7f0e2d, + 0x3386f658, 0x9dee67c9, 0xb426d33b, 0x1a4e42aa, 0x65bc6073, + 0xcbd4f1e2, 0xe21c4510, 0x4c74d481, 0xb18d2cf4, 0x1fe5bd65, + 0x362d0997, 0x98459806, 0x16afff3c, 0xb8c76ead, 0x910fda5f, + 0x3f674bce, 0xc29eb3bb, 0x6cf6222a, 0x453e96d8, 0xeb560749, + 0x839b5eed, 0x2df3cf7c, 0x043b7b8e, 0xaa53ea1f, 0x57aa126a, + 0xf9c283fb, 0xd00a3709, 0x7e62a698, 0xf088c1a2, 0x5ee05033, + 0x7728e4c1, 0xd9407550, 0x24b98d25, 0x8ad11cb4, 0xa319a846, + 0x0d7139d7}, + {0x00000000, 0xb9fbdbe8, 0xa886b191, 0x117d6a79, 0x8a7c6563, + 0x3387be8b, 0x22fad4f2, 0x9b010f1a, 0xcf89cc87, 0x7672176f, + 0x670f7d16, 0xdef4a6fe, 0x45f5a9e4, 0xfc0e720c, 0xed731875, + 0x5488c39d, 0x44629f4f, 0xfd9944a7, 0xece42ede, 0x551ff536, + 0xce1efa2c, 0x77e521c4, 0x66984bbd, 0xdf639055, 0x8beb53c8, + 0x32108820, 0x236de259, 0x9a9639b1, 0x019736ab, 0xb86ced43, + 0xa911873a, 0x10ea5cd2, 0x88c53e9e, 0x313ee576, 0x20438f0f, + 0x99b854e7, 0x02b95bfd, 0xbb428015, 0xaa3fea6c, 0x13c43184, + 0x474cf219, 0xfeb729f1, 0xefca4388, 0x56319860, 0xcd30977a, + 0x74cb4c92, 0x65b626eb, 0xdc4dfd03, 0xcca7a1d1, 0x755c7a39, + 0x64211040, 0xdddacba8, 0x46dbc4b2, 0xff201f5a, 0xee5d7523, + 0x57a6aecb, 0x032e6d56, 0xbad5b6be, 0xaba8dcc7, 0x1253072f, + 0x89520835, 0x30a9d3dd, 0x21d4b9a4, 0x982f624c, 0xcafb7b7d, + 0x7300a095, 0x627dcaec, 0xdb861104, 0x40871e1e, 0xf97cc5f6, + 0xe801af8f, 0x51fa7467, 0x0572b7fa, 0xbc896c12, 0xadf4066b, + 0x140fdd83, 0x8f0ed299, 0x36f50971, 0x27886308, 0x9e73b8e0, + 0x8e99e432, 0x37623fda, 0x261f55a3, 0x9fe48e4b, 0x04e58151, + 0xbd1e5ab9, 0xac6330c0, 0x1598eb28, 0x411028b5, 0xf8ebf35d, + 0xe9969924, 0x506d42cc, 0xcb6c4dd6, 0x7297963e, 0x63eafc47, + 0xda1127af, 0x423e45e3, 0xfbc59e0b, 0xeab8f472, 0x53432f9a, + 0xc8422080, 0x71b9fb68, 0x60c49111, 0xd93f4af9, 0x8db78964, + 0x344c528c, 0x253138f5, 0x9ccae31d, 0x07cbec07, 0xbe3037ef, + 0xaf4d5d96, 0x16b6867e, 0x065cdaac, 0xbfa70144, 0xaeda6b3d, + 0x1721b0d5, 0x8c20bfcf, 0x35db6427, 0x24a60e5e, 0x9d5dd5b6, + 0xc9d5162b, 0x702ecdc3, 0x6153a7ba, 0xd8a87c52, 0x43a97348, + 0xfa52a8a0, 0xeb2fc2d9, 0x52d41931, 0x4e87f0bb, 0xf77c2b53, + 0xe601412a, 0x5ffa9ac2, 0xc4fb95d8, 0x7d004e30, 0x6c7d2449, + 0xd586ffa1, 0x810e3c3c, 0x38f5e7d4, 0x29888dad, 0x90735645, + 0x0b72595f, 0xb28982b7, 0xa3f4e8ce, 0x1a0f3326, 0x0ae56ff4, + 0xb31eb41c, 0xa263de65, 0x1b98058d, 0x80990a97, 0x3962d17f, + 0x281fbb06, 0x91e460ee, 0xc56ca373, 0x7c97789b, 0x6dea12e2, + 0xd411c90a, 0x4f10c610, 0xf6eb1df8, 0xe7967781, 0x5e6dac69, + 0xc642ce25, 0x7fb915cd, 0x6ec47fb4, 0xd73fa45c, 0x4c3eab46, + 0xf5c570ae, 0xe4b81ad7, 0x5d43c13f, 0x09cb02a2, 0xb030d94a, + 0xa14db333, 0x18b668db, 0x83b767c1, 0x3a4cbc29, 0x2b31d650, + 0x92ca0db8, 0x8220516a, 0x3bdb8a82, 0x2aa6e0fb, 0x935d3b13, + 0x085c3409, 0xb1a7efe1, 0xa0da8598, 0x19215e70, 0x4da99ded, + 0xf4524605, 0xe52f2c7c, 0x5cd4f794, 0xc7d5f88e, 0x7e2e2366, + 0x6f53491f, 0xd6a892f7, 0x847c8bc6, 0x3d87502e, 0x2cfa3a57, + 0x9501e1bf, 0x0e00eea5, 0xb7fb354d, 0xa6865f34, 0x1f7d84dc, + 0x4bf54741, 0xf20e9ca9, 0xe373f6d0, 0x5a882d38, 0xc1892222, + 0x7872f9ca, 0x690f93b3, 0xd0f4485b, 0xc01e1489, 0x79e5cf61, + 0x6898a518, 0xd1637ef0, 0x4a6271ea, 0xf399aa02, 0xe2e4c07b, + 0x5b1f1b93, 0x0f97d80e, 0xb66c03e6, 0xa711699f, 0x1eeab277, + 0x85ebbd6d, 0x3c106685, 0x2d6d0cfc, 0x9496d714, 0x0cb9b558, + 0xb5426eb0, 0xa43f04c9, 0x1dc4df21, 0x86c5d03b, 0x3f3e0bd3, + 0x2e4361aa, 0x97b8ba42, 0xc33079df, 0x7acba237, 0x6bb6c84e, + 0xd24d13a6, 0x494c1cbc, 0xf0b7c754, 0xe1caad2d, 0x583176c5, + 0x48db2a17, 0xf120f1ff, 0xe05d9b86, 0x59a6406e, 0xc2a74f74, + 0x7b5c949c, 0x6a21fee5, 0xd3da250d, 0x8752e690, 0x3ea93d78, + 0x2fd45701, 0x962f8ce9, 0x0d2e83f3, 0xb4d5581b, 0xa5a83262, + 0x1c53e98a}, + {0x00000000, 0x9d0fe176, 0xe16ec4ad, 0x7c6125db, 0x19ac8f1b, + 0x84a36e6d, 0xf8c24bb6, 0x65cdaac0, 0x33591e36, 0xae56ff40, + 0xd237da9b, 0x4f383bed, 0x2af5912d, 0xb7fa705b, 0xcb9b5580, + 0x5694b4f6, 0x66b23c6c, 0xfbbddd1a, 0x87dcf8c1, 0x1ad319b7, + 0x7f1eb377, 0xe2115201, 0x9e7077da, 0x037f96ac, 0x55eb225a, + 0xc8e4c32c, 0xb485e6f7, 0x298a0781, 0x4c47ad41, 0xd1484c37, + 0xad2969ec, 0x3026889a, 0xcd6478d8, 0x506b99ae, 0x2c0abc75, + 0xb1055d03, 0xd4c8f7c3, 0x49c716b5, 0x35a6336e, 0xa8a9d218, + 0xfe3d66ee, 0x63328798, 0x1f53a243, 0x825c4335, 0xe791e9f5, + 0x7a9e0883, 0x06ff2d58, 0x9bf0cc2e, 0xabd644b4, 0x36d9a5c2, + 0x4ab88019, 0xd7b7616f, 0xb27acbaf, 0x2f752ad9, 0x53140f02, + 0xce1bee74, 0x988f5a82, 0x0580bbf4, 0x79e19e2f, 0xe4ee7f59, + 0x8123d599, 0x1c2c34ef, 0x604d1134, 0xfd42f042, 0x41b9f7f1, + 0xdcb61687, 0xa0d7335c, 0x3dd8d22a, 0x581578ea, 0xc51a999c, + 0xb97bbc47, 0x24745d31, 0x72e0e9c7, 0xefef08b1, 0x938e2d6a, + 0x0e81cc1c, 0x6b4c66dc, 0xf64387aa, 0x8a22a271, 0x172d4307, + 0x270bcb9d, 0xba042aeb, 0xc6650f30, 0x5b6aee46, 0x3ea74486, + 0xa3a8a5f0, 0xdfc9802b, 0x42c6615d, 0x1452d5ab, 0x895d34dd, + 0xf53c1106, 0x6833f070, 0x0dfe5ab0, 0x90f1bbc6, 0xec909e1d, + 0x719f7f6b, 0x8cdd8f29, 0x11d26e5f, 0x6db34b84, 0xf0bcaaf2, + 0x95710032, 0x087ee144, 0x741fc49f, 0xe91025e9, 0xbf84911f, + 0x228b7069, 0x5eea55b2, 0xc3e5b4c4, 0xa6281e04, 0x3b27ff72, + 0x4746daa9, 0xda493bdf, 0xea6fb345, 0x77605233, 0x0b0177e8, + 0x960e969e, 0xf3c33c5e, 0x6eccdd28, 0x12adf8f3, 0x8fa21985, + 0xd936ad73, 0x44394c05, 0x385869de, 0xa55788a8, 0xc09a2268, + 0x5d95c31e, 0x21f4e6c5, 0xbcfb07b3, 0x8373efe2, 0x1e7c0e94, + 0x621d2b4f, 0xff12ca39, 0x9adf60f9, 0x07d0818f, 0x7bb1a454, + 0xe6be4522, 0xb02af1d4, 0x2d2510a2, 0x51443579, 0xcc4bd40f, + 0xa9867ecf, 0x34899fb9, 0x48e8ba62, 0xd5e75b14, 0xe5c1d38e, + 0x78ce32f8, 0x04af1723, 0x99a0f655, 0xfc6d5c95, 0x6162bde3, + 0x1d039838, 0x800c794e, 0xd698cdb8, 0x4b972cce, 0x37f60915, + 0xaaf9e863, 0xcf3442a3, 0x523ba3d5, 0x2e5a860e, 0xb3556778, + 0x4e17973a, 0xd318764c, 0xaf795397, 0x3276b2e1, 0x57bb1821, + 0xcab4f957, 0xb6d5dc8c, 0x2bda3dfa, 0x7d4e890c, 0xe041687a, + 0x9c204da1, 0x012facd7, 0x64e20617, 0xf9ede761, 0x858cc2ba, + 0x188323cc, 0x28a5ab56, 0xb5aa4a20, 0xc9cb6ffb, 0x54c48e8d, + 0x3109244d, 0xac06c53b, 0xd067e0e0, 0x4d680196, 0x1bfcb560, + 0x86f35416, 0xfa9271cd, 0x679d90bb, 0x02503a7b, 0x9f5fdb0d, + 0xe33efed6, 0x7e311fa0, 0xc2ca1813, 0x5fc5f965, 0x23a4dcbe, + 0xbeab3dc8, 0xdb669708, 0x4669767e, 0x3a0853a5, 0xa707b2d3, + 0xf1930625, 0x6c9ce753, 0x10fdc288, 0x8df223fe, 0xe83f893e, + 0x75306848, 0x09514d93, 0x945eace5, 0xa478247f, 0x3977c509, + 0x4516e0d2, 0xd81901a4, 0xbdd4ab64, 0x20db4a12, 0x5cba6fc9, + 0xc1b58ebf, 0x97213a49, 0x0a2edb3f, 0x764ffee4, 0xeb401f92, + 0x8e8db552, 0x13825424, 0x6fe371ff, 0xf2ec9089, 0x0fae60cb, + 0x92a181bd, 0xeec0a466, 0x73cf4510, 0x1602efd0, 0x8b0d0ea6, + 0xf76c2b7d, 0x6a63ca0b, 0x3cf77efd, 0xa1f89f8b, 0xdd99ba50, + 0x40965b26, 0x255bf1e6, 0xb8541090, 0xc435354b, 0x593ad43d, + 0x691c5ca7, 0xf413bdd1, 0x8872980a, 0x157d797c, 0x70b0d3bc, + 0xedbf32ca, 0x91de1711, 0x0cd1f667, 0x5a454291, 0xc74aa3e7, + 0xbb2b863c, 0x2624674a, 0x43e9cd8a, 0xdee62cfc, 0xa2870927, + 0x3f88e851}, + {0x00000000, 0xdd96d985, 0x605cb54b, 0xbdca6cce, 0xc0b96a96, + 0x1d2fb313, 0xa0e5dfdd, 0x7d730658, 0x5a03d36d, 0x87950ae8, + 0x3a5f6626, 0xe7c9bfa3, 0x9abab9fb, 0x472c607e, 0xfae60cb0, + 0x2770d535, 0xb407a6da, 0x69917f5f, 0xd45b1391, 0x09cdca14, + 0x74becc4c, 0xa92815c9, 0x14e27907, 0xc974a082, 0xee0475b7, + 0x3392ac32, 0x8e58c0fc, 0x53ce1979, 0x2ebd1f21, 0xf32bc6a4, + 0x4ee1aa6a, 0x937773ef, 0xb37e4bf5, 0x6ee89270, 0xd322febe, + 0x0eb4273b, 0x73c72163, 0xae51f8e6, 0x139b9428, 0xce0d4dad, + 0xe97d9898, 0x34eb411d, 0x89212dd3, 0x54b7f456, 0x29c4f20e, + 0xf4522b8b, 0x49984745, 0x940e9ec0, 0x0779ed2f, 0xdaef34aa, + 0x67255864, 0xbab381e1, 0xc7c087b9, 0x1a565e3c, 0xa79c32f2, + 0x7a0aeb77, 0x5d7a3e42, 0x80ece7c7, 0x3d268b09, 0xe0b0528c, + 0x9dc354d4, 0x40558d51, 0xfd9fe19f, 0x2009381a, 0xbd8d91ab, + 0x601b482e, 0xddd124e0, 0x0047fd65, 0x7d34fb3d, 0xa0a222b8, + 0x1d684e76, 0xc0fe97f3, 0xe78e42c6, 0x3a189b43, 0x87d2f78d, + 0x5a442e08, 0x27372850, 0xfaa1f1d5, 0x476b9d1b, 0x9afd449e, + 0x098a3771, 0xd41ceef4, 0x69d6823a, 0xb4405bbf, 0xc9335de7, + 0x14a58462, 0xa96fe8ac, 0x74f93129, 0x5389e41c, 0x8e1f3d99, + 0x33d55157, 0xee4388d2, 0x93308e8a, 0x4ea6570f, 0xf36c3bc1, + 0x2efae244, 0x0ef3da5e, 0xd36503db, 0x6eaf6f15, 0xb339b690, + 0xce4ab0c8, 0x13dc694d, 0xae160583, 0x7380dc06, 0x54f00933, + 0x8966d0b6, 0x34acbc78, 0xe93a65fd, 0x944963a5, 0x49dfba20, + 0xf415d6ee, 0x29830f6b, 0xbaf47c84, 0x6762a501, 0xdaa8c9cf, + 0x073e104a, 0x7a4d1612, 0xa7dbcf97, 0x1a11a359, 0xc7877adc, + 0xe0f7afe9, 0x3d61766c, 0x80ab1aa2, 0x5d3dc327, 0x204ec57f, + 0xfdd81cfa, 0x40127034, 0x9d84a9b1, 0xa06a2517, 0x7dfcfc92, + 0xc036905c, 0x1da049d9, 0x60d34f81, 0xbd459604, 0x008ffaca, + 0xdd19234f, 0xfa69f67a, 0x27ff2fff, 0x9a354331, 0x47a39ab4, + 0x3ad09cec, 0xe7464569, 0x5a8c29a7, 0x871af022, 0x146d83cd, + 0xc9fb5a48, 0x74313686, 0xa9a7ef03, 0xd4d4e95b, 0x094230de, + 0xb4885c10, 0x691e8595, 0x4e6e50a0, 0x93f88925, 0x2e32e5eb, + 0xf3a43c6e, 0x8ed73a36, 0x5341e3b3, 0xee8b8f7d, 0x331d56f8, + 0x13146ee2, 0xce82b767, 0x7348dba9, 0xaede022c, 0xd3ad0474, + 0x0e3bddf1, 0xb3f1b13f, 0x6e6768ba, 0x4917bd8f, 0x9481640a, + 0x294b08c4, 0xf4ddd141, 0x89aed719, 0x54380e9c, 0xe9f26252, + 0x3464bbd7, 0xa713c838, 0x7a8511bd, 0xc74f7d73, 0x1ad9a4f6, + 0x67aaa2ae, 0xba3c7b2b, 0x07f617e5, 0xda60ce60, 0xfd101b55, + 0x2086c2d0, 0x9d4cae1e, 0x40da779b, 0x3da971c3, 0xe03fa846, + 0x5df5c488, 0x80631d0d, 0x1de7b4bc, 0xc0716d39, 0x7dbb01f7, + 0xa02dd872, 0xdd5ede2a, 0x00c807af, 0xbd026b61, 0x6094b2e4, + 0x47e467d1, 0x9a72be54, 0x27b8d29a, 0xfa2e0b1f, 0x875d0d47, + 0x5acbd4c2, 0xe701b80c, 0x3a976189, 0xa9e01266, 0x7476cbe3, + 0xc9bca72d, 0x142a7ea8, 0x695978f0, 0xb4cfa175, 0x0905cdbb, + 0xd493143e, 0xf3e3c10b, 0x2e75188e, 0x93bf7440, 0x4e29adc5, + 0x335aab9d, 0xeecc7218, 0x53061ed6, 0x8e90c753, 0xae99ff49, + 0x730f26cc, 0xcec54a02, 0x13539387, 0x6e2095df, 0xb3b64c5a, + 0x0e7c2094, 0xd3eaf911, 0xf49a2c24, 0x290cf5a1, 0x94c6996f, + 0x495040ea, 0x342346b2, 0xe9b59f37, 0x547ff3f9, 0x89e92a7c, + 0x1a9e5993, 0xc7088016, 0x7ac2ecd8, 0xa754355d, 0xda273305, + 0x07b1ea80, 0xba7b864e, 0x67ed5fcb, 0x409d8afe, 0x9d0b537b, + 0x20c13fb5, 0xfd57e630, 0x8024e068, 0x5db239ed, 0xe0785523, + 0x3dee8ca6}, + {0x00000000, 0x9ba54c6f, 0xec3b9e9f, 0x779ed2f0, 0x03063b7f, + 0x98a37710, 0xef3da5e0, 0x7498e98f, 0x060c76fe, 0x9da93a91, + 0xea37e861, 0x7192a40e, 0x050a4d81, 0x9eaf01ee, 0xe931d31e, + 0x72949f71, 0x0c18edfc, 0x97bda193, 0xe0237363, 0x7b863f0c, + 0x0f1ed683, 0x94bb9aec, 0xe325481c, 0x78800473, 0x0a149b02, + 0x91b1d76d, 0xe62f059d, 0x7d8a49f2, 0x0912a07d, 0x92b7ec12, + 0xe5293ee2, 0x7e8c728d, 0x1831dbf8, 0x83949797, 0xf40a4567, + 0x6faf0908, 0x1b37e087, 0x8092ace8, 0xf70c7e18, 0x6ca93277, + 0x1e3dad06, 0x8598e169, 0xf2063399, 0x69a37ff6, 0x1d3b9679, + 0x869eda16, 0xf10008e6, 0x6aa54489, 0x14293604, 0x8f8c7a6b, + 0xf812a89b, 0x63b7e4f4, 0x172f0d7b, 0x8c8a4114, 0xfb1493e4, + 0x60b1df8b, 0x122540fa, 0x89800c95, 0xfe1ede65, 0x65bb920a, + 0x11237b85, 0x8a8637ea, 0xfd18e51a, 0x66bda975, 0x3063b7f0, + 0xabc6fb9f, 0xdc58296f, 0x47fd6500, 0x33658c8f, 0xa8c0c0e0, + 0xdf5e1210, 0x44fb5e7f, 0x366fc10e, 0xadca8d61, 0xda545f91, + 0x41f113fe, 0x3569fa71, 0xaeccb61e, 0xd95264ee, 0x42f72881, + 0x3c7b5a0c, 0xa7de1663, 0xd040c493, 0x4be588fc, 0x3f7d6173, + 0xa4d82d1c, 0xd346ffec, 0x48e3b383, 0x3a772cf2, 0xa1d2609d, + 0xd64cb26d, 0x4de9fe02, 0x3971178d, 0xa2d45be2, 0xd54a8912, + 0x4eefc57d, 0x28526c08, 0xb3f72067, 0xc469f297, 0x5fccbef8, + 0x2b545777, 0xb0f11b18, 0xc76fc9e8, 0x5cca8587, 0x2e5e1af6, + 0xb5fb5699, 0xc2658469, 0x59c0c806, 0x2d582189, 0xb6fd6de6, + 0xc163bf16, 0x5ac6f379, 0x244a81f4, 0xbfefcd9b, 0xc8711f6b, + 0x53d45304, 0x274cba8b, 0xbce9f6e4, 0xcb772414, 0x50d2687b, + 0x2246f70a, 0xb9e3bb65, 0xce7d6995, 0x55d825fa, 0x2140cc75, + 0xbae5801a, 0xcd7b52ea, 0x56de1e85, 0x60c76fe0, 0xfb62238f, + 0x8cfcf17f, 0x1759bd10, 0x63c1549f, 0xf86418f0, 0x8ffaca00, + 0x145f866f, 0x66cb191e, 0xfd6e5571, 0x8af08781, 0x1155cbee, + 0x65cd2261, 0xfe686e0e, 0x89f6bcfe, 0x1253f091, 0x6cdf821c, + 0xf77ace73, 0x80e41c83, 0x1b4150ec, 0x6fd9b963, 0xf47cf50c, + 0x83e227fc, 0x18476b93, 0x6ad3f4e2, 0xf176b88d, 0x86e86a7d, + 0x1d4d2612, 0x69d5cf9d, 0xf27083f2, 0x85ee5102, 0x1e4b1d6d, + 0x78f6b418, 0xe353f877, 0x94cd2a87, 0x0f6866e8, 0x7bf08f67, + 0xe055c308, 0x97cb11f8, 0x0c6e5d97, 0x7efac2e6, 0xe55f8e89, + 0x92c15c79, 0x09641016, 0x7dfcf999, 0xe659b5f6, 0x91c76706, + 0x0a622b69, 0x74ee59e4, 0xef4b158b, 0x98d5c77b, 0x03708b14, + 0x77e8629b, 0xec4d2ef4, 0x9bd3fc04, 0x0076b06b, 0x72e22f1a, + 0xe9476375, 0x9ed9b185, 0x057cfdea, 0x71e41465, 0xea41580a, + 0x9ddf8afa, 0x067ac695, 0x50a4d810, 0xcb01947f, 0xbc9f468f, + 0x273a0ae0, 0x53a2e36f, 0xc807af00, 0xbf997df0, 0x243c319f, + 0x56a8aeee, 0xcd0de281, 0xba933071, 0x21367c1e, 0x55ae9591, + 0xce0bd9fe, 0xb9950b0e, 0x22304761, 0x5cbc35ec, 0xc7197983, + 0xb087ab73, 0x2b22e71c, 0x5fba0e93, 0xc41f42fc, 0xb381900c, + 0x2824dc63, 0x5ab04312, 0xc1150f7d, 0xb68bdd8d, 0x2d2e91e2, + 0x59b6786d, 0xc2133402, 0xb58de6f2, 0x2e28aa9d, 0x489503e8, + 0xd3304f87, 0xa4ae9d77, 0x3f0bd118, 0x4b933897, 0xd03674f8, + 0xa7a8a608, 0x3c0dea67, 0x4e997516, 0xd53c3979, 0xa2a2eb89, + 0x3907a7e6, 0x4d9f4e69, 0xd63a0206, 0xa1a4d0f6, 0x3a019c99, + 0x448dee14, 0xdf28a27b, 0xa8b6708b, 0x33133ce4, 0x478bd56b, + 0xdc2e9904, 0xabb04bf4, 0x3015079b, 0x428198ea, 0xd924d485, + 0xaeba0675, 0x351f4a1a, 0x4187a395, 0xda22effa, 0xadbc3d0a, + 0x36197165}, + {0x00000000, 0xc18edfc0, 0x586cb9c1, 0x99e26601, 0xb0d97382, + 0x7157ac42, 0xe8b5ca43, 0x293b1583, 0xbac3e145, 0x7b4d3e85, + 0xe2af5884, 0x23218744, 0x0a1a92c7, 0xcb944d07, 0x52762b06, + 0x93f8f4c6, 0xaef6c4cb, 0x6f781b0b, 0xf69a7d0a, 0x3714a2ca, + 0x1e2fb749, 0xdfa16889, 0x46430e88, 0x87cdd148, 0x1435258e, + 0xd5bbfa4e, 0x4c599c4f, 0x8dd7438f, 0xa4ec560c, 0x656289cc, + 0xfc80efcd, 0x3d0e300d, 0x869c8fd7, 0x47125017, 0xdef03616, + 0x1f7ee9d6, 0x3645fc55, 0xf7cb2395, 0x6e294594, 0xafa79a54, + 0x3c5f6e92, 0xfdd1b152, 0x6433d753, 0xa5bd0893, 0x8c861d10, + 0x4d08c2d0, 0xd4eaa4d1, 0x15647b11, 0x286a4b1c, 0xe9e494dc, + 0x7006f2dd, 0xb1882d1d, 0x98b3389e, 0x593de75e, 0xc0df815f, + 0x01515e9f, 0x92a9aa59, 0x53277599, 0xcac51398, 0x0b4bcc58, + 0x2270d9db, 0xe3fe061b, 0x7a1c601a, 0xbb92bfda, 0xd64819ef, + 0x17c6c62f, 0x8e24a02e, 0x4faa7fee, 0x66916a6d, 0xa71fb5ad, + 0x3efdd3ac, 0xff730c6c, 0x6c8bf8aa, 0xad05276a, 0x34e7416b, + 0xf5699eab, 0xdc528b28, 0x1ddc54e8, 0x843e32e9, 0x45b0ed29, + 0x78bedd24, 0xb93002e4, 0x20d264e5, 0xe15cbb25, 0xc867aea6, + 0x09e97166, 0x900b1767, 0x5185c8a7, 0xc27d3c61, 0x03f3e3a1, + 0x9a1185a0, 0x5b9f5a60, 0x72a44fe3, 0xb32a9023, 0x2ac8f622, + 0xeb4629e2, 0x50d49638, 0x915a49f8, 0x08b82ff9, 0xc936f039, + 0xe00de5ba, 0x21833a7a, 0xb8615c7b, 0x79ef83bb, 0xea17777d, + 0x2b99a8bd, 0xb27bcebc, 0x73f5117c, 0x5ace04ff, 0x9b40db3f, + 0x02a2bd3e, 0xc32c62fe, 0xfe2252f3, 0x3fac8d33, 0xa64eeb32, + 0x67c034f2, 0x4efb2171, 0x8f75feb1, 0x169798b0, 0xd7194770, + 0x44e1b3b6, 0x856f6c76, 0x1c8d0a77, 0xdd03d5b7, 0xf438c034, + 0x35b61ff4, 0xac5479f5, 0x6ddaa635, 0x77e1359f, 0xb66fea5f, + 0x2f8d8c5e, 0xee03539e, 0xc738461d, 0x06b699dd, 0x9f54ffdc, + 0x5eda201c, 0xcd22d4da, 0x0cac0b1a, 0x954e6d1b, 0x54c0b2db, + 0x7dfba758, 0xbc757898, 0x25971e99, 0xe419c159, 0xd917f154, + 0x18992e94, 0x817b4895, 0x40f59755, 0x69ce82d6, 0xa8405d16, + 0x31a23b17, 0xf02ce4d7, 0x63d41011, 0xa25acfd1, 0x3bb8a9d0, + 0xfa367610, 0xd30d6393, 0x1283bc53, 0x8b61da52, 0x4aef0592, + 0xf17dba48, 0x30f36588, 0xa9110389, 0x689fdc49, 0x41a4c9ca, + 0x802a160a, 0x19c8700b, 0xd846afcb, 0x4bbe5b0d, 0x8a3084cd, + 0x13d2e2cc, 0xd25c3d0c, 0xfb67288f, 0x3ae9f74f, 0xa30b914e, + 0x62854e8e, 0x5f8b7e83, 0x9e05a143, 0x07e7c742, 0xc6691882, + 0xef520d01, 0x2edcd2c1, 0xb73eb4c0, 0x76b06b00, 0xe5489fc6, + 0x24c64006, 0xbd242607, 0x7caaf9c7, 0x5591ec44, 0x941f3384, + 0x0dfd5585, 0xcc738a45, 0xa1a92c70, 0x6027f3b0, 0xf9c595b1, + 0x384b4a71, 0x11705ff2, 0xd0fe8032, 0x491ce633, 0x889239f3, + 0x1b6acd35, 0xdae412f5, 0x430674f4, 0x8288ab34, 0xabb3beb7, + 0x6a3d6177, 0xf3df0776, 0x3251d8b6, 0x0f5fe8bb, 0xced1377b, + 0x5733517a, 0x96bd8eba, 0xbf869b39, 0x7e0844f9, 0xe7ea22f8, + 0x2664fd38, 0xb59c09fe, 0x7412d63e, 0xedf0b03f, 0x2c7e6fff, + 0x05457a7c, 0xc4cba5bc, 0x5d29c3bd, 0x9ca71c7d, 0x2735a3a7, + 0xe6bb7c67, 0x7f591a66, 0xbed7c5a6, 0x97ecd025, 0x56620fe5, + 0xcf8069e4, 0x0e0eb624, 0x9df642e2, 0x5c789d22, 0xc59afb23, + 0x041424e3, 0x2d2f3160, 0xeca1eea0, 0x754388a1, 0xb4cd5761, + 0x89c3676c, 0x484db8ac, 0xd1afdead, 0x1021016d, 0x391a14ee, + 0xf894cb2e, 0x6176ad2f, 0xa0f872ef, 0x33008629, 0xf28e59e9, + 0x6b6c3fe8, 0xaae2e028, 0x83d9f5ab, 0x42572a6b, 0xdbb54c6a, + 0x1a3b93aa}, + {0x00000000, 0xefc26b3e, 0x04f5d03d, 0xeb37bb03, 0x09eba07a, + 0xe629cb44, 0x0d1e7047, 0xe2dc1b79, 0x13d740f4, 0xfc152bca, + 0x172290c9, 0xf8e0fbf7, 0x1a3ce08e, 0xf5fe8bb0, 0x1ec930b3, + 0xf10b5b8d, 0x27ae81e8, 0xc86cead6, 0x235b51d5, 0xcc993aeb, + 0x2e452192, 0xc1874aac, 0x2ab0f1af, 0xc5729a91, 0x3479c11c, + 0xdbbbaa22, 0x308c1121, 0xdf4e7a1f, 0x3d926166, 0xd2500a58, + 0x3967b15b, 0xd6a5da65, 0x4f5d03d0, 0xa09f68ee, 0x4ba8d3ed, + 0xa46ab8d3, 0x46b6a3aa, 0xa974c894, 0x42437397, 0xad8118a9, + 0x5c8a4324, 0xb348281a, 0x587f9319, 0xb7bdf827, 0x5561e35e, + 0xbaa38860, 0x51943363, 0xbe56585d, 0x68f38238, 0x8731e906, + 0x6c065205, 0x83c4393b, 0x61182242, 0x8eda497c, 0x65edf27f, + 0x8a2f9941, 0x7b24c2cc, 0x94e6a9f2, 0x7fd112f1, 0x901379cf, + 0x72cf62b6, 0x9d0d0988, 0x763ab28b, 0x99f8d9b5, 0x9eba07a0, + 0x71786c9e, 0x9a4fd79d, 0x758dbca3, 0x9751a7da, 0x7893cce4, + 0x93a477e7, 0x7c661cd9, 0x8d6d4754, 0x62af2c6a, 0x89989769, + 0x665afc57, 0x8486e72e, 0x6b448c10, 0x80733713, 0x6fb15c2d, + 0xb9148648, 0x56d6ed76, 0xbde15675, 0x52233d4b, 0xb0ff2632, + 0x5f3d4d0c, 0xb40af60f, 0x5bc89d31, 0xaac3c6bc, 0x4501ad82, + 0xae361681, 0x41f47dbf, 0xa32866c6, 0x4cea0df8, 0xa7ddb6fb, + 0x481fddc5, 0xd1e70470, 0x3e256f4e, 0xd512d44d, 0x3ad0bf73, + 0xd80ca40a, 0x37cecf34, 0xdcf97437, 0x333b1f09, 0xc2304484, + 0x2df22fba, 0xc6c594b9, 0x2907ff87, 0xcbdbe4fe, 0x24198fc0, + 0xcf2e34c3, 0x20ec5ffd, 0xf6498598, 0x198beea6, 0xf2bc55a5, + 0x1d7e3e9b, 0xffa225e2, 0x10604edc, 0xfb57f5df, 0x14959ee1, + 0xe59ec56c, 0x0a5cae52, 0xe16b1551, 0x0ea97e6f, 0xec756516, + 0x03b70e28, 0xe880b52b, 0x0742de15, 0xe6050901, 0x09c7623f, + 0xe2f0d93c, 0x0d32b202, 0xefeea97b, 0x002cc245, 0xeb1b7946, + 0x04d91278, 0xf5d249f5, 0x1a1022cb, 0xf12799c8, 0x1ee5f2f6, + 0xfc39e98f, 0x13fb82b1, 0xf8cc39b2, 0x170e528c, 0xc1ab88e9, + 0x2e69e3d7, 0xc55e58d4, 0x2a9c33ea, 0xc8402893, 0x278243ad, + 0xccb5f8ae, 0x23779390, 0xd27cc81d, 0x3dbea323, 0xd6891820, + 0x394b731e, 0xdb976867, 0x34550359, 0xdf62b85a, 0x30a0d364, + 0xa9580ad1, 0x469a61ef, 0xadaddaec, 0x426fb1d2, 0xa0b3aaab, + 0x4f71c195, 0xa4467a96, 0x4b8411a8, 0xba8f4a25, 0x554d211b, + 0xbe7a9a18, 0x51b8f126, 0xb364ea5f, 0x5ca68161, 0xb7913a62, + 0x5853515c, 0x8ef68b39, 0x6134e007, 0x8a035b04, 0x65c1303a, + 0x871d2b43, 0x68df407d, 0x83e8fb7e, 0x6c2a9040, 0x9d21cbcd, + 0x72e3a0f3, 0x99d41bf0, 0x761670ce, 0x94ca6bb7, 0x7b080089, + 0x903fbb8a, 0x7ffdd0b4, 0x78bf0ea1, 0x977d659f, 0x7c4ade9c, + 0x9388b5a2, 0x7154aedb, 0x9e96c5e5, 0x75a17ee6, 0x9a6315d8, + 0x6b684e55, 0x84aa256b, 0x6f9d9e68, 0x805ff556, 0x6283ee2f, + 0x8d418511, 0x66763e12, 0x89b4552c, 0x5f118f49, 0xb0d3e477, + 0x5be45f74, 0xb426344a, 0x56fa2f33, 0xb938440d, 0x520fff0e, + 0xbdcd9430, 0x4cc6cfbd, 0xa304a483, 0x48331f80, 0xa7f174be, + 0x452d6fc7, 0xaaef04f9, 0x41d8bffa, 0xae1ad4c4, 0x37e20d71, + 0xd820664f, 0x3317dd4c, 0xdcd5b672, 0x3e09ad0b, 0xd1cbc635, + 0x3afc7d36, 0xd53e1608, 0x24354d85, 0xcbf726bb, 0x20c09db8, + 0xcf02f686, 0x2ddeedff, 0xc21c86c1, 0x292b3dc2, 0xc6e956fc, + 0x104c8c99, 0xff8ee7a7, 0x14b95ca4, 0xfb7b379a, 0x19a72ce3, + 0xf66547dd, 0x1d52fcde, 0xf29097e0, 0x039bcc6d, 0xec59a753, + 0x076e1c50, 0xe8ac776e, 0x0a706c17, 0xe5b20729, 0x0e85bc2a, + 0xe147d714}, + {0x00000000, 0x177b1443, 0x2ef62886, 0x398d3cc5, 0x5dec510c, + 0x4a97454f, 0x731a798a, 0x64616dc9, 0xbbd8a218, 0xaca3b65b, + 0x952e8a9e, 0x82559edd, 0xe634f314, 0xf14fe757, 0xc8c2db92, + 0xdfb9cfd1, 0xacc04271, 0xbbbb5632, 0x82366af7, 0x954d7eb4, + 0xf12c137d, 0xe657073e, 0xdfda3bfb, 0xc8a12fb8, 0x1718e069, + 0x0063f42a, 0x39eec8ef, 0x2e95dcac, 0x4af4b165, 0x5d8fa526, + 0x640299e3, 0x73798da0, 0x82f182a3, 0x958a96e0, 0xac07aa25, + 0xbb7cbe66, 0xdf1dd3af, 0xc866c7ec, 0xf1ebfb29, 0xe690ef6a, + 0x392920bb, 0x2e5234f8, 0x17df083d, 0x00a41c7e, 0x64c571b7, + 0x73be65f4, 0x4a335931, 0x5d484d72, 0x2e31c0d2, 0x394ad491, + 0x00c7e854, 0x17bcfc17, 0x73dd91de, 0x64a6859d, 0x5d2bb958, + 0x4a50ad1b, 0x95e962ca, 0x82927689, 0xbb1f4a4c, 0xac645e0f, + 0xc80533c6, 0xdf7e2785, 0xe6f31b40, 0xf1880f03, 0xde920307, + 0xc9e91744, 0xf0642b81, 0xe71f3fc2, 0x837e520b, 0x94054648, + 0xad887a8d, 0xbaf36ece, 0x654aa11f, 0x7231b55c, 0x4bbc8999, + 0x5cc79dda, 0x38a6f013, 0x2fdde450, 0x1650d895, 0x012bccd6, + 0x72524176, 0x65295535, 0x5ca469f0, 0x4bdf7db3, 0x2fbe107a, + 0x38c50439, 0x014838fc, 0x16332cbf, 0xc98ae36e, 0xdef1f72d, + 0xe77ccbe8, 0xf007dfab, 0x9466b262, 0x831da621, 0xba909ae4, + 0xadeb8ea7, 0x5c6381a4, 0x4b1895e7, 0x7295a922, 0x65eebd61, + 0x018fd0a8, 0x16f4c4eb, 0x2f79f82e, 0x3802ec6d, 0xe7bb23bc, + 0xf0c037ff, 0xc94d0b3a, 0xde361f79, 0xba5772b0, 0xad2c66f3, + 0x94a15a36, 0x83da4e75, 0xf0a3c3d5, 0xe7d8d796, 0xde55eb53, + 0xc92eff10, 0xad4f92d9, 0xba34869a, 0x83b9ba5f, 0x94c2ae1c, + 0x4b7b61cd, 0x5c00758e, 0x658d494b, 0x72f65d08, 0x169730c1, + 0x01ec2482, 0x38611847, 0x2f1a0c04, 0x6655004f, 0x712e140c, + 0x48a328c9, 0x5fd83c8a, 0x3bb95143, 0x2cc24500, 0x154f79c5, + 0x02346d86, 0xdd8da257, 0xcaf6b614, 0xf37b8ad1, 0xe4009e92, + 0x8061f35b, 0x971ae718, 0xae97dbdd, 0xb9eccf9e, 0xca95423e, + 0xddee567d, 0xe4636ab8, 0xf3187efb, 0x97791332, 0x80020771, + 0xb98f3bb4, 0xaef42ff7, 0x714de026, 0x6636f465, 0x5fbbc8a0, + 0x48c0dce3, 0x2ca1b12a, 0x3bdaa569, 0x025799ac, 0x152c8def, + 0xe4a482ec, 0xf3df96af, 0xca52aa6a, 0xdd29be29, 0xb948d3e0, + 0xae33c7a3, 0x97befb66, 0x80c5ef25, 0x5f7c20f4, 0x480734b7, + 0x718a0872, 0x66f11c31, 0x029071f8, 0x15eb65bb, 0x2c66597e, + 0x3b1d4d3d, 0x4864c09d, 0x5f1fd4de, 0x6692e81b, 0x71e9fc58, + 0x15889191, 0x02f385d2, 0x3b7eb917, 0x2c05ad54, 0xf3bc6285, + 0xe4c776c6, 0xdd4a4a03, 0xca315e40, 0xae503389, 0xb92b27ca, + 0x80a61b0f, 0x97dd0f4c, 0xb8c70348, 0xafbc170b, 0x96312bce, + 0x814a3f8d, 0xe52b5244, 0xf2504607, 0xcbdd7ac2, 0xdca66e81, + 0x031fa150, 0x1464b513, 0x2de989d6, 0x3a929d95, 0x5ef3f05c, + 0x4988e41f, 0x7005d8da, 0x677ecc99, 0x14074139, 0x037c557a, + 0x3af169bf, 0x2d8a7dfc, 0x49eb1035, 0x5e900476, 0x671d38b3, + 0x70662cf0, 0xafdfe321, 0xb8a4f762, 0x8129cba7, 0x9652dfe4, + 0xf233b22d, 0xe548a66e, 0xdcc59aab, 0xcbbe8ee8, 0x3a3681eb, + 0x2d4d95a8, 0x14c0a96d, 0x03bbbd2e, 0x67dad0e7, 0x70a1c4a4, + 0x492cf861, 0x5e57ec22, 0x81ee23f3, 0x969537b0, 0xaf180b75, + 0xb8631f36, 0xdc0272ff, 0xcb7966bc, 0xf2f45a79, 0xe58f4e3a, + 0x96f6c39a, 0x818dd7d9, 0xb800eb1c, 0xaf7bff5f, 0xcb1a9296, + 0xdc6186d5, 0xe5ecba10, 0xf297ae53, 0x2d2e6182, 0x3a5575c1, + 0x03d84904, 0x14a35d47, 0x70c2308e, 0x67b924cd, 0x5e341808, + 0x494f0c4b}}; + +local const z_word_t FAR crc_braid_big_table[][256] = { + {0x0000000000000000, 0x43147b1700000000, 0x8628f62e00000000, + 0xc53c8d3900000000, 0x0c51ec5d00000000, 0x4f45974a00000000, + 0x8a791a7300000000, 0xc96d616400000000, 0x18a2d8bb00000000, + 0x5bb6a3ac00000000, 0x9e8a2e9500000000, 0xdd9e558200000000, + 0x14f334e600000000, 0x57e74ff100000000, 0x92dbc2c800000000, + 0xd1cfb9df00000000, 0x7142c0ac00000000, 0x3256bbbb00000000, + 0xf76a368200000000, 0xb47e4d9500000000, 0x7d132cf100000000, + 0x3e0757e600000000, 0xfb3bdadf00000000, 0xb82fa1c800000000, + 0x69e0181700000000, 0x2af4630000000000, 0xefc8ee3900000000, + 0xacdc952e00000000, 0x65b1f44a00000000, 0x26a58f5d00000000, + 0xe399026400000000, 0xa08d797300000000, 0xa382f18200000000, + 0xe0968a9500000000, 0x25aa07ac00000000, 0x66be7cbb00000000, + 0xafd31ddf00000000, 0xecc766c800000000, 0x29fbebf100000000, + 0x6aef90e600000000, 0xbb20293900000000, 0xf834522e00000000, + 0x3d08df1700000000, 0x7e1ca40000000000, 0xb771c56400000000, + 0xf465be7300000000, 0x3159334a00000000, 0x724d485d00000000, + 0xd2c0312e00000000, 0x91d44a3900000000, 0x54e8c70000000000, + 0x17fcbc1700000000, 0xde91dd7300000000, 0x9d85a66400000000, + 0x58b92b5d00000000, 0x1bad504a00000000, 0xca62e99500000000, + 0x8976928200000000, 0x4c4a1fbb00000000, 0x0f5e64ac00000000, + 0xc63305c800000000, 0x85277edf00000000, 0x401bf3e600000000, + 0x030f88f100000000, 0x070392de00000000, 0x4417e9c900000000, + 0x812b64f000000000, 0xc23f1fe700000000, 0x0b527e8300000000, + 0x4846059400000000, 0x8d7a88ad00000000, 0xce6ef3ba00000000, + 0x1fa14a6500000000, 0x5cb5317200000000, 0x9989bc4b00000000, + 0xda9dc75c00000000, 0x13f0a63800000000, 0x50e4dd2f00000000, + 0x95d8501600000000, 0xd6cc2b0100000000, 0x7641527200000000, + 0x3555296500000000, 0xf069a45c00000000, 0xb37ddf4b00000000, + 0x7a10be2f00000000, 0x3904c53800000000, 0xfc38480100000000, + 0xbf2c331600000000, 0x6ee38ac900000000, 0x2df7f1de00000000, + 0xe8cb7ce700000000, 0xabdf07f000000000, 0x62b2669400000000, + 0x21a61d8300000000, 0xe49a90ba00000000, 0xa78eebad00000000, + 0xa481635c00000000, 0xe795184b00000000, 0x22a9957200000000, + 0x61bdee6500000000, 0xa8d08f0100000000, 0xebc4f41600000000, + 0x2ef8792f00000000, 0x6dec023800000000, 0xbc23bbe700000000, + 0xff37c0f000000000, 0x3a0b4dc900000000, 0x791f36de00000000, + 0xb07257ba00000000, 0xf3662cad00000000, 0x365aa19400000000, + 0x754eda8300000000, 0xd5c3a3f000000000, 0x96d7d8e700000000, + 0x53eb55de00000000, 0x10ff2ec900000000, 0xd9924fad00000000, + 0x9a8634ba00000000, 0x5fbab98300000000, 0x1caec29400000000, + 0xcd617b4b00000000, 0x8e75005c00000000, 0x4b498d6500000000, + 0x085df67200000000, 0xc130971600000000, 0x8224ec0100000000, + 0x4718613800000000, 0x040c1a2f00000000, 0x4f00556600000000, + 0x0c142e7100000000, 0xc928a34800000000, 0x8a3cd85f00000000, + 0x4351b93b00000000, 0x0045c22c00000000, 0xc5794f1500000000, + 0x866d340200000000, 0x57a28ddd00000000, 0x14b6f6ca00000000, + 0xd18a7bf300000000, 0x929e00e400000000, 0x5bf3618000000000, + 0x18e71a9700000000, 0xdddb97ae00000000, 0x9ecfecb900000000, + 0x3e4295ca00000000, 0x7d56eedd00000000, 0xb86a63e400000000, + 0xfb7e18f300000000, 0x3213799700000000, 0x7107028000000000, + 0xb43b8fb900000000, 0xf72ff4ae00000000, 0x26e04d7100000000, + 0x65f4366600000000, 0xa0c8bb5f00000000, 0xe3dcc04800000000, + 0x2ab1a12c00000000, 0x69a5da3b00000000, 0xac99570200000000, + 0xef8d2c1500000000, 0xec82a4e400000000, 0xaf96dff300000000, + 0x6aaa52ca00000000, 0x29be29dd00000000, 0xe0d348b900000000, + 0xa3c733ae00000000, 0x66fbbe9700000000, 0x25efc58000000000, + 0xf4207c5f00000000, 0xb734074800000000, 0x72088a7100000000, + 0x311cf16600000000, 0xf871900200000000, 0xbb65eb1500000000, + 0x7e59662c00000000, 0x3d4d1d3b00000000, 0x9dc0644800000000, + 0xded41f5f00000000, 0x1be8926600000000, 0x58fce97100000000, + 0x9191881500000000, 0xd285f30200000000, 0x17b97e3b00000000, + 0x54ad052c00000000, 0x8562bcf300000000, 0xc676c7e400000000, + 0x034a4add00000000, 0x405e31ca00000000, 0x893350ae00000000, + 0xca272bb900000000, 0x0f1ba68000000000, 0x4c0fdd9700000000, + 0x4803c7b800000000, 0x0b17bcaf00000000, 0xce2b319600000000, + 0x8d3f4a8100000000, 0x44522be500000000, 0x074650f200000000, + 0xc27addcb00000000, 0x816ea6dc00000000, 0x50a11f0300000000, + 0x13b5641400000000, 0xd689e92d00000000, 0x959d923a00000000, + 0x5cf0f35e00000000, 0x1fe4884900000000, 0xdad8057000000000, + 0x99cc7e6700000000, 0x3941071400000000, 0x7a557c0300000000, + 0xbf69f13a00000000, 0xfc7d8a2d00000000, 0x3510eb4900000000, + 0x7604905e00000000, 0xb3381d6700000000, 0xf02c667000000000, + 0x21e3dfaf00000000, 0x62f7a4b800000000, 0xa7cb298100000000, + 0xe4df529600000000, 0x2db233f200000000, 0x6ea648e500000000, + 0xab9ac5dc00000000, 0xe88ebecb00000000, 0xeb81363a00000000, + 0xa8954d2d00000000, 0x6da9c01400000000, 0x2ebdbb0300000000, + 0xe7d0da6700000000, 0xa4c4a17000000000, 0x61f82c4900000000, + 0x22ec575e00000000, 0xf323ee8100000000, 0xb037959600000000, + 0x750b18af00000000, 0x361f63b800000000, 0xff7202dc00000000, + 0xbc6679cb00000000, 0x795af4f200000000, 0x3a4e8fe500000000, + 0x9ac3f69600000000, 0xd9d78d8100000000, 0x1ceb00b800000000, + 0x5fff7baf00000000, 0x96921acb00000000, 0xd58661dc00000000, + 0x10baece500000000, 0x53ae97f200000000, 0x82612e2d00000000, + 0xc175553a00000000, 0x0449d80300000000, 0x475da31400000000, + 0x8e30c27000000000, 0xcd24b96700000000, 0x0818345e00000000, + 0x4b0c4f4900000000}, + {0x0000000000000000, 0x3e6bc2ef00000000, 0x3dd0f50400000000, + 0x03bb37eb00000000, 0x7aa0eb0900000000, 0x44cb29e600000000, + 0x47701e0d00000000, 0x791bdce200000000, 0xf440d71300000000, + 0xca2b15fc00000000, 0xc990221700000000, 0xf7fbe0f800000000, + 0x8ee03c1a00000000, 0xb08bfef500000000, 0xb330c91e00000000, + 0x8d5b0bf100000000, 0xe881ae2700000000, 0xd6ea6cc800000000, + 0xd5515b2300000000, 0xeb3a99cc00000000, 0x9221452e00000000, + 0xac4a87c100000000, 0xaff1b02a00000000, 0x919a72c500000000, + 0x1cc1793400000000, 0x22aabbdb00000000, 0x21118c3000000000, + 0x1f7a4edf00000000, 0x6661923d00000000, 0x580a50d200000000, + 0x5bb1673900000000, 0x65daa5d600000000, 0xd0035d4f00000000, + 0xee689fa000000000, 0xedd3a84b00000000, 0xd3b86aa400000000, + 0xaaa3b64600000000, 0x94c874a900000000, 0x9773434200000000, + 0xa91881ad00000000, 0x24438a5c00000000, 0x1a2848b300000000, + 0x19937f5800000000, 0x27f8bdb700000000, 0x5ee3615500000000, + 0x6088a3ba00000000, 0x6333945100000000, 0x5d5856be00000000, + 0x3882f36800000000, 0x06e9318700000000, 0x0552066c00000000, + 0x3b39c48300000000, 0x4222186100000000, 0x7c49da8e00000000, + 0x7ff2ed6500000000, 0x41992f8a00000000, 0xccc2247b00000000, + 0xf2a9e69400000000, 0xf112d17f00000000, 0xcf79139000000000, + 0xb662cf7200000000, 0x88090d9d00000000, 0x8bb23a7600000000, + 0xb5d9f89900000000, 0xa007ba9e00000000, 0x9e6c787100000000, + 0x9dd74f9a00000000, 0xa3bc8d7500000000, 0xdaa7519700000000, + 0xe4cc937800000000, 0xe777a49300000000, 0xd91c667c00000000, + 0x54476d8d00000000, 0x6a2caf6200000000, 0x6997988900000000, + 0x57fc5a6600000000, 0x2ee7868400000000, 0x108c446b00000000, + 0x1337738000000000, 0x2d5cb16f00000000, 0x488614b900000000, + 0x76edd65600000000, 0x7556e1bd00000000, 0x4b3d235200000000, + 0x3226ffb000000000, 0x0c4d3d5f00000000, 0x0ff60ab400000000, + 0x319dc85b00000000, 0xbcc6c3aa00000000, 0x82ad014500000000, + 0x811636ae00000000, 0xbf7df44100000000, 0xc66628a300000000, + 0xf80dea4c00000000, 0xfbb6dda700000000, 0xc5dd1f4800000000, + 0x7004e7d100000000, 0x4e6f253e00000000, 0x4dd412d500000000, + 0x73bfd03a00000000, 0x0aa40cd800000000, 0x34cfce3700000000, + 0x3774f9dc00000000, 0x091f3b3300000000, 0x844430c200000000, + 0xba2ff22d00000000, 0xb994c5c600000000, 0x87ff072900000000, + 0xfee4dbcb00000000, 0xc08f192400000000, 0xc3342ecf00000000, + 0xfd5fec2000000000, 0x988549f600000000, 0xa6ee8b1900000000, + 0xa555bcf200000000, 0x9b3e7e1d00000000, 0xe225a2ff00000000, + 0xdc4e601000000000, 0xdff557fb00000000, 0xe19e951400000000, + 0x6cc59ee500000000, 0x52ae5c0a00000000, 0x51156be100000000, + 0x6f7ea90e00000000, 0x166575ec00000000, 0x280eb70300000000, + 0x2bb580e800000000, 0x15de420700000000, 0x010905e600000000, + 0x3f62c70900000000, 0x3cd9f0e200000000, 0x02b2320d00000000, + 0x7ba9eeef00000000, 0x45c22c0000000000, 0x46791beb00000000, + 0x7812d90400000000, 0xf549d2f500000000, 0xcb22101a00000000, + 0xc89927f100000000, 0xf6f2e51e00000000, 0x8fe939fc00000000, + 0xb182fb1300000000, 0xb239ccf800000000, 0x8c520e1700000000, + 0xe988abc100000000, 0xd7e3692e00000000, 0xd4585ec500000000, + 0xea339c2a00000000, 0x932840c800000000, 0xad43822700000000, + 0xaef8b5cc00000000, 0x9093772300000000, 0x1dc87cd200000000, + 0x23a3be3d00000000, 0x201889d600000000, 0x1e734b3900000000, + 0x676897db00000000, 0x5903553400000000, 0x5ab862df00000000, + 0x64d3a03000000000, 0xd10a58a900000000, 0xef619a4600000000, + 0xecdaadad00000000, 0xd2b16f4200000000, 0xabaab3a000000000, + 0x95c1714f00000000, 0x967a46a400000000, 0xa811844b00000000, + 0x254a8fba00000000, 0x1b214d5500000000, 0x189a7abe00000000, + 0x26f1b85100000000, 0x5fea64b300000000, 0x6181a65c00000000, + 0x623a91b700000000, 0x5c51535800000000, 0x398bf68e00000000, + 0x07e0346100000000, 0x045b038a00000000, 0x3a30c16500000000, + 0x432b1d8700000000, 0x7d40df6800000000, 0x7efbe88300000000, + 0x40902a6c00000000, 0xcdcb219d00000000, 0xf3a0e37200000000, + 0xf01bd49900000000, 0xce70167600000000, 0xb76bca9400000000, + 0x8900087b00000000, 0x8abb3f9000000000, 0xb4d0fd7f00000000, + 0xa10ebf7800000000, 0x9f657d9700000000, 0x9cde4a7c00000000, + 0xa2b5889300000000, 0xdbae547100000000, 0xe5c5969e00000000, + 0xe67ea17500000000, 0xd815639a00000000, 0x554e686b00000000, + 0x6b25aa8400000000, 0x689e9d6f00000000, 0x56f55f8000000000, + 0x2fee836200000000, 0x1185418d00000000, 0x123e766600000000, + 0x2c55b48900000000, 0x498f115f00000000, 0x77e4d3b000000000, + 0x745fe45b00000000, 0x4a3426b400000000, 0x332ffa5600000000, + 0x0d4438b900000000, 0x0eff0f5200000000, 0x3094cdbd00000000, + 0xbdcfc64c00000000, 0x83a404a300000000, 0x801f334800000000, + 0xbe74f1a700000000, 0xc76f2d4500000000, 0xf904efaa00000000, + 0xfabfd84100000000, 0xc4d41aae00000000, 0x710de23700000000, + 0x4f6620d800000000, 0x4cdd173300000000, 0x72b6d5dc00000000, + 0x0bad093e00000000, 0x35c6cbd100000000, 0x367dfc3a00000000, + 0x08163ed500000000, 0x854d352400000000, 0xbb26f7cb00000000, + 0xb89dc02000000000, 0x86f602cf00000000, 0xffedde2d00000000, + 0xc1861cc200000000, 0xc23d2b2900000000, 0xfc56e9c600000000, + 0x998c4c1000000000, 0xa7e78eff00000000, 0xa45cb91400000000, + 0x9a377bfb00000000, 0xe32ca71900000000, 0xdd4765f600000000, + 0xdefc521d00000000, 0xe09790f200000000, 0x6dcc9b0300000000, + 0x53a759ec00000000, 0x501c6e0700000000, 0x6e77ace800000000, + 0x176c700a00000000, 0x2907b2e500000000, 0x2abc850e00000000, + 0x14d747e100000000}, + {0x0000000000000000, 0xc0df8ec100000000, 0xc1b96c5800000000, + 0x0166e29900000000, 0x8273d9b000000000, 0x42ac577100000000, + 0x43cab5e800000000, 0x83153b2900000000, 0x45e1c3ba00000000, + 0x853e4d7b00000000, 0x8458afe200000000, 0x4487212300000000, + 0xc7921a0a00000000, 0x074d94cb00000000, 0x062b765200000000, + 0xc6f4f89300000000, 0xcbc4f6ae00000000, 0x0b1b786f00000000, + 0x0a7d9af600000000, 0xcaa2143700000000, 0x49b72f1e00000000, + 0x8968a1df00000000, 0x880e434600000000, 0x48d1cd8700000000, + 0x8e25351400000000, 0x4efabbd500000000, 0x4f9c594c00000000, + 0x8f43d78d00000000, 0x0c56eca400000000, 0xcc89626500000000, + 0xcdef80fc00000000, 0x0d300e3d00000000, 0xd78f9c8600000000, + 0x1750124700000000, 0x1636f0de00000000, 0xd6e97e1f00000000, + 0x55fc453600000000, 0x9523cbf700000000, 0x9445296e00000000, + 0x549aa7af00000000, 0x926e5f3c00000000, 0x52b1d1fd00000000, + 0x53d7336400000000, 0x9308bda500000000, 0x101d868c00000000, + 0xd0c2084d00000000, 0xd1a4ead400000000, 0x117b641500000000, + 0x1c4b6a2800000000, 0xdc94e4e900000000, 0xddf2067000000000, + 0x1d2d88b100000000, 0x9e38b39800000000, 0x5ee73d5900000000, + 0x5f81dfc000000000, 0x9f5e510100000000, 0x59aaa99200000000, + 0x9975275300000000, 0x9813c5ca00000000, 0x58cc4b0b00000000, + 0xdbd9702200000000, 0x1b06fee300000000, 0x1a601c7a00000000, + 0xdabf92bb00000000, 0xef1948d600000000, 0x2fc6c61700000000, + 0x2ea0248e00000000, 0xee7faa4f00000000, 0x6d6a916600000000, + 0xadb51fa700000000, 0xacd3fd3e00000000, 0x6c0c73ff00000000, + 0xaaf88b6c00000000, 0x6a2705ad00000000, 0x6b41e73400000000, + 0xab9e69f500000000, 0x288b52dc00000000, 0xe854dc1d00000000, + 0xe9323e8400000000, 0x29edb04500000000, 0x24ddbe7800000000, + 0xe40230b900000000, 0xe564d22000000000, 0x25bb5ce100000000, + 0xa6ae67c800000000, 0x6671e90900000000, 0x67170b9000000000, + 0xa7c8855100000000, 0x613c7dc200000000, 0xa1e3f30300000000, + 0xa085119a00000000, 0x605a9f5b00000000, 0xe34fa47200000000, + 0x23902ab300000000, 0x22f6c82a00000000, 0xe22946eb00000000, + 0x3896d45000000000, 0xf8495a9100000000, 0xf92fb80800000000, + 0x39f036c900000000, 0xbae50de000000000, 0x7a3a832100000000, + 0x7b5c61b800000000, 0xbb83ef7900000000, 0x7d7717ea00000000, + 0xbda8992b00000000, 0xbcce7bb200000000, 0x7c11f57300000000, + 0xff04ce5a00000000, 0x3fdb409b00000000, 0x3ebda20200000000, + 0xfe622cc300000000, 0xf35222fe00000000, 0x338dac3f00000000, + 0x32eb4ea600000000, 0xf234c06700000000, 0x7121fb4e00000000, + 0xb1fe758f00000000, 0xb098971600000000, 0x704719d700000000, + 0xb6b3e14400000000, 0x766c6f8500000000, 0x770a8d1c00000000, + 0xb7d503dd00000000, 0x34c038f400000000, 0xf41fb63500000000, + 0xf57954ac00000000, 0x35a6da6d00000000, 0x9f35e17700000000, + 0x5fea6fb600000000, 0x5e8c8d2f00000000, 0x9e5303ee00000000, + 0x1d4638c700000000, 0xdd99b60600000000, 0xdcff549f00000000, + 0x1c20da5e00000000, 0xdad422cd00000000, 0x1a0bac0c00000000, + 0x1b6d4e9500000000, 0xdbb2c05400000000, 0x58a7fb7d00000000, + 0x987875bc00000000, 0x991e972500000000, 0x59c119e400000000, + 0x54f117d900000000, 0x942e991800000000, 0x95487b8100000000, + 0x5597f54000000000, 0xd682ce6900000000, 0x165d40a800000000, + 0x173ba23100000000, 0xd7e42cf000000000, 0x1110d46300000000, + 0xd1cf5aa200000000, 0xd0a9b83b00000000, 0x107636fa00000000, + 0x93630dd300000000, 0x53bc831200000000, 0x52da618b00000000, + 0x9205ef4a00000000, 0x48ba7df100000000, 0x8865f33000000000, + 0x890311a900000000, 0x49dc9f6800000000, 0xcac9a44100000000, + 0x0a162a8000000000, 0x0b70c81900000000, 0xcbaf46d800000000, + 0x0d5bbe4b00000000, 0xcd84308a00000000, 0xcce2d21300000000, + 0x0c3d5cd200000000, 0x8f2867fb00000000, 0x4ff7e93a00000000, + 0x4e910ba300000000, 0x8e4e856200000000, 0x837e8b5f00000000, + 0x43a1059e00000000, 0x42c7e70700000000, 0x821869c600000000, + 0x010d52ef00000000, 0xc1d2dc2e00000000, 0xc0b43eb700000000, + 0x006bb07600000000, 0xc69f48e500000000, 0x0640c62400000000, + 0x072624bd00000000, 0xc7f9aa7c00000000, 0x44ec915500000000, + 0x84331f9400000000, 0x8555fd0d00000000, 0x458a73cc00000000, + 0x702ca9a100000000, 0xb0f3276000000000, 0xb195c5f900000000, + 0x714a4b3800000000, 0xf25f701100000000, 0x3280fed000000000, + 0x33e61c4900000000, 0xf339928800000000, 0x35cd6a1b00000000, + 0xf512e4da00000000, 0xf474064300000000, 0x34ab888200000000, + 0xb7beb3ab00000000, 0x77613d6a00000000, 0x7607dff300000000, + 0xb6d8513200000000, 0xbbe85f0f00000000, 0x7b37d1ce00000000, + 0x7a51335700000000, 0xba8ebd9600000000, 0x399b86bf00000000, + 0xf944087e00000000, 0xf822eae700000000, 0x38fd642600000000, + 0xfe099cb500000000, 0x3ed6127400000000, 0x3fb0f0ed00000000, + 0xff6f7e2c00000000, 0x7c7a450500000000, 0xbca5cbc400000000, + 0xbdc3295d00000000, 0x7d1ca79c00000000, 0xa7a3352700000000, + 0x677cbbe600000000, 0x661a597f00000000, 0xa6c5d7be00000000, + 0x25d0ec9700000000, 0xe50f625600000000, 0xe46980cf00000000, + 0x24b60e0e00000000, 0xe242f69d00000000, 0x229d785c00000000, + 0x23fb9ac500000000, 0xe324140400000000, 0x60312f2d00000000, + 0xa0eea1ec00000000, 0xa188437500000000, 0x6157cdb400000000, + 0x6c67c38900000000, 0xacb84d4800000000, 0xaddeafd100000000, + 0x6d01211000000000, 0xee141a3900000000, 0x2ecb94f800000000, + 0x2fad766100000000, 0xef72f8a000000000, 0x2986003300000000, + 0xe9598ef200000000, 0xe83f6c6b00000000, 0x28e0e2aa00000000, + 0xabf5d98300000000, 0x6b2a574200000000, 0x6a4cb5db00000000, + 0xaa933b1a00000000}, + {0x0000000000000000, 0x6f4ca59b00000000, 0x9f9e3bec00000000, + 0xf0d29e7700000000, 0x7f3b060300000000, 0x1077a39800000000, + 0xe0a53def00000000, 0x8fe9987400000000, 0xfe760c0600000000, + 0x913aa99d00000000, 0x61e837ea00000000, 0x0ea4927100000000, + 0x814d0a0500000000, 0xee01af9e00000000, 0x1ed331e900000000, + 0x719f947200000000, 0xfced180c00000000, 0x93a1bd9700000000, + 0x637323e000000000, 0x0c3f867b00000000, 0x83d61e0f00000000, + 0xec9abb9400000000, 0x1c4825e300000000, 0x7304807800000000, + 0x029b140a00000000, 0x6dd7b19100000000, 0x9d052fe600000000, + 0xf2498a7d00000000, 0x7da0120900000000, 0x12ecb79200000000, + 0xe23e29e500000000, 0x8d728c7e00000000, 0xf8db311800000000, + 0x9797948300000000, 0x67450af400000000, 0x0809af6f00000000, + 0x87e0371b00000000, 0xe8ac928000000000, 0x187e0cf700000000, + 0x7732a96c00000000, 0x06ad3d1e00000000, 0x69e1988500000000, + 0x993306f200000000, 0xf67fa36900000000, 0x79963b1d00000000, + 0x16da9e8600000000, 0xe60800f100000000, 0x8944a56a00000000, + 0x0436291400000000, 0x6b7a8c8f00000000, 0x9ba812f800000000, + 0xf4e4b76300000000, 0x7b0d2f1700000000, 0x14418a8c00000000, + 0xe49314fb00000000, 0x8bdfb16000000000, 0xfa40251200000000, + 0x950c808900000000, 0x65de1efe00000000, 0x0a92bb6500000000, + 0x857b231100000000, 0xea37868a00000000, 0x1ae518fd00000000, + 0x75a9bd6600000000, 0xf0b7633000000000, 0x9ffbc6ab00000000, + 0x6f2958dc00000000, 0x0065fd4700000000, 0x8f8c653300000000, + 0xe0c0c0a800000000, 0x10125edf00000000, 0x7f5efb4400000000, + 0x0ec16f3600000000, 0x618dcaad00000000, 0x915f54da00000000, + 0xfe13f14100000000, 0x71fa693500000000, 0x1eb6ccae00000000, + 0xee6452d900000000, 0x8128f74200000000, 0x0c5a7b3c00000000, + 0x6316dea700000000, 0x93c440d000000000, 0xfc88e54b00000000, + 0x73617d3f00000000, 0x1c2dd8a400000000, 0xecff46d300000000, + 0x83b3e34800000000, 0xf22c773a00000000, 0x9d60d2a100000000, + 0x6db24cd600000000, 0x02fee94d00000000, 0x8d17713900000000, + 0xe25bd4a200000000, 0x12894ad500000000, 0x7dc5ef4e00000000, + 0x086c522800000000, 0x6720f7b300000000, 0x97f269c400000000, + 0xf8becc5f00000000, 0x7757542b00000000, 0x181bf1b000000000, + 0xe8c96fc700000000, 0x8785ca5c00000000, 0xf61a5e2e00000000, + 0x9956fbb500000000, 0x698465c200000000, 0x06c8c05900000000, + 0x8921582d00000000, 0xe66dfdb600000000, 0x16bf63c100000000, + 0x79f3c65a00000000, 0xf4814a2400000000, 0x9bcdefbf00000000, + 0x6b1f71c800000000, 0x0453d45300000000, 0x8bba4c2700000000, + 0xe4f6e9bc00000000, 0x142477cb00000000, 0x7b68d25000000000, + 0x0af7462200000000, 0x65bbe3b900000000, 0x95697dce00000000, + 0xfa25d85500000000, 0x75cc402100000000, 0x1a80e5ba00000000, + 0xea527bcd00000000, 0x851ede5600000000, 0xe06fc76000000000, + 0x8f2362fb00000000, 0x7ff1fc8c00000000, 0x10bd591700000000, + 0x9f54c16300000000, 0xf01864f800000000, 0x00cafa8f00000000, + 0x6f865f1400000000, 0x1e19cb6600000000, 0x71556efd00000000, + 0x8187f08a00000000, 0xeecb551100000000, 0x6122cd6500000000, + 0x0e6e68fe00000000, 0xfebcf68900000000, 0x91f0531200000000, + 0x1c82df6c00000000, 0x73ce7af700000000, 0x831ce48000000000, + 0xec50411b00000000, 0x63b9d96f00000000, 0x0cf57cf400000000, + 0xfc27e28300000000, 0x936b471800000000, 0xe2f4d36a00000000, + 0x8db876f100000000, 0x7d6ae88600000000, 0x12264d1d00000000, + 0x9dcfd56900000000, 0xf28370f200000000, 0x0251ee8500000000, + 0x6d1d4b1e00000000, 0x18b4f67800000000, 0x77f853e300000000, + 0x872acd9400000000, 0xe866680f00000000, 0x678ff07b00000000, + 0x08c355e000000000, 0xf811cb9700000000, 0x975d6e0c00000000, + 0xe6c2fa7e00000000, 0x898e5fe500000000, 0x795cc19200000000, + 0x1610640900000000, 0x99f9fc7d00000000, 0xf6b559e600000000, + 0x0667c79100000000, 0x692b620a00000000, 0xe459ee7400000000, + 0x8b154bef00000000, 0x7bc7d59800000000, 0x148b700300000000, + 0x9b62e87700000000, 0xf42e4dec00000000, 0x04fcd39b00000000, + 0x6bb0760000000000, 0x1a2fe27200000000, 0x756347e900000000, + 0x85b1d99e00000000, 0xeafd7c0500000000, 0x6514e47100000000, + 0x0a5841ea00000000, 0xfa8adf9d00000000, 0x95c67a0600000000, + 0x10d8a45000000000, 0x7f9401cb00000000, 0x8f469fbc00000000, + 0xe00a3a2700000000, 0x6fe3a25300000000, 0x00af07c800000000, + 0xf07d99bf00000000, 0x9f313c2400000000, 0xeeaea85600000000, + 0x81e20dcd00000000, 0x713093ba00000000, 0x1e7c362100000000, + 0x9195ae5500000000, 0xfed90bce00000000, 0x0e0b95b900000000, + 0x6147302200000000, 0xec35bc5c00000000, 0x837919c700000000, + 0x73ab87b000000000, 0x1ce7222b00000000, 0x930eba5f00000000, + 0xfc421fc400000000, 0x0c9081b300000000, 0x63dc242800000000, + 0x1243b05a00000000, 0x7d0f15c100000000, 0x8ddd8bb600000000, + 0xe2912e2d00000000, 0x6d78b65900000000, 0x023413c200000000, + 0xf2e68db500000000, 0x9daa282e00000000, 0xe803954800000000, + 0x874f30d300000000, 0x779daea400000000, 0x18d10b3f00000000, + 0x9738934b00000000, 0xf87436d000000000, 0x08a6a8a700000000, + 0x67ea0d3c00000000, 0x1675994e00000000, 0x79393cd500000000, + 0x89eba2a200000000, 0xe6a7073900000000, 0x694e9f4d00000000, + 0x06023ad600000000, 0xf6d0a4a100000000, 0x999c013a00000000, + 0x14ee8d4400000000, 0x7ba228df00000000, 0x8b70b6a800000000, + 0xe43c133300000000, 0x6bd58b4700000000, 0x04992edc00000000, + 0xf44bb0ab00000000, 0x9b07153000000000, 0xea98814200000000, + 0x85d424d900000000, 0x7506baae00000000, 0x1a4a1f3500000000, + 0x95a3874100000000, 0xfaef22da00000000, 0x0a3dbcad00000000, + 0x6571193600000000}, + {0x0000000000000000, 0x85d996dd00000000, 0x4bb55c6000000000, + 0xce6ccabd00000000, 0x966ab9c000000000, 0x13b32f1d00000000, + 0xdddfe5a000000000, 0x5806737d00000000, 0x6dd3035a00000000, + 0xe80a958700000000, 0x26665f3a00000000, 0xa3bfc9e700000000, + 0xfbb9ba9a00000000, 0x7e602c4700000000, 0xb00ce6fa00000000, + 0x35d5702700000000, 0xdaa607b400000000, 0x5f7f916900000000, + 0x91135bd400000000, 0x14cacd0900000000, 0x4cccbe7400000000, + 0xc91528a900000000, 0x0779e21400000000, 0x82a074c900000000, + 0xb77504ee00000000, 0x32ac923300000000, 0xfcc0588e00000000, + 0x7919ce5300000000, 0x211fbd2e00000000, 0xa4c62bf300000000, + 0x6aaae14e00000000, 0xef73779300000000, 0xf54b7eb300000000, + 0x7092e86e00000000, 0xbefe22d300000000, 0x3b27b40e00000000, + 0x6321c77300000000, 0xe6f851ae00000000, 0x28949b1300000000, + 0xad4d0dce00000000, 0x98987de900000000, 0x1d41eb3400000000, + 0xd32d218900000000, 0x56f4b75400000000, 0x0ef2c42900000000, + 0x8b2b52f400000000, 0x4547984900000000, 0xc09e0e9400000000, + 0x2fed790700000000, 0xaa34efda00000000, 0x6458256700000000, + 0xe181b3ba00000000, 0xb987c0c700000000, 0x3c5e561a00000000, + 0xf2329ca700000000, 0x77eb0a7a00000000, 0x423e7a5d00000000, + 0xc7e7ec8000000000, 0x098b263d00000000, 0x8c52b0e000000000, + 0xd454c39d00000000, 0x518d554000000000, 0x9fe19ffd00000000, + 0x1a38092000000000, 0xab918dbd00000000, 0x2e481b6000000000, + 0xe024d1dd00000000, 0x65fd470000000000, 0x3dfb347d00000000, + 0xb822a2a000000000, 0x764e681d00000000, 0xf397fec000000000, + 0xc6428ee700000000, 0x439b183a00000000, 0x8df7d28700000000, + 0x082e445a00000000, 0x5028372700000000, 0xd5f1a1fa00000000, + 0x1b9d6b4700000000, 0x9e44fd9a00000000, 0x71378a0900000000, + 0xf4ee1cd400000000, 0x3a82d66900000000, 0xbf5b40b400000000, + 0xe75d33c900000000, 0x6284a51400000000, 0xace86fa900000000, + 0x2931f97400000000, 0x1ce4895300000000, 0x993d1f8e00000000, + 0x5751d53300000000, 0xd28843ee00000000, 0x8a8e309300000000, + 0x0f57a64e00000000, 0xc13b6cf300000000, 0x44e2fa2e00000000, + 0x5edaf30e00000000, 0xdb0365d300000000, 0x156faf6e00000000, + 0x90b639b300000000, 0xc8b04ace00000000, 0x4d69dc1300000000, + 0x830516ae00000000, 0x06dc807300000000, 0x3309f05400000000, + 0xb6d0668900000000, 0x78bcac3400000000, 0xfd653ae900000000, + 0xa563499400000000, 0x20badf4900000000, 0xeed615f400000000, + 0x6b0f832900000000, 0x847cf4ba00000000, 0x01a5626700000000, + 0xcfc9a8da00000000, 0x4a103e0700000000, 0x12164d7a00000000, + 0x97cfdba700000000, 0x59a3111a00000000, 0xdc7a87c700000000, + 0xe9aff7e000000000, 0x6c76613d00000000, 0xa21aab8000000000, + 0x27c33d5d00000000, 0x7fc54e2000000000, 0xfa1cd8fd00000000, + 0x3470124000000000, 0xb1a9849d00000000, 0x17256aa000000000, + 0x92fcfc7d00000000, 0x5c9036c000000000, 0xd949a01d00000000, + 0x814fd36000000000, 0x049645bd00000000, 0xcafa8f0000000000, + 0x4f2319dd00000000, 0x7af669fa00000000, 0xff2fff2700000000, + 0x3143359a00000000, 0xb49aa34700000000, 0xec9cd03a00000000, + 0x694546e700000000, 0xa7298c5a00000000, 0x22f01a8700000000, + 0xcd836d1400000000, 0x485afbc900000000, 0x8636317400000000, + 0x03efa7a900000000, 0x5be9d4d400000000, 0xde30420900000000, + 0x105c88b400000000, 0x95851e6900000000, 0xa0506e4e00000000, + 0x2589f89300000000, 0xebe5322e00000000, 0x6e3ca4f300000000, + 0x363ad78e00000000, 0xb3e3415300000000, 0x7d8f8bee00000000, + 0xf8561d3300000000, 0xe26e141300000000, 0x67b782ce00000000, + 0xa9db487300000000, 0x2c02deae00000000, 0x7404add300000000, + 0xf1dd3b0e00000000, 0x3fb1f1b300000000, 0xba68676e00000000, + 0x8fbd174900000000, 0x0a64819400000000, 0xc4084b2900000000, + 0x41d1ddf400000000, 0x19d7ae8900000000, 0x9c0e385400000000, + 0x5262f2e900000000, 0xd7bb643400000000, 0x38c813a700000000, + 0xbd11857a00000000, 0x737d4fc700000000, 0xf6a4d91a00000000, + 0xaea2aa6700000000, 0x2b7b3cba00000000, 0xe517f60700000000, + 0x60ce60da00000000, 0x551b10fd00000000, 0xd0c2862000000000, + 0x1eae4c9d00000000, 0x9b77da4000000000, 0xc371a93d00000000, + 0x46a83fe000000000, 0x88c4f55d00000000, 0x0d1d638000000000, + 0xbcb4e71d00000000, 0x396d71c000000000, 0xf701bb7d00000000, + 0x72d82da000000000, 0x2ade5edd00000000, 0xaf07c80000000000, + 0x616b02bd00000000, 0xe4b2946000000000, 0xd167e44700000000, + 0x54be729a00000000, 0x9ad2b82700000000, 0x1f0b2efa00000000, + 0x470d5d8700000000, 0xc2d4cb5a00000000, 0x0cb801e700000000, + 0x8961973a00000000, 0x6612e0a900000000, 0xe3cb767400000000, + 0x2da7bcc900000000, 0xa87e2a1400000000, 0xf078596900000000, + 0x75a1cfb400000000, 0xbbcd050900000000, 0x3e1493d400000000, + 0x0bc1e3f300000000, 0x8e18752e00000000, 0x4074bf9300000000, + 0xc5ad294e00000000, 0x9dab5a3300000000, 0x1872ccee00000000, + 0xd61e065300000000, 0x53c7908e00000000, 0x49ff99ae00000000, + 0xcc260f7300000000, 0x024ac5ce00000000, 0x8793531300000000, + 0xdf95206e00000000, 0x5a4cb6b300000000, 0x94207c0e00000000, + 0x11f9ead300000000, 0x242c9af400000000, 0xa1f50c2900000000, + 0x6f99c69400000000, 0xea40504900000000, 0xb246233400000000, + 0x379fb5e900000000, 0xf9f37f5400000000, 0x7c2ae98900000000, + 0x93599e1a00000000, 0x168008c700000000, 0xd8ecc27a00000000, + 0x5d3554a700000000, 0x053327da00000000, 0x80eab10700000000, + 0x4e867bba00000000, 0xcb5fed6700000000, 0xfe8a9d4000000000, + 0x7b530b9d00000000, 0xb53fc12000000000, 0x30e657fd00000000, + 0x68e0248000000000, 0xed39b25d00000000, 0x235578e000000000, + 0xa68cee3d00000000}, + {0x0000000000000000, 0x76e10f9d00000000, 0xadc46ee100000000, + 0xdb25617c00000000, 0x1b8fac1900000000, 0x6d6ea38400000000, + 0xb64bc2f800000000, 0xc0aacd6500000000, 0x361e593300000000, + 0x40ff56ae00000000, 0x9bda37d200000000, 0xed3b384f00000000, + 0x2d91f52a00000000, 0x5b70fab700000000, 0x80559bcb00000000, + 0xf6b4945600000000, 0x6c3cb26600000000, 0x1addbdfb00000000, + 0xc1f8dc8700000000, 0xb719d31a00000000, 0x77b31e7f00000000, + 0x015211e200000000, 0xda77709e00000000, 0xac967f0300000000, + 0x5a22eb5500000000, 0x2cc3e4c800000000, 0xf7e685b400000000, + 0x81078a2900000000, 0x41ad474c00000000, 0x374c48d100000000, + 0xec6929ad00000000, 0x9a88263000000000, 0xd87864cd00000000, + 0xae996b5000000000, 0x75bc0a2c00000000, 0x035d05b100000000, + 0xc3f7c8d400000000, 0xb516c74900000000, 0x6e33a63500000000, + 0x18d2a9a800000000, 0xee663dfe00000000, 0x9887326300000000, + 0x43a2531f00000000, 0x35435c8200000000, 0xf5e991e700000000, + 0x83089e7a00000000, 0x582dff0600000000, 0x2eccf09b00000000, + 0xb444d6ab00000000, 0xc2a5d93600000000, 0x1980b84a00000000, + 0x6f61b7d700000000, 0xafcb7ab200000000, 0xd92a752f00000000, + 0x020f145300000000, 0x74ee1bce00000000, 0x825a8f9800000000, + 0xf4bb800500000000, 0x2f9ee17900000000, 0x597feee400000000, + 0x99d5238100000000, 0xef342c1c00000000, 0x34114d6000000000, + 0x42f042fd00000000, 0xf1f7b94100000000, 0x8716b6dc00000000, + 0x5c33d7a000000000, 0x2ad2d83d00000000, 0xea78155800000000, + 0x9c991ac500000000, 0x47bc7bb900000000, 0x315d742400000000, + 0xc7e9e07200000000, 0xb108efef00000000, 0x6a2d8e9300000000, + 0x1ccc810e00000000, 0xdc664c6b00000000, 0xaa8743f600000000, + 0x71a2228a00000000, 0x07432d1700000000, 0x9dcb0b2700000000, + 0xeb2a04ba00000000, 0x300f65c600000000, 0x46ee6a5b00000000, + 0x8644a73e00000000, 0xf0a5a8a300000000, 0x2b80c9df00000000, + 0x5d61c64200000000, 0xabd5521400000000, 0xdd345d8900000000, + 0x06113cf500000000, 0x70f0336800000000, 0xb05afe0d00000000, + 0xc6bbf19000000000, 0x1d9e90ec00000000, 0x6b7f9f7100000000, + 0x298fdd8c00000000, 0x5f6ed21100000000, 0x844bb36d00000000, + 0xf2aabcf000000000, 0x3200719500000000, 0x44e17e0800000000, + 0x9fc41f7400000000, 0xe92510e900000000, 0x1f9184bf00000000, + 0x69708b2200000000, 0xb255ea5e00000000, 0xc4b4e5c300000000, + 0x041e28a600000000, 0x72ff273b00000000, 0xa9da464700000000, + 0xdf3b49da00000000, 0x45b36fea00000000, 0x3352607700000000, + 0xe877010b00000000, 0x9e960e9600000000, 0x5e3cc3f300000000, + 0x28ddcc6e00000000, 0xf3f8ad1200000000, 0x8519a28f00000000, + 0x73ad36d900000000, 0x054c394400000000, 0xde69583800000000, + 0xa88857a500000000, 0x68229ac000000000, 0x1ec3955d00000000, + 0xc5e6f42100000000, 0xb307fbbc00000000, 0xe2ef738300000000, + 0x940e7c1e00000000, 0x4f2b1d6200000000, 0x39ca12ff00000000, + 0xf960df9a00000000, 0x8f81d00700000000, 0x54a4b17b00000000, + 0x2245bee600000000, 0xd4f12ab000000000, 0xa210252d00000000, + 0x7935445100000000, 0x0fd44bcc00000000, 0xcf7e86a900000000, + 0xb99f893400000000, 0x62bae84800000000, 0x145be7d500000000, + 0x8ed3c1e500000000, 0xf832ce7800000000, 0x2317af0400000000, + 0x55f6a09900000000, 0x955c6dfc00000000, 0xe3bd626100000000, + 0x3898031d00000000, 0x4e790c8000000000, 0xb8cd98d600000000, + 0xce2c974b00000000, 0x1509f63700000000, 0x63e8f9aa00000000, + 0xa34234cf00000000, 0xd5a33b5200000000, 0x0e865a2e00000000, + 0x786755b300000000, 0x3a97174e00000000, 0x4c7618d300000000, + 0x975379af00000000, 0xe1b2763200000000, 0x2118bb5700000000, + 0x57f9b4ca00000000, 0x8cdcd5b600000000, 0xfa3dda2b00000000, + 0x0c894e7d00000000, 0x7a6841e000000000, 0xa14d209c00000000, + 0xd7ac2f0100000000, 0x1706e26400000000, 0x61e7edf900000000, + 0xbac28c8500000000, 0xcc23831800000000, 0x56aba52800000000, + 0x204aaab500000000, 0xfb6fcbc900000000, 0x8d8ec45400000000, + 0x4d24093100000000, 0x3bc506ac00000000, 0xe0e067d000000000, + 0x9601684d00000000, 0x60b5fc1b00000000, 0x1654f38600000000, + 0xcd7192fa00000000, 0xbb909d6700000000, 0x7b3a500200000000, + 0x0ddb5f9f00000000, 0xd6fe3ee300000000, 0xa01f317e00000000, + 0x1318cac200000000, 0x65f9c55f00000000, 0xbedca42300000000, + 0xc83dabbe00000000, 0x089766db00000000, 0x7e76694600000000, + 0xa553083a00000000, 0xd3b207a700000000, 0x250693f100000000, + 0x53e79c6c00000000, 0x88c2fd1000000000, 0xfe23f28d00000000, + 0x3e893fe800000000, 0x4868307500000000, 0x934d510900000000, + 0xe5ac5e9400000000, 0x7f2478a400000000, 0x09c5773900000000, + 0xd2e0164500000000, 0xa40119d800000000, 0x64abd4bd00000000, + 0x124adb2000000000, 0xc96fba5c00000000, 0xbf8eb5c100000000, + 0x493a219700000000, 0x3fdb2e0a00000000, 0xe4fe4f7600000000, + 0x921f40eb00000000, 0x52b58d8e00000000, 0x2454821300000000, + 0xff71e36f00000000, 0x8990ecf200000000, 0xcb60ae0f00000000, + 0xbd81a19200000000, 0x66a4c0ee00000000, 0x1045cf7300000000, + 0xd0ef021600000000, 0xa60e0d8b00000000, 0x7d2b6cf700000000, + 0x0bca636a00000000, 0xfd7ef73c00000000, 0x8b9ff8a100000000, + 0x50ba99dd00000000, 0x265b964000000000, 0xe6f15b2500000000, + 0x901054b800000000, 0x4b3535c400000000, 0x3dd43a5900000000, + 0xa75c1c6900000000, 0xd1bd13f400000000, 0x0a98728800000000, + 0x7c797d1500000000, 0xbcd3b07000000000, 0xca32bfed00000000, + 0x1117de9100000000, 0x67f6d10c00000000, 0x9142455a00000000, + 0xe7a34ac700000000, 0x3c862bbb00000000, 0x4a67242600000000, + 0x8acde94300000000, 0xfc2ce6de00000000, 0x270987a200000000, + 0x51e8883f00000000}, + {0x0000000000000000, 0xe8dbfbb900000000, 0x91b186a800000000, + 0x796a7d1100000000, 0x63657c8a00000000, 0x8bbe873300000000, + 0xf2d4fa2200000000, 0x1a0f019b00000000, 0x87cc89cf00000000, + 0x6f17727600000000, 0x167d0f6700000000, 0xfea6f4de00000000, + 0xe4a9f54500000000, 0x0c720efc00000000, 0x751873ed00000000, + 0x9dc3885400000000, 0x4f9f624400000000, 0xa74499fd00000000, + 0xde2ee4ec00000000, 0x36f51f5500000000, 0x2cfa1ece00000000, + 0xc421e57700000000, 0xbd4b986600000000, 0x559063df00000000, + 0xc853eb8b00000000, 0x2088103200000000, 0x59e26d2300000000, + 0xb139969a00000000, 0xab36970100000000, 0x43ed6cb800000000, + 0x3a8711a900000000, 0xd25cea1000000000, 0x9e3ec58800000000, + 0x76e53e3100000000, 0x0f8f432000000000, 0xe754b89900000000, + 0xfd5bb90200000000, 0x158042bb00000000, 0x6cea3faa00000000, + 0x8431c41300000000, 0x19f24c4700000000, 0xf129b7fe00000000, + 0x8843caef00000000, 0x6098315600000000, 0x7a9730cd00000000, + 0x924ccb7400000000, 0xeb26b66500000000, 0x03fd4ddc00000000, + 0xd1a1a7cc00000000, 0x397a5c7500000000, 0x4010216400000000, + 0xa8cbdadd00000000, 0xb2c4db4600000000, 0x5a1f20ff00000000, + 0x23755dee00000000, 0xcbaea65700000000, 0x566d2e0300000000, + 0xbeb6d5ba00000000, 0xc7dca8ab00000000, 0x2f07531200000000, + 0x3508528900000000, 0xddd3a93000000000, 0xa4b9d42100000000, + 0x4c622f9800000000, 0x7d7bfbca00000000, 0x95a0007300000000, + 0xecca7d6200000000, 0x041186db00000000, 0x1e1e874000000000, + 0xf6c57cf900000000, 0x8faf01e800000000, 0x6774fa5100000000, + 0xfab7720500000000, 0x126c89bc00000000, 0x6b06f4ad00000000, + 0x83dd0f1400000000, 0x99d20e8f00000000, 0x7109f53600000000, + 0x0863882700000000, 0xe0b8739e00000000, 0x32e4998e00000000, + 0xda3f623700000000, 0xa3551f2600000000, 0x4b8ee49f00000000, + 0x5181e50400000000, 0xb95a1ebd00000000, 0xc03063ac00000000, + 0x28eb981500000000, 0xb528104100000000, 0x5df3ebf800000000, + 0x249996e900000000, 0xcc426d5000000000, 0xd64d6ccb00000000, + 0x3e96977200000000, 0x47fcea6300000000, 0xaf2711da00000000, + 0xe3453e4200000000, 0x0b9ec5fb00000000, 0x72f4b8ea00000000, + 0x9a2f435300000000, 0x802042c800000000, 0x68fbb97100000000, + 0x1191c46000000000, 0xf94a3fd900000000, 0x6489b78d00000000, + 0x8c524c3400000000, 0xf538312500000000, 0x1de3ca9c00000000, + 0x07eccb0700000000, 0xef3730be00000000, 0x965d4daf00000000, + 0x7e86b61600000000, 0xacda5c0600000000, 0x4401a7bf00000000, + 0x3d6bdaae00000000, 0xd5b0211700000000, 0xcfbf208c00000000, + 0x2764db3500000000, 0x5e0ea62400000000, 0xb6d55d9d00000000, + 0x2b16d5c900000000, 0xc3cd2e7000000000, 0xbaa7536100000000, + 0x527ca8d800000000, 0x4873a94300000000, 0xa0a852fa00000000, + 0xd9c22feb00000000, 0x3119d45200000000, 0xbbf0874e00000000, + 0x532b7cf700000000, 0x2a4101e600000000, 0xc29afa5f00000000, + 0xd895fbc400000000, 0x304e007d00000000, 0x49247d6c00000000, + 0xa1ff86d500000000, 0x3c3c0e8100000000, 0xd4e7f53800000000, + 0xad8d882900000000, 0x4556739000000000, 0x5f59720b00000000, + 0xb78289b200000000, 0xcee8f4a300000000, 0x26330f1a00000000, + 0xf46fe50a00000000, 0x1cb41eb300000000, 0x65de63a200000000, + 0x8d05981b00000000, 0x970a998000000000, 0x7fd1623900000000, + 0x06bb1f2800000000, 0xee60e49100000000, 0x73a36cc500000000, + 0x9b78977c00000000, 0xe212ea6d00000000, 0x0ac911d400000000, + 0x10c6104f00000000, 0xf81debf600000000, 0x817796e700000000, + 0x69ac6d5e00000000, 0x25ce42c600000000, 0xcd15b97f00000000, + 0xb47fc46e00000000, 0x5ca43fd700000000, 0x46ab3e4c00000000, + 0xae70c5f500000000, 0xd71ab8e400000000, 0x3fc1435d00000000, + 0xa202cb0900000000, 0x4ad930b000000000, 0x33b34da100000000, + 0xdb68b61800000000, 0xc167b78300000000, 0x29bc4c3a00000000, + 0x50d6312b00000000, 0xb80dca9200000000, 0x6a51208200000000, + 0x828adb3b00000000, 0xfbe0a62a00000000, 0x133b5d9300000000, + 0x09345c0800000000, 0xe1efa7b100000000, 0x9885daa000000000, + 0x705e211900000000, 0xed9da94d00000000, 0x054652f400000000, + 0x7c2c2fe500000000, 0x94f7d45c00000000, 0x8ef8d5c700000000, + 0x66232e7e00000000, 0x1f49536f00000000, 0xf792a8d600000000, + 0xc68b7c8400000000, 0x2e50873d00000000, 0x573afa2c00000000, + 0xbfe1019500000000, 0xa5ee000e00000000, 0x4d35fbb700000000, + 0x345f86a600000000, 0xdc847d1f00000000, 0x4147f54b00000000, + 0xa99c0ef200000000, 0xd0f673e300000000, 0x382d885a00000000, + 0x222289c100000000, 0xcaf9727800000000, 0xb3930f6900000000, + 0x5b48f4d000000000, 0x89141ec000000000, 0x61cfe57900000000, + 0x18a5986800000000, 0xf07e63d100000000, 0xea71624a00000000, + 0x02aa99f300000000, 0x7bc0e4e200000000, 0x931b1f5b00000000, + 0x0ed8970f00000000, 0xe6036cb600000000, 0x9f6911a700000000, + 0x77b2ea1e00000000, 0x6dbdeb8500000000, 0x8566103c00000000, + 0xfc0c6d2d00000000, 0x14d7969400000000, 0x58b5b90c00000000, + 0xb06e42b500000000, 0xc9043fa400000000, 0x21dfc41d00000000, + 0x3bd0c58600000000, 0xd30b3e3f00000000, 0xaa61432e00000000, + 0x42bab89700000000, 0xdf7930c300000000, 0x37a2cb7a00000000, + 0x4ec8b66b00000000, 0xa6134dd200000000, 0xbc1c4c4900000000, + 0x54c7b7f000000000, 0x2dadcae100000000, 0xc576315800000000, + 0x172adb4800000000, 0xfff120f100000000, 0x869b5de000000000, + 0x6e40a65900000000, 0x744fa7c200000000, 0x9c945c7b00000000, + 0xe5fe216a00000000, 0x0d25dad300000000, 0x90e6528700000000, + 0x783da93e00000000, 0x0157d42f00000000, 0xe98c2f9600000000, + 0xf3832e0d00000000, 0x1b58d5b400000000, 0x6232a8a500000000, + 0x8ae9531c00000000}, + {0x0000000000000000, 0x919168ae00000000, 0x6325a08700000000, + 0xf2b4c82900000000, 0x874c31d400000000, 0x16dd597a00000000, + 0xe469915300000000, 0x75f8f9fd00000000, 0x4f9f137300000000, + 0xde0e7bdd00000000, 0x2cbab3f400000000, 0xbd2bdb5a00000000, + 0xc8d322a700000000, 0x59424a0900000000, 0xabf6822000000000, + 0x3a67ea8e00000000, 0x9e3e27e600000000, 0x0faf4f4800000000, + 0xfd1b876100000000, 0x6c8aefcf00000000, 0x1972163200000000, + 0x88e37e9c00000000, 0x7a57b6b500000000, 0xebc6de1b00000000, + 0xd1a1349500000000, 0x40305c3b00000000, 0xb284941200000000, + 0x2315fcbc00000000, 0x56ed054100000000, 0xc77c6def00000000, + 0x35c8a5c600000000, 0xa459cd6800000000, 0x7d7b3f1700000000, + 0xecea57b900000000, 0x1e5e9f9000000000, 0x8fcff73e00000000, + 0xfa370ec300000000, 0x6ba6666d00000000, 0x9912ae4400000000, + 0x0883c6ea00000000, 0x32e42c6400000000, 0xa37544ca00000000, + 0x51c18ce300000000, 0xc050e44d00000000, 0xb5a81db000000000, + 0x2439751e00000000, 0xd68dbd3700000000, 0x471cd59900000000, + 0xe34518f100000000, 0x72d4705f00000000, 0x8060b87600000000, + 0x11f1d0d800000000, 0x6409292500000000, 0xf598418b00000000, + 0x072c89a200000000, 0x96bde10c00000000, 0xacda0b8200000000, + 0x3d4b632c00000000, 0xcfffab0500000000, 0x5e6ec3ab00000000, + 0x2b963a5600000000, 0xba0752f800000000, 0x48b39ad100000000, + 0xd922f27f00000000, 0xfaf67e2e00000000, 0x6b67168000000000, + 0x99d3dea900000000, 0x0842b60700000000, 0x7dba4ffa00000000, + 0xec2b275400000000, 0x1e9fef7d00000000, 0x8f0e87d300000000, + 0xb5696d5d00000000, 0x24f805f300000000, 0xd64ccdda00000000, + 0x47dda57400000000, 0x32255c8900000000, 0xa3b4342700000000, + 0x5100fc0e00000000, 0xc09194a000000000, 0x64c859c800000000, + 0xf559316600000000, 0x07edf94f00000000, 0x967c91e100000000, + 0xe384681c00000000, 0x721500b200000000, 0x80a1c89b00000000, + 0x1130a03500000000, 0x2b574abb00000000, 0xbac6221500000000, + 0x4872ea3c00000000, 0xd9e3829200000000, 0xac1b7b6f00000000, + 0x3d8a13c100000000, 0xcf3edbe800000000, 0x5eafb34600000000, + 0x878d413900000000, 0x161c299700000000, 0xe4a8e1be00000000, + 0x7539891000000000, 0x00c170ed00000000, 0x9150184300000000, + 0x63e4d06a00000000, 0xf275b8c400000000, 0xc812524a00000000, + 0x59833ae400000000, 0xab37f2cd00000000, 0x3aa69a6300000000, + 0x4f5e639e00000000, 0xdecf0b3000000000, 0x2c7bc31900000000, + 0xbdeaabb700000000, 0x19b366df00000000, 0x88220e7100000000, + 0x7a96c65800000000, 0xeb07aef600000000, 0x9eff570b00000000, + 0x0f6e3fa500000000, 0xfddaf78c00000000, 0x6c4b9f2200000000, + 0x562c75ac00000000, 0xc7bd1d0200000000, 0x3509d52b00000000, + 0xa498bd8500000000, 0xd160447800000000, 0x40f12cd600000000, + 0xb245e4ff00000000, 0x23d48c5100000000, 0xf4edfd5c00000000, + 0x657c95f200000000, 0x97c85ddb00000000, 0x0659357500000000, + 0x73a1cc8800000000, 0xe230a42600000000, 0x10846c0f00000000, + 0x811504a100000000, 0xbb72ee2f00000000, 0x2ae3868100000000, + 0xd8574ea800000000, 0x49c6260600000000, 0x3c3edffb00000000, + 0xadafb75500000000, 0x5f1b7f7c00000000, 0xce8a17d200000000, + 0x6ad3daba00000000, 0xfb42b21400000000, 0x09f67a3d00000000, + 0x9867129300000000, 0xed9feb6e00000000, 0x7c0e83c000000000, + 0x8eba4be900000000, 0x1f2b234700000000, 0x254cc9c900000000, + 0xb4dda16700000000, 0x4669694e00000000, 0xd7f801e000000000, + 0xa200f81d00000000, 0x339190b300000000, 0xc125589a00000000, + 0x50b4303400000000, 0x8996c24b00000000, 0x1807aae500000000, + 0xeab362cc00000000, 0x7b220a6200000000, 0x0edaf39f00000000, + 0x9f4b9b3100000000, 0x6dff531800000000, 0xfc6e3bb600000000, + 0xc609d13800000000, 0x5798b99600000000, 0xa52c71bf00000000, + 0x34bd191100000000, 0x4145e0ec00000000, 0xd0d4884200000000, + 0x2260406b00000000, 0xb3f128c500000000, 0x17a8e5ad00000000, + 0x86398d0300000000, 0x748d452a00000000, 0xe51c2d8400000000, + 0x90e4d47900000000, 0x0175bcd700000000, 0xf3c174fe00000000, + 0x62501c5000000000, 0x5837f6de00000000, 0xc9a69e7000000000, + 0x3b12565900000000, 0xaa833ef700000000, 0xdf7bc70a00000000, + 0x4eeaafa400000000, 0xbc5e678d00000000, 0x2dcf0f2300000000, + 0x0e1b837200000000, 0x9f8aebdc00000000, 0x6d3e23f500000000, + 0xfcaf4b5b00000000, 0x8957b2a600000000, 0x18c6da0800000000, + 0xea72122100000000, 0x7be37a8f00000000, 0x4184900100000000, + 0xd015f8af00000000, 0x22a1308600000000, 0xb330582800000000, + 0xc6c8a1d500000000, 0x5759c97b00000000, 0xa5ed015200000000, + 0x347c69fc00000000, 0x9025a49400000000, 0x01b4cc3a00000000, + 0xf300041300000000, 0x62916cbd00000000, 0x1769954000000000, + 0x86f8fdee00000000, 0x744c35c700000000, 0xe5dd5d6900000000, + 0xdfbab7e700000000, 0x4e2bdf4900000000, 0xbc9f176000000000, + 0x2d0e7fce00000000, 0x58f6863300000000, 0xc967ee9d00000000, + 0x3bd326b400000000, 0xaa424e1a00000000, 0x7360bc6500000000, + 0xe2f1d4cb00000000, 0x10451ce200000000, 0x81d4744c00000000, + 0xf42c8db100000000, 0x65bde51f00000000, 0x97092d3600000000, + 0x0698459800000000, 0x3cffaf1600000000, 0xad6ec7b800000000, + 0x5fda0f9100000000, 0xce4b673f00000000, 0xbbb39ec200000000, + 0x2a22f66c00000000, 0xd8963e4500000000, 0x490756eb00000000, + 0xed5e9b8300000000, 0x7ccff32d00000000, 0x8e7b3b0400000000, + 0x1fea53aa00000000, 0x6a12aa5700000000, 0xfb83c2f900000000, + 0x09370ad000000000, 0x98a6627e00000000, 0xa2c188f000000000, + 0x3350e05e00000000, 0xc1e4287700000000, 0x507540d900000000, + 0x258db92400000000, 0xb41cd18a00000000, 0x46a819a300000000, + 0xd739710d00000000}}; + +#else /* W == 4 */ + +local const z_crc_t FAR crc_braid_table[][256] = { + {0x00000000, 0xccaa009e, 0x4225077d, 0x8e8f07e3, 0x844a0efa, + 0x48e00e64, 0xc66f0987, 0x0ac50919, 0xd3e51bb5, 0x1f4f1b2b, + 0x91c01cc8, 0x5d6a1c56, 0x57af154f, 0x9b0515d1, 0x158a1232, + 0xd92012ac, 0x7cbb312b, 0xb01131b5, 0x3e9e3656, 0xf23436c8, + 0xf8f13fd1, 0x345b3f4f, 0xbad438ac, 0x767e3832, 0xaf5e2a9e, + 0x63f42a00, 0xed7b2de3, 0x21d12d7d, 0x2b142464, 0xe7be24fa, + 0x69312319, 0xa59b2387, 0xf9766256, 0x35dc62c8, 0xbb53652b, + 0x77f965b5, 0x7d3c6cac, 0xb1966c32, 0x3f196bd1, 0xf3b36b4f, + 0x2a9379e3, 0xe639797d, 0x68b67e9e, 0xa41c7e00, 0xaed97719, + 0x62737787, 0xecfc7064, 0x205670fa, 0x85cd537d, 0x496753e3, + 0xc7e85400, 0x0b42549e, 0x01875d87, 0xcd2d5d19, 0x43a25afa, + 0x8f085a64, 0x562848c8, 0x9a824856, 0x140d4fb5, 0xd8a74f2b, + 0xd2624632, 0x1ec846ac, 0x9047414f, 0x5ced41d1, 0x299dc2ed, + 0xe537c273, 0x6bb8c590, 0xa712c50e, 0xadd7cc17, 0x617dcc89, + 0xeff2cb6a, 0x2358cbf4, 0xfa78d958, 0x36d2d9c6, 0xb85dde25, + 0x74f7debb, 0x7e32d7a2, 0xb298d73c, 0x3c17d0df, 0xf0bdd041, + 0x5526f3c6, 0x998cf358, 0x1703f4bb, 0xdba9f425, 0xd16cfd3c, + 0x1dc6fda2, 0x9349fa41, 0x5fe3fadf, 0x86c3e873, 0x4a69e8ed, + 0xc4e6ef0e, 0x084cef90, 0x0289e689, 0xce23e617, 0x40ace1f4, + 0x8c06e16a, 0xd0eba0bb, 0x1c41a025, 0x92cea7c6, 0x5e64a758, + 0x54a1ae41, 0x980baedf, 0x1684a93c, 0xda2ea9a2, 0x030ebb0e, + 0xcfa4bb90, 0x412bbc73, 0x8d81bced, 0x8744b5f4, 0x4beeb56a, + 0xc561b289, 0x09cbb217, 0xac509190, 0x60fa910e, 0xee7596ed, + 0x22df9673, 0x281a9f6a, 0xe4b09ff4, 0x6a3f9817, 0xa6959889, + 0x7fb58a25, 0xb31f8abb, 0x3d908d58, 0xf13a8dc6, 0xfbff84df, + 0x37558441, 0xb9da83a2, 0x7570833c, 0x533b85da, 0x9f918544, + 0x111e82a7, 0xddb48239, 0xd7718b20, 0x1bdb8bbe, 0x95548c5d, + 0x59fe8cc3, 0x80de9e6f, 0x4c749ef1, 0xc2fb9912, 0x0e51998c, + 0x04949095, 0xc83e900b, 0x46b197e8, 0x8a1b9776, 0x2f80b4f1, + 0xe32ab46f, 0x6da5b38c, 0xa10fb312, 0xabcaba0b, 0x6760ba95, + 0xe9efbd76, 0x2545bde8, 0xfc65af44, 0x30cfafda, 0xbe40a839, + 0x72eaa8a7, 0x782fa1be, 0xb485a120, 0x3a0aa6c3, 0xf6a0a65d, + 0xaa4de78c, 0x66e7e712, 0xe868e0f1, 0x24c2e06f, 0x2e07e976, + 0xe2ade9e8, 0x6c22ee0b, 0xa088ee95, 0x79a8fc39, 0xb502fca7, + 0x3b8dfb44, 0xf727fbda, 0xfde2f2c3, 0x3148f25d, 0xbfc7f5be, + 0x736df520, 0xd6f6d6a7, 0x1a5cd639, 0x94d3d1da, 0x5879d144, + 0x52bcd85d, 0x9e16d8c3, 0x1099df20, 0xdc33dfbe, 0x0513cd12, + 0xc9b9cd8c, 0x4736ca6f, 0x8b9ccaf1, 0x8159c3e8, 0x4df3c376, + 0xc37cc495, 0x0fd6c40b, 0x7aa64737, 0xb60c47a9, 0x3883404a, + 0xf42940d4, 0xfeec49cd, 0x32464953, 0xbcc94eb0, 0x70634e2e, + 0xa9435c82, 0x65e95c1c, 0xeb665bff, 0x27cc5b61, 0x2d095278, + 0xe1a352e6, 0x6f2c5505, 0xa386559b, 0x061d761c, 0xcab77682, + 0x44387161, 0x889271ff, 0x825778e6, 0x4efd7878, 0xc0727f9b, + 0x0cd87f05, 0xd5f86da9, 0x19526d37, 0x97dd6ad4, 0x5b776a4a, + 0x51b26353, 0x9d1863cd, 0x1397642e, 0xdf3d64b0, 0x83d02561, + 0x4f7a25ff, 0xc1f5221c, 0x0d5f2282, 0x079a2b9b, 0xcb302b05, + 0x45bf2ce6, 0x89152c78, 0x50353ed4, 0x9c9f3e4a, 0x121039a9, + 0xdeba3937, 0xd47f302e, 0x18d530b0, 0x965a3753, 0x5af037cd, + 0xff6b144a, 0x33c114d4, 0xbd4e1337, 0x71e413a9, 0x7b211ab0, + 0xb78b1a2e, 0x39041dcd, 0xf5ae1d53, 0x2c8e0fff, 0xe0240f61, + 0x6eab0882, 0xa201081c, 0xa8c40105, 0x646e019b, 0xeae10678, + 0x264b06e6}, + {0x00000000, 0xa6770bb4, 0x979f1129, 0x31e81a9d, 0xf44f2413, + 0x52382fa7, 0x63d0353a, 0xc5a73e8e, 0x33ef4e67, 0x959845d3, + 0xa4705f4e, 0x020754fa, 0xc7a06a74, 0x61d761c0, 0x503f7b5d, + 0xf64870e9, 0x67de9cce, 0xc1a9977a, 0xf0418de7, 0x56368653, + 0x9391b8dd, 0x35e6b369, 0x040ea9f4, 0xa279a240, 0x5431d2a9, + 0xf246d91d, 0xc3aec380, 0x65d9c834, 0xa07ef6ba, 0x0609fd0e, + 0x37e1e793, 0x9196ec27, 0xcfbd399c, 0x69ca3228, 0x582228b5, + 0xfe552301, 0x3bf21d8f, 0x9d85163b, 0xac6d0ca6, 0x0a1a0712, + 0xfc5277fb, 0x5a257c4f, 0x6bcd66d2, 0xcdba6d66, 0x081d53e8, + 0xae6a585c, 0x9f8242c1, 0x39f54975, 0xa863a552, 0x0e14aee6, + 0x3ffcb47b, 0x998bbfcf, 0x5c2c8141, 0xfa5b8af5, 0xcbb39068, + 0x6dc49bdc, 0x9b8ceb35, 0x3dfbe081, 0x0c13fa1c, 0xaa64f1a8, + 0x6fc3cf26, 0xc9b4c492, 0xf85cde0f, 0x5e2bd5bb, 0x440b7579, + 0xe27c7ecd, 0xd3946450, 0x75e36fe4, 0xb044516a, 0x16335ade, + 0x27db4043, 0x81ac4bf7, 0x77e43b1e, 0xd19330aa, 0xe07b2a37, + 0x460c2183, 0x83ab1f0d, 0x25dc14b9, 0x14340e24, 0xb2430590, + 0x23d5e9b7, 0x85a2e203, 0xb44af89e, 0x123df32a, 0xd79acda4, + 0x71edc610, 0x4005dc8d, 0xe672d739, 0x103aa7d0, 0xb64dac64, + 0x87a5b6f9, 0x21d2bd4d, 0xe47583c3, 0x42028877, 0x73ea92ea, + 0xd59d995e, 0x8bb64ce5, 0x2dc14751, 0x1c295dcc, 0xba5e5678, + 0x7ff968f6, 0xd98e6342, 0xe86679df, 0x4e11726b, 0xb8590282, + 0x1e2e0936, 0x2fc613ab, 0x89b1181f, 0x4c162691, 0xea612d25, + 0xdb8937b8, 0x7dfe3c0c, 0xec68d02b, 0x4a1fdb9f, 0x7bf7c102, + 0xdd80cab6, 0x1827f438, 0xbe50ff8c, 0x8fb8e511, 0x29cfeea5, + 0xdf879e4c, 0x79f095f8, 0x48188f65, 0xee6f84d1, 0x2bc8ba5f, + 0x8dbfb1eb, 0xbc57ab76, 0x1a20a0c2, 0x8816eaf2, 0x2e61e146, + 0x1f89fbdb, 0xb9fef06f, 0x7c59cee1, 0xda2ec555, 0xebc6dfc8, + 0x4db1d47c, 0xbbf9a495, 0x1d8eaf21, 0x2c66b5bc, 0x8a11be08, + 0x4fb68086, 0xe9c18b32, 0xd82991af, 0x7e5e9a1b, 0xefc8763c, + 0x49bf7d88, 0x78576715, 0xde206ca1, 0x1b87522f, 0xbdf0599b, + 0x8c184306, 0x2a6f48b2, 0xdc27385b, 0x7a5033ef, 0x4bb82972, + 0xedcf22c6, 0x28681c48, 0x8e1f17fc, 0xbff70d61, 0x198006d5, + 0x47abd36e, 0xe1dcd8da, 0xd034c247, 0x7643c9f3, 0xb3e4f77d, + 0x1593fcc9, 0x247be654, 0x820cede0, 0x74449d09, 0xd23396bd, + 0xe3db8c20, 0x45ac8794, 0x800bb91a, 0x267cb2ae, 0x1794a833, + 0xb1e3a387, 0x20754fa0, 0x86024414, 0xb7ea5e89, 0x119d553d, + 0xd43a6bb3, 0x724d6007, 0x43a57a9a, 0xe5d2712e, 0x139a01c7, + 0xb5ed0a73, 0x840510ee, 0x22721b5a, 0xe7d525d4, 0x41a22e60, + 0x704a34fd, 0xd63d3f49, 0xcc1d9f8b, 0x6a6a943f, 0x5b828ea2, + 0xfdf58516, 0x3852bb98, 0x9e25b02c, 0xafcdaab1, 0x09baa105, + 0xfff2d1ec, 0x5985da58, 0x686dc0c5, 0xce1acb71, 0x0bbdf5ff, + 0xadcafe4b, 0x9c22e4d6, 0x3a55ef62, 0xabc30345, 0x0db408f1, + 0x3c5c126c, 0x9a2b19d8, 0x5f8c2756, 0xf9fb2ce2, 0xc813367f, + 0x6e643dcb, 0x982c4d22, 0x3e5b4696, 0x0fb35c0b, 0xa9c457bf, + 0x6c636931, 0xca146285, 0xfbfc7818, 0x5d8b73ac, 0x03a0a617, + 0xa5d7ada3, 0x943fb73e, 0x3248bc8a, 0xf7ef8204, 0x519889b0, + 0x6070932d, 0xc6079899, 0x304fe870, 0x9638e3c4, 0xa7d0f959, + 0x01a7f2ed, 0xc400cc63, 0x6277c7d7, 0x539fdd4a, 0xf5e8d6fe, + 0x647e3ad9, 0xc209316d, 0xf3e12bf0, 0x55962044, 0x90311eca, + 0x3646157e, 0x07ae0fe3, 0xa1d90457, 0x579174be, 0xf1e67f0a, + 0xc00e6597, 0x66796e23, 0xa3de50ad, 0x05a95b19, 0x34414184, + 0x92364a30}, + {0x00000000, 0xcb5cd3a5, 0x4dc8a10b, 0x869472ae, 0x9b914216, + 0x50cd91b3, 0xd659e31d, 0x1d0530b8, 0xec53826d, 0x270f51c8, + 0xa19b2366, 0x6ac7f0c3, 0x77c2c07b, 0xbc9e13de, 0x3a0a6170, + 0xf156b2d5, 0x03d6029b, 0xc88ad13e, 0x4e1ea390, 0x85427035, + 0x9847408d, 0x531b9328, 0xd58fe186, 0x1ed33223, 0xef8580f6, + 0x24d95353, 0xa24d21fd, 0x6911f258, 0x7414c2e0, 0xbf481145, + 0x39dc63eb, 0xf280b04e, 0x07ac0536, 0xccf0d693, 0x4a64a43d, + 0x81387798, 0x9c3d4720, 0x57619485, 0xd1f5e62b, 0x1aa9358e, + 0xebff875b, 0x20a354fe, 0xa6372650, 0x6d6bf5f5, 0x706ec54d, + 0xbb3216e8, 0x3da66446, 0xf6fab7e3, 0x047a07ad, 0xcf26d408, + 0x49b2a6a6, 0x82ee7503, 0x9feb45bb, 0x54b7961e, 0xd223e4b0, + 0x197f3715, 0xe82985c0, 0x23755665, 0xa5e124cb, 0x6ebdf76e, + 0x73b8c7d6, 0xb8e41473, 0x3e7066dd, 0xf52cb578, 0x0f580a6c, + 0xc404d9c9, 0x4290ab67, 0x89cc78c2, 0x94c9487a, 0x5f959bdf, + 0xd901e971, 0x125d3ad4, 0xe30b8801, 0x28575ba4, 0xaec3290a, + 0x659ffaaf, 0x789aca17, 0xb3c619b2, 0x35526b1c, 0xfe0eb8b9, + 0x0c8e08f7, 0xc7d2db52, 0x4146a9fc, 0x8a1a7a59, 0x971f4ae1, + 0x5c439944, 0xdad7ebea, 0x118b384f, 0xe0dd8a9a, 0x2b81593f, + 0xad152b91, 0x6649f834, 0x7b4cc88c, 0xb0101b29, 0x36846987, + 0xfdd8ba22, 0x08f40f5a, 0xc3a8dcff, 0x453cae51, 0x8e607df4, + 0x93654d4c, 0x58399ee9, 0xdeadec47, 0x15f13fe2, 0xe4a78d37, + 0x2ffb5e92, 0xa96f2c3c, 0x6233ff99, 0x7f36cf21, 0xb46a1c84, + 0x32fe6e2a, 0xf9a2bd8f, 0x0b220dc1, 0xc07ede64, 0x46eaacca, + 0x8db67f6f, 0x90b34fd7, 0x5bef9c72, 0xdd7beedc, 0x16273d79, + 0xe7718fac, 0x2c2d5c09, 0xaab92ea7, 0x61e5fd02, 0x7ce0cdba, + 0xb7bc1e1f, 0x31286cb1, 0xfa74bf14, 0x1eb014d8, 0xd5ecc77d, + 0x5378b5d3, 0x98246676, 0x852156ce, 0x4e7d856b, 0xc8e9f7c5, + 0x03b52460, 0xf2e396b5, 0x39bf4510, 0xbf2b37be, 0x7477e41b, + 0x6972d4a3, 0xa22e0706, 0x24ba75a8, 0xefe6a60d, 0x1d661643, + 0xd63ac5e6, 0x50aeb748, 0x9bf264ed, 0x86f75455, 0x4dab87f0, + 0xcb3ff55e, 0x006326fb, 0xf135942e, 0x3a69478b, 0xbcfd3525, + 0x77a1e680, 0x6aa4d638, 0xa1f8059d, 0x276c7733, 0xec30a496, + 0x191c11ee, 0xd240c24b, 0x54d4b0e5, 0x9f886340, 0x828d53f8, + 0x49d1805d, 0xcf45f2f3, 0x04192156, 0xf54f9383, 0x3e134026, + 0xb8873288, 0x73dbe12d, 0x6eded195, 0xa5820230, 0x2316709e, + 0xe84aa33b, 0x1aca1375, 0xd196c0d0, 0x5702b27e, 0x9c5e61db, + 0x815b5163, 0x4a0782c6, 0xcc93f068, 0x07cf23cd, 0xf6999118, + 0x3dc542bd, 0xbb513013, 0x700de3b6, 0x6d08d30e, 0xa65400ab, + 0x20c07205, 0xeb9ca1a0, 0x11e81eb4, 0xdab4cd11, 0x5c20bfbf, + 0x977c6c1a, 0x8a795ca2, 0x41258f07, 0xc7b1fda9, 0x0ced2e0c, + 0xfdbb9cd9, 0x36e74f7c, 0xb0733dd2, 0x7b2fee77, 0x662adecf, + 0xad760d6a, 0x2be27fc4, 0xe0beac61, 0x123e1c2f, 0xd962cf8a, + 0x5ff6bd24, 0x94aa6e81, 0x89af5e39, 0x42f38d9c, 0xc467ff32, + 0x0f3b2c97, 0xfe6d9e42, 0x35314de7, 0xb3a53f49, 0x78f9ecec, + 0x65fcdc54, 0xaea00ff1, 0x28347d5f, 0xe368aefa, 0x16441b82, + 0xdd18c827, 0x5b8cba89, 0x90d0692c, 0x8dd55994, 0x46898a31, + 0xc01df89f, 0x0b412b3a, 0xfa1799ef, 0x314b4a4a, 0xb7df38e4, + 0x7c83eb41, 0x6186dbf9, 0xaada085c, 0x2c4e7af2, 0xe712a957, + 0x15921919, 0xdececabc, 0x585ab812, 0x93066bb7, 0x8e035b0f, + 0x455f88aa, 0xc3cbfa04, 0x089729a1, 0xf9c19b74, 0x329d48d1, + 0xb4093a7f, 0x7f55e9da, 0x6250d962, 0xa90c0ac7, 0x2f987869, + 0xe4c4abcc}, + {0x00000000, 0x3d6029b0, 0x7ac05360, 0x47a07ad0, 0xf580a6c0, + 0xc8e08f70, 0x8f40f5a0, 0xb220dc10, 0x30704bc1, 0x0d106271, + 0x4ab018a1, 0x77d03111, 0xc5f0ed01, 0xf890c4b1, 0xbf30be61, + 0x825097d1, 0x60e09782, 0x5d80be32, 0x1a20c4e2, 0x2740ed52, + 0x95603142, 0xa80018f2, 0xefa06222, 0xd2c04b92, 0x5090dc43, + 0x6df0f5f3, 0x2a508f23, 0x1730a693, 0xa5107a83, 0x98705333, + 0xdfd029e3, 0xe2b00053, 0xc1c12f04, 0xfca106b4, 0xbb017c64, + 0x866155d4, 0x344189c4, 0x0921a074, 0x4e81daa4, 0x73e1f314, + 0xf1b164c5, 0xccd14d75, 0x8b7137a5, 0xb6111e15, 0x0431c205, + 0x3951ebb5, 0x7ef19165, 0x4391b8d5, 0xa121b886, 0x9c419136, + 0xdbe1ebe6, 0xe681c256, 0x54a11e46, 0x69c137f6, 0x2e614d26, + 0x13016496, 0x9151f347, 0xac31daf7, 0xeb91a027, 0xd6f18997, + 0x64d15587, 0x59b17c37, 0x1e1106e7, 0x23712f57, 0x58f35849, + 0x659371f9, 0x22330b29, 0x1f532299, 0xad73fe89, 0x9013d739, + 0xd7b3ade9, 0xead38459, 0x68831388, 0x55e33a38, 0x124340e8, + 0x2f236958, 0x9d03b548, 0xa0639cf8, 0xe7c3e628, 0xdaa3cf98, + 0x3813cfcb, 0x0573e67b, 0x42d39cab, 0x7fb3b51b, 0xcd93690b, + 0xf0f340bb, 0xb7533a6b, 0x8a3313db, 0x0863840a, 0x3503adba, + 0x72a3d76a, 0x4fc3feda, 0xfde322ca, 0xc0830b7a, 0x872371aa, + 0xba43581a, 0x9932774d, 0xa4525efd, 0xe3f2242d, 0xde920d9d, + 0x6cb2d18d, 0x51d2f83d, 0x167282ed, 0x2b12ab5d, 0xa9423c8c, + 0x9422153c, 0xd3826fec, 0xeee2465c, 0x5cc29a4c, 0x61a2b3fc, + 0x2602c92c, 0x1b62e09c, 0xf9d2e0cf, 0xc4b2c97f, 0x8312b3af, + 0xbe729a1f, 0x0c52460f, 0x31326fbf, 0x7692156f, 0x4bf23cdf, + 0xc9a2ab0e, 0xf4c282be, 0xb362f86e, 0x8e02d1de, 0x3c220dce, + 0x0142247e, 0x46e25eae, 0x7b82771e, 0xb1e6b092, 0x8c869922, + 0xcb26e3f2, 0xf646ca42, 0x44661652, 0x79063fe2, 0x3ea64532, + 0x03c66c82, 0x8196fb53, 0xbcf6d2e3, 0xfb56a833, 0xc6368183, + 0x74165d93, 0x49767423, 0x0ed60ef3, 0x33b62743, 0xd1062710, + 0xec660ea0, 0xabc67470, 0x96a65dc0, 0x248681d0, 0x19e6a860, + 0x5e46d2b0, 0x6326fb00, 0xe1766cd1, 0xdc164561, 0x9bb63fb1, + 0xa6d61601, 0x14f6ca11, 0x2996e3a1, 0x6e369971, 0x5356b0c1, + 0x70279f96, 0x4d47b626, 0x0ae7ccf6, 0x3787e546, 0x85a73956, + 0xb8c710e6, 0xff676a36, 0xc2074386, 0x4057d457, 0x7d37fde7, + 0x3a978737, 0x07f7ae87, 0xb5d77297, 0x88b75b27, 0xcf1721f7, + 0xf2770847, 0x10c70814, 0x2da721a4, 0x6a075b74, 0x576772c4, + 0xe547aed4, 0xd8278764, 0x9f87fdb4, 0xa2e7d404, 0x20b743d5, + 0x1dd76a65, 0x5a7710b5, 0x67173905, 0xd537e515, 0xe857cca5, + 0xaff7b675, 0x92979fc5, 0xe915e8db, 0xd475c16b, 0x93d5bbbb, + 0xaeb5920b, 0x1c954e1b, 0x21f567ab, 0x66551d7b, 0x5b3534cb, + 0xd965a31a, 0xe4058aaa, 0xa3a5f07a, 0x9ec5d9ca, 0x2ce505da, + 0x11852c6a, 0x562556ba, 0x6b457f0a, 0x89f57f59, 0xb49556e9, + 0xf3352c39, 0xce550589, 0x7c75d999, 0x4115f029, 0x06b58af9, + 0x3bd5a349, 0xb9853498, 0x84e51d28, 0xc34567f8, 0xfe254e48, + 0x4c059258, 0x7165bbe8, 0x36c5c138, 0x0ba5e888, 0x28d4c7df, + 0x15b4ee6f, 0x521494bf, 0x6f74bd0f, 0xdd54611f, 0xe03448af, + 0xa794327f, 0x9af41bcf, 0x18a48c1e, 0x25c4a5ae, 0x6264df7e, + 0x5f04f6ce, 0xed242ade, 0xd044036e, 0x97e479be, 0xaa84500e, + 0x4834505d, 0x755479ed, 0x32f4033d, 0x0f942a8d, 0xbdb4f69d, + 0x80d4df2d, 0xc774a5fd, 0xfa148c4d, 0x78441b9c, 0x4524322c, + 0x028448fc, 0x3fe4614c, 0x8dc4bd5c, 0xb0a494ec, 0xf704ee3c, + 0xca64c78c}}; + +local const z_word_t FAR crc_braid_big_table[][256] = { + {0x00000000, 0xb029603d, 0x6053c07a, 0xd07aa047, 0xc0a680f5, + 0x708fe0c8, 0xa0f5408f, 0x10dc20b2, 0xc14b7030, 0x7162100d, + 0xa118b04a, 0x1131d077, 0x01edf0c5, 0xb1c490f8, 0x61be30bf, + 0xd1975082, 0x8297e060, 0x32be805d, 0xe2c4201a, 0x52ed4027, + 0x42316095, 0xf21800a8, 0x2262a0ef, 0x924bc0d2, 0x43dc9050, + 0xf3f5f06d, 0x238f502a, 0x93a63017, 0x837a10a5, 0x33537098, + 0xe329d0df, 0x5300b0e2, 0x042fc1c1, 0xb406a1fc, 0x647c01bb, + 0xd4556186, 0xc4894134, 0x74a02109, 0xa4da814e, 0x14f3e173, + 0xc564b1f1, 0x754dd1cc, 0xa537718b, 0x151e11b6, 0x05c23104, + 0xb5eb5139, 0x6591f17e, 0xd5b89143, 0x86b821a1, 0x3691419c, + 0xe6ebe1db, 0x56c281e6, 0x461ea154, 0xf637c169, 0x264d612e, + 0x96640113, 0x47f35191, 0xf7da31ac, 0x27a091eb, 0x9789f1d6, + 0x8755d164, 0x377cb159, 0xe706111e, 0x572f7123, 0x4958f358, + 0xf9719365, 0x290b3322, 0x9922531f, 0x89fe73ad, 0x39d71390, + 0xe9adb3d7, 0x5984d3ea, 0x88138368, 0x383ae355, 0xe8404312, + 0x5869232f, 0x48b5039d, 0xf89c63a0, 0x28e6c3e7, 0x98cfa3da, + 0xcbcf1338, 0x7be67305, 0xab9cd342, 0x1bb5b37f, 0x0b6993cd, + 0xbb40f3f0, 0x6b3a53b7, 0xdb13338a, 0x0a846308, 0xbaad0335, + 0x6ad7a372, 0xdafec34f, 0xca22e3fd, 0x7a0b83c0, 0xaa712387, + 0x1a5843ba, 0x4d773299, 0xfd5e52a4, 0x2d24f2e3, 0x9d0d92de, + 0x8dd1b26c, 0x3df8d251, 0xed827216, 0x5dab122b, 0x8c3c42a9, + 0x3c152294, 0xec6f82d3, 0x5c46e2ee, 0x4c9ac25c, 0xfcb3a261, + 0x2cc90226, 0x9ce0621b, 0xcfe0d2f9, 0x7fc9b2c4, 0xafb31283, + 0x1f9a72be, 0x0f46520c, 0xbf6f3231, 0x6f159276, 0xdf3cf24b, + 0x0eaba2c9, 0xbe82c2f4, 0x6ef862b3, 0xded1028e, 0xce0d223c, + 0x7e244201, 0xae5ee246, 0x1e77827b, 0x92b0e6b1, 0x2299868c, + 0xf2e326cb, 0x42ca46f6, 0x52166644, 0xe23f0679, 0x3245a63e, + 0x826cc603, 0x53fb9681, 0xe3d2f6bc, 0x33a856fb, 0x838136c6, + 0x935d1674, 0x23747649, 0xf30ed60e, 0x4327b633, 0x102706d1, + 0xa00e66ec, 0x7074c6ab, 0xc05da696, 0xd0818624, 0x60a8e619, + 0xb0d2465e, 0x00fb2663, 0xd16c76e1, 0x614516dc, 0xb13fb69b, + 0x0116d6a6, 0x11caf614, 0xa1e39629, 0x7199366e, 0xc1b05653, + 0x969f2770, 0x26b6474d, 0xf6cce70a, 0x46e58737, 0x5639a785, + 0xe610c7b8, 0x366a67ff, 0x864307c2, 0x57d45740, 0xe7fd377d, + 0x3787973a, 0x87aef707, 0x9772d7b5, 0x275bb788, 0xf72117cf, + 0x470877f2, 0x1408c710, 0xa421a72d, 0x745b076a, 0xc4726757, + 0xd4ae47e5, 0x648727d8, 0xb4fd879f, 0x04d4e7a2, 0xd543b720, + 0x656ad71d, 0xb510775a, 0x05391767, 0x15e537d5, 0xa5cc57e8, + 0x75b6f7af, 0xc59f9792, 0xdbe815e9, 0x6bc175d4, 0xbbbbd593, + 0x0b92b5ae, 0x1b4e951c, 0xab67f521, 0x7b1d5566, 0xcb34355b, + 0x1aa365d9, 0xaa8a05e4, 0x7af0a5a3, 0xcad9c59e, 0xda05e52c, + 0x6a2c8511, 0xba562556, 0x0a7f456b, 0x597ff589, 0xe95695b4, + 0x392c35f3, 0x890555ce, 0x99d9757c, 0x29f01541, 0xf98ab506, + 0x49a3d53b, 0x983485b9, 0x281de584, 0xf86745c3, 0x484e25fe, + 0x5892054c, 0xe8bb6571, 0x38c1c536, 0x88e8a50b, 0xdfc7d428, + 0x6feeb415, 0xbf941452, 0x0fbd746f, 0x1f6154dd, 0xaf4834e0, + 0x7f3294a7, 0xcf1bf49a, 0x1e8ca418, 0xaea5c425, 0x7edf6462, + 0xcef6045f, 0xde2a24ed, 0x6e0344d0, 0xbe79e497, 0x0e5084aa, + 0x5d503448, 0xed795475, 0x3d03f432, 0x8d2a940f, 0x9df6b4bd, + 0x2ddfd480, 0xfda574c7, 0x4d8c14fa, 0x9c1b4478, 0x2c322445, + 0xfc488402, 0x4c61e43f, 0x5cbdc48d, 0xec94a4b0, 0x3cee04f7, + 0x8cc764ca}, + {0x00000000, 0xa5d35ccb, 0x0ba1c84d, 0xae729486, 0x1642919b, + 0xb391cd50, 0x1de359d6, 0xb830051d, 0x6d8253ec, 0xc8510f27, + 0x66239ba1, 0xc3f0c76a, 0x7bc0c277, 0xde139ebc, 0x70610a3a, + 0xd5b256f1, 0x9b02d603, 0x3ed18ac8, 0x90a31e4e, 0x35704285, + 0x8d404798, 0x28931b53, 0x86e18fd5, 0x2332d31e, 0xf68085ef, + 0x5353d924, 0xfd214da2, 0x58f21169, 0xe0c21474, 0x451148bf, + 0xeb63dc39, 0x4eb080f2, 0x3605ac07, 0x93d6f0cc, 0x3da4644a, + 0x98773881, 0x20473d9c, 0x85946157, 0x2be6f5d1, 0x8e35a91a, + 0x5b87ffeb, 0xfe54a320, 0x502637a6, 0xf5f56b6d, 0x4dc56e70, + 0xe81632bb, 0x4664a63d, 0xe3b7faf6, 0xad077a04, 0x08d426cf, + 0xa6a6b249, 0x0375ee82, 0xbb45eb9f, 0x1e96b754, 0xb0e423d2, + 0x15377f19, 0xc08529e8, 0x65567523, 0xcb24e1a5, 0x6ef7bd6e, + 0xd6c7b873, 0x7314e4b8, 0xdd66703e, 0x78b52cf5, 0x6c0a580f, + 0xc9d904c4, 0x67ab9042, 0xc278cc89, 0x7a48c994, 0xdf9b955f, + 0x71e901d9, 0xd43a5d12, 0x01880be3, 0xa45b5728, 0x0a29c3ae, + 0xaffa9f65, 0x17ca9a78, 0xb219c6b3, 0x1c6b5235, 0xb9b80efe, + 0xf7088e0c, 0x52dbd2c7, 0xfca94641, 0x597a1a8a, 0xe14a1f97, + 0x4499435c, 0xeaebd7da, 0x4f388b11, 0x9a8adde0, 0x3f59812b, + 0x912b15ad, 0x34f84966, 0x8cc84c7b, 0x291b10b0, 0x87698436, + 0x22bad8fd, 0x5a0ff408, 0xffdca8c3, 0x51ae3c45, 0xf47d608e, + 0x4c4d6593, 0xe99e3958, 0x47ecadde, 0xe23ff115, 0x378da7e4, + 0x925efb2f, 0x3c2c6fa9, 0x99ff3362, 0x21cf367f, 0x841c6ab4, + 0x2a6efe32, 0x8fbda2f9, 0xc10d220b, 0x64de7ec0, 0xcaacea46, + 0x6f7fb68d, 0xd74fb390, 0x729cef5b, 0xdcee7bdd, 0x793d2716, + 0xac8f71e7, 0x095c2d2c, 0xa72eb9aa, 0x02fde561, 0xbacde07c, + 0x1f1ebcb7, 0xb16c2831, 0x14bf74fa, 0xd814b01e, 0x7dc7ecd5, + 0xd3b57853, 0x76662498, 0xce562185, 0x6b857d4e, 0xc5f7e9c8, + 0x6024b503, 0xb596e3f2, 0x1045bf39, 0xbe372bbf, 0x1be47774, + 0xa3d47269, 0x06072ea2, 0xa875ba24, 0x0da6e6ef, 0x4316661d, + 0xe6c53ad6, 0x48b7ae50, 0xed64f29b, 0x5554f786, 0xf087ab4d, + 0x5ef53fcb, 0xfb266300, 0x2e9435f1, 0x8b47693a, 0x2535fdbc, + 0x80e6a177, 0x38d6a46a, 0x9d05f8a1, 0x33776c27, 0x96a430ec, + 0xee111c19, 0x4bc240d2, 0xe5b0d454, 0x4063889f, 0xf8538d82, + 0x5d80d149, 0xf3f245cf, 0x56211904, 0x83934ff5, 0x2640133e, + 0x883287b8, 0x2de1db73, 0x95d1de6e, 0x300282a5, 0x9e701623, + 0x3ba34ae8, 0x7513ca1a, 0xd0c096d1, 0x7eb20257, 0xdb615e9c, + 0x63515b81, 0xc682074a, 0x68f093cc, 0xcd23cf07, 0x189199f6, + 0xbd42c53d, 0x133051bb, 0xb6e30d70, 0x0ed3086d, 0xab0054a6, + 0x0572c020, 0xa0a19ceb, 0xb41ee811, 0x11cdb4da, 0xbfbf205c, + 0x1a6c7c97, 0xa25c798a, 0x078f2541, 0xa9fdb1c7, 0x0c2eed0c, + 0xd99cbbfd, 0x7c4fe736, 0xd23d73b0, 0x77ee2f7b, 0xcfde2a66, + 0x6a0d76ad, 0xc47fe22b, 0x61acbee0, 0x2f1c3e12, 0x8acf62d9, + 0x24bdf65f, 0x816eaa94, 0x395eaf89, 0x9c8df342, 0x32ff67c4, + 0x972c3b0f, 0x429e6dfe, 0xe74d3135, 0x493fa5b3, 0xececf978, + 0x54dcfc65, 0xf10fa0ae, 0x5f7d3428, 0xfaae68e3, 0x821b4416, + 0x27c818dd, 0x89ba8c5b, 0x2c69d090, 0x9459d58d, 0x318a8946, + 0x9ff81dc0, 0x3a2b410b, 0xef9917fa, 0x4a4a4b31, 0xe438dfb7, + 0x41eb837c, 0xf9db8661, 0x5c08daaa, 0xf27a4e2c, 0x57a912e7, + 0x19199215, 0xbccacede, 0x12b85a58, 0xb76b0693, 0x0f5b038e, + 0xaa885f45, 0x04facbc3, 0xa1299708, 0x749bc1f9, 0xd1489d32, + 0x7f3a09b4, 0xdae9557f, 0x62d95062, 0xc70a0ca9, 0x6978982f, + 0xccabc4e4}, + {0x00000000, 0xb40b77a6, 0x29119f97, 0x9d1ae831, 0x13244ff4, + 0xa72f3852, 0x3a35d063, 0x8e3ea7c5, 0x674eef33, 0xd3459895, + 0x4e5f70a4, 0xfa540702, 0x746aa0c7, 0xc061d761, 0x5d7b3f50, + 0xe97048f6, 0xce9cde67, 0x7a97a9c1, 0xe78d41f0, 0x53863656, + 0xddb89193, 0x69b3e635, 0xf4a90e04, 0x40a279a2, 0xa9d23154, + 0x1dd946f2, 0x80c3aec3, 0x34c8d965, 0xbaf67ea0, 0x0efd0906, + 0x93e7e137, 0x27ec9691, 0x9c39bdcf, 0x2832ca69, 0xb5282258, + 0x012355fe, 0x8f1df23b, 0x3b16859d, 0xa60c6dac, 0x12071a0a, + 0xfb7752fc, 0x4f7c255a, 0xd266cd6b, 0x666dbacd, 0xe8531d08, + 0x5c586aae, 0xc142829f, 0x7549f539, 0x52a563a8, 0xe6ae140e, + 0x7bb4fc3f, 0xcfbf8b99, 0x41812c5c, 0xf58a5bfa, 0x6890b3cb, + 0xdc9bc46d, 0x35eb8c9b, 0x81e0fb3d, 0x1cfa130c, 0xa8f164aa, + 0x26cfc36f, 0x92c4b4c9, 0x0fde5cf8, 0xbbd52b5e, 0x79750b44, + 0xcd7e7ce2, 0x506494d3, 0xe46fe375, 0x6a5144b0, 0xde5a3316, + 0x4340db27, 0xf74bac81, 0x1e3be477, 0xaa3093d1, 0x372a7be0, + 0x83210c46, 0x0d1fab83, 0xb914dc25, 0x240e3414, 0x900543b2, + 0xb7e9d523, 0x03e2a285, 0x9ef84ab4, 0x2af33d12, 0xa4cd9ad7, + 0x10c6ed71, 0x8ddc0540, 0x39d772e6, 0xd0a73a10, 0x64ac4db6, + 0xf9b6a587, 0x4dbdd221, 0xc38375e4, 0x77880242, 0xea92ea73, + 0x5e999dd5, 0xe54cb68b, 0x5147c12d, 0xcc5d291c, 0x78565eba, + 0xf668f97f, 0x42638ed9, 0xdf7966e8, 0x6b72114e, 0x820259b8, + 0x36092e1e, 0xab13c62f, 0x1f18b189, 0x9126164c, 0x252d61ea, + 0xb83789db, 0x0c3cfe7d, 0x2bd068ec, 0x9fdb1f4a, 0x02c1f77b, + 0xb6ca80dd, 0x38f42718, 0x8cff50be, 0x11e5b88f, 0xa5eecf29, + 0x4c9e87df, 0xf895f079, 0x658f1848, 0xd1846fee, 0x5fbac82b, + 0xebb1bf8d, 0x76ab57bc, 0xc2a0201a, 0xf2ea1688, 0x46e1612e, + 0xdbfb891f, 0x6ff0feb9, 0xe1ce597c, 0x55c52eda, 0xc8dfc6eb, + 0x7cd4b14d, 0x95a4f9bb, 0x21af8e1d, 0xbcb5662c, 0x08be118a, + 0x8680b64f, 0x328bc1e9, 0xaf9129d8, 0x1b9a5e7e, 0x3c76c8ef, + 0x887dbf49, 0x15675778, 0xa16c20de, 0x2f52871b, 0x9b59f0bd, + 0x0643188c, 0xb2486f2a, 0x5b3827dc, 0xef33507a, 0x7229b84b, + 0xc622cfed, 0x481c6828, 0xfc171f8e, 0x610df7bf, 0xd5068019, + 0x6ed3ab47, 0xdad8dce1, 0x47c234d0, 0xf3c94376, 0x7df7e4b3, + 0xc9fc9315, 0x54e67b24, 0xe0ed0c82, 0x099d4474, 0xbd9633d2, + 0x208cdbe3, 0x9487ac45, 0x1ab90b80, 0xaeb27c26, 0x33a89417, + 0x87a3e3b1, 0xa04f7520, 0x14440286, 0x895eeab7, 0x3d559d11, + 0xb36b3ad4, 0x07604d72, 0x9a7aa543, 0x2e71d2e5, 0xc7019a13, + 0x730aedb5, 0xee100584, 0x5a1b7222, 0xd425d5e7, 0x602ea241, + 0xfd344a70, 0x493f3dd6, 0x8b9f1dcc, 0x3f946a6a, 0xa28e825b, + 0x1685f5fd, 0x98bb5238, 0x2cb0259e, 0xb1aacdaf, 0x05a1ba09, + 0xecd1f2ff, 0x58da8559, 0xc5c06d68, 0x71cb1ace, 0xfff5bd0b, + 0x4bfecaad, 0xd6e4229c, 0x62ef553a, 0x4503c3ab, 0xf108b40d, + 0x6c125c3c, 0xd8192b9a, 0x56278c5f, 0xe22cfbf9, 0x7f3613c8, + 0xcb3d646e, 0x224d2c98, 0x96465b3e, 0x0b5cb30f, 0xbf57c4a9, + 0x3169636c, 0x856214ca, 0x1878fcfb, 0xac738b5d, 0x17a6a003, + 0xa3add7a5, 0x3eb73f94, 0x8abc4832, 0x0482eff7, 0xb0899851, + 0x2d937060, 0x999807c6, 0x70e84f30, 0xc4e33896, 0x59f9d0a7, + 0xedf2a701, 0x63cc00c4, 0xd7c77762, 0x4add9f53, 0xfed6e8f5, + 0xd93a7e64, 0x6d3109c2, 0xf02be1f3, 0x44209655, 0xca1e3190, + 0x7e154636, 0xe30fae07, 0x5704d9a1, 0xbe749157, 0x0a7fe6f1, + 0x97650ec0, 0x236e7966, 0xad50dea3, 0x195ba905, 0x84414134, + 0x304a3692}, + {0x00000000, 0x9e00aacc, 0x7d072542, 0xe3078f8e, 0xfa0e4a84, + 0x640ee048, 0x87096fc6, 0x1909c50a, 0xb51be5d3, 0x2b1b4f1f, + 0xc81cc091, 0x561c6a5d, 0x4f15af57, 0xd115059b, 0x32128a15, + 0xac1220d9, 0x2b31bb7c, 0xb53111b0, 0x56369e3e, 0xc83634f2, + 0xd13ff1f8, 0x4f3f5b34, 0xac38d4ba, 0x32387e76, 0x9e2a5eaf, + 0x002af463, 0xe32d7bed, 0x7d2dd121, 0x6424142b, 0xfa24bee7, + 0x19233169, 0x87239ba5, 0x566276f9, 0xc862dc35, 0x2b6553bb, + 0xb565f977, 0xac6c3c7d, 0x326c96b1, 0xd16b193f, 0x4f6bb3f3, + 0xe379932a, 0x7d7939e6, 0x9e7eb668, 0x007e1ca4, 0x1977d9ae, + 0x87777362, 0x6470fcec, 0xfa705620, 0x7d53cd85, 0xe3536749, + 0x0054e8c7, 0x9e54420b, 0x875d8701, 0x195d2dcd, 0xfa5aa243, + 0x645a088f, 0xc8482856, 0x5648829a, 0xb54f0d14, 0x2b4fa7d8, + 0x324662d2, 0xac46c81e, 0x4f414790, 0xd141ed5c, 0xedc29d29, + 0x73c237e5, 0x90c5b86b, 0x0ec512a7, 0x17ccd7ad, 0x89cc7d61, + 0x6acbf2ef, 0xf4cb5823, 0x58d978fa, 0xc6d9d236, 0x25de5db8, + 0xbbdef774, 0xa2d7327e, 0x3cd798b2, 0xdfd0173c, 0x41d0bdf0, + 0xc6f32655, 0x58f38c99, 0xbbf40317, 0x25f4a9db, 0x3cfd6cd1, + 0xa2fdc61d, 0x41fa4993, 0xdffae35f, 0x73e8c386, 0xede8694a, + 0x0eefe6c4, 0x90ef4c08, 0x89e68902, 0x17e623ce, 0xf4e1ac40, + 0x6ae1068c, 0xbba0ebd0, 0x25a0411c, 0xc6a7ce92, 0x58a7645e, + 0x41aea154, 0xdfae0b98, 0x3ca98416, 0xa2a92eda, 0x0ebb0e03, + 0x90bba4cf, 0x73bc2b41, 0xedbc818d, 0xf4b54487, 0x6ab5ee4b, + 0x89b261c5, 0x17b2cb09, 0x909150ac, 0x0e91fa60, 0xed9675ee, + 0x7396df22, 0x6a9f1a28, 0xf49fb0e4, 0x17983f6a, 0x899895a6, + 0x258ab57f, 0xbb8a1fb3, 0x588d903d, 0xc68d3af1, 0xdf84fffb, + 0x41845537, 0xa283dab9, 0x3c837075, 0xda853b53, 0x4485919f, + 0xa7821e11, 0x3982b4dd, 0x208b71d7, 0xbe8bdb1b, 0x5d8c5495, + 0xc38cfe59, 0x6f9ede80, 0xf19e744c, 0x1299fbc2, 0x8c99510e, + 0x95909404, 0x0b903ec8, 0xe897b146, 0x76971b8a, 0xf1b4802f, + 0x6fb42ae3, 0x8cb3a56d, 0x12b30fa1, 0x0bbacaab, 0x95ba6067, + 0x76bdefe9, 0xe8bd4525, 0x44af65fc, 0xdaafcf30, 0x39a840be, + 0xa7a8ea72, 0xbea12f78, 0x20a185b4, 0xc3a60a3a, 0x5da6a0f6, + 0x8ce74daa, 0x12e7e766, 0xf1e068e8, 0x6fe0c224, 0x76e9072e, + 0xe8e9ade2, 0x0bee226c, 0x95ee88a0, 0x39fca879, 0xa7fc02b5, + 0x44fb8d3b, 0xdafb27f7, 0xc3f2e2fd, 0x5df24831, 0xbef5c7bf, + 0x20f56d73, 0xa7d6f6d6, 0x39d65c1a, 0xdad1d394, 0x44d17958, + 0x5dd8bc52, 0xc3d8169e, 0x20df9910, 0xbedf33dc, 0x12cd1305, + 0x8ccdb9c9, 0x6fca3647, 0xf1ca9c8b, 0xe8c35981, 0x76c3f34d, + 0x95c47cc3, 0x0bc4d60f, 0x3747a67a, 0xa9470cb6, 0x4a408338, + 0xd44029f4, 0xcd49ecfe, 0x53494632, 0xb04ec9bc, 0x2e4e6370, + 0x825c43a9, 0x1c5ce965, 0xff5b66eb, 0x615bcc27, 0x7852092d, + 0xe652a3e1, 0x05552c6f, 0x9b5586a3, 0x1c761d06, 0x8276b7ca, + 0x61713844, 0xff719288, 0xe6785782, 0x7878fd4e, 0x9b7f72c0, + 0x057fd80c, 0xa96df8d5, 0x376d5219, 0xd46add97, 0x4a6a775b, + 0x5363b251, 0xcd63189d, 0x2e649713, 0xb0643ddf, 0x6125d083, + 0xff257a4f, 0x1c22f5c1, 0x82225f0d, 0x9b2b9a07, 0x052b30cb, + 0xe62cbf45, 0x782c1589, 0xd43e3550, 0x4a3e9f9c, 0xa9391012, + 0x3739bade, 0x2e307fd4, 0xb030d518, 0x53375a96, 0xcd37f05a, + 0x4a146bff, 0xd414c133, 0x37134ebd, 0xa913e471, 0xb01a217b, + 0x2e1a8bb7, 0xcd1d0439, 0x531daef5, 0xff0f8e2c, 0x610f24e0, + 0x8208ab6e, 0x1c0801a2, 0x0501c4a8, 0x9b016e64, 0x7806e1ea, + 0xe6064b26}}; + +#endif + +#endif + +#if N == 3 + +#if W == 8 + +local const z_crc_t FAR crc_braid_table[][256] = { + {0x00000000, 0x81256527, 0xd93bcc0f, 0x581ea928, 0x69069e5f, + 0xe823fb78, 0xb03d5250, 0x31183777, 0xd20d3cbe, 0x53285999, + 0x0b36f0b1, 0x8a139596, 0xbb0ba2e1, 0x3a2ec7c6, 0x62306eee, + 0xe3150bc9, 0x7f6b7f3d, 0xfe4e1a1a, 0xa650b332, 0x2775d615, + 0x166de162, 0x97488445, 0xcf562d6d, 0x4e73484a, 0xad664383, + 0x2c4326a4, 0x745d8f8c, 0xf578eaab, 0xc460dddc, 0x4545b8fb, + 0x1d5b11d3, 0x9c7e74f4, 0xfed6fe7a, 0x7ff39b5d, 0x27ed3275, + 0xa6c85752, 0x97d06025, 0x16f50502, 0x4eebac2a, 0xcfcec90d, + 0x2cdbc2c4, 0xadfea7e3, 0xf5e00ecb, 0x74c56bec, 0x45dd5c9b, + 0xc4f839bc, 0x9ce69094, 0x1dc3f5b3, 0x81bd8147, 0x0098e460, + 0x58864d48, 0xd9a3286f, 0xe8bb1f18, 0x699e7a3f, 0x3180d317, + 0xb0a5b630, 0x53b0bdf9, 0xd295d8de, 0x8a8b71f6, 0x0bae14d1, + 0x3ab623a6, 0xbb934681, 0xe38defa9, 0x62a88a8e, 0x26dcfab5, + 0xa7f99f92, 0xffe736ba, 0x7ec2539d, 0x4fda64ea, 0xceff01cd, + 0x96e1a8e5, 0x17c4cdc2, 0xf4d1c60b, 0x75f4a32c, 0x2dea0a04, + 0xaccf6f23, 0x9dd75854, 0x1cf23d73, 0x44ec945b, 0xc5c9f17c, + 0x59b78588, 0xd892e0af, 0x808c4987, 0x01a92ca0, 0x30b11bd7, + 0xb1947ef0, 0xe98ad7d8, 0x68afb2ff, 0x8bbab936, 0x0a9fdc11, + 0x52817539, 0xd3a4101e, 0xe2bc2769, 0x6399424e, 0x3b87eb66, + 0xbaa28e41, 0xd80a04cf, 0x592f61e8, 0x0131c8c0, 0x8014ade7, + 0xb10c9a90, 0x3029ffb7, 0x6837569f, 0xe91233b8, 0x0a073871, + 0x8b225d56, 0xd33cf47e, 0x52199159, 0x6301a62e, 0xe224c309, + 0xba3a6a21, 0x3b1f0f06, 0xa7617bf2, 0x26441ed5, 0x7e5ab7fd, + 0xff7fd2da, 0xce67e5ad, 0x4f42808a, 0x175c29a2, 0x96794c85, + 0x756c474c, 0xf449226b, 0xac578b43, 0x2d72ee64, 0x1c6ad913, + 0x9d4fbc34, 0xc551151c, 0x4474703b, 0x4db9f56a, 0xcc9c904d, + 0x94823965, 0x15a75c42, 0x24bf6b35, 0xa59a0e12, 0xfd84a73a, + 0x7ca1c21d, 0x9fb4c9d4, 0x1e91acf3, 0x468f05db, 0xc7aa60fc, + 0xf6b2578b, 0x779732ac, 0x2f899b84, 0xaeacfea3, 0x32d28a57, + 0xb3f7ef70, 0xebe94658, 0x6acc237f, 0x5bd41408, 0xdaf1712f, + 0x82efd807, 0x03cabd20, 0xe0dfb6e9, 0x61fad3ce, 0x39e47ae6, + 0xb8c11fc1, 0x89d928b6, 0x08fc4d91, 0x50e2e4b9, 0xd1c7819e, + 0xb36f0b10, 0x324a6e37, 0x6a54c71f, 0xeb71a238, 0xda69954f, + 0x5b4cf068, 0x03525940, 0x82773c67, 0x616237ae, 0xe0475289, + 0xb859fba1, 0x397c9e86, 0x0864a9f1, 0x8941ccd6, 0xd15f65fe, + 0x507a00d9, 0xcc04742d, 0x4d21110a, 0x153fb822, 0x941add05, + 0xa502ea72, 0x24278f55, 0x7c39267d, 0xfd1c435a, 0x1e094893, + 0x9f2c2db4, 0xc732849c, 0x4617e1bb, 0x770fd6cc, 0xf62ab3eb, + 0xae341ac3, 0x2f117fe4, 0x6b650fdf, 0xea406af8, 0xb25ec3d0, + 0x337ba6f7, 0x02639180, 0x8346f4a7, 0xdb585d8f, 0x5a7d38a8, + 0xb9683361, 0x384d5646, 0x6053ff6e, 0xe1769a49, 0xd06ead3e, + 0x514bc819, 0x09556131, 0x88700416, 0x140e70e2, 0x952b15c5, + 0xcd35bced, 0x4c10d9ca, 0x7d08eebd, 0xfc2d8b9a, 0xa43322b2, + 0x25164795, 0xc6034c5c, 0x4726297b, 0x1f388053, 0x9e1de574, + 0xaf05d203, 0x2e20b724, 0x763e1e0c, 0xf71b7b2b, 0x95b3f1a5, + 0x14969482, 0x4c883daa, 0xcdad588d, 0xfcb56ffa, 0x7d900add, + 0x258ea3f5, 0xa4abc6d2, 0x47becd1b, 0xc69ba83c, 0x9e850114, + 0x1fa06433, 0x2eb85344, 0xaf9d3663, 0xf7839f4b, 0x76a6fa6c, + 0xead88e98, 0x6bfdebbf, 0x33e34297, 0xb2c627b0, 0x83de10c7, + 0x02fb75e0, 0x5ae5dcc8, 0xdbc0b9ef, 0x38d5b226, 0xb9f0d701, + 0xe1ee7e29, 0x60cb1b0e, 0x51d32c79, 0xd0f6495e, 0x88e8e076, + 0x09cd8551}, + {0x00000000, 0x9b73ead4, 0xed96d3e9, 0x76e5393d, 0x005ca193, + 0x9b2f4b47, 0xedca727a, 0x76b998ae, 0x00b94326, 0x9bcaa9f2, + 0xed2f90cf, 0x765c7a1b, 0x00e5e2b5, 0x9b960861, 0xed73315c, + 0x7600db88, 0x0172864c, 0x9a016c98, 0xece455a5, 0x7797bf71, + 0x012e27df, 0x9a5dcd0b, 0xecb8f436, 0x77cb1ee2, 0x01cbc56a, + 0x9ab82fbe, 0xec5d1683, 0x772efc57, 0x019764f9, 0x9ae48e2d, + 0xec01b710, 0x77725dc4, 0x02e50c98, 0x9996e64c, 0xef73df71, + 0x740035a5, 0x02b9ad0b, 0x99ca47df, 0xef2f7ee2, 0x745c9436, + 0x025c4fbe, 0x992fa56a, 0xefca9c57, 0x74b97683, 0x0200ee2d, + 0x997304f9, 0xef963dc4, 0x74e5d710, 0x03978ad4, 0x98e46000, + 0xee01593d, 0x7572b3e9, 0x03cb2b47, 0x98b8c193, 0xee5df8ae, + 0x752e127a, 0x032ec9f2, 0x985d2326, 0xeeb81a1b, 0x75cbf0cf, + 0x03726861, 0x980182b5, 0xeee4bb88, 0x7597515c, 0x05ca1930, + 0x9eb9f3e4, 0xe85ccad9, 0x732f200d, 0x0596b8a3, 0x9ee55277, + 0xe8006b4a, 0x7373819e, 0x05735a16, 0x9e00b0c2, 0xe8e589ff, + 0x7396632b, 0x052ffb85, 0x9e5c1151, 0xe8b9286c, 0x73cac2b8, + 0x04b89f7c, 0x9fcb75a8, 0xe92e4c95, 0x725da641, 0x04e43eef, + 0x9f97d43b, 0xe972ed06, 0x720107d2, 0x0401dc5a, 0x9f72368e, + 0xe9970fb3, 0x72e4e567, 0x045d7dc9, 0x9f2e971d, 0xe9cbae20, + 0x72b844f4, 0x072f15a8, 0x9c5cff7c, 0xeab9c641, 0x71ca2c95, + 0x0773b43b, 0x9c005eef, 0xeae567d2, 0x71968d06, 0x0796568e, + 0x9ce5bc5a, 0xea008567, 0x71736fb3, 0x07caf71d, 0x9cb91dc9, + 0xea5c24f4, 0x712fce20, 0x065d93e4, 0x9d2e7930, 0xebcb400d, + 0x70b8aad9, 0x06013277, 0x9d72d8a3, 0xeb97e19e, 0x70e40b4a, + 0x06e4d0c2, 0x9d973a16, 0xeb72032b, 0x7001e9ff, 0x06b87151, + 0x9dcb9b85, 0xeb2ea2b8, 0x705d486c, 0x0b943260, 0x90e7d8b4, + 0xe602e189, 0x7d710b5d, 0x0bc893f3, 0x90bb7927, 0xe65e401a, + 0x7d2daace, 0x0b2d7146, 0x905e9b92, 0xe6bba2af, 0x7dc8487b, + 0x0b71d0d5, 0x90023a01, 0xe6e7033c, 0x7d94e9e8, 0x0ae6b42c, + 0x91955ef8, 0xe77067c5, 0x7c038d11, 0x0aba15bf, 0x91c9ff6b, + 0xe72cc656, 0x7c5f2c82, 0x0a5ff70a, 0x912c1dde, 0xe7c924e3, + 0x7cbace37, 0x0a035699, 0x9170bc4d, 0xe7958570, 0x7ce66fa4, + 0x09713ef8, 0x9202d42c, 0xe4e7ed11, 0x7f9407c5, 0x092d9f6b, + 0x925e75bf, 0xe4bb4c82, 0x7fc8a656, 0x09c87dde, 0x92bb970a, + 0xe45eae37, 0x7f2d44e3, 0x0994dc4d, 0x92e73699, 0xe4020fa4, + 0x7f71e570, 0x0803b8b4, 0x93705260, 0xe5956b5d, 0x7ee68189, + 0x085f1927, 0x932cf3f3, 0xe5c9cace, 0x7eba201a, 0x08bafb92, + 0x93c91146, 0xe52c287b, 0x7e5fc2af, 0x08e65a01, 0x9395b0d5, + 0xe57089e8, 0x7e03633c, 0x0e5e2b50, 0x952dc184, 0xe3c8f8b9, + 0x78bb126d, 0x0e028ac3, 0x95716017, 0xe394592a, 0x78e7b3fe, + 0x0ee76876, 0x959482a2, 0xe371bb9f, 0x7802514b, 0x0ebbc9e5, + 0x95c82331, 0xe32d1a0c, 0x785ef0d8, 0x0f2cad1c, 0x945f47c8, + 0xe2ba7ef5, 0x79c99421, 0x0f700c8f, 0x9403e65b, 0xe2e6df66, + 0x799535b2, 0x0f95ee3a, 0x94e604ee, 0xe2033dd3, 0x7970d707, + 0x0fc94fa9, 0x94baa57d, 0xe25f9c40, 0x792c7694, 0x0cbb27c8, + 0x97c8cd1c, 0xe12df421, 0x7a5e1ef5, 0x0ce7865b, 0x97946c8f, + 0xe17155b2, 0x7a02bf66, 0x0c0264ee, 0x97718e3a, 0xe194b707, + 0x7ae75dd3, 0x0c5ec57d, 0x972d2fa9, 0xe1c81694, 0x7abbfc40, + 0x0dc9a184, 0x96ba4b50, 0xe05f726d, 0x7b2c98b9, 0x0d950017, + 0x96e6eac3, 0xe003d3fe, 0x7b70392a, 0x0d70e2a2, 0x96030876, + 0xe0e6314b, 0x7b95db9f, 0x0d2c4331, 0x965fa9e5, 0xe0ba90d8, + 0x7bc97a0c}, + {0x00000000, 0x172864c0, 0x2e50c980, 0x3978ad40, 0x5ca19300, + 0x4b89f7c0, 0x72f15a80, 0x65d93e40, 0xb9432600, 0xae6b42c0, + 0x9713ef80, 0x803b8b40, 0xe5e2b500, 0xf2cad1c0, 0xcbb27c80, + 0xdc9a1840, 0xa9f74a41, 0xbedf2e81, 0x87a783c1, 0x908fe701, + 0xf556d941, 0xe27ebd81, 0xdb0610c1, 0xcc2e7401, 0x10b46c41, + 0x079c0881, 0x3ee4a5c1, 0x29ccc101, 0x4c15ff41, 0x5b3d9b81, + 0x624536c1, 0x756d5201, 0x889f92c3, 0x9fb7f603, 0xa6cf5b43, + 0xb1e73f83, 0xd43e01c3, 0xc3166503, 0xfa6ec843, 0xed46ac83, + 0x31dcb4c3, 0x26f4d003, 0x1f8c7d43, 0x08a41983, 0x6d7d27c3, + 0x7a554303, 0x432dee43, 0x54058a83, 0x2168d882, 0x3640bc42, + 0x0f381102, 0x181075c2, 0x7dc94b82, 0x6ae12f42, 0x53998202, + 0x44b1e6c2, 0x982bfe82, 0x8f039a42, 0xb67b3702, 0xa15353c2, + 0xc48a6d82, 0xd3a20942, 0xeadaa402, 0xfdf2c0c2, 0xca4e23c7, + 0xdd664707, 0xe41eea47, 0xf3368e87, 0x96efb0c7, 0x81c7d407, + 0xb8bf7947, 0xaf971d87, 0x730d05c7, 0x64256107, 0x5d5dcc47, + 0x4a75a887, 0x2fac96c7, 0x3884f207, 0x01fc5f47, 0x16d43b87, + 0x63b96986, 0x74910d46, 0x4de9a006, 0x5ac1c4c6, 0x3f18fa86, + 0x28309e46, 0x11483306, 0x066057c6, 0xdafa4f86, 0xcdd22b46, + 0xf4aa8606, 0xe382e2c6, 0x865bdc86, 0x9173b846, 0xa80b1506, + 0xbf2371c6, 0x42d1b104, 0x55f9d5c4, 0x6c817884, 0x7ba91c44, + 0x1e702204, 0x095846c4, 0x3020eb84, 0x27088f44, 0xfb929704, + 0xecbaf3c4, 0xd5c25e84, 0xc2ea3a44, 0xa7330404, 0xb01b60c4, + 0x8963cd84, 0x9e4ba944, 0xeb26fb45, 0xfc0e9f85, 0xc57632c5, + 0xd25e5605, 0xb7876845, 0xa0af0c85, 0x99d7a1c5, 0x8effc505, + 0x5265dd45, 0x454db985, 0x7c3514c5, 0x6b1d7005, 0x0ec44e45, + 0x19ec2a85, 0x209487c5, 0x37bce305, 0x4fed41cf, 0x58c5250f, + 0x61bd884f, 0x7695ec8f, 0x134cd2cf, 0x0464b60f, 0x3d1c1b4f, + 0x2a347f8f, 0xf6ae67cf, 0xe186030f, 0xd8feae4f, 0xcfd6ca8f, + 0xaa0ff4cf, 0xbd27900f, 0x845f3d4f, 0x9377598f, 0xe61a0b8e, + 0xf1326f4e, 0xc84ac20e, 0xdf62a6ce, 0xbabb988e, 0xad93fc4e, + 0x94eb510e, 0x83c335ce, 0x5f592d8e, 0x4871494e, 0x7109e40e, + 0x662180ce, 0x03f8be8e, 0x14d0da4e, 0x2da8770e, 0x3a8013ce, + 0xc772d30c, 0xd05ab7cc, 0xe9221a8c, 0xfe0a7e4c, 0x9bd3400c, + 0x8cfb24cc, 0xb583898c, 0xa2abed4c, 0x7e31f50c, 0x691991cc, + 0x50613c8c, 0x4749584c, 0x2290660c, 0x35b802cc, 0x0cc0af8c, + 0x1be8cb4c, 0x6e85994d, 0x79adfd8d, 0x40d550cd, 0x57fd340d, + 0x32240a4d, 0x250c6e8d, 0x1c74c3cd, 0x0b5ca70d, 0xd7c6bf4d, + 0xc0eedb8d, 0xf99676cd, 0xeebe120d, 0x8b672c4d, 0x9c4f488d, + 0xa537e5cd, 0xb21f810d, 0x85a36208, 0x928b06c8, 0xabf3ab88, + 0xbcdbcf48, 0xd902f108, 0xce2a95c8, 0xf7523888, 0xe07a5c48, + 0x3ce04408, 0x2bc820c8, 0x12b08d88, 0x0598e948, 0x6041d708, + 0x7769b3c8, 0x4e111e88, 0x59397a48, 0x2c542849, 0x3b7c4c89, + 0x0204e1c9, 0x152c8509, 0x70f5bb49, 0x67dddf89, 0x5ea572c9, + 0x498d1609, 0x95170e49, 0x823f6a89, 0xbb47c7c9, 0xac6fa309, + 0xc9b69d49, 0xde9ef989, 0xe7e654c9, 0xf0ce3009, 0x0d3cf0cb, + 0x1a14940b, 0x236c394b, 0x34445d8b, 0x519d63cb, 0x46b5070b, + 0x7fcdaa4b, 0x68e5ce8b, 0xb47fd6cb, 0xa357b20b, 0x9a2f1f4b, + 0x8d077b8b, 0xe8de45cb, 0xfff6210b, 0xc68e8c4b, 0xd1a6e88b, + 0xa4cbba8a, 0xb3e3de4a, 0x8a9b730a, 0x9db317ca, 0xf86a298a, + 0xef424d4a, 0xd63ae00a, 0xc11284ca, 0x1d889c8a, 0x0aa0f84a, + 0x33d8550a, 0x24f031ca, 0x41290f8a, 0x56016b4a, 0x6f79c60a, + 0x7851a2ca}, + {0x00000000, 0x9fda839e, 0xe4c4017d, 0x7b1e82e3, 0x12f904bb, + 0x8d238725, 0xf63d05c6, 0x69e78658, 0x25f20976, 0xba288ae8, + 0xc136080b, 0x5eec8b95, 0x370b0dcd, 0xa8d18e53, 0xd3cf0cb0, + 0x4c158f2e, 0x4be412ec, 0xd43e9172, 0xaf201391, 0x30fa900f, + 0x591d1657, 0xc6c795c9, 0xbdd9172a, 0x220394b4, 0x6e161b9a, + 0xf1cc9804, 0x8ad21ae7, 0x15089979, 0x7cef1f21, 0xe3359cbf, + 0x982b1e5c, 0x07f19dc2, 0x97c825d8, 0x0812a646, 0x730c24a5, + 0xecd6a73b, 0x85312163, 0x1aeba2fd, 0x61f5201e, 0xfe2fa380, + 0xb23a2cae, 0x2de0af30, 0x56fe2dd3, 0xc924ae4d, 0xa0c32815, + 0x3f19ab8b, 0x44072968, 0xdbddaaf6, 0xdc2c3734, 0x43f6b4aa, + 0x38e83649, 0xa732b5d7, 0xced5338f, 0x510fb011, 0x2a1132f2, + 0xb5cbb16c, 0xf9de3e42, 0x6604bddc, 0x1d1a3f3f, 0x82c0bca1, + 0xeb273af9, 0x74fdb967, 0x0fe33b84, 0x9039b81a, 0xf4e14df1, + 0x6b3bce6f, 0x10254c8c, 0x8fffcf12, 0xe618494a, 0x79c2cad4, + 0x02dc4837, 0x9d06cba9, 0xd1134487, 0x4ec9c719, 0x35d745fa, + 0xaa0dc664, 0xc3ea403c, 0x5c30c3a2, 0x272e4141, 0xb8f4c2df, + 0xbf055f1d, 0x20dfdc83, 0x5bc15e60, 0xc41bddfe, 0xadfc5ba6, + 0x3226d838, 0x49385adb, 0xd6e2d945, 0x9af7566b, 0x052dd5f5, + 0x7e335716, 0xe1e9d488, 0x880e52d0, 0x17d4d14e, 0x6cca53ad, + 0xf310d033, 0x63296829, 0xfcf3ebb7, 0x87ed6954, 0x1837eaca, + 0x71d06c92, 0xee0aef0c, 0x95146def, 0x0aceee71, 0x46db615f, + 0xd901e2c1, 0xa21f6022, 0x3dc5e3bc, 0x542265e4, 0xcbf8e67a, + 0xb0e66499, 0x2f3ce707, 0x28cd7ac5, 0xb717f95b, 0xcc097bb8, + 0x53d3f826, 0x3a347e7e, 0xa5eefde0, 0xdef07f03, 0x412afc9d, + 0x0d3f73b3, 0x92e5f02d, 0xe9fb72ce, 0x7621f150, 0x1fc67708, + 0x801cf496, 0xfb027675, 0x64d8f5eb, 0x32b39da3, 0xad691e3d, + 0xd6779cde, 0x49ad1f40, 0x204a9918, 0xbf901a86, 0xc48e9865, + 0x5b541bfb, 0x174194d5, 0x889b174b, 0xf38595a8, 0x6c5f1636, + 0x05b8906e, 0x9a6213f0, 0xe17c9113, 0x7ea6128d, 0x79578f4f, + 0xe68d0cd1, 0x9d938e32, 0x02490dac, 0x6bae8bf4, 0xf474086a, + 0x8f6a8a89, 0x10b00917, 0x5ca58639, 0xc37f05a7, 0xb8618744, + 0x27bb04da, 0x4e5c8282, 0xd186011c, 0xaa9883ff, 0x35420061, + 0xa57bb87b, 0x3aa13be5, 0x41bfb906, 0xde653a98, 0xb782bcc0, + 0x28583f5e, 0x5346bdbd, 0xcc9c3e23, 0x8089b10d, 0x1f533293, + 0x644db070, 0xfb9733ee, 0x9270b5b6, 0x0daa3628, 0x76b4b4cb, + 0xe96e3755, 0xee9faa97, 0x71452909, 0x0a5babea, 0x95812874, + 0xfc66ae2c, 0x63bc2db2, 0x18a2af51, 0x87782ccf, 0xcb6da3e1, + 0x54b7207f, 0x2fa9a29c, 0xb0732102, 0xd994a75a, 0x464e24c4, + 0x3d50a627, 0xa28a25b9, 0xc652d052, 0x598853cc, 0x2296d12f, + 0xbd4c52b1, 0xd4abd4e9, 0x4b715777, 0x306fd594, 0xafb5560a, + 0xe3a0d924, 0x7c7a5aba, 0x0764d859, 0x98be5bc7, 0xf159dd9f, + 0x6e835e01, 0x159ddce2, 0x8a475f7c, 0x8db6c2be, 0x126c4120, + 0x6972c3c3, 0xf6a8405d, 0x9f4fc605, 0x0095459b, 0x7b8bc778, + 0xe45144e6, 0xa844cbc8, 0x379e4856, 0x4c80cab5, 0xd35a492b, + 0xbabdcf73, 0x25674ced, 0x5e79ce0e, 0xc1a34d90, 0x519af58a, + 0xce407614, 0xb55ef4f7, 0x2a847769, 0x4363f131, 0xdcb972af, + 0xa7a7f04c, 0x387d73d2, 0x7468fcfc, 0xebb27f62, 0x90acfd81, + 0x0f767e1f, 0x6691f847, 0xf94b7bd9, 0x8255f93a, 0x1d8f7aa4, + 0x1a7ee766, 0x85a464f8, 0xfebae61b, 0x61606585, 0x0887e3dd, + 0x975d6043, 0xec43e2a0, 0x7399613e, 0x3f8cee10, 0xa0566d8e, + 0xdb48ef6d, 0x44926cf3, 0x2d75eaab, 0xb2af6935, 0xc9b1ebd6, + 0x566b6848}, + {0x00000000, 0x65673b46, 0xcace768c, 0xafa94dca, 0x4eedeb59, + 0x2b8ad01f, 0x84239dd5, 0xe144a693, 0x9ddbd6b2, 0xf8bcedf4, + 0x5715a03e, 0x32729b78, 0xd3363deb, 0xb65106ad, 0x19f84b67, + 0x7c9f7021, 0xe0c6ab25, 0x85a19063, 0x2a08dda9, 0x4f6fe6ef, + 0xae2b407c, 0xcb4c7b3a, 0x64e536f0, 0x01820db6, 0x7d1d7d97, + 0x187a46d1, 0xb7d30b1b, 0xd2b4305d, 0x33f096ce, 0x5697ad88, + 0xf93ee042, 0x9c59db04, 0x1afc500b, 0x7f9b6b4d, 0xd0322687, + 0xb5551dc1, 0x5411bb52, 0x31768014, 0x9edfcdde, 0xfbb8f698, + 0x872786b9, 0xe240bdff, 0x4de9f035, 0x288ecb73, 0xc9ca6de0, + 0xacad56a6, 0x03041b6c, 0x6663202a, 0xfa3afb2e, 0x9f5dc068, + 0x30f48da2, 0x5593b6e4, 0xb4d71077, 0xd1b02b31, 0x7e1966fb, + 0x1b7e5dbd, 0x67e12d9c, 0x028616da, 0xad2f5b10, 0xc8486056, + 0x290cc6c5, 0x4c6bfd83, 0xe3c2b049, 0x86a58b0f, 0x35f8a016, + 0x509f9b50, 0xff36d69a, 0x9a51eddc, 0x7b154b4f, 0x1e727009, + 0xb1db3dc3, 0xd4bc0685, 0xa82376a4, 0xcd444de2, 0x62ed0028, + 0x078a3b6e, 0xe6ce9dfd, 0x83a9a6bb, 0x2c00eb71, 0x4967d037, + 0xd53e0b33, 0xb0593075, 0x1ff07dbf, 0x7a9746f9, 0x9bd3e06a, + 0xfeb4db2c, 0x511d96e6, 0x347aada0, 0x48e5dd81, 0x2d82e6c7, + 0x822bab0d, 0xe74c904b, 0x060836d8, 0x636f0d9e, 0xccc64054, + 0xa9a17b12, 0x2f04f01d, 0x4a63cb5b, 0xe5ca8691, 0x80adbdd7, + 0x61e91b44, 0x048e2002, 0xab276dc8, 0xce40568e, 0xb2df26af, + 0xd7b81de9, 0x78115023, 0x1d766b65, 0xfc32cdf6, 0x9955f6b0, + 0x36fcbb7a, 0x539b803c, 0xcfc25b38, 0xaaa5607e, 0x050c2db4, + 0x606b16f2, 0x812fb061, 0xe4488b27, 0x4be1c6ed, 0x2e86fdab, + 0x52198d8a, 0x377eb6cc, 0x98d7fb06, 0xfdb0c040, 0x1cf466d3, + 0x79935d95, 0xd63a105f, 0xb35d2b19, 0x6bf1402c, 0x0e967b6a, + 0xa13f36a0, 0xc4580de6, 0x251cab75, 0x407b9033, 0xefd2ddf9, + 0x8ab5e6bf, 0xf62a969e, 0x934dadd8, 0x3ce4e012, 0x5983db54, + 0xb8c77dc7, 0xdda04681, 0x72090b4b, 0x176e300d, 0x8b37eb09, + 0xee50d04f, 0x41f99d85, 0x249ea6c3, 0xc5da0050, 0xa0bd3b16, + 0x0f1476dc, 0x6a734d9a, 0x16ec3dbb, 0x738b06fd, 0xdc224b37, + 0xb9457071, 0x5801d6e2, 0x3d66eda4, 0x92cfa06e, 0xf7a89b28, + 0x710d1027, 0x146a2b61, 0xbbc366ab, 0xdea45ded, 0x3fe0fb7e, + 0x5a87c038, 0xf52e8df2, 0x9049b6b4, 0xecd6c695, 0x89b1fdd3, + 0x2618b019, 0x437f8b5f, 0xa23b2dcc, 0xc75c168a, 0x68f55b40, + 0x0d926006, 0x91cbbb02, 0xf4ac8044, 0x5b05cd8e, 0x3e62f6c8, + 0xdf26505b, 0xba416b1d, 0x15e826d7, 0x708f1d91, 0x0c106db0, + 0x697756f6, 0xc6de1b3c, 0xa3b9207a, 0x42fd86e9, 0x279abdaf, + 0x8833f065, 0xed54cb23, 0x5e09e03a, 0x3b6edb7c, 0x94c796b6, + 0xf1a0adf0, 0x10e40b63, 0x75833025, 0xda2a7def, 0xbf4d46a9, + 0xc3d23688, 0xa6b50dce, 0x091c4004, 0x6c7b7b42, 0x8d3fddd1, + 0xe858e697, 0x47f1ab5d, 0x2296901b, 0xbecf4b1f, 0xdba87059, + 0x74013d93, 0x116606d5, 0xf022a046, 0x95459b00, 0x3aecd6ca, + 0x5f8bed8c, 0x23149dad, 0x4673a6eb, 0xe9daeb21, 0x8cbdd067, + 0x6df976f4, 0x089e4db2, 0xa7370078, 0xc2503b3e, 0x44f5b031, + 0x21928b77, 0x8e3bc6bd, 0xeb5cfdfb, 0x0a185b68, 0x6f7f602e, + 0xc0d62de4, 0xa5b116a2, 0xd92e6683, 0xbc495dc5, 0x13e0100f, + 0x76872b49, 0x97c38dda, 0xf2a4b69c, 0x5d0dfb56, 0x386ac010, + 0xa4331b14, 0xc1542052, 0x6efd6d98, 0x0b9a56de, 0xeadef04d, + 0x8fb9cb0b, 0x201086c1, 0x4577bd87, 0x39e8cda6, 0x5c8ff6e0, + 0xf326bb2a, 0x9641806c, 0x770526ff, 0x12621db9, 0xbdcb5073, + 0xd8ac6b35}, + {0x00000000, 0xd7e28058, 0x74b406f1, 0xa35686a9, 0xe9680de2, + 0x3e8a8dba, 0x9ddc0b13, 0x4a3e8b4b, 0x09a11d85, 0xde439ddd, + 0x7d151b74, 0xaaf79b2c, 0xe0c91067, 0x372b903f, 0x947d1696, + 0x439f96ce, 0x13423b0a, 0xc4a0bb52, 0x67f63dfb, 0xb014bda3, + 0xfa2a36e8, 0x2dc8b6b0, 0x8e9e3019, 0x597cb041, 0x1ae3268f, + 0xcd01a6d7, 0x6e57207e, 0xb9b5a026, 0xf38b2b6d, 0x2469ab35, + 0x873f2d9c, 0x50ddadc4, 0x26847614, 0xf166f64c, 0x523070e5, + 0x85d2f0bd, 0xcfec7bf6, 0x180efbae, 0xbb587d07, 0x6cbafd5f, + 0x2f256b91, 0xf8c7ebc9, 0x5b916d60, 0x8c73ed38, 0xc64d6673, + 0x11afe62b, 0xb2f96082, 0x651be0da, 0x35c64d1e, 0xe224cd46, + 0x41724bef, 0x9690cbb7, 0xdcae40fc, 0x0b4cc0a4, 0xa81a460d, + 0x7ff8c655, 0x3c67509b, 0xeb85d0c3, 0x48d3566a, 0x9f31d632, + 0xd50f5d79, 0x02eddd21, 0xa1bb5b88, 0x7659dbd0, 0x4d08ec28, + 0x9aea6c70, 0x39bcead9, 0xee5e6a81, 0xa460e1ca, 0x73826192, + 0xd0d4e73b, 0x07366763, 0x44a9f1ad, 0x934b71f5, 0x301df75c, + 0xe7ff7704, 0xadc1fc4f, 0x7a237c17, 0xd975fabe, 0x0e977ae6, + 0x5e4ad722, 0x89a8577a, 0x2afed1d3, 0xfd1c518b, 0xb722dac0, + 0x60c05a98, 0xc396dc31, 0x14745c69, 0x57ebcaa7, 0x80094aff, + 0x235fcc56, 0xf4bd4c0e, 0xbe83c745, 0x6961471d, 0xca37c1b4, + 0x1dd541ec, 0x6b8c9a3c, 0xbc6e1a64, 0x1f389ccd, 0xc8da1c95, + 0x82e497de, 0x55061786, 0xf650912f, 0x21b21177, 0x622d87b9, + 0xb5cf07e1, 0x16998148, 0xc17b0110, 0x8b458a5b, 0x5ca70a03, + 0xfff18caa, 0x28130cf2, 0x78cea136, 0xaf2c216e, 0x0c7aa7c7, + 0xdb98279f, 0x91a6acd4, 0x46442c8c, 0xe512aa25, 0x32f02a7d, + 0x716fbcb3, 0xa68d3ceb, 0x05dbba42, 0xd2393a1a, 0x9807b151, + 0x4fe53109, 0xecb3b7a0, 0x3b5137f8, 0x9a11d850, 0x4df35808, + 0xeea5dea1, 0x39475ef9, 0x7379d5b2, 0xa49b55ea, 0x07cdd343, + 0xd02f531b, 0x93b0c5d5, 0x4452458d, 0xe704c324, 0x30e6437c, + 0x7ad8c837, 0xad3a486f, 0x0e6ccec6, 0xd98e4e9e, 0x8953e35a, + 0x5eb16302, 0xfde7e5ab, 0x2a0565f3, 0x603beeb8, 0xb7d96ee0, + 0x148fe849, 0xc36d6811, 0x80f2fedf, 0x57107e87, 0xf446f82e, + 0x23a47876, 0x699af33d, 0xbe787365, 0x1d2ef5cc, 0xcacc7594, + 0xbc95ae44, 0x6b772e1c, 0xc821a8b5, 0x1fc328ed, 0x55fda3a6, + 0x821f23fe, 0x2149a557, 0xf6ab250f, 0xb534b3c1, 0x62d63399, + 0xc180b530, 0x16623568, 0x5c5cbe23, 0x8bbe3e7b, 0x28e8b8d2, + 0xff0a388a, 0xafd7954e, 0x78351516, 0xdb6393bf, 0x0c8113e7, + 0x46bf98ac, 0x915d18f4, 0x320b9e5d, 0xe5e91e05, 0xa67688cb, + 0x71940893, 0xd2c28e3a, 0x05200e62, 0x4f1e8529, 0x98fc0571, + 0x3baa83d8, 0xec480380, 0xd7193478, 0x00fbb420, 0xa3ad3289, + 0x744fb2d1, 0x3e71399a, 0xe993b9c2, 0x4ac53f6b, 0x9d27bf33, + 0xdeb829fd, 0x095aa9a5, 0xaa0c2f0c, 0x7deeaf54, 0x37d0241f, + 0xe032a447, 0x436422ee, 0x9486a2b6, 0xc45b0f72, 0x13b98f2a, + 0xb0ef0983, 0x670d89db, 0x2d330290, 0xfad182c8, 0x59870461, + 0x8e658439, 0xcdfa12f7, 0x1a1892af, 0xb94e1406, 0x6eac945e, + 0x24921f15, 0xf3709f4d, 0x502619e4, 0x87c499bc, 0xf19d426c, + 0x267fc234, 0x8529449d, 0x52cbc4c5, 0x18f54f8e, 0xcf17cfd6, + 0x6c41497f, 0xbba3c927, 0xf83c5fe9, 0x2fdedfb1, 0x8c885918, + 0x5b6ad940, 0x1154520b, 0xc6b6d253, 0x65e054fa, 0xb202d4a2, + 0xe2df7966, 0x353df93e, 0x966b7f97, 0x4189ffcf, 0x0bb77484, + 0xdc55f4dc, 0x7f037275, 0xa8e1f22d, 0xeb7e64e3, 0x3c9ce4bb, + 0x9fca6212, 0x4828e24a, 0x02166901, 0xd5f4e959, 0x76a26ff0, + 0xa140efa8}, + {0x00000000, 0xef52b6e1, 0x05d46b83, 0xea86dd62, 0x0ba8d706, + 0xe4fa61e7, 0x0e7cbc85, 0xe12e0a64, 0x1751ae0c, 0xf80318ed, + 0x1285c58f, 0xfdd7736e, 0x1cf9790a, 0xf3abcfeb, 0x192d1289, + 0xf67fa468, 0x2ea35c18, 0xc1f1eaf9, 0x2b77379b, 0xc425817a, + 0x250b8b1e, 0xca593dff, 0x20dfe09d, 0xcf8d567c, 0x39f2f214, + 0xd6a044f5, 0x3c269997, 0xd3742f76, 0x325a2512, 0xdd0893f3, + 0x378e4e91, 0xd8dcf870, 0x5d46b830, 0xb2140ed1, 0x5892d3b3, + 0xb7c06552, 0x56ee6f36, 0xb9bcd9d7, 0x533a04b5, 0xbc68b254, + 0x4a17163c, 0xa545a0dd, 0x4fc37dbf, 0xa091cb5e, 0x41bfc13a, + 0xaeed77db, 0x446baab9, 0xab391c58, 0x73e5e428, 0x9cb752c9, + 0x76318fab, 0x9963394a, 0x784d332e, 0x971f85cf, 0x7d9958ad, + 0x92cbee4c, 0x64b44a24, 0x8be6fcc5, 0x616021a7, 0x8e329746, + 0x6f1c9d22, 0x804e2bc3, 0x6ac8f6a1, 0x859a4040, 0xba8d7060, + 0x55dfc681, 0xbf591be3, 0x500bad02, 0xb125a766, 0x5e771187, + 0xb4f1cce5, 0x5ba37a04, 0xaddcde6c, 0x428e688d, 0xa808b5ef, + 0x475a030e, 0xa674096a, 0x4926bf8b, 0xa3a062e9, 0x4cf2d408, + 0x942e2c78, 0x7b7c9a99, 0x91fa47fb, 0x7ea8f11a, 0x9f86fb7e, + 0x70d44d9f, 0x9a5290fd, 0x7500261c, 0x837f8274, 0x6c2d3495, + 0x86abe9f7, 0x69f95f16, 0x88d75572, 0x6785e393, 0x8d033ef1, + 0x62518810, 0xe7cbc850, 0x08997eb1, 0xe21fa3d3, 0x0d4d1532, + 0xec631f56, 0x0331a9b7, 0xe9b774d5, 0x06e5c234, 0xf09a665c, + 0x1fc8d0bd, 0xf54e0ddf, 0x1a1cbb3e, 0xfb32b15a, 0x146007bb, + 0xfee6dad9, 0x11b46c38, 0xc9689448, 0x263a22a9, 0xccbcffcb, + 0x23ee492a, 0xc2c0434e, 0x2d92f5af, 0xc71428cd, 0x28469e2c, + 0xde393a44, 0x316b8ca5, 0xdbed51c7, 0x34bfe726, 0xd591ed42, + 0x3ac35ba3, 0xd04586c1, 0x3f173020, 0xae6be681, 0x41395060, + 0xabbf8d02, 0x44ed3be3, 0xa5c33187, 0x4a918766, 0xa0175a04, + 0x4f45ece5, 0xb93a488d, 0x5668fe6c, 0xbcee230e, 0x53bc95ef, + 0xb2929f8b, 0x5dc0296a, 0xb746f408, 0x581442e9, 0x80c8ba99, + 0x6f9a0c78, 0x851cd11a, 0x6a4e67fb, 0x8b606d9f, 0x6432db7e, + 0x8eb4061c, 0x61e6b0fd, 0x97991495, 0x78cba274, 0x924d7f16, + 0x7d1fc9f7, 0x9c31c393, 0x73637572, 0x99e5a810, 0x76b71ef1, + 0xf32d5eb1, 0x1c7fe850, 0xf6f93532, 0x19ab83d3, 0xf88589b7, + 0x17d73f56, 0xfd51e234, 0x120354d5, 0xe47cf0bd, 0x0b2e465c, + 0xe1a89b3e, 0x0efa2ddf, 0xefd427bb, 0x0086915a, 0xea004c38, + 0x0552fad9, 0xdd8e02a9, 0x32dcb448, 0xd85a692a, 0x3708dfcb, + 0xd626d5af, 0x3974634e, 0xd3f2be2c, 0x3ca008cd, 0xcadfaca5, + 0x258d1a44, 0xcf0bc726, 0x205971c7, 0xc1777ba3, 0x2e25cd42, + 0xc4a31020, 0x2bf1a6c1, 0x14e696e1, 0xfbb42000, 0x1132fd62, + 0xfe604b83, 0x1f4e41e7, 0xf01cf706, 0x1a9a2a64, 0xf5c89c85, + 0x03b738ed, 0xece58e0c, 0x0663536e, 0xe931e58f, 0x081fefeb, + 0xe74d590a, 0x0dcb8468, 0xe2993289, 0x3a45caf9, 0xd5177c18, + 0x3f91a17a, 0xd0c3179b, 0x31ed1dff, 0xdebfab1e, 0x3439767c, + 0xdb6bc09d, 0x2d1464f5, 0xc246d214, 0x28c00f76, 0xc792b997, + 0x26bcb3f3, 0xc9ee0512, 0x2368d870, 0xcc3a6e91, 0x49a02ed1, + 0xa6f29830, 0x4c744552, 0xa326f3b3, 0x4208f9d7, 0xad5a4f36, + 0x47dc9254, 0xa88e24b5, 0x5ef180dd, 0xb1a3363c, 0x5b25eb5e, + 0xb4775dbf, 0x555957db, 0xba0be13a, 0x508d3c58, 0xbfdf8ab9, + 0x670372c9, 0x8851c428, 0x62d7194a, 0x8d85afab, 0x6caba5cf, + 0x83f9132e, 0x697fce4c, 0x862d78ad, 0x7052dcc5, 0x9f006a24, + 0x7586b746, 0x9ad401a7, 0x7bfa0bc3, 0x94a8bd22, 0x7e2e6040, + 0x917cd6a1}, + {0x00000000, 0x87a6cb43, 0xd43c90c7, 0x539a5b84, 0x730827cf, + 0xf4aeec8c, 0xa734b708, 0x20927c4b, 0xe6104f9e, 0x61b684dd, + 0x322cdf59, 0xb58a141a, 0x95186851, 0x12bea312, 0x4124f896, + 0xc68233d5, 0x1751997d, 0x90f7523e, 0xc36d09ba, 0x44cbc2f9, + 0x6459beb2, 0xe3ff75f1, 0xb0652e75, 0x37c3e536, 0xf141d6e3, + 0x76e71da0, 0x257d4624, 0xa2db8d67, 0x8249f12c, 0x05ef3a6f, + 0x567561eb, 0xd1d3aaa8, 0x2ea332fa, 0xa905f9b9, 0xfa9fa23d, + 0x7d39697e, 0x5dab1535, 0xda0dde76, 0x899785f2, 0x0e314eb1, + 0xc8b37d64, 0x4f15b627, 0x1c8feda3, 0x9b2926e0, 0xbbbb5aab, + 0x3c1d91e8, 0x6f87ca6c, 0xe821012f, 0x39f2ab87, 0xbe5460c4, + 0xedce3b40, 0x6a68f003, 0x4afa8c48, 0xcd5c470b, 0x9ec61c8f, + 0x1960d7cc, 0xdfe2e419, 0x58442f5a, 0x0bde74de, 0x8c78bf9d, + 0xaceac3d6, 0x2b4c0895, 0x78d65311, 0xff709852, 0x5d4665f4, + 0xdae0aeb7, 0x897af533, 0x0edc3e70, 0x2e4e423b, 0xa9e88978, + 0xfa72d2fc, 0x7dd419bf, 0xbb562a6a, 0x3cf0e129, 0x6f6abaad, + 0xe8cc71ee, 0xc85e0da5, 0x4ff8c6e6, 0x1c629d62, 0x9bc45621, + 0x4a17fc89, 0xcdb137ca, 0x9e2b6c4e, 0x198da70d, 0x391fdb46, + 0xbeb91005, 0xed234b81, 0x6a8580c2, 0xac07b317, 0x2ba17854, + 0x783b23d0, 0xff9de893, 0xdf0f94d8, 0x58a95f9b, 0x0b33041f, + 0x8c95cf5c, 0x73e5570e, 0xf4439c4d, 0xa7d9c7c9, 0x207f0c8a, + 0x00ed70c1, 0x874bbb82, 0xd4d1e006, 0x53772b45, 0x95f51890, + 0x1253d3d3, 0x41c98857, 0xc66f4314, 0xe6fd3f5f, 0x615bf41c, + 0x32c1af98, 0xb56764db, 0x64b4ce73, 0xe3120530, 0xb0885eb4, + 0x372e95f7, 0x17bce9bc, 0x901a22ff, 0xc380797b, 0x4426b238, + 0x82a481ed, 0x05024aae, 0x5698112a, 0xd13eda69, 0xf1aca622, + 0x760a6d61, 0x259036e5, 0xa236fda6, 0xba8ccbe8, 0x3d2a00ab, + 0x6eb05b2f, 0xe916906c, 0xc984ec27, 0x4e222764, 0x1db87ce0, + 0x9a1eb7a3, 0x5c9c8476, 0xdb3a4f35, 0x88a014b1, 0x0f06dff2, + 0x2f94a3b9, 0xa83268fa, 0xfba8337e, 0x7c0ef83d, 0xaddd5295, + 0x2a7b99d6, 0x79e1c252, 0xfe470911, 0xded5755a, 0x5973be19, + 0x0ae9e59d, 0x8d4f2ede, 0x4bcd1d0b, 0xcc6bd648, 0x9ff18dcc, + 0x1857468f, 0x38c53ac4, 0xbf63f187, 0xecf9aa03, 0x6b5f6140, + 0x942ff912, 0x13893251, 0x401369d5, 0xc7b5a296, 0xe727dedd, + 0x6081159e, 0x331b4e1a, 0xb4bd8559, 0x723fb68c, 0xf5997dcf, + 0xa603264b, 0x21a5ed08, 0x01379143, 0x86915a00, 0xd50b0184, + 0x52adcac7, 0x837e606f, 0x04d8ab2c, 0x5742f0a8, 0xd0e43beb, + 0xf07647a0, 0x77d08ce3, 0x244ad767, 0xa3ec1c24, 0x656e2ff1, + 0xe2c8e4b2, 0xb152bf36, 0x36f47475, 0x1666083e, 0x91c0c37d, + 0xc25a98f9, 0x45fc53ba, 0xe7caae1c, 0x606c655f, 0x33f63edb, + 0xb450f598, 0x94c289d3, 0x13644290, 0x40fe1914, 0xc758d257, + 0x01dae182, 0x867c2ac1, 0xd5e67145, 0x5240ba06, 0x72d2c64d, + 0xf5740d0e, 0xa6ee568a, 0x21489dc9, 0xf09b3761, 0x773dfc22, + 0x24a7a7a6, 0xa3016ce5, 0x839310ae, 0x0435dbed, 0x57af8069, + 0xd0094b2a, 0x168b78ff, 0x912db3bc, 0xc2b7e838, 0x4511237b, + 0x65835f30, 0xe2259473, 0xb1bfcff7, 0x361904b4, 0xc9699ce6, + 0x4ecf57a5, 0x1d550c21, 0x9af3c762, 0xba61bb29, 0x3dc7706a, + 0x6e5d2bee, 0xe9fbe0ad, 0x2f79d378, 0xa8df183b, 0xfb4543bf, + 0x7ce388fc, 0x5c71f4b7, 0xdbd73ff4, 0x884d6470, 0x0febaf33, + 0xde38059b, 0x599eced8, 0x0a04955c, 0x8da25e1f, 0xad302254, + 0x2a96e917, 0x790cb293, 0xfeaa79d0, 0x38284a05, 0xbf8e8146, + 0xec14dac2, 0x6bb21181, 0x4b206dca, 0xcc86a689, 0x9f1cfd0d, + 0x18ba364e}}; + +local const z_word_t FAR crc_braid_big_table[][256] = { + {0x0000000000000000, 0x43cba68700000000, 0xc7903cd400000000, + 0x845b9a5300000000, 0xcf27087300000000, 0x8cecaef400000000, + 0x08b734a700000000, 0x4b7c922000000000, 0x9e4f10e600000000, + 0xdd84b66100000000, 0x59df2c3200000000, 0x1a148ab500000000, + 0x5168189500000000, 0x12a3be1200000000, 0x96f8244100000000, + 0xd53382c600000000, 0x7d99511700000000, 0x3e52f79000000000, + 0xba096dc300000000, 0xf9c2cb4400000000, 0xb2be596400000000, + 0xf175ffe300000000, 0x752e65b000000000, 0x36e5c33700000000, + 0xe3d641f100000000, 0xa01de77600000000, 0x24467d2500000000, + 0x678ddba200000000, 0x2cf1498200000000, 0x6f3aef0500000000, + 0xeb61755600000000, 0xa8aad3d100000000, 0xfa32a32e00000000, + 0xb9f905a900000000, 0x3da29ffa00000000, 0x7e69397d00000000, + 0x3515ab5d00000000, 0x76de0dda00000000, 0xf285978900000000, + 0xb14e310e00000000, 0x647db3c800000000, 0x27b6154f00000000, + 0xa3ed8f1c00000000, 0xe026299b00000000, 0xab5abbbb00000000, + 0xe8911d3c00000000, 0x6cca876f00000000, 0x2f0121e800000000, + 0x87abf23900000000, 0xc46054be00000000, 0x403bceed00000000, + 0x03f0686a00000000, 0x488cfa4a00000000, 0x0b475ccd00000000, + 0x8f1cc69e00000000, 0xccd7601900000000, 0x19e4e2df00000000, + 0x5a2f445800000000, 0xde74de0b00000000, 0x9dbf788c00000000, + 0xd6c3eaac00000000, 0x95084c2b00000000, 0x1153d67800000000, + 0x529870ff00000000, 0xf465465d00000000, 0xb7aee0da00000000, + 0x33f57a8900000000, 0x703edc0e00000000, 0x3b424e2e00000000, + 0x7889e8a900000000, 0xfcd272fa00000000, 0xbf19d47d00000000, + 0x6a2a56bb00000000, 0x29e1f03c00000000, 0xadba6a6f00000000, + 0xee71cce800000000, 0xa50d5ec800000000, 0xe6c6f84f00000000, + 0x629d621c00000000, 0x2156c49b00000000, 0x89fc174a00000000, + 0xca37b1cd00000000, 0x4e6c2b9e00000000, 0x0da78d1900000000, + 0x46db1f3900000000, 0x0510b9be00000000, 0x814b23ed00000000, + 0xc280856a00000000, 0x17b307ac00000000, 0x5478a12b00000000, + 0xd0233b7800000000, 0x93e89dff00000000, 0xd8940fdf00000000, + 0x9b5fa95800000000, 0x1f04330b00000000, 0x5ccf958c00000000, + 0x0e57e57300000000, 0x4d9c43f400000000, 0xc9c7d9a700000000, + 0x8a0c7f2000000000, 0xc170ed0000000000, 0x82bb4b8700000000, + 0x06e0d1d400000000, 0x452b775300000000, 0x9018f59500000000, + 0xd3d3531200000000, 0x5788c94100000000, 0x14436fc600000000, + 0x5f3ffde600000000, 0x1cf45b6100000000, 0x98afc13200000000, + 0xdb6467b500000000, 0x73ceb46400000000, 0x300512e300000000, + 0xb45e88b000000000, 0xf7952e3700000000, 0xbce9bc1700000000, + 0xff221a9000000000, 0x7b7980c300000000, 0x38b2264400000000, + 0xed81a48200000000, 0xae4a020500000000, 0x2a11985600000000, + 0x69da3ed100000000, 0x22a6acf100000000, 0x616d0a7600000000, + 0xe536902500000000, 0xa6fd36a200000000, 0xe8cb8cba00000000, + 0xab002a3d00000000, 0x2f5bb06e00000000, 0x6c9016e900000000, + 0x27ec84c900000000, 0x6427224e00000000, 0xe07cb81d00000000, + 0xa3b71e9a00000000, 0x76849c5c00000000, 0x354f3adb00000000, + 0xb114a08800000000, 0xf2df060f00000000, 0xb9a3942f00000000, + 0xfa6832a800000000, 0x7e33a8fb00000000, 0x3df80e7c00000000, + 0x9552ddad00000000, 0xd6997b2a00000000, 0x52c2e17900000000, + 0x110947fe00000000, 0x5a75d5de00000000, 0x19be735900000000, + 0x9de5e90a00000000, 0xde2e4f8d00000000, 0x0b1dcd4b00000000, + 0x48d66bcc00000000, 0xcc8df19f00000000, 0x8f46571800000000, + 0xc43ac53800000000, 0x87f163bf00000000, 0x03aaf9ec00000000, + 0x40615f6b00000000, 0x12f92f9400000000, 0x5132891300000000, + 0xd569134000000000, 0x96a2b5c700000000, 0xddde27e700000000, + 0x9e15816000000000, 0x1a4e1b3300000000, 0x5985bdb400000000, + 0x8cb63f7200000000, 0xcf7d99f500000000, 0x4b2603a600000000, + 0x08eda52100000000, 0x4391370100000000, 0x005a918600000000, + 0x84010bd500000000, 0xc7caad5200000000, 0x6f607e8300000000, + 0x2cabd80400000000, 0xa8f0425700000000, 0xeb3be4d000000000, + 0xa04776f000000000, 0xe38cd07700000000, 0x67d74a2400000000, + 0x241ceca300000000, 0xf12f6e6500000000, 0xb2e4c8e200000000, + 0x36bf52b100000000, 0x7574f43600000000, 0x3e08661600000000, + 0x7dc3c09100000000, 0xf9985ac200000000, 0xba53fc4500000000, + 0x1caecae700000000, 0x5f656c6000000000, 0xdb3ef63300000000, + 0x98f550b400000000, 0xd389c29400000000, 0x9042641300000000, + 0x1419fe4000000000, 0x57d258c700000000, 0x82e1da0100000000, + 0xc12a7c8600000000, 0x4571e6d500000000, 0x06ba405200000000, + 0x4dc6d27200000000, 0x0e0d74f500000000, 0x8a56eea600000000, + 0xc99d482100000000, 0x61379bf000000000, 0x22fc3d7700000000, + 0xa6a7a72400000000, 0xe56c01a300000000, 0xae10938300000000, + 0xeddb350400000000, 0x6980af5700000000, 0x2a4b09d000000000, + 0xff788b1600000000, 0xbcb32d9100000000, 0x38e8b7c200000000, + 0x7b23114500000000, 0x305f836500000000, 0x739425e200000000, + 0xf7cfbfb100000000, 0xb404193600000000, 0xe69c69c900000000, + 0xa557cf4e00000000, 0x210c551d00000000, 0x62c7f39a00000000, + 0x29bb61ba00000000, 0x6a70c73d00000000, 0xee2b5d6e00000000, + 0xade0fbe900000000, 0x78d3792f00000000, 0x3b18dfa800000000, + 0xbf4345fb00000000, 0xfc88e37c00000000, 0xb7f4715c00000000, + 0xf43fd7db00000000, 0x70644d8800000000, 0x33afeb0f00000000, + 0x9b0538de00000000, 0xd8ce9e5900000000, 0x5c95040a00000000, + 0x1f5ea28d00000000, 0x542230ad00000000, 0x17e9962a00000000, + 0x93b20c7900000000, 0xd079aafe00000000, 0x054a283800000000, + 0x46818ebf00000000, 0xc2da14ec00000000, 0x8111b26b00000000, + 0xca6d204b00000000, 0x89a686cc00000000, 0x0dfd1c9f00000000, + 0x4e36ba1800000000}, + {0x0000000000000000, 0xe1b652ef00000000, 0x836bd40500000000, + 0x62dd86ea00000000, 0x06d7a80b00000000, 0xe761fae400000000, + 0x85bc7c0e00000000, 0x640a2ee100000000, 0x0cae511700000000, + 0xed1803f800000000, 0x8fc5851200000000, 0x6e73d7fd00000000, + 0x0a79f91c00000000, 0xebcfabf300000000, 0x89122d1900000000, + 0x68a47ff600000000, 0x185ca32e00000000, 0xf9eaf1c100000000, + 0x9b37772b00000000, 0x7a8125c400000000, 0x1e8b0b2500000000, + 0xff3d59ca00000000, 0x9de0df2000000000, 0x7c568dcf00000000, + 0x14f2f23900000000, 0xf544a0d600000000, 0x9799263c00000000, + 0x762f74d300000000, 0x12255a3200000000, 0xf39308dd00000000, + 0x914e8e3700000000, 0x70f8dcd800000000, 0x30b8465d00000000, + 0xd10e14b200000000, 0xb3d3925800000000, 0x5265c0b700000000, + 0x366fee5600000000, 0xd7d9bcb900000000, 0xb5043a5300000000, + 0x54b268bc00000000, 0x3c16174a00000000, 0xdda045a500000000, + 0xbf7dc34f00000000, 0x5ecb91a000000000, 0x3ac1bf4100000000, + 0xdb77edae00000000, 0xb9aa6b4400000000, 0x581c39ab00000000, + 0x28e4e57300000000, 0xc952b79c00000000, 0xab8f317600000000, + 0x4a39639900000000, 0x2e334d7800000000, 0xcf851f9700000000, + 0xad58997d00000000, 0x4ceecb9200000000, 0x244ab46400000000, + 0xc5fce68b00000000, 0xa721606100000000, 0x4697328e00000000, + 0x229d1c6f00000000, 0xc32b4e8000000000, 0xa1f6c86a00000000, + 0x40409a8500000000, 0x60708dba00000000, 0x81c6df5500000000, + 0xe31b59bf00000000, 0x02ad0b5000000000, 0x66a725b100000000, + 0x8711775e00000000, 0xe5ccf1b400000000, 0x047aa35b00000000, + 0x6cdedcad00000000, 0x8d688e4200000000, 0xefb508a800000000, + 0x0e035a4700000000, 0x6a0974a600000000, 0x8bbf264900000000, + 0xe962a0a300000000, 0x08d4f24c00000000, 0x782c2e9400000000, + 0x999a7c7b00000000, 0xfb47fa9100000000, 0x1af1a87e00000000, + 0x7efb869f00000000, 0x9f4dd47000000000, 0xfd90529a00000000, + 0x1c26007500000000, 0x74827f8300000000, 0x95342d6c00000000, + 0xf7e9ab8600000000, 0x165ff96900000000, 0x7255d78800000000, + 0x93e3856700000000, 0xf13e038d00000000, 0x1088516200000000, + 0x50c8cbe700000000, 0xb17e990800000000, 0xd3a31fe200000000, + 0x32154d0d00000000, 0x561f63ec00000000, 0xb7a9310300000000, + 0xd574b7e900000000, 0x34c2e50600000000, 0x5c669af000000000, + 0xbdd0c81f00000000, 0xdf0d4ef500000000, 0x3ebb1c1a00000000, + 0x5ab132fb00000000, 0xbb07601400000000, 0xd9dae6fe00000000, + 0x386cb41100000000, 0x489468c900000000, 0xa9223a2600000000, + 0xcbffbccc00000000, 0x2a49ee2300000000, 0x4e43c0c200000000, + 0xaff5922d00000000, 0xcd2814c700000000, 0x2c9e462800000000, + 0x443a39de00000000, 0xa58c6b3100000000, 0xc751eddb00000000, + 0x26e7bf3400000000, 0x42ed91d500000000, 0xa35bc33a00000000, + 0xc18645d000000000, 0x2030173f00000000, 0x81e66bae00000000, + 0x6050394100000000, 0x028dbfab00000000, 0xe33bed4400000000, + 0x8731c3a500000000, 0x6687914a00000000, 0x045a17a000000000, + 0xe5ec454f00000000, 0x8d483ab900000000, 0x6cfe685600000000, + 0x0e23eebc00000000, 0xef95bc5300000000, 0x8b9f92b200000000, + 0x6a29c05d00000000, 0x08f446b700000000, 0xe942145800000000, + 0x99bac88000000000, 0x780c9a6f00000000, 0x1ad11c8500000000, + 0xfb674e6a00000000, 0x9f6d608b00000000, 0x7edb326400000000, + 0x1c06b48e00000000, 0xfdb0e66100000000, 0x9514999700000000, + 0x74a2cb7800000000, 0x167f4d9200000000, 0xf7c91f7d00000000, + 0x93c3319c00000000, 0x7275637300000000, 0x10a8e59900000000, + 0xf11eb77600000000, 0xb15e2df300000000, 0x50e87f1c00000000, + 0x3235f9f600000000, 0xd383ab1900000000, 0xb78985f800000000, + 0x563fd71700000000, 0x34e251fd00000000, 0xd554031200000000, + 0xbdf07ce400000000, 0x5c462e0b00000000, 0x3e9ba8e100000000, + 0xdf2dfa0e00000000, 0xbb27d4ef00000000, 0x5a91860000000000, + 0x384c00ea00000000, 0xd9fa520500000000, 0xa9028edd00000000, + 0x48b4dc3200000000, 0x2a695ad800000000, 0xcbdf083700000000, + 0xafd526d600000000, 0x4e63743900000000, 0x2cbef2d300000000, + 0xcd08a03c00000000, 0xa5acdfca00000000, 0x441a8d2500000000, + 0x26c70bcf00000000, 0xc771592000000000, 0xa37b77c100000000, + 0x42cd252e00000000, 0x2010a3c400000000, 0xc1a6f12b00000000, + 0xe196e61400000000, 0x0020b4fb00000000, 0x62fd321100000000, + 0x834b60fe00000000, 0xe7414e1f00000000, 0x06f71cf000000000, + 0x642a9a1a00000000, 0x859cc8f500000000, 0xed38b70300000000, + 0x0c8ee5ec00000000, 0x6e53630600000000, 0x8fe531e900000000, + 0xebef1f0800000000, 0x0a594de700000000, 0x6884cb0d00000000, + 0x893299e200000000, 0xf9ca453a00000000, 0x187c17d500000000, + 0x7aa1913f00000000, 0x9b17c3d000000000, 0xff1ded3100000000, + 0x1eabbfde00000000, 0x7c76393400000000, 0x9dc06bdb00000000, + 0xf564142d00000000, 0x14d246c200000000, 0x760fc02800000000, + 0x97b992c700000000, 0xf3b3bc2600000000, 0x1205eec900000000, + 0x70d8682300000000, 0x916e3acc00000000, 0xd12ea04900000000, + 0x3098f2a600000000, 0x5245744c00000000, 0xb3f326a300000000, + 0xd7f9084200000000, 0x364f5aad00000000, 0x5492dc4700000000, + 0xb5248ea800000000, 0xdd80f15e00000000, 0x3c36a3b100000000, + 0x5eeb255b00000000, 0xbf5d77b400000000, 0xdb57595500000000, + 0x3ae10bba00000000, 0x583c8d5000000000, 0xb98adfbf00000000, + 0xc972036700000000, 0x28c4518800000000, 0x4a19d76200000000, + 0xabaf858d00000000, 0xcfa5ab6c00000000, 0x2e13f98300000000, + 0x4cce7f6900000000, 0xad782d8600000000, 0xc5dc527000000000, + 0x246a009f00000000, 0x46b7867500000000, 0xa701d49a00000000, + 0xc30bfa7b00000000, 0x22bda89400000000, 0x40602e7e00000000, + 0xa1d67c9100000000}, + {0x0000000000000000, 0x5880e2d700000000, 0xf106b47400000000, + 0xa98656a300000000, 0xe20d68e900000000, 0xba8d8a3e00000000, + 0x130bdc9d00000000, 0x4b8b3e4a00000000, 0x851da10900000000, + 0xdd9d43de00000000, 0x741b157d00000000, 0x2c9bf7aa00000000, + 0x6710c9e000000000, 0x3f902b3700000000, 0x96167d9400000000, + 0xce969f4300000000, 0x0a3b421300000000, 0x52bba0c400000000, + 0xfb3df66700000000, 0xa3bd14b000000000, 0xe8362afa00000000, + 0xb0b6c82d00000000, 0x19309e8e00000000, 0x41b07c5900000000, + 0x8f26e31a00000000, 0xd7a601cd00000000, 0x7e20576e00000000, + 0x26a0b5b900000000, 0x6d2b8bf300000000, 0x35ab692400000000, + 0x9c2d3f8700000000, 0xc4addd5000000000, 0x1476842600000000, + 0x4cf666f100000000, 0xe570305200000000, 0xbdf0d28500000000, + 0xf67beccf00000000, 0xaefb0e1800000000, 0x077d58bb00000000, + 0x5ffdba6c00000000, 0x916b252f00000000, 0xc9ebc7f800000000, + 0x606d915b00000000, 0x38ed738c00000000, 0x73664dc600000000, + 0x2be6af1100000000, 0x8260f9b200000000, 0xdae01b6500000000, + 0x1e4dc63500000000, 0x46cd24e200000000, 0xef4b724100000000, + 0xb7cb909600000000, 0xfc40aedc00000000, 0xa4c04c0b00000000, + 0x0d461aa800000000, 0x55c6f87f00000000, 0x9b50673c00000000, + 0xc3d085eb00000000, 0x6a56d34800000000, 0x32d6319f00000000, + 0x795d0fd500000000, 0x21dded0200000000, 0x885bbba100000000, + 0xd0db597600000000, 0x28ec084d00000000, 0x706cea9a00000000, + 0xd9eabc3900000000, 0x816a5eee00000000, 0xcae160a400000000, + 0x9261827300000000, 0x3be7d4d000000000, 0x6367360700000000, + 0xadf1a94400000000, 0xf5714b9300000000, 0x5cf71d3000000000, + 0x0477ffe700000000, 0x4ffcc1ad00000000, 0x177c237a00000000, + 0xbefa75d900000000, 0xe67a970e00000000, 0x22d74a5e00000000, + 0x7a57a88900000000, 0xd3d1fe2a00000000, 0x8b511cfd00000000, + 0xc0da22b700000000, 0x985ac06000000000, 0x31dc96c300000000, + 0x695c741400000000, 0xa7caeb5700000000, 0xff4a098000000000, + 0x56cc5f2300000000, 0x0e4cbdf400000000, 0x45c783be00000000, + 0x1d47616900000000, 0xb4c137ca00000000, 0xec41d51d00000000, + 0x3c9a8c6b00000000, 0x641a6ebc00000000, 0xcd9c381f00000000, + 0x951cdac800000000, 0xde97e48200000000, 0x8617065500000000, + 0x2f9150f600000000, 0x7711b22100000000, 0xb9872d6200000000, + 0xe107cfb500000000, 0x4881991600000000, 0x10017bc100000000, + 0x5b8a458b00000000, 0x030aa75c00000000, 0xaa8cf1ff00000000, + 0xf20c132800000000, 0x36a1ce7800000000, 0x6e212caf00000000, + 0xc7a77a0c00000000, 0x9f2798db00000000, 0xd4aca69100000000, + 0x8c2c444600000000, 0x25aa12e500000000, 0x7d2af03200000000, + 0xb3bc6f7100000000, 0xeb3c8da600000000, 0x42badb0500000000, + 0x1a3a39d200000000, 0x51b1079800000000, 0x0931e54f00000000, + 0xa0b7b3ec00000000, 0xf837513b00000000, 0x50d8119a00000000, + 0x0858f34d00000000, 0xa1dea5ee00000000, 0xf95e473900000000, + 0xb2d5797300000000, 0xea559ba400000000, 0x43d3cd0700000000, + 0x1b532fd000000000, 0xd5c5b09300000000, 0x8d45524400000000, + 0x24c304e700000000, 0x7c43e63000000000, 0x37c8d87a00000000, + 0x6f483aad00000000, 0xc6ce6c0e00000000, 0x9e4e8ed900000000, + 0x5ae3538900000000, 0x0263b15e00000000, 0xabe5e7fd00000000, + 0xf365052a00000000, 0xb8ee3b6000000000, 0xe06ed9b700000000, + 0x49e88f1400000000, 0x11686dc300000000, 0xdffef28000000000, + 0x877e105700000000, 0x2ef846f400000000, 0x7678a42300000000, + 0x3df39a6900000000, 0x657378be00000000, 0xccf52e1d00000000, + 0x9475ccca00000000, 0x44ae95bc00000000, 0x1c2e776b00000000, + 0xb5a821c800000000, 0xed28c31f00000000, 0xa6a3fd5500000000, + 0xfe231f8200000000, 0x57a5492100000000, 0x0f25abf600000000, + 0xc1b334b500000000, 0x9933d66200000000, 0x30b580c100000000, + 0x6835621600000000, 0x23be5c5c00000000, 0x7b3ebe8b00000000, + 0xd2b8e82800000000, 0x8a380aff00000000, 0x4e95d7af00000000, + 0x1615357800000000, 0xbf9363db00000000, 0xe713810c00000000, + 0xac98bf4600000000, 0xf4185d9100000000, 0x5d9e0b3200000000, + 0x051ee9e500000000, 0xcb8876a600000000, 0x9308947100000000, + 0x3a8ec2d200000000, 0x620e200500000000, 0x29851e4f00000000, + 0x7105fc9800000000, 0xd883aa3b00000000, 0x800348ec00000000, + 0x783419d700000000, 0x20b4fb0000000000, 0x8932ada300000000, + 0xd1b24f7400000000, 0x9a39713e00000000, 0xc2b993e900000000, + 0x6b3fc54a00000000, 0x33bf279d00000000, 0xfd29b8de00000000, + 0xa5a95a0900000000, 0x0c2f0caa00000000, 0x54afee7d00000000, + 0x1f24d03700000000, 0x47a432e000000000, 0xee22644300000000, + 0xb6a2869400000000, 0x720f5bc400000000, 0x2a8fb91300000000, + 0x8309efb000000000, 0xdb890d6700000000, 0x9002332d00000000, + 0xc882d1fa00000000, 0x6104875900000000, 0x3984658e00000000, + 0xf712facd00000000, 0xaf92181a00000000, 0x06144eb900000000, + 0x5e94ac6e00000000, 0x151f922400000000, 0x4d9f70f300000000, + 0xe419265000000000, 0xbc99c48700000000, 0x6c429df100000000, + 0x34c27f2600000000, 0x9d44298500000000, 0xc5c4cb5200000000, + 0x8e4ff51800000000, 0xd6cf17cf00000000, 0x7f49416c00000000, + 0x27c9a3bb00000000, 0xe95f3cf800000000, 0xb1dfde2f00000000, + 0x1859888c00000000, 0x40d96a5b00000000, 0x0b52541100000000, + 0x53d2b6c600000000, 0xfa54e06500000000, 0xa2d402b200000000, + 0x6679dfe200000000, 0x3ef93d3500000000, 0x977f6b9600000000, + 0xcfff894100000000, 0x8474b70b00000000, 0xdcf455dc00000000, + 0x7572037f00000000, 0x2df2e1a800000000, 0xe3647eeb00000000, + 0xbbe49c3c00000000, 0x1262ca9f00000000, 0x4ae2284800000000, + 0x0169160200000000, 0x59e9f4d500000000, 0xf06fa27600000000, + 0xa8ef40a100000000}, + {0x0000000000000000, 0x463b676500000000, 0x8c76ceca00000000, + 0xca4da9af00000000, 0x59ebed4e00000000, 0x1fd08a2b00000000, + 0xd59d238400000000, 0x93a644e100000000, 0xb2d6db9d00000000, + 0xf4edbcf800000000, 0x3ea0155700000000, 0x789b723200000000, + 0xeb3d36d300000000, 0xad0651b600000000, 0x674bf81900000000, + 0x21709f7c00000000, 0x25abc6e000000000, 0x6390a18500000000, + 0xa9dd082a00000000, 0xefe66f4f00000000, 0x7c402bae00000000, + 0x3a7b4ccb00000000, 0xf036e56400000000, 0xb60d820100000000, + 0x977d1d7d00000000, 0xd1467a1800000000, 0x1b0bd3b700000000, + 0x5d30b4d200000000, 0xce96f03300000000, 0x88ad975600000000, + 0x42e03ef900000000, 0x04db599c00000000, 0x0b50fc1a00000000, + 0x4d6b9b7f00000000, 0x872632d000000000, 0xc11d55b500000000, + 0x52bb115400000000, 0x1480763100000000, 0xdecddf9e00000000, + 0x98f6b8fb00000000, 0xb986278700000000, 0xffbd40e200000000, + 0x35f0e94d00000000, 0x73cb8e2800000000, 0xe06dcac900000000, + 0xa656adac00000000, 0x6c1b040300000000, 0x2a20636600000000, + 0x2efb3afa00000000, 0x68c05d9f00000000, 0xa28df43000000000, + 0xe4b6935500000000, 0x7710d7b400000000, 0x312bb0d100000000, + 0xfb66197e00000000, 0xbd5d7e1b00000000, 0x9c2de16700000000, + 0xda16860200000000, 0x105b2fad00000000, 0x566048c800000000, + 0xc5c60c2900000000, 0x83fd6b4c00000000, 0x49b0c2e300000000, + 0x0f8ba58600000000, 0x16a0f83500000000, 0x509b9f5000000000, + 0x9ad636ff00000000, 0xdced519a00000000, 0x4f4b157b00000000, + 0x0970721e00000000, 0xc33ddbb100000000, 0x8506bcd400000000, + 0xa47623a800000000, 0xe24d44cd00000000, 0x2800ed6200000000, + 0x6e3b8a0700000000, 0xfd9dcee600000000, 0xbba6a98300000000, + 0x71eb002c00000000, 0x37d0674900000000, 0x330b3ed500000000, + 0x753059b000000000, 0xbf7df01f00000000, 0xf946977a00000000, + 0x6ae0d39b00000000, 0x2cdbb4fe00000000, 0xe6961d5100000000, + 0xa0ad7a3400000000, 0x81dde54800000000, 0xc7e6822d00000000, + 0x0dab2b8200000000, 0x4b904ce700000000, 0xd836080600000000, + 0x9e0d6f6300000000, 0x5440c6cc00000000, 0x127ba1a900000000, + 0x1df0042f00000000, 0x5bcb634a00000000, 0x9186cae500000000, + 0xd7bdad8000000000, 0x441be96100000000, 0x02208e0400000000, + 0xc86d27ab00000000, 0x8e5640ce00000000, 0xaf26dfb200000000, + 0xe91db8d700000000, 0x2350117800000000, 0x656b761d00000000, + 0xf6cd32fc00000000, 0xb0f6559900000000, 0x7abbfc3600000000, + 0x3c809b5300000000, 0x385bc2cf00000000, 0x7e60a5aa00000000, + 0xb42d0c0500000000, 0xf2166b6000000000, 0x61b02f8100000000, + 0x278b48e400000000, 0xedc6e14b00000000, 0xabfd862e00000000, + 0x8a8d195200000000, 0xccb67e3700000000, 0x06fbd79800000000, + 0x40c0b0fd00000000, 0xd366f41c00000000, 0x955d937900000000, + 0x5f103ad600000000, 0x192b5db300000000, 0x2c40f16b00000000, + 0x6a7b960e00000000, 0xa0363fa100000000, 0xe60d58c400000000, + 0x75ab1c2500000000, 0x33907b4000000000, 0xf9ddd2ef00000000, + 0xbfe6b58a00000000, 0x9e962af600000000, 0xd8ad4d9300000000, + 0x12e0e43c00000000, 0x54db835900000000, 0xc77dc7b800000000, + 0x8146a0dd00000000, 0x4b0b097200000000, 0x0d306e1700000000, + 0x09eb378b00000000, 0x4fd050ee00000000, 0x859df94100000000, + 0xc3a69e2400000000, 0x5000dac500000000, 0x163bbda000000000, + 0xdc76140f00000000, 0x9a4d736a00000000, 0xbb3dec1600000000, + 0xfd068b7300000000, 0x374b22dc00000000, 0x717045b900000000, + 0xe2d6015800000000, 0xa4ed663d00000000, 0x6ea0cf9200000000, + 0x289ba8f700000000, 0x27100d7100000000, 0x612b6a1400000000, + 0xab66c3bb00000000, 0xed5da4de00000000, 0x7efbe03f00000000, + 0x38c0875a00000000, 0xf28d2ef500000000, 0xb4b6499000000000, + 0x95c6d6ec00000000, 0xd3fdb18900000000, 0x19b0182600000000, + 0x5f8b7f4300000000, 0xcc2d3ba200000000, 0x8a165cc700000000, + 0x405bf56800000000, 0x0660920d00000000, 0x02bbcb9100000000, + 0x4480acf400000000, 0x8ecd055b00000000, 0xc8f6623e00000000, + 0x5b5026df00000000, 0x1d6b41ba00000000, 0xd726e81500000000, + 0x911d8f7000000000, 0xb06d100c00000000, 0xf656776900000000, + 0x3c1bdec600000000, 0x7a20b9a300000000, 0xe986fd4200000000, + 0xafbd9a2700000000, 0x65f0338800000000, 0x23cb54ed00000000, + 0x3ae0095e00000000, 0x7cdb6e3b00000000, 0xb696c79400000000, + 0xf0ada0f100000000, 0x630be41000000000, 0x2530837500000000, + 0xef7d2ada00000000, 0xa9464dbf00000000, 0x8836d2c300000000, + 0xce0db5a600000000, 0x04401c0900000000, 0x427b7b6c00000000, + 0xd1dd3f8d00000000, 0x97e658e800000000, 0x5dabf14700000000, + 0x1b90962200000000, 0x1f4bcfbe00000000, 0x5970a8db00000000, + 0x933d017400000000, 0xd506661100000000, 0x46a022f000000000, + 0x009b459500000000, 0xcad6ec3a00000000, 0x8ced8b5f00000000, + 0xad9d142300000000, 0xeba6734600000000, 0x21ebdae900000000, + 0x67d0bd8c00000000, 0xf476f96d00000000, 0xb24d9e0800000000, + 0x780037a700000000, 0x3e3b50c200000000, 0x31b0f54400000000, + 0x778b922100000000, 0xbdc63b8e00000000, 0xfbfd5ceb00000000, + 0x685b180a00000000, 0x2e607f6f00000000, 0xe42dd6c000000000, + 0xa216b1a500000000, 0x83662ed900000000, 0xc55d49bc00000000, + 0x0f10e01300000000, 0x492b877600000000, 0xda8dc39700000000, + 0x9cb6a4f200000000, 0x56fb0d5d00000000, 0x10c06a3800000000, + 0x141b33a400000000, 0x522054c100000000, 0x986dfd6e00000000, + 0xde569a0b00000000, 0x4df0deea00000000, 0x0bcbb98f00000000, + 0xc186102000000000, 0x87bd774500000000, 0xa6cde83900000000, + 0xe0f68f5c00000000, 0x2abb26f300000000, 0x6c80419600000000, + 0xff26057700000000, 0xb91d621200000000, 0x7350cbbd00000000, + 0x356bacd800000000}, + {0x0000000000000000, 0x9e83da9f00000000, 0x7d01c4e400000000, + 0xe3821e7b00000000, 0xbb04f91200000000, 0x2587238d00000000, + 0xc6053df600000000, 0x5886e76900000000, 0x7609f22500000000, + 0xe88a28ba00000000, 0x0b0836c100000000, 0x958bec5e00000000, + 0xcd0d0b3700000000, 0x538ed1a800000000, 0xb00ccfd300000000, + 0x2e8f154c00000000, 0xec12e44b00000000, 0x72913ed400000000, + 0x911320af00000000, 0x0f90fa3000000000, 0x57161d5900000000, + 0xc995c7c600000000, 0x2a17d9bd00000000, 0xb494032200000000, + 0x9a1b166e00000000, 0x0498ccf100000000, 0xe71ad28a00000000, + 0x7999081500000000, 0x211fef7c00000000, 0xbf9c35e300000000, + 0x5c1e2b9800000000, 0xc29df10700000000, 0xd825c89700000000, + 0x46a6120800000000, 0xa5240c7300000000, 0x3ba7d6ec00000000, + 0x6321318500000000, 0xfda2eb1a00000000, 0x1e20f56100000000, + 0x80a32ffe00000000, 0xae2c3ab200000000, 0x30afe02d00000000, + 0xd32dfe5600000000, 0x4dae24c900000000, 0x1528c3a000000000, + 0x8bab193f00000000, 0x6829074400000000, 0xf6aadddb00000000, + 0x34372cdc00000000, 0xaab4f64300000000, 0x4936e83800000000, + 0xd7b532a700000000, 0x8f33d5ce00000000, 0x11b00f5100000000, + 0xf232112a00000000, 0x6cb1cbb500000000, 0x423edef900000000, + 0xdcbd046600000000, 0x3f3f1a1d00000000, 0xa1bcc08200000000, + 0xf93a27eb00000000, 0x67b9fd7400000000, 0x843be30f00000000, + 0x1ab8399000000000, 0xf14de1f400000000, 0x6fce3b6b00000000, + 0x8c4c251000000000, 0x12cfff8f00000000, 0x4a4918e600000000, + 0xd4cac27900000000, 0x3748dc0200000000, 0xa9cb069d00000000, + 0x874413d100000000, 0x19c7c94e00000000, 0xfa45d73500000000, + 0x64c60daa00000000, 0x3c40eac300000000, 0xa2c3305c00000000, + 0x41412e2700000000, 0xdfc2f4b800000000, 0x1d5f05bf00000000, + 0x83dcdf2000000000, 0x605ec15b00000000, 0xfedd1bc400000000, + 0xa65bfcad00000000, 0x38d8263200000000, 0xdb5a384900000000, + 0x45d9e2d600000000, 0x6b56f79a00000000, 0xf5d52d0500000000, + 0x1657337e00000000, 0x88d4e9e100000000, 0xd0520e8800000000, + 0x4ed1d41700000000, 0xad53ca6c00000000, 0x33d010f300000000, + 0x2968296300000000, 0xb7ebf3fc00000000, 0x5469ed8700000000, + 0xcaea371800000000, 0x926cd07100000000, 0x0cef0aee00000000, + 0xef6d149500000000, 0x71eece0a00000000, 0x5f61db4600000000, + 0xc1e201d900000000, 0x22601fa200000000, 0xbce3c53d00000000, + 0xe465225400000000, 0x7ae6f8cb00000000, 0x9964e6b000000000, + 0x07e73c2f00000000, 0xc57acd2800000000, 0x5bf917b700000000, + 0xb87b09cc00000000, 0x26f8d35300000000, 0x7e7e343a00000000, + 0xe0fdeea500000000, 0x037ff0de00000000, 0x9dfc2a4100000000, + 0xb3733f0d00000000, 0x2df0e59200000000, 0xce72fbe900000000, + 0x50f1217600000000, 0x0877c61f00000000, 0x96f41c8000000000, + 0x757602fb00000000, 0xebf5d86400000000, 0xa39db33200000000, + 0x3d1e69ad00000000, 0xde9c77d600000000, 0x401fad4900000000, + 0x18994a2000000000, 0x861a90bf00000000, 0x65988ec400000000, + 0xfb1b545b00000000, 0xd594411700000000, 0x4b179b8800000000, + 0xa89585f300000000, 0x36165f6c00000000, 0x6e90b80500000000, + 0xf013629a00000000, 0x13917ce100000000, 0x8d12a67e00000000, + 0x4f8f577900000000, 0xd10c8de600000000, 0x328e939d00000000, + 0xac0d490200000000, 0xf48bae6b00000000, 0x6a0874f400000000, + 0x898a6a8f00000000, 0x1709b01000000000, 0x3986a55c00000000, + 0xa7057fc300000000, 0x448761b800000000, 0xda04bb2700000000, + 0x82825c4e00000000, 0x1c0186d100000000, 0xff8398aa00000000, + 0x6100423500000000, 0x7bb87ba500000000, 0xe53ba13a00000000, + 0x06b9bf4100000000, 0x983a65de00000000, 0xc0bc82b700000000, + 0x5e3f582800000000, 0xbdbd465300000000, 0x233e9ccc00000000, + 0x0db1898000000000, 0x9332531f00000000, 0x70b04d6400000000, + 0xee3397fb00000000, 0xb6b5709200000000, 0x2836aa0d00000000, + 0xcbb4b47600000000, 0x55376ee900000000, 0x97aa9fee00000000, + 0x0929457100000000, 0xeaab5b0a00000000, 0x7428819500000000, + 0x2cae66fc00000000, 0xb22dbc6300000000, 0x51afa21800000000, + 0xcf2c788700000000, 0xe1a36dcb00000000, 0x7f20b75400000000, + 0x9ca2a92f00000000, 0x022173b000000000, 0x5aa794d900000000, + 0xc4244e4600000000, 0x27a6503d00000000, 0xb9258aa200000000, + 0x52d052c600000000, 0xcc53885900000000, 0x2fd1962200000000, + 0xb1524cbd00000000, 0xe9d4abd400000000, 0x7757714b00000000, + 0x94d56f3000000000, 0x0a56b5af00000000, 0x24d9a0e300000000, + 0xba5a7a7c00000000, 0x59d8640700000000, 0xc75bbe9800000000, + 0x9fdd59f100000000, 0x015e836e00000000, 0xe2dc9d1500000000, + 0x7c5f478a00000000, 0xbec2b68d00000000, 0x20416c1200000000, + 0xc3c3726900000000, 0x5d40a8f600000000, 0x05c64f9f00000000, + 0x9b45950000000000, 0x78c78b7b00000000, 0xe64451e400000000, + 0xc8cb44a800000000, 0x56489e3700000000, 0xb5ca804c00000000, + 0x2b495ad300000000, 0x73cfbdba00000000, 0xed4c672500000000, + 0x0ece795e00000000, 0x904da3c100000000, 0x8af59a5100000000, + 0x147640ce00000000, 0xf7f45eb500000000, 0x6977842a00000000, + 0x31f1634300000000, 0xaf72b9dc00000000, 0x4cf0a7a700000000, + 0xd2737d3800000000, 0xfcfc687400000000, 0x627fb2eb00000000, + 0x81fdac9000000000, 0x1f7e760f00000000, 0x47f8916600000000, + 0xd97b4bf900000000, 0x3af9558200000000, 0xa47a8f1d00000000, + 0x66e77e1a00000000, 0xf864a48500000000, 0x1be6bafe00000000, + 0x8565606100000000, 0xdde3870800000000, 0x43605d9700000000, + 0xa0e243ec00000000, 0x3e61997300000000, 0x10ee8c3f00000000, + 0x8e6d56a000000000, 0x6def48db00000000, 0xf36c924400000000, + 0xabea752d00000000, 0x3569afb200000000, 0xd6ebb1c900000000, + 0x48686b5600000000}, + {0x0000000000000000, 0xc064281700000000, 0x80c9502e00000000, + 0x40ad783900000000, 0x0093a15c00000000, 0xc0f7894b00000000, + 0x805af17200000000, 0x403ed96500000000, 0x002643b900000000, + 0xc0426bae00000000, 0x80ef139700000000, 0x408b3b8000000000, + 0x00b5e2e500000000, 0xc0d1caf200000000, 0x807cb2cb00000000, + 0x40189adc00000000, 0x414af7a900000000, 0x812edfbe00000000, + 0xc183a78700000000, 0x01e78f9000000000, 0x41d956f500000000, + 0x81bd7ee200000000, 0xc11006db00000000, 0x01742ecc00000000, + 0x416cb41000000000, 0x81089c0700000000, 0xc1a5e43e00000000, + 0x01c1cc2900000000, 0x41ff154c00000000, 0x819b3d5b00000000, + 0xc136456200000000, 0x01526d7500000000, 0xc3929f8800000000, + 0x03f6b79f00000000, 0x435bcfa600000000, 0x833fe7b100000000, + 0xc3013ed400000000, 0x036516c300000000, 0x43c86efa00000000, + 0x83ac46ed00000000, 0xc3b4dc3100000000, 0x03d0f42600000000, + 0x437d8c1f00000000, 0x8319a40800000000, 0xc3277d6d00000000, + 0x0343557a00000000, 0x43ee2d4300000000, 0x838a055400000000, + 0x82d8682100000000, 0x42bc403600000000, 0x0211380f00000000, + 0xc275101800000000, 0x824bc97d00000000, 0x422fe16a00000000, + 0x0282995300000000, 0xc2e6b14400000000, 0x82fe2b9800000000, + 0x429a038f00000000, 0x02377bb600000000, 0xc25353a100000000, + 0x826d8ac400000000, 0x4209a2d300000000, 0x02a4daea00000000, + 0xc2c0f2fd00000000, 0xc7234eca00000000, 0x074766dd00000000, + 0x47ea1ee400000000, 0x878e36f300000000, 0xc7b0ef9600000000, + 0x07d4c78100000000, 0x4779bfb800000000, 0x871d97af00000000, + 0xc7050d7300000000, 0x0761256400000000, 0x47cc5d5d00000000, + 0x87a8754a00000000, 0xc796ac2f00000000, 0x07f2843800000000, + 0x475ffc0100000000, 0x873bd41600000000, 0x8669b96300000000, + 0x460d917400000000, 0x06a0e94d00000000, 0xc6c4c15a00000000, + 0x86fa183f00000000, 0x469e302800000000, 0x0633481100000000, + 0xc657600600000000, 0x864ffada00000000, 0x462bd2cd00000000, + 0x0686aaf400000000, 0xc6e282e300000000, 0x86dc5b8600000000, + 0x46b8739100000000, 0x06150ba800000000, 0xc67123bf00000000, + 0x04b1d14200000000, 0xc4d5f95500000000, 0x8478816c00000000, + 0x441ca97b00000000, 0x0422701e00000000, 0xc446580900000000, + 0x84eb203000000000, 0x448f082700000000, 0x049792fb00000000, + 0xc4f3baec00000000, 0x845ec2d500000000, 0x443aeac200000000, + 0x040433a700000000, 0xc4601bb000000000, 0x84cd638900000000, + 0x44a94b9e00000000, 0x45fb26eb00000000, 0x859f0efc00000000, + 0xc53276c500000000, 0x05565ed200000000, 0x456887b700000000, + 0x850cafa000000000, 0xc5a1d79900000000, 0x05c5ff8e00000000, + 0x45dd655200000000, 0x85b94d4500000000, 0xc514357c00000000, + 0x05701d6b00000000, 0x454ec40e00000000, 0x852aec1900000000, + 0xc587942000000000, 0x05e3bc3700000000, 0xcf41ed4f00000000, + 0x0f25c55800000000, 0x4f88bd6100000000, 0x8fec957600000000, + 0xcfd24c1300000000, 0x0fb6640400000000, 0x4f1b1c3d00000000, + 0x8f7f342a00000000, 0xcf67aef600000000, 0x0f0386e100000000, + 0x4faefed800000000, 0x8fcad6cf00000000, 0xcff40faa00000000, + 0x0f9027bd00000000, 0x4f3d5f8400000000, 0x8f59779300000000, + 0x8e0b1ae600000000, 0x4e6f32f100000000, 0x0ec24ac800000000, + 0xcea662df00000000, 0x8e98bbba00000000, 0x4efc93ad00000000, + 0x0e51eb9400000000, 0xce35c38300000000, 0x8e2d595f00000000, + 0x4e49714800000000, 0x0ee4097100000000, 0xce80216600000000, + 0x8ebef80300000000, 0x4edad01400000000, 0x0e77a82d00000000, + 0xce13803a00000000, 0x0cd372c700000000, 0xccb75ad000000000, + 0x8c1a22e900000000, 0x4c7e0afe00000000, 0x0c40d39b00000000, + 0xcc24fb8c00000000, 0x8c8983b500000000, 0x4cedaba200000000, + 0x0cf5317e00000000, 0xcc91196900000000, 0x8c3c615000000000, + 0x4c58494700000000, 0x0c66902200000000, 0xcc02b83500000000, + 0x8cafc00c00000000, 0x4ccbe81b00000000, 0x4d99856e00000000, + 0x8dfdad7900000000, 0xcd50d54000000000, 0x0d34fd5700000000, + 0x4d0a243200000000, 0x8d6e0c2500000000, 0xcdc3741c00000000, + 0x0da75c0b00000000, 0x4dbfc6d700000000, 0x8ddbeec000000000, + 0xcd7696f900000000, 0x0d12beee00000000, 0x4d2c678b00000000, + 0x8d484f9c00000000, 0xcde537a500000000, 0x0d811fb200000000, + 0x0862a38500000000, 0xc8068b9200000000, 0x88abf3ab00000000, + 0x48cfdbbc00000000, 0x08f102d900000000, 0xc8952ace00000000, + 0x883852f700000000, 0x485c7ae000000000, 0x0844e03c00000000, + 0xc820c82b00000000, 0x888db01200000000, 0x48e9980500000000, + 0x08d7416000000000, 0xc8b3697700000000, 0x881e114e00000000, + 0x487a395900000000, 0x4928542c00000000, 0x894c7c3b00000000, + 0xc9e1040200000000, 0x09852c1500000000, 0x49bbf57000000000, + 0x89dfdd6700000000, 0xc972a55e00000000, 0x09168d4900000000, + 0x490e179500000000, 0x896a3f8200000000, 0xc9c747bb00000000, + 0x09a36fac00000000, 0x499db6c900000000, 0x89f99ede00000000, + 0xc954e6e700000000, 0x0930cef000000000, 0xcbf03c0d00000000, + 0x0b94141a00000000, 0x4b396c2300000000, 0x8b5d443400000000, + 0xcb639d5100000000, 0x0b07b54600000000, 0x4baacd7f00000000, + 0x8bcee56800000000, 0xcbd67fb400000000, 0x0bb257a300000000, + 0x4b1f2f9a00000000, 0x8b7b078d00000000, 0xcb45dee800000000, + 0x0b21f6ff00000000, 0x4b8c8ec600000000, 0x8be8a6d100000000, + 0x8abacba400000000, 0x4adee3b300000000, 0x0a739b8a00000000, + 0xca17b39d00000000, 0x8a296af800000000, 0x4a4d42ef00000000, + 0x0ae03ad600000000, 0xca8412c100000000, 0x8a9c881d00000000, + 0x4af8a00a00000000, 0x0a55d83300000000, 0xca31f02400000000, + 0x8a0f294100000000, 0x4a6b015600000000, 0x0ac6796f00000000, + 0xcaa2517800000000}, + {0x0000000000000000, 0xd4ea739b00000000, 0xe9d396ed00000000, + 0x3d39e57600000000, 0x93a15c0000000000, 0x474b2f9b00000000, + 0x7a72caed00000000, 0xae98b97600000000, 0x2643b90000000000, + 0xf2a9ca9b00000000, 0xcf902fed00000000, 0x1b7a5c7600000000, + 0xb5e2e50000000000, 0x6108969b00000000, 0x5c3173ed00000000, + 0x88db007600000000, 0x4c86720100000000, 0x986c019a00000000, + 0xa555e4ec00000000, 0x71bf977700000000, 0xdf272e0100000000, + 0x0bcd5d9a00000000, 0x36f4b8ec00000000, 0xe21ecb7700000000, + 0x6ac5cb0100000000, 0xbe2fb89a00000000, 0x83165dec00000000, + 0x57fc2e7700000000, 0xf964970100000000, 0x2d8ee49a00000000, + 0x10b701ec00000000, 0xc45d727700000000, 0x980ce50200000000, + 0x4ce6969900000000, 0x71df73ef00000000, 0xa535007400000000, + 0x0badb90200000000, 0xdf47ca9900000000, 0xe27e2fef00000000, + 0x36945c7400000000, 0xbe4f5c0200000000, 0x6aa52f9900000000, + 0x579ccaef00000000, 0x8376b97400000000, 0x2dee000200000000, + 0xf904739900000000, 0xc43d96ef00000000, 0x10d7e57400000000, + 0xd48a970300000000, 0x0060e49800000000, 0x3d5901ee00000000, + 0xe9b3727500000000, 0x472bcb0300000000, 0x93c1b89800000000, + 0xaef85dee00000000, 0x7a122e7500000000, 0xf2c92e0300000000, + 0x26235d9800000000, 0x1b1ab8ee00000000, 0xcff0cb7500000000, + 0x6168720300000000, 0xb582019800000000, 0x88bbe4ee00000000, + 0x5c51977500000000, 0x3019ca0500000000, 0xe4f3b99e00000000, + 0xd9ca5ce800000000, 0x0d202f7300000000, 0xa3b8960500000000, + 0x7752e59e00000000, 0x4a6b00e800000000, 0x9e81737300000000, + 0x165a730500000000, 0xc2b0009e00000000, 0xff89e5e800000000, + 0x2b63967300000000, 0x85fb2f0500000000, 0x51115c9e00000000, + 0x6c28b9e800000000, 0xb8c2ca7300000000, 0x7c9fb80400000000, + 0xa875cb9f00000000, 0x954c2ee900000000, 0x41a65d7200000000, + 0xef3ee40400000000, 0x3bd4979f00000000, 0x06ed72e900000000, + 0xd207017200000000, 0x5adc010400000000, 0x8e36729f00000000, + 0xb30f97e900000000, 0x67e5e47200000000, 0xc97d5d0400000000, + 0x1d972e9f00000000, 0x20aecbe900000000, 0xf444b87200000000, + 0xa8152f0700000000, 0x7cff5c9c00000000, 0x41c6b9ea00000000, + 0x952cca7100000000, 0x3bb4730700000000, 0xef5e009c00000000, + 0xd267e5ea00000000, 0x068d967100000000, 0x8e56960700000000, + 0x5abce59c00000000, 0x678500ea00000000, 0xb36f737100000000, + 0x1df7ca0700000000, 0xc91db99c00000000, 0xf4245cea00000000, + 0x20ce2f7100000000, 0xe4935d0600000000, 0x30792e9d00000000, + 0x0d40cbeb00000000, 0xd9aab87000000000, 0x7732010600000000, + 0xa3d8729d00000000, 0x9ee197eb00000000, 0x4a0be47000000000, + 0xc2d0e40600000000, 0x163a979d00000000, 0x2b0372eb00000000, + 0xffe9017000000000, 0x5171b80600000000, 0x859bcb9d00000000, + 0xb8a22eeb00000000, 0x6c485d7000000000, 0x6032940b00000000, + 0xb4d8e79000000000, 0x89e102e600000000, 0x5d0b717d00000000, + 0xf393c80b00000000, 0x2779bb9000000000, 0x1a405ee600000000, + 0xceaa2d7d00000000, 0x46712d0b00000000, 0x929b5e9000000000, + 0xafa2bbe600000000, 0x7b48c87d00000000, 0xd5d0710b00000000, + 0x013a029000000000, 0x3c03e7e600000000, 0xe8e9947d00000000, + 0x2cb4e60a00000000, 0xf85e959100000000, 0xc56770e700000000, + 0x118d037c00000000, 0xbf15ba0a00000000, 0x6bffc99100000000, + 0x56c62ce700000000, 0x822c5f7c00000000, 0x0af75f0a00000000, + 0xde1d2c9100000000, 0xe324c9e700000000, 0x37ceba7c00000000, + 0x9956030a00000000, 0x4dbc709100000000, 0x708595e700000000, + 0xa46fe67c00000000, 0xf83e710900000000, 0x2cd4029200000000, + 0x11ede7e400000000, 0xc507947f00000000, 0x6b9f2d0900000000, + 0xbf755e9200000000, 0x824cbbe400000000, 0x56a6c87f00000000, + 0xde7dc80900000000, 0x0a97bb9200000000, 0x37ae5ee400000000, + 0xe3442d7f00000000, 0x4ddc940900000000, 0x9936e79200000000, + 0xa40f02e400000000, 0x70e5717f00000000, 0xb4b8030800000000, + 0x6052709300000000, 0x5d6b95e500000000, 0x8981e67e00000000, + 0x27195f0800000000, 0xf3f32c9300000000, 0xcecac9e500000000, + 0x1a20ba7e00000000, 0x92fbba0800000000, 0x4611c99300000000, + 0x7b282ce500000000, 0xafc25f7e00000000, 0x015ae60800000000, + 0xd5b0959300000000, 0xe88970e500000000, 0x3c63037e00000000, + 0x502b5e0e00000000, 0x84c12d9500000000, 0xb9f8c8e300000000, + 0x6d12bb7800000000, 0xc38a020e00000000, 0x1760719500000000, + 0x2a5994e300000000, 0xfeb3e77800000000, 0x7668e70e00000000, + 0xa282949500000000, 0x9fbb71e300000000, 0x4b51027800000000, + 0xe5c9bb0e00000000, 0x3123c89500000000, 0x0c1a2de300000000, + 0xd8f05e7800000000, 0x1cad2c0f00000000, 0xc8475f9400000000, + 0xf57ebae200000000, 0x2194c97900000000, 0x8f0c700f00000000, + 0x5be6039400000000, 0x66dfe6e200000000, 0xb235957900000000, + 0x3aee950f00000000, 0xee04e69400000000, 0xd33d03e200000000, + 0x07d7707900000000, 0xa94fc90f00000000, 0x7da5ba9400000000, + 0x409c5fe200000000, 0x94762c7900000000, 0xc827bb0c00000000, + 0x1ccdc89700000000, 0x21f42de100000000, 0xf51e5e7a00000000, + 0x5b86e70c00000000, 0x8f6c949700000000, 0xb25571e100000000, + 0x66bf027a00000000, 0xee64020c00000000, 0x3a8e719700000000, + 0x07b794e100000000, 0xd35de77a00000000, 0x7dc55e0c00000000, + 0xa92f2d9700000000, 0x9416c8e100000000, 0x40fcbb7a00000000, + 0x84a1c90d00000000, 0x504bba9600000000, 0x6d725fe000000000, + 0xb9982c7b00000000, 0x1700950d00000000, 0xc3eae69600000000, + 0xfed303e000000000, 0x2a39707b00000000, 0xa2e2700d00000000, + 0x7608039600000000, 0x4b31e6e000000000, 0x9fdb957b00000000, + 0x31432c0d00000000, 0xe5a95f9600000000, 0xd890bae000000000, + 0x0c7ac97b00000000}, + {0x0000000000000000, 0x2765258100000000, 0x0fcc3bd900000000, + 0x28a91e5800000000, 0x5f9e066900000000, 0x78fb23e800000000, + 0x50523db000000000, 0x7737183100000000, 0xbe3c0dd200000000, + 0x9959285300000000, 0xb1f0360b00000000, 0x9695138a00000000, + 0xe1a20bbb00000000, 0xc6c72e3a00000000, 0xee6e306200000000, + 0xc90b15e300000000, 0x3d7f6b7f00000000, 0x1a1a4efe00000000, + 0x32b350a600000000, 0x15d6752700000000, 0x62e16d1600000000, + 0x4584489700000000, 0x6d2d56cf00000000, 0x4a48734e00000000, + 0x834366ad00000000, 0xa426432c00000000, 0x8c8f5d7400000000, + 0xabea78f500000000, 0xdcdd60c400000000, 0xfbb8454500000000, + 0xd3115b1d00000000, 0xf4747e9c00000000, 0x7afed6fe00000000, + 0x5d9bf37f00000000, 0x7532ed2700000000, 0x5257c8a600000000, + 0x2560d09700000000, 0x0205f51600000000, 0x2aaceb4e00000000, + 0x0dc9cecf00000000, 0xc4c2db2c00000000, 0xe3a7fead00000000, + 0xcb0ee0f500000000, 0xec6bc57400000000, 0x9b5cdd4500000000, + 0xbc39f8c400000000, 0x9490e69c00000000, 0xb3f5c31d00000000, + 0x4781bd8100000000, 0x60e4980000000000, 0x484d865800000000, + 0x6f28a3d900000000, 0x181fbbe800000000, 0x3f7a9e6900000000, + 0x17d3803100000000, 0x30b6a5b000000000, 0xf9bdb05300000000, + 0xded895d200000000, 0xf6718b8a00000000, 0xd114ae0b00000000, + 0xa623b63a00000000, 0x814693bb00000000, 0xa9ef8de300000000, + 0x8e8aa86200000000, 0xb5fadc2600000000, 0x929ff9a700000000, + 0xba36e7ff00000000, 0x9d53c27e00000000, 0xea64da4f00000000, + 0xcd01ffce00000000, 0xe5a8e19600000000, 0xc2cdc41700000000, + 0x0bc6d1f400000000, 0x2ca3f47500000000, 0x040aea2d00000000, + 0x236fcfac00000000, 0x5458d79d00000000, 0x733df21c00000000, + 0x5b94ec4400000000, 0x7cf1c9c500000000, 0x8885b75900000000, + 0xafe092d800000000, 0x87498c8000000000, 0xa02ca90100000000, + 0xd71bb13000000000, 0xf07e94b100000000, 0xd8d78ae900000000, + 0xffb2af6800000000, 0x36b9ba8b00000000, 0x11dc9f0a00000000, + 0x3975815200000000, 0x1e10a4d300000000, 0x6927bce200000000, + 0x4e42996300000000, 0x66eb873b00000000, 0x418ea2ba00000000, + 0xcf040ad800000000, 0xe8612f5900000000, 0xc0c8310100000000, + 0xe7ad148000000000, 0x909a0cb100000000, 0xb7ff293000000000, + 0x9f56376800000000, 0xb83312e900000000, 0x7138070a00000000, + 0x565d228b00000000, 0x7ef43cd300000000, 0x5991195200000000, + 0x2ea6016300000000, 0x09c324e200000000, 0x216a3aba00000000, + 0x060f1f3b00000000, 0xf27b61a700000000, 0xd51e442600000000, + 0xfdb75a7e00000000, 0xdad27fff00000000, 0xade567ce00000000, + 0x8a80424f00000000, 0xa2295c1700000000, 0x854c799600000000, + 0x4c476c7500000000, 0x6b2249f400000000, 0x438b57ac00000000, + 0x64ee722d00000000, 0x13d96a1c00000000, 0x34bc4f9d00000000, + 0x1c1551c500000000, 0x3b70744400000000, 0x6af5b94d00000000, + 0x4d909ccc00000000, 0x6539829400000000, 0x425ca71500000000, + 0x356bbf2400000000, 0x120e9aa500000000, 0x3aa784fd00000000, + 0x1dc2a17c00000000, 0xd4c9b49f00000000, 0xf3ac911e00000000, + 0xdb058f4600000000, 0xfc60aac700000000, 0x8b57b2f600000000, + 0xac32977700000000, 0x849b892f00000000, 0xa3feacae00000000, + 0x578ad23200000000, 0x70eff7b300000000, 0x5846e9eb00000000, + 0x7f23cc6a00000000, 0x0814d45b00000000, 0x2f71f1da00000000, + 0x07d8ef8200000000, 0x20bdca0300000000, 0xe9b6dfe000000000, + 0xced3fa6100000000, 0xe67ae43900000000, 0xc11fc1b800000000, + 0xb628d98900000000, 0x914dfc0800000000, 0xb9e4e25000000000, + 0x9e81c7d100000000, 0x100b6fb300000000, 0x376e4a3200000000, + 0x1fc7546a00000000, 0x38a271eb00000000, 0x4f9569da00000000, + 0x68f04c5b00000000, 0x4059520300000000, 0x673c778200000000, + 0xae37626100000000, 0x895247e000000000, 0xa1fb59b800000000, + 0x869e7c3900000000, 0xf1a9640800000000, 0xd6cc418900000000, + 0xfe655fd100000000, 0xd9007a5000000000, 0x2d7404cc00000000, + 0x0a11214d00000000, 0x22b83f1500000000, 0x05dd1a9400000000, + 0x72ea02a500000000, 0x558f272400000000, 0x7d26397c00000000, + 0x5a431cfd00000000, 0x9348091e00000000, 0xb42d2c9f00000000, + 0x9c8432c700000000, 0xbbe1174600000000, 0xccd60f7700000000, + 0xebb32af600000000, 0xc31a34ae00000000, 0xe47f112f00000000, + 0xdf0f656b00000000, 0xf86a40ea00000000, 0xd0c35eb200000000, + 0xf7a67b3300000000, 0x8091630200000000, 0xa7f4468300000000, + 0x8f5d58db00000000, 0xa8387d5a00000000, 0x613368b900000000, + 0x46564d3800000000, 0x6eff536000000000, 0x499a76e100000000, + 0x3ead6ed000000000, 0x19c84b5100000000, 0x3161550900000000, + 0x1604708800000000, 0xe2700e1400000000, 0xc5152b9500000000, + 0xedbc35cd00000000, 0xcad9104c00000000, 0xbdee087d00000000, + 0x9a8b2dfc00000000, 0xb22233a400000000, 0x9547162500000000, + 0x5c4c03c600000000, 0x7b29264700000000, 0x5380381f00000000, + 0x74e51d9e00000000, 0x03d205af00000000, 0x24b7202e00000000, + 0x0c1e3e7600000000, 0x2b7b1bf700000000, 0xa5f1b39500000000, + 0x8294961400000000, 0xaa3d884c00000000, 0x8d58adcd00000000, + 0xfa6fb5fc00000000, 0xdd0a907d00000000, 0xf5a38e2500000000, + 0xd2c6aba400000000, 0x1bcdbe4700000000, 0x3ca89bc600000000, + 0x1401859e00000000, 0x3364a01f00000000, 0x4453b82e00000000, + 0x63369daf00000000, 0x4b9f83f700000000, 0x6cfaa67600000000, + 0x988ed8ea00000000, 0xbfebfd6b00000000, 0x9742e33300000000, + 0xb027c6b200000000, 0xc710de8300000000, 0xe075fb0200000000, + 0xc8dce55a00000000, 0xefb9c0db00000000, 0x26b2d53800000000, + 0x01d7f0b900000000, 0x297eeee100000000, 0x0e1bcb6000000000, + 0x792cd35100000000, 0x5e49f6d000000000, 0x76e0e88800000000, + 0x5185cd0900000000}}; + +#else /* W == 4 */ + +local const z_crc_t FAR crc_braid_table[][256] = { + {0x00000000, 0x9ba54c6f, 0xec3b9e9f, 0x779ed2f0, 0x03063b7f, + 0x98a37710, 0xef3da5e0, 0x7498e98f, 0x060c76fe, 0x9da93a91, + 0xea37e861, 0x7192a40e, 0x050a4d81, 0x9eaf01ee, 0xe931d31e, + 0x72949f71, 0x0c18edfc, 0x97bda193, 0xe0237363, 0x7b863f0c, + 0x0f1ed683, 0x94bb9aec, 0xe325481c, 0x78800473, 0x0a149b02, + 0x91b1d76d, 0xe62f059d, 0x7d8a49f2, 0x0912a07d, 0x92b7ec12, + 0xe5293ee2, 0x7e8c728d, 0x1831dbf8, 0x83949797, 0xf40a4567, + 0x6faf0908, 0x1b37e087, 0x8092ace8, 0xf70c7e18, 0x6ca93277, + 0x1e3dad06, 0x8598e169, 0xf2063399, 0x69a37ff6, 0x1d3b9679, + 0x869eda16, 0xf10008e6, 0x6aa54489, 0x14293604, 0x8f8c7a6b, + 0xf812a89b, 0x63b7e4f4, 0x172f0d7b, 0x8c8a4114, 0xfb1493e4, + 0x60b1df8b, 0x122540fa, 0x89800c95, 0xfe1ede65, 0x65bb920a, + 0x11237b85, 0x8a8637ea, 0xfd18e51a, 0x66bda975, 0x3063b7f0, + 0xabc6fb9f, 0xdc58296f, 0x47fd6500, 0x33658c8f, 0xa8c0c0e0, + 0xdf5e1210, 0x44fb5e7f, 0x366fc10e, 0xadca8d61, 0xda545f91, + 0x41f113fe, 0x3569fa71, 0xaeccb61e, 0xd95264ee, 0x42f72881, + 0x3c7b5a0c, 0xa7de1663, 0xd040c493, 0x4be588fc, 0x3f7d6173, + 0xa4d82d1c, 0xd346ffec, 0x48e3b383, 0x3a772cf2, 0xa1d2609d, + 0xd64cb26d, 0x4de9fe02, 0x3971178d, 0xa2d45be2, 0xd54a8912, + 0x4eefc57d, 0x28526c08, 0xb3f72067, 0xc469f297, 0x5fccbef8, + 0x2b545777, 0xb0f11b18, 0xc76fc9e8, 0x5cca8587, 0x2e5e1af6, + 0xb5fb5699, 0xc2658469, 0x59c0c806, 0x2d582189, 0xb6fd6de6, + 0xc163bf16, 0x5ac6f379, 0x244a81f4, 0xbfefcd9b, 0xc8711f6b, + 0x53d45304, 0x274cba8b, 0xbce9f6e4, 0xcb772414, 0x50d2687b, + 0x2246f70a, 0xb9e3bb65, 0xce7d6995, 0x55d825fa, 0x2140cc75, + 0xbae5801a, 0xcd7b52ea, 0x56de1e85, 0x60c76fe0, 0xfb62238f, + 0x8cfcf17f, 0x1759bd10, 0x63c1549f, 0xf86418f0, 0x8ffaca00, + 0x145f866f, 0x66cb191e, 0xfd6e5571, 0x8af08781, 0x1155cbee, + 0x65cd2261, 0xfe686e0e, 0x89f6bcfe, 0x1253f091, 0x6cdf821c, + 0xf77ace73, 0x80e41c83, 0x1b4150ec, 0x6fd9b963, 0xf47cf50c, + 0x83e227fc, 0x18476b93, 0x6ad3f4e2, 0xf176b88d, 0x86e86a7d, + 0x1d4d2612, 0x69d5cf9d, 0xf27083f2, 0x85ee5102, 0x1e4b1d6d, + 0x78f6b418, 0xe353f877, 0x94cd2a87, 0x0f6866e8, 0x7bf08f67, + 0xe055c308, 0x97cb11f8, 0x0c6e5d97, 0x7efac2e6, 0xe55f8e89, + 0x92c15c79, 0x09641016, 0x7dfcf999, 0xe659b5f6, 0x91c76706, + 0x0a622b69, 0x74ee59e4, 0xef4b158b, 0x98d5c77b, 0x03708b14, + 0x77e8629b, 0xec4d2ef4, 0x9bd3fc04, 0x0076b06b, 0x72e22f1a, + 0xe9476375, 0x9ed9b185, 0x057cfdea, 0x71e41465, 0xea41580a, + 0x9ddf8afa, 0x067ac695, 0x50a4d810, 0xcb01947f, 0xbc9f468f, + 0x273a0ae0, 0x53a2e36f, 0xc807af00, 0xbf997df0, 0x243c319f, + 0x56a8aeee, 0xcd0de281, 0xba933071, 0x21367c1e, 0x55ae9591, + 0xce0bd9fe, 0xb9950b0e, 0x22304761, 0x5cbc35ec, 0xc7197983, + 0xb087ab73, 0x2b22e71c, 0x5fba0e93, 0xc41f42fc, 0xb381900c, + 0x2824dc63, 0x5ab04312, 0xc1150f7d, 0xb68bdd8d, 0x2d2e91e2, + 0x59b6786d, 0xc2133402, 0xb58de6f2, 0x2e28aa9d, 0x489503e8, + 0xd3304f87, 0xa4ae9d77, 0x3f0bd118, 0x4b933897, 0xd03674f8, + 0xa7a8a608, 0x3c0dea67, 0x4e997516, 0xd53c3979, 0xa2a2eb89, + 0x3907a7e6, 0x4d9f4e69, 0xd63a0206, 0xa1a4d0f6, 0x3a019c99, + 0x448dee14, 0xdf28a27b, 0xa8b6708b, 0x33133ce4, 0x478bd56b, + 0xdc2e9904, 0xabb04bf4, 0x3015079b, 0x428198ea, 0xd924d485, + 0xaeba0675, 0x351f4a1a, 0x4187a395, 0xda22effa, 0xadbc3d0a, + 0x36197165}, + {0x00000000, 0xc18edfc0, 0x586cb9c1, 0x99e26601, 0xb0d97382, + 0x7157ac42, 0xe8b5ca43, 0x293b1583, 0xbac3e145, 0x7b4d3e85, + 0xe2af5884, 0x23218744, 0x0a1a92c7, 0xcb944d07, 0x52762b06, + 0x93f8f4c6, 0xaef6c4cb, 0x6f781b0b, 0xf69a7d0a, 0x3714a2ca, + 0x1e2fb749, 0xdfa16889, 0x46430e88, 0x87cdd148, 0x1435258e, + 0xd5bbfa4e, 0x4c599c4f, 0x8dd7438f, 0xa4ec560c, 0x656289cc, + 0xfc80efcd, 0x3d0e300d, 0x869c8fd7, 0x47125017, 0xdef03616, + 0x1f7ee9d6, 0x3645fc55, 0xf7cb2395, 0x6e294594, 0xafa79a54, + 0x3c5f6e92, 0xfdd1b152, 0x6433d753, 0xa5bd0893, 0x8c861d10, + 0x4d08c2d0, 0xd4eaa4d1, 0x15647b11, 0x286a4b1c, 0xe9e494dc, + 0x7006f2dd, 0xb1882d1d, 0x98b3389e, 0x593de75e, 0xc0df815f, + 0x01515e9f, 0x92a9aa59, 0x53277599, 0xcac51398, 0x0b4bcc58, + 0x2270d9db, 0xe3fe061b, 0x7a1c601a, 0xbb92bfda, 0xd64819ef, + 0x17c6c62f, 0x8e24a02e, 0x4faa7fee, 0x66916a6d, 0xa71fb5ad, + 0x3efdd3ac, 0xff730c6c, 0x6c8bf8aa, 0xad05276a, 0x34e7416b, + 0xf5699eab, 0xdc528b28, 0x1ddc54e8, 0x843e32e9, 0x45b0ed29, + 0x78bedd24, 0xb93002e4, 0x20d264e5, 0xe15cbb25, 0xc867aea6, + 0x09e97166, 0x900b1767, 0x5185c8a7, 0xc27d3c61, 0x03f3e3a1, + 0x9a1185a0, 0x5b9f5a60, 0x72a44fe3, 0xb32a9023, 0x2ac8f622, + 0xeb4629e2, 0x50d49638, 0x915a49f8, 0x08b82ff9, 0xc936f039, + 0xe00de5ba, 0x21833a7a, 0xb8615c7b, 0x79ef83bb, 0xea17777d, + 0x2b99a8bd, 0xb27bcebc, 0x73f5117c, 0x5ace04ff, 0x9b40db3f, + 0x02a2bd3e, 0xc32c62fe, 0xfe2252f3, 0x3fac8d33, 0xa64eeb32, + 0x67c034f2, 0x4efb2171, 0x8f75feb1, 0x169798b0, 0xd7194770, + 0x44e1b3b6, 0x856f6c76, 0x1c8d0a77, 0xdd03d5b7, 0xf438c034, + 0x35b61ff4, 0xac5479f5, 0x6ddaa635, 0x77e1359f, 0xb66fea5f, + 0x2f8d8c5e, 0xee03539e, 0xc738461d, 0x06b699dd, 0x9f54ffdc, + 0x5eda201c, 0xcd22d4da, 0x0cac0b1a, 0x954e6d1b, 0x54c0b2db, + 0x7dfba758, 0xbc757898, 0x25971e99, 0xe419c159, 0xd917f154, + 0x18992e94, 0x817b4895, 0x40f59755, 0x69ce82d6, 0xa8405d16, + 0x31a23b17, 0xf02ce4d7, 0x63d41011, 0xa25acfd1, 0x3bb8a9d0, + 0xfa367610, 0xd30d6393, 0x1283bc53, 0x8b61da52, 0x4aef0592, + 0xf17dba48, 0x30f36588, 0xa9110389, 0x689fdc49, 0x41a4c9ca, + 0x802a160a, 0x19c8700b, 0xd846afcb, 0x4bbe5b0d, 0x8a3084cd, + 0x13d2e2cc, 0xd25c3d0c, 0xfb67288f, 0x3ae9f74f, 0xa30b914e, + 0x62854e8e, 0x5f8b7e83, 0x9e05a143, 0x07e7c742, 0xc6691882, + 0xef520d01, 0x2edcd2c1, 0xb73eb4c0, 0x76b06b00, 0xe5489fc6, + 0x24c64006, 0xbd242607, 0x7caaf9c7, 0x5591ec44, 0x941f3384, + 0x0dfd5585, 0xcc738a45, 0xa1a92c70, 0x6027f3b0, 0xf9c595b1, + 0x384b4a71, 0x11705ff2, 0xd0fe8032, 0x491ce633, 0x889239f3, + 0x1b6acd35, 0xdae412f5, 0x430674f4, 0x8288ab34, 0xabb3beb7, + 0x6a3d6177, 0xf3df0776, 0x3251d8b6, 0x0f5fe8bb, 0xced1377b, + 0x5733517a, 0x96bd8eba, 0xbf869b39, 0x7e0844f9, 0xe7ea22f8, + 0x2664fd38, 0xb59c09fe, 0x7412d63e, 0xedf0b03f, 0x2c7e6fff, + 0x05457a7c, 0xc4cba5bc, 0x5d29c3bd, 0x9ca71c7d, 0x2735a3a7, + 0xe6bb7c67, 0x7f591a66, 0xbed7c5a6, 0x97ecd025, 0x56620fe5, + 0xcf8069e4, 0x0e0eb624, 0x9df642e2, 0x5c789d22, 0xc59afb23, + 0x041424e3, 0x2d2f3160, 0xeca1eea0, 0x754388a1, 0xb4cd5761, + 0x89c3676c, 0x484db8ac, 0xd1afdead, 0x1021016d, 0x391a14ee, + 0xf894cb2e, 0x6176ad2f, 0xa0f872ef, 0x33008629, 0xf28e59e9, + 0x6b6c3fe8, 0xaae2e028, 0x83d9f5ab, 0x42572a6b, 0xdbb54c6a, + 0x1a3b93aa}, + {0x00000000, 0xefc26b3e, 0x04f5d03d, 0xeb37bb03, 0x09eba07a, + 0xe629cb44, 0x0d1e7047, 0xe2dc1b79, 0x13d740f4, 0xfc152bca, + 0x172290c9, 0xf8e0fbf7, 0x1a3ce08e, 0xf5fe8bb0, 0x1ec930b3, + 0xf10b5b8d, 0x27ae81e8, 0xc86cead6, 0x235b51d5, 0xcc993aeb, + 0x2e452192, 0xc1874aac, 0x2ab0f1af, 0xc5729a91, 0x3479c11c, + 0xdbbbaa22, 0x308c1121, 0xdf4e7a1f, 0x3d926166, 0xd2500a58, + 0x3967b15b, 0xd6a5da65, 0x4f5d03d0, 0xa09f68ee, 0x4ba8d3ed, + 0xa46ab8d3, 0x46b6a3aa, 0xa974c894, 0x42437397, 0xad8118a9, + 0x5c8a4324, 0xb348281a, 0x587f9319, 0xb7bdf827, 0x5561e35e, + 0xbaa38860, 0x51943363, 0xbe56585d, 0x68f38238, 0x8731e906, + 0x6c065205, 0x83c4393b, 0x61182242, 0x8eda497c, 0x65edf27f, + 0x8a2f9941, 0x7b24c2cc, 0x94e6a9f2, 0x7fd112f1, 0x901379cf, + 0x72cf62b6, 0x9d0d0988, 0x763ab28b, 0x99f8d9b5, 0x9eba07a0, + 0x71786c9e, 0x9a4fd79d, 0x758dbca3, 0x9751a7da, 0x7893cce4, + 0x93a477e7, 0x7c661cd9, 0x8d6d4754, 0x62af2c6a, 0x89989769, + 0x665afc57, 0x8486e72e, 0x6b448c10, 0x80733713, 0x6fb15c2d, + 0xb9148648, 0x56d6ed76, 0xbde15675, 0x52233d4b, 0xb0ff2632, + 0x5f3d4d0c, 0xb40af60f, 0x5bc89d31, 0xaac3c6bc, 0x4501ad82, + 0xae361681, 0x41f47dbf, 0xa32866c6, 0x4cea0df8, 0xa7ddb6fb, + 0x481fddc5, 0xd1e70470, 0x3e256f4e, 0xd512d44d, 0x3ad0bf73, + 0xd80ca40a, 0x37cecf34, 0xdcf97437, 0x333b1f09, 0xc2304484, + 0x2df22fba, 0xc6c594b9, 0x2907ff87, 0xcbdbe4fe, 0x24198fc0, + 0xcf2e34c3, 0x20ec5ffd, 0xf6498598, 0x198beea6, 0xf2bc55a5, + 0x1d7e3e9b, 0xffa225e2, 0x10604edc, 0xfb57f5df, 0x14959ee1, + 0xe59ec56c, 0x0a5cae52, 0xe16b1551, 0x0ea97e6f, 0xec756516, + 0x03b70e28, 0xe880b52b, 0x0742de15, 0xe6050901, 0x09c7623f, + 0xe2f0d93c, 0x0d32b202, 0xefeea97b, 0x002cc245, 0xeb1b7946, + 0x04d91278, 0xf5d249f5, 0x1a1022cb, 0xf12799c8, 0x1ee5f2f6, + 0xfc39e98f, 0x13fb82b1, 0xf8cc39b2, 0x170e528c, 0xc1ab88e9, + 0x2e69e3d7, 0xc55e58d4, 0x2a9c33ea, 0xc8402893, 0x278243ad, + 0xccb5f8ae, 0x23779390, 0xd27cc81d, 0x3dbea323, 0xd6891820, + 0x394b731e, 0xdb976867, 0x34550359, 0xdf62b85a, 0x30a0d364, + 0xa9580ad1, 0x469a61ef, 0xadaddaec, 0x426fb1d2, 0xa0b3aaab, + 0x4f71c195, 0xa4467a96, 0x4b8411a8, 0xba8f4a25, 0x554d211b, + 0xbe7a9a18, 0x51b8f126, 0xb364ea5f, 0x5ca68161, 0xb7913a62, + 0x5853515c, 0x8ef68b39, 0x6134e007, 0x8a035b04, 0x65c1303a, + 0x871d2b43, 0x68df407d, 0x83e8fb7e, 0x6c2a9040, 0x9d21cbcd, + 0x72e3a0f3, 0x99d41bf0, 0x761670ce, 0x94ca6bb7, 0x7b080089, + 0x903fbb8a, 0x7ffdd0b4, 0x78bf0ea1, 0x977d659f, 0x7c4ade9c, + 0x9388b5a2, 0x7154aedb, 0x9e96c5e5, 0x75a17ee6, 0x9a6315d8, + 0x6b684e55, 0x84aa256b, 0x6f9d9e68, 0x805ff556, 0x6283ee2f, + 0x8d418511, 0x66763e12, 0x89b4552c, 0x5f118f49, 0xb0d3e477, + 0x5be45f74, 0xb426344a, 0x56fa2f33, 0xb938440d, 0x520fff0e, + 0xbdcd9430, 0x4cc6cfbd, 0xa304a483, 0x48331f80, 0xa7f174be, + 0x452d6fc7, 0xaaef04f9, 0x41d8bffa, 0xae1ad4c4, 0x37e20d71, + 0xd820664f, 0x3317dd4c, 0xdcd5b672, 0x3e09ad0b, 0xd1cbc635, + 0x3afc7d36, 0xd53e1608, 0x24354d85, 0xcbf726bb, 0x20c09db8, + 0xcf02f686, 0x2ddeedff, 0xc21c86c1, 0x292b3dc2, 0xc6e956fc, + 0x104c8c99, 0xff8ee7a7, 0x14b95ca4, 0xfb7b379a, 0x19a72ce3, + 0xf66547dd, 0x1d52fcde, 0xf29097e0, 0x039bcc6d, 0xec59a753, + 0x076e1c50, 0xe8ac776e, 0x0a706c17, 0xe5b20729, 0x0e85bc2a, + 0xe147d714}, + {0x00000000, 0x177b1443, 0x2ef62886, 0x398d3cc5, 0x5dec510c, + 0x4a97454f, 0x731a798a, 0x64616dc9, 0xbbd8a218, 0xaca3b65b, + 0x952e8a9e, 0x82559edd, 0xe634f314, 0xf14fe757, 0xc8c2db92, + 0xdfb9cfd1, 0xacc04271, 0xbbbb5632, 0x82366af7, 0x954d7eb4, + 0xf12c137d, 0xe657073e, 0xdfda3bfb, 0xc8a12fb8, 0x1718e069, + 0x0063f42a, 0x39eec8ef, 0x2e95dcac, 0x4af4b165, 0x5d8fa526, + 0x640299e3, 0x73798da0, 0x82f182a3, 0x958a96e0, 0xac07aa25, + 0xbb7cbe66, 0xdf1dd3af, 0xc866c7ec, 0xf1ebfb29, 0xe690ef6a, + 0x392920bb, 0x2e5234f8, 0x17df083d, 0x00a41c7e, 0x64c571b7, + 0x73be65f4, 0x4a335931, 0x5d484d72, 0x2e31c0d2, 0x394ad491, + 0x00c7e854, 0x17bcfc17, 0x73dd91de, 0x64a6859d, 0x5d2bb958, + 0x4a50ad1b, 0x95e962ca, 0x82927689, 0xbb1f4a4c, 0xac645e0f, + 0xc80533c6, 0xdf7e2785, 0xe6f31b40, 0xf1880f03, 0xde920307, + 0xc9e91744, 0xf0642b81, 0xe71f3fc2, 0x837e520b, 0x94054648, + 0xad887a8d, 0xbaf36ece, 0x654aa11f, 0x7231b55c, 0x4bbc8999, + 0x5cc79dda, 0x38a6f013, 0x2fdde450, 0x1650d895, 0x012bccd6, + 0x72524176, 0x65295535, 0x5ca469f0, 0x4bdf7db3, 0x2fbe107a, + 0x38c50439, 0x014838fc, 0x16332cbf, 0xc98ae36e, 0xdef1f72d, + 0xe77ccbe8, 0xf007dfab, 0x9466b262, 0x831da621, 0xba909ae4, + 0xadeb8ea7, 0x5c6381a4, 0x4b1895e7, 0x7295a922, 0x65eebd61, + 0x018fd0a8, 0x16f4c4eb, 0x2f79f82e, 0x3802ec6d, 0xe7bb23bc, + 0xf0c037ff, 0xc94d0b3a, 0xde361f79, 0xba5772b0, 0xad2c66f3, + 0x94a15a36, 0x83da4e75, 0xf0a3c3d5, 0xe7d8d796, 0xde55eb53, + 0xc92eff10, 0xad4f92d9, 0xba34869a, 0x83b9ba5f, 0x94c2ae1c, + 0x4b7b61cd, 0x5c00758e, 0x658d494b, 0x72f65d08, 0x169730c1, + 0x01ec2482, 0x38611847, 0x2f1a0c04, 0x6655004f, 0x712e140c, + 0x48a328c9, 0x5fd83c8a, 0x3bb95143, 0x2cc24500, 0x154f79c5, + 0x02346d86, 0xdd8da257, 0xcaf6b614, 0xf37b8ad1, 0xe4009e92, + 0x8061f35b, 0x971ae718, 0xae97dbdd, 0xb9eccf9e, 0xca95423e, + 0xddee567d, 0xe4636ab8, 0xf3187efb, 0x97791332, 0x80020771, + 0xb98f3bb4, 0xaef42ff7, 0x714de026, 0x6636f465, 0x5fbbc8a0, + 0x48c0dce3, 0x2ca1b12a, 0x3bdaa569, 0x025799ac, 0x152c8def, + 0xe4a482ec, 0xf3df96af, 0xca52aa6a, 0xdd29be29, 0xb948d3e0, + 0xae33c7a3, 0x97befb66, 0x80c5ef25, 0x5f7c20f4, 0x480734b7, + 0x718a0872, 0x66f11c31, 0x029071f8, 0x15eb65bb, 0x2c66597e, + 0x3b1d4d3d, 0x4864c09d, 0x5f1fd4de, 0x6692e81b, 0x71e9fc58, + 0x15889191, 0x02f385d2, 0x3b7eb917, 0x2c05ad54, 0xf3bc6285, + 0xe4c776c6, 0xdd4a4a03, 0xca315e40, 0xae503389, 0xb92b27ca, + 0x80a61b0f, 0x97dd0f4c, 0xb8c70348, 0xafbc170b, 0x96312bce, + 0x814a3f8d, 0xe52b5244, 0xf2504607, 0xcbdd7ac2, 0xdca66e81, + 0x031fa150, 0x1464b513, 0x2de989d6, 0x3a929d95, 0x5ef3f05c, + 0x4988e41f, 0x7005d8da, 0x677ecc99, 0x14074139, 0x037c557a, + 0x3af169bf, 0x2d8a7dfc, 0x49eb1035, 0x5e900476, 0x671d38b3, + 0x70662cf0, 0xafdfe321, 0xb8a4f762, 0x8129cba7, 0x9652dfe4, + 0xf233b22d, 0xe548a66e, 0xdcc59aab, 0xcbbe8ee8, 0x3a3681eb, + 0x2d4d95a8, 0x14c0a96d, 0x03bbbd2e, 0x67dad0e7, 0x70a1c4a4, + 0x492cf861, 0x5e57ec22, 0x81ee23f3, 0x969537b0, 0xaf180b75, + 0xb8631f36, 0xdc0272ff, 0xcb7966bc, 0xf2f45a79, 0xe58f4e3a, + 0x96f6c39a, 0x818dd7d9, 0xb800eb1c, 0xaf7bff5f, 0xcb1a9296, + 0xdc6186d5, 0xe5ecba10, 0xf297ae53, 0x2d2e6182, 0x3a5575c1, + 0x03d84904, 0x14a35d47, 0x70c2308e, 0x67b924cd, 0x5e341808, + 0x494f0c4b}}; + +local const z_word_t FAR crc_braid_big_table[][256] = { + {0x00000000, 0x43147b17, 0x8628f62e, 0xc53c8d39, 0x0c51ec5d, + 0x4f45974a, 0x8a791a73, 0xc96d6164, 0x18a2d8bb, 0x5bb6a3ac, + 0x9e8a2e95, 0xdd9e5582, 0x14f334e6, 0x57e74ff1, 0x92dbc2c8, + 0xd1cfb9df, 0x7142c0ac, 0x3256bbbb, 0xf76a3682, 0xb47e4d95, + 0x7d132cf1, 0x3e0757e6, 0xfb3bdadf, 0xb82fa1c8, 0x69e01817, + 0x2af46300, 0xefc8ee39, 0xacdc952e, 0x65b1f44a, 0x26a58f5d, + 0xe3990264, 0xa08d7973, 0xa382f182, 0xe0968a95, 0x25aa07ac, + 0x66be7cbb, 0xafd31ddf, 0xecc766c8, 0x29fbebf1, 0x6aef90e6, + 0xbb202939, 0xf834522e, 0x3d08df17, 0x7e1ca400, 0xb771c564, + 0xf465be73, 0x3159334a, 0x724d485d, 0xd2c0312e, 0x91d44a39, + 0x54e8c700, 0x17fcbc17, 0xde91dd73, 0x9d85a664, 0x58b92b5d, + 0x1bad504a, 0xca62e995, 0x89769282, 0x4c4a1fbb, 0x0f5e64ac, + 0xc63305c8, 0x85277edf, 0x401bf3e6, 0x030f88f1, 0x070392de, + 0x4417e9c9, 0x812b64f0, 0xc23f1fe7, 0x0b527e83, 0x48460594, + 0x8d7a88ad, 0xce6ef3ba, 0x1fa14a65, 0x5cb53172, 0x9989bc4b, + 0xda9dc75c, 0x13f0a638, 0x50e4dd2f, 0x95d85016, 0xd6cc2b01, + 0x76415272, 0x35552965, 0xf069a45c, 0xb37ddf4b, 0x7a10be2f, + 0x3904c538, 0xfc384801, 0xbf2c3316, 0x6ee38ac9, 0x2df7f1de, + 0xe8cb7ce7, 0xabdf07f0, 0x62b26694, 0x21a61d83, 0xe49a90ba, + 0xa78eebad, 0xa481635c, 0xe795184b, 0x22a99572, 0x61bdee65, + 0xa8d08f01, 0xebc4f416, 0x2ef8792f, 0x6dec0238, 0xbc23bbe7, + 0xff37c0f0, 0x3a0b4dc9, 0x791f36de, 0xb07257ba, 0xf3662cad, + 0x365aa194, 0x754eda83, 0xd5c3a3f0, 0x96d7d8e7, 0x53eb55de, + 0x10ff2ec9, 0xd9924fad, 0x9a8634ba, 0x5fbab983, 0x1caec294, + 0xcd617b4b, 0x8e75005c, 0x4b498d65, 0x085df672, 0xc1309716, + 0x8224ec01, 0x47186138, 0x040c1a2f, 0x4f005566, 0x0c142e71, + 0xc928a348, 0x8a3cd85f, 0x4351b93b, 0x0045c22c, 0xc5794f15, + 0x866d3402, 0x57a28ddd, 0x14b6f6ca, 0xd18a7bf3, 0x929e00e4, + 0x5bf36180, 0x18e71a97, 0xdddb97ae, 0x9ecfecb9, 0x3e4295ca, + 0x7d56eedd, 0xb86a63e4, 0xfb7e18f3, 0x32137997, 0x71070280, + 0xb43b8fb9, 0xf72ff4ae, 0x26e04d71, 0x65f43666, 0xa0c8bb5f, + 0xe3dcc048, 0x2ab1a12c, 0x69a5da3b, 0xac995702, 0xef8d2c15, + 0xec82a4e4, 0xaf96dff3, 0x6aaa52ca, 0x29be29dd, 0xe0d348b9, + 0xa3c733ae, 0x66fbbe97, 0x25efc580, 0xf4207c5f, 0xb7340748, + 0x72088a71, 0x311cf166, 0xf8719002, 0xbb65eb15, 0x7e59662c, + 0x3d4d1d3b, 0x9dc06448, 0xded41f5f, 0x1be89266, 0x58fce971, + 0x91918815, 0xd285f302, 0x17b97e3b, 0x54ad052c, 0x8562bcf3, + 0xc676c7e4, 0x034a4add, 0x405e31ca, 0x893350ae, 0xca272bb9, + 0x0f1ba680, 0x4c0fdd97, 0x4803c7b8, 0x0b17bcaf, 0xce2b3196, + 0x8d3f4a81, 0x44522be5, 0x074650f2, 0xc27addcb, 0x816ea6dc, + 0x50a11f03, 0x13b56414, 0xd689e92d, 0x959d923a, 0x5cf0f35e, + 0x1fe48849, 0xdad80570, 0x99cc7e67, 0x39410714, 0x7a557c03, + 0xbf69f13a, 0xfc7d8a2d, 0x3510eb49, 0x7604905e, 0xb3381d67, + 0xf02c6670, 0x21e3dfaf, 0x62f7a4b8, 0xa7cb2981, 0xe4df5296, + 0x2db233f2, 0x6ea648e5, 0xab9ac5dc, 0xe88ebecb, 0xeb81363a, + 0xa8954d2d, 0x6da9c014, 0x2ebdbb03, 0xe7d0da67, 0xa4c4a170, + 0x61f82c49, 0x22ec575e, 0xf323ee81, 0xb0379596, 0x750b18af, + 0x361f63b8, 0xff7202dc, 0xbc6679cb, 0x795af4f2, 0x3a4e8fe5, + 0x9ac3f696, 0xd9d78d81, 0x1ceb00b8, 0x5fff7baf, 0x96921acb, + 0xd58661dc, 0x10baece5, 0x53ae97f2, 0x82612e2d, 0xc175553a, + 0x0449d803, 0x475da314, 0x8e30c270, 0xcd24b967, 0x0818345e, + 0x4b0c4f49}, + {0x00000000, 0x3e6bc2ef, 0x3dd0f504, 0x03bb37eb, 0x7aa0eb09, + 0x44cb29e6, 0x47701e0d, 0x791bdce2, 0xf440d713, 0xca2b15fc, + 0xc9902217, 0xf7fbe0f8, 0x8ee03c1a, 0xb08bfef5, 0xb330c91e, + 0x8d5b0bf1, 0xe881ae27, 0xd6ea6cc8, 0xd5515b23, 0xeb3a99cc, + 0x9221452e, 0xac4a87c1, 0xaff1b02a, 0x919a72c5, 0x1cc17934, + 0x22aabbdb, 0x21118c30, 0x1f7a4edf, 0x6661923d, 0x580a50d2, + 0x5bb16739, 0x65daa5d6, 0xd0035d4f, 0xee689fa0, 0xedd3a84b, + 0xd3b86aa4, 0xaaa3b646, 0x94c874a9, 0x97734342, 0xa91881ad, + 0x24438a5c, 0x1a2848b3, 0x19937f58, 0x27f8bdb7, 0x5ee36155, + 0x6088a3ba, 0x63339451, 0x5d5856be, 0x3882f368, 0x06e93187, + 0x0552066c, 0x3b39c483, 0x42221861, 0x7c49da8e, 0x7ff2ed65, + 0x41992f8a, 0xccc2247b, 0xf2a9e694, 0xf112d17f, 0xcf791390, + 0xb662cf72, 0x88090d9d, 0x8bb23a76, 0xb5d9f899, 0xa007ba9e, + 0x9e6c7871, 0x9dd74f9a, 0xa3bc8d75, 0xdaa75197, 0xe4cc9378, + 0xe777a493, 0xd91c667c, 0x54476d8d, 0x6a2caf62, 0x69979889, + 0x57fc5a66, 0x2ee78684, 0x108c446b, 0x13377380, 0x2d5cb16f, + 0x488614b9, 0x76edd656, 0x7556e1bd, 0x4b3d2352, 0x3226ffb0, + 0x0c4d3d5f, 0x0ff60ab4, 0x319dc85b, 0xbcc6c3aa, 0x82ad0145, + 0x811636ae, 0xbf7df441, 0xc66628a3, 0xf80dea4c, 0xfbb6dda7, + 0xc5dd1f48, 0x7004e7d1, 0x4e6f253e, 0x4dd412d5, 0x73bfd03a, + 0x0aa40cd8, 0x34cfce37, 0x3774f9dc, 0x091f3b33, 0x844430c2, + 0xba2ff22d, 0xb994c5c6, 0x87ff0729, 0xfee4dbcb, 0xc08f1924, + 0xc3342ecf, 0xfd5fec20, 0x988549f6, 0xa6ee8b19, 0xa555bcf2, + 0x9b3e7e1d, 0xe225a2ff, 0xdc4e6010, 0xdff557fb, 0xe19e9514, + 0x6cc59ee5, 0x52ae5c0a, 0x51156be1, 0x6f7ea90e, 0x166575ec, + 0x280eb703, 0x2bb580e8, 0x15de4207, 0x010905e6, 0x3f62c709, + 0x3cd9f0e2, 0x02b2320d, 0x7ba9eeef, 0x45c22c00, 0x46791beb, + 0x7812d904, 0xf549d2f5, 0xcb22101a, 0xc89927f1, 0xf6f2e51e, + 0x8fe939fc, 0xb182fb13, 0xb239ccf8, 0x8c520e17, 0xe988abc1, + 0xd7e3692e, 0xd4585ec5, 0xea339c2a, 0x932840c8, 0xad438227, + 0xaef8b5cc, 0x90937723, 0x1dc87cd2, 0x23a3be3d, 0x201889d6, + 0x1e734b39, 0x676897db, 0x59035534, 0x5ab862df, 0x64d3a030, + 0xd10a58a9, 0xef619a46, 0xecdaadad, 0xd2b16f42, 0xabaab3a0, + 0x95c1714f, 0x967a46a4, 0xa811844b, 0x254a8fba, 0x1b214d55, + 0x189a7abe, 0x26f1b851, 0x5fea64b3, 0x6181a65c, 0x623a91b7, + 0x5c515358, 0x398bf68e, 0x07e03461, 0x045b038a, 0x3a30c165, + 0x432b1d87, 0x7d40df68, 0x7efbe883, 0x40902a6c, 0xcdcb219d, + 0xf3a0e372, 0xf01bd499, 0xce701676, 0xb76bca94, 0x8900087b, + 0x8abb3f90, 0xb4d0fd7f, 0xa10ebf78, 0x9f657d97, 0x9cde4a7c, + 0xa2b58893, 0xdbae5471, 0xe5c5969e, 0xe67ea175, 0xd815639a, + 0x554e686b, 0x6b25aa84, 0x689e9d6f, 0x56f55f80, 0x2fee8362, + 0x1185418d, 0x123e7666, 0x2c55b489, 0x498f115f, 0x77e4d3b0, + 0x745fe45b, 0x4a3426b4, 0x332ffa56, 0x0d4438b9, 0x0eff0f52, + 0x3094cdbd, 0xbdcfc64c, 0x83a404a3, 0x801f3348, 0xbe74f1a7, + 0xc76f2d45, 0xf904efaa, 0xfabfd841, 0xc4d41aae, 0x710de237, + 0x4f6620d8, 0x4cdd1733, 0x72b6d5dc, 0x0bad093e, 0x35c6cbd1, + 0x367dfc3a, 0x08163ed5, 0x854d3524, 0xbb26f7cb, 0xb89dc020, + 0x86f602cf, 0xffedde2d, 0xc1861cc2, 0xc23d2b29, 0xfc56e9c6, + 0x998c4c10, 0xa7e78eff, 0xa45cb914, 0x9a377bfb, 0xe32ca719, + 0xdd4765f6, 0xdefc521d, 0xe09790f2, 0x6dcc9b03, 0x53a759ec, + 0x501c6e07, 0x6e77ace8, 0x176c700a, 0x2907b2e5, 0x2abc850e, + 0x14d747e1}, + {0x00000000, 0xc0df8ec1, 0xc1b96c58, 0x0166e299, 0x8273d9b0, + 0x42ac5771, 0x43cab5e8, 0x83153b29, 0x45e1c3ba, 0x853e4d7b, + 0x8458afe2, 0x44872123, 0xc7921a0a, 0x074d94cb, 0x062b7652, + 0xc6f4f893, 0xcbc4f6ae, 0x0b1b786f, 0x0a7d9af6, 0xcaa21437, + 0x49b72f1e, 0x8968a1df, 0x880e4346, 0x48d1cd87, 0x8e253514, + 0x4efabbd5, 0x4f9c594c, 0x8f43d78d, 0x0c56eca4, 0xcc896265, + 0xcdef80fc, 0x0d300e3d, 0xd78f9c86, 0x17501247, 0x1636f0de, + 0xd6e97e1f, 0x55fc4536, 0x9523cbf7, 0x9445296e, 0x549aa7af, + 0x926e5f3c, 0x52b1d1fd, 0x53d73364, 0x9308bda5, 0x101d868c, + 0xd0c2084d, 0xd1a4ead4, 0x117b6415, 0x1c4b6a28, 0xdc94e4e9, + 0xddf20670, 0x1d2d88b1, 0x9e38b398, 0x5ee73d59, 0x5f81dfc0, + 0x9f5e5101, 0x59aaa992, 0x99752753, 0x9813c5ca, 0x58cc4b0b, + 0xdbd97022, 0x1b06fee3, 0x1a601c7a, 0xdabf92bb, 0xef1948d6, + 0x2fc6c617, 0x2ea0248e, 0xee7faa4f, 0x6d6a9166, 0xadb51fa7, + 0xacd3fd3e, 0x6c0c73ff, 0xaaf88b6c, 0x6a2705ad, 0x6b41e734, + 0xab9e69f5, 0x288b52dc, 0xe854dc1d, 0xe9323e84, 0x29edb045, + 0x24ddbe78, 0xe40230b9, 0xe564d220, 0x25bb5ce1, 0xa6ae67c8, + 0x6671e909, 0x67170b90, 0xa7c88551, 0x613c7dc2, 0xa1e3f303, + 0xa085119a, 0x605a9f5b, 0xe34fa472, 0x23902ab3, 0x22f6c82a, + 0xe22946eb, 0x3896d450, 0xf8495a91, 0xf92fb808, 0x39f036c9, + 0xbae50de0, 0x7a3a8321, 0x7b5c61b8, 0xbb83ef79, 0x7d7717ea, + 0xbda8992b, 0xbcce7bb2, 0x7c11f573, 0xff04ce5a, 0x3fdb409b, + 0x3ebda202, 0xfe622cc3, 0xf35222fe, 0x338dac3f, 0x32eb4ea6, + 0xf234c067, 0x7121fb4e, 0xb1fe758f, 0xb0989716, 0x704719d7, + 0xb6b3e144, 0x766c6f85, 0x770a8d1c, 0xb7d503dd, 0x34c038f4, + 0xf41fb635, 0xf57954ac, 0x35a6da6d, 0x9f35e177, 0x5fea6fb6, + 0x5e8c8d2f, 0x9e5303ee, 0x1d4638c7, 0xdd99b606, 0xdcff549f, + 0x1c20da5e, 0xdad422cd, 0x1a0bac0c, 0x1b6d4e95, 0xdbb2c054, + 0x58a7fb7d, 0x987875bc, 0x991e9725, 0x59c119e4, 0x54f117d9, + 0x942e9918, 0x95487b81, 0x5597f540, 0xd682ce69, 0x165d40a8, + 0x173ba231, 0xd7e42cf0, 0x1110d463, 0xd1cf5aa2, 0xd0a9b83b, + 0x107636fa, 0x93630dd3, 0x53bc8312, 0x52da618b, 0x9205ef4a, + 0x48ba7df1, 0x8865f330, 0x890311a9, 0x49dc9f68, 0xcac9a441, + 0x0a162a80, 0x0b70c819, 0xcbaf46d8, 0x0d5bbe4b, 0xcd84308a, + 0xcce2d213, 0x0c3d5cd2, 0x8f2867fb, 0x4ff7e93a, 0x4e910ba3, + 0x8e4e8562, 0x837e8b5f, 0x43a1059e, 0x42c7e707, 0x821869c6, + 0x010d52ef, 0xc1d2dc2e, 0xc0b43eb7, 0x006bb076, 0xc69f48e5, + 0x0640c624, 0x072624bd, 0xc7f9aa7c, 0x44ec9155, 0x84331f94, + 0x8555fd0d, 0x458a73cc, 0x702ca9a1, 0xb0f32760, 0xb195c5f9, + 0x714a4b38, 0xf25f7011, 0x3280fed0, 0x33e61c49, 0xf3399288, + 0x35cd6a1b, 0xf512e4da, 0xf4740643, 0x34ab8882, 0xb7beb3ab, + 0x77613d6a, 0x7607dff3, 0xb6d85132, 0xbbe85f0f, 0x7b37d1ce, + 0x7a513357, 0xba8ebd96, 0x399b86bf, 0xf944087e, 0xf822eae7, + 0x38fd6426, 0xfe099cb5, 0x3ed61274, 0x3fb0f0ed, 0xff6f7e2c, + 0x7c7a4505, 0xbca5cbc4, 0xbdc3295d, 0x7d1ca79c, 0xa7a33527, + 0x677cbbe6, 0x661a597f, 0xa6c5d7be, 0x25d0ec97, 0xe50f6256, + 0xe46980cf, 0x24b60e0e, 0xe242f69d, 0x229d785c, 0x23fb9ac5, + 0xe3241404, 0x60312f2d, 0xa0eea1ec, 0xa1884375, 0x6157cdb4, + 0x6c67c389, 0xacb84d48, 0xaddeafd1, 0x6d012110, 0xee141a39, + 0x2ecb94f8, 0x2fad7661, 0xef72f8a0, 0x29860033, 0xe9598ef2, + 0xe83f6c6b, 0x28e0e2aa, 0xabf5d983, 0x6b2a5742, 0x6a4cb5db, + 0xaa933b1a}, + {0x00000000, 0x6f4ca59b, 0x9f9e3bec, 0xf0d29e77, 0x7f3b0603, + 0x1077a398, 0xe0a53def, 0x8fe99874, 0xfe760c06, 0x913aa99d, + 0x61e837ea, 0x0ea49271, 0x814d0a05, 0xee01af9e, 0x1ed331e9, + 0x719f9472, 0xfced180c, 0x93a1bd97, 0x637323e0, 0x0c3f867b, + 0x83d61e0f, 0xec9abb94, 0x1c4825e3, 0x73048078, 0x029b140a, + 0x6dd7b191, 0x9d052fe6, 0xf2498a7d, 0x7da01209, 0x12ecb792, + 0xe23e29e5, 0x8d728c7e, 0xf8db3118, 0x97979483, 0x67450af4, + 0x0809af6f, 0x87e0371b, 0xe8ac9280, 0x187e0cf7, 0x7732a96c, + 0x06ad3d1e, 0x69e19885, 0x993306f2, 0xf67fa369, 0x79963b1d, + 0x16da9e86, 0xe60800f1, 0x8944a56a, 0x04362914, 0x6b7a8c8f, + 0x9ba812f8, 0xf4e4b763, 0x7b0d2f17, 0x14418a8c, 0xe49314fb, + 0x8bdfb160, 0xfa402512, 0x950c8089, 0x65de1efe, 0x0a92bb65, + 0x857b2311, 0xea37868a, 0x1ae518fd, 0x75a9bd66, 0xf0b76330, + 0x9ffbc6ab, 0x6f2958dc, 0x0065fd47, 0x8f8c6533, 0xe0c0c0a8, + 0x10125edf, 0x7f5efb44, 0x0ec16f36, 0x618dcaad, 0x915f54da, + 0xfe13f141, 0x71fa6935, 0x1eb6ccae, 0xee6452d9, 0x8128f742, + 0x0c5a7b3c, 0x6316dea7, 0x93c440d0, 0xfc88e54b, 0x73617d3f, + 0x1c2dd8a4, 0xecff46d3, 0x83b3e348, 0xf22c773a, 0x9d60d2a1, + 0x6db24cd6, 0x02fee94d, 0x8d177139, 0xe25bd4a2, 0x12894ad5, + 0x7dc5ef4e, 0x086c5228, 0x6720f7b3, 0x97f269c4, 0xf8becc5f, + 0x7757542b, 0x181bf1b0, 0xe8c96fc7, 0x8785ca5c, 0xf61a5e2e, + 0x9956fbb5, 0x698465c2, 0x06c8c059, 0x8921582d, 0xe66dfdb6, + 0x16bf63c1, 0x79f3c65a, 0xf4814a24, 0x9bcdefbf, 0x6b1f71c8, + 0x0453d453, 0x8bba4c27, 0xe4f6e9bc, 0x142477cb, 0x7b68d250, + 0x0af74622, 0x65bbe3b9, 0x95697dce, 0xfa25d855, 0x75cc4021, + 0x1a80e5ba, 0xea527bcd, 0x851ede56, 0xe06fc760, 0x8f2362fb, + 0x7ff1fc8c, 0x10bd5917, 0x9f54c163, 0xf01864f8, 0x00cafa8f, + 0x6f865f14, 0x1e19cb66, 0x71556efd, 0x8187f08a, 0xeecb5511, + 0x6122cd65, 0x0e6e68fe, 0xfebcf689, 0x91f05312, 0x1c82df6c, + 0x73ce7af7, 0x831ce480, 0xec50411b, 0x63b9d96f, 0x0cf57cf4, + 0xfc27e283, 0x936b4718, 0xe2f4d36a, 0x8db876f1, 0x7d6ae886, + 0x12264d1d, 0x9dcfd569, 0xf28370f2, 0x0251ee85, 0x6d1d4b1e, + 0x18b4f678, 0x77f853e3, 0x872acd94, 0xe866680f, 0x678ff07b, + 0x08c355e0, 0xf811cb97, 0x975d6e0c, 0xe6c2fa7e, 0x898e5fe5, + 0x795cc192, 0x16106409, 0x99f9fc7d, 0xf6b559e6, 0x0667c791, + 0x692b620a, 0xe459ee74, 0x8b154bef, 0x7bc7d598, 0x148b7003, + 0x9b62e877, 0xf42e4dec, 0x04fcd39b, 0x6bb07600, 0x1a2fe272, + 0x756347e9, 0x85b1d99e, 0xeafd7c05, 0x6514e471, 0x0a5841ea, + 0xfa8adf9d, 0x95c67a06, 0x10d8a450, 0x7f9401cb, 0x8f469fbc, + 0xe00a3a27, 0x6fe3a253, 0x00af07c8, 0xf07d99bf, 0x9f313c24, + 0xeeaea856, 0x81e20dcd, 0x713093ba, 0x1e7c3621, 0x9195ae55, + 0xfed90bce, 0x0e0b95b9, 0x61473022, 0xec35bc5c, 0x837919c7, + 0x73ab87b0, 0x1ce7222b, 0x930eba5f, 0xfc421fc4, 0x0c9081b3, + 0x63dc2428, 0x1243b05a, 0x7d0f15c1, 0x8ddd8bb6, 0xe2912e2d, + 0x6d78b659, 0x023413c2, 0xf2e68db5, 0x9daa282e, 0xe8039548, + 0x874f30d3, 0x779daea4, 0x18d10b3f, 0x9738934b, 0xf87436d0, + 0x08a6a8a7, 0x67ea0d3c, 0x1675994e, 0x79393cd5, 0x89eba2a2, + 0xe6a70739, 0x694e9f4d, 0x06023ad6, 0xf6d0a4a1, 0x999c013a, + 0x14ee8d44, 0x7ba228df, 0x8b70b6a8, 0xe43c1333, 0x6bd58b47, + 0x04992edc, 0xf44bb0ab, 0x9b071530, 0xea988142, 0x85d424d9, + 0x7506baae, 0x1a4a1f35, 0x95a38741, 0xfaef22da, 0x0a3dbcad, + 0x65711936}}; + +#endif + +#endif + +#if N == 4 + +#if W == 8 + +local const z_crc_t FAR crc_braid_table[][256] = { + {0x00000000, 0xf1da05aa, 0x38c50d15, 0xc91f08bf, 0x718a1a2a, + 0x80501f80, 0x494f173f, 0xb8951295, 0xe3143454, 0x12ce31fe, + 0xdbd13941, 0x2a0b3ceb, 0x929e2e7e, 0x63442bd4, 0xaa5b236b, + 0x5b8126c1, 0x1d596ee9, 0xec836b43, 0x259c63fc, 0xd4466656, + 0x6cd374c3, 0x9d097169, 0x541679d6, 0xa5cc7c7c, 0xfe4d5abd, + 0x0f975f17, 0xc68857a8, 0x37525202, 0x8fc74097, 0x7e1d453d, + 0xb7024d82, 0x46d84828, 0x3ab2ddd2, 0xcb68d878, 0x0277d0c7, + 0xf3add56d, 0x4b38c7f8, 0xbae2c252, 0x73fdcaed, 0x8227cf47, + 0xd9a6e986, 0x287cec2c, 0xe163e493, 0x10b9e139, 0xa82cf3ac, + 0x59f6f606, 0x90e9feb9, 0x6133fb13, 0x27ebb33b, 0xd631b691, + 0x1f2ebe2e, 0xeef4bb84, 0x5661a911, 0xa7bbacbb, 0x6ea4a404, + 0x9f7ea1ae, 0xc4ff876f, 0x352582c5, 0xfc3a8a7a, 0x0de08fd0, + 0xb5759d45, 0x44af98ef, 0x8db09050, 0x7c6a95fa, 0x7565bba4, + 0x84bfbe0e, 0x4da0b6b1, 0xbc7ab31b, 0x04efa18e, 0xf535a424, + 0x3c2aac9b, 0xcdf0a931, 0x96718ff0, 0x67ab8a5a, 0xaeb482e5, + 0x5f6e874f, 0xe7fb95da, 0x16219070, 0xdf3e98cf, 0x2ee49d65, + 0x683cd54d, 0x99e6d0e7, 0x50f9d858, 0xa123ddf2, 0x19b6cf67, + 0xe86ccacd, 0x2173c272, 0xd0a9c7d8, 0x8b28e119, 0x7af2e4b3, + 0xb3edec0c, 0x4237e9a6, 0xfaa2fb33, 0x0b78fe99, 0xc267f626, + 0x33bdf38c, 0x4fd76676, 0xbe0d63dc, 0x77126b63, 0x86c86ec9, + 0x3e5d7c5c, 0xcf8779f6, 0x06987149, 0xf74274e3, 0xacc35222, + 0x5d195788, 0x94065f37, 0x65dc5a9d, 0xdd494808, 0x2c934da2, + 0xe58c451d, 0x145640b7, 0x528e089f, 0xa3540d35, 0x6a4b058a, + 0x9b910020, 0x230412b5, 0xd2de171f, 0x1bc11fa0, 0xea1b1a0a, + 0xb19a3ccb, 0x40403961, 0x895f31de, 0x78853474, 0xc01026e1, + 0x31ca234b, 0xf8d52bf4, 0x090f2e5e, 0xeacb7748, 0x1b1172e2, + 0xd20e7a5d, 0x23d47ff7, 0x9b416d62, 0x6a9b68c8, 0xa3846077, + 0x525e65dd, 0x09df431c, 0xf80546b6, 0x311a4e09, 0xc0c04ba3, + 0x78555936, 0x898f5c9c, 0x40905423, 0xb14a5189, 0xf79219a1, + 0x06481c0b, 0xcf5714b4, 0x3e8d111e, 0x8618038b, 0x77c20621, + 0xbedd0e9e, 0x4f070b34, 0x14862df5, 0xe55c285f, 0x2c4320e0, + 0xdd99254a, 0x650c37df, 0x94d63275, 0x5dc93aca, 0xac133f60, + 0xd079aa9a, 0x21a3af30, 0xe8bca78f, 0x1966a225, 0xa1f3b0b0, + 0x5029b51a, 0x9936bda5, 0x68ecb80f, 0x336d9ece, 0xc2b79b64, + 0x0ba893db, 0xfa729671, 0x42e784e4, 0xb33d814e, 0x7a2289f1, + 0x8bf88c5b, 0xcd20c473, 0x3cfac1d9, 0xf5e5c966, 0x043fcccc, + 0xbcaade59, 0x4d70dbf3, 0x846fd34c, 0x75b5d6e6, 0x2e34f027, + 0xdfeef58d, 0x16f1fd32, 0xe72bf898, 0x5fbeea0d, 0xae64efa7, + 0x677be718, 0x96a1e2b2, 0x9faeccec, 0x6e74c946, 0xa76bc1f9, + 0x56b1c453, 0xee24d6c6, 0x1ffed36c, 0xd6e1dbd3, 0x273bde79, + 0x7cbaf8b8, 0x8d60fd12, 0x447ff5ad, 0xb5a5f007, 0x0d30e292, + 0xfceae738, 0x35f5ef87, 0xc42fea2d, 0x82f7a205, 0x732da7af, + 0xba32af10, 0x4be8aaba, 0xf37db82f, 0x02a7bd85, 0xcbb8b53a, + 0x3a62b090, 0x61e39651, 0x903993fb, 0x59269b44, 0xa8fc9eee, + 0x10698c7b, 0xe1b389d1, 0x28ac816e, 0xd97684c4, 0xa51c113e, + 0x54c61494, 0x9dd91c2b, 0x6c031981, 0xd4960b14, 0x254c0ebe, + 0xec530601, 0x1d8903ab, 0x4608256a, 0xb7d220c0, 0x7ecd287f, + 0x8f172dd5, 0x37823f40, 0xc6583aea, 0x0f473255, 0xfe9d37ff, + 0xb8457fd7, 0x499f7a7d, 0x808072c2, 0x715a7768, 0xc9cf65fd, + 0x38156057, 0xf10a68e8, 0x00d06d42, 0x5b514b83, 0xaa8b4e29, + 0x63944696, 0x924e433c, 0x2adb51a9, 0xdb015403, 0x121e5cbc, + 0xe3c45916}, + {0x00000000, 0x0ee7e8d1, 0x1dcfd1a2, 0x13283973, 0x3b9fa344, + 0x35784b95, 0x265072e6, 0x28b79a37, 0x773f4688, 0x79d8ae59, + 0x6af0972a, 0x64177ffb, 0x4ca0e5cc, 0x42470d1d, 0x516f346e, + 0x5f88dcbf, 0xee7e8d10, 0xe09965c1, 0xf3b15cb2, 0xfd56b463, + 0xd5e12e54, 0xdb06c685, 0xc82efff6, 0xc6c91727, 0x9941cb98, + 0x97a62349, 0x848e1a3a, 0x8a69f2eb, 0xa2de68dc, 0xac39800d, + 0xbf11b97e, 0xb1f651af, 0x078c1c61, 0x096bf4b0, 0x1a43cdc3, + 0x14a42512, 0x3c13bf25, 0x32f457f4, 0x21dc6e87, 0x2f3b8656, + 0x70b35ae9, 0x7e54b238, 0x6d7c8b4b, 0x639b639a, 0x4b2cf9ad, + 0x45cb117c, 0x56e3280f, 0x5804c0de, 0xe9f29171, 0xe71579a0, + 0xf43d40d3, 0xfadaa802, 0xd26d3235, 0xdc8adae4, 0xcfa2e397, + 0xc1450b46, 0x9ecdd7f9, 0x902a3f28, 0x8302065b, 0x8de5ee8a, + 0xa55274bd, 0xabb59c6c, 0xb89da51f, 0xb67a4dce, 0x0f1838c2, + 0x01ffd013, 0x12d7e960, 0x1c3001b1, 0x34879b86, 0x3a607357, + 0x29484a24, 0x27afa2f5, 0x78277e4a, 0x76c0969b, 0x65e8afe8, + 0x6b0f4739, 0x43b8dd0e, 0x4d5f35df, 0x5e770cac, 0x5090e47d, + 0xe166b5d2, 0xef815d03, 0xfca96470, 0xf24e8ca1, 0xdaf91696, + 0xd41efe47, 0xc736c734, 0xc9d12fe5, 0x9659f35a, 0x98be1b8b, + 0x8b9622f8, 0x8571ca29, 0xadc6501e, 0xa321b8cf, 0xb00981bc, + 0xbeee696d, 0x089424a3, 0x0673cc72, 0x155bf501, 0x1bbc1dd0, + 0x330b87e7, 0x3dec6f36, 0x2ec45645, 0x2023be94, 0x7fab622b, + 0x714c8afa, 0x6264b389, 0x6c835b58, 0x4434c16f, 0x4ad329be, + 0x59fb10cd, 0x571cf81c, 0xe6eaa9b3, 0xe80d4162, 0xfb257811, + 0xf5c290c0, 0xdd750af7, 0xd392e226, 0xc0badb55, 0xce5d3384, + 0x91d5ef3b, 0x9f3207ea, 0x8c1a3e99, 0x82fdd648, 0xaa4a4c7f, + 0xa4ada4ae, 0xb7859ddd, 0xb962750c, 0x1e307184, 0x10d79955, + 0x03ffa026, 0x0d1848f7, 0x25afd2c0, 0x2b483a11, 0x38600362, + 0x3687ebb3, 0x690f370c, 0x67e8dfdd, 0x74c0e6ae, 0x7a270e7f, + 0x52909448, 0x5c777c99, 0x4f5f45ea, 0x41b8ad3b, 0xf04efc94, + 0xfea91445, 0xed812d36, 0xe366c5e7, 0xcbd15fd0, 0xc536b701, + 0xd61e8e72, 0xd8f966a3, 0x8771ba1c, 0x899652cd, 0x9abe6bbe, + 0x9459836f, 0xbcee1958, 0xb209f189, 0xa121c8fa, 0xafc6202b, + 0x19bc6de5, 0x175b8534, 0x0473bc47, 0x0a945496, 0x2223cea1, + 0x2cc42670, 0x3fec1f03, 0x310bf7d2, 0x6e832b6d, 0x6064c3bc, + 0x734cfacf, 0x7dab121e, 0x551c8829, 0x5bfb60f8, 0x48d3598b, + 0x4634b15a, 0xf7c2e0f5, 0xf9250824, 0xea0d3157, 0xe4ead986, + 0xcc5d43b1, 0xc2baab60, 0xd1929213, 0xdf757ac2, 0x80fda67d, + 0x8e1a4eac, 0x9d3277df, 0x93d59f0e, 0xbb620539, 0xb585ede8, + 0xa6add49b, 0xa84a3c4a, 0x11284946, 0x1fcfa197, 0x0ce798e4, + 0x02007035, 0x2ab7ea02, 0x245002d3, 0x37783ba0, 0x399fd371, + 0x66170fce, 0x68f0e71f, 0x7bd8de6c, 0x753f36bd, 0x5d88ac8a, + 0x536f445b, 0x40477d28, 0x4ea095f9, 0xff56c456, 0xf1b12c87, + 0xe29915f4, 0xec7efd25, 0xc4c96712, 0xca2e8fc3, 0xd906b6b0, + 0xd7e15e61, 0x886982de, 0x868e6a0f, 0x95a6537c, 0x9b41bbad, + 0xb3f6219a, 0xbd11c94b, 0xae39f038, 0xa0de18e9, 0x16a45527, + 0x1843bdf6, 0x0b6b8485, 0x058c6c54, 0x2d3bf663, 0x23dc1eb2, + 0x30f427c1, 0x3e13cf10, 0x619b13af, 0x6f7cfb7e, 0x7c54c20d, + 0x72b32adc, 0x5a04b0eb, 0x54e3583a, 0x47cb6149, 0x492c8998, + 0xf8dad837, 0xf63d30e6, 0xe5150995, 0xebf2e144, 0xc3457b73, + 0xcda293a2, 0xde8aaad1, 0xd06d4200, 0x8fe59ebf, 0x8102766e, + 0x922a4f1d, 0x9ccda7cc, 0xb47a3dfb, 0xba9dd52a, 0xa9b5ec59, + 0xa7520488}, + {0x00000000, 0x3c60e308, 0x78c1c610, 0x44a12518, 0xf1838c20, + 0xcde36f28, 0x89424a30, 0xb522a938, 0x38761e01, 0x0416fd09, + 0x40b7d811, 0x7cd73b19, 0xc9f59221, 0xf5957129, 0xb1345431, + 0x8d54b739, 0x70ec3c02, 0x4c8cdf0a, 0x082dfa12, 0x344d191a, + 0x816fb022, 0xbd0f532a, 0xf9ae7632, 0xc5ce953a, 0x489a2203, + 0x74fac10b, 0x305be413, 0x0c3b071b, 0xb919ae23, 0x85794d2b, + 0xc1d86833, 0xfdb88b3b, 0xe1d87804, 0xddb89b0c, 0x9919be14, + 0xa5795d1c, 0x105bf424, 0x2c3b172c, 0x689a3234, 0x54fad13c, + 0xd9ae6605, 0xe5ce850d, 0xa16fa015, 0x9d0f431d, 0x282dea25, + 0x144d092d, 0x50ec2c35, 0x6c8ccf3d, 0x91344406, 0xad54a70e, + 0xe9f58216, 0xd595611e, 0x60b7c826, 0x5cd72b2e, 0x18760e36, + 0x2416ed3e, 0xa9425a07, 0x9522b90f, 0xd1839c17, 0xede37f1f, + 0x58c1d627, 0x64a1352f, 0x20001037, 0x1c60f33f, 0x18c1f649, + 0x24a11541, 0x60003059, 0x5c60d351, 0xe9427a69, 0xd5229961, + 0x9183bc79, 0xade35f71, 0x20b7e848, 0x1cd70b40, 0x58762e58, + 0x6416cd50, 0xd1346468, 0xed548760, 0xa9f5a278, 0x95954170, + 0x682dca4b, 0x544d2943, 0x10ec0c5b, 0x2c8cef53, 0x99ae466b, + 0xa5cea563, 0xe16f807b, 0xdd0f6373, 0x505bd44a, 0x6c3b3742, + 0x289a125a, 0x14faf152, 0xa1d8586a, 0x9db8bb62, 0xd9199e7a, + 0xe5797d72, 0xf9198e4d, 0xc5796d45, 0x81d8485d, 0xbdb8ab55, + 0x089a026d, 0x34fae165, 0x705bc47d, 0x4c3b2775, 0xc16f904c, + 0xfd0f7344, 0xb9ae565c, 0x85ceb554, 0x30ec1c6c, 0x0c8cff64, + 0x482dda7c, 0x744d3974, 0x89f5b24f, 0xb5955147, 0xf134745f, + 0xcd549757, 0x78763e6f, 0x4416dd67, 0x00b7f87f, 0x3cd71b77, + 0xb183ac4e, 0x8de34f46, 0xc9426a5e, 0xf5228956, 0x4000206e, + 0x7c60c366, 0x38c1e67e, 0x04a10576, 0x3183ec92, 0x0de30f9a, + 0x49422a82, 0x7522c98a, 0xc00060b2, 0xfc6083ba, 0xb8c1a6a2, + 0x84a145aa, 0x09f5f293, 0x3595119b, 0x71343483, 0x4d54d78b, + 0xf8767eb3, 0xc4169dbb, 0x80b7b8a3, 0xbcd75bab, 0x416fd090, + 0x7d0f3398, 0x39ae1680, 0x05cef588, 0xb0ec5cb0, 0x8c8cbfb8, + 0xc82d9aa0, 0xf44d79a8, 0x7919ce91, 0x45792d99, 0x01d80881, + 0x3db8eb89, 0x889a42b1, 0xb4faa1b9, 0xf05b84a1, 0xcc3b67a9, + 0xd05b9496, 0xec3b779e, 0xa89a5286, 0x94fab18e, 0x21d818b6, + 0x1db8fbbe, 0x5919dea6, 0x65793dae, 0xe82d8a97, 0xd44d699f, + 0x90ec4c87, 0xac8caf8f, 0x19ae06b7, 0x25cee5bf, 0x616fc0a7, + 0x5d0f23af, 0xa0b7a894, 0x9cd74b9c, 0xd8766e84, 0xe4168d8c, + 0x513424b4, 0x6d54c7bc, 0x29f5e2a4, 0x159501ac, 0x98c1b695, + 0xa4a1559d, 0xe0007085, 0xdc60938d, 0x69423ab5, 0x5522d9bd, + 0x1183fca5, 0x2de31fad, 0x29421adb, 0x1522f9d3, 0x5183dccb, + 0x6de33fc3, 0xd8c196fb, 0xe4a175f3, 0xa00050eb, 0x9c60b3e3, + 0x113404da, 0x2d54e7d2, 0x69f5c2ca, 0x559521c2, 0xe0b788fa, + 0xdcd76bf2, 0x98764eea, 0xa416ade2, 0x59ae26d9, 0x65cec5d1, + 0x216fe0c9, 0x1d0f03c1, 0xa82daaf9, 0x944d49f1, 0xd0ec6ce9, + 0xec8c8fe1, 0x61d838d8, 0x5db8dbd0, 0x1919fec8, 0x25791dc0, + 0x905bb4f8, 0xac3b57f0, 0xe89a72e8, 0xd4fa91e0, 0xc89a62df, + 0xf4fa81d7, 0xb05ba4cf, 0x8c3b47c7, 0x3919eeff, 0x05790df7, + 0x41d828ef, 0x7db8cbe7, 0xf0ec7cde, 0xcc8c9fd6, 0x882dbace, + 0xb44d59c6, 0x016ff0fe, 0x3d0f13f6, 0x79ae36ee, 0x45ced5e6, + 0xb8765edd, 0x8416bdd5, 0xc0b798cd, 0xfcd77bc5, 0x49f5d2fd, + 0x759531f5, 0x313414ed, 0x0d54f7e5, 0x800040dc, 0xbc60a3d4, + 0xf8c186cc, 0xc4a165c4, 0x7183ccfc, 0x4de32ff4, 0x09420aec, + 0x3522e9e4}, + {0x00000000, 0x6307d924, 0xc60fb248, 0xa5086b6c, 0x576e62d1, + 0x3469bbf5, 0x9161d099, 0xf26609bd, 0xaedcc5a2, 0xcddb1c86, + 0x68d377ea, 0x0bd4aece, 0xf9b2a773, 0x9ab57e57, 0x3fbd153b, + 0x5cbacc1f, 0x86c88d05, 0xe5cf5421, 0x40c73f4d, 0x23c0e669, + 0xd1a6efd4, 0xb2a136f0, 0x17a95d9c, 0x74ae84b8, 0x281448a7, + 0x4b139183, 0xee1bfaef, 0x8d1c23cb, 0x7f7a2a76, 0x1c7df352, + 0xb975983e, 0xda72411a, 0xd6e01c4b, 0xb5e7c56f, 0x10efae03, + 0x73e87727, 0x818e7e9a, 0xe289a7be, 0x4781ccd2, 0x248615f6, + 0x783cd9e9, 0x1b3b00cd, 0xbe336ba1, 0xdd34b285, 0x2f52bb38, + 0x4c55621c, 0xe95d0970, 0x8a5ad054, 0x5028914e, 0x332f486a, + 0x96272306, 0xf520fa22, 0x0746f39f, 0x64412abb, 0xc14941d7, + 0xa24e98f3, 0xfef454ec, 0x9df38dc8, 0x38fbe6a4, 0x5bfc3f80, + 0xa99a363d, 0xca9def19, 0x6f958475, 0x0c925d51, 0x76b13ed7, + 0x15b6e7f3, 0xb0be8c9f, 0xd3b955bb, 0x21df5c06, 0x42d88522, + 0xe7d0ee4e, 0x84d7376a, 0xd86dfb75, 0xbb6a2251, 0x1e62493d, + 0x7d659019, 0x8f0399a4, 0xec044080, 0x490c2bec, 0x2a0bf2c8, + 0xf079b3d2, 0x937e6af6, 0x3676019a, 0x5571d8be, 0xa717d103, + 0xc4100827, 0x6118634b, 0x021fba6f, 0x5ea57670, 0x3da2af54, + 0x98aac438, 0xfbad1d1c, 0x09cb14a1, 0x6acccd85, 0xcfc4a6e9, + 0xacc37fcd, 0xa051229c, 0xc356fbb8, 0x665e90d4, 0x055949f0, + 0xf73f404d, 0x94389969, 0x3130f205, 0x52372b21, 0x0e8de73e, + 0x6d8a3e1a, 0xc8825576, 0xab858c52, 0x59e385ef, 0x3ae45ccb, + 0x9fec37a7, 0xfcebee83, 0x2699af99, 0x459e76bd, 0xe0961dd1, + 0x8391c4f5, 0x71f7cd48, 0x12f0146c, 0xb7f87f00, 0xd4ffa624, + 0x88456a3b, 0xeb42b31f, 0x4e4ad873, 0x2d4d0157, 0xdf2b08ea, + 0xbc2cd1ce, 0x1924baa2, 0x7a236386, 0xed627dae, 0x8e65a48a, + 0x2b6dcfe6, 0x486a16c2, 0xba0c1f7f, 0xd90bc65b, 0x7c03ad37, + 0x1f047413, 0x43beb80c, 0x20b96128, 0x85b10a44, 0xe6b6d360, + 0x14d0dadd, 0x77d703f9, 0xd2df6895, 0xb1d8b1b1, 0x6baaf0ab, + 0x08ad298f, 0xada542e3, 0xcea29bc7, 0x3cc4927a, 0x5fc34b5e, + 0xfacb2032, 0x99ccf916, 0xc5763509, 0xa671ec2d, 0x03798741, + 0x607e5e65, 0x921857d8, 0xf11f8efc, 0x5417e590, 0x37103cb4, + 0x3b8261e5, 0x5885b8c1, 0xfd8dd3ad, 0x9e8a0a89, 0x6cec0334, + 0x0febda10, 0xaae3b17c, 0xc9e46858, 0x955ea447, 0xf6597d63, + 0x5351160f, 0x3056cf2b, 0xc230c696, 0xa1371fb2, 0x043f74de, + 0x6738adfa, 0xbd4aece0, 0xde4d35c4, 0x7b455ea8, 0x1842878c, + 0xea248e31, 0x89235715, 0x2c2b3c79, 0x4f2ce55d, 0x13962942, + 0x7091f066, 0xd5999b0a, 0xb69e422e, 0x44f84b93, 0x27ff92b7, + 0x82f7f9db, 0xe1f020ff, 0x9bd34379, 0xf8d49a5d, 0x5ddcf131, + 0x3edb2815, 0xccbd21a8, 0xafbaf88c, 0x0ab293e0, 0x69b54ac4, + 0x350f86db, 0x56085fff, 0xf3003493, 0x9007edb7, 0x6261e40a, + 0x01663d2e, 0xa46e5642, 0xc7698f66, 0x1d1bce7c, 0x7e1c1758, + 0xdb147c34, 0xb813a510, 0x4a75acad, 0x29727589, 0x8c7a1ee5, + 0xef7dc7c1, 0xb3c70bde, 0xd0c0d2fa, 0x75c8b996, 0x16cf60b2, + 0xe4a9690f, 0x87aeb02b, 0x22a6db47, 0x41a10263, 0x4d335f32, + 0x2e348616, 0x8b3ced7a, 0xe83b345e, 0x1a5d3de3, 0x795ae4c7, + 0xdc528fab, 0xbf55568f, 0xe3ef9a90, 0x80e843b4, 0x25e028d8, + 0x46e7f1fc, 0xb481f841, 0xd7862165, 0x728e4a09, 0x1189932d, + 0xcbfbd237, 0xa8fc0b13, 0x0df4607f, 0x6ef3b95b, 0x9c95b0e6, + 0xff9269c2, 0x5a9a02ae, 0x399ddb8a, 0x65271795, 0x0620ceb1, + 0xa328a5dd, 0xc02f7cf9, 0x32497544, 0x514eac60, 0xf446c70c, + 0x97411e28}, + {0x00000000, 0x01b5fd1d, 0x036bfa3a, 0x02de0727, 0x06d7f474, + 0x07620969, 0x05bc0e4e, 0x0409f353, 0x0dafe8e8, 0x0c1a15f5, + 0x0ec412d2, 0x0f71efcf, 0x0b781c9c, 0x0acde181, 0x0813e6a6, + 0x09a61bbb, 0x1b5fd1d0, 0x1aea2ccd, 0x18342bea, 0x1981d6f7, + 0x1d8825a4, 0x1c3dd8b9, 0x1ee3df9e, 0x1f562283, 0x16f03938, + 0x1745c425, 0x159bc302, 0x142e3e1f, 0x1027cd4c, 0x11923051, + 0x134c3776, 0x12f9ca6b, 0x36bfa3a0, 0x370a5ebd, 0x35d4599a, + 0x3461a487, 0x306857d4, 0x31ddaac9, 0x3303adee, 0x32b650f3, + 0x3b104b48, 0x3aa5b655, 0x387bb172, 0x39ce4c6f, 0x3dc7bf3c, + 0x3c724221, 0x3eac4506, 0x3f19b81b, 0x2de07270, 0x2c558f6d, + 0x2e8b884a, 0x2f3e7557, 0x2b378604, 0x2a827b19, 0x285c7c3e, + 0x29e98123, 0x204f9a98, 0x21fa6785, 0x232460a2, 0x22919dbf, + 0x26986eec, 0x272d93f1, 0x25f394d6, 0x244669cb, 0x6d7f4740, + 0x6ccaba5d, 0x6e14bd7a, 0x6fa14067, 0x6ba8b334, 0x6a1d4e29, + 0x68c3490e, 0x6976b413, 0x60d0afa8, 0x616552b5, 0x63bb5592, + 0x620ea88f, 0x66075bdc, 0x67b2a6c1, 0x656ca1e6, 0x64d95cfb, + 0x76209690, 0x77956b8d, 0x754b6caa, 0x74fe91b7, 0x70f762e4, + 0x71429ff9, 0x739c98de, 0x722965c3, 0x7b8f7e78, 0x7a3a8365, + 0x78e48442, 0x7951795f, 0x7d588a0c, 0x7ced7711, 0x7e337036, + 0x7f868d2b, 0x5bc0e4e0, 0x5a7519fd, 0x58ab1eda, 0x591ee3c7, + 0x5d171094, 0x5ca2ed89, 0x5e7ceaae, 0x5fc917b3, 0x566f0c08, + 0x57daf115, 0x5504f632, 0x54b10b2f, 0x50b8f87c, 0x510d0561, + 0x53d30246, 0x5266ff5b, 0x409f3530, 0x412ac82d, 0x43f4cf0a, + 0x42413217, 0x4648c144, 0x47fd3c59, 0x45233b7e, 0x4496c663, + 0x4d30ddd8, 0x4c8520c5, 0x4e5b27e2, 0x4feedaff, 0x4be729ac, + 0x4a52d4b1, 0x488cd396, 0x49392e8b, 0xdafe8e80, 0xdb4b739d, + 0xd99574ba, 0xd82089a7, 0xdc297af4, 0xdd9c87e9, 0xdf4280ce, + 0xdef77dd3, 0xd7516668, 0xd6e49b75, 0xd43a9c52, 0xd58f614f, + 0xd186921c, 0xd0336f01, 0xd2ed6826, 0xd358953b, 0xc1a15f50, + 0xc014a24d, 0xc2caa56a, 0xc37f5877, 0xc776ab24, 0xc6c35639, + 0xc41d511e, 0xc5a8ac03, 0xcc0eb7b8, 0xcdbb4aa5, 0xcf654d82, + 0xced0b09f, 0xcad943cc, 0xcb6cbed1, 0xc9b2b9f6, 0xc80744eb, + 0xec412d20, 0xedf4d03d, 0xef2ad71a, 0xee9f2a07, 0xea96d954, + 0xeb232449, 0xe9fd236e, 0xe848de73, 0xe1eec5c8, 0xe05b38d5, + 0xe2853ff2, 0xe330c2ef, 0xe73931bc, 0xe68ccca1, 0xe452cb86, + 0xe5e7369b, 0xf71efcf0, 0xf6ab01ed, 0xf47506ca, 0xf5c0fbd7, + 0xf1c90884, 0xf07cf599, 0xf2a2f2be, 0xf3170fa3, 0xfab11418, + 0xfb04e905, 0xf9daee22, 0xf86f133f, 0xfc66e06c, 0xfdd31d71, + 0xff0d1a56, 0xfeb8e74b, 0xb781c9c0, 0xb63434dd, 0xb4ea33fa, + 0xb55fcee7, 0xb1563db4, 0xb0e3c0a9, 0xb23dc78e, 0xb3883a93, + 0xba2e2128, 0xbb9bdc35, 0xb945db12, 0xb8f0260f, 0xbcf9d55c, + 0xbd4c2841, 0xbf922f66, 0xbe27d27b, 0xacde1810, 0xad6be50d, + 0xafb5e22a, 0xae001f37, 0xaa09ec64, 0xabbc1179, 0xa962165e, + 0xa8d7eb43, 0xa171f0f8, 0xa0c40de5, 0xa21a0ac2, 0xa3aff7df, + 0xa7a6048c, 0xa613f991, 0xa4cdfeb6, 0xa57803ab, 0x813e6a60, + 0x808b977d, 0x8255905a, 0x83e06d47, 0x87e99e14, 0x865c6309, + 0x8482642e, 0x85379933, 0x8c918288, 0x8d247f95, 0x8ffa78b2, + 0x8e4f85af, 0x8a4676fc, 0x8bf38be1, 0x892d8cc6, 0x889871db, + 0x9a61bbb0, 0x9bd446ad, 0x990a418a, 0x98bfbc97, 0x9cb64fc4, + 0x9d03b2d9, 0x9fddb5fe, 0x9e6848e3, 0x97ce5358, 0x967bae45, + 0x94a5a962, 0x9510547f, 0x9119a72c, 0x90ac5a31, 0x92725d16, + 0x93c7a00b}, + {0x00000000, 0x6e8c1b41, 0xdd183682, 0xb3942dc3, 0x61416b45, + 0x0fcd7004, 0xbc595dc7, 0xd2d54686, 0xc282d68a, 0xac0ecdcb, + 0x1f9ae008, 0x7116fb49, 0xa3c3bdcf, 0xcd4fa68e, 0x7edb8b4d, + 0x1057900c, 0x5e74ab55, 0x30f8b014, 0x836c9dd7, 0xede08696, + 0x3f35c010, 0x51b9db51, 0xe22df692, 0x8ca1edd3, 0x9cf67ddf, + 0xf27a669e, 0x41ee4b5d, 0x2f62501c, 0xfdb7169a, 0x933b0ddb, + 0x20af2018, 0x4e233b59, 0xbce956aa, 0xd2654deb, 0x61f16028, + 0x0f7d7b69, 0xdda83def, 0xb32426ae, 0x00b00b6d, 0x6e3c102c, + 0x7e6b8020, 0x10e79b61, 0xa373b6a2, 0xcdffade3, 0x1f2aeb65, + 0x71a6f024, 0xc232dde7, 0xacbec6a6, 0xe29dfdff, 0x8c11e6be, + 0x3f85cb7d, 0x5109d03c, 0x83dc96ba, 0xed508dfb, 0x5ec4a038, + 0x3048bb79, 0x201f2b75, 0x4e933034, 0xfd071df7, 0x938b06b6, + 0x415e4030, 0x2fd25b71, 0x9c4676b2, 0xf2ca6df3, 0xa2a3ab15, + 0xcc2fb054, 0x7fbb9d97, 0x113786d6, 0xc3e2c050, 0xad6edb11, + 0x1efaf6d2, 0x7076ed93, 0x60217d9f, 0x0ead66de, 0xbd394b1d, + 0xd3b5505c, 0x016016da, 0x6fec0d9b, 0xdc782058, 0xb2f43b19, + 0xfcd70040, 0x925b1b01, 0x21cf36c2, 0x4f432d83, 0x9d966b05, + 0xf31a7044, 0x408e5d87, 0x2e0246c6, 0x3e55d6ca, 0x50d9cd8b, + 0xe34de048, 0x8dc1fb09, 0x5f14bd8f, 0x3198a6ce, 0x820c8b0d, + 0xec80904c, 0x1e4afdbf, 0x70c6e6fe, 0xc352cb3d, 0xadded07c, + 0x7f0b96fa, 0x11878dbb, 0xa213a078, 0xcc9fbb39, 0xdcc82b35, + 0xb2443074, 0x01d01db7, 0x6f5c06f6, 0xbd894070, 0xd3055b31, + 0x609176f2, 0x0e1d6db3, 0x403e56ea, 0x2eb24dab, 0x9d266068, + 0xf3aa7b29, 0x217f3daf, 0x4ff326ee, 0xfc670b2d, 0x92eb106c, + 0x82bc8060, 0xec309b21, 0x5fa4b6e2, 0x3128ada3, 0xe3fdeb25, + 0x8d71f064, 0x3ee5dda7, 0x5069c6e6, 0x9e36506b, 0xf0ba4b2a, + 0x432e66e9, 0x2da27da8, 0xff773b2e, 0x91fb206f, 0x226f0dac, + 0x4ce316ed, 0x5cb486e1, 0x32389da0, 0x81acb063, 0xef20ab22, + 0x3df5eda4, 0x5379f6e5, 0xe0eddb26, 0x8e61c067, 0xc042fb3e, + 0xaecee07f, 0x1d5acdbc, 0x73d6d6fd, 0xa103907b, 0xcf8f8b3a, + 0x7c1ba6f9, 0x1297bdb8, 0x02c02db4, 0x6c4c36f5, 0xdfd81b36, + 0xb1540077, 0x638146f1, 0x0d0d5db0, 0xbe997073, 0xd0156b32, + 0x22df06c1, 0x4c531d80, 0xffc73043, 0x914b2b02, 0x439e6d84, + 0x2d1276c5, 0x9e865b06, 0xf00a4047, 0xe05dd04b, 0x8ed1cb0a, + 0x3d45e6c9, 0x53c9fd88, 0x811cbb0e, 0xef90a04f, 0x5c048d8c, + 0x328896cd, 0x7cabad94, 0x1227b6d5, 0xa1b39b16, 0xcf3f8057, + 0x1deac6d1, 0x7366dd90, 0xc0f2f053, 0xae7eeb12, 0xbe297b1e, + 0xd0a5605f, 0x63314d9c, 0x0dbd56dd, 0xdf68105b, 0xb1e40b1a, + 0x027026d9, 0x6cfc3d98, 0x3c95fb7e, 0x5219e03f, 0xe18dcdfc, + 0x8f01d6bd, 0x5dd4903b, 0x33588b7a, 0x80cca6b9, 0xee40bdf8, + 0xfe172df4, 0x909b36b5, 0x230f1b76, 0x4d830037, 0x9f5646b1, + 0xf1da5df0, 0x424e7033, 0x2cc26b72, 0x62e1502b, 0x0c6d4b6a, + 0xbff966a9, 0xd1757de8, 0x03a03b6e, 0x6d2c202f, 0xdeb80dec, + 0xb03416ad, 0xa06386a1, 0xceef9de0, 0x7d7bb023, 0x13f7ab62, + 0xc122ede4, 0xafaef6a5, 0x1c3adb66, 0x72b6c027, 0x807cadd4, + 0xeef0b695, 0x5d649b56, 0x33e88017, 0xe13dc691, 0x8fb1ddd0, + 0x3c25f013, 0x52a9eb52, 0x42fe7b5e, 0x2c72601f, 0x9fe64ddc, + 0xf16a569d, 0x23bf101b, 0x4d330b5a, 0xfea72699, 0x902b3dd8, + 0xde080681, 0xb0841dc0, 0x03103003, 0x6d9c2b42, 0xbf496dc4, + 0xd1c57685, 0x62515b46, 0x0cdd4007, 0x1c8ad00b, 0x7206cb4a, + 0xc192e689, 0xaf1efdc8, 0x7dcbbb4e, 0x1347a00f, 0xa0d38dcc, + 0xce5f968d}, + {0x00000000, 0xe71da697, 0x154a4b6f, 0xf257edf8, 0x2a9496de, + 0xcd893049, 0x3fdeddb1, 0xd8c37b26, 0x55292dbc, 0xb2348b2b, + 0x406366d3, 0xa77ec044, 0x7fbdbb62, 0x98a01df5, 0x6af7f00d, + 0x8dea569a, 0xaa525b78, 0x4d4ffdef, 0xbf181017, 0x5805b680, + 0x80c6cda6, 0x67db6b31, 0x958c86c9, 0x7291205e, 0xff7b76c4, + 0x1866d053, 0xea313dab, 0x0d2c9b3c, 0xd5efe01a, 0x32f2468d, + 0xc0a5ab75, 0x27b80de2, 0x8fd5b0b1, 0x68c81626, 0x9a9ffbde, + 0x7d825d49, 0xa541266f, 0x425c80f8, 0xb00b6d00, 0x5716cb97, + 0xdafc9d0d, 0x3de13b9a, 0xcfb6d662, 0x28ab70f5, 0xf0680bd3, + 0x1775ad44, 0xe52240bc, 0x023fe62b, 0x2587ebc9, 0xc29a4d5e, + 0x30cda0a6, 0xd7d00631, 0x0f137d17, 0xe80edb80, 0x1a593678, + 0xfd4490ef, 0x70aec675, 0x97b360e2, 0x65e48d1a, 0x82f92b8d, + 0x5a3a50ab, 0xbd27f63c, 0x4f701bc4, 0xa86dbd53, 0xc4da6723, + 0x23c7c1b4, 0xd1902c4c, 0x368d8adb, 0xee4ef1fd, 0x0953576a, + 0xfb04ba92, 0x1c191c05, 0x91f34a9f, 0x76eeec08, 0x84b901f0, + 0x63a4a767, 0xbb67dc41, 0x5c7a7ad6, 0xae2d972e, 0x493031b9, + 0x6e883c5b, 0x89959acc, 0x7bc27734, 0x9cdfd1a3, 0x441caa85, + 0xa3010c12, 0x5156e1ea, 0xb64b477d, 0x3ba111e7, 0xdcbcb770, + 0x2eeb5a88, 0xc9f6fc1f, 0x11358739, 0xf62821ae, 0x047fcc56, + 0xe3626ac1, 0x4b0fd792, 0xac127105, 0x5e459cfd, 0xb9583a6a, + 0x619b414c, 0x8686e7db, 0x74d10a23, 0x93ccacb4, 0x1e26fa2e, + 0xf93b5cb9, 0x0b6cb141, 0xec7117d6, 0x34b26cf0, 0xd3afca67, + 0x21f8279f, 0xc6e58108, 0xe15d8cea, 0x06402a7d, 0xf417c785, + 0x130a6112, 0xcbc91a34, 0x2cd4bca3, 0xde83515b, 0x399ef7cc, + 0xb474a156, 0x536907c1, 0xa13eea39, 0x46234cae, 0x9ee03788, + 0x79fd911f, 0x8baa7ce7, 0x6cb7da70, 0x52c5c807, 0xb5d86e90, + 0x478f8368, 0xa09225ff, 0x78515ed9, 0x9f4cf84e, 0x6d1b15b6, + 0x8a06b321, 0x07ece5bb, 0xe0f1432c, 0x12a6aed4, 0xf5bb0843, + 0x2d787365, 0xca65d5f2, 0x3832380a, 0xdf2f9e9d, 0xf897937f, + 0x1f8a35e8, 0xedddd810, 0x0ac07e87, 0xd20305a1, 0x351ea336, + 0xc7494ece, 0x2054e859, 0xadbebec3, 0x4aa31854, 0xb8f4f5ac, + 0x5fe9533b, 0x872a281d, 0x60378e8a, 0x92606372, 0x757dc5e5, + 0xdd1078b6, 0x3a0dde21, 0xc85a33d9, 0x2f47954e, 0xf784ee68, + 0x109948ff, 0xe2cea507, 0x05d30390, 0x8839550a, 0x6f24f39d, + 0x9d731e65, 0x7a6eb8f2, 0xa2adc3d4, 0x45b06543, 0xb7e788bb, + 0x50fa2e2c, 0x774223ce, 0x905f8559, 0x620868a1, 0x8515ce36, + 0x5dd6b510, 0xbacb1387, 0x489cfe7f, 0xaf8158e8, 0x226b0e72, + 0xc576a8e5, 0x3721451d, 0xd03ce38a, 0x08ff98ac, 0xefe23e3b, + 0x1db5d3c3, 0xfaa87554, 0x961faf24, 0x710209b3, 0x8355e44b, + 0x644842dc, 0xbc8b39fa, 0x5b969f6d, 0xa9c17295, 0x4edcd402, + 0xc3368298, 0x242b240f, 0xd67cc9f7, 0x31616f60, 0xe9a21446, + 0x0ebfb2d1, 0xfce85f29, 0x1bf5f9be, 0x3c4df45c, 0xdb5052cb, + 0x2907bf33, 0xce1a19a4, 0x16d96282, 0xf1c4c415, 0x039329ed, + 0xe48e8f7a, 0x6964d9e0, 0x8e797f77, 0x7c2e928f, 0x9b333418, + 0x43f04f3e, 0xa4ede9a9, 0x56ba0451, 0xb1a7a2c6, 0x19ca1f95, + 0xfed7b902, 0x0c8054fa, 0xeb9df26d, 0x335e894b, 0xd4432fdc, + 0x2614c224, 0xc10964b3, 0x4ce33229, 0xabfe94be, 0x59a97946, + 0xbeb4dfd1, 0x6677a4f7, 0x816a0260, 0x733def98, 0x9420490f, + 0xb39844ed, 0x5485e27a, 0xa6d20f82, 0x41cfa915, 0x990cd233, + 0x7e1174a4, 0x8c46995c, 0x6b5b3fcb, 0xe6b16951, 0x01accfc6, + 0xf3fb223e, 0x14e684a9, 0xcc25ff8f, 0x2b385918, 0xd96fb4e0, + 0x3e721277}, + {0x00000000, 0xa58b900e, 0x9066265d, 0x35edb653, 0xfbbd4afb, + 0x5e36daf5, 0x6bdb6ca6, 0xce50fca8, 0x2c0b93b7, 0x898003b9, + 0xbc6db5ea, 0x19e625e4, 0xd7b6d94c, 0x723d4942, 0x47d0ff11, + 0xe25b6f1f, 0x5817276e, 0xfd9cb760, 0xc8710133, 0x6dfa913d, + 0xa3aa6d95, 0x0621fd9b, 0x33cc4bc8, 0x9647dbc6, 0x741cb4d9, + 0xd19724d7, 0xe47a9284, 0x41f1028a, 0x8fa1fe22, 0x2a2a6e2c, + 0x1fc7d87f, 0xba4c4871, 0xb02e4edc, 0x15a5ded2, 0x20486881, + 0x85c3f88f, 0x4b930427, 0xee189429, 0xdbf5227a, 0x7e7eb274, + 0x9c25dd6b, 0x39ae4d65, 0x0c43fb36, 0xa9c86b38, 0x67989790, + 0xc213079e, 0xf7feb1cd, 0x527521c3, 0xe83969b2, 0x4db2f9bc, + 0x785f4fef, 0xddd4dfe1, 0x13842349, 0xb60fb347, 0x83e20514, + 0x2669951a, 0xc432fa05, 0x61b96a0b, 0x5454dc58, 0xf1df4c56, + 0x3f8fb0fe, 0x9a0420f0, 0xafe996a3, 0x0a6206ad, 0xbb2d9bf9, + 0x1ea60bf7, 0x2b4bbda4, 0x8ec02daa, 0x4090d102, 0xe51b410c, + 0xd0f6f75f, 0x757d6751, 0x9726084e, 0x32ad9840, 0x07402e13, + 0xa2cbbe1d, 0x6c9b42b5, 0xc910d2bb, 0xfcfd64e8, 0x5976f4e6, + 0xe33abc97, 0x46b12c99, 0x735c9aca, 0xd6d70ac4, 0x1887f66c, + 0xbd0c6662, 0x88e1d031, 0x2d6a403f, 0xcf312f20, 0x6ababf2e, + 0x5f57097d, 0xfadc9973, 0x348c65db, 0x9107f5d5, 0xa4ea4386, + 0x0161d388, 0x0b03d525, 0xae88452b, 0x9b65f378, 0x3eee6376, + 0xf0be9fde, 0x55350fd0, 0x60d8b983, 0xc553298d, 0x27084692, + 0x8283d69c, 0xb76e60cf, 0x12e5f0c1, 0xdcb50c69, 0x793e9c67, + 0x4cd32a34, 0xe958ba3a, 0x5314f24b, 0xf69f6245, 0xc372d416, + 0x66f94418, 0xa8a9b8b0, 0x0d2228be, 0x38cf9eed, 0x9d440ee3, + 0x7f1f61fc, 0xda94f1f2, 0xef7947a1, 0x4af2d7af, 0x84a22b07, + 0x2129bb09, 0x14c40d5a, 0xb14f9d54, 0xad2a31b3, 0x08a1a1bd, + 0x3d4c17ee, 0x98c787e0, 0x56977b48, 0xf31ceb46, 0xc6f15d15, + 0x637acd1b, 0x8121a204, 0x24aa320a, 0x11478459, 0xb4cc1457, + 0x7a9ce8ff, 0xdf1778f1, 0xeafacea2, 0x4f715eac, 0xf53d16dd, + 0x50b686d3, 0x655b3080, 0xc0d0a08e, 0x0e805c26, 0xab0bcc28, + 0x9ee67a7b, 0x3b6dea75, 0xd936856a, 0x7cbd1564, 0x4950a337, + 0xecdb3339, 0x228bcf91, 0x87005f9f, 0xb2ede9cc, 0x176679c2, + 0x1d047f6f, 0xb88fef61, 0x8d625932, 0x28e9c93c, 0xe6b93594, + 0x4332a59a, 0x76df13c9, 0xd35483c7, 0x310fecd8, 0x94847cd6, + 0xa169ca85, 0x04e25a8b, 0xcab2a623, 0x6f39362d, 0x5ad4807e, + 0xff5f1070, 0x45135801, 0xe098c80f, 0xd5757e5c, 0x70feee52, + 0xbeae12fa, 0x1b2582f4, 0x2ec834a7, 0x8b43a4a9, 0x6918cbb6, + 0xcc935bb8, 0xf97eedeb, 0x5cf57de5, 0x92a5814d, 0x372e1143, + 0x02c3a710, 0xa748371e, 0x1607aa4a, 0xb38c3a44, 0x86618c17, + 0x23ea1c19, 0xedbae0b1, 0x483170bf, 0x7ddcc6ec, 0xd85756e2, + 0x3a0c39fd, 0x9f87a9f3, 0xaa6a1fa0, 0x0fe18fae, 0xc1b17306, + 0x643ae308, 0x51d7555b, 0xf45cc555, 0x4e108d24, 0xeb9b1d2a, + 0xde76ab79, 0x7bfd3b77, 0xb5adc7df, 0x102657d1, 0x25cbe182, + 0x8040718c, 0x621b1e93, 0xc7908e9d, 0xf27d38ce, 0x57f6a8c0, + 0x99a65468, 0x3c2dc466, 0x09c07235, 0xac4be23b, 0xa629e496, + 0x03a27498, 0x364fc2cb, 0x93c452c5, 0x5d94ae6d, 0xf81f3e63, + 0xcdf28830, 0x6879183e, 0x8a227721, 0x2fa9e72f, 0x1a44517c, + 0xbfcfc172, 0x719f3dda, 0xd414add4, 0xe1f91b87, 0x44728b89, + 0xfe3ec3f8, 0x5bb553f6, 0x6e58e5a5, 0xcbd375ab, 0x05838903, + 0xa008190d, 0x95e5af5e, 0x306e3f50, 0xd235504f, 0x77bec041, + 0x42537612, 0xe7d8e61c, 0x29881ab4, 0x8c038aba, 0xb9ee3ce9, + 0x1c65ace7}}; + +local const z_word_t FAR crc_braid_big_table[][256] = { + {0x0000000000000000, 0x0e908ba500000000, 0x5d26669000000000, + 0x53b6ed3500000000, 0xfb4abdfb00000000, 0xf5da365e00000000, + 0xa66cdb6b00000000, 0xa8fc50ce00000000, 0xb7930b2c00000000, + 0xb903808900000000, 0xeab56dbc00000000, 0xe425e61900000000, + 0x4cd9b6d700000000, 0x42493d7200000000, 0x11ffd04700000000, + 0x1f6f5be200000000, 0x6e27175800000000, 0x60b79cfd00000000, + 0x330171c800000000, 0x3d91fa6d00000000, 0x956daaa300000000, + 0x9bfd210600000000, 0xc84bcc3300000000, 0xc6db479600000000, + 0xd9b41c7400000000, 0xd72497d100000000, 0x84927ae400000000, + 0x8a02f14100000000, 0x22fea18f00000000, 0x2c6e2a2a00000000, + 0x7fd8c71f00000000, 0x71484cba00000000, 0xdc4e2eb000000000, + 0xd2dea51500000000, 0x8168482000000000, 0x8ff8c38500000000, + 0x2704934b00000000, 0x299418ee00000000, 0x7a22f5db00000000, + 0x74b27e7e00000000, 0x6bdd259c00000000, 0x654dae3900000000, + 0x36fb430c00000000, 0x386bc8a900000000, 0x9097986700000000, + 0x9e0713c200000000, 0xcdb1fef700000000, 0xc321755200000000, + 0xb26939e800000000, 0xbcf9b24d00000000, 0xef4f5f7800000000, + 0xe1dfd4dd00000000, 0x4923841300000000, 0x47b30fb600000000, + 0x1405e28300000000, 0x1a95692600000000, 0x05fa32c400000000, + 0x0b6ab96100000000, 0x58dc545400000000, 0x564cdff100000000, + 0xfeb08f3f00000000, 0xf020049a00000000, 0xa396e9af00000000, + 0xad06620a00000000, 0xf99b2dbb00000000, 0xf70ba61e00000000, + 0xa4bd4b2b00000000, 0xaa2dc08e00000000, 0x02d1904000000000, + 0x0c411be500000000, 0x5ff7f6d000000000, 0x51677d7500000000, + 0x4e08269700000000, 0x4098ad3200000000, 0x132e400700000000, + 0x1dbecba200000000, 0xb5429b6c00000000, 0xbbd210c900000000, + 0xe864fdfc00000000, 0xe6f4765900000000, 0x97bc3ae300000000, + 0x992cb14600000000, 0xca9a5c7300000000, 0xc40ad7d600000000, + 0x6cf6871800000000, 0x62660cbd00000000, 0x31d0e18800000000, + 0x3f406a2d00000000, 0x202f31cf00000000, 0x2ebfba6a00000000, + 0x7d09575f00000000, 0x7399dcfa00000000, 0xdb658c3400000000, + 0xd5f5079100000000, 0x8643eaa400000000, 0x88d3610100000000, + 0x25d5030b00000000, 0x2b4588ae00000000, 0x78f3659b00000000, + 0x7663ee3e00000000, 0xde9fbef000000000, 0xd00f355500000000, + 0x83b9d86000000000, 0x8d2953c500000000, 0x9246082700000000, + 0x9cd6838200000000, 0xcf606eb700000000, 0xc1f0e51200000000, + 0x690cb5dc00000000, 0x679c3e7900000000, 0x342ad34c00000000, + 0x3aba58e900000000, 0x4bf2145300000000, 0x45629ff600000000, + 0x16d472c300000000, 0x1844f96600000000, 0xb0b8a9a800000000, + 0xbe28220d00000000, 0xed9ecf3800000000, 0xe30e449d00000000, + 0xfc611f7f00000000, 0xf2f194da00000000, 0xa14779ef00000000, + 0xafd7f24a00000000, 0x072ba28400000000, 0x09bb292100000000, + 0x5a0dc41400000000, 0x549d4fb100000000, 0xb3312aad00000000, + 0xbda1a10800000000, 0xee174c3d00000000, 0xe087c79800000000, + 0x487b975600000000, 0x46eb1cf300000000, 0x155df1c600000000, + 0x1bcd7a6300000000, 0x04a2218100000000, 0x0a32aa2400000000, + 0x5984471100000000, 0x5714ccb400000000, 0xffe89c7a00000000, + 0xf17817df00000000, 0xa2cefaea00000000, 0xac5e714f00000000, + 0xdd163df500000000, 0xd386b65000000000, 0x80305b6500000000, + 0x8ea0d0c000000000, 0x265c800e00000000, 0x28cc0bab00000000, + 0x7b7ae69e00000000, 0x75ea6d3b00000000, 0x6a8536d900000000, + 0x6415bd7c00000000, 0x37a3504900000000, 0x3933dbec00000000, + 0x91cf8b2200000000, 0x9f5f008700000000, 0xcce9edb200000000, + 0xc279661700000000, 0x6f7f041d00000000, 0x61ef8fb800000000, + 0x3259628d00000000, 0x3cc9e92800000000, 0x9435b9e600000000, + 0x9aa5324300000000, 0xc913df7600000000, 0xc78354d300000000, + 0xd8ec0f3100000000, 0xd67c849400000000, 0x85ca69a100000000, + 0x8b5ae20400000000, 0x23a6b2ca00000000, 0x2d36396f00000000, + 0x7e80d45a00000000, 0x70105fff00000000, 0x0158134500000000, + 0x0fc898e000000000, 0x5c7e75d500000000, 0x52eefe7000000000, + 0xfa12aebe00000000, 0xf482251b00000000, 0xa734c82e00000000, + 0xa9a4438b00000000, 0xb6cb186900000000, 0xb85b93cc00000000, + 0xebed7ef900000000, 0xe57df55c00000000, 0x4d81a59200000000, + 0x43112e3700000000, 0x10a7c30200000000, 0x1e3748a700000000, + 0x4aaa071600000000, 0x443a8cb300000000, 0x178c618600000000, + 0x191cea2300000000, 0xb1e0baed00000000, 0xbf70314800000000, + 0xecc6dc7d00000000, 0xe25657d800000000, 0xfd390c3a00000000, + 0xf3a9879f00000000, 0xa01f6aaa00000000, 0xae8fe10f00000000, + 0x0673b1c100000000, 0x08e33a6400000000, 0x5b55d75100000000, + 0x55c55cf400000000, 0x248d104e00000000, 0x2a1d9beb00000000, + 0x79ab76de00000000, 0x773bfd7b00000000, 0xdfc7adb500000000, + 0xd157261000000000, 0x82e1cb2500000000, 0x8c71408000000000, + 0x931e1b6200000000, 0x9d8e90c700000000, 0xce387df200000000, + 0xc0a8f65700000000, 0x6854a69900000000, 0x66c42d3c00000000, + 0x3572c00900000000, 0x3be24bac00000000, 0x96e429a600000000, + 0x9874a20300000000, 0xcbc24f3600000000, 0xc552c49300000000, + 0x6dae945d00000000, 0x633e1ff800000000, 0x3088f2cd00000000, + 0x3e18796800000000, 0x2177228a00000000, 0x2fe7a92f00000000, + 0x7c51441a00000000, 0x72c1cfbf00000000, 0xda3d9f7100000000, + 0xd4ad14d400000000, 0x871bf9e100000000, 0x898b724400000000, + 0xf8c33efe00000000, 0xf653b55b00000000, 0xa5e5586e00000000, + 0xab75d3cb00000000, 0x0389830500000000, 0x0d1908a000000000, + 0x5eafe59500000000, 0x503f6e3000000000, 0x4f5035d200000000, + 0x41c0be7700000000, 0x1276534200000000, 0x1ce6d8e700000000, + 0xb41a882900000000, 0xba8a038c00000000, 0xe93ceeb900000000, + 0xe7ac651c00000000}, + {0x0000000000000000, 0x97a61de700000000, 0x6f4b4a1500000000, + 0xf8ed57f200000000, 0xde96942a00000000, 0x493089cd00000000, + 0xb1ddde3f00000000, 0x267bc3d800000000, 0xbc2d295500000000, + 0x2b8b34b200000000, 0xd366634000000000, 0x44c07ea700000000, + 0x62bbbd7f00000000, 0xf51da09800000000, 0x0df0f76a00000000, + 0x9a56ea8d00000000, 0x785b52aa00000000, 0xeffd4f4d00000000, + 0x171018bf00000000, 0x80b6055800000000, 0xa6cdc68000000000, + 0x316bdb6700000000, 0xc9868c9500000000, 0x5e20917200000000, + 0xc4767bff00000000, 0x53d0661800000000, 0xab3d31ea00000000, + 0x3c9b2c0d00000000, 0x1ae0efd500000000, 0x8d46f23200000000, + 0x75aba5c000000000, 0xe20db82700000000, 0xb1b0d58f00000000, + 0x2616c86800000000, 0xdefb9f9a00000000, 0x495d827d00000000, + 0x6f2641a500000000, 0xf8805c4200000000, 0x006d0bb000000000, + 0x97cb165700000000, 0x0d9dfcda00000000, 0x9a3be13d00000000, + 0x62d6b6cf00000000, 0xf570ab2800000000, 0xd30b68f000000000, + 0x44ad751700000000, 0xbc4022e500000000, 0x2be63f0200000000, + 0xc9eb872500000000, 0x5e4d9ac200000000, 0xa6a0cd3000000000, + 0x3106d0d700000000, 0x177d130f00000000, 0x80db0ee800000000, + 0x7836591a00000000, 0xef9044fd00000000, 0x75c6ae7000000000, + 0xe260b39700000000, 0x1a8de46500000000, 0x8d2bf98200000000, + 0xab503a5a00000000, 0x3cf627bd00000000, 0xc41b704f00000000, + 0x53bd6da800000000, 0x2367dac400000000, 0xb4c1c72300000000, + 0x4c2c90d100000000, 0xdb8a8d3600000000, 0xfdf14eee00000000, + 0x6a57530900000000, 0x92ba04fb00000000, 0x051c191c00000000, + 0x9f4af39100000000, 0x08ecee7600000000, 0xf001b98400000000, + 0x67a7a46300000000, 0x41dc67bb00000000, 0xd67a7a5c00000000, + 0x2e972dae00000000, 0xb931304900000000, 0x5b3c886e00000000, + 0xcc9a958900000000, 0x3477c27b00000000, 0xa3d1df9c00000000, + 0x85aa1c4400000000, 0x120c01a300000000, 0xeae1565100000000, + 0x7d474bb600000000, 0xe711a13b00000000, 0x70b7bcdc00000000, + 0x885aeb2e00000000, 0x1ffcf6c900000000, 0x3987351100000000, + 0xae2128f600000000, 0x56cc7f0400000000, 0xc16a62e300000000, + 0x92d70f4b00000000, 0x057112ac00000000, 0xfd9c455e00000000, + 0x6a3a58b900000000, 0x4c419b6100000000, 0xdbe7868600000000, + 0x230ad17400000000, 0xb4accc9300000000, 0x2efa261e00000000, + 0xb95c3bf900000000, 0x41b16c0b00000000, 0xd61771ec00000000, + 0xf06cb23400000000, 0x67caafd300000000, 0x9f27f82100000000, + 0x0881e5c600000000, 0xea8c5de100000000, 0x7d2a400600000000, + 0x85c717f400000000, 0x12610a1300000000, 0x341ac9cb00000000, + 0xa3bcd42c00000000, 0x5b5183de00000000, 0xccf79e3900000000, + 0x56a174b400000000, 0xc107695300000000, 0x39ea3ea100000000, + 0xae4c234600000000, 0x8837e09e00000000, 0x1f91fd7900000000, + 0xe77caa8b00000000, 0x70dab76c00000000, 0x07c8c55200000000, + 0x906ed8b500000000, 0x68838f4700000000, 0xff2592a000000000, + 0xd95e517800000000, 0x4ef84c9f00000000, 0xb6151b6d00000000, + 0x21b3068a00000000, 0xbbe5ec0700000000, 0x2c43f1e000000000, + 0xd4aea61200000000, 0x4308bbf500000000, 0x6573782d00000000, + 0xf2d565ca00000000, 0x0a38323800000000, 0x9d9e2fdf00000000, + 0x7f9397f800000000, 0xe8358a1f00000000, 0x10d8dded00000000, + 0x877ec00a00000000, 0xa10503d200000000, 0x36a31e3500000000, + 0xce4e49c700000000, 0x59e8542000000000, 0xc3bebead00000000, + 0x5418a34a00000000, 0xacf5f4b800000000, 0x3b53e95f00000000, + 0x1d282a8700000000, 0x8a8e376000000000, 0x7263609200000000, + 0xe5c57d7500000000, 0xb67810dd00000000, 0x21de0d3a00000000, + 0xd9335ac800000000, 0x4e95472f00000000, 0x68ee84f700000000, + 0xff48991000000000, 0x07a5cee200000000, 0x9003d30500000000, + 0x0a55398800000000, 0x9df3246f00000000, 0x651e739d00000000, + 0xf2b86e7a00000000, 0xd4c3ada200000000, 0x4365b04500000000, + 0xbb88e7b700000000, 0x2c2efa5000000000, 0xce23427700000000, + 0x59855f9000000000, 0xa168086200000000, 0x36ce158500000000, + 0x10b5d65d00000000, 0x8713cbba00000000, 0x7ffe9c4800000000, + 0xe85881af00000000, 0x720e6b2200000000, 0xe5a876c500000000, + 0x1d45213700000000, 0x8ae33cd000000000, 0xac98ff0800000000, + 0x3b3ee2ef00000000, 0xc3d3b51d00000000, 0x5475a8fa00000000, + 0x24af1f9600000000, 0xb309027100000000, 0x4be4558300000000, + 0xdc42486400000000, 0xfa398bbc00000000, 0x6d9f965b00000000, + 0x9572c1a900000000, 0x02d4dc4e00000000, 0x988236c300000000, + 0x0f242b2400000000, 0xf7c97cd600000000, 0x606f613100000000, + 0x4614a2e900000000, 0xd1b2bf0e00000000, 0x295fe8fc00000000, + 0xbef9f51b00000000, 0x5cf44d3c00000000, 0xcb5250db00000000, + 0x33bf072900000000, 0xa4191ace00000000, 0x8262d91600000000, + 0x15c4c4f100000000, 0xed29930300000000, 0x7a8f8ee400000000, + 0xe0d9646900000000, 0x777f798e00000000, 0x8f922e7c00000000, + 0x1834339b00000000, 0x3e4ff04300000000, 0xa9e9eda400000000, + 0x5104ba5600000000, 0xc6a2a7b100000000, 0x951fca1900000000, + 0x02b9d7fe00000000, 0xfa54800c00000000, 0x6df29deb00000000, + 0x4b895e3300000000, 0xdc2f43d400000000, 0x24c2142600000000, + 0xb36409c100000000, 0x2932e34c00000000, 0xbe94feab00000000, + 0x4679a95900000000, 0xd1dfb4be00000000, 0xf7a4776600000000, + 0x60026a8100000000, 0x98ef3d7300000000, 0x0f49209400000000, + 0xed4498b300000000, 0x7ae2855400000000, 0x820fd2a600000000, + 0x15a9cf4100000000, 0x33d20c9900000000, 0xa474117e00000000, + 0x5c99468c00000000, 0xcb3f5b6b00000000, 0x5169b1e600000000, + 0xc6cfac0100000000, 0x3e22fbf300000000, 0xa984e61400000000, + 0x8fff25cc00000000, 0x1859382b00000000, 0xe0b46fd900000000, + 0x7712723e00000000}, + {0x0000000000000000, 0x411b8c6e00000000, 0x823618dd00000000, + 0xc32d94b300000000, 0x456b416100000000, 0x0470cd0f00000000, + 0xc75d59bc00000000, 0x8646d5d200000000, 0x8ad682c200000000, + 0xcbcd0eac00000000, 0x08e09a1f00000000, 0x49fb167100000000, + 0xcfbdc3a300000000, 0x8ea64fcd00000000, 0x4d8bdb7e00000000, + 0x0c90571000000000, 0x55ab745e00000000, 0x14b0f83000000000, + 0xd79d6c8300000000, 0x9686e0ed00000000, 0x10c0353f00000000, + 0x51dbb95100000000, 0x92f62de200000000, 0xd3eda18c00000000, + 0xdf7df69c00000000, 0x9e667af200000000, 0x5d4bee4100000000, + 0x1c50622f00000000, 0x9a16b7fd00000000, 0xdb0d3b9300000000, + 0x1820af2000000000, 0x593b234e00000000, 0xaa56e9bc00000000, + 0xeb4d65d200000000, 0x2860f16100000000, 0x697b7d0f00000000, + 0xef3da8dd00000000, 0xae2624b300000000, 0x6d0bb00000000000, + 0x2c103c6e00000000, 0x20806b7e00000000, 0x619be71000000000, + 0xa2b673a300000000, 0xe3adffcd00000000, 0x65eb2a1f00000000, + 0x24f0a67100000000, 0xe7dd32c200000000, 0xa6c6beac00000000, + 0xfffd9de200000000, 0xbee6118c00000000, 0x7dcb853f00000000, + 0x3cd0095100000000, 0xba96dc8300000000, 0xfb8d50ed00000000, + 0x38a0c45e00000000, 0x79bb483000000000, 0x752b1f2000000000, + 0x3430934e00000000, 0xf71d07fd00000000, 0xb6068b9300000000, + 0x30405e4100000000, 0x715bd22f00000000, 0xb276469c00000000, + 0xf36dcaf200000000, 0x15aba3a200000000, 0x54b02fcc00000000, + 0x979dbb7f00000000, 0xd686371100000000, 0x50c0e2c300000000, + 0x11db6ead00000000, 0xd2f6fa1e00000000, 0x93ed767000000000, + 0x9f7d216000000000, 0xde66ad0e00000000, 0x1d4b39bd00000000, + 0x5c50b5d300000000, 0xda16600100000000, 0x9b0dec6f00000000, + 0x582078dc00000000, 0x193bf4b200000000, 0x4000d7fc00000000, + 0x011b5b9200000000, 0xc236cf2100000000, 0x832d434f00000000, + 0x056b969d00000000, 0x44701af300000000, 0x875d8e4000000000, + 0xc646022e00000000, 0xcad6553e00000000, 0x8bcdd95000000000, + 0x48e04de300000000, 0x09fbc18d00000000, 0x8fbd145f00000000, + 0xcea6983100000000, 0x0d8b0c8200000000, 0x4c9080ec00000000, + 0xbffd4a1e00000000, 0xfee6c67000000000, 0x3dcb52c300000000, + 0x7cd0dead00000000, 0xfa960b7f00000000, 0xbb8d871100000000, + 0x78a013a200000000, 0x39bb9fcc00000000, 0x352bc8dc00000000, + 0x743044b200000000, 0xb71dd00100000000, 0xf6065c6f00000000, + 0x704089bd00000000, 0x315b05d300000000, 0xf276916000000000, + 0xb36d1d0e00000000, 0xea563e4000000000, 0xab4db22e00000000, + 0x6860269d00000000, 0x297baaf300000000, 0xaf3d7f2100000000, + 0xee26f34f00000000, 0x2d0b67fc00000000, 0x6c10eb9200000000, + 0x6080bc8200000000, 0x219b30ec00000000, 0xe2b6a45f00000000, + 0xa3ad283100000000, 0x25ebfde300000000, 0x64f0718d00000000, + 0xa7dde53e00000000, 0xe6c6695000000000, 0x6b50369e00000000, + 0x2a4bbaf000000000, 0xe9662e4300000000, 0xa87da22d00000000, + 0x2e3b77ff00000000, 0x6f20fb9100000000, 0xac0d6f2200000000, + 0xed16e34c00000000, 0xe186b45c00000000, 0xa09d383200000000, + 0x63b0ac8100000000, 0x22ab20ef00000000, 0xa4edf53d00000000, + 0xe5f6795300000000, 0x26dbede000000000, 0x67c0618e00000000, + 0x3efb42c000000000, 0x7fe0ceae00000000, 0xbccd5a1d00000000, + 0xfdd6d67300000000, 0x7b9003a100000000, 0x3a8b8fcf00000000, + 0xf9a61b7c00000000, 0xb8bd971200000000, 0xb42dc00200000000, + 0xf5364c6c00000000, 0x361bd8df00000000, 0x770054b100000000, + 0xf146816300000000, 0xb05d0d0d00000000, 0x737099be00000000, + 0x326b15d000000000, 0xc106df2200000000, 0x801d534c00000000, + 0x4330c7ff00000000, 0x022b4b9100000000, 0x846d9e4300000000, + 0xc576122d00000000, 0x065b869e00000000, 0x47400af000000000, + 0x4bd05de000000000, 0x0acbd18e00000000, 0xc9e6453d00000000, + 0x88fdc95300000000, 0x0ebb1c8100000000, 0x4fa090ef00000000, + 0x8c8d045c00000000, 0xcd96883200000000, 0x94adab7c00000000, + 0xd5b6271200000000, 0x169bb3a100000000, 0x57803fcf00000000, + 0xd1c6ea1d00000000, 0x90dd667300000000, 0x53f0f2c000000000, + 0x12eb7eae00000000, 0x1e7b29be00000000, 0x5f60a5d000000000, + 0x9c4d316300000000, 0xdd56bd0d00000000, 0x5b1068df00000000, + 0x1a0be4b100000000, 0xd926700200000000, 0x983dfc6c00000000, + 0x7efb953c00000000, 0x3fe0195200000000, 0xfccd8de100000000, + 0xbdd6018f00000000, 0x3b90d45d00000000, 0x7a8b583300000000, + 0xb9a6cc8000000000, 0xf8bd40ee00000000, 0xf42d17fe00000000, + 0xb5369b9000000000, 0x761b0f2300000000, 0x3700834d00000000, + 0xb146569f00000000, 0xf05ddaf100000000, 0x33704e4200000000, + 0x726bc22c00000000, 0x2b50e16200000000, 0x6a4b6d0c00000000, + 0xa966f9bf00000000, 0xe87d75d100000000, 0x6e3ba00300000000, + 0x2f202c6d00000000, 0xec0db8de00000000, 0xad1634b000000000, + 0xa18663a000000000, 0xe09defce00000000, 0x23b07b7d00000000, + 0x62abf71300000000, 0xe4ed22c100000000, 0xa5f6aeaf00000000, + 0x66db3a1c00000000, 0x27c0b67200000000, 0xd4ad7c8000000000, + 0x95b6f0ee00000000, 0x569b645d00000000, 0x1780e83300000000, + 0x91c63de100000000, 0xd0ddb18f00000000, 0x13f0253c00000000, + 0x52eba95200000000, 0x5e7bfe4200000000, 0x1f60722c00000000, + 0xdc4de69f00000000, 0x9d566af100000000, 0x1b10bf2300000000, + 0x5a0b334d00000000, 0x9926a7fe00000000, 0xd83d2b9000000000, + 0x810608de00000000, 0xc01d84b000000000, 0x0330100300000000, + 0x422b9c6d00000000, 0xc46d49bf00000000, 0x8576c5d100000000, + 0x465b516200000000, 0x0740dd0c00000000, 0x0bd08a1c00000000, + 0x4acb067200000000, 0x89e692c100000000, 0xc8fd1eaf00000000, + 0x4ebbcb7d00000000, 0x0fa0471300000000, 0xcc8dd3a000000000, + 0x8d965fce00000000}, + {0x0000000000000000, 0x1dfdb50100000000, 0x3afa6b0300000000, + 0x2707de0200000000, 0x74f4d70600000000, 0x6909620700000000, + 0x4e0ebc0500000000, 0x53f3090400000000, 0xe8e8af0d00000000, + 0xf5151a0c00000000, 0xd212c40e00000000, 0xcfef710f00000000, + 0x9c1c780b00000000, 0x81e1cd0a00000000, 0xa6e6130800000000, + 0xbb1ba60900000000, 0xd0d15f1b00000000, 0xcd2cea1a00000000, + 0xea2b341800000000, 0xf7d6811900000000, 0xa425881d00000000, + 0xb9d83d1c00000000, 0x9edfe31e00000000, 0x8322561f00000000, + 0x3839f01600000000, 0x25c4451700000000, 0x02c39b1500000000, + 0x1f3e2e1400000000, 0x4ccd271000000000, 0x5130921100000000, + 0x76374c1300000000, 0x6bcaf91200000000, 0xa0a3bf3600000000, + 0xbd5e0a3700000000, 0x9a59d43500000000, 0x87a4613400000000, + 0xd457683000000000, 0xc9aadd3100000000, 0xeead033300000000, + 0xf350b63200000000, 0x484b103b00000000, 0x55b6a53a00000000, + 0x72b17b3800000000, 0x6f4cce3900000000, 0x3cbfc73d00000000, + 0x2142723c00000000, 0x0645ac3e00000000, 0x1bb8193f00000000, + 0x7072e02d00000000, 0x6d8f552c00000000, 0x4a888b2e00000000, + 0x57753e2f00000000, 0x0486372b00000000, 0x197b822a00000000, + 0x3e7c5c2800000000, 0x2381e92900000000, 0x989a4f2000000000, + 0x8567fa2100000000, 0xa260242300000000, 0xbf9d912200000000, + 0xec6e982600000000, 0xf1932d2700000000, 0xd694f32500000000, + 0xcb69462400000000, 0x40477f6d00000000, 0x5dbaca6c00000000, + 0x7abd146e00000000, 0x6740a16f00000000, 0x34b3a86b00000000, + 0x294e1d6a00000000, 0x0e49c36800000000, 0x13b4766900000000, + 0xa8afd06000000000, 0xb552656100000000, 0x9255bb6300000000, + 0x8fa80e6200000000, 0xdc5b076600000000, 0xc1a6b26700000000, + 0xe6a16c6500000000, 0xfb5cd96400000000, 0x9096207600000000, + 0x8d6b957700000000, 0xaa6c4b7500000000, 0xb791fe7400000000, + 0xe462f77000000000, 0xf99f427100000000, 0xde989c7300000000, + 0xc365297200000000, 0x787e8f7b00000000, 0x65833a7a00000000, + 0x4284e47800000000, 0x5f79517900000000, 0x0c8a587d00000000, + 0x1177ed7c00000000, 0x3670337e00000000, 0x2b8d867f00000000, + 0xe0e4c05b00000000, 0xfd19755a00000000, 0xda1eab5800000000, + 0xc7e31e5900000000, 0x9410175d00000000, 0x89eda25c00000000, + 0xaeea7c5e00000000, 0xb317c95f00000000, 0x080c6f5600000000, + 0x15f1da5700000000, 0x32f6045500000000, 0x2f0bb15400000000, + 0x7cf8b85000000000, 0x61050d5100000000, 0x4602d35300000000, + 0x5bff665200000000, 0x30359f4000000000, 0x2dc82a4100000000, + 0x0acff44300000000, 0x1732414200000000, 0x44c1484600000000, + 0x593cfd4700000000, 0x7e3b234500000000, 0x63c6964400000000, + 0xd8dd304d00000000, 0xc520854c00000000, 0xe2275b4e00000000, + 0xffdaee4f00000000, 0xac29e74b00000000, 0xb1d4524a00000000, + 0x96d38c4800000000, 0x8b2e394900000000, 0x808efeda00000000, + 0x9d734bdb00000000, 0xba7495d900000000, 0xa78920d800000000, + 0xf47a29dc00000000, 0xe9879cdd00000000, 0xce8042df00000000, + 0xd37df7de00000000, 0x686651d700000000, 0x759be4d600000000, + 0x529c3ad400000000, 0x4f618fd500000000, 0x1c9286d100000000, + 0x016f33d000000000, 0x2668edd200000000, 0x3b9558d300000000, + 0x505fa1c100000000, 0x4da214c000000000, 0x6aa5cac200000000, + 0x77587fc300000000, 0x24ab76c700000000, 0x3956c3c600000000, + 0x1e511dc400000000, 0x03aca8c500000000, 0xb8b70ecc00000000, + 0xa54abbcd00000000, 0x824d65cf00000000, 0x9fb0d0ce00000000, + 0xcc43d9ca00000000, 0xd1be6ccb00000000, 0xf6b9b2c900000000, + 0xeb4407c800000000, 0x202d41ec00000000, 0x3dd0f4ed00000000, + 0x1ad72aef00000000, 0x072a9fee00000000, 0x54d996ea00000000, + 0x492423eb00000000, 0x6e23fde900000000, 0x73de48e800000000, + 0xc8c5eee100000000, 0xd5385be000000000, 0xf23f85e200000000, + 0xefc230e300000000, 0xbc3139e700000000, 0xa1cc8ce600000000, + 0x86cb52e400000000, 0x9b36e7e500000000, 0xf0fc1ef700000000, + 0xed01abf600000000, 0xca0675f400000000, 0xd7fbc0f500000000, + 0x8408c9f100000000, 0x99f57cf000000000, 0xbef2a2f200000000, + 0xa30f17f300000000, 0x1814b1fa00000000, 0x05e904fb00000000, + 0x22eedaf900000000, 0x3f136ff800000000, 0x6ce066fc00000000, + 0x711dd3fd00000000, 0x561a0dff00000000, 0x4be7b8fe00000000, + 0xc0c981b700000000, 0xdd3434b600000000, 0xfa33eab400000000, + 0xe7ce5fb500000000, 0xb43d56b100000000, 0xa9c0e3b000000000, + 0x8ec73db200000000, 0x933a88b300000000, 0x28212eba00000000, + 0x35dc9bbb00000000, 0x12db45b900000000, 0x0f26f0b800000000, + 0x5cd5f9bc00000000, 0x41284cbd00000000, 0x662f92bf00000000, + 0x7bd227be00000000, 0x1018deac00000000, 0x0de56bad00000000, + 0x2ae2b5af00000000, 0x371f00ae00000000, 0x64ec09aa00000000, + 0x7911bcab00000000, 0x5e1662a900000000, 0x43ebd7a800000000, + 0xf8f071a100000000, 0xe50dc4a000000000, 0xc20a1aa200000000, + 0xdff7afa300000000, 0x8c04a6a700000000, 0x91f913a600000000, + 0xb6fecda400000000, 0xab0378a500000000, 0x606a3e8100000000, + 0x7d978b8000000000, 0x5a90558200000000, 0x476de08300000000, + 0x149ee98700000000, 0x09635c8600000000, 0x2e64828400000000, + 0x3399378500000000, 0x8882918c00000000, 0x957f248d00000000, + 0xb278fa8f00000000, 0xaf854f8e00000000, 0xfc76468a00000000, + 0xe18bf38b00000000, 0xc68c2d8900000000, 0xdb71988800000000, + 0xb0bb619a00000000, 0xad46d49b00000000, 0x8a410a9900000000, + 0x97bcbf9800000000, 0xc44fb69c00000000, 0xd9b2039d00000000, + 0xfeb5dd9f00000000, 0xe348689e00000000, 0x5853ce9700000000, + 0x45ae7b9600000000, 0x62a9a59400000000, 0x7f54109500000000, + 0x2ca7199100000000, 0x315aac9000000000, 0x165d729200000000, + 0x0ba0c79300000000}, + {0x0000000000000000, 0x24d9076300000000, 0x48b20fc600000000, + 0x6c6b08a500000000, 0xd1626e5700000000, 0xf5bb693400000000, + 0x99d0619100000000, 0xbd0966f200000000, 0xa2c5dcae00000000, + 0x861cdbcd00000000, 0xea77d36800000000, 0xceaed40b00000000, + 0x73a7b2f900000000, 0x577eb59a00000000, 0x3b15bd3f00000000, + 0x1fccba5c00000000, 0x058dc88600000000, 0x2154cfe500000000, + 0x4d3fc74000000000, 0x69e6c02300000000, 0xd4efa6d100000000, + 0xf036a1b200000000, 0x9c5da91700000000, 0xb884ae7400000000, + 0xa748142800000000, 0x8391134b00000000, 0xeffa1bee00000000, + 0xcb231c8d00000000, 0x762a7a7f00000000, 0x52f37d1c00000000, + 0x3e9875b900000000, 0x1a4172da00000000, 0x4b1ce0d600000000, + 0x6fc5e7b500000000, 0x03aeef1000000000, 0x2777e87300000000, + 0x9a7e8e8100000000, 0xbea789e200000000, 0xd2cc814700000000, + 0xf615862400000000, 0xe9d93c7800000000, 0xcd003b1b00000000, + 0xa16b33be00000000, 0x85b234dd00000000, 0x38bb522f00000000, + 0x1c62554c00000000, 0x70095de900000000, 0x54d05a8a00000000, + 0x4e91285000000000, 0x6a482f3300000000, 0x0623279600000000, + 0x22fa20f500000000, 0x9ff3460700000000, 0xbb2a416400000000, + 0xd74149c100000000, 0xf3984ea200000000, 0xec54f4fe00000000, + 0xc88df39d00000000, 0xa4e6fb3800000000, 0x803ffc5b00000000, + 0x3d369aa900000000, 0x19ef9dca00000000, 0x7584956f00000000, + 0x515d920c00000000, 0xd73eb17600000000, 0xf3e7b61500000000, + 0x9f8cbeb000000000, 0xbb55b9d300000000, 0x065cdf2100000000, + 0x2285d84200000000, 0x4eeed0e700000000, 0x6a37d78400000000, + 0x75fb6dd800000000, 0x51226abb00000000, 0x3d49621e00000000, + 0x1990657d00000000, 0xa499038f00000000, 0x804004ec00000000, + 0xec2b0c4900000000, 0xc8f20b2a00000000, 0xd2b379f000000000, + 0xf66a7e9300000000, 0x9a01763600000000, 0xbed8715500000000, + 0x03d117a700000000, 0x270810c400000000, 0x4b63186100000000, + 0x6fba1f0200000000, 0x7076a55e00000000, 0x54afa23d00000000, + 0x38c4aa9800000000, 0x1c1dadfb00000000, 0xa114cb0900000000, + 0x85cdcc6a00000000, 0xe9a6c4cf00000000, 0xcd7fc3ac00000000, + 0x9c2251a000000000, 0xb8fb56c300000000, 0xd4905e6600000000, + 0xf049590500000000, 0x4d403ff700000000, 0x6999389400000000, + 0x05f2303100000000, 0x212b375200000000, 0x3ee78d0e00000000, + 0x1a3e8a6d00000000, 0x765582c800000000, 0x528c85ab00000000, + 0xef85e35900000000, 0xcb5ce43a00000000, 0xa737ec9f00000000, + 0x83eeebfc00000000, 0x99af992600000000, 0xbd769e4500000000, + 0xd11d96e000000000, 0xf5c4918300000000, 0x48cdf77100000000, + 0x6c14f01200000000, 0x007ff8b700000000, 0x24a6ffd400000000, + 0x3b6a458800000000, 0x1fb342eb00000000, 0x73d84a4e00000000, + 0x57014d2d00000000, 0xea082bdf00000000, 0xced12cbc00000000, + 0xa2ba241900000000, 0x8663237a00000000, 0xae7d62ed00000000, + 0x8aa4658e00000000, 0xe6cf6d2b00000000, 0xc2166a4800000000, + 0x7f1f0cba00000000, 0x5bc60bd900000000, 0x37ad037c00000000, + 0x1374041f00000000, 0x0cb8be4300000000, 0x2861b92000000000, + 0x440ab18500000000, 0x60d3b6e600000000, 0xdddad01400000000, + 0xf903d77700000000, 0x9568dfd200000000, 0xb1b1d8b100000000, + 0xabf0aa6b00000000, 0x8f29ad0800000000, 0xe342a5ad00000000, + 0xc79ba2ce00000000, 0x7a92c43c00000000, 0x5e4bc35f00000000, + 0x3220cbfa00000000, 0x16f9cc9900000000, 0x093576c500000000, + 0x2dec71a600000000, 0x4187790300000000, 0x655e7e6000000000, + 0xd857189200000000, 0xfc8e1ff100000000, 0x90e5175400000000, + 0xb43c103700000000, 0xe561823b00000000, 0xc1b8855800000000, + 0xadd38dfd00000000, 0x890a8a9e00000000, 0x3403ec6c00000000, + 0x10daeb0f00000000, 0x7cb1e3aa00000000, 0x5868e4c900000000, + 0x47a45e9500000000, 0x637d59f600000000, 0x0f16515300000000, + 0x2bcf563000000000, 0x96c630c200000000, 0xb21f37a100000000, + 0xde743f0400000000, 0xfaad386700000000, 0xe0ec4abd00000000, + 0xc4354dde00000000, 0xa85e457b00000000, 0x8c87421800000000, + 0x318e24ea00000000, 0x1557238900000000, 0x793c2b2c00000000, + 0x5de52c4f00000000, 0x4229961300000000, 0x66f0917000000000, + 0x0a9b99d500000000, 0x2e429eb600000000, 0x934bf84400000000, + 0xb792ff2700000000, 0xdbf9f78200000000, 0xff20f0e100000000, + 0x7943d39b00000000, 0x5d9ad4f800000000, 0x31f1dc5d00000000, + 0x1528db3e00000000, 0xa821bdcc00000000, 0x8cf8baaf00000000, + 0xe093b20a00000000, 0xc44ab56900000000, 0xdb860f3500000000, + 0xff5f085600000000, 0x933400f300000000, 0xb7ed079000000000, + 0x0ae4616200000000, 0x2e3d660100000000, 0x42566ea400000000, + 0x668f69c700000000, 0x7cce1b1d00000000, 0x58171c7e00000000, + 0x347c14db00000000, 0x10a513b800000000, 0xadac754a00000000, + 0x8975722900000000, 0xe51e7a8c00000000, 0xc1c77def00000000, + 0xde0bc7b300000000, 0xfad2c0d000000000, 0x96b9c87500000000, + 0xb260cf1600000000, 0x0f69a9e400000000, 0x2bb0ae8700000000, + 0x47dba62200000000, 0x6302a14100000000, 0x325f334d00000000, + 0x1686342e00000000, 0x7aed3c8b00000000, 0x5e343be800000000, + 0xe33d5d1a00000000, 0xc7e45a7900000000, 0xab8f52dc00000000, + 0x8f5655bf00000000, 0x909aefe300000000, 0xb443e88000000000, + 0xd828e02500000000, 0xfcf1e74600000000, 0x41f881b400000000, + 0x652186d700000000, 0x094a8e7200000000, 0x2d93891100000000, + 0x37d2fbcb00000000, 0x130bfca800000000, 0x7f60f40d00000000, + 0x5bb9f36e00000000, 0xe6b0959c00000000, 0xc26992ff00000000, + 0xae029a5a00000000, 0x8adb9d3900000000, 0x9517276500000000, + 0xb1ce200600000000, 0xdda528a300000000, 0xf97c2fc000000000, + 0x4475493200000000, 0x60ac4e5100000000, 0x0cc746f400000000, + 0x281e419700000000}, + {0x0000000000000000, 0x08e3603c00000000, 0x10c6c17800000000, + 0x1825a14400000000, 0x208c83f100000000, 0x286fe3cd00000000, + 0x304a428900000000, 0x38a922b500000000, 0x011e763800000000, + 0x09fd160400000000, 0x11d8b74000000000, 0x193bd77c00000000, + 0x2192f5c900000000, 0x297195f500000000, 0x315434b100000000, + 0x39b7548d00000000, 0x023cec7000000000, 0x0adf8c4c00000000, + 0x12fa2d0800000000, 0x1a194d3400000000, 0x22b06f8100000000, + 0x2a530fbd00000000, 0x3276aef900000000, 0x3a95cec500000000, + 0x03229a4800000000, 0x0bc1fa7400000000, 0x13e45b3000000000, + 0x1b073b0c00000000, 0x23ae19b900000000, 0x2b4d798500000000, + 0x3368d8c100000000, 0x3b8bb8fd00000000, 0x0478d8e100000000, + 0x0c9bb8dd00000000, 0x14be199900000000, 0x1c5d79a500000000, + 0x24f45b1000000000, 0x2c173b2c00000000, 0x34329a6800000000, + 0x3cd1fa5400000000, 0x0566aed900000000, 0x0d85cee500000000, + 0x15a06fa100000000, 0x1d430f9d00000000, 0x25ea2d2800000000, + 0x2d094d1400000000, 0x352cec5000000000, 0x3dcf8c6c00000000, + 0x0644349100000000, 0x0ea754ad00000000, 0x1682f5e900000000, + 0x1e6195d500000000, 0x26c8b76000000000, 0x2e2bd75c00000000, + 0x360e761800000000, 0x3eed162400000000, 0x075a42a900000000, + 0x0fb9229500000000, 0x179c83d100000000, 0x1f7fe3ed00000000, + 0x27d6c15800000000, 0x2f35a16400000000, 0x3710002000000000, + 0x3ff3601c00000000, 0x49f6c11800000000, 0x4115a12400000000, + 0x5930006000000000, 0x51d3605c00000000, 0x697a42e900000000, + 0x619922d500000000, 0x79bc839100000000, 0x715fe3ad00000000, + 0x48e8b72000000000, 0x400bd71c00000000, 0x582e765800000000, + 0x50cd166400000000, 0x686434d100000000, 0x608754ed00000000, + 0x78a2f5a900000000, 0x7041959500000000, 0x4bca2d6800000000, + 0x43294d5400000000, 0x5b0cec1000000000, 0x53ef8c2c00000000, + 0x6b46ae9900000000, 0x63a5cea500000000, 0x7b806fe100000000, + 0x73630fdd00000000, 0x4ad45b5000000000, 0x42373b6c00000000, + 0x5a129a2800000000, 0x52f1fa1400000000, 0x6a58d8a100000000, + 0x62bbb89d00000000, 0x7a9e19d900000000, 0x727d79e500000000, + 0x4d8e19f900000000, 0x456d79c500000000, 0x5d48d88100000000, + 0x55abb8bd00000000, 0x6d029a0800000000, 0x65e1fa3400000000, + 0x7dc45b7000000000, 0x75273b4c00000000, 0x4c906fc100000000, + 0x44730ffd00000000, 0x5c56aeb900000000, 0x54b5ce8500000000, + 0x6c1cec3000000000, 0x64ff8c0c00000000, 0x7cda2d4800000000, + 0x74394d7400000000, 0x4fb2f58900000000, 0x475195b500000000, + 0x5f7434f100000000, 0x579754cd00000000, 0x6f3e767800000000, + 0x67dd164400000000, 0x7ff8b70000000000, 0x771bd73c00000000, + 0x4eac83b100000000, 0x464fe38d00000000, 0x5e6a42c900000000, + 0x568922f500000000, 0x6e20004000000000, 0x66c3607c00000000, + 0x7ee6c13800000000, 0x7605a10400000000, 0x92ec833100000000, + 0x9a0fe30d00000000, 0x822a424900000000, 0x8ac9227500000000, + 0xb26000c000000000, 0xba8360fc00000000, 0xa2a6c1b800000000, + 0xaa45a18400000000, 0x93f2f50900000000, 0x9b11953500000000, + 0x8334347100000000, 0x8bd7544d00000000, 0xb37e76f800000000, + 0xbb9d16c400000000, 0xa3b8b78000000000, 0xab5bd7bc00000000, + 0x90d06f4100000000, 0x98330f7d00000000, 0x8016ae3900000000, + 0x88f5ce0500000000, 0xb05cecb000000000, 0xb8bf8c8c00000000, + 0xa09a2dc800000000, 0xa8794df400000000, 0x91ce197900000000, + 0x992d794500000000, 0x8108d80100000000, 0x89ebb83d00000000, + 0xb1429a8800000000, 0xb9a1fab400000000, 0xa1845bf000000000, + 0xa9673bcc00000000, 0x96945bd000000000, 0x9e773bec00000000, + 0x86529aa800000000, 0x8eb1fa9400000000, 0xb618d82100000000, + 0xbefbb81d00000000, 0xa6de195900000000, 0xae3d796500000000, + 0x978a2de800000000, 0x9f694dd400000000, 0x874cec9000000000, + 0x8faf8cac00000000, 0xb706ae1900000000, 0xbfe5ce2500000000, + 0xa7c06f6100000000, 0xaf230f5d00000000, 0x94a8b7a000000000, + 0x9c4bd79c00000000, 0x846e76d800000000, 0x8c8d16e400000000, + 0xb424345100000000, 0xbcc7546d00000000, 0xa4e2f52900000000, + 0xac01951500000000, 0x95b6c19800000000, 0x9d55a1a400000000, + 0x857000e000000000, 0x8d9360dc00000000, 0xb53a426900000000, + 0xbdd9225500000000, 0xa5fc831100000000, 0xad1fe32d00000000, + 0xdb1a422900000000, 0xd3f9221500000000, 0xcbdc835100000000, + 0xc33fe36d00000000, 0xfb96c1d800000000, 0xf375a1e400000000, + 0xeb5000a000000000, 0xe3b3609c00000000, 0xda04341100000000, + 0xd2e7542d00000000, 0xcac2f56900000000, 0xc221955500000000, + 0xfa88b7e000000000, 0xf26bd7dc00000000, 0xea4e769800000000, + 0xe2ad16a400000000, 0xd926ae5900000000, 0xd1c5ce6500000000, + 0xc9e06f2100000000, 0xc1030f1d00000000, 0xf9aa2da800000000, + 0xf1494d9400000000, 0xe96cecd000000000, 0xe18f8cec00000000, + 0xd838d86100000000, 0xd0dbb85d00000000, 0xc8fe191900000000, + 0xc01d792500000000, 0xf8b45b9000000000, 0xf0573bac00000000, + 0xe8729ae800000000, 0xe091fad400000000, 0xdf629ac800000000, + 0xd781faf400000000, 0xcfa45bb000000000, 0xc7473b8c00000000, + 0xffee193900000000, 0xf70d790500000000, 0xef28d84100000000, + 0xe7cbb87d00000000, 0xde7cecf000000000, 0xd69f8ccc00000000, + 0xceba2d8800000000, 0xc6594db400000000, 0xfef06f0100000000, + 0xf6130f3d00000000, 0xee36ae7900000000, 0xe6d5ce4500000000, + 0xdd5e76b800000000, 0xd5bd168400000000, 0xcd98b7c000000000, + 0xc57bd7fc00000000, 0xfdd2f54900000000, 0xf531957500000000, + 0xed14343100000000, 0xe5f7540d00000000, 0xdc40008000000000, + 0xd4a360bc00000000, 0xcc86c1f800000000, 0xc465a1c400000000, + 0xfccc837100000000, 0xf42fe34d00000000, 0xec0a420900000000, + 0xe4e9223500000000}, + {0x0000000000000000, 0xd1e8e70e00000000, 0xa2d1cf1d00000000, + 0x7339281300000000, 0x44a39f3b00000000, 0x954b783500000000, + 0xe672502600000000, 0x379ab72800000000, 0x88463f7700000000, + 0x59aed87900000000, 0x2a97f06a00000000, 0xfb7f176400000000, + 0xcce5a04c00000000, 0x1d0d474200000000, 0x6e346f5100000000, + 0xbfdc885f00000000, 0x108d7eee00000000, 0xc16599e000000000, + 0xb25cb1f300000000, 0x63b456fd00000000, 0x542ee1d500000000, + 0x85c606db00000000, 0xf6ff2ec800000000, 0x2717c9c600000000, + 0x98cb419900000000, 0x4923a69700000000, 0x3a1a8e8400000000, + 0xebf2698a00000000, 0xdc68dea200000000, 0x0d8039ac00000000, + 0x7eb911bf00000000, 0xaf51f6b100000000, 0x611c8c0700000000, + 0xb0f46b0900000000, 0xc3cd431a00000000, 0x1225a41400000000, + 0x25bf133c00000000, 0xf457f43200000000, 0x876edc2100000000, + 0x56863b2f00000000, 0xe95ab37000000000, 0x38b2547e00000000, + 0x4b8b7c6d00000000, 0x9a639b6300000000, 0xadf92c4b00000000, + 0x7c11cb4500000000, 0x0f28e35600000000, 0xdec0045800000000, + 0x7191f2e900000000, 0xa07915e700000000, 0xd3403df400000000, + 0x02a8dafa00000000, 0x35326dd200000000, 0xe4da8adc00000000, + 0x97e3a2cf00000000, 0x460b45c100000000, 0xf9d7cd9e00000000, + 0x283f2a9000000000, 0x5b06028300000000, 0x8aeee58d00000000, + 0xbd7452a500000000, 0x6c9cb5ab00000000, 0x1fa59db800000000, + 0xce4d7ab600000000, 0xc238180f00000000, 0x13d0ff0100000000, + 0x60e9d71200000000, 0xb101301c00000000, 0x869b873400000000, + 0x5773603a00000000, 0x244a482900000000, 0xf5a2af2700000000, + 0x4a7e277800000000, 0x9b96c07600000000, 0xe8afe86500000000, + 0x39470f6b00000000, 0x0eddb84300000000, 0xdf355f4d00000000, + 0xac0c775e00000000, 0x7de4905000000000, 0xd2b566e100000000, + 0x035d81ef00000000, 0x7064a9fc00000000, 0xa18c4ef200000000, + 0x9616f9da00000000, 0x47fe1ed400000000, 0x34c736c700000000, + 0xe52fd1c900000000, 0x5af3599600000000, 0x8b1bbe9800000000, + 0xf822968b00000000, 0x29ca718500000000, 0x1e50c6ad00000000, + 0xcfb821a300000000, 0xbc8109b000000000, 0x6d69eebe00000000, + 0xa324940800000000, 0x72cc730600000000, 0x01f55b1500000000, + 0xd01dbc1b00000000, 0xe7870b3300000000, 0x366fec3d00000000, + 0x4556c42e00000000, 0x94be232000000000, 0x2b62ab7f00000000, + 0xfa8a4c7100000000, 0x89b3646200000000, 0x585b836c00000000, + 0x6fc1344400000000, 0xbe29d34a00000000, 0xcd10fb5900000000, + 0x1cf81c5700000000, 0xb3a9eae600000000, 0x62410de800000000, + 0x117825fb00000000, 0xc090c2f500000000, 0xf70a75dd00000000, + 0x26e292d300000000, 0x55dbbac000000000, 0x84335dce00000000, + 0x3befd59100000000, 0xea07329f00000000, 0x993e1a8c00000000, + 0x48d6fd8200000000, 0x7f4c4aaa00000000, 0xaea4ada400000000, + 0xdd9d85b700000000, 0x0c7562b900000000, 0x8471301e00000000, + 0x5599d71000000000, 0x26a0ff0300000000, 0xf748180d00000000, + 0xc0d2af2500000000, 0x113a482b00000000, 0x6203603800000000, + 0xb3eb873600000000, 0x0c370f6900000000, 0xdddfe86700000000, + 0xaee6c07400000000, 0x7f0e277a00000000, 0x4894905200000000, + 0x997c775c00000000, 0xea455f4f00000000, 0x3badb84100000000, + 0x94fc4ef000000000, 0x4514a9fe00000000, 0x362d81ed00000000, + 0xe7c566e300000000, 0xd05fd1cb00000000, 0x01b736c500000000, + 0x728e1ed600000000, 0xa366f9d800000000, 0x1cba718700000000, + 0xcd52968900000000, 0xbe6bbe9a00000000, 0x6f83599400000000, + 0x5819eebc00000000, 0x89f109b200000000, 0xfac821a100000000, + 0x2b20c6af00000000, 0xe56dbc1900000000, 0x34855b1700000000, + 0x47bc730400000000, 0x9654940a00000000, 0xa1ce232200000000, + 0x7026c42c00000000, 0x031fec3f00000000, 0xd2f70b3100000000, + 0x6d2b836e00000000, 0xbcc3646000000000, 0xcffa4c7300000000, + 0x1e12ab7d00000000, 0x29881c5500000000, 0xf860fb5b00000000, + 0x8b59d34800000000, 0x5ab1344600000000, 0xf5e0c2f700000000, + 0x240825f900000000, 0x57310dea00000000, 0x86d9eae400000000, + 0xb1435dcc00000000, 0x60abbac200000000, 0x139292d100000000, + 0xc27a75df00000000, 0x7da6fd8000000000, 0xac4e1a8e00000000, + 0xdf77329d00000000, 0x0e9fd59300000000, 0x390562bb00000000, + 0xe8ed85b500000000, 0x9bd4ada600000000, 0x4a3c4aa800000000, + 0x4649281100000000, 0x97a1cf1f00000000, 0xe498e70c00000000, + 0x3570000200000000, 0x02eab72a00000000, 0xd302502400000000, + 0xa03b783700000000, 0x71d39f3900000000, 0xce0f176600000000, + 0x1fe7f06800000000, 0x6cded87b00000000, 0xbd363f7500000000, + 0x8aac885d00000000, 0x5b446f5300000000, 0x287d474000000000, + 0xf995a04e00000000, 0x56c456ff00000000, 0x872cb1f100000000, + 0xf41599e200000000, 0x25fd7eec00000000, 0x1267c9c400000000, + 0xc38f2eca00000000, 0xb0b606d900000000, 0x615ee1d700000000, + 0xde82698800000000, 0x0f6a8e8600000000, 0x7c53a69500000000, + 0xadbb419b00000000, 0x9a21f6b300000000, 0x4bc911bd00000000, + 0x38f039ae00000000, 0xe918dea000000000, 0x2755a41600000000, + 0xf6bd431800000000, 0x85846b0b00000000, 0x546c8c0500000000, + 0x63f63b2d00000000, 0xb21edc2300000000, 0xc127f43000000000, + 0x10cf133e00000000, 0xaf139b6100000000, 0x7efb7c6f00000000, + 0x0dc2547c00000000, 0xdc2ab37200000000, 0xebb0045a00000000, + 0x3a58e35400000000, 0x4961cb4700000000, 0x98892c4900000000, + 0x37d8daf800000000, 0xe6303df600000000, 0x950915e500000000, + 0x44e1f2eb00000000, 0x737b45c300000000, 0xa293a2cd00000000, + 0xd1aa8ade00000000, 0x00426dd000000000, 0xbf9ee58f00000000, + 0x6e76028100000000, 0x1d4f2a9200000000, 0xcca7cd9c00000000, + 0xfb3d7ab400000000, 0x2ad59dba00000000, 0x59ecb5a900000000, + 0x880452a700000000}, + {0x0000000000000000, 0xaa05daf100000000, 0x150dc53800000000, + 0xbf081fc900000000, 0x2a1a8a7100000000, 0x801f508000000000, + 0x3f174f4900000000, 0x951295b800000000, 0x543414e300000000, + 0xfe31ce1200000000, 0x4139d1db00000000, 0xeb3c0b2a00000000, + 0x7e2e9e9200000000, 0xd42b446300000000, 0x6b235baa00000000, + 0xc126815b00000000, 0xe96e591d00000000, 0x436b83ec00000000, + 0xfc639c2500000000, 0x566646d400000000, 0xc374d36c00000000, + 0x6971099d00000000, 0xd679165400000000, 0x7c7ccca500000000, + 0xbd5a4dfe00000000, 0x175f970f00000000, 0xa85788c600000000, + 0x0252523700000000, 0x9740c78f00000000, 0x3d451d7e00000000, + 0x824d02b700000000, 0x2848d84600000000, 0xd2ddb23a00000000, + 0x78d868cb00000000, 0xc7d0770200000000, 0x6dd5adf300000000, + 0xf8c7384b00000000, 0x52c2e2ba00000000, 0xedcafd7300000000, + 0x47cf278200000000, 0x86e9a6d900000000, 0x2cec7c2800000000, + 0x93e463e100000000, 0x39e1b91000000000, 0xacf32ca800000000, + 0x06f6f65900000000, 0xb9fee99000000000, 0x13fb336100000000, + 0x3bb3eb2700000000, 0x91b631d600000000, 0x2ebe2e1f00000000, + 0x84bbf4ee00000000, 0x11a9615600000000, 0xbbacbba700000000, + 0x04a4a46e00000000, 0xaea17e9f00000000, 0x6f87ffc400000000, + 0xc582253500000000, 0x7a8a3afc00000000, 0xd08fe00d00000000, + 0x459d75b500000000, 0xef98af4400000000, 0x5090b08d00000000, + 0xfa956a7c00000000, 0xa4bb657500000000, 0x0ebebf8400000000, + 0xb1b6a04d00000000, 0x1bb37abc00000000, 0x8ea1ef0400000000, + 0x24a435f500000000, 0x9bac2a3c00000000, 0x31a9f0cd00000000, + 0xf08f719600000000, 0x5a8aab6700000000, 0xe582b4ae00000000, + 0x4f876e5f00000000, 0xda95fbe700000000, 0x7090211600000000, + 0xcf983edf00000000, 0x659de42e00000000, 0x4dd53c6800000000, + 0xe7d0e69900000000, 0x58d8f95000000000, 0xf2dd23a100000000, + 0x67cfb61900000000, 0xcdca6ce800000000, 0x72c2732100000000, + 0xd8c7a9d000000000, 0x19e1288b00000000, 0xb3e4f27a00000000, + 0x0cecedb300000000, 0xa6e9374200000000, 0x33fba2fa00000000, + 0x99fe780b00000000, 0x26f667c200000000, 0x8cf3bd3300000000, + 0x7666d74f00000000, 0xdc630dbe00000000, 0x636b127700000000, + 0xc96ec88600000000, 0x5c7c5d3e00000000, 0xf67987cf00000000, + 0x4971980600000000, 0xe37442f700000000, 0x2252c3ac00000000, + 0x8857195d00000000, 0x375f069400000000, 0x9d5adc6500000000, + 0x084849dd00000000, 0xa24d932c00000000, 0x1d458ce500000000, + 0xb740561400000000, 0x9f088e5200000000, 0x350d54a300000000, + 0x8a054b6a00000000, 0x2000919b00000000, 0xb512042300000000, + 0x1f17ded200000000, 0xa01fc11b00000000, 0x0a1a1bea00000000, + 0xcb3c9ab100000000, 0x6139404000000000, 0xde315f8900000000, + 0x7434857800000000, 0xe12610c000000000, 0x4b23ca3100000000, + 0xf42bd5f800000000, 0x5e2e0f0900000000, 0x4877cbea00000000, + 0xe272111b00000000, 0x5d7a0ed200000000, 0xf77fd42300000000, + 0x626d419b00000000, 0xc8689b6a00000000, 0x776084a300000000, + 0xdd655e5200000000, 0x1c43df0900000000, 0xb64605f800000000, + 0x094e1a3100000000, 0xa34bc0c000000000, 0x3659557800000000, + 0x9c5c8f8900000000, 0x2354904000000000, 0x89514ab100000000, + 0xa11992f700000000, 0x0b1c480600000000, 0xb41457cf00000000, + 0x1e118d3e00000000, 0x8b03188600000000, 0x2106c27700000000, + 0x9e0eddbe00000000, 0x340b074f00000000, 0xf52d861400000000, + 0x5f285ce500000000, 0xe020432c00000000, 0x4a2599dd00000000, + 0xdf370c6500000000, 0x7532d69400000000, 0xca3ac95d00000000, + 0x603f13ac00000000, 0x9aaa79d000000000, 0x30afa32100000000, + 0x8fa7bce800000000, 0x25a2661900000000, 0xb0b0f3a100000000, + 0x1ab5295000000000, 0xa5bd369900000000, 0x0fb8ec6800000000, + 0xce9e6d3300000000, 0x649bb7c200000000, 0xdb93a80b00000000, + 0x719672fa00000000, 0xe484e74200000000, 0x4e813db300000000, + 0xf189227a00000000, 0x5b8cf88b00000000, 0x73c420cd00000000, + 0xd9c1fa3c00000000, 0x66c9e5f500000000, 0xcccc3f0400000000, + 0x59deaabc00000000, 0xf3db704d00000000, 0x4cd36f8400000000, + 0xe6d6b57500000000, 0x27f0342e00000000, 0x8df5eedf00000000, + 0x32fdf11600000000, 0x98f82be700000000, 0x0deabe5f00000000, + 0xa7ef64ae00000000, 0x18e77b6700000000, 0xb2e2a19600000000, + 0xecccae9f00000000, 0x46c9746e00000000, 0xf9c16ba700000000, + 0x53c4b15600000000, 0xc6d624ee00000000, 0x6cd3fe1f00000000, + 0xd3dbe1d600000000, 0x79de3b2700000000, 0xb8f8ba7c00000000, + 0x12fd608d00000000, 0xadf57f4400000000, 0x07f0a5b500000000, + 0x92e2300d00000000, 0x38e7eafc00000000, 0x87eff53500000000, + 0x2dea2fc400000000, 0x05a2f78200000000, 0xafa72d7300000000, + 0x10af32ba00000000, 0xbaaae84b00000000, 0x2fb87df300000000, + 0x85bda70200000000, 0x3ab5b8cb00000000, 0x90b0623a00000000, + 0x5196e36100000000, 0xfb93399000000000, 0x449b265900000000, + 0xee9efca800000000, 0x7b8c691000000000, 0xd189b3e100000000, + 0x6e81ac2800000000, 0xc48476d900000000, 0x3e111ca500000000, + 0x9414c65400000000, 0x2b1cd99d00000000, 0x8119036c00000000, + 0x140b96d400000000, 0xbe0e4c2500000000, 0x010653ec00000000, + 0xab03891d00000000, 0x6a25084600000000, 0xc020d2b700000000, + 0x7f28cd7e00000000, 0xd52d178f00000000, 0x403f823700000000, + 0xea3a58c600000000, 0x5532470f00000000, 0xff379dfe00000000, + 0xd77f45b800000000, 0x7d7a9f4900000000, 0xc272808000000000, + 0x68775a7100000000, 0xfd65cfc900000000, 0x5760153800000000, + 0xe8680af100000000, 0x426dd00000000000, 0x834b515b00000000, + 0x294e8baa00000000, 0x9646946300000000, 0x3c434e9200000000, + 0xa951db2a00000000, 0x035401db00000000, 0xbc5c1e1200000000, + 0x1659c4e300000000}}; + +#else /* W == 4 */ + +local const z_crc_t FAR crc_braid_table[][256] = { + {0x00000000, 0xae689191, 0x87a02563, 0x29c8b4f2, 0xd4314c87, + 0x7a59dd16, 0x539169e4, 0xfdf9f875, 0x73139f4f, 0xdd7b0ede, + 0xf4b3ba2c, 0x5adb2bbd, 0xa722d3c8, 0x094a4259, 0x2082f6ab, + 0x8eea673a, 0xe6273e9e, 0x484faf0f, 0x61871bfd, 0xcfef8a6c, + 0x32167219, 0x9c7ee388, 0xb5b6577a, 0x1bdec6eb, 0x9534a1d1, + 0x3b5c3040, 0x129484b2, 0xbcfc1523, 0x4105ed56, 0xef6d7cc7, + 0xc6a5c835, 0x68cd59a4, 0x173f7b7d, 0xb957eaec, 0x909f5e1e, + 0x3ef7cf8f, 0xc30e37fa, 0x6d66a66b, 0x44ae1299, 0xeac68308, + 0x642ce432, 0xca4475a3, 0xe38cc151, 0x4de450c0, 0xb01da8b5, + 0x1e753924, 0x37bd8dd6, 0x99d51c47, 0xf11845e3, 0x5f70d472, + 0x76b86080, 0xd8d0f111, 0x25290964, 0x8b4198f5, 0xa2892c07, + 0x0ce1bd96, 0x820bdaac, 0x2c634b3d, 0x05abffcf, 0xabc36e5e, + 0x563a962b, 0xf85207ba, 0xd19ab348, 0x7ff222d9, 0x2e7ef6fa, + 0x8016676b, 0xa9ded399, 0x07b64208, 0xfa4fba7d, 0x54272bec, + 0x7def9f1e, 0xd3870e8f, 0x5d6d69b5, 0xf305f824, 0xdacd4cd6, + 0x74a5dd47, 0x895c2532, 0x2734b4a3, 0x0efc0051, 0xa09491c0, + 0xc859c864, 0x663159f5, 0x4ff9ed07, 0xe1917c96, 0x1c6884e3, + 0xb2001572, 0x9bc8a180, 0x35a03011, 0xbb4a572b, 0x1522c6ba, + 0x3cea7248, 0x9282e3d9, 0x6f7b1bac, 0xc1138a3d, 0xe8db3ecf, + 0x46b3af5e, 0x39418d87, 0x97291c16, 0xbee1a8e4, 0x10893975, + 0xed70c100, 0x43185091, 0x6ad0e463, 0xc4b875f2, 0x4a5212c8, + 0xe43a8359, 0xcdf237ab, 0x639aa63a, 0x9e635e4f, 0x300bcfde, + 0x19c37b2c, 0xb7abeabd, 0xdf66b319, 0x710e2288, 0x58c6967a, + 0xf6ae07eb, 0x0b57ff9e, 0xa53f6e0f, 0x8cf7dafd, 0x229f4b6c, + 0xac752c56, 0x021dbdc7, 0x2bd50935, 0x85bd98a4, 0x784460d1, + 0xd62cf140, 0xffe445b2, 0x518cd423, 0x5cfdedf4, 0xf2957c65, + 0xdb5dc897, 0x75355906, 0x88cca173, 0x26a430e2, 0x0f6c8410, + 0xa1041581, 0x2fee72bb, 0x8186e32a, 0xa84e57d8, 0x0626c649, + 0xfbdf3e3c, 0x55b7afad, 0x7c7f1b5f, 0xd2178ace, 0xbadad36a, + 0x14b242fb, 0x3d7af609, 0x93126798, 0x6eeb9fed, 0xc0830e7c, + 0xe94bba8e, 0x47232b1f, 0xc9c94c25, 0x67a1ddb4, 0x4e696946, + 0xe001f8d7, 0x1df800a2, 0xb3909133, 0x9a5825c1, 0x3430b450, + 0x4bc29689, 0xe5aa0718, 0xcc62b3ea, 0x620a227b, 0x9ff3da0e, + 0x319b4b9f, 0x1853ff6d, 0xb63b6efc, 0x38d109c6, 0x96b99857, + 0xbf712ca5, 0x1119bd34, 0xece04541, 0x4288d4d0, 0x6b406022, + 0xc528f1b3, 0xade5a817, 0x038d3986, 0x2a458d74, 0x842d1ce5, + 0x79d4e490, 0xd7bc7501, 0xfe74c1f3, 0x501c5062, 0xdef63758, + 0x709ea6c9, 0x5956123b, 0xf73e83aa, 0x0ac77bdf, 0xa4afea4e, + 0x8d675ebc, 0x230fcf2d, 0x72831b0e, 0xdceb8a9f, 0xf5233e6d, + 0x5b4baffc, 0xa6b25789, 0x08dac618, 0x211272ea, 0x8f7ae37b, + 0x01908441, 0xaff815d0, 0x8630a122, 0x285830b3, 0xd5a1c8c6, + 0x7bc95957, 0x5201eda5, 0xfc697c34, 0x94a42590, 0x3accb401, + 0x130400f3, 0xbd6c9162, 0x40956917, 0xeefdf886, 0xc7354c74, + 0x695ddde5, 0xe7b7badf, 0x49df2b4e, 0x60179fbc, 0xce7f0e2d, + 0x3386f658, 0x9dee67c9, 0xb426d33b, 0x1a4e42aa, 0x65bc6073, + 0xcbd4f1e2, 0xe21c4510, 0x4c74d481, 0xb18d2cf4, 0x1fe5bd65, + 0x362d0997, 0x98459806, 0x16afff3c, 0xb8c76ead, 0x910fda5f, + 0x3f674bce, 0xc29eb3bb, 0x6cf6222a, 0x453e96d8, 0xeb560749, + 0x839b5eed, 0x2df3cf7c, 0x043b7b8e, 0xaa53ea1f, 0x57aa126a, + 0xf9c283fb, 0xd00a3709, 0x7e62a698, 0xf088c1a2, 0x5ee05033, + 0x7728e4c1, 0xd9407550, 0x24b98d25, 0x8ad11cb4, 0xa319a846, + 0x0d7139d7}, + {0x00000000, 0xb9fbdbe8, 0xa886b191, 0x117d6a79, 0x8a7c6563, + 0x3387be8b, 0x22fad4f2, 0x9b010f1a, 0xcf89cc87, 0x7672176f, + 0x670f7d16, 0xdef4a6fe, 0x45f5a9e4, 0xfc0e720c, 0xed731875, + 0x5488c39d, 0x44629f4f, 0xfd9944a7, 0xece42ede, 0x551ff536, + 0xce1efa2c, 0x77e521c4, 0x66984bbd, 0xdf639055, 0x8beb53c8, + 0x32108820, 0x236de259, 0x9a9639b1, 0x019736ab, 0xb86ced43, + 0xa911873a, 0x10ea5cd2, 0x88c53e9e, 0x313ee576, 0x20438f0f, + 0x99b854e7, 0x02b95bfd, 0xbb428015, 0xaa3fea6c, 0x13c43184, + 0x474cf219, 0xfeb729f1, 0xefca4388, 0x56319860, 0xcd30977a, + 0x74cb4c92, 0x65b626eb, 0xdc4dfd03, 0xcca7a1d1, 0x755c7a39, + 0x64211040, 0xdddacba8, 0x46dbc4b2, 0xff201f5a, 0xee5d7523, + 0x57a6aecb, 0x032e6d56, 0xbad5b6be, 0xaba8dcc7, 0x1253072f, + 0x89520835, 0x30a9d3dd, 0x21d4b9a4, 0x982f624c, 0xcafb7b7d, + 0x7300a095, 0x627dcaec, 0xdb861104, 0x40871e1e, 0xf97cc5f6, + 0xe801af8f, 0x51fa7467, 0x0572b7fa, 0xbc896c12, 0xadf4066b, + 0x140fdd83, 0x8f0ed299, 0x36f50971, 0x27886308, 0x9e73b8e0, + 0x8e99e432, 0x37623fda, 0x261f55a3, 0x9fe48e4b, 0x04e58151, + 0xbd1e5ab9, 0xac6330c0, 0x1598eb28, 0x411028b5, 0xf8ebf35d, + 0xe9969924, 0x506d42cc, 0xcb6c4dd6, 0x7297963e, 0x63eafc47, + 0xda1127af, 0x423e45e3, 0xfbc59e0b, 0xeab8f472, 0x53432f9a, + 0xc8422080, 0x71b9fb68, 0x60c49111, 0xd93f4af9, 0x8db78964, + 0x344c528c, 0x253138f5, 0x9ccae31d, 0x07cbec07, 0xbe3037ef, + 0xaf4d5d96, 0x16b6867e, 0x065cdaac, 0xbfa70144, 0xaeda6b3d, + 0x1721b0d5, 0x8c20bfcf, 0x35db6427, 0x24a60e5e, 0x9d5dd5b6, + 0xc9d5162b, 0x702ecdc3, 0x6153a7ba, 0xd8a87c52, 0x43a97348, + 0xfa52a8a0, 0xeb2fc2d9, 0x52d41931, 0x4e87f0bb, 0xf77c2b53, + 0xe601412a, 0x5ffa9ac2, 0xc4fb95d8, 0x7d004e30, 0x6c7d2449, + 0xd586ffa1, 0x810e3c3c, 0x38f5e7d4, 0x29888dad, 0x90735645, + 0x0b72595f, 0xb28982b7, 0xa3f4e8ce, 0x1a0f3326, 0x0ae56ff4, + 0xb31eb41c, 0xa263de65, 0x1b98058d, 0x80990a97, 0x3962d17f, + 0x281fbb06, 0x91e460ee, 0xc56ca373, 0x7c97789b, 0x6dea12e2, + 0xd411c90a, 0x4f10c610, 0xf6eb1df8, 0xe7967781, 0x5e6dac69, + 0xc642ce25, 0x7fb915cd, 0x6ec47fb4, 0xd73fa45c, 0x4c3eab46, + 0xf5c570ae, 0xe4b81ad7, 0x5d43c13f, 0x09cb02a2, 0xb030d94a, + 0xa14db333, 0x18b668db, 0x83b767c1, 0x3a4cbc29, 0x2b31d650, + 0x92ca0db8, 0x8220516a, 0x3bdb8a82, 0x2aa6e0fb, 0x935d3b13, + 0x085c3409, 0xb1a7efe1, 0xa0da8598, 0x19215e70, 0x4da99ded, + 0xf4524605, 0xe52f2c7c, 0x5cd4f794, 0xc7d5f88e, 0x7e2e2366, + 0x6f53491f, 0xd6a892f7, 0x847c8bc6, 0x3d87502e, 0x2cfa3a57, + 0x9501e1bf, 0x0e00eea5, 0xb7fb354d, 0xa6865f34, 0x1f7d84dc, + 0x4bf54741, 0xf20e9ca9, 0xe373f6d0, 0x5a882d38, 0xc1892222, + 0x7872f9ca, 0x690f93b3, 0xd0f4485b, 0xc01e1489, 0x79e5cf61, + 0x6898a518, 0xd1637ef0, 0x4a6271ea, 0xf399aa02, 0xe2e4c07b, + 0x5b1f1b93, 0x0f97d80e, 0xb66c03e6, 0xa711699f, 0x1eeab277, + 0x85ebbd6d, 0x3c106685, 0x2d6d0cfc, 0x9496d714, 0x0cb9b558, + 0xb5426eb0, 0xa43f04c9, 0x1dc4df21, 0x86c5d03b, 0x3f3e0bd3, + 0x2e4361aa, 0x97b8ba42, 0xc33079df, 0x7acba237, 0x6bb6c84e, + 0xd24d13a6, 0x494c1cbc, 0xf0b7c754, 0xe1caad2d, 0x583176c5, + 0x48db2a17, 0xf120f1ff, 0xe05d9b86, 0x59a6406e, 0xc2a74f74, + 0x7b5c949c, 0x6a21fee5, 0xd3da250d, 0x8752e690, 0x3ea93d78, + 0x2fd45701, 0x962f8ce9, 0x0d2e83f3, 0xb4d5581b, 0xa5a83262, + 0x1c53e98a}, + {0x00000000, 0x9d0fe176, 0xe16ec4ad, 0x7c6125db, 0x19ac8f1b, + 0x84a36e6d, 0xf8c24bb6, 0x65cdaac0, 0x33591e36, 0xae56ff40, + 0xd237da9b, 0x4f383bed, 0x2af5912d, 0xb7fa705b, 0xcb9b5580, + 0x5694b4f6, 0x66b23c6c, 0xfbbddd1a, 0x87dcf8c1, 0x1ad319b7, + 0x7f1eb377, 0xe2115201, 0x9e7077da, 0x037f96ac, 0x55eb225a, + 0xc8e4c32c, 0xb485e6f7, 0x298a0781, 0x4c47ad41, 0xd1484c37, + 0xad2969ec, 0x3026889a, 0xcd6478d8, 0x506b99ae, 0x2c0abc75, + 0xb1055d03, 0xd4c8f7c3, 0x49c716b5, 0x35a6336e, 0xa8a9d218, + 0xfe3d66ee, 0x63328798, 0x1f53a243, 0x825c4335, 0xe791e9f5, + 0x7a9e0883, 0x06ff2d58, 0x9bf0cc2e, 0xabd644b4, 0x36d9a5c2, + 0x4ab88019, 0xd7b7616f, 0xb27acbaf, 0x2f752ad9, 0x53140f02, + 0xce1bee74, 0x988f5a82, 0x0580bbf4, 0x79e19e2f, 0xe4ee7f59, + 0x8123d599, 0x1c2c34ef, 0x604d1134, 0xfd42f042, 0x41b9f7f1, + 0xdcb61687, 0xa0d7335c, 0x3dd8d22a, 0x581578ea, 0xc51a999c, + 0xb97bbc47, 0x24745d31, 0x72e0e9c7, 0xefef08b1, 0x938e2d6a, + 0x0e81cc1c, 0x6b4c66dc, 0xf64387aa, 0x8a22a271, 0x172d4307, + 0x270bcb9d, 0xba042aeb, 0xc6650f30, 0x5b6aee46, 0x3ea74486, + 0xa3a8a5f0, 0xdfc9802b, 0x42c6615d, 0x1452d5ab, 0x895d34dd, + 0xf53c1106, 0x6833f070, 0x0dfe5ab0, 0x90f1bbc6, 0xec909e1d, + 0x719f7f6b, 0x8cdd8f29, 0x11d26e5f, 0x6db34b84, 0xf0bcaaf2, + 0x95710032, 0x087ee144, 0x741fc49f, 0xe91025e9, 0xbf84911f, + 0x228b7069, 0x5eea55b2, 0xc3e5b4c4, 0xa6281e04, 0x3b27ff72, + 0x4746daa9, 0xda493bdf, 0xea6fb345, 0x77605233, 0x0b0177e8, + 0x960e969e, 0xf3c33c5e, 0x6eccdd28, 0x12adf8f3, 0x8fa21985, + 0xd936ad73, 0x44394c05, 0x385869de, 0xa55788a8, 0xc09a2268, + 0x5d95c31e, 0x21f4e6c5, 0xbcfb07b3, 0x8373efe2, 0x1e7c0e94, + 0x621d2b4f, 0xff12ca39, 0x9adf60f9, 0x07d0818f, 0x7bb1a454, + 0xe6be4522, 0xb02af1d4, 0x2d2510a2, 0x51443579, 0xcc4bd40f, + 0xa9867ecf, 0x34899fb9, 0x48e8ba62, 0xd5e75b14, 0xe5c1d38e, + 0x78ce32f8, 0x04af1723, 0x99a0f655, 0xfc6d5c95, 0x6162bde3, + 0x1d039838, 0x800c794e, 0xd698cdb8, 0x4b972cce, 0x37f60915, + 0xaaf9e863, 0xcf3442a3, 0x523ba3d5, 0x2e5a860e, 0xb3556778, + 0x4e17973a, 0xd318764c, 0xaf795397, 0x3276b2e1, 0x57bb1821, + 0xcab4f957, 0xb6d5dc8c, 0x2bda3dfa, 0x7d4e890c, 0xe041687a, + 0x9c204da1, 0x012facd7, 0x64e20617, 0xf9ede761, 0x858cc2ba, + 0x188323cc, 0x28a5ab56, 0xb5aa4a20, 0xc9cb6ffb, 0x54c48e8d, + 0x3109244d, 0xac06c53b, 0xd067e0e0, 0x4d680196, 0x1bfcb560, + 0x86f35416, 0xfa9271cd, 0x679d90bb, 0x02503a7b, 0x9f5fdb0d, + 0xe33efed6, 0x7e311fa0, 0xc2ca1813, 0x5fc5f965, 0x23a4dcbe, + 0xbeab3dc8, 0xdb669708, 0x4669767e, 0x3a0853a5, 0xa707b2d3, + 0xf1930625, 0x6c9ce753, 0x10fdc288, 0x8df223fe, 0xe83f893e, + 0x75306848, 0x09514d93, 0x945eace5, 0xa478247f, 0x3977c509, + 0x4516e0d2, 0xd81901a4, 0xbdd4ab64, 0x20db4a12, 0x5cba6fc9, + 0xc1b58ebf, 0x97213a49, 0x0a2edb3f, 0x764ffee4, 0xeb401f92, + 0x8e8db552, 0x13825424, 0x6fe371ff, 0xf2ec9089, 0x0fae60cb, + 0x92a181bd, 0xeec0a466, 0x73cf4510, 0x1602efd0, 0x8b0d0ea6, + 0xf76c2b7d, 0x6a63ca0b, 0x3cf77efd, 0xa1f89f8b, 0xdd99ba50, + 0x40965b26, 0x255bf1e6, 0xb8541090, 0xc435354b, 0x593ad43d, + 0x691c5ca7, 0xf413bdd1, 0x8872980a, 0x157d797c, 0x70b0d3bc, + 0xedbf32ca, 0x91de1711, 0x0cd1f667, 0x5a454291, 0xc74aa3e7, + 0xbb2b863c, 0x2624674a, 0x43e9cd8a, 0xdee62cfc, 0xa2870927, + 0x3f88e851}, + {0x00000000, 0xdd96d985, 0x605cb54b, 0xbdca6cce, 0xc0b96a96, + 0x1d2fb313, 0xa0e5dfdd, 0x7d730658, 0x5a03d36d, 0x87950ae8, + 0x3a5f6626, 0xe7c9bfa3, 0x9abab9fb, 0x472c607e, 0xfae60cb0, + 0x2770d535, 0xb407a6da, 0x69917f5f, 0xd45b1391, 0x09cdca14, + 0x74becc4c, 0xa92815c9, 0x14e27907, 0xc974a082, 0xee0475b7, + 0x3392ac32, 0x8e58c0fc, 0x53ce1979, 0x2ebd1f21, 0xf32bc6a4, + 0x4ee1aa6a, 0x937773ef, 0xb37e4bf5, 0x6ee89270, 0xd322febe, + 0x0eb4273b, 0x73c72163, 0xae51f8e6, 0x139b9428, 0xce0d4dad, + 0xe97d9898, 0x34eb411d, 0x89212dd3, 0x54b7f456, 0x29c4f20e, + 0xf4522b8b, 0x49984745, 0x940e9ec0, 0x0779ed2f, 0xdaef34aa, + 0x67255864, 0xbab381e1, 0xc7c087b9, 0x1a565e3c, 0xa79c32f2, + 0x7a0aeb77, 0x5d7a3e42, 0x80ece7c7, 0x3d268b09, 0xe0b0528c, + 0x9dc354d4, 0x40558d51, 0xfd9fe19f, 0x2009381a, 0xbd8d91ab, + 0x601b482e, 0xddd124e0, 0x0047fd65, 0x7d34fb3d, 0xa0a222b8, + 0x1d684e76, 0xc0fe97f3, 0xe78e42c6, 0x3a189b43, 0x87d2f78d, + 0x5a442e08, 0x27372850, 0xfaa1f1d5, 0x476b9d1b, 0x9afd449e, + 0x098a3771, 0xd41ceef4, 0x69d6823a, 0xb4405bbf, 0xc9335de7, + 0x14a58462, 0xa96fe8ac, 0x74f93129, 0x5389e41c, 0x8e1f3d99, + 0x33d55157, 0xee4388d2, 0x93308e8a, 0x4ea6570f, 0xf36c3bc1, + 0x2efae244, 0x0ef3da5e, 0xd36503db, 0x6eaf6f15, 0xb339b690, + 0xce4ab0c8, 0x13dc694d, 0xae160583, 0x7380dc06, 0x54f00933, + 0x8966d0b6, 0x34acbc78, 0xe93a65fd, 0x944963a5, 0x49dfba20, + 0xf415d6ee, 0x29830f6b, 0xbaf47c84, 0x6762a501, 0xdaa8c9cf, + 0x073e104a, 0x7a4d1612, 0xa7dbcf97, 0x1a11a359, 0xc7877adc, + 0xe0f7afe9, 0x3d61766c, 0x80ab1aa2, 0x5d3dc327, 0x204ec57f, + 0xfdd81cfa, 0x40127034, 0x9d84a9b1, 0xa06a2517, 0x7dfcfc92, + 0xc036905c, 0x1da049d9, 0x60d34f81, 0xbd459604, 0x008ffaca, + 0xdd19234f, 0xfa69f67a, 0x27ff2fff, 0x9a354331, 0x47a39ab4, + 0x3ad09cec, 0xe7464569, 0x5a8c29a7, 0x871af022, 0x146d83cd, + 0xc9fb5a48, 0x74313686, 0xa9a7ef03, 0xd4d4e95b, 0x094230de, + 0xb4885c10, 0x691e8595, 0x4e6e50a0, 0x93f88925, 0x2e32e5eb, + 0xf3a43c6e, 0x8ed73a36, 0x5341e3b3, 0xee8b8f7d, 0x331d56f8, + 0x13146ee2, 0xce82b767, 0x7348dba9, 0xaede022c, 0xd3ad0474, + 0x0e3bddf1, 0xb3f1b13f, 0x6e6768ba, 0x4917bd8f, 0x9481640a, + 0x294b08c4, 0xf4ddd141, 0x89aed719, 0x54380e9c, 0xe9f26252, + 0x3464bbd7, 0xa713c838, 0x7a8511bd, 0xc74f7d73, 0x1ad9a4f6, + 0x67aaa2ae, 0xba3c7b2b, 0x07f617e5, 0xda60ce60, 0xfd101b55, + 0x2086c2d0, 0x9d4cae1e, 0x40da779b, 0x3da971c3, 0xe03fa846, + 0x5df5c488, 0x80631d0d, 0x1de7b4bc, 0xc0716d39, 0x7dbb01f7, + 0xa02dd872, 0xdd5ede2a, 0x00c807af, 0xbd026b61, 0x6094b2e4, + 0x47e467d1, 0x9a72be54, 0x27b8d29a, 0xfa2e0b1f, 0x875d0d47, + 0x5acbd4c2, 0xe701b80c, 0x3a976189, 0xa9e01266, 0x7476cbe3, + 0xc9bca72d, 0x142a7ea8, 0x695978f0, 0xb4cfa175, 0x0905cdbb, + 0xd493143e, 0xf3e3c10b, 0x2e75188e, 0x93bf7440, 0x4e29adc5, + 0x335aab9d, 0xeecc7218, 0x53061ed6, 0x8e90c753, 0xae99ff49, + 0x730f26cc, 0xcec54a02, 0x13539387, 0x6e2095df, 0xb3b64c5a, + 0x0e7c2094, 0xd3eaf911, 0xf49a2c24, 0x290cf5a1, 0x94c6996f, + 0x495040ea, 0x342346b2, 0xe9b59f37, 0x547ff3f9, 0x89e92a7c, + 0x1a9e5993, 0xc7088016, 0x7ac2ecd8, 0xa754355d, 0xda273305, + 0x07b1ea80, 0xba7b864e, 0x67ed5fcb, 0x409d8afe, 0x9d0b537b, + 0x20c13fb5, 0xfd57e630, 0x8024e068, 0x5db239ed, 0xe0785523, + 0x3dee8ca6}}; + +local const z_word_t FAR crc_braid_big_table[][256] = { + {0x00000000, 0x85d996dd, 0x4bb55c60, 0xce6ccabd, 0x966ab9c0, + 0x13b32f1d, 0xdddfe5a0, 0x5806737d, 0x6dd3035a, 0xe80a9587, + 0x26665f3a, 0xa3bfc9e7, 0xfbb9ba9a, 0x7e602c47, 0xb00ce6fa, + 0x35d57027, 0xdaa607b4, 0x5f7f9169, 0x91135bd4, 0x14cacd09, + 0x4cccbe74, 0xc91528a9, 0x0779e214, 0x82a074c9, 0xb77504ee, + 0x32ac9233, 0xfcc0588e, 0x7919ce53, 0x211fbd2e, 0xa4c62bf3, + 0x6aaae14e, 0xef737793, 0xf54b7eb3, 0x7092e86e, 0xbefe22d3, + 0x3b27b40e, 0x6321c773, 0xe6f851ae, 0x28949b13, 0xad4d0dce, + 0x98987de9, 0x1d41eb34, 0xd32d2189, 0x56f4b754, 0x0ef2c429, + 0x8b2b52f4, 0x45479849, 0xc09e0e94, 0x2fed7907, 0xaa34efda, + 0x64582567, 0xe181b3ba, 0xb987c0c7, 0x3c5e561a, 0xf2329ca7, + 0x77eb0a7a, 0x423e7a5d, 0xc7e7ec80, 0x098b263d, 0x8c52b0e0, + 0xd454c39d, 0x518d5540, 0x9fe19ffd, 0x1a380920, 0xab918dbd, + 0x2e481b60, 0xe024d1dd, 0x65fd4700, 0x3dfb347d, 0xb822a2a0, + 0x764e681d, 0xf397fec0, 0xc6428ee7, 0x439b183a, 0x8df7d287, + 0x082e445a, 0x50283727, 0xd5f1a1fa, 0x1b9d6b47, 0x9e44fd9a, + 0x71378a09, 0xf4ee1cd4, 0x3a82d669, 0xbf5b40b4, 0xe75d33c9, + 0x6284a514, 0xace86fa9, 0x2931f974, 0x1ce48953, 0x993d1f8e, + 0x5751d533, 0xd28843ee, 0x8a8e3093, 0x0f57a64e, 0xc13b6cf3, + 0x44e2fa2e, 0x5edaf30e, 0xdb0365d3, 0x156faf6e, 0x90b639b3, + 0xc8b04ace, 0x4d69dc13, 0x830516ae, 0x06dc8073, 0x3309f054, + 0xb6d06689, 0x78bcac34, 0xfd653ae9, 0xa5634994, 0x20badf49, + 0xeed615f4, 0x6b0f8329, 0x847cf4ba, 0x01a56267, 0xcfc9a8da, + 0x4a103e07, 0x12164d7a, 0x97cfdba7, 0x59a3111a, 0xdc7a87c7, + 0xe9aff7e0, 0x6c76613d, 0xa21aab80, 0x27c33d5d, 0x7fc54e20, + 0xfa1cd8fd, 0x34701240, 0xb1a9849d, 0x17256aa0, 0x92fcfc7d, + 0x5c9036c0, 0xd949a01d, 0x814fd360, 0x049645bd, 0xcafa8f00, + 0x4f2319dd, 0x7af669fa, 0xff2fff27, 0x3143359a, 0xb49aa347, + 0xec9cd03a, 0x694546e7, 0xa7298c5a, 0x22f01a87, 0xcd836d14, + 0x485afbc9, 0x86363174, 0x03efa7a9, 0x5be9d4d4, 0xde304209, + 0x105c88b4, 0x95851e69, 0xa0506e4e, 0x2589f893, 0xebe5322e, + 0x6e3ca4f3, 0x363ad78e, 0xb3e34153, 0x7d8f8bee, 0xf8561d33, + 0xe26e1413, 0x67b782ce, 0xa9db4873, 0x2c02deae, 0x7404add3, + 0xf1dd3b0e, 0x3fb1f1b3, 0xba68676e, 0x8fbd1749, 0x0a648194, + 0xc4084b29, 0x41d1ddf4, 0x19d7ae89, 0x9c0e3854, 0x5262f2e9, + 0xd7bb6434, 0x38c813a7, 0xbd11857a, 0x737d4fc7, 0xf6a4d91a, + 0xaea2aa67, 0x2b7b3cba, 0xe517f607, 0x60ce60da, 0x551b10fd, + 0xd0c28620, 0x1eae4c9d, 0x9b77da40, 0xc371a93d, 0x46a83fe0, + 0x88c4f55d, 0x0d1d6380, 0xbcb4e71d, 0x396d71c0, 0xf701bb7d, + 0x72d82da0, 0x2ade5edd, 0xaf07c800, 0x616b02bd, 0xe4b29460, + 0xd167e447, 0x54be729a, 0x9ad2b827, 0x1f0b2efa, 0x470d5d87, + 0xc2d4cb5a, 0x0cb801e7, 0x8961973a, 0x6612e0a9, 0xe3cb7674, + 0x2da7bcc9, 0xa87e2a14, 0xf0785969, 0x75a1cfb4, 0xbbcd0509, + 0x3e1493d4, 0x0bc1e3f3, 0x8e18752e, 0x4074bf93, 0xc5ad294e, + 0x9dab5a33, 0x1872ccee, 0xd61e0653, 0x53c7908e, 0x49ff99ae, + 0xcc260f73, 0x024ac5ce, 0x87935313, 0xdf95206e, 0x5a4cb6b3, + 0x94207c0e, 0x11f9ead3, 0x242c9af4, 0xa1f50c29, 0x6f99c694, + 0xea405049, 0xb2462334, 0x379fb5e9, 0xf9f37f54, 0x7c2ae989, + 0x93599e1a, 0x168008c7, 0xd8ecc27a, 0x5d3554a7, 0x053327da, + 0x80eab107, 0x4e867bba, 0xcb5fed67, 0xfe8a9d40, 0x7b530b9d, + 0xb53fc120, 0x30e657fd, 0x68e02480, 0xed39b25d, 0x235578e0, + 0xa68cee3d}, + {0x00000000, 0x76e10f9d, 0xadc46ee1, 0xdb25617c, 0x1b8fac19, + 0x6d6ea384, 0xb64bc2f8, 0xc0aacd65, 0x361e5933, 0x40ff56ae, + 0x9bda37d2, 0xed3b384f, 0x2d91f52a, 0x5b70fab7, 0x80559bcb, + 0xf6b49456, 0x6c3cb266, 0x1addbdfb, 0xc1f8dc87, 0xb719d31a, + 0x77b31e7f, 0x015211e2, 0xda77709e, 0xac967f03, 0x5a22eb55, + 0x2cc3e4c8, 0xf7e685b4, 0x81078a29, 0x41ad474c, 0x374c48d1, + 0xec6929ad, 0x9a882630, 0xd87864cd, 0xae996b50, 0x75bc0a2c, + 0x035d05b1, 0xc3f7c8d4, 0xb516c749, 0x6e33a635, 0x18d2a9a8, + 0xee663dfe, 0x98873263, 0x43a2531f, 0x35435c82, 0xf5e991e7, + 0x83089e7a, 0x582dff06, 0x2eccf09b, 0xb444d6ab, 0xc2a5d936, + 0x1980b84a, 0x6f61b7d7, 0xafcb7ab2, 0xd92a752f, 0x020f1453, + 0x74ee1bce, 0x825a8f98, 0xf4bb8005, 0x2f9ee179, 0x597feee4, + 0x99d52381, 0xef342c1c, 0x34114d60, 0x42f042fd, 0xf1f7b941, + 0x8716b6dc, 0x5c33d7a0, 0x2ad2d83d, 0xea781558, 0x9c991ac5, + 0x47bc7bb9, 0x315d7424, 0xc7e9e072, 0xb108efef, 0x6a2d8e93, + 0x1ccc810e, 0xdc664c6b, 0xaa8743f6, 0x71a2228a, 0x07432d17, + 0x9dcb0b27, 0xeb2a04ba, 0x300f65c6, 0x46ee6a5b, 0x8644a73e, + 0xf0a5a8a3, 0x2b80c9df, 0x5d61c642, 0xabd55214, 0xdd345d89, + 0x06113cf5, 0x70f03368, 0xb05afe0d, 0xc6bbf190, 0x1d9e90ec, + 0x6b7f9f71, 0x298fdd8c, 0x5f6ed211, 0x844bb36d, 0xf2aabcf0, + 0x32007195, 0x44e17e08, 0x9fc41f74, 0xe92510e9, 0x1f9184bf, + 0x69708b22, 0xb255ea5e, 0xc4b4e5c3, 0x041e28a6, 0x72ff273b, + 0xa9da4647, 0xdf3b49da, 0x45b36fea, 0x33526077, 0xe877010b, + 0x9e960e96, 0x5e3cc3f3, 0x28ddcc6e, 0xf3f8ad12, 0x8519a28f, + 0x73ad36d9, 0x054c3944, 0xde695838, 0xa88857a5, 0x68229ac0, + 0x1ec3955d, 0xc5e6f421, 0xb307fbbc, 0xe2ef7383, 0x940e7c1e, + 0x4f2b1d62, 0x39ca12ff, 0xf960df9a, 0x8f81d007, 0x54a4b17b, + 0x2245bee6, 0xd4f12ab0, 0xa210252d, 0x79354451, 0x0fd44bcc, + 0xcf7e86a9, 0xb99f8934, 0x62bae848, 0x145be7d5, 0x8ed3c1e5, + 0xf832ce78, 0x2317af04, 0x55f6a099, 0x955c6dfc, 0xe3bd6261, + 0x3898031d, 0x4e790c80, 0xb8cd98d6, 0xce2c974b, 0x1509f637, + 0x63e8f9aa, 0xa34234cf, 0xd5a33b52, 0x0e865a2e, 0x786755b3, + 0x3a97174e, 0x4c7618d3, 0x975379af, 0xe1b27632, 0x2118bb57, + 0x57f9b4ca, 0x8cdcd5b6, 0xfa3dda2b, 0x0c894e7d, 0x7a6841e0, + 0xa14d209c, 0xd7ac2f01, 0x1706e264, 0x61e7edf9, 0xbac28c85, + 0xcc238318, 0x56aba528, 0x204aaab5, 0xfb6fcbc9, 0x8d8ec454, + 0x4d240931, 0x3bc506ac, 0xe0e067d0, 0x9601684d, 0x60b5fc1b, + 0x1654f386, 0xcd7192fa, 0xbb909d67, 0x7b3a5002, 0x0ddb5f9f, + 0xd6fe3ee3, 0xa01f317e, 0x1318cac2, 0x65f9c55f, 0xbedca423, + 0xc83dabbe, 0x089766db, 0x7e766946, 0xa553083a, 0xd3b207a7, + 0x250693f1, 0x53e79c6c, 0x88c2fd10, 0xfe23f28d, 0x3e893fe8, + 0x48683075, 0x934d5109, 0xe5ac5e94, 0x7f2478a4, 0x09c57739, + 0xd2e01645, 0xa40119d8, 0x64abd4bd, 0x124adb20, 0xc96fba5c, + 0xbf8eb5c1, 0x493a2197, 0x3fdb2e0a, 0xe4fe4f76, 0x921f40eb, + 0x52b58d8e, 0x24548213, 0xff71e36f, 0x8990ecf2, 0xcb60ae0f, + 0xbd81a192, 0x66a4c0ee, 0x1045cf73, 0xd0ef0216, 0xa60e0d8b, + 0x7d2b6cf7, 0x0bca636a, 0xfd7ef73c, 0x8b9ff8a1, 0x50ba99dd, + 0x265b9640, 0xe6f15b25, 0x901054b8, 0x4b3535c4, 0x3dd43a59, + 0xa75c1c69, 0xd1bd13f4, 0x0a987288, 0x7c797d15, 0xbcd3b070, + 0xca32bfed, 0x1117de91, 0x67f6d10c, 0x9142455a, 0xe7a34ac7, + 0x3c862bbb, 0x4a672426, 0x8acde943, 0xfc2ce6de, 0x270987a2, + 0x51e8883f}, + {0x00000000, 0xe8dbfbb9, 0x91b186a8, 0x796a7d11, 0x63657c8a, + 0x8bbe8733, 0xf2d4fa22, 0x1a0f019b, 0x87cc89cf, 0x6f177276, + 0x167d0f67, 0xfea6f4de, 0xe4a9f545, 0x0c720efc, 0x751873ed, + 0x9dc38854, 0x4f9f6244, 0xa74499fd, 0xde2ee4ec, 0x36f51f55, + 0x2cfa1ece, 0xc421e577, 0xbd4b9866, 0x559063df, 0xc853eb8b, + 0x20881032, 0x59e26d23, 0xb139969a, 0xab369701, 0x43ed6cb8, + 0x3a8711a9, 0xd25cea10, 0x9e3ec588, 0x76e53e31, 0x0f8f4320, + 0xe754b899, 0xfd5bb902, 0x158042bb, 0x6cea3faa, 0x8431c413, + 0x19f24c47, 0xf129b7fe, 0x8843caef, 0x60983156, 0x7a9730cd, + 0x924ccb74, 0xeb26b665, 0x03fd4ddc, 0xd1a1a7cc, 0x397a5c75, + 0x40102164, 0xa8cbdadd, 0xb2c4db46, 0x5a1f20ff, 0x23755dee, + 0xcbaea657, 0x566d2e03, 0xbeb6d5ba, 0xc7dca8ab, 0x2f075312, + 0x35085289, 0xddd3a930, 0xa4b9d421, 0x4c622f98, 0x7d7bfbca, + 0x95a00073, 0xecca7d62, 0x041186db, 0x1e1e8740, 0xf6c57cf9, + 0x8faf01e8, 0x6774fa51, 0xfab77205, 0x126c89bc, 0x6b06f4ad, + 0x83dd0f14, 0x99d20e8f, 0x7109f536, 0x08638827, 0xe0b8739e, + 0x32e4998e, 0xda3f6237, 0xa3551f26, 0x4b8ee49f, 0x5181e504, + 0xb95a1ebd, 0xc03063ac, 0x28eb9815, 0xb5281041, 0x5df3ebf8, + 0x249996e9, 0xcc426d50, 0xd64d6ccb, 0x3e969772, 0x47fcea63, + 0xaf2711da, 0xe3453e42, 0x0b9ec5fb, 0x72f4b8ea, 0x9a2f4353, + 0x802042c8, 0x68fbb971, 0x1191c460, 0xf94a3fd9, 0x6489b78d, + 0x8c524c34, 0xf5383125, 0x1de3ca9c, 0x07eccb07, 0xef3730be, + 0x965d4daf, 0x7e86b616, 0xacda5c06, 0x4401a7bf, 0x3d6bdaae, + 0xd5b02117, 0xcfbf208c, 0x2764db35, 0x5e0ea624, 0xb6d55d9d, + 0x2b16d5c9, 0xc3cd2e70, 0xbaa75361, 0x527ca8d8, 0x4873a943, + 0xa0a852fa, 0xd9c22feb, 0x3119d452, 0xbbf0874e, 0x532b7cf7, + 0x2a4101e6, 0xc29afa5f, 0xd895fbc4, 0x304e007d, 0x49247d6c, + 0xa1ff86d5, 0x3c3c0e81, 0xd4e7f538, 0xad8d8829, 0x45567390, + 0x5f59720b, 0xb78289b2, 0xcee8f4a3, 0x26330f1a, 0xf46fe50a, + 0x1cb41eb3, 0x65de63a2, 0x8d05981b, 0x970a9980, 0x7fd16239, + 0x06bb1f28, 0xee60e491, 0x73a36cc5, 0x9b78977c, 0xe212ea6d, + 0x0ac911d4, 0x10c6104f, 0xf81debf6, 0x817796e7, 0x69ac6d5e, + 0x25ce42c6, 0xcd15b97f, 0xb47fc46e, 0x5ca43fd7, 0x46ab3e4c, + 0xae70c5f5, 0xd71ab8e4, 0x3fc1435d, 0xa202cb09, 0x4ad930b0, + 0x33b34da1, 0xdb68b618, 0xc167b783, 0x29bc4c3a, 0x50d6312b, + 0xb80dca92, 0x6a512082, 0x828adb3b, 0xfbe0a62a, 0x133b5d93, + 0x09345c08, 0xe1efa7b1, 0x9885daa0, 0x705e2119, 0xed9da94d, + 0x054652f4, 0x7c2c2fe5, 0x94f7d45c, 0x8ef8d5c7, 0x66232e7e, + 0x1f49536f, 0xf792a8d6, 0xc68b7c84, 0x2e50873d, 0x573afa2c, + 0xbfe10195, 0xa5ee000e, 0x4d35fbb7, 0x345f86a6, 0xdc847d1f, + 0x4147f54b, 0xa99c0ef2, 0xd0f673e3, 0x382d885a, 0x222289c1, + 0xcaf97278, 0xb3930f69, 0x5b48f4d0, 0x89141ec0, 0x61cfe579, + 0x18a59868, 0xf07e63d1, 0xea71624a, 0x02aa99f3, 0x7bc0e4e2, + 0x931b1f5b, 0x0ed8970f, 0xe6036cb6, 0x9f6911a7, 0x77b2ea1e, + 0x6dbdeb85, 0x8566103c, 0xfc0c6d2d, 0x14d79694, 0x58b5b90c, + 0xb06e42b5, 0xc9043fa4, 0x21dfc41d, 0x3bd0c586, 0xd30b3e3f, + 0xaa61432e, 0x42bab897, 0xdf7930c3, 0x37a2cb7a, 0x4ec8b66b, + 0xa6134dd2, 0xbc1c4c49, 0x54c7b7f0, 0x2dadcae1, 0xc5763158, + 0x172adb48, 0xfff120f1, 0x869b5de0, 0x6e40a659, 0x744fa7c2, + 0x9c945c7b, 0xe5fe216a, 0x0d25dad3, 0x90e65287, 0x783da93e, + 0x0157d42f, 0xe98c2f96, 0xf3832e0d, 0x1b58d5b4, 0x6232a8a5, + 0x8ae9531c}, + {0x00000000, 0x919168ae, 0x6325a087, 0xf2b4c829, 0x874c31d4, + 0x16dd597a, 0xe4699153, 0x75f8f9fd, 0x4f9f1373, 0xde0e7bdd, + 0x2cbab3f4, 0xbd2bdb5a, 0xc8d322a7, 0x59424a09, 0xabf68220, + 0x3a67ea8e, 0x9e3e27e6, 0x0faf4f48, 0xfd1b8761, 0x6c8aefcf, + 0x19721632, 0x88e37e9c, 0x7a57b6b5, 0xebc6de1b, 0xd1a13495, + 0x40305c3b, 0xb2849412, 0x2315fcbc, 0x56ed0541, 0xc77c6def, + 0x35c8a5c6, 0xa459cd68, 0x7d7b3f17, 0xecea57b9, 0x1e5e9f90, + 0x8fcff73e, 0xfa370ec3, 0x6ba6666d, 0x9912ae44, 0x0883c6ea, + 0x32e42c64, 0xa37544ca, 0x51c18ce3, 0xc050e44d, 0xb5a81db0, + 0x2439751e, 0xd68dbd37, 0x471cd599, 0xe34518f1, 0x72d4705f, + 0x8060b876, 0x11f1d0d8, 0x64092925, 0xf598418b, 0x072c89a2, + 0x96bde10c, 0xacda0b82, 0x3d4b632c, 0xcfffab05, 0x5e6ec3ab, + 0x2b963a56, 0xba0752f8, 0x48b39ad1, 0xd922f27f, 0xfaf67e2e, + 0x6b671680, 0x99d3dea9, 0x0842b607, 0x7dba4ffa, 0xec2b2754, + 0x1e9fef7d, 0x8f0e87d3, 0xb5696d5d, 0x24f805f3, 0xd64ccdda, + 0x47dda574, 0x32255c89, 0xa3b43427, 0x5100fc0e, 0xc09194a0, + 0x64c859c8, 0xf5593166, 0x07edf94f, 0x967c91e1, 0xe384681c, + 0x721500b2, 0x80a1c89b, 0x1130a035, 0x2b574abb, 0xbac62215, + 0x4872ea3c, 0xd9e38292, 0xac1b7b6f, 0x3d8a13c1, 0xcf3edbe8, + 0x5eafb346, 0x878d4139, 0x161c2997, 0xe4a8e1be, 0x75398910, + 0x00c170ed, 0x91501843, 0x63e4d06a, 0xf275b8c4, 0xc812524a, + 0x59833ae4, 0xab37f2cd, 0x3aa69a63, 0x4f5e639e, 0xdecf0b30, + 0x2c7bc319, 0xbdeaabb7, 0x19b366df, 0x88220e71, 0x7a96c658, + 0xeb07aef6, 0x9eff570b, 0x0f6e3fa5, 0xfddaf78c, 0x6c4b9f22, + 0x562c75ac, 0xc7bd1d02, 0x3509d52b, 0xa498bd85, 0xd1604478, + 0x40f12cd6, 0xb245e4ff, 0x23d48c51, 0xf4edfd5c, 0x657c95f2, + 0x97c85ddb, 0x06593575, 0x73a1cc88, 0xe230a426, 0x10846c0f, + 0x811504a1, 0xbb72ee2f, 0x2ae38681, 0xd8574ea8, 0x49c62606, + 0x3c3edffb, 0xadafb755, 0x5f1b7f7c, 0xce8a17d2, 0x6ad3daba, + 0xfb42b214, 0x09f67a3d, 0x98671293, 0xed9feb6e, 0x7c0e83c0, + 0x8eba4be9, 0x1f2b2347, 0x254cc9c9, 0xb4dda167, 0x4669694e, + 0xd7f801e0, 0xa200f81d, 0x339190b3, 0xc125589a, 0x50b43034, + 0x8996c24b, 0x1807aae5, 0xeab362cc, 0x7b220a62, 0x0edaf39f, + 0x9f4b9b31, 0x6dff5318, 0xfc6e3bb6, 0xc609d138, 0x5798b996, + 0xa52c71bf, 0x34bd1911, 0x4145e0ec, 0xd0d48842, 0x2260406b, + 0xb3f128c5, 0x17a8e5ad, 0x86398d03, 0x748d452a, 0xe51c2d84, + 0x90e4d479, 0x0175bcd7, 0xf3c174fe, 0x62501c50, 0x5837f6de, + 0xc9a69e70, 0x3b125659, 0xaa833ef7, 0xdf7bc70a, 0x4eeaafa4, + 0xbc5e678d, 0x2dcf0f23, 0x0e1b8372, 0x9f8aebdc, 0x6d3e23f5, + 0xfcaf4b5b, 0x8957b2a6, 0x18c6da08, 0xea721221, 0x7be37a8f, + 0x41849001, 0xd015f8af, 0x22a13086, 0xb3305828, 0xc6c8a1d5, + 0x5759c97b, 0xa5ed0152, 0x347c69fc, 0x9025a494, 0x01b4cc3a, + 0xf3000413, 0x62916cbd, 0x17699540, 0x86f8fdee, 0x744c35c7, + 0xe5dd5d69, 0xdfbab7e7, 0x4e2bdf49, 0xbc9f1760, 0x2d0e7fce, + 0x58f68633, 0xc967ee9d, 0x3bd326b4, 0xaa424e1a, 0x7360bc65, + 0xe2f1d4cb, 0x10451ce2, 0x81d4744c, 0xf42c8db1, 0x65bde51f, + 0x97092d36, 0x06984598, 0x3cffaf16, 0xad6ec7b8, 0x5fda0f91, + 0xce4b673f, 0xbbb39ec2, 0x2a22f66c, 0xd8963e45, 0x490756eb, + 0xed5e9b83, 0x7ccff32d, 0x8e7b3b04, 0x1fea53aa, 0x6a12aa57, + 0xfb83c2f9, 0x09370ad0, 0x98a6627e, 0xa2c188f0, 0x3350e05e, + 0xc1e42877, 0x507540d9, 0x258db924, 0xb41cd18a, 0x46a819a3, + 0xd739710d}}; + +#endif + +#endif + +#if N == 5 + +#if W == 8 + +local const z_crc_t FAR crc_braid_table[][256] = { + {0x00000000, 0xaf449247, 0x85f822cf, 0x2abcb088, 0xd08143df, + 0x7fc5d198, 0x55796110, 0xfa3df357, 0x7a7381ff, 0xd53713b8, + 0xff8ba330, 0x50cf3177, 0xaaf2c220, 0x05b65067, 0x2f0ae0ef, + 0x804e72a8, 0xf4e703fe, 0x5ba391b9, 0x711f2131, 0xde5bb376, + 0x24664021, 0x8b22d266, 0xa19e62ee, 0x0edaf0a9, 0x8e948201, + 0x21d01046, 0x0b6ca0ce, 0xa4283289, 0x5e15c1de, 0xf1515399, + 0xdbede311, 0x74a97156, 0x32bf01bd, 0x9dfb93fa, 0xb7472372, + 0x1803b135, 0xe23e4262, 0x4d7ad025, 0x67c660ad, 0xc882f2ea, + 0x48cc8042, 0xe7881205, 0xcd34a28d, 0x627030ca, 0x984dc39d, + 0x370951da, 0x1db5e152, 0xb2f17315, 0xc6580243, 0x691c9004, + 0x43a0208c, 0xece4b2cb, 0x16d9419c, 0xb99dd3db, 0x93216353, + 0x3c65f114, 0xbc2b83bc, 0x136f11fb, 0x39d3a173, 0x96973334, + 0x6caac063, 0xc3ee5224, 0xe952e2ac, 0x461670eb, 0x657e037a, + 0xca3a913d, 0xe08621b5, 0x4fc2b3f2, 0xb5ff40a5, 0x1abbd2e2, + 0x3007626a, 0x9f43f02d, 0x1f0d8285, 0xb04910c2, 0x9af5a04a, + 0x35b1320d, 0xcf8cc15a, 0x60c8531d, 0x4a74e395, 0xe53071d2, + 0x91990084, 0x3edd92c3, 0x1461224b, 0xbb25b00c, 0x4118435b, + 0xee5cd11c, 0xc4e06194, 0x6ba4f3d3, 0xebea817b, 0x44ae133c, + 0x6e12a3b4, 0xc15631f3, 0x3b6bc2a4, 0x942f50e3, 0xbe93e06b, + 0x11d7722c, 0x57c102c7, 0xf8859080, 0xd2392008, 0x7d7db24f, + 0x87404118, 0x2804d35f, 0x02b863d7, 0xadfcf190, 0x2db28338, + 0x82f6117f, 0xa84aa1f7, 0x070e33b0, 0xfd33c0e7, 0x527752a0, + 0x78cbe228, 0xd78f706f, 0xa3260139, 0x0c62937e, 0x26de23f6, + 0x899ab1b1, 0x73a742e6, 0xdce3d0a1, 0xf65f6029, 0x591bf26e, + 0xd95580c6, 0x76111281, 0x5cada209, 0xf3e9304e, 0x09d4c319, + 0xa690515e, 0x8c2ce1d6, 0x23687391, 0xcafc06f4, 0x65b894b3, + 0x4f04243b, 0xe040b67c, 0x1a7d452b, 0xb539d76c, 0x9f8567e4, + 0x30c1f5a3, 0xb08f870b, 0x1fcb154c, 0x3577a5c4, 0x9a333783, + 0x600ec4d4, 0xcf4a5693, 0xe5f6e61b, 0x4ab2745c, 0x3e1b050a, + 0x915f974d, 0xbbe327c5, 0x14a7b582, 0xee9a46d5, 0x41ded492, + 0x6b62641a, 0xc426f65d, 0x446884f5, 0xeb2c16b2, 0xc190a63a, + 0x6ed4347d, 0x94e9c72a, 0x3bad556d, 0x1111e5e5, 0xbe5577a2, + 0xf8430749, 0x5707950e, 0x7dbb2586, 0xd2ffb7c1, 0x28c24496, + 0x8786d6d1, 0xad3a6659, 0x027ef41e, 0x823086b6, 0x2d7414f1, + 0x07c8a479, 0xa88c363e, 0x52b1c569, 0xfdf5572e, 0xd749e7a6, + 0x780d75e1, 0x0ca404b7, 0xa3e096f0, 0x895c2678, 0x2618b43f, + 0xdc254768, 0x7361d52f, 0x59dd65a7, 0xf699f7e0, 0x76d78548, + 0xd993170f, 0xf32fa787, 0x5c6b35c0, 0xa656c697, 0x091254d0, + 0x23aee458, 0x8cea761f, 0xaf82058e, 0x00c697c9, 0x2a7a2741, + 0x853eb506, 0x7f034651, 0xd047d416, 0xfafb649e, 0x55bff6d9, + 0xd5f18471, 0x7ab51636, 0x5009a6be, 0xff4d34f9, 0x0570c7ae, + 0xaa3455e9, 0x8088e561, 0x2fcc7726, 0x5b650670, 0xf4219437, + 0xde9d24bf, 0x71d9b6f8, 0x8be445af, 0x24a0d7e8, 0x0e1c6760, + 0xa158f527, 0x2116878f, 0x8e5215c8, 0xa4eea540, 0x0baa3707, + 0xf197c450, 0x5ed35617, 0x746fe69f, 0xdb2b74d8, 0x9d3d0433, + 0x32799674, 0x18c526fc, 0xb781b4bb, 0x4dbc47ec, 0xe2f8d5ab, + 0xc8446523, 0x6700f764, 0xe74e85cc, 0x480a178b, 0x62b6a703, + 0xcdf23544, 0x37cfc613, 0x988b5454, 0xb237e4dc, 0x1d73769b, + 0x69da07cd, 0xc69e958a, 0xec222502, 0x4366b745, 0xb95b4412, + 0x161fd655, 0x3ca366dd, 0x93e7f49a, 0x13a98632, 0xbced1475, + 0x9651a4fd, 0x391536ba, 0xc328c5ed, 0x6c6c57aa, 0x46d0e722, + 0xe9947565}, + {0x00000000, 0x4e890ba9, 0x9d121752, 0xd39b1cfb, 0xe15528e5, + 0xafdc234c, 0x7c473fb7, 0x32ce341e, 0x19db578b, 0x57525c22, + 0x84c940d9, 0xca404b70, 0xf88e7f6e, 0xb60774c7, 0x659c683c, + 0x2b156395, 0x33b6af16, 0x7d3fa4bf, 0xaea4b844, 0xe02db3ed, + 0xd2e387f3, 0x9c6a8c5a, 0x4ff190a1, 0x01789b08, 0x2a6df89d, + 0x64e4f334, 0xb77fefcf, 0xf9f6e466, 0xcb38d078, 0x85b1dbd1, + 0x562ac72a, 0x18a3cc83, 0x676d5e2c, 0x29e45585, 0xfa7f497e, + 0xb4f642d7, 0x863876c9, 0xc8b17d60, 0x1b2a619b, 0x55a36a32, + 0x7eb609a7, 0x303f020e, 0xe3a41ef5, 0xad2d155c, 0x9fe32142, + 0xd16a2aeb, 0x02f13610, 0x4c783db9, 0x54dbf13a, 0x1a52fa93, + 0xc9c9e668, 0x8740edc1, 0xb58ed9df, 0xfb07d276, 0x289cce8d, + 0x6615c524, 0x4d00a6b1, 0x0389ad18, 0xd012b1e3, 0x9e9bba4a, + 0xac558e54, 0xe2dc85fd, 0x31479906, 0x7fce92af, 0xcedabc58, + 0x8053b7f1, 0x53c8ab0a, 0x1d41a0a3, 0x2f8f94bd, 0x61069f14, + 0xb29d83ef, 0xfc148846, 0xd701ebd3, 0x9988e07a, 0x4a13fc81, + 0x049af728, 0x3654c336, 0x78ddc89f, 0xab46d464, 0xe5cfdfcd, + 0xfd6c134e, 0xb3e518e7, 0x607e041c, 0x2ef70fb5, 0x1c393bab, + 0x52b03002, 0x812b2cf9, 0xcfa22750, 0xe4b744c5, 0xaa3e4f6c, + 0x79a55397, 0x372c583e, 0x05e26c20, 0x4b6b6789, 0x98f07b72, + 0xd67970db, 0xa9b7e274, 0xe73ee9dd, 0x34a5f526, 0x7a2cfe8f, + 0x48e2ca91, 0x066bc138, 0xd5f0ddc3, 0x9b79d66a, 0xb06cb5ff, + 0xfee5be56, 0x2d7ea2ad, 0x63f7a904, 0x51399d1a, 0x1fb096b3, + 0xcc2b8a48, 0x82a281e1, 0x9a014d62, 0xd48846cb, 0x07135a30, + 0x499a5199, 0x7b546587, 0x35dd6e2e, 0xe64672d5, 0xa8cf797c, + 0x83da1ae9, 0xcd531140, 0x1ec80dbb, 0x50410612, 0x628f320c, + 0x2c0639a5, 0xff9d255e, 0xb1142ef7, 0x46c47ef1, 0x084d7558, + 0xdbd669a3, 0x955f620a, 0xa7915614, 0xe9185dbd, 0x3a834146, + 0x740a4aef, 0x5f1f297a, 0x119622d3, 0xc20d3e28, 0x8c843581, + 0xbe4a019f, 0xf0c30a36, 0x235816cd, 0x6dd11d64, 0x7572d1e7, + 0x3bfbda4e, 0xe860c6b5, 0xa6e9cd1c, 0x9427f902, 0xdaaef2ab, + 0x0935ee50, 0x47bce5f9, 0x6ca9866c, 0x22208dc5, 0xf1bb913e, + 0xbf329a97, 0x8dfcae89, 0xc375a520, 0x10eeb9db, 0x5e67b272, + 0x21a920dd, 0x6f202b74, 0xbcbb378f, 0xf2323c26, 0xc0fc0838, + 0x8e750391, 0x5dee1f6a, 0x136714c3, 0x38727756, 0x76fb7cff, + 0xa5606004, 0xebe96bad, 0xd9275fb3, 0x97ae541a, 0x443548e1, + 0x0abc4348, 0x121f8fcb, 0x5c968462, 0x8f0d9899, 0xc1849330, + 0xf34aa72e, 0xbdc3ac87, 0x6e58b07c, 0x20d1bbd5, 0x0bc4d840, + 0x454dd3e9, 0x96d6cf12, 0xd85fc4bb, 0xea91f0a5, 0xa418fb0c, + 0x7783e7f7, 0x390aec5e, 0x881ec2a9, 0xc697c900, 0x150cd5fb, + 0x5b85de52, 0x694bea4c, 0x27c2e1e5, 0xf459fd1e, 0xbad0f6b7, + 0x91c59522, 0xdf4c9e8b, 0x0cd78270, 0x425e89d9, 0x7090bdc7, + 0x3e19b66e, 0xed82aa95, 0xa30ba13c, 0xbba86dbf, 0xf5216616, + 0x26ba7aed, 0x68337144, 0x5afd455a, 0x14744ef3, 0xc7ef5208, + 0x896659a1, 0xa2733a34, 0xecfa319d, 0x3f612d66, 0x71e826cf, + 0x432612d1, 0x0daf1978, 0xde340583, 0x90bd0e2a, 0xef739c85, + 0xa1fa972c, 0x72618bd7, 0x3ce8807e, 0x0e26b460, 0x40afbfc9, + 0x9334a332, 0xddbda89b, 0xf6a8cb0e, 0xb821c0a7, 0x6bbadc5c, + 0x2533d7f5, 0x17fde3eb, 0x5974e842, 0x8aeff4b9, 0xc466ff10, + 0xdcc53393, 0x924c383a, 0x41d724c1, 0x0f5e2f68, 0x3d901b76, + 0x731910df, 0xa0820c24, 0xee0b078d, 0xc51e6418, 0x8b976fb1, + 0x580c734a, 0x168578e3, 0x244b4cfd, 0x6ac24754, 0xb9595baf, + 0xf7d05006}, + {0x00000000, 0x8d88fde2, 0xc060fd85, 0x4de80067, 0x5bb0fd4b, + 0xd63800a9, 0x9bd000ce, 0x1658fd2c, 0xb761fa96, 0x3ae90774, + 0x77010713, 0xfa89faf1, 0xecd107dd, 0x6159fa3f, 0x2cb1fa58, + 0xa13907ba, 0xb5b2f36d, 0x383a0e8f, 0x75d20ee8, 0xf85af30a, + 0xee020e26, 0x638af3c4, 0x2e62f3a3, 0xa3ea0e41, 0x02d309fb, + 0x8f5bf419, 0xc2b3f47e, 0x4f3b099c, 0x5963f4b0, 0xd4eb0952, + 0x99030935, 0x148bf4d7, 0xb014e09b, 0x3d9c1d79, 0x70741d1e, + 0xfdfce0fc, 0xeba41dd0, 0x662ce032, 0x2bc4e055, 0xa64c1db7, + 0x07751a0d, 0x8afde7ef, 0xc715e788, 0x4a9d1a6a, 0x5cc5e746, + 0xd14d1aa4, 0x9ca51ac3, 0x112de721, 0x05a613f6, 0x882eee14, + 0xc5c6ee73, 0x484e1391, 0x5e16eebd, 0xd39e135f, 0x9e761338, + 0x13feeeda, 0xb2c7e960, 0x3f4f1482, 0x72a714e5, 0xff2fe907, + 0xe977142b, 0x64ffe9c9, 0x2917e9ae, 0xa49f144c, 0xbb58c777, + 0x36d03a95, 0x7b383af2, 0xf6b0c710, 0xe0e83a3c, 0x6d60c7de, + 0x2088c7b9, 0xad003a5b, 0x0c393de1, 0x81b1c003, 0xcc59c064, + 0x41d13d86, 0x5789c0aa, 0xda013d48, 0x97e93d2f, 0x1a61c0cd, + 0x0eea341a, 0x8362c9f8, 0xce8ac99f, 0x4302347d, 0x555ac951, + 0xd8d234b3, 0x953a34d4, 0x18b2c936, 0xb98bce8c, 0x3403336e, + 0x79eb3309, 0xf463ceeb, 0xe23b33c7, 0x6fb3ce25, 0x225bce42, + 0xafd333a0, 0x0b4c27ec, 0x86c4da0e, 0xcb2cda69, 0x46a4278b, + 0x50fcdaa7, 0xdd742745, 0x909c2722, 0x1d14dac0, 0xbc2ddd7a, + 0x31a52098, 0x7c4d20ff, 0xf1c5dd1d, 0xe79d2031, 0x6a15ddd3, + 0x27fdddb4, 0xaa752056, 0xbefed481, 0x33762963, 0x7e9e2904, + 0xf316d4e6, 0xe54e29ca, 0x68c6d428, 0x252ed44f, 0xa8a629ad, + 0x099f2e17, 0x8417d3f5, 0xc9ffd392, 0x44772e70, 0x522fd35c, + 0xdfa72ebe, 0x924f2ed9, 0x1fc7d33b, 0xadc088af, 0x2048754d, + 0x6da0752a, 0xe02888c8, 0xf67075e4, 0x7bf88806, 0x36108861, + 0xbb987583, 0x1aa17239, 0x97298fdb, 0xdac18fbc, 0x5749725e, + 0x41118f72, 0xcc997290, 0x817172f7, 0x0cf98f15, 0x18727bc2, + 0x95fa8620, 0xd8128647, 0x559a7ba5, 0x43c28689, 0xce4a7b6b, + 0x83a27b0c, 0x0e2a86ee, 0xaf138154, 0x229b7cb6, 0x6f737cd1, + 0xe2fb8133, 0xf4a37c1f, 0x792b81fd, 0x34c3819a, 0xb94b7c78, + 0x1dd46834, 0x905c95d6, 0xddb495b1, 0x503c6853, 0x4664957f, + 0xcbec689d, 0x860468fa, 0x0b8c9518, 0xaab592a2, 0x273d6f40, + 0x6ad56f27, 0xe75d92c5, 0xf1056fe9, 0x7c8d920b, 0x3165926c, + 0xbced6f8e, 0xa8669b59, 0x25ee66bb, 0x680666dc, 0xe58e9b3e, + 0xf3d66612, 0x7e5e9bf0, 0x33b69b97, 0xbe3e6675, 0x1f0761cf, + 0x928f9c2d, 0xdf679c4a, 0x52ef61a8, 0x44b79c84, 0xc93f6166, + 0x84d76101, 0x095f9ce3, 0x16984fd8, 0x9b10b23a, 0xd6f8b25d, + 0x5b704fbf, 0x4d28b293, 0xc0a04f71, 0x8d484f16, 0x00c0b2f4, + 0xa1f9b54e, 0x2c7148ac, 0x619948cb, 0xec11b529, 0xfa494805, + 0x77c1b5e7, 0x3a29b580, 0xb7a14862, 0xa32abcb5, 0x2ea24157, + 0x634a4130, 0xeec2bcd2, 0xf89a41fe, 0x7512bc1c, 0x38fabc7b, + 0xb5724199, 0x144b4623, 0x99c3bbc1, 0xd42bbba6, 0x59a34644, + 0x4ffbbb68, 0xc273468a, 0x8f9b46ed, 0x0213bb0f, 0xa68caf43, + 0x2b0452a1, 0x66ec52c6, 0xeb64af24, 0xfd3c5208, 0x70b4afea, + 0x3d5caf8d, 0xb0d4526f, 0x11ed55d5, 0x9c65a837, 0xd18da850, + 0x5c0555b2, 0x4a5da89e, 0xc7d5557c, 0x8a3d551b, 0x07b5a8f9, + 0x133e5c2e, 0x9eb6a1cc, 0xd35ea1ab, 0x5ed65c49, 0x488ea165, + 0xc5065c87, 0x88ee5ce0, 0x0566a102, 0xa45fa6b8, 0x29d75b5a, + 0x643f5b3d, 0xe9b7a6df, 0xffef5bf3, 0x7267a611, 0x3f8fa676, + 0xb2075b94}, + {0x00000000, 0x80f0171f, 0xda91287f, 0x5a613f60, 0x6e5356bf, + 0xeea341a0, 0xb4c27ec0, 0x343269df, 0xdca6ad7e, 0x5c56ba61, + 0x06378501, 0x86c7921e, 0xb2f5fbc1, 0x3205ecde, 0x6864d3be, + 0xe894c4a1, 0x623c5cbd, 0xe2cc4ba2, 0xb8ad74c2, 0x385d63dd, + 0x0c6f0a02, 0x8c9f1d1d, 0xd6fe227d, 0x560e3562, 0xbe9af1c3, + 0x3e6ae6dc, 0x640bd9bc, 0xe4fbcea3, 0xd0c9a77c, 0x5039b063, + 0x0a588f03, 0x8aa8981c, 0xc478b97a, 0x4488ae65, 0x1ee99105, + 0x9e19861a, 0xaa2befc5, 0x2adbf8da, 0x70bac7ba, 0xf04ad0a5, + 0x18de1404, 0x982e031b, 0xc24f3c7b, 0x42bf2b64, 0x768d42bb, + 0xf67d55a4, 0xac1c6ac4, 0x2cec7ddb, 0xa644e5c7, 0x26b4f2d8, + 0x7cd5cdb8, 0xfc25daa7, 0xc817b378, 0x48e7a467, 0x12869b07, + 0x92768c18, 0x7ae248b9, 0xfa125fa6, 0xa07360c6, 0x208377d9, + 0x14b11e06, 0x94410919, 0xce203679, 0x4ed02166, 0x538074b5, + 0xd37063aa, 0x89115cca, 0x09e14bd5, 0x3dd3220a, 0xbd233515, + 0xe7420a75, 0x67b21d6a, 0x8f26d9cb, 0x0fd6ced4, 0x55b7f1b4, + 0xd547e6ab, 0xe1758f74, 0x6185986b, 0x3be4a70b, 0xbb14b014, + 0x31bc2808, 0xb14c3f17, 0xeb2d0077, 0x6bdd1768, 0x5fef7eb7, + 0xdf1f69a8, 0x857e56c8, 0x058e41d7, 0xed1a8576, 0x6dea9269, + 0x378bad09, 0xb77bba16, 0x8349d3c9, 0x03b9c4d6, 0x59d8fbb6, + 0xd928eca9, 0x97f8cdcf, 0x1708dad0, 0x4d69e5b0, 0xcd99f2af, + 0xf9ab9b70, 0x795b8c6f, 0x233ab30f, 0xa3caa410, 0x4b5e60b1, + 0xcbae77ae, 0x91cf48ce, 0x113f5fd1, 0x250d360e, 0xa5fd2111, + 0xff9c1e71, 0x7f6c096e, 0xf5c49172, 0x7534866d, 0x2f55b90d, + 0xafa5ae12, 0x9b97c7cd, 0x1b67d0d2, 0x4106efb2, 0xc1f6f8ad, + 0x29623c0c, 0xa9922b13, 0xf3f31473, 0x7303036c, 0x47316ab3, + 0xc7c17dac, 0x9da042cc, 0x1d5055d3, 0xa700e96a, 0x27f0fe75, + 0x7d91c115, 0xfd61d60a, 0xc953bfd5, 0x49a3a8ca, 0x13c297aa, + 0x933280b5, 0x7ba64414, 0xfb56530b, 0xa1376c6b, 0x21c77b74, + 0x15f512ab, 0x950505b4, 0xcf643ad4, 0x4f942dcb, 0xc53cb5d7, + 0x45cca2c8, 0x1fad9da8, 0x9f5d8ab7, 0xab6fe368, 0x2b9ff477, + 0x71fecb17, 0xf10edc08, 0x199a18a9, 0x996a0fb6, 0xc30b30d6, + 0x43fb27c9, 0x77c94e16, 0xf7395909, 0xad586669, 0x2da87176, + 0x63785010, 0xe388470f, 0xb9e9786f, 0x39196f70, 0x0d2b06af, + 0x8ddb11b0, 0xd7ba2ed0, 0x574a39cf, 0xbfdefd6e, 0x3f2eea71, + 0x654fd511, 0xe5bfc20e, 0xd18dabd1, 0x517dbcce, 0x0b1c83ae, + 0x8bec94b1, 0x01440cad, 0x81b41bb2, 0xdbd524d2, 0x5b2533cd, + 0x6f175a12, 0xefe74d0d, 0xb586726d, 0x35766572, 0xdde2a1d3, + 0x5d12b6cc, 0x077389ac, 0x87839eb3, 0xb3b1f76c, 0x3341e073, + 0x6920df13, 0xe9d0c80c, 0xf4809ddf, 0x74708ac0, 0x2e11b5a0, + 0xaee1a2bf, 0x9ad3cb60, 0x1a23dc7f, 0x4042e31f, 0xc0b2f400, + 0x282630a1, 0xa8d627be, 0xf2b718de, 0x72470fc1, 0x4675661e, + 0xc6857101, 0x9ce44e61, 0x1c14597e, 0x96bcc162, 0x164cd67d, + 0x4c2de91d, 0xccddfe02, 0xf8ef97dd, 0x781f80c2, 0x227ebfa2, + 0xa28ea8bd, 0x4a1a6c1c, 0xcaea7b03, 0x908b4463, 0x107b537c, + 0x24493aa3, 0xa4b92dbc, 0xfed812dc, 0x7e2805c3, 0x30f824a5, + 0xb00833ba, 0xea690cda, 0x6a991bc5, 0x5eab721a, 0xde5b6505, + 0x843a5a65, 0x04ca4d7a, 0xec5e89db, 0x6cae9ec4, 0x36cfa1a4, + 0xb63fb6bb, 0x820ddf64, 0x02fdc87b, 0x589cf71b, 0xd86ce004, + 0x52c47818, 0xd2346f07, 0x88555067, 0x08a54778, 0x3c972ea7, + 0xbc6739b8, 0xe60606d8, 0x66f611c7, 0x8e62d566, 0x0e92c279, + 0x54f3fd19, 0xd403ea06, 0xe03183d9, 0x60c194c6, 0x3aa0aba6, + 0xba50bcb9}, + {0x00000000, 0x9570d495, 0xf190af6b, 0x64e07bfe, 0x38505897, + 0xad208c02, 0xc9c0f7fc, 0x5cb02369, 0x70a0b12e, 0xe5d065bb, + 0x81301e45, 0x1440cad0, 0x48f0e9b9, 0xdd803d2c, 0xb96046d2, + 0x2c109247, 0xe141625c, 0x7431b6c9, 0x10d1cd37, 0x85a119a2, + 0xd9113acb, 0x4c61ee5e, 0x288195a0, 0xbdf14135, 0x91e1d372, + 0x049107e7, 0x60717c19, 0xf501a88c, 0xa9b18be5, 0x3cc15f70, + 0x5821248e, 0xcd51f01b, 0x19f3c2f9, 0x8c83166c, 0xe8636d92, + 0x7d13b907, 0x21a39a6e, 0xb4d34efb, 0xd0333505, 0x4543e190, + 0x695373d7, 0xfc23a742, 0x98c3dcbc, 0x0db30829, 0x51032b40, + 0xc473ffd5, 0xa093842b, 0x35e350be, 0xf8b2a0a5, 0x6dc27430, + 0x09220fce, 0x9c52db5b, 0xc0e2f832, 0x55922ca7, 0x31725759, + 0xa40283cc, 0x8812118b, 0x1d62c51e, 0x7982bee0, 0xecf26a75, + 0xb042491c, 0x25329d89, 0x41d2e677, 0xd4a232e2, 0x33e785f2, + 0xa6975167, 0xc2772a99, 0x5707fe0c, 0x0bb7dd65, 0x9ec709f0, + 0xfa27720e, 0x6f57a69b, 0x434734dc, 0xd637e049, 0xb2d79bb7, + 0x27a74f22, 0x7b176c4b, 0xee67b8de, 0x8a87c320, 0x1ff717b5, + 0xd2a6e7ae, 0x47d6333b, 0x233648c5, 0xb6469c50, 0xeaf6bf39, + 0x7f866bac, 0x1b661052, 0x8e16c4c7, 0xa2065680, 0x37768215, + 0x5396f9eb, 0xc6e62d7e, 0x9a560e17, 0x0f26da82, 0x6bc6a17c, + 0xfeb675e9, 0x2a14470b, 0xbf64939e, 0xdb84e860, 0x4ef43cf5, + 0x12441f9c, 0x8734cb09, 0xe3d4b0f7, 0x76a46462, 0x5ab4f625, + 0xcfc422b0, 0xab24594e, 0x3e548ddb, 0x62e4aeb2, 0xf7947a27, + 0x937401d9, 0x0604d54c, 0xcb552557, 0x5e25f1c2, 0x3ac58a3c, + 0xafb55ea9, 0xf3057dc0, 0x6675a955, 0x0295d2ab, 0x97e5063e, + 0xbbf59479, 0x2e8540ec, 0x4a653b12, 0xdf15ef87, 0x83a5ccee, + 0x16d5187b, 0x72356385, 0xe745b710, 0x67cf0be4, 0xf2bfdf71, + 0x965fa48f, 0x032f701a, 0x5f9f5373, 0xcaef87e6, 0xae0ffc18, + 0x3b7f288d, 0x176fbaca, 0x821f6e5f, 0xe6ff15a1, 0x738fc134, + 0x2f3fe25d, 0xba4f36c8, 0xdeaf4d36, 0x4bdf99a3, 0x868e69b8, + 0x13febd2d, 0x771ec6d3, 0xe26e1246, 0xbede312f, 0x2baee5ba, + 0x4f4e9e44, 0xda3e4ad1, 0xf62ed896, 0x635e0c03, 0x07be77fd, + 0x92cea368, 0xce7e8001, 0x5b0e5494, 0x3fee2f6a, 0xaa9efbff, + 0x7e3cc91d, 0xeb4c1d88, 0x8fac6676, 0x1adcb2e3, 0x466c918a, + 0xd31c451f, 0xb7fc3ee1, 0x228cea74, 0x0e9c7833, 0x9becaca6, + 0xff0cd758, 0x6a7c03cd, 0x36cc20a4, 0xa3bcf431, 0xc75c8fcf, + 0x522c5b5a, 0x9f7dab41, 0x0a0d7fd4, 0x6eed042a, 0xfb9dd0bf, + 0xa72df3d6, 0x325d2743, 0x56bd5cbd, 0xc3cd8828, 0xefdd1a6f, + 0x7aadcefa, 0x1e4db504, 0x8b3d6191, 0xd78d42f8, 0x42fd966d, + 0x261ded93, 0xb36d3906, 0x54288e16, 0xc1585a83, 0xa5b8217d, + 0x30c8f5e8, 0x6c78d681, 0xf9080214, 0x9de879ea, 0x0898ad7f, + 0x24883f38, 0xb1f8ebad, 0xd5189053, 0x406844c6, 0x1cd867af, + 0x89a8b33a, 0xed48c8c4, 0x78381c51, 0xb569ec4a, 0x201938df, + 0x44f94321, 0xd18997b4, 0x8d39b4dd, 0x18496048, 0x7ca91bb6, + 0xe9d9cf23, 0xc5c95d64, 0x50b989f1, 0x3459f20f, 0xa129269a, + 0xfd9905f3, 0x68e9d166, 0x0c09aa98, 0x99797e0d, 0x4ddb4cef, + 0xd8ab987a, 0xbc4be384, 0x293b3711, 0x758b1478, 0xe0fbc0ed, + 0x841bbb13, 0x116b6f86, 0x3d7bfdc1, 0xa80b2954, 0xcceb52aa, + 0x599b863f, 0x052ba556, 0x905b71c3, 0xf4bb0a3d, 0x61cbdea8, + 0xac9a2eb3, 0x39eafa26, 0x5d0a81d8, 0xc87a554d, 0x94ca7624, + 0x01baa2b1, 0x655ad94f, 0xf02a0dda, 0xdc3a9f9d, 0x494a4b08, + 0x2daa30f6, 0xb8dae463, 0xe46ac70a, 0x711a139f, 0x15fa6861, + 0x808abcf4}, + {0x00000000, 0xcf9e17c8, 0x444d29d1, 0x8bd33e19, 0x889a53a2, + 0x4704446a, 0xccd77a73, 0x03496dbb, 0xca45a105, 0x05dbb6cd, + 0x8e0888d4, 0x41969f1c, 0x42dff2a7, 0x8d41e56f, 0x0692db76, + 0xc90cccbe, 0x4ffa444b, 0x80645383, 0x0bb76d9a, 0xc4297a52, + 0xc76017e9, 0x08fe0021, 0x832d3e38, 0x4cb329f0, 0x85bfe54e, + 0x4a21f286, 0xc1f2cc9f, 0x0e6cdb57, 0x0d25b6ec, 0xc2bba124, + 0x49689f3d, 0x86f688f5, 0x9ff48896, 0x506a9f5e, 0xdbb9a147, + 0x1427b68f, 0x176edb34, 0xd8f0ccfc, 0x5323f2e5, 0x9cbde52d, + 0x55b12993, 0x9a2f3e5b, 0x11fc0042, 0xde62178a, 0xdd2b7a31, + 0x12b56df9, 0x996653e0, 0x56f84428, 0xd00eccdd, 0x1f90db15, + 0x9443e50c, 0x5bddf2c4, 0x58949f7f, 0x970a88b7, 0x1cd9b6ae, + 0xd347a166, 0x1a4b6dd8, 0xd5d57a10, 0x5e064409, 0x919853c1, + 0x92d13e7a, 0x5d4f29b2, 0xd69c17ab, 0x19020063, 0xe498176d, + 0x2b0600a5, 0xa0d53ebc, 0x6f4b2974, 0x6c0244cf, 0xa39c5307, + 0x284f6d1e, 0xe7d17ad6, 0x2eddb668, 0xe143a1a0, 0x6a909fb9, + 0xa50e8871, 0xa647e5ca, 0x69d9f202, 0xe20acc1b, 0x2d94dbd3, + 0xab625326, 0x64fc44ee, 0xef2f7af7, 0x20b16d3f, 0x23f80084, + 0xec66174c, 0x67b52955, 0xa82b3e9d, 0x6127f223, 0xaeb9e5eb, + 0x256adbf2, 0xeaf4cc3a, 0xe9bda181, 0x2623b649, 0xadf08850, + 0x626e9f98, 0x7b6c9ffb, 0xb4f28833, 0x3f21b62a, 0xf0bfa1e2, + 0xf3f6cc59, 0x3c68db91, 0xb7bbe588, 0x7825f240, 0xb1293efe, + 0x7eb72936, 0xf564172f, 0x3afa00e7, 0x39b36d5c, 0xf62d7a94, + 0x7dfe448d, 0xb2605345, 0x3496dbb0, 0xfb08cc78, 0x70dbf261, + 0xbf45e5a9, 0xbc0c8812, 0x73929fda, 0xf841a1c3, 0x37dfb60b, + 0xfed37ab5, 0x314d6d7d, 0xba9e5364, 0x750044ac, 0x76492917, + 0xb9d73edf, 0x320400c6, 0xfd9a170e, 0x1241289b, 0xdddf3f53, + 0x560c014a, 0x99921682, 0x9adb7b39, 0x55456cf1, 0xde9652e8, + 0x11084520, 0xd804899e, 0x179a9e56, 0x9c49a04f, 0x53d7b787, + 0x509eda3c, 0x9f00cdf4, 0x14d3f3ed, 0xdb4de425, 0x5dbb6cd0, + 0x92257b18, 0x19f64501, 0xd66852c9, 0xd5213f72, 0x1abf28ba, + 0x916c16a3, 0x5ef2016b, 0x97fecdd5, 0x5860da1d, 0xd3b3e404, + 0x1c2df3cc, 0x1f649e77, 0xd0fa89bf, 0x5b29b7a6, 0x94b7a06e, + 0x8db5a00d, 0x422bb7c5, 0xc9f889dc, 0x06669e14, 0x052ff3af, + 0xcab1e467, 0x4162da7e, 0x8efccdb6, 0x47f00108, 0x886e16c0, + 0x03bd28d9, 0xcc233f11, 0xcf6a52aa, 0x00f44562, 0x8b277b7b, + 0x44b96cb3, 0xc24fe446, 0x0dd1f38e, 0x8602cd97, 0x499cda5f, + 0x4ad5b7e4, 0x854ba02c, 0x0e989e35, 0xc10689fd, 0x080a4543, + 0xc794528b, 0x4c476c92, 0x83d97b5a, 0x809016e1, 0x4f0e0129, + 0xc4dd3f30, 0x0b4328f8, 0xf6d93ff6, 0x3947283e, 0xb2941627, + 0x7d0a01ef, 0x7e436c54, 0xb1dd7b9c, 0x3a0e4585, 0xf590524d, + 0x3c9c9ef3, 0xf302893b, 0x78d1b722, 0xb74fa0ea, 0xb406cd51, + 0x7b98da99, 0xf04be480, 0x3fd5f348, 0xb9237bbd, 0x76bd6c75, + 0xfd6e526c, 0x32f045a4, 0x31b9281f, 0xfe273fd7, 0x75f401ce, + 0xba6a1606, 0x7366dab8, 0xbcf8cd70, 0x372bf369, 0xf8b5e4a1, + 0xfbfc891a, 0x34629ed2, 0xbfb1a0cb, 0x702fb703, 0x692db760, + 0xa6b3a0a8, 0x2d609eb1, 0xe2fe8979, 0xe1b7e4c2, 0x2e29f30a, + 0xa5facd13, 0x6a64dadb, 0xa3681665, 0x6cf601ad, 0xe7253fb4, + 0x28bb287c, 0x2bf245c7, 0xe46c520f, 0x6fbf6c16, 0xa0217bde, + 0x26d7f32b, 0xe949e4e3, 0x629adafa, 0xad04cd32, 0xae4da089, + 0x61d3b741, 0xea008958, 0x259e9e90, 0xec92522e, 0x230c45e6, + 0xa8df7bff, 0x67416c37, 0x6408018c, 0xab961644, 0x2045285d, + 0xefdb3f95}, + {0x00000000, 0x24825136, 0x4904a26c, 0x6d86f35a, 0x920944d8, + 0xb68b15ee, 0xdb0de6b4, 0xff8fb782, 0xff638ff1, 0xdbe1dec7, + 0xb6672d9d, 0x92e57cab, 0x6d6acb29, 0x49e89a1f, 0x246e6945, + 0x00ec3873, 0x25b619a3, 0x01344895, 0x6cb2bbcf, 0x4830eaf9, + 0xb7bf5d7b, 0x933d0c4d, 0xfebbff17, 0xda39ae21, 0xdad59652, + 0xfe57c764, 0x93d1343e, 0xb7536508, 0x48dcd28a, 0x6c5e83bc, + 0x01d870e6, 0x255a21d0, 0x4b6c3346, 0x6fee6270, 0x0268912a, + 0x26eac01c, 0xd965779e, 0xfde726a8, 0x9061d5f2, 0xb4e384c4, + 0xb40fbcb7, 0x908ded81, 0xfd0b1edb, 0xd9894fed, 0x2606f86f, + 0x0284a959, 0x6f025a03, 0x4b800b35, 0x6eda2ae5, 0x4a587bd3, + 0x27de8889, 0x035cd9bf, 0xfcd36e3d, 0xd8513f0b, 0xb5d7cc51, + 0x91559d67, 0x91b9a514, 0xb53bf422, 0xd8bd0778, 0xfc3f564e, + 0x03b0e1cc, 0x2732b0fa, 0x4ab443a0, 0x6e361296, 0x96d8668c, + 0xb25a37ba, 0xdfdcc4e0, 0xfb5e95d6, 0x04d12254, 0x20537362, + 0x4dd58038, 0x6957d10e, 0x69bbe97d, 0x4d39b84b, 0x20bf4b11, + 0x043d1a27, 0xfbb2ada5, 0xdf30fc93, 0xb2b60fc9, 0x96345eff, + 0xb36e7f2f, 0x97ec2e19, 0xfa6add43, 0xdee88c75, 0x21673bf7, + 0x05e56ac1, 0x6863999b, 0x4ce1c8ad, 0x4c0df0de, 0x688fa1e8, + 0x050952b2, 0x218b0384, 0xde04b406, 0xfa86e530, 0x9700166a, + 0xb382475c, 0xddb455ca, 0xf93604fc, 0x94b0f7a6, 0xb032a690, + 0x4fbd1112, 0x6b3f4024, 0x06b9b37e, 0x223be248, 0x22d7da3b, + 0x06558b0d, 0x6bd37857, 0x4f512961, 0xb0de9ee3, 0x945ccfd5, + 0xf9da3c8f, 0xdd586db9, 0xf8024c69, 0xdc801d5f, 0xb106ee05, + 0x9584bf33, 0x6a0b08b1, 0x4e895987, 0x230faadd, 0x078dfbeb, + 0x0761c398, 0x23e392ae, 0x4e6561f4, 0x6ae730c2, 0x95688740, + 0xb1ead676, 0xdc6c252c, 0xf8ee741a, 0xf6c1cb59, 0xd2439a6f, + 0xbfc56935, 0x9b473803, 0x64c88f81, 0x404adeb7, 0x2dcc2ded, + 0x094e7cdb, 0x09a244a8, 0x2d20159e, 0x40a6e6c4, 0x6424b7f2, + 0x9bab0070, 0xbf295146, 0xd2afa21c, 0xf62df32a, 0xd377d2fa, + 0xf7f583cc, 0x9a737096, 0xbef121a0, 0x417e9622, 0x65fcc714, + 0x087a344e, 0x2cf86578, 0x2c145d0b, 0x08960c3d, 0x6510ff67, + 0x4192ae51, 0xbe1d19d3, 0x9a9f48e5, 0xf719bbbf, 0xd39bea89, + 0xbdadf81f, 0x992fa929, 0xf4a95a73, 0xd02b0b45, 0x2fa4bcc7, + 0x0b26edf1, 0x66a01eab, 0x42224f9d, 0x42ce77ee, 0x664c26d8, + 0x0bcad582, 0x2f4884b4, 0xd0c73336, 0xf4456200, 0x99c3915a, + 0xbd41c06c, 0x981be1bc, 0xbc99b08a, 0xd11f43d0, 0xf59d12e6, + 0x0a12a564, 0x2e90f452, 0x43160708, 0x6794563e, 0x67786e4d, + 0x43fa3f7b, 0x2e7ccc21, 0x0afe9d17, 0xf5712a95, 0xd1f37ba3, + 0xbc7588f9, 0x98f7d9cf, 0x6019add5, 0x449bfce3, 0x291d0fb9, + 0x0d9f5e8f, 0xf210e90d, 0xd692b83b, 0xbb144b61, 0x9f961a57, + 0x9f7a2224, 0xbbf87312, 0xd67e8048, 0xf2fcd17e, 0x0d7366fc, + 0x29f137ca, 0x4477c490, 0x60f595a6, 0x45afb476, 0x612de540, + 0x0cab161a, 0x2829472c, 0xd7a6f0ae, 0xf324a198, 0x9ea252c2, + 0xba2003f4, 0xbacc3b87, 0x9e4e6ab1, 0xf3c899eb, 0xd74ac8dd, + 0x28c57f5f, 0x0c472e69, 0x61c1dd33, 0x45438c05, 0x2b759e93, + 0x0ff7cfa5, 0x62713cff, 0x46f36dc9, 0xb97cda4b, 0x9dfe8b7d, + 0xf0787827, 0xd4fa2911, 0xd4161162, 0xf0944054, 0x9d12b30e, + 0xb990e238, 0x461f55ba, 0x629d048c, 0x0f1bf7d6, 0x2b99a6e0, + 0x0ec38730, 0x2a41d606, 0x47c7255c, 0x6345746a, 0x9ccac3e8, + 0xb84892de, 0xd5ce6184, 0xf14c30b2, 0xf1a008c1, 0xd52259f7, + 0xb8a4aaad, 0x9c26fb9b, 0x63a94c19, 0x472b1d2f, 0x2aadee75, + 0x0e2fbf43}, + {0x00000000, 0x36f290f3, 0x6de521e6, 0x5b17b115, 0xdbca43cc, + 0xed38d33f, 0xb62f622a, 0x80ddf2d9, 0x6ce581d9, 0x5a17112a, + 0x0100a03f, 0x37f230cc, 0xb72fc215, 0x81dd52e6, 0xdacae3f3, + 0xec387300, 0xd9cb03b2, 0xef399341, 0xb42e2254, 0x82dcb2a7, + 0x0201407e, 0x34f3d08d, 0x6fe46198, 0x5916f16b, 0xb52e826b, + 0x83dc1298, 0xd8cba38d, 0xee39337e, 0x6ee4c1a7, 0x58165154, + 0x0301e041, 0x35f370b2, 0x68e70125, 0x5e1591d6, 0x050220c3, + 0x33f0b030, 0xb32d42e9, 0x85dfd21a, 0xdec8630f, 0xe83af3fc, + 0x040280fc, 0x32f0100f, 0x69e7a11a, 0x5f1531e9, 0xdfc8c330, + 0xe93a53c3, 0xb22de2d6, 0x84df7225, 0xb12c0297, 0x87de9264, + 0xdcc92371, 0xea3bb382, 0x6ae6415b, 0x5c14d1a8, 0x070360bd, + 0x31f1f04e, 0xddc9834e, 0xeb3b13bd, 0xb02ca2a8, 0x86de325b, + 0x0603c082, 0x30f15071, 0x6be6e164, 0x5d147197, 0xd1ce024a, + 0xe73c92b9, 0xbc2b23ac, 0x8ad9b35f, 0x0a044186, 0x3cf6d175, + 0x67e16060, 0x5113f093, 0xbd2b8393, 0x8bd91360, 0xd0cea275, + 0xe63c3286, 0x66e1c05f, 0x501350ac, 0x0b04e1b9, 0x3df6714a, + 0x080501f8, 0x3ef7910b, 0x65e0201e, 0x5312b0ed, 0xd3cf4234, + 0xe53dd2c7, 0xbe2a63d2, 0x88d8f321, 0x64e08021, 0x521210d2, + 0x0905a1c7, 0x3ff73134, 0xbf2ac3ed, 0x89d8531e, 0xd2cfe20b, + 0xe43d72f8, 0xb929036f, 0x8fdb939c, 0xd4cc2289, 0xe23eb27a, + 0x62e340a3, 0x5411d050, 0x0f066145, 0x39f4f1b6, 0xd5cc82b6, + 0xe33e1245, 0xb829a350, 0x8edb33a3, 0x0e06c17a, 0x38f45189, + 0x63e3e09c, 0x5511706f, 0x60e200dd, 0x5610902e, 0x0d07213b, + 0x3bf5b1c8, 0xbb284311, 0x8ddad3e2, 0xd6cd62f7, 0xe03ff204, + 0x0c078104, 0x3af511f7, 0x61e2a0e2, 0x57103011, 0xd7cdc2c8, + 0xe13f523b, 0xba28e32e, 0x8cda73dd, 0x78ed02d5, 0x4e1f9226, + 0x15082333, 0x23fab3c0, 0xa3274119, 0x95d5d1ea, 0xcec260ff, + 0xf830f00c, 0x1408830c, 0x22fa13ff, 0x79eda2ea, 0x4f1f3219, + 0xcfc2c0c0, 0xf9305033, 0xa227e126, 0x94d571d5, 0xa1260167, + 0x97d49194, 0xccc32081, 0xfa31b072, 0x7aec42ab, 0x4c1ed258, + 0x1709634d, 0x21fbf3be, 0xcdc380be, 0xfb31104d, 0xa026a158, + 0x96d431ab, 0x1609c372, 0x20fb5381, 0x7bece294, 0x4d1e7267, + 0x100a03f0, 0x26f89303, 0x7def2216, 0x4b1db2e5, 0xcbc0403c, + 0xfd32d0cf, 0xa62561da, 0x90d7f129, 0x7cef8229, 0x4a1d12da, + 0x110aa3cf, 0x27f8333c, 0xa725c1e5, 0x91d75116, 0xcac0e003, + 0xfc3270f0, 0xc9c10042, 0xff3390b1, 0xa42421a4, 0x92d6b157, + 0x120b438e, 0x24f9d37d, 0x7fee6268, 0x491cf29b, 0xa524819b, + 0x93d61168, 0xc8c1a07d, 0xfe33308e, 0x7eeec257, 0x481c52a4, + 0x130be3b1, 0x25f97342, 0xa923009f, 0x9fd1906c, 0xc4c62179, + 0xf234b18a, 0x72e94353, 0x441bd3a0, 0x1f0c62b5, 0x29fef246, + 0xc5c68146, 0xf33411b5, 0xa823a0a0, 0x9ed13053, 0x1e0cc28a, + 0x28fe5279, 0x73e9e36c, 0x451b739f, 0x70e8032d, 0x461a93de, + 0x1d0d22cb, 0x2bffb238, 0xab2240e1, 0x9dd0d012, 0xc6c76107, + 0xf035f1f4, 0x1c0d82f4, 0x2aff1207, 0x71e8a312, 0x471a33e1, + 0xc7c7c138, 0xf13551cb, 0xaa22e0de, 0x9cd0702d, 0xc1c401ba, + 0xf7369149, 0xac21205c, 0x9ad3b0af, 0x1a0e4276, 0x2cfcd285, + 0x77eb6390, 0x4119f363, 0xad218063, 0x9bd31090, 0xc0c4a185, + 0xf6363176, 0x76ebc3af, 0x4019535c, 0x1b0ee249, 0x2dfc72ba, + 0x180f0208, 0x2efd92fb, 0x75ea23ee, 0x4318b31d, 0xc3c541c4, + 0xf537d137, 0xae206022, 0x98d2f0d1, 0x74ea83d1, 0x42181322, + 0x190fa237, 0x2ffd32c4, 0xaf20c01d, 0x99d250ee, 0xc2c5e1fb, + 0xf4377108}}; + +local const z_word_t FAR crc_braid_big_table[][256] = { + {0x0000000000000000, 0xf390f23600000000, 0xe621e56d00000000, + 0x15b1175b00000000, 0xcc43cadb00000000, 0x3fd338ed00000000, + 0x2a622fb600000000, 0xd9f2dd8000000000, 0xd981e56c00000000, + 0x2a11175a00000000, 0x3fa0000100000000, 0xcc30f23700000000, + 0x15c22fb700000000, 0xe652dd8100000000, 0xf3e3cada00000000, + 0x007338ec00000000, 0xb203cbd900000000, 0x419339ef00000000, + 0x54222eb400000000, 0xa7b2dc8200000000, 0x7e40010200000000, + 0x8dd0f33400000000, 0x9861e46f00000000, 0x6bf1165900000000, + 0x6b822eb500000000, 0x9812dc8300000000, 0x8da3cbd800000000, + 0x7e3339ee00000000, 0xa7c1e46e00000000, 0x5451165800000000, + 0x41e0010300000000, 0xb270f33500000000, 0x2501e76800000000, + 0xd691155e00000000, 0xc320020500000000, 0x30b0f03300000000, + 0xe9422db300000000, 0x1ad2df8500000000, 0x0f63c8de00000000, + 0xfcf33ae800000000, 0xfc80020400000000, 0x0f10f03200000000, + 0x1aa1e76900000000, 0xe931155f00000000, 0x30c3c8df00000000, + 0xc3533ae900000000, 0xd6e22db200000000, 0x2572df8400000000, + 0x97022cb100000000, 0x6492de8700000000, 0x7123c9dc00000000, + 0x82b33bea00000000, 0x5b41e66a00000000, 0xa8d1145c00000000, + 0xbd60030700000000, 0x4ef0f13100000000, 0x4e83c9dd00000000, + 0xbd133beb00000000, 0xa8a22cb000000000, 0x5b32de8600000000, + 0x82c0030600000000, 0x7150f13000000000, 0x64e1e66b00000000, + 0x9771145d00000000, 0x4a02ced100000000, 0xb9923ce700000000, + 0xac232bbc00000000, 0x5fb3d98a00000000, 0x8641040a00000000, + 0x75d1f63c00000000, 0x6060e16700000000, 0x93f0135100000000, + 0x93832bbd00000000, 0x6013d98b00000000, 0x75a2ced000000000, + 0x86323ce600000000, 0x5fc0e16600000000, 0xac50135000000000, + 0xb9e1040b00000000, 0x4a71f63d00000000, 0xf801050800000000, + 0x0b91f73e00000000, 0x1e20e06500000000, 0xedb0125300000000, + 0x3442cfd300000000, 0xc7d23de500000000, 0xd2632abe00000000, + 0x21f3d88800000000, 0x2180e06400000000, 0xd210125200000000, + 0xc7a1050900000000, 0x3431f73f00000000, 0xedc32abf00000000, + 0x1e53d88900000000, 0x0be2cfd200000000, 0xf8723de400000000, + 0x6f0329b900000000, 0x9c93db8f00000000, 0x8922ccd400000000, + 0x7ab23ee200000000, 0xa340e36200000000, 0x50d0115400000000, + 0x4561060f00000000, 0xb6f1f43900000000, 0xb682ccd500000000, + 0x45123ee300000000, 0x50a329b800000000, 0xa333db8e00000000, + 0x7ac1060e00000000, 0x8951f43800000000, 0x9ce0e36300000000, + 0x6f70115500000000, 0xdd00e26000000000, 0x2e90105600000000, + 0x3b21070d00000000, 0xc8b1f53b00000000, 0x114328bb00000000, + 0xe2d3da8d00000000, 0xf762cdd600000000, 0x04f23fe000000000, + 0x0481070c00000000, 0xf711f53a00000000, 0xe2a0e26100000000, + 0x1130105700000000, 0xc8c2cdd700000000, 0x3b523fe100000000, + 0x2ee328ba00000000, 0xdd73da8c00000000, 0xd502ed7800000000, + 0x26921f4e00000000, 0x3323081500000000, 0xc0b3fa2300000000, + 0x194127a300000000, 0xead1d59500000000, 0xff60c2ce00000000, + 0x0cf030f800000000, 0x0c83081400000000, 0xff13fa2200000000, + 0xeaa2ed7900000000, 0x19321f4f00000000, 0xc0c0c2cf00000000, + 0x335030f900000000, 0x26e127a200000000, 0xd571d59400000000, + 0x670126a100000000, 0x9491d49700000000, 0x8120c3cc00000000, + 0x72b031fa00000000, 0xab42ec7a00000000, 0x58d21e4c00000000, + 0x4d63091700000000, 0xbef3fb2100000000, 0xbe80c3cd00000000, + 0x4d1031fb00000000, 0x58a126a000000000, 0xab31d49600000000, + 0x72c3091600000000, 0x8153fb2000000000, 0x94e2ec7b00000000, + 0x67721e4d00000000, 0xf0030a1000000000, 0x0393f82600000000, + 0x1622ef7d00000000, 0xe5b21d4b00000000, 0x3c40c0cb00000000, + 0xcfd032fd00000000, 0xda6125a600000000, 0x29f1d79000000000, + 0x2982ef7c00000000, 0xda121d4a00000000, 0xcfa30a1100000000, + 0x3c33f82700000000, 0xe5c125a700000000, 0x1651d79100000000, + 0x03e0c0ca00000000, 0xf07032fc00000000, 0x4200c1c900000000, + 0xb19033ff00000000, 0xa42124a400000000, 0x57b1d69200000000, + 0x8e430b1200000000, 0x7dd3f92400000000, 0x6862ee7f00000000, + 0x9bf21c4900000000, 0x9b8124a500000000, 0x6811d69300000000, + 0x7da0c1c800000000, 0x8e3033fe00000000, 0x57c2ee7e00000000, + 0xa4521c4800000000, 0xb1e30b1300000000, 0x4273f92500000000, + 0x9f0023a900000000, 0x6c90d19f00000000, 0x7921c6c400000000, + 0x8ab134f200000000, 0x5343e97200000000, 0xa0d31b4400000000, + 0xb5620c1f00000000, 0x46f2fe2900000000, 0x4681c6c500000000, + 0xb51134f300000000, 0xa0a023a800000000, 0x5330d19e00000000, + 0x8ac20c1e00000000, 0x7952fe2800000000, 0x6ce3e97300000000, + 0x9f731b4500000000, 0x2d03e87000000000, 0xde931a4600000000, + 0xcb220d1d00000000, 0x38b2ff2b00000000, 0xe14022ab00000000, + 0x12d0d09d00000000, 0x0761c7c600000000, 0xf4f135f000000000, + 0xf4820d1c00000000, 0x0712ff2a00000000, 0x12a3e87100000000, + 0xe1331a4700000000, 0x38c1c7c700000000, 0xcb5135f100000000, + 0xdee022aa00000000, 0x2d70d09c00000000, 0xba01c4c100000000, + 0x499136f700000000, 0x5c2021ac00000000, 0xafb0d39a00000000, + 0x76420e1a00000000, 0x85d2fc2c00000000, 0x9063eb7700000000, + 0x63f3194100000000, 0x638021ad00000000, 0x9010d39b00000000, + 0x85a1c4c000000000, 0x763136f600000000, 0xafc3eb7600000000, + 0x5c53194000000000, 0x49e20e1b00000000, 0xba72fc2d00000000, + 0x08020f1800000000, 0xfb92fd2e00000000, 0xee23ea7500000000, + 0x1db3184300000000, 0xc441c5c300000000, 0x37d137f500000000, + 0x226020ae00000000, 0xd1f0d29800000000, 0xd183ea7400000000, + 0x2213184200000000, 0x37a20f1900000000, 0xc432fd2f00000000, + 0x1dc020af00000000, 0xee50d29900000000, 0xfbe1c5c200000000, + 0x087137f400000000}, + {0x0000000000000000, 0x3651822400000000, 0x6ca2044900000000, + 0x5af3866d00000000, 0xd844099200000000, 0xee158bb600000000, + 0xb4e60ddb00000000, 0x82b78fff00000000, 0xf18f63ff00000000, + 0xc7dee1db00000000, 0x9d2d67b600000000, 0xab7ce59200000000, + 0x29cb6a6d00000000, 0x1f9ae84900000000, 0x45696e2400000000, + 0x7338ec0000000000, 0xa319b62500000000, 0x9548340100000000, + 0xcfbbb26c00000000, 0xf9ea304800000000, 0x7b5dbfb700000000, + 0x4d0c3d9300000000, 0x17ffbbfe00000000, 0x21ae39da00000000, + 0x5296d5da00000000, 0x64c757fe00000000, 0x3e34d19300000000, + 0x086553b700000000, 0x8ad2dc4800000000, 0xbc835e6c00000000, + 0xe670d80100000000, 0xd0215a2500000000, 0x46336c4b00000000, + 0x7062ee6f00000000, 0x2a91680200000000, 0x1cc0ea2600000000, + 0x9e7765d900000000, 0xa826e7fd00000000, 0xf2d5619000000000, + 0xc484e3b400000000, 0xb7bc0fb400000000, 0x81ed8d9000000000, + 0xdb1e0bfd00000000, 0xed4f89d900000000, 0x6ff8062600000000, + 0x59a9840200000000, 0x035a026f00000000, 0x350b804b00000000, + 0xe52ada6e00000000, 0xd37b584a00000000, 0x8988de2700000000, + 0xbfd95c0300000000, 0x3d6ed3fc00000000, 0x0b3f51d800000000, + 0x51ccd7b500000000, 0x679d559100000000, 0x14a5b99100000000, + 0x22f43bb500000000, 0x7807bdd800000000, 0x4e563ffc00000000, + 0xcce1b00300000000, 0xfab0322700000000, 0xa043b44a00000000, + 0x9612366e00000000, 0x8c66d89600000000, 0xba375ab200000000, + 0xe0c4dcdf00000000, 0xd6955efb00000000, 0x5422d10400000000, + 0x6273532000000000, 0x3880d54d00000000, 0x0ed1576900000000, + 0x7de9bb6900000000, 0x4bb8394d00000000, 0x114bbf2000000000, + 0x271a3d0400000000, 0xa5adb2fb00000000, 0x93fc30df00000000, + 0xc90fb6b200000000, 0xff5e349600000000, 0x2f7f6eb300000000, + 0x192eec9700000000, 0x43dd6afa00000000, 0x758ce8de00000000, + 0xf73b672100000000, 0xc16ae50500000000, 0x9b99636800000000, + 0xadc8e14c00000000, 0xdef00d4c00000000, 0xe8a18f6800000000, + 0xb252090500000000, 0x84038b2100000000, 0x06b404de00000000, + 0x30e586fa00000000, 0x6a16009700000000, 0x5c4782b300000000, + 0xca55b4dd00000000, 0xfc0436f900000000, 0xa6f7b09400000000, + 0x90a632b000000000, 0x1211bd4f00000000, 0x24403f6b00000000, + 0x7eb3b90600000000, 0x48e23b2200000000, 0x3bdad72200000000, + 0x0d8b550600000000, 0x5778d36b00000000, 0x6129514f00000000, + 0xe39edeb000000000, 0xd5cf5c9400000000, 0x8f3cdaf900000000, + 0xb96d58dd00000000, 0x694c02f800000000, 0x5f1d80dc00000000, + 0x05ee06b100000000, 0x33bf849500000000, 0xb1080b6a00000000, + 0x8759894e00000000, 0xddaa0f2300000000, 0xebfb8d0700000000, + 0x98c3610700000000, 0xae92e32300000000, 0xf461654e00000000, + 0xc230e76a00000000, 0x4087689500000000, 0x76d6eab100000000, + 0x2c256cdc00000000, 0x1a74eef800000000, 0x59cbc1f600000000, + 0x6f9a43d200000000, 0x3569c5bf00000000, 0x0338479b00000000, + 0x818fc86400000000, 0xb7de4a4000000000, 0xed2dcc2d00000000, + 0xdb7c4e0900000000, 0xa844a20900000000, 0x9e15202d00000000, + 0xc4e6a64000000000, 0xf2b7246400000000, 0x7000ab9b00000000, + 0x465129bf00000000, 0x1ca2afd200000000, 0x2af32df600000000, + 0xfad277d300000000, 0xcc83f5f700000000, 0x9670739a00000000, + 0xa021f1be00000000, 0x22967e4100000000, 0x14c7fc6500000000, + 0x4e347a0800000000, 0x7865f82c00000000, 0x0b5d142c00000000, + 0x3d0c960800000000, 0x67ff106500000000, 0x51ae924100000000, + 0xd3191dbe00000000, 0xe5489f9a00000000, 0xbfbb19f700000000, + 0x89ea9bd300000000, 0x1ff8adbd00000000, 0x29a92f9900000000, + 0x735aa9f400000000, 0x450b2bd000000000, 0xc7bca42f00000000, + 0xf1ed260b00000000, 0xab1ea06600000000, 0x9d4f224200000000, + 0xee77ce4200000000, 0xd8264c6600000000, 0x82d5ca0b00000000, + 0xb484482f00000000, 0x3633c7d000000000, 0x006245f400000000, + 0x5a91c39900000000, 0x6cc041bd00000000, 0xbce11b9800000000, + 0x8ab099bc00000000, 0xd0431fd100000000, 0xe6129df500000000, + 0x64a5120a00000000, 0x52f4902e00000000, 0x0807164300000000, + 0x3e56946700000000, 0x4d6e786700000000, 0x7b3ffa4300000000, + 0x21cc7c2e00000000, 0x179dfe0a00000000, 0x952a71f500000000, + 0xa37bf3d100000000, 0xf98875bc00000000, 0xcfd9f79800000000, + 0xd5ad196000000000, 0xe3fc9b4400000000, 0xb90f1d2900000000, + 0x8f5e9f0d00000000, 0x0de910f200000000, 0x3bb892d600000000, + 0x614b14bb00000000, 0x571a969f00000000, 0x24227a9f00000000, + 0x1273f8bb00000000, 0x48807ed600000000, 0x7ed1fcf200000000, + 0xfc66730d00000000, 0xca37f12900000000, 0x90c4774400000000, + 0xa695f56000000000, 0x76b4af4500000000, 0x40e52d6100000000, + 0x1a16ab0c00000000, 0x2c47292800000000, 0xaef0a6d700000000, + 0x98a124f300000000, 0xc252a29e00000000, 0xf40320ba00000000, + 0x873bccba00000000, 0xb16a4e9e00000000, 0xeb99c8f300000000, + 0xddc84ad700000000, 0x5f7fc52800000000, 0x692e470c00000000, + 0x33ddc16100000000, 0x058c434500000000, 0x939e752b00000000, + 0xa5cff70f00000000, 0xff3c716200000000, 0xc96df34600000000, + 0x4bda7cb900000000, 0x7d8bfe9d00000000, 0x277878f000000000, + 0x1129fad400000000, 0x621116d400000000, 0x544094f000000000, + 0x0eb3129d00000000, 0x38e290b900000000, 0xba551f4600000000, + 0x8c049d6200000000, 0xd6f71b0f00000000, 0xe0a6992b00000000, + 0x3087c30e00000000, 0x06d6412a00000000, 0x5c25c74700000000, + 0x6a74456300000000, 0xe8c3ca9c00000000, 0xde9248b800000000, + 0x8461ced500000000, 0xb2304cf100000000, 0xc108a0f100000000, + 0xf75922d500000000, 0xadaaa4b800000000, 0x9bfb269c00000000, + 0x194ca96300000000, 0x2f1d2b4700000000, 0x75eead2a00000000, + 0x43bf2f0e00000000}, + {0x0000000000000000, 0xc8179ecf00000000, 0xd1294d4400000000, + 0x193ed38b00000000, 0xa2539a8800000000, 0x6a44044700000000, + 0x737ad7cc00000000, 0xbb6d490300000000, 0x05a145ca00000000, + 0xcdb6db0500000000, 0xd488088e00000000, 0x1c9f964100000000, + 0xa7f2df4200000000, 0x6fe5418d00000000, 0x76db920600000000, + 0xbecc0cc900000000, 0x4b44fa4f00000000, 0x8353648000000000, + 0x9a6db70b00000000, 0x527a29c400000000, 0xe91760c700000000, + 0x2100fe0800000000, 0x383e2d8300000000, 0xf029b34c00000000, + 0x4ee5bf8500000000, 0x86f2214a00000000, 0x9fccf2c100000000, + 0x57db6c0e00000000, 0xecb6250d00000000, 0x24a1bbc200000000, + 0x3d9f684900000000, 0xf588f68600000000, 0x9688f49f00000000, + 0x5e9f6a5000000000, 0x47a1b9db00000000, 0x8fb6271400000000, + 0x34db6e1700000000, 0xfcccf0d800000000, 0xe5f2235300000000, + 0x2de5bd9c00000000, 0x9329b15500000000, 0x5b3e2f9a00000000, + 0x4200fc1100000000, 0x8a1762de00000000, 0x317a2bdd00000000, + 0xf96db51200000000, 0xe053669900000000, 0x2844f85600000000, + 0xddcc0ed000000000, 0x15db901f00000000, 0x0ce5439400000000, + 0xc4f2dd5b00000000, 0x7f9f945800000000, 0xb7880a9700000000, + 0xaeb6d91c00000000, 0x66a147d300000000, 0xd86d4b1a00000000, + 0x107ad5d500000000, 0x0944065e00000000, 0xc153989100000000, + 0x7a3ed19200000000, 0xb2294f5d00000000, 0xab179cd600000000, + 0x6300021900000000, 0x6d1798e400000000, 0xa500062b00000000, + 0xbc3ed5a000000000, 0x74294b6f00000000, 0xcf44026c00000000, + 0x07539ca300000000, 0x1e6d4f2800000000, 0xd67ad1e700000000, + 0x68b6dd2e00000000, 0xa0a143e100000000, 0xb99f906a00000000, + 0x71880ea500000000, 0xcae547a600000000, 0x02f2d96900000000, + 0x1bcc0ae200000000, 0xd3db942d00000000, 0x265362ab00000000, + 0xee44fc6400000000, 0xf77a2fef00000000, 0x3f6db12000000000, + 0x8400f82300000000, 0x4c1766ec00000000, 0x5529b56700000000, + 0x9d3e2ba800000000, 0x23f2276100000000, 0xebe5b9ae00000000, + 0xf2db6a2500000000, 0x3accf4ea00000000, 0x81a1bde900000000, + 0x49b6232600000000, 0x5088f0ad00000000, 0x989f6e6200000000, + 0xfb9f6c7b00000000, 0x3388f2b400000000, 0x2ab6213f00000000, + 0xe2a1bff000000000, 0x59ccf6f300000000, 0x91db683c00000000, + 0x88e5bbb700000000, 0x40f2257800000000, 0xfe3e29b100000000, + 0x3629b77e00000000, 0x2f1764f500000000, 0xe700fa3a00000000, + 0x5c6db33900000000, 0x947a2df600000000, 0x8d44fe7d00000000, + 0x455360b200000000, 0xb0db963400000000, 0x78cc08fb00000000, + 0x61f2db7000000000, 0xa9e545bf00000000, 0x12880cbc00000000, + 0xda9f927300000000, 0xc3a141f800000000, 0x0bb6df3700000000, + 0xb57ad3fe00000000, 0x7d6d4d3100000000, 0x64539eba00000000, + 0xac44007500000000, 0x1729497600000000, 0xdf3ed7b900000000, + 0xc600043200000000, 0x0e179afd00000000, 0x9b28411200000000, + 0x533fdfdd00000000, 0x4a010c5600000000, 0x8216929900000000, + 0x397bdb9a00000000, 0xf16c455500000000, 0xe85296de00000000, + 0x2045081100000000, 0x9e8904d800000000, 0x569e9a1700000000, + 0x4fa0499c00000000, 0x87b7d75300000000, 0x3cda9e5000000000, + 0xf4cd009f00000000, 0xedf3d31400000000, 0x25e44ddb00000000, + 0xd06cbb5d00000000, 0x187b259200000000, 0x0145f61900000000, + 0xc95268d600000000, 0x723f21d500000000, 0xba28bf1a00000000, + 0xa3166c9100000000, 0x6b01f25e00000000, 0xd5cdfe9700000000, + 0x1dda605800000000, 0x04e4b3d300000000, 0xccf32d1c00000000, + 0x779e641f00000000, 0xbf89fad000000000, 0xa6b7295b00000000, + 0x6ea0b79400000000, 0x0da0b58d00000000, 0xc5b72b4200000000, + 0xdc89f8c900000000, 0x149e660600000000, 0xaff32f0500000000, + 0x67e4b1ca00000000, 0x7eda624100000000, 0xb6cdfc8e00000000, + 0x0801f04700000000, 0xc0166e8800000000, 0xd928bd0300000000, + 0x113f23cc00000000, 0xaa526acf00000000, 0x6245f40000000000, + 0x7b7b278b00000000, 0xb36cb94400000000, 0x46e44fc200000000, + 0x8ef3d10d00000000, 0x97cd028600000000, 0x5fda9c4900000000, + 0xe4b7d54a00000000, 0x2ca04b8500000000, 0x359e980e00000000, + 0xfd8906c100000000, 0x43450a0800000000, 0x8b5294c700000000, + 0x926c474c00000000, 0x5a7bd98300000000, 0xe116908000000000, + 0x29010e4f00000000, 0x303fddc400000000, 0xf828430b00000000, + 0xf63fd9f600000000, 0x3e28473900000000, 0x271694b200000000, + 0xef010a7d00000000, 0x546c437e00000000, 0x9c7bddb100000000, + 0x85450e3a00000000, 0x4d5290f500000000, 0xf39e9c3c00000000, + 0x3b8902f300000000, 0x22b7d17800000000, 0xeaa04fb700000000, + 0x51cd06b400000000, 0x99da987b00000000, 0x80e44bf000000000, + 0x48f3d53f00000000, 0xbd7b23b900000000, 0x756cbd7600000000, + 0x6c526efd00000000, 0xa445f03200000000, 0x1f28b93100000000, + 0xd73f27fe00000000, 0xce01f47500000000, 0x06166aba00000000, + 0xb8da667300000000, 0x70cdf8bc00000000, 0x69f32b3700000000, + 0xa1e4b5f800000000, 0x1a89fcfb00000000, 0xd29e623400000000, + 0xcba0b1bf00000000, 0x03b72f7000000000, 0x60b72d6900000000, + 0xa8a0b3a600000000, 0xb19e602d00000000, 0x7989fee200000000, + 0xc2e4b7e100000000, 0x0af3292e00000000, 0x13cdfaa500000000, + 0xdbda646a00000000, 0x651668a300000000, 0xad01f66c00000000, + 0xb43f25e700000000, 0x7c28bb2800000000, 0xc745f22b00000000, + 0x0f526ce400000000, 0x166cbf6f00000000, 0xde7b21a000000000, + 0x2bf3d72600000000, 0xe3e449e900000000, 0xfada9a6200000000, + 0x32cd04ad00000000, 0x89a04dae00000000, 0x41b7d36100000000, + 0x588900ea00000000, 0x909e9e2500000000, 0x2e5292ec00000000, + 0xe6450c2300000000, 0xff7bdfa800000000, 0x376c416700000000, + 0x8c01086400000000, 0x441696ab00000000, 0x5d28452000000000, + 0x953fdbef00000000}, + {0x0000000000000000, 0x95d4709500000000, 0x6baf90f100000000, + 0xfe7be06400000000, 0x9758503800000000, 0x028c20ad00000000, + 0xfcf7c0c900000000, 0x6923b05c00000000, 0x2eb1a07000000000, + 0xbb65d0e500000000, 0x451e308100000000, 0xd0ca401400000000, + 0xb9e9f04800000000, 0x2c3d80dd00000000, 0xd24660b900000000, + 0x4792102c00000000, 0x5c6241e100000000, 0xc9b6317400000000, + 0x37cdd11000000000, 0xa219a18500000000, 0xcb3a11d900000000, + 0x5eee614c00000000, 0xa095812800000000, 0x3541f1bd00000000, + 0x72d3e19100000000, 0xe707910400000000, 0x197c716000000000, + 0x8ca801f500000000, 0xe58bb1a900000000, 0x705fc13c00000000, + 0x8e24215800000000, 0x1bf051cd00000000, 0xf9c2f31900000000, + 0x6c16838c00000000, 0x926d63e800000000, 0x07b9137d00000000, + 0x6e9aa32100000000, 0xfb4ed3b400000000, 0x053533d000000000, + 0x90e1434500000000, 0xd773536900000000, 0x42a723fc00000000, + 0xbcdcc39800000000, 0x2908b30d00000000, 0x402b035100000000, + 0xd5ff73c400000000, 0x2b8493a000000000, 0xbe50e33500000000, + 0xa5a0b2f800000000, 0x3074c26d00000000, 0xce0f220900000000, + 0x5bdb529c00000000, 0x32f8e2c000000000, 0xa72c925500000000, + 0x5957723100000000, 0xcc8302a400000000, 0x8b11128800000000, + 0x1ec5621d00000000, 0xe0be827900000000, 0x756af2ec00000000, + 0x1c4942b000000000, 0x899d322500000000, 0x77e6d24100000000, + 0xe232a2d400000000, 0xf285e73300000000, 0x675197a600000000, + 0x992a77c200000000, 0x0cfe075700000000, 0x65ddb70b00000000, + 0xf009c79e00000000, 0x0e7227fa00000000, 0x9ba6576f00000000, + 0xdc34474300000000, 0x49e037d600000000, 0xb79bd7b200000000, + 0x224fa72700000000, 0x4b6c177b00000000, 0xdeb867ee00000000, + 0x20c3878a00000000, 0xb517f71f00000000, 0xaee7a6d200000000, + 0x3b33d64700000000, 0xc548362300000000, 0x509c46b600000000, + 0x39bff6ea00000000, 0xac6b867f00000000, 0x5210661b00000000, + 0xc7c4168e00000000, 0x805606a200000000, 0x1582763700000000, + 0xebf9965300000000, 0x7e2de6c600000000, 0x170e569a00000000, + 0x82da260f00000000, 0x7ca1c66b00000000, 0xe975b6fe00000000, + 0x0b47142a00000000, 0x9e9364bf00000000, 0x60e884db00000000, + 0xf53cf44e00000000, 0x9c1f441200000000, 0x09cb348700000000, + 0xf7b0d4e300000000, 0x6264a47600000000, 0x25f6b45a00000000, + 0xb022c4cf00000000, 0x4e5924ab00000000, 0xdb8d543e00000000, + 0xb2aee46200000000, 0x277a94f700000000, 0xd901749300000000, + 0x4cd5040600000000, 0x572555cb00000000, 0xc2f1255e00000000, + 0x3c8ac53a00000000, 0xa95eb5af00000000, 0xc07d05f300000000, + 0x55a9756600000000, 0xabd2950200000000, 0x3e06e59700000000, + 0x7994f5bb00000000, 0xec40852e00000000, 0x123b654a00000000, + 0x87ef15df00000000, 0xeecca58300000000, 0x7b18d51600000000, + 0x8563357200000000, 0x10b745e700000000, 0xe40bcf6700000000, + 0x71dfbff200000000, 0x8fa45f9600000000, 0x1a702f0300000000, + 0x73539f5f00000000, 0xe687efca00000000, 0x18fc0fae00000000, + 0x8d287f3b00000000, 0xcaba6f1700000000, 0x5f6e1f8200000000, + 0xa115ffe600000000, 0x34c18f7300000000, 0x5de23f2f00000000, + 0xc8364fba00000000, 0x364dafde00000000, 0xa399df4b00000000, + 0xb8698e8600000000, 0x2dbdfe1300000000, 0xd3c61e7700000000, + 0x46126ee200000000, 0x2f31debe00000000, 0xbae5ae2b00000000, + 0x449e4e4f00000000, 0xd14a3eda00000000, 0x96d82ef600000000, + 0x030c5e6300000000, 0xfd77be0700000000, 0x68a3ce9200000000, + 0x01807ece00000000, 0x94540e5b00000000, 0x6a2fee3f00000000, + 0xfffb9eaa00000000, 0x1dc93c7e00000000, 0x881d4ceb00000000, + 0x7666ac8f00000000, 0xe3b2dc1a00000000, 0x8a916c4600000000, + 0x1f451cd300000000, 0xe13efcb700000000, 0x74ea8c2200000000, + 0x33789c0e00000000, 0xa6acec9b00000000, 0x58d70cff00000000, + 0xcd037c6a00000000, 0xa420cc3600000000, 0x31f4bca300000000, + 0xcf8f5cc700000000, 0x5a5b2c5200000000, 0x41ab7d9f00000000, + 0xd47f0d0a00000000, 0x2a04ed6e00000000, 0xbfd09dfb00000000, + 0xd6f32da700000000, 0x43275d3200000000, 0xbd5cbd5600000000, + 0x2888cdc300000000, 0x6f1addef00000000, 0xfacead7a00000000, + 0x04b54d1e00000000, 0x91613d8b00000000, 0xf8428dd700000000, + 0x6d96fd4200000000, 0x93ed1d2600000000, 0x06396db300000000, + 0x168e285400000000, 0x835a58c100000000, 0x7d21b8a500000000, + 0xe8f5c83000000000, 0x81d6786c00000000, 0x140208f900000000, + 0xea79e89d00000000, 0x7fad980800000000, 0x383f882400000000, + 0xadebf8b100000000, 0x539018d500000000, 0xc644684000000000, + 0xaf67d81c00000000, 0x3ab3a88900000000, 0xc4c848ed00000000, + 0x511c387800000000, 0x4aec69b500000000, 0xdf38192000000000, + 0x2143f94400000000, 0xb49789d100000000, 0xddb4398d00000000, + 0x4860491800000000, 0xb61ba97c00000000, 0x23cfd9e900000000, + 0x645dc9c500000000, 0xf189b95000000000, 0x0ff2593400000000, + 0x9a2629a100000000, 0xf30599fd00000000, 0x66d1e96800000000, + 0x98aa090c00000000, 0x0d7e799900000000, 0xef4cdb4d00000000, + 0x7a98abd800000000, 0x84e34bbc00000000, 0x11373b2900000000, + 0x78148b7500000000, 0xedc0fbe000000000, 0x13bb1b8400000000, + 0x866f6b1100000000, 0xc1fd7b3d00000000, 0x54290ba800000000, + 0xaa52ebcc00000000, 0x3f869b5900000000, 0x56a52b0500000000, + 0xc3715b9000000000, 0x3d0abbf400000000, 0xa8decb6100000000, + 0xb32e9aac00000000, 0x26faea3900000000, 0xd8810a5d00000000, + 0x4d557ac800000000, 0x2476ca9400000000, 0xb1a2ba0100000000, + 0x4fd95a6500000000, 0xda0d2af000000000, 0x9d9f3adc00000000, + 0x084b4a4900000000, 0xf630aa2d00000000, 0x63e4dab800000000, + 0x0ac76ae400000000, 0x9f131a7100000000, 0x6168fa1500000000, + 0xf4bc8a8000000000}, + {0x0000000000000000, 0x1f17f08000000000, 0x7f2891da00000000, + 0x603f615a00000000, 0xbf56536e00000000, 0xa041a3ee00000000, + 0xc07ec2b400000000, 0xdf69323400000000, 0x7eada6dc00000000, + 0x61ba565c00000000, 0x0185370600000000, 0x1e92c78600000000, + 0xc1fbf5b200000000, 0xdeec053200000000, 0xbed3646800000000, + 0xa1c494e800000000, 0xbd5c3c6200000000, 0xa24bcce200000000, + 0xc274adb800000000, 0xdd635d3800000000, 0x020a6f0c00000000, + 0x1d1d9f8c00000000, 0x7d22fed600000000, 0x62350e5600000000, + 0xc3f19abe00000000, 0xdce66a3e00000000, 0xbcd90b6400000000, + 0xa3cefbe400000000, 0x7ca7c9d000000000, 0x63b0395000000000, + 0x038f580a00000000, 0x1c98a88a00000000, 0x7ab978c400000000, + 0x65ae884400000000, 0x0591e91e00000000, 0x1a86199e00000000, + 0xc5ef2baa00000000, 0xdaf8db2a00000000, 0xbac7ba7000000000, + 0xa5d04af000000000, 0x0414de1800000000, 0x1b032e9800000000, + 0x7b3c4fc200000000, 0x642bbf4200000000, 0xbb428d7600000000, + 0xa4557df600000000, 0xc46a1cac00000000, 0xdb7dec2c00000000, + 0xc7e544a600000000, 0xd8f2b42600000000, 0xb8cdd57c00000000, + 0xa7da25fc00000000, 0x78b317c800000000, 0x67a4e74800000000, + 0x079b861200000000, 0x188c769200000000, 0xb948e27a00000000, + 0xa65f12fa00000000, 0xc66073a000000000, 0xd977832000000000, + 0x061eb11400000000, 0x1909419400000000, 0x793620ce00000000, + 0x6621d04e00000000, 0xb574805300000000, 0xaa6370d300000000, + 0xca5c118900000000, 0xd54be10900000000, 0x0a22d33d00000000, + 0x153523bd00000000, 0x750a42e700000000, 0x6a1db26700000000, + 0xcbd9268f00000000, 0xd4ced60f00000000, 0xb4f1b75500000000, + 0xabe647d500000000, 0x748f75e100000000, 0x6b98856100000000, + 0x0ba7e43b00000000, 0x14b014bb00000000, 0x0828bc3100000000, + 0x173f4cb100000000, 0x77002deb00000000, 0x6817dd6b00000000, + 0xb77eef5f00000000, 0xa8691fdf00000000, 0xc8567e8500000000, + 0xd7418e0500000000, 0x76851aed00000000, 0x6992ea6d00000000, + 0x09ad8b3700000000, 0x16ba7bb700000000, 0xc9d3498300000000, + 0xd6c4b90300000000, 0xb6fbd85900000000, 0xa9ec28d900000000, + 0xcfcdf89700000000, 0xd0da081700000000, 0xb0e5694d00000000, + 0xaff299cd00000000, 0x709babf900000000, 0x6f8c5b7900000000, + 0x0fb33a2300000000, 0x10a4caa300000000, 0xb1605e4b00000000, + 0xae77aecb00000000, 0xce48cf9100000000, 0xd15f3f1100000000, + 0x0e360d2500000000, 0x1121fda500000000, 0x711e9cff00000000, + 0x6e096c7f00000000, 0x7291c4f500000000, 0x6d86347500000000, + 0x0db9552f00000000, 0x12aea5af00000000, 0xcdc7979b00000000, + 0xd2d0671b00000000, 0xb2ef064100000000, 0xadf8f6c100000000, + 0x0c3c622900000000, 0x132b92a900000000, 0x7314f3f300000000, + 0x6c03037300000000, 0xb36a314700000000, 0xac7dc1c700000000, + 0xcc42a09d00000000, 0xd355501d00000000, 0x6ae900a700000000, + 0x75fef02700000000, 0x15c1917d00000000, 0x0ad661fd00000000, + 0xd5bf53c900000000, 0xcaa8a34900000000, 0xaa97c21300000000, + 0xb580329300000000, 0x1444a67b00000000, 0x0b5356fb00000000, + 0x6b6c37a100000000, 0x747bc72100000000, 0xab12f51500000000, + 0xb405059500000000, 0xd43a64cf00000000, 0xcb2d944f00000000, + 0xd7b53cc500000000, 0xc8a2cc4500000000, 0xa89dad1f00000000, + 0xb78a5d9f00000000, 0x68e36fab00000000, 0x77f49f2b00000000, + 0x17cbfe7100000000, 0x08dc0ef100000000, 0xa9189a1900000000, + 0xb60f6a9900000000, 0xd6300bc300000000, 0xc927fb4300000000, + 0x164ec97700000000, 0x095939f700000000, 0x696658ad00000000, + 0x7671a82d00000000, 0x1050786300000000, 0x0f4788e300000000, + 0x6f78e9b900000000, 0x706f193900000000, 0xaf062b0d00000000, + 0xb011db8d00000000, 0xd02ebad700000000, 0xcf394a5700000000, + 0x6efddebf00000000, 0x71ea2e3f00000000, 0x11d54f6500000000, + 0x0ec2bfe500000000, 0xd1ab8dd100000000, 0xcebc7d5100000000, + 0xae831c0b00000000, 0xb194ec8b00000000, 0xad0c440100000000, + 0xb21bb48100000000, 0xd224d5db00000000, 0xcd33255b00000000, + 0x125a176f00000000, 0x0d4de7ef00000000, 0x6d7286b500000000, + 0x7265763500000000, 0xd3a1e2dd00000000, 0xccb6125d00000000, + 0xac89730700000000, 0xb39e838700000000, 0x6cf7b1b300000000, + 0x73e0413300000000, 0x13df206900000000, 0x0cc8d0e900000000, + 0xdf9d80f400000000, 0xc08a707400000000, 0xa0b5112e00000000, + 0xbfa2e1ae00000000, 0x60cbd39a00000000, 0x7fdc231a00000000, + 0x1fe3424000000000, 0x00f4b2c000000000, 0xa130262800000000, + 0xbe27d6a800000000, 0xde18b7f200000000, 0xc10f477200000000, + 0x1e66754600000000, 0x017185c600000000, 0x614ee49c00000000, + 0x7e59141c00000000, 0x62c1bc9600000000, 0x7dd64c1600000000, + 0x1de92d4c00000000, 0x02feddcc00000000, 0xdd97eff800000000, + 0xc2801f7800000000, 0xa2bf7e2200000000, 0xbda88ea200000000, + 0x1c6c1a4a00000000, 0x037beaca00000000, 0x63448b9000000000, + 0x7c537b1000000000, 0xa33a492400000000, 0xbc2db9a400000000, + 0xdc12d8fe00000000, 0xc305287e00000000, 0xa524f83000000000, + 0xba3308b000000000, 0xda0c69ea00000000, 0xc51b996a00000000, + 0x1a72ab5e00000000, 0x05655bde00000000, 0x655a3a8400000000, + 0x7a4dca0400000000, 0xdb895eec00000000, 0xc49eae6c00000000, + 0xa4a1cf3600000000, 0xbbb63fb600000000, 0x64df0d8200000000, + 0x7bc8fd0200000000, 0x1bf79c5800000000, 0x04e06cd800000000, + 0x1878c45200000000, 0x076f34d200000000, 0x6750558800000000, + 0x7847a50800000000, 0xa72e973c00000000, 0xb83967bc00000000, + 0xd80606e600000000, 0xc711f66600000000, 0x66d5628e00000000, + 0x79c2920e00000000, 0x19fdf35400000000, 0x06ea03d400000000, + 0xd98331e000000000, 0xc694c16000000000, 0xa6aba03a00000000, + 0xb9bc50ba00000000}, + {0x0000000000000000, 0xe2fd888d00000000, 0x85fd60c000000000, + 0x6700e84d00000000, 0x4bfdb05b00000000, 0xa90038d600000000, + 0xce00d09b00000000, 0x2cfd581600000000, 0x96fa61b700000000, + 0x7407e93a00000000, 0x1307017700000000, 0xf1fa89fa00000000, + 0xdd07d1ec00000000, 0x3ffa596100000000, 0x58fab12c00000000, + 0xba0739a100000000, 0x6df3b2b500000000, 0x8f0e3a3800000000, + 0xe80ed27500000000, 0x0af35af800000000, 0x260e02ee00000000, + 0xc4f38a6300000000, 0xa3f3622e00000000, 0x410eeaa300000000, + 0xfb09d30200000000, 0x19f45b8f00000000, 0x7ef4b3c200000000, + 0x9c093b4f00000000, 0xb0f4635900000000, 0x5209ebd400000000, + 0x3509039900000000, 0xd7f48b1400000000, 0x9be014b000000000, + 0x791d9c3d00000000, 0x1e1d747000000000, 0xfce0fcfd00000000, + 0xd01da4eb00000000, 0x32e02c6600000000, 0x55e0c42b00000000, + 0xb71d4ca600000000, 0x0d1a750700000000, 0xefe7fd8a00000000, + 0x88e715c700000000, 0x6a1a9d4a00000000, 0x46e7c55c00000000, + 0xa41a4dd100000000, 0xc31aa59c00000000, 0x21e72d1100000000, + 0xf613a60500000000, 0x14ee2e8800000000, 0x73eec6c500000000, + 0x91134e4800000000, 0xbdee165e00000000, 0x5f139ed300000000, + 0x3813769e00000000, 0xdaeefe1300000000, 0x60e9c7b200000000, + 0x82144f3f00000000, 0xe514a77200000000, 0x07e92fff00000000, + 0x2b1477e900000000, 0xc9e9ff6400000000, 0xaee9172900000000, + 0x4c149fa400000000, 0x77c758bb00000000, 0x953ad03600000000, + 0xf23a387b00000000, 0x10c7b0f600000000, 0x3c3ae8e000000000, + 0xdec7606d00000000, 0xb9c7882000000000, 0x5b3a00ad00000000, + 0xe13d390c00000000, 0x03c0b18100000000, 0x64c059cc00000000, + 0x863dd14100000000, 0xaac0895700000000, 0x483d01da00000000, + 0x2f3de99700000000, 0xcdc0611a00000000, 0x1a34ea0e00000000, + 0xf8c9628300000000, 0x9fc98ace00000000, 0x7d34024300000000, + 0x51c95a5500000000, 0xb334d2d800000000, 0xd4343a9500000000, + 0x36c9b21800000000, 0x8cce8bb900000000, 0x6e33033400000000, + 0x0933eb7900000000, 0xebce63f400000000, 0xc7333be200000000, + 0x25ceb36f00000000, 0x42ce5b2200000000, 0xa033d3af00000000, + 0xec274c0b00000000, 0x0edac48600000000, 0x69da2ccb00000000, + 0x8b27a44600000000, 0xa7dafc5000000000, 0x452774dd00000000, + 0x22279c9000000000, 0xc0da141d00000000, 0x7add2dbc00000000, + 0x9820a53100000000, 0xff204d7c00000000, 0x1dddc5f100000000, + 0x31209de700000000, 0xd3dd156a00000000, 0xb4ddfd2700000000, + 0x562075aa00000000, 0x81d4febe00000000, 0x6329763300000000, + 0x04299e7e00000000, 0xe6d416f300000000, 0xca294ee500000000, + 0x28d4c66800000000, 0x4fd42e2500000000, 0xad29a6a800000000, + 0x172e9f0900000000, 0xf5d3178400000000, 0x92d3ffc900000000, + 0x702e774400000000, 0x5cd32f5200000000, 0xbe2ea7df00000000, + 0xd92e4f9200000000, 0x3bd3c71f00000000, 0xaf88c0ad00000000, + 0x4d75482000000000, 0x2a75a06d00000000, 0xc88828e000000000, + 0xe47570f600000000, 0x0688f87b00000000, 0x6188103600000000, + 0x837598bb00000000, 0x3972a11a00000000, 0xdb8f299700000000, + 0xbc8fc1da00000000, 0x5e72495700000000, 0x728f114100000000, + 0x907299cc00000000, 0xf772718100000000, 0x158ff90c00000000, + 0xc27b721800000000, 0x2086fa9500000000, 0x478612d800000000, + 0xa57b9a5500000000, 0x8986c24300000000, 0x6b7b4ace00000000, + 0x0c7ba28300000000, 0xee862a0e00000000, 0x548113af00000000, + 0xb67c9b2200000000, 0xd17c736f00000000, 0x3381fbe200000000, + 0x1f7ca3f400000000, 0xfd812b7900000000, 0x9a81c33400000000, + 0x787c4bb900000000, 0x3468d41d00000000, 0xd6955c9000000000, + 0xb195b4dd00000000, 0x53683c5000000000, 0x7f95644600000000, + 0x9d68eccb00000000, 0xfa68048600000000, 0x18958c0b00000000, + 0xa292b5aa00000000, 0x406f3d2700000000, 0x276fd56a00000000, + 0xc5925de700000000, 0xe96f05f100000000, 0x0b928d7c00000000, + 0x6c92653100000000, 0x8e6fedbc00000000, 0x599b66a800000000, + 0xbb66ee2500000000, 0xdc66066800000000, 0x3e9b8ee500000000, + 0x1266d6f300000000, 0xf09b5e7e00000000, 0x979bb63300000000, + 0x75663ebe00000000, 0xcf61071f00000000, 0x2d9c8f9200000000, + 0x4a9c67df00000000, 0xa861ef5200000000, 0x849cb74400000000, + 0x66613fc900000000, 0x0161d78400000000, 0xe39c5f0900000000, + 0xd84f981600000000, 0x3ab2109b00000000, 0x5db2f8d600000000, + 0xbf4f705b00000000, 0x93b2284d00000000, 0x714fa0c000000000, + 0x164f488d00000000, 0xf4b2c00000000000, 0x4eb5f9a100000000, + 0xac48712c00000000, 0xcb48996100000000, 0x29b511ec00000000, + 0x054849fa00000000, 0xe7b5c17700000000, 0x80b5293a00000000, + 0x6248a1b700000000, 0xb5bc2aa300000000, 0x5741a22e00000000, + 0x30414a6300000000, 0xd2bcc2ee00000000, 0xfe419af800000000, + 0x1cbc127500000000, 0x7bbcfa3800000000, 0x994172b500000000, + 0x23464b1400000000, 0xc1bbc39900000000, 0xa6bb2bd400000000, + 0x4446a35900000000, 0x68bbfb4f00000000, 0x8a4673c200000000, + 0xed469b8f00000000, 0x0fbb130200000000, 0x43af8ca600000000, + 0xa152042b00000000, 0xc652ec6600000000, 0x24af64eb00000000, + 0x08523cfd00000000, 0xeaafb47000000000, 0x8daf5c3d00000000, + 0x6f52d4b000000000, 0xd555ed1100000000, 0x37a8659c00000000, + 0x50a88dd100000000, 0xb255055c00000000, 0x9ea85d4a00000000, + 0x7c55d5c700000000, 0x1b553d8a00000000, 0xf9a8b50700000000, + 0x2e5c3e1300000000, 0xcca1b69e00000000, 0xaba15ed300000000, + 0x495cd65e00000000, 0x65a18e4800000000, 0x875c06c500000000, + 0xe05cee8800000000, 0x02a1660500000000, 0xb8a65fa400000000, + 0x5a5bd72900000000, 0x3d5b3f6400000000, 0xdfa6b7e900000000, + 0xf35befff00000000, 0x11a6677200000000, 0x76a68f3f00000000, + 0x945b07b200000000}, + {0x0000000000000000, 0xa90b894e00000000, 0x5217129d00000000, + 0xfb1c9bd300000000, 0xe52855e100000000, 0x4c23dcaf00000000, + 0xb73f477c00000000, 0x1e34ce3200000000, 0x8b57db1900000000, + 0x225c525700000000, 0xd940c98400000000, 0x704b40ca00000000, + 0x6e7f8ef800000000, 0xc77407b600000000, 0x3c689c6500000000, + 0x9563152b00000000, 0x16afb63300000000, 0xbfa43f7d00000000, + 0x44b8a4ae00000000, 0xedb32de000000000, 0xf387e3d200000000, + 0x5a8c6a9c00000000, 0xa190f14f00000000, 0x089b780100000000, + 0x9df86d2a00000000, 0x34f3e46400000000, 0xcfef7fb700000000, + 0x66e4f6f900000000, 0x78d038cb00000000, 0xd1dbb18500000000, + 0x2ac72a5600000000, 0x83cca31800000000, 0x2c5e6d6700000000, + 0x8555e42900000000, 0x7e497ffa00000000, 0xd742f6b400000000, + 0xc976388600000000, 0x607db1c800000000, 0x9b612a1b00000000, + 0x326aa35500000000, 0xa709b67e00000000, 0x0e023f3000000000, + 0xf51ea4e300000000, 0x5c152dad00000000, 0x4221e39f00000000, + 0xeb2a6ad100000000, 0x1036f10200000000, 0xb93d784c00000000, + 0x3af1db5400000000, 0x93fa521a00000000, 0x68e6c9c900000000, + 0xc1ed408700000000, 0xdfd98eb500000000, 0x76d207fb00000000, + 0x8dce9c2800000000, 0x24c5156600000000, 0xb1a6004d00000000, + 0x18ad890300000000, 0xe3b112d000000000, 0x4aba9b9e00000000, + 0x548e55ac00000000, 0xfd85dce200000000, 0x0699473100000000, + 0xaf92ce7f00000000, 0x58bcdace00000000, 0xf1b7538000000000, + 0x0aabc85300000000, 0xa3a0411d00000000, 0xbd948f2f00000000, + 0x149f066100000000, 0xef839db200000000, 0x468814fc00000000, + 0xd3eb01d700000000, 0x7ae0889900000000, 0x81fc134a00000000, + 0x28f79a0400000000, 0x36c3543600000000, 0x9fc8dd7800000000, + 0x64d446ab00000000, 0xcddfcfe500000000, 0x4e136cfd00000000, + 0xe718e5b300000000, 0x1c047e6000000000, 0xb50ff72e00000000, + 0xab3b391c00000000, 0x0230b05200000000, 0xf92c2b8100000000, + 0x5027a2cf00000000, 0xc544b7e400000000, 0x6c4f3eaa00000000, + 0x9753a57900000000, 0x3e582c3700000000, 0x206ce20500000000, + 0x89676b4b00000000, 0x727bf09800000000, 0xdb7079d600000000, + 0x74e2b7a900000000, 0xdde93ee700000000, 0x26f5a53400000000, + 0x8ffe2c7a00000000, 0x91cae24800000000, 0x38c16b0600000000, + 0xc3ddf0d500000000, 0x6ad6799b00000000, 0xffb56cb000000000, + 0x56bee5fe00000000, 0xada27e2d00000000, 0x04a9f76300000000, + 0x1a9d395100000000, 0xb396b01f00000000, 0x488a2bcc00000000, + 0xe181a28200000000, 0x624d019a00000000, 0xcb4688d400000000, + 0x305a130700000000, 0x99519a4900000000, 0x8765547b00000000, + 0x2e6edd3500000000, 0xd57246e600000000, 0x7c79cfa800000000, + 0xe91ada8300000000, 0x401153cd00000000, 0xbb0dc81e00000000, + 0x1206415000000000, 0x0c328f6200000000, 0xa539062c00000000, + 0x5e259dff00000000, 0xf72e14b100000000, 0xf17ec44600000000, + 0x58754d0800000000, 0xa369d6db00000000, 0x0a625f9500000000, + 0x145691a700000000, 0xbd5d18e900000000, 0x4641833a00000000, + 0xef4a0a7400000000, 0x7a291f5f00000000, 0xd322961100000000, + 0x283e0dc200000000, 0x8135848c00000000, 0x9f014abe00000000, + 0x360ac3f000000000, 0xcd16582300000000, 0x641dd16d00000000, + 0xe7d1727500000000, 0x4edafb3b00000000, 0xb5c660e800000000, + 0x1ccde9a600000000, 0x02f9279400000000, 0xabf2aeda00000000, + 0x50ee350900000000, 0xf9e5bc4700000000, 0x6c86a96c00000000, + 0xc58d202200000000, 0x3e91bbf100000000, 0x979a32bf00000000, + 0x89aefc8d00000000, 0x20a575c300000000, 0xdbb9ee1000000000, + 0x72b2675e00000000, 0xdd20a92100000000, 0x742b206f00000000, + 0x8f37bbbc00000000, 0x263c32f200000000, 0x3808fcc000000000, + 0x9103758e00000000, 0x6a1fee5d00000000, 0xc314671300000000, + 0x5677723800000000, 0xff7cfb7600000000, 0x046060a500000000, + 0xad6be9eb00000000, 0xb35f27d900000000, 0x1a54ae9700000000, + 0xe148354400000000, 0x4843bc0a00000000, 0xcb8f1f1200000000, + 0x6284965c00000000, 0x99980d8f00000000, 0x309384c100000000, + 0x2ea74af300000000, 0x87acc3bd00000000, 0x7cb0586e00000000, + 0xd5bbd12000000000, 0x40d8c40b00000000, 0xe9d34d4500000000, + 0x12cfd69600000000, 0xbbc45fd800000000, 0xa5f091ea00000000, + 0x0cfb18a400000000, 0xf7e7837700000000, 0x5eec0a3900000000, + 0xa9c21e8800000000, 0x00c997c600000000, 0xfbd50c1500000000, + 0x52de855b00000000, 0x4cea4b6900000000, 0xe5e1c22700000000, + 0x1efd59f400000000, 0xb7f6d0ba00000000, 0x2295c59100000000, + 0x8b9e4cdf00000000, 0x7082d70c00000000, 0xd9895e4200000000, + 0xc7bd907000000000, 0x6eb6193e00000000, 0x95aa82ed00000000, + 0x3ca10ba300000000, 0xbf6da8bb00000000, 0x166621f500000000, + 0xed7aba2600000000, 0x4471336800000000, 0x5a45fd5a00000000, + 0xf34e741400000000, 0x0852efc700000000, 0xa159668900000000, + 0x343a73a200000000, 0x9d31faec00000000, 0x662d613f00000000, + 0xcf26e87100000000, 0xd112264300000000, 0x7819af0d00000000, + 0x830534de00000000, 0x2a0ebd9000000000, 0x859c73ef00000000, + 0x2c97faa100000000, 0xd78b617200000000, 0x7e80e83c00000000, + 0x60b4260e00000000, 0xc9bfaf4000000000, 0x32a3349300000000, + 0x9ba8bddd00000000, 0x0ecba8f600000000, 0xa7c021b800000000, + 0x5cdcba6b00000000, 0xf5d7332500000000, 0xebe3fd1700000000, + 0x42e8745900000000, 0xb9f4ef8a00000000, 0x10ff66c400000000, + 0x9333c5dc00000000, 0x3a384c9200000000, 0xc124d74100000000, + 0x682f5e0f00000000, 0x761b903d00000000, 0xdf10197300000000, + 0x240c82a000000000, 0x8d070bee00000000, 0x18641ec500000000, + 0xb16f978b00000000, 0x4a730c5800000000, 0xe378851600000000, + 0xfd4c4b2400000000, 0x5447c26a00000000, 0xaf5b59b900000000, + 0x0650d0f700000000}, + {0x0000000000000000, 0x479244af00000000, 0xcf22f88500000000, + 0x88b0bc2a00000000, 0xdf4381d000000000, 0x98d1c57f00000000, + 0x1061795500000000, 0x57f33dfa00000000, 0xff81737a00000000, + 0xb81337d500000000, 0x30a38bff00000000, 0x7731cf5000000000, + 0x20c2f2aa00000000, 0x6750b60500000000, 0xefe00a2f00000000, + 0xa8724e8000000000, 0xfe03e7f400000000, 0xb991a35b00000000, + 0x31211f7100000000, 0x76b35bde00000000, 0x2140662400000000, + 0x66d2228b00000000, 0xee629ea100000000, 0xa9f0da0e00000000, + 0x0182948e00000000, 0x4610d02100000000, 0xcea06c0b00000000, + 0x893228a400000000, 0xdec1155e00000000, 0x995351f100000000, + 0x11e3eddb00000000, 0x5671a97400000000, 0xbd01bf3200000000, + 0xfa93fb9d00000000, 0x722347b700000000, 0x35b1031800000000, + 0x62423ee200000000, 0x25d07a4d00000000, 0xad60c66700000000, + 0xeaf282c800000000, 0x4280cc4800000000, 0x051288e700000000, + 0x8da234cd00000000, 0xca30706200000000, 0x9dc34d9800000000, + 0xda51093700000000, 0x52e1b51d00000000, 0x1573f1b200000000, + 0x430258c600000000, 0x04901c6900000000, 0x8c20a04300000000, + 0xcbb2e4ec00000000, 0x9c41d91600000000, 0xdbd39db900000000, + 0x5363219300000000, 0x14f1653c00000000, 0xbc832bbc00000000, + 0xfb116f1300000000, 0x73a1d33900000000, 0x3433979600000000, + 0x63c0aa6c00000000, 0x2452eec300000000, 0xace252e900000000, + 0xeb70164600000000, 0x7a037e6500000000, 0x3d913aca00000000, + 0xb52186e000000000, 0xf2b3c24f00000000, 0xa540ffb500000000, + 0xe2d2bb1a00000000, 0x6a62073000000000, 0x2df0439f00000000, + 0x85820d1f00000000, 0xc21049b000000000, 0x4aa0f59a00000000, + 0x0d32b13500000000, 0x5ac18ccf00000000, 0x1d53c86000000000, + 0x95e3744a00000000, 0xd27130e500000000, 0x8400999100000000, + 0xc392dd3e00000000, 0x4b22611400000000, 0x0cb025bb00000000, + 0x5b43184100000000, 0x1cd15cee00000000, 0x9461e0c400000000, + 0xd3f3a46b00000000, 0x7b81eaeb00000000, 0x3c13ae4400000000, + 0xb4a3126e00000000, 0xf33156c100000000, 0xa4c26b3b00000000, + 0xe3502f9400000000, 0x6be093be00000000, 0x2c72d71100000000, + 0xc702c15700000000, 0x809085f800000000, 0x082039d200000000, + 0x4fb27d7d00000000, 0x1841408700000000, 0x5fd3042800000000, + 0xd763b80200000000, 0x90f1fcad00000000, 0x3883b22d00000000, + 0x7f11f68200000000, 0xf7a14aa800000000, 0xb0330e0700000000, + 0xe7c033fd00000000, 0xa052775200000000, 0x28e2cb7800000000, + 0x6f708fd700000000, 0x390126a300000000, 0x7e93620c00000000, + 0xf623de2600000000, 0xb1b19a8900000000, 0xe642a77300000000, + 0xa1d0e3dc00000000, 0x29605ff600000000, 0x6ef21b5900000000, + 0xc68055d900000000, 0x8112117600000000, 0x09a2ad5c00000000, + 0x4e30e9f300000000, 0x19c3d40900000000, 0x5e5190a600000000, + 0xd6e12c8c00000000, 0x9173682300000000, 0xf406fcca00000000, + 0xb394b86500000000, 0x3b24044f00000000, 0x7cb640e000000000, + 0x2b457d1a00000000, 0x6cd739b500000000, 0xe467859f00000000, + 0xa3f5c13000000000, 0x0b878fb000000000, 0x4c15cb1f00000000, + 0xc4a5773500000000, 0x8337339a00000000, 0xd4c40e6000000000, + 0x93564acf00000000, 0x1be6f6e500000000, 0x5c74b24a00000000, + 0x0a051b3e00000000, 0x4d975f9100000000, 0xc527e3bb00000000, + 0x82b5a71400000000, 0xd5469aee00000000, 0x92d4de4100000000, + 0x1a64626b00000000, 0x5df626c400000000, 0xf584684400000000, + 0xb2162ceb00000000, 0x3aa690c100000000, 0x7d34d46e00000000, + 0x2ac7e99400000000, 0x6d55ad3b00000000, 0xe5e5111100000000, + 0xa27755be00000000, 0x490743f800000000, 0x0e95075700000000, + 0x8625bb7d00000000, 0xc1b7ffd200000000, 0x9644c22800000000, + 0xd1d6868700000000, 0x59663aad00000000, 0x1ef47e0200000000, + 0xb686308200000000, 0xf114742d00000000, 0x79a4c80700000000, + 0x3e368ca800000000, 0x69c5b15200000000, 0x2e57f5fd00000000, + 0xa6e749d700000000, 0xe1750d7800000000, 0xb704a40c00000000, + 0xf096e0a300000000, 0x78265c8900000000, 0x3fb4182600000000, + 0x684725dc00000000, 0x2fd5617300000000, 0xa765dd5900000000, + 0xe0f799f600000000, 0x4885d77600000000, 0x0f1793d900000000, + 0x87a72ff300000000, 0xc0356b5c00000000, 0x97c656a600000000, + 0xd054120900000000, 0x58e4ae2300000000, 0x1f76ea8c00000000, + 0x8e0582af00000000, 0xc997c60000000000, 0x41277a2a00000000, + 0x06b53e8500000000, 0x5146037f00000000, 0x16d447d000000000, + 0x9e64fbfa00000000, 0xd9f6bf5500000000, 0x7184f1d500000000, + 0x3616b57a00000000, 0xbea6095000000000, 0xf9344dff00000000, + 0xaec7700500000000, 0xe95534aa00000000, 0x61e5888000000000, + 0x2677cc2f00000000, 0x7006655b00000000, 0x379421f400000000, + 0xbf249dde00000000, 0xf8b6d97100000000, 0xaf45e48b00000000, + 0xe8d7a02400000000, 0x60671c0e00000000, 0x27f558a100000000, + 0x8f87162100000000, 0xc815528e00000000, 0x40a5eea400000000, + 0x0737aa0b00000000, 0x50c497f100000000, 0x1756d35e00000000, + 0x9fe66f7400000000, 0xd8742bdb00000000, 0x33043d9d00000000, + 0x7496793200000000, 0xfc26c51800000000, 0xbbb481b700000000, + 0xec47bc4d00000000, 0xabd5f8e200000000, 0x236544c800000000, + 0x64f7006700000000, 0xcc854ee700000000, 0x8b170a4800000000, + 0x03a7b66200000000, 0x4435f2cd00000000, 0x13c6cf3700000000, + 0x54548b9800000000, 0xdce437b200000000, 0x9b76731d00000000, + 0xcd07da6900000000, 0x8a959ec600000000, 0x022522ec00000000, + 0x45b7664300000000, 0x12445bb900000000, 0x55d61f1600000000, + 0xdd66a33c00000000, 0x9af4e79300000000, 0x3286a91300000000, + 0x7514edbc00000000, 0xfda4519600000000, 0xba36153900000000, + 0xedc528c300000000, 0xaa576c6c00000000, 0x22e7d04600000000, + 0x657594e900000000}}; + +#else /* W == 4 */ + +local const z_crc_t FAR crc_braid_table[][256] = { + {0x00000000, 0x65673b46, 0xcace768c, 0xafa94dca, 0x4eedeb59, + 0x2b8ad01f, 0x84239dd5, 0xe144a693, 0x9ddbd6b2, 0xf8bcedf4, + 0x5715a03e, 0x32729b78, 0xd3363deb, 0xb65106ad, 0x19f84b67, + 0x7c9f7021, 0xe0c6ab25, 0x85a19063, 0x2a08dda9, 0x4f6fe6ef, + 0xae2b407c, 0xcb4c7b3a, 0x64e536f0, 0x01820db6, 0x7d1d7d97, + 0x187a46d1, 0xb7d30b1b, 0xd2b4305d, 0x33f096ce, 0x5697ad88, + 0xf93ee042, 0x9c59db04, 0x1afc500b, 0x7f9b6b4d, 0xd0322687, + 0xb5551dc1, 0x5411bb52, 0x31768014, 0x9edfcdde, 0xfbb8f698, + 0x872786b9, 0xe240bdff, 0x4de9f035, 0x288ecb73, 0xc9ca6de0, + 0xacad56a6, 0x03041b6c, 0x6663202a, 0xfa3afb2e, 0x9f5dc068, + 0x30f48da2, 0x5593b6e4, 0xb4d71077, 0xd1b02b31, 0x7e1966fb, + 0x1b7e5dbd, 0x67e12d9c, 0x028616da, 0xad2f5b10, 0xc8486056, + 0x290cc6c5, 0x4c6bfd83, 0xe3c2b049, 0x86a58b0f, 0x35f8a016, + 0x509f9b50, 0xff36d69a, 0x9a51eddc, 0x7b154b4f, 0x1e727009, + 0xb1db3dc3, 0xd4bc0685, 0xa82376a4, 0xcd444de2, 0x62ed0028, + 0x078a3b6e, 0xe6ce9dfd, 0x83a9a6bb, 0x2c00eb71, 0x4967d037, + 0xd53e0b33, 0xb0593075, 0x1ff07dbf, 0x7a9746f9, 0x9bd3e06a, + 0xfeb4db2c, 0x511d96e6, 0x347aada0, 0x48e5dd81, 0x2d82e6c7, + 0x822bab0d, 0xe74c904b, 0x060836d8, 0x636f0d9e, 0xccc64054, + 0xa9a17b12, 0x2f04f01d, 0x4a63cb5b, 0xe5ca8691, 0x80adbdd7, + 0x61e91b44, 0x048e2002, 0xab276dc8, 0xce40568e, 0xb2df26af, + 0xd7b81de9, 0x78115023, 0x1d766b65, 0xfc32cdf6, 0x9955f6b0, + 0x36fcbb7a, 0x539b803c, 0xcfc25b38, 0xaaa5607e, 0x050c2db4, + 0x606b16f2, 0x812fb061, 0xe4488b27, 0x4be1c6ed, 0x2e86fdab, + 0x52198d8a, 0x377eb6cc, 0x98d7fb06, 0xfdb0c040, 0x1cf466d3, + 0x79935d95, 0xd63a105f, 0xb35d2b19, 0x6bf1402c, 0x0e967b6a, + 0xa13f36a0, 0xc4580de6, 0x251cab75, 0x407b9033, 0xefd2ddf9, + 0x8ab5e6bf, 0xf62a969e, 0x934dadd8, 0x3ce4e012, 0x5983db54, + 0xb8c77dc7, 0xdda04681, 0x72090b4b, 0x176e300d, 0x8b37eb09, + 0xee50d04f, 0x41f99d85, 0x249ea6c3, 0xc5da0050, 0xa0bd3b16, + 0x0f1476dc, 0x6a734d9a, 0x16ec3dbb, 0x738b06fd, 0xdc224b37, + 0xb9457071, 0x5801d6e2, 0x3d66eda4, 0x92cfa06e, 0xf7a89b28, + 0x710d1027, 0x146a2b61, 0xbbc366ab, 0xdea45ded, 0x3fe0fb7e, + 0x5a87c038, 0xf52e8df2, 0x9049b6b4, 0xecd6c695, 0x89b1fdd3, + 0x2618b019, 0x437f8b5f, 0xa23b2dcc, 0xc75c168a, 0x68f55b40, + 0x0d926006, 0x91cbbb02, 0xf4ac8044, 0x5b05cd8e, 0x3e62f6c8, + 0xdf26505b, 0xba416b1d, 0x15e826d7, 0x708f1d91, 0x0c106db0, + 0x697756f6, 0xc6de1b3c, 0xa3b9207a, 0x42fd86e9, 0x279abdaf, + 0x8833f065, 0xed54cb23, 0x5e09e03a, 0x3b6edb7c, 0x94c796b6, + 0xf1a0adf0, 0x10e40b63, 0x75833025, 0xda2a7def, 0xbf4d46a9, + 0xc3d23688, 0xa6b50dce, 0x091c4004, 0x6c7b7b42, 0x8d3fddd1, + 0xe858e697, 0x47f1ab5d, 0x2296901b, 0xbecf4b1f, 0xdba87059, + 0x74013d93, 0x116606d5, 0xf022a046, 0x95459b00, 0x3aecd6ca, + 0x5f8bed8c, 0x23149dad, 0x4673a6eb, 0xe9daeb21, 0x8cbdd067, + 0x6df976f4, 0x089e4db2, 0xa7370078, 0xc2503b3e, 0x44f5b031, + 0x21928b77, 0x8e3bc6bd, 0xeb5cfdfb, 0x0a185b68, 0x6f7f602e, + 0xc0d62de4, 0xa5b116a2, 0xd92e6683, 0xbc495dc5, 0x13e0100f, + 0x76872b49, 0x97c38dda, 0xf2a4b69c, 0x5d0dfb56, 0x386ac010, + 0xa4331b14, 0xc1542052, 0x6efd6d98, 0x0b9a56de, 0xeadef04d, + 0x8fb9cb0b, 0x201086c1, 0x4577bd87, 0x39e8cda6, 0x5c8ff6e0, + 0xf326bb2a, 0x9641806c, 0x770526ff, 0x12621db9, 0xbdcb5073, + 0xd8ac6b35}, + {0x00000000, 0xd7e28058, 0x74b406f1, 0xa35686a9, 0xe9680de2, + 0x3e8a8dba, 0x9ddc0b13, 0x4a3e8b4b, 0x09a11d85, 0xde439ddd, + 0x7d151b74, 0xaaf79b2c, 0xe0c91067, 0x372b903f, 0x947d1696, + 0x439f96ce, 0x13423b0a, 0xc4a0bb52, 0x67f63dfb, 0xb014bda3, + 0xfa2a36e8, 0x2dc8b6b0, 0x8e9e3019, 0x597cb041, 0x1ae3268f, + 0xcd01a6d7, 0x6e57207e, 0xb9b5a026, 0xf38b2b6d, 0x2469ab35, + 0x873f2d9c, 0x50ddadc4, 0x26847614, 0xf166f64c, 0x523070e5, + 0x85d2f0bd, 0xcfec7bf6, 0x180efbae, 0xbb587d07, 0x6cbafd5f, + 0x2f256b91, 0xf8c7ebc9, 0x5b916d60, 0x8c73ed38, 0xc64d6673, + 0x11afe62b, 0xb2f96082, 0x651be0da, 0x35c64d1e, 0xe224cd46, + 0x41724bef, 0x9690cbb7, 0xdcae40fc, 0x0b4cc0a4, 0xa81a460d, + 0x7ff8c655, 0x3c67509b, 0xeb85d0c3, 0x48d3566a, 0x9f31d632, + 0xd50f5d79, 0x02eddd21, 0xa1bb5b88, 0x7659dbd0, 0x4d08ec28, + 0x9aea6c70, 0x39bcead9, 0xee5e6a81, 0xa460e1ca, 0x73826192, + 0xd0d4e73b, 0x07366763, 0x44a9f1ad, 0x934b71f5, 0x301df75c, + 0xe7ff7704, 0xadc1fc4f, 0x7a237c17, 0xd975fabe, 0x0e977ae6, + 0x5e4ad722, 0x89a8577a, 0x2afed1d3, 0xfd1c518b, 0xb722dac0, + 0x60c05a98, 0xc396dc31, 0x14745c69, 0x57ebcaa7, 0x80094aff, + 0x235fcc56, 0xf4bd4c0e, 0xbe83c745, 0x6961471d, 0xca37c1b4, + 0x1dd541ec, 0x6b8c9a3c, 0xbc6e1a64, 0x1f389ccd, 0xc8da1c95, + 0x82e497de, 0x55061786, 0xf650912f, 0x21b21177, 0x622d87b9, + 0xb5cf07e1, 0x16998148, 0xc17b0110, 0x8b458a5b, 0x5ca70a03, + 0xfff18caa, 0x28130cf2, 0x78cea136, 0xaf2c216e, 0x0c7aa7c7, + 0xdb98279f, 0x91a6acd4, 0x46442c8c, 0xe512aa25, 0x32f02a7d, + 0x716fbcb3, 0xa68d3ceb, 0x05dbba42, 0xd2393a1a, 0x9807b151, + 0x4fe53109, 0xecb3b7a0, 0x3b5137f8, 0x9a11d850, 0x4df35808, + 0xeea5dea1, 0x39475ef9, 0x7379d5b2, 0xa49b55ea, 0x07cdd343, + 0xd02f531b, 0x93b0c5d5, 0x4452458d, 0xe704c324, 0x30e6437c, + 0x7ad8c837, 0xad3a486f, 0x0e6ccec6, 0xd98e4e9e, 0x8953e35a, + 0x5eb16302, 0xfde7e5ab, 0x2a0565f3, 0x603beeb8, 0xb7d96ee0, + 0x148fe849, 0xc36d6811, 0x80f2fedf, 0x57107e87, 0xf446f82e, + 0x23a47876, 0x699af33d, 0xbe787365, 0x1d2ef5cc, 0xcacc7594, + 0xbc95ae44, 0x6b772e1c, 0xc821a8b5, 0x1fc328ed, 0x55fda3a6, + 0x821f23fe, 0x2149a557, 0xf6ab250f, 0xb534b3c1, 0x62d63399, + 0xc180b530, 0x16623568, 0x5c5cbe23, 0x8bbe3e7b, 0x28e8b8d2, + 0xff0a388a, 0xafd7954e, 0x78351516, 0xdb6393bf, 0x0c8113e7, + 0x46bf98ac, 0x915d18f4, 0x320b9e5d, 0xe5e91e05, 0xa67688cb, + 0x71940893, 0xd2c28e3a, 0x05200e62, 0x4f1e8529, 0x98fc0571, + 0x3baa83d8, 0xec480380, 0xd7193478, 0x00fbb420, 0xa3ad3289, + 0x744fb2d1, 0x3e71399a, 0xe993b9c2, 0x4ac53f6b, 0x9d27bf33, + 0xdeb829fd, 0x095aa9a5, 0xaa0c2f0c, 0x7deeaf54, 0x37d0241f, + 0xe032a447, 0x436422ee, 0x9486a2b6, 0xc45b0f72, 0x13b98f2a, + 0xb0ef0983, 0x670d89db, 0x2d330290, 0xfad182c8, 0x59870461, + 0x8e658439, 0xcdfa12f7, 0x1a1892af, 0xb94e1406, 0x6eac945e, + 0x24921f15, 0xf3709f4d, 0x502619e4, 0x87c499bc, 0xf19d426c, + 0x267fc234, 0x8529449d, 0x52cbc4c5, 0x18f54f8e, 0xcf17cfd6, + 0x6c41497f, 0xbba3c927, 0xf83c5fe9, 0x2fdedfb1, 0x8c885918, + 0x5b6ad940, 0x1154520b, 0xc6b6d253, 0x65e054fa, 0xb202d4a2, + 0xe2df7966, 0x353df93e, 0x966b7f97, 0x4189ffcf, 0x0bb77484, + 0xdc55f4dc, 0x7f037275, 0xa8e1f22d, 0xeb7e64e3, 0x3c9ce4bb, + 0x9fca6212, 0x4828e24a, 0x02166901, 0xd5f4e959, 0x76a26ff0, + 0xa140efa8}, + {0x00000000, 0xef52b6e1, 0x05d46b83, 0xea86dd62, 0x0ba8d706, + 0xe4fa61e7, 0x0e7cbc85, 0xe12e0a64, 0x1751ae0c, 0xf80318ed, + 0x1285c58f, 0xfdd7736e, 0x1cf9790a, 0xf3abcfeb, 0x192d1289, + 0xf67fa468, 0x2ea35c18, 0xc1f1eaf9, 0x2b77379b, 0xc425817a, + 0x250b8b1e, 0xca593dff, 0x20dfe09d, 0xcf8d567c, 0x39f2f214, + 0xd6a044f5, 0x3c269997, 0xd3742f76, 0x325a2512, 0xdd0893f3, + 0x378e4e91, 0xd8dcf870, 0x5d46b830, 0xb2140ed1, 0x5892d3b3, + 0xb7c06552, 0x56ee6f36, 0xb9bcd9d7, 0x533a04b5, 0xbc68b254, + 0x4a17163c, 0xa545a0dd, 0x4fc37dbf, 0xa091cb5e, 0x41bfc13a, + 0xaeed77db, 0x446baab9, 0xab391c58, 0x73e5e428, 0x9cb752c9, + 0x76318fab, 0x9963394a, 0x784d332e, 0x971f85cf, 0x7d9958ad, + 0x92cbee4c, 0x64b44a24, 0x8be6fcc5, 0x616021a7, 0x8e329746, + 0x6f1c9d22, 0x804e2bc3, 0x6ac8f6a1, 0x859a4040, 0xba8d7060, + 0x55dfc681, 0xbf591be3, 0x500bad02, 0xb125a766, 0x5e771187, + 0xb4f1cce5, 0x5ba37a04, 0xaddcde6c, 0x428e688d, 0xa808b5ef, + 0x475a030e, 0xa674096a, 0x4926bf8b, 0xa3a062e9, 0x4cf2d408, + 0x942e2c78, 0x7b7c9a99, 0x91fa47fb, 0x7ea8f11a, 0x9f86fb7e, + 0x70d44d9f, 0x9a5290fd, 0x7500261c, 0x837f8274, 0x6c2d3495, + 0x86abe9f7, 0x69f95f16, 0x88d75572, 0x6785e393, 0x8d033ef1, + 0x62518810, 0xe7cbc850, 0x08997eb1, 0xe21fa3d3, 0x0d4d1532, + 0xec631f56, 0x0331a9b7, 0xe9b774d5, 0x06e5c234, 0xf09a665c, + 0x1fc8d0bd, 0xf54e0ddf, 0x1a1cbb3e, 0xfb32b15a, 0x146007bb, + 0xfee6dad9, 0x11b46c38, 0xc9689448, 0x263a22a9, 0xccbcffcb, + 0x23ee492a, 0xc2c0434e, 0x2d92f5af, 0xc71428cd, 0x28469e2c, + 0xde393a44, 0x316b8ca5, 0xdbed51c7, 0x34bfe726, 0xd591ed42, + 0x3ac35ba3, 0xd04586c1, 0x3f173020, 0xae6be681, 0x41395060, + 0xabbf8d02, 0x44ed3be3, 0xa5c33187, 0x4a918766, 0xa0175a04, + 0x4f45ece5, 0xb93a488d, 0x5668fe6c, 0xbcee230e, 0x53bc95ef, + 0xb2929f8b, 0x5dc0296a, 0xb746f408, 0x581442e9, 0x80c8ba99, + 0x6f9a0c78, 0x851cd11a, 0x6a4e67fb, 0x8b606d9f, 0x6432db7e, + 0x8eb4061c, 0x61e6b0fd, 0x97991495, 0x78cba274, 0x924d7f16, + 0x7d1fc9f7, 0x9c31c393, 0x73637572, 0x99e5a810, 0x76b71ef1, + 0xf32d5eb1, 0x1c7fe850, 0xf6f93532, 0x19ab83d3, 0xf88589b7, + 0x17d73f56, 0xfd51e234, 0x120354d5, 0xe47cf0bd, 0x0b2e465c, + 0xe1a89b3e, 0x0efa2ddf, 0xefd427bb, 0x0086915a, 0xea004c38, + 0x0552fad9, 0xdd8e02a9, 0x32dcb448, 0xd85a692a, 0x3708dfcb, + 0xd626d5af, 0x3974634e, 0xd3f2be2c, 0x3ca008cd, 0xcadfaca5, + 0x258d1a44, 0xcf0bc726, 0x205971c7, 0xc1777ba3, 0x2e25cd42, + 0xc4a31020, 0x2bf1a6c1, 0x14e696e1, 0xfbb42000, 0x1132fd62, + 0xfe604b83, 0x1f4e41e7, 0xf01cf706, 0x1a9a2a64, 0xf5c89c85, + 0x03b738ed, 0xece58e0c, 0x0663536e, 0xe931e58f, 0x081fefeb, + 0xe74d590a, 0x0dcb8468, 0xe2993289, 0x3a45caf9, 0xd5177c18, + 0x3f91a17a, 0xd0c3179b, 0x31ed1dff, 0xdebfab1e, 0x3439767c, + 0xdb6bc09d, 0x2d1464f5, 0xc246d214, 0x28c00f76, 0xc792b997, + 0x26bcb3f3, 0xc9ee0512, 0x2368d870, 0xcc3a6e91, 0x49a02ed1, + 0xa6f29830, 0x4c744552, 0xa326f3b3, 0x4208f9d7, 0xad5a4f36, + 0x47dc9254, 0xa88e24b5, 0x5ef180dd, 0xb1a3363c, 0x5b25eb5e, + 0xb4775dbf, 0x555957db, 0xba0be13a, 0x508d3c58, 0xbfdf8ab9, + 0x670372c9, 0x8851c428, 0x62d7194a, 0x8d85afab, 0x6caba5cf, + 0x83f9132e, 0x697fce4c, 0x862d78ad, 0x7052dcc5, 0x9f006a24, + 0x7586b746, 0x9ad401a7, 0x7bfa0bc3, 0x94a8bd22, 0x7e2e6040, + 0x917cd6a1}, + {0x00000000, 0x87a6cb43, 0xd43c90c7, 0x539a5b84, 0x730827cf, + 0xf4aeec8c, 0xa734b708, 0x20927c4b, 0xe6104f9e, 0x61b684dd, + 0x322cdf59, 0xb58a141a, 0x95186851, 0x12bea312, 0x4124f896, + 0xc68233d5, 0x1751997d, 0x90f7523e, 0xc36d09ba, 0x44cbc2f9, + 0x6459beb2, 0xe3ff75f1, 0xb0652e75, 0x37c3e536, 0xf141d6e3, + 0x76e71da0, 0x257d4624, 0xa2db8d67, 0x8249f12c, 0x05ef3a6f, + 0x567561eb, 0xd1d3aaa8, 0x2ea332fa, 0xa905f9b9, 0xfa9fa23d, + 0x7d39697e, 0x5dab1535, 0xda0dde76, 0x899785f2, 0x0e314eb1, + 0xc8b37d64, 0x4f15b627, 0x1c8feda3, 0x9b2926e0, 0xbbbb5aab, + 0x3c1d91e8, 0x6f87ca6c, 0xe821012f, 0x39f2ab87, 0xbe5460c4, + 0xedce3b40, 0x6a68f003, 0x4afa8c48, 0xcd5c470b, 0x9ec61c8f, + 0x1960d7cc, 0xdfe2e419, 0x58442f5a, 0x0bde74de, 0x8c78bf9d, + 0xaceac3d6, 0x2b4c0895, 0x78d65311, 0xff709852, 0x5d4665f4, + 0xdae0aeb7, 0x897af533, 0x0edc3e70, 0x2e4e423b, 0xa9e88978, + 0xfa72d2fc, 0x7dd419bf, 0xbb562a6a, 0x3cf0e129, 0x6f6abaad, + 0xe8cc71ee, 0xc85e0da5, 0x4ff8c6e6, 0x1c629d62, 0x9bc45621, + 0x4a17fc89, 0xcdb137ca, 0x9e2b6c4e, 0x198da70d, 0x391fdb46, + 0xbeb91005, 0xed234b81, 0x6a8580c2, 0xac07b317, 0x2ba17854, + 0x783b23d0, 0xff9de893, 0xdf0f94d8, 0x58a95f9b, 0x0b33041f, + 0x8c95cf5c, 0x73e5570e, 0xf4439c4d, 0xa7d9c7c9, 0x207f0c8a, + 0x00ed70c1, 0x874bbb82, 0xd4d1e006, 0x53772b45, 0x95f51890, + 0x1253d3d3, 0x41c98857, 0xc66f4314, 0xe6fd3f5f, 0x615bf41c, + 0x32c1af98, 0xb56764db, 0x64b4ce73, 0xe3120530, 0xb0885eb4, + 0x372e95f7, 0x17bce9bc, 0x901a22ff, 0xc380797b, 0x4426b238, + 0x82a481ed, 0x05024aae, 0x5698112a, 0xd13eda69, 0xf1aca622, + 0x760a6d61, 0x259036e5, 0xa236fda6, 0xba8ccbe8, 0x3d2a00ab, + 0x6eb05b2f, 0xe916906c, 0xc984ec27, 0x4e222764, 0x1db87ce0, + 0x9a1eb7a3, 0x5c9c8476, 0xdb3a4f35, 0x88a014b1, 0x0f06dff2, + 0x2f94a3b9, 0xa83268fa, 0xfba8337e, 0x7c0ef83d, 0xaddd5295, + 0x2a7b99d6, 0x79e1c252, 0xfe470911, 0xded5755a, 0x5973be19, + 0x0ae9e59d, 0x8d4f2ede, 0x4bcd1d0b, 0xcc6bd648, 0x9ff18dcc, + 0x1857468f, 0x38c53ac4, 0xbf63f187, 0xecf9aa03, 0x6b5f6140, + 0x942ff912, 0x13893251, 0x401369d5, 0xc7b5a296, 0xe727dedd, + 0x6081159e, 0x331b4e1a, 0xb4bd8559, 0x723fb68c, 0xf5997dcf, + 0xa603264b, 0x21a5ed08, 0x01379143, 0x86915a00, 0xd50b0184, + 0x52adcac7, 0x837e606f, 0x04d8ab2c, 0x5742f0a8, 0xd0e43beb, + 0xf07647a0, 0x77d08ce3, 0x244ad767, 0xa3ec1c24, 0x656e2ff1, + 0xe2c8e4b2, 0xb152bf36, 0x36f47475, 0x1666083e, 0x91c0c37d, + 0xc25a98f9, 0x45fc53ba, 0xe7caae1c, 0x606c655f, 0x33f63edb, + 0xb450f598, 0x94c289d3, 0x13644290, 0x40fe1914, 0xc758d257, + 0x01dae182, 0x867c2ac1, 0xd5e67145, 0x5240ba06, 0x72d2c64d, + 0xf5740d0e, 0xa6ee568a, 0x21489dc9, 0xf09b3761, 0x773dfc22, + 0x24a7a7a6, 0xa3016ce5, 0x839310ae, 0x0435dbed, 0x57af8069, + 0xd0094b2a, 0x168b78ff, 0x912db3bc, 0xc2b7e838, 0x4511237b, + 0x65835f30, 0xe2259473, 0xb1bfcff7, 0x361904b4, 0xc9699ce6, + 0x4ecf57a5, 0x1d550c21, 0x9af3c762, 0xba61bb29, 0x3dc7706a, + 0x6e5d2bee, 0xe9fbe0ad, 0x2f79d378, 0xa8df183b, 0xfb4543bf, + 0x7ce388fc, 0x5c71f4b7, 0xdbd73ff4, 0x884d6470, 0x0febaf33, + 0xde38059b, 0x599eced8, 0x0a04955c, 0x8da25e1f, 0xad302254, + 0x2a96e917, 0x790cb293, 0xfeaa79d0, 0x38284a05, 0xbf8e8146, + 0xec14dac2, 0x6bb21181, 0x4b206dca, 0xcc86a689, 0x9f1cfd0d, + 0x18ba364e}}; + +local const z_word_t FAR crc_braid_big_table[][256] = { + {0x00000000, 0x43cba687, 0xc7903cd4, 0x845b9a53, 0xcf270873, + 0x8cecaef4, 0x08b734a7, 0x4b7c9220, 0x9e4f10e6, 0xdd84b661, + 0x59df2c32, 0x1a148ab5, 0x51681895, 0x12a3be12, 0x96f82441, + 0xd53382c6, 0x7d995117, 0x3e52f790, 0xba096dc3, 0xf9c2cb44, + 0xb2be5964, 0xf175ffe3, 0x752e65b0, 0x36e5c337, 0xe3d641f1, + 0xa01de776, 0x24467d25, 0x678ddba2, 0x2cf14982, 0x6f3aef05, + 0xeb617556, 0xa8aad3d1, 0xfa32a32e, 0xb9f905a9, 0x3da29ffa, + 0x7e69397d, 0x3515ab5d, 0x76de0dda, 0xf2859789, 0xb14e310e, + 0x647db3c8, 0x27b6154f, 0xa3ed8f1c, 0xe026299b, 0xab5abbbb, + 0xe8911d3c, 0x6cca876f, 0x2f0121e8, 0x87abf239, 0xc46054be, + 0x403bceed, 0x03f0686a, 0x488cfa4a, 0x0b475ccd, 0x8f1cc69e, + 0xccd76019, 0x19e4e2df, 0x5a2f4458, 0xde74de0b, 0x9dbf788c, + 0xd6c3eaac, 0x95084c2b, 0x1153d678, 0x529870ff, 0xf465465d, + 0xb7aee0da, 0x33f57a89, 0x703edc0e, 0x3b424e2e, 0x7889e8a9, + 0xfcd272fa, 0xbf19d47d, 0x6a2a56bb, 0x29e1f03c, 0xadba6a6f, + 0xee71cce8, 0xa50d5ec8, 0xe6c6f84f, 0x629d621c, 0x2156c49b, + 0x89fc174a, 0xca37b1cd, 0x4e6c2b9e, 0x0da78d19, 0x46db1f39, + 0x0510b9be, 0x814b23ed, 0xc280856a, 0x17b307ac, 0x5478a12b, + 0xd0233b78, 0x93e89dff, 0xd8940fdf, 0x9b5fa958, 0x1f04330b, + 0x5ccf958c, 0x0e57e573, 0x4d9c43f4, 0xc9c7d9a7, 0x8a0c7f20, + 0xc170ed00, 0x82bb4b87, 0x06e0d1d4, 0x452b7753, 0x9018f595, + 0xd3d35312, 0x5788c941, 0x14436fc6, 0x5f3ffde6, 0x1cf45b61, + 0x98afc132, 0xdb6467b5, 0x73ceb464, 0x300512e3, 0xb45e88b0, + 0xf7952e37, 0xbce9bc17, 0xff221a90, 0x7b7980c3, 0x38b22644, + 0xed81a482, 0xae4a0205, 0x2a119856, 0x69da3ed1, 0x22a6acf1, + 0x616d0a76, 0xe5369025, 0xa6fd36a2, 0xe8cb8cba, 0xab002a3d, + 0x2f5bb06e, 0x6c9016e9, 0x27ec84c9, 0x6427224e, 0xe07cb81d, + 0xa3b71e9a, 0x76849c5c, 0x354f3adb, 0xb114a088, 0xf2df060f, + 0xb9a3942f, 0xfa6832a8, 0x7e33a8fb, 0x3df80e7c, 0x9552ddad, + 0xd6997b2a, 0x52c2e179, 0x110947fe, 0x5a75d5de, 0x19be7359, + 0x9de5e90a, 0xde2e4f8d, 0x0b1dcd4b, 0x48d66bcc, 0xcc8df19f, + 0x8f465718, 0xc43ac538, 0x87f163bf, 0x03aaf9ec, 0x40615f6b, + 0x12f92f94, 0x51328913, 0xd5691340, 0x96a2b5c7, 0xddde27e7, + 0x9e158160, 0x1a4e1b33, 0x5985bdb4, 0x8cb63f72, 0xcf7d99f5, + 0x4b2603a6, 0x08eda521, 0x43913701, 0x005a9186, 0x84010bd5, + 0xc7caad52, 0x6f607e83, 0x2cabd804, 0xa8f04257, 0xeb3be4d0, + 0xa04776f0, 0xe38cd077, 0x67d74a24, 0x241ceca3, 0xf12f6e65, + 0xb2e4c8e2, 0x36bf52b1, 0x7574f436, 0x3e086616, 0x7dc3c091, + 0xf9985ac2, 0xba53fc45, 0x1caecae7, 0x5f656c60, 0xdb3ef633, + 0x98f550b4, 0xd389c294, 0x90426413, 0x1419fe40, 0x57d258c7, + 0x82e1da01, 0xc12a7c86, 0x4571e6d5, 0x06ba4052, 0x4dc6d272, + 0x0e0d74f5, 0x8a56eea6, 0xc99d4821, 0x61379bf0, 0x22fc3d77, + 0xa6a7a724, 0xe56c01a3, 0xae109383, 0xeddb3504, 0x6980af57, + 0x2a4b09d0, 0xff788b16, 0xbcb32d91, 0x38e8b7c2, 0x7b231145, + 0x305f8365, 0x739425e2, 0xf7cfbfb1, 0xb4041936, 0xe69c69c9, + 0xa557cf4e, 0x210c551d, 0x62c7f39a, 0x29bb61ba, 0x6a70c73d, + 0xee2b5d6e, 0xade0fbe9, 0x78d3792f, 0x3b18dfa8, 0xbf4345fb, + 0xfc88e37c, 0xb7f4715c, 0xf43fd7db, 0x70644d88, 0x33afeb0f, + 0x9b0538de, 0xd8ce9e59, 0x5c95040a, 0x1f5ea28d, 0x542230ad, + 0x17e9962a, 0x93b20c79, 0xd079aafe, 0x054a2838, 0x46818ebf, + 0xc2da14ec, 0x8111b26b, 0xca6d204b, 0x89a686cc, 0x0dfd1c9f, + 0x4e36ba18}, + {0x00000000, 0xe1b652ef, 0x836bd405, 0x62dd86ea, 0x06d7a80b, + 0xe761fae4, 0x85bc7c0e, 0x640a2ee1, 0x0cae5117, 0xed1803f8, + 0x8fc58512, 0x6e73d7fd, 0x0a79f91c, 0xebcfabf3, 0x89122d19, + 0x68a47ff6, 0x185ca32e, 0xf9eaf1c1, 0x9b37772b, 0x7a8125c4, + 0x1e8b0b25, 0xff3d59ca, 0x9de0df20, 0x7c568dcf, 0x14f2f239, + 0xf544a0d6, 0x9799263c, 0x762f74d3, 0x12255a32, 0xf39308dd, + 0x914e8e37, 0x70f8dcd8, 0x30b8465d, 0xd10e14b2, 0xb3d39258, + 0x5265c0b7, 0x366fee56, 0xd7d9bcb9, 0xb5043a53, 0x54b268bc, + 0x3c16174a, 0xdda045a5, 0xbf7dc34f, 0x5ecb91a0, 0x3ac1bf41, + 0xdb77edae, 0xb9aa6b44, 0x581c39ab, 0x28e4e573, 0xc952b79c, + 0xab8f3176, 0x4a396399, 0x2e334d78, 0xcf851f97, 0xad58997d, + 0x4ceecb92, 0x244ab464, 0xc5fce68b, 0xa7216061, 0x4697328e, + 0x229d1c6f, 0xc32b4e80, 0xa1f6c86a, 0x40409a85, 0x60708dba, + 0x81c6df55, 0xe31b59bf, 0x02ad0b50, 0x66a725b1, 0x8711775e, + 0xe5ccf1b4, 0x047aa35b, 0x6cdedcad, 0x8d688e42, 0xefb508a8, + 0x0e035a47, 0x6a0974a6, 0x8bbf2649, 0xe962a0a3, 0x08d4f24c, + 0x782c2e94, 0x999a7c7b, 0xfb47fa91, 0x1af1a87e, 0x7efb869f, + 0x9f4dd470, 0xfd90529a, 0x1c260075, 0x74827f83, 0x95342d6c, + 0xf7e9ab86, 0x165ff969, 0x7255d788, 0x93e38567, 0xf13e038d, + 0x10885162, 0x50c8cbe7, 0xb17e9908, 0xd3a31fe2, 0x32154d0d, + 0x561f63ec, 0xb7a93103, 0xd574b7e9, 0x34c2e506, 0x5c669af0, + 0xbdd0c81f, 0xdf0d4ef5, 0x3ebb1c1a, 0x5ab132fb, 0xbb076014, + 0xd9dae6fe, 0x386cb411, 0x489468c9, 0xa9223a26, 0xcbffbccc, + 0x2a49ee23, 0x4e43c0c2, 0xaff5922d, 0xcd2814c7, 0x2c9e4628, + 0x443a39de, 0xa58c6b31, 0xc751eddb, 0x26e7bf34, 0x42ed91d5, + 0xa35bc33a, 0xc18645d0, 0x2030173f, 0x81e66bae, 0x60503941, + 0x028dbfab, 0xe33bed44, 0x8731c3a5, 0x6687914a, 0x045a17a0, + 0xe5ec454f, 0x8d483ab9, 0x6cfe6856, 0x0e23eebc, 0xef95bc53, + 0x8b9f92b2, 0x6a29c05d, 0x08f446b7, 0xe9421458, 0x99bac880, + 0x780c9a6f, 0x1ad11c85, 0xfb674e6a, 0x9f6d608b, 0x7edb3264, + 0x1c06b48e, 0xfdb0e661, 0x95149997, 0x74a2cb78, 0x167f4d92, + 0xf7c91f7d, 0x93c3319c, 0x72756373, 0x10a8e599, 0xf11eb776, + 0xb15e2df3, 0x50e87f1c, 0x3235f9f6, 0xd383ab19, 0xb78985f8, + 0x563fd717, 0x34e251fd, 0xd5540312, 0xbdf07ce4, 0x5c462e0b, + 0x3e9ba8e1, 0xdf2dfa0e, 0xbb27d4ef, 0x5a918600, 0x384c00ea, + 0xd9fa5205, 0xa9028edd, 0x48b4dc32, 0x2a695ad8, 0xcbdf0837, + 0xafd526d6, 0x4e637439, 0x2cbef2d3, 0xcd08a03c, 0xa5acdfca, + 0x441a8d25, 0x26c70bcf, 0xc7715920, 0xa37b77c1, 0x42cd252e, + 0x2010a3c4, 0xc1a6f12b, 0xe196e614, 0x0020b4fb, 0x62fd3211, + 0x834b60fe, 0xe7414e1f, 0x06f71cf0, 0x642a9a1a, 0x859cc8f5, + 0xed38b703, 0x0c8ee5ec, 0x6e536306, 0x8fe531e9, 0xebef1f08, + 0x0a594de7, 0x6884cb0d, 0x893299e2, 0xf9ca453a, 0x187c17d5, + 0x7aa1913f, 0x9b17c3d0, 0xff1ded31, 0x1eabbfde, 0x7c763934, + 0x9dc06bdb, 0xf564142d, 0x14d246c2, 0x760fc028, 0x97b992c7, + 0xf3b3bc26, 0x1205eec9, 0x70d86823, 0x916e3acc, 0xd12ea049, + 0x3098f2a6, 0x5245744c, 0xb3f326a3, 0xd7f90842, 0x364f5aad, + 0x5492dc47, 0xb5248ea8, 0xdd80f15e, 0x3c36a3b1, 0x5eeb255b, + 0xbf5d77b4, 0xdb575955, 0x3ae10bba, 0x583c8d50, 0xb98adfbf, + 0xc9720367, 0x28c45188, 0x4a19d762, 0xabaf858d, 0xcfa5ab6c, + 0x2e13f983, 0x4cce7f69, 0xad782d86, 0xc5dc5270, 0x246a009f, + 0x46b78675, 0xa701d49a, 0xc30bfa7b, 0x22bda894, 0x40602e7e, + 0xa1d67c91}, + {0x00000000, 0x5880e2d7, 0xf106b474, 0xa98656a3, 0xe20d68e9, + 0xba8d8a3e, 0x130bdc9d, 0x4b8b3e4a, 0x851da109, 0xdd9d43de, + 0x741b157d, 0x2c9bf7aa, 0x6710c9e0, 0x3f902b37, 0x96167d94, + 0xce969f43, 0x0a3b4213, 0x52bba0c4, 0xfb3df667, 0xa3bd14b0, + 0xe8362afa, 0xb0b6c82d, 0x19309e8e, 0x41b07c59, 0x8f26e31a, + 0xd7a601cd, 0x7e20576e, 0x26a0b5b9, 0x6d2b8bf3, 0x35ab6924, + 0x9c2d3f87, 0xc4addd50, 0x14768426, 0x4cf666f1, 0xe5703052, + 0xbdf0d285, 0xf67beccf, 0xaefb0e18, 0x077d58bb, 0x5ffdba6c, + 0x916b252f, 0xc9ebc7f8, 0x606d915b, 0x38ed738c, 0x73664dc6, + 0x2be6af11, 0x8260f9b2, 0xdae01b65, 0x1e4dc635, 0x46cd24e2, + 0xef4b7241, 0xb7cb9096, 0xfc40aedc, 0xa4c04c0b, 0x0d461aa8, + 0x55c6f87f, 0x9b50673c, 0xc3d085eb, 0x6a56d348, 0x32d6319f, + 0x795d0fd5, 0x21dded02, 0x885bbba1, 0xd0db5976, 0x28ec084d, + 0x706cea9a, 0xd9eabc39, 0x816a5eee, 0xcae160a4, 0x92618273, + 0x3be7d4d0, 0x63673607, 0xadf1a944, 0xf5714b93, 0x5cf71d30, + 0x0477ffe7, 0x4ffcc1ad, 0x177c237a, 0xbefa75d9, 0xe67a970e, + 0x22d74a5e, 0x7a57a889, 0xd3d1fe2a, 0x8b511cfd, 0xc0da22b7, + 0x985ac060, 0x31dc96c3, 0x695c7414, 0xa7caeb57, 0xff4a0980, + 0x56cc5f23, 0x0e4cbdf4, 0x45c783be, 0x1d476169, 0xb4c137ca, + 0xec41d51d, 0x3c9a8c6b, 0x641a6ebc, 0xcd9c381f, 0x951cdac8, + 0xde97e482, 0x86170655, 0x2f9150f6, 0x7711b221, 0xb9872d62, + 0xe107cfb5, 0x48819916, 0x10017bc1, 0x5b8a458b, 0x030aa75c, + 0xaa8cf1ff, 0xf20c1328, 0x36a1ce78, 0x6e212caf, 0xc7a77a0c, + 0x9f2798db, 0xd4aca691, 0x8c2c4446, 0x25aa12e5, 0x7d2af032, + 0xb3bc6f71, 0xeb3c8da6, 0x42badb05, 0x1a3a39d2, 0x51b10798, + 0x0931e54f, 0xa0b7b3ec, 0xf837513b, 0x50d8119a, 0x0858f34d, + 0xa1dea5ee, 0xf95e4739, 0xb2d57973, 0xea559ba4, 0x43d3cd07, + 0x1b532fd0, 0xd5c5b093, 0x8d455244, 0x24c304e7, 0x7c43e630, + 0x37c8d87a, 0x6f483aad, 0xc6ce6c0e, 0x9e4e8ed9, 0x5ae35389, + 0x0263b15e, 0xabe5e7fd, 0xf365052a, 0xb8ee3b60, 0xe06ed9b7, + 0x49e88f14, 0x11686dc3, 0xdffef280, 0x877e1057, 0x2ef846f4, + 0x7678a423, 0x3df39a69, 0x657378be, 0xccf52e1d, 0x9475ccca, + 0x44ae95bc, 0x1c2e776b, 0xb5a821c8, 0xed28c31f, 0xa6a3fd55, + 0xfe231f82, 0x57a54921, 0x0f25abf6, 0xc1b334b5, 0x9933d662, + 0x30b580c1, 0x68356216, 0x23be5c5c, 0x7b3ebe8b, 0xd2b8e828, + 0x8a380aff, 0x4e95d7af, 0x16153578, 0xbf9363db, 0xe713810c, + 0xac98bf46, 0xf4185d91, 0x5d9e0b32, 0x051ee9e5, 0xcb8876a6, + 0x93089471, 0x3a8ec2d2, 0x620e2005, 0x29851e4f, 0x7105fc98, + 0xd883aa3b, 0x800348ec, 0x783419d7, 0x20b4fb00, 0x8932ada3, + 0xd1b24f74, 0x9a39713e, 0xc2b993e9, 0x6b3fc54a, 0x33bf279d, + 0xfd29b8de, 0xa5a95a09, 0x0c2f0caa, 0x54afee7d, 0x1f24d037, + 0x47a432e0, 0xee226443, 0xb6a28694, 0x720f5bc4, 0x2a8fb913, + 0x8309efb0, 0xdb890d67, 0x9002332d, 0xc882d1fa, 0x61048759, + 0x3984658e, 0xf712facd, 0xaf92181a, 0x06144eb9, 0x5e94ac6e, + 0x151f9224, 0x4d9f70f3, 0xe4192650, 0xbc99c487, 0x6c429df1, + 0x34c27f26, 0x9d442985, 0xc5c4cb52, 0x8e4ff518, 0xd6cf17cf, + 0x7f49416c, 0x27c9a3bb, 0xe95f3cf8, 0xb1dfde2f, 0x1859888c, + 0x40d96a5b, 0x0b525411, 0x53d2b6c6, 0xfa54e065, 0xa2d402b2, + 0x6679dfe2, 0x3ef93d35, 0x977f6b96, 0xcfff8941, 0x8474b70b, + 0xdcf455dc, 0x7572037f, 0x2df2e1a8, 0xe3647eeb, 0xbbe49c3c, + 0x1262ca9f, 0x4ae22848, 0x01691602, 0x59e9f4d5, 0xf06fa276, + 0xa8ef40a1}, + {0x00000000, 0x463b6765, 0x8c76ceca, 0xca4da9af, 0x59ebed4e, + 0x1fd08a2b, 0xd59d2384, 0x93a644e1, 0xb2d6db9d, 0xf4edbcf8, + 0x3ea01557, 0x789b7232, 0xeb3d36d3, 0xad0651b6, 0x674bf819, + 0x21709f7c, 0x25abc6e0, 0x6390a185, 0xa9dd082a, 0xefe66f4f, + 0x7c402bae, 0x3a7b4ccb, 0xf036e564, 0xb60d8201, 0x977d1d7d, + 0xd1467a18, 0x1b0bd3b7, 0x5d30b4d2, 0xce96f033, 0x88ad9756, + 0x42e03ef9, 0x04db599c, 0x0b50fc1a, 0x4d6b9b7f, 0x872632d0, + 0xc11d55b5, 0x52bb1154, 0x14807631, 0xdecddf9e, 0x98f6b8fb, + 0xb9862787, 0xffbd40e2, 0x35f0e94d, 0x73cb8e28, 0xe06dcac9, + 0xa656adac, 0x6c1b0403, 0x2a206366, 0x2efb3afa, 0x68c05d9f, + 0xa28df430, 0xe4b69355, 0x7710d7b4, 0x312bb0d1, 0xfb66197e, + 0xbd5d7e1b, 0x9c2de167, 0xda168602, 0x105b2fad, 0x566048c8, + 0xc5c60c29, 0x83fd6b4c, 0x49b0c2e3, 0x0f8ba586, 0x16a0f835, + 0x509b9f50, 0x9ad636ff, 0xdced519a, 0x4f4b157b, 0x0970721e, + 0xc33ddbb1, 0x8506bcd4, 0xa47623a8, 0xe24d44cd, 0x2800ed62, + 0x6e3b8a07, 0xfd9dcee6, 0xbba6a983, 0x71eb002c, 0x37d06749, + 0x330b3ed5, 0x753059b0, 0xbf7df01f, 0xf946977a, 0x6ae0d39b, + 0x2cdbb4fe, 0xe6961d51, 0xa0ad7a34, 0x81dde548, 0xc7e6822d, + 0x0dab2b82, 0x4b904ce7, 0xd8360806, 0x9e0d6f63, 0x5440c6cc, + 0x127ba1a9, 0x1df0042f, 0x5bcb634a, 0x9186cae5, 0xd7bdad80, + 0x441be961, 0x02208e04, 0xc86d27ab, 0x8e5640ce, 0xaf26dfb2, + 0xe91db8d7, 0x23501178, 0x656b761d, 0xf6cd32fc, 0xb0f65599, + 0x7abbfc36, 0x3c809b53, 0x385bc2cf, 0x7e60a5aa, 0xb42d0c05, + 0xf2166b60, 0x61b02f81, 0x278b48e4, 0xedc6e14b, 0xabfd862e, + 0x8a8d1952, 0xccb67e37, 0x06fbd798, 0x40c0b0fd, 0xd366f41c, + 0x955d9379, 0x5f103ad6, 0x192b5db3, 0x2c40f16b, 0x6a7b960e, + 0xa0363fa1, 0xe60d58c4, 0x75ab1c25, 0x33907b40, 0xf9ddd2ef, + 0xbfe6b58a, 0x9e962af6, 0xd8ad4d93, 0x12e0e43c, 0x54db8359, + 0xc77dc7b8, 0x8146a0dd, 0x4b0b0972, 0x0d306e17, 0x09eb378b, + 0x4fd050ee, 0x859df941, 0xc3a69e24, 0x5000dac5, 0x163bbda0, + 0xdc76140f, 0x9a4d736a, 0xbb3dec16, 0xfd068b73, 0x374b22dc, + 0x717045b9, 0xe2d60158, 0xa4ed663d, 0x6ea0cf92, 0x289ba8f7, + 0x27100d71, 0x612b6a14, 0xab66c3bb, 0xed5da4de, 0x7efbe03f, + 0x38c0875a, 0xf28d2ef5, 0xb4b64990, 0x95c6d6ec, 0xd3fdb189, + 0x19b01826, 0x5f8b7f43, 0xcc2d3ba2, 0x8a165cc7, 0x405bf568, + 0x0660920d, 0x02bbcb91, 0x4480acf4, 0x8ecd055b, 0xc8f6623e, + 0x5b5026df, 0x1d6b41ba, 0xd726e815, 0x911d8f70, 0xb06d100c, + 0xf6567769, 0x3c1bdec6, 0x7a20b9a3, 0xe986fd42, 0xafbd9a27, + 0x65f03388, 0x23cb54ed, 0x3ae0095e, 0x7cdb6e3b, 0xb696c794, + 0xf0ada0f1, 0x630be410, 0x25308375, 0xef7d2ada, 0xa9464dbf, + 0x8836d2c3, 0xce0db5a6, 0x04401c09, 0x427b7b6c, 0xd1dd3f8d, + 0x97e658e8, 0x5dabf147, 0x1b909622, 0x1f4bcfbe, 0x5970a8db, + 0x933d0174, 0xd5066611, 0x46a022f0, 0x009b4595, 0xcad6ec3a, + 0x8ced8b5f, 0xad9d1423, 0xeba67346, 0x21ebdae9, 0x67d0bd8c, + 0xf476f96d, 0xb24d9e08, 0x780037a7, 0x3e3b50c2, 0x31b0f544, + 0x778b9221, 0xbdc63b8e, 0xfbfd5ceb, 0x685b180a, 0x2e607f6f, + 0xe42dd6c0, 0xa216b1a5, 0x83662ed9, 0xc55d49bc, 0x0f10e013, + 0x492b8776, 0xda8dc397, 0x9cb6a4f2, 0x56fb0d5d, 0x10c06a38, + 0x141b33a4, 0x522054c1, 0x986dfd6e, 0xde569a0b, 0x4df0deea, + 0x0bcbb98f, 0xc1861020, 0x87bd7745, 0xa6cde839, 0xe0f68f5c, + 0x2abb26f3, 0x6c804196, 0xff260577, 0xb91d6212, 0x7350cbbd, + 0x356bacd8}}; + +#endif + +#endif + +#if N == 6 + +#if W == 8 + +local const z_crc_t FAR crc_braid_table[][256] = { + {0x00000000, 0x3db1ecdc, 0x7b63d9b8, 0x46d23564, 0xf6c7b370, + 0xcb765fac, 0x8da46ac8, 0xb0158614, 0x36fe60a1, 0x0b4f8c7d, + 0x4d9db919, 0x702c55c5, 0xc039d3d1, 0xfd883f0d, 0xbb5a0a69, + 0x86ebe6b5, 0x6dfcc142, 0x504d2d9e, 0x169f18fa, 0x2b2ef426, + 0x9b3b7232, 0xa68a9eee, 0xe058ab8a, 0xdde94756, 0x5b02a1e3, + 0x66b34d3f, 0x2061785b, 0x1dd09487, 0xadc51293, 0x9074fe4f, + 0xd6a6cb2b, 0xeb1727f7, 0xdbf98284, 0xe6486e58, 0xa09a5b3c, + 0x9d2bb7e0, 0x2d3e31f4, 0x108fdd28, 0x565de84c, 0x6bec0490, + 0xed07e225, 0xd0b60ef9, 0x96643b9d, 0xabd5d741, 0x1bc05155, + 0x2671bd89, 0x60a388ed, 0x5d126431, 0xb60543c6, 0x8bb4af1a, + 0xcd669a7e, 0xf0d776a2, 0x40c2f0b6, 0x7d731c6a, 0x3ba1290e, + 0x0610c5d2, 0x80fb2367, 0xbd4acfbb, 0xfb98fadf, 0xc6291603, + 0x763c9017, 0x4b8d7ccb, 0x0d5f49af, 0x30eea573, 0x6c820349, + 0x5133ef95, 0x17e1daf1, 0x2a50362d, 0x9a45b039, 0xa7f45ce5, + 0xe1266981, 0xdc97855d, 0x5a7c63e8, 0x67cd8f34, 0x211fba50, + 0x1cae568c, 0xacbbd098, 0x910a3c44, 0xd7d80920, 0xea69e5fc, + 0x017ec20b, 0x3ccf2ed7, 0x7a1d1bb3, 0x47acf76f, 0xf7b9717b, + 0xca089da7, 0x8cdaa8c3, 0xb16b441f, 0x3780a2aa, 0x0a314e76, + 0x4ce37b12, 0x715297ce, 0xc14711da, 0xfcf6fd06, 0xba24c862, + 0x879524be, 0xb77b81cd, 0x8aca6d11, 0xcc185875, 0xf1a9b4a9, + 0x41bc32bd, 0x7c0dde61, 0x3adfeb05, 0x076e07d9, 0x8185e16c, + 0xbc340db0, 0xfae638d4, 0xc757d408, 0x7742521c, 0x4af3bec0, + 0x0c218ba4, 0x31906778, 0xda87408f, 0xe736ac53, 0xa1e49937, + 0x9c5575eb, 0x2c40f3ff, 0x11f11f23, 0x57232a47, 0x6a92c69b, + 0xec79202e, 0xd1c8ccf2, 0x971af996, 0xaaab154a, 0x1abe935e, + 0x270f7f82, 0x61dd4ae6, 0x5c6ca63a, 0xd9040692, 0xe4b5ea4e, + 0xa267df2a, 0x9fd633f6, 0x2fc3b5e2, 0x1272593e, 0x54a06c5a, + 0x69118086, 0xeffa6633, 0xd24b8aef, 0x9499bf8b, 0xa9285357, + 0x193dd543, 0x248c399f, 0x625e0cfb, 0x5fefe027, 0xb4f8c7d0, + 0x89492b0c, 0xcf9b1e68, 0xf22af2b4, 0x423f74a0, 0x7f8e987c, + 0x395cad18, 0x04ed41c4, 0x8206a771, 0xbfb74bad, 0xf9657ec9, + 0xc4d49215, 0x74c11401, 0x4970f8dd, 0x0fa2cdb9, 0x32132165, + 0x02fd8416, 0x3f4c68ca, 0x799e5dae, 0x442fb172, 0xf43a3766, + 0xc98bdbba, 0x8f59eede, 0xb2e80202, 0x3403e4b7, 0x09b2086b, + 0x4f603d0f, 0x72d1d1d3, 0xc2c457c7, 0xff75bb1b, 0xb9a78e7f, + 0x841662a3, 0x6f014554, 0x52b0a988, 0x14629cec, 0x29d37030, + 0x99c6f624, 0xa4771af8, 0xe2a52f9c, 0xdf14c340, 0x59ff25f5, + 0x644ec929, 0x229cfc4d, 0x1f2d1091, 0xaf389685, 0x92897a59, + 0xd45b4f3d, 0xe9eaa3e1, 0xb58605db, 0x8837e907, 0xcee5dc63, + 0xf35430bf, 0x4341b6ab, 0x7ef05a77, 0x38226f13, 0x059383cf, + 0x8378657a, 0xbec989a6, 0xf81bbcc2, 0xc5aa501e, 0x75bfd60a, + 0x480e3ad6, 0x0edc0fb2, 0x336de36e, 0xd87ac499, 0xe5cb2845, + 0xa3191d21, 0x9ea8f1fd, 0x2ebd77e9, 0x130c9b35, 0x55deae51, + 0x686f428d, 0xee84a438, 0xd33548e4, 0x95e77d80, 0xa856915c, + 0x18431748, 0x25f2fb94, 0x6320cef0, 0x5e91222c, 0x6e7f875f, + 0x53ce6b83, 0x151c5ee7, 0x28adb23b, 0x98b8342f, 0xa509d8f3, + 0xe3dbed97, 0xde6a014b, 0x5881e7fe, 0x65300b22, 0x23e23e46, + 0x1e53d29a, 0xae46548e, 0x93f7b852, 0xd5258d36, 0xe89461ea, + 0x0383461d, 0x3e32aac1, 0x78e09fa5, 0x45517379, 0xf544f56d, + 0xc8f519b1, 0x8e272cd5, 0xb396c009, 0x357d26bc, 0x08ccca60, + 0x4e1eff04, 0x73af13d8, 0xc3ba95cc, 0xfe0b7910, 0xb8d94c74, + 0x8568a0a8}, + {0x00000000, 0x69790b65, 0xd2f216ca, 0xbb8b1daf, 0x7e952bd5, + 0x17ec20b0, 0xac673d1f, 0xc51e367a, 0xfd2a57aa, 0x94535ccf, + 0x2fd84160, 0x46a14a05, 0x83bf7c7f, 0xeac6771a, 0x514d6ab5, + 0x383461d0, 0x2125a915, 0x485ca270, 0xf3d7bfdf, 0x9aaeb4ba, + 0x5fb082c0, 0x36c989a5, 0x8d42940a, 0xe43b9f6f, 0xdc0ffebf, + 0xb576f5da, 0x0efde875, 0x6784e310, 0xa29ad56a, 0xcbe3de0f, + 0x7068c3a0, 0x1911c8c5, 0x424b522a, 0x2b32594f, 0x90b944e0, + 0xf9c04f85, 0x3cde79ff, 0x55a7729a, 0xee2c6f35, 0x87556450, + 0xbf610580, 0xd6180ee5, 0x6d93134a, 0x04ea182f, 0xc1f42e55, + 0xa88d2530, 0x1306389f, 0x7a7f33fa, 0x636efb3f, 0x0a17f05a, + 0xb19cedf5, 0xd8e5e690, 0x1dfbd0ea, 0x7482db8f, 0xcf09c620, + 0xa670cd45, 0x9e44ac95, 0xf73da7f0, 0x4cb6ba5f, 0x25cfb13a, + 0xe0d18740, 0x89a88c25, 0x3223918a, 0x5b5a9aef, 0x8496a454, + 0xedefaf31, 0x5664b29e, 0x3f1db9fb, 0xfa038f81, 0x937a84e4, + 0x28f1994b, 0x4188922e, 0x79bcf3fe, 0x10c5f89b, 0xab4ee534, + 0xc237ee51, 0x0729d82b, 0x6e50d34e, 0xd5dbcee1, 0xbca2c584, + 0xa5b30d41, 0xccca0624, 0x77411b8b, 0x1e3810ee, 0xdb262694, + 0xb25f2df1, 0x09d4305e, 0x60ad3b3b, 0x58995aeb, 0x31e0518e, + 0x8a6b4c21, 0xe3124744, 0x260c713e, 0x4f757a5b, 0xf4fe67f4, + 0x9d876c91, 0xc6ddf67e, 0xafa4fd1b, 0x142fe0b4, 0x7d56ebd1, + 0xb848ddab, 0xd131d6ce, 0x6abacb61, 0x03c3c004, 0x3bf7a1d4, + 0x528eaab1, 0xe905b71e, 0x807cbc7b, 0x45628a01, 0x2c1b8164, + 0x97909ccb, 0xfee997ae, 0xe7f85f6b, 0x8e81540e, 0x350a49a1, + 0x5c7342c4, 0x996d74be, 0xf0147fdb, 0x4b9f6274, 0x22e66911, + 0x1ad208c1, 0x73ab03a4, 0xc8201e0b, 0xa159156e, 0x64472314, + 0x0d3e2871, 0xb6b535de, 0xdfcc3ebb, 0xd25c4ee9, 0xbb25458c, + 0x00ae5823, 0x69d75346, 0xacc9653c, 0xc5b06e59, 0x7e3b73f6, + 0x17427893, 0x2f761943, 0x460f1226, 0xfd840f89, 0x94fd04ec, + 0x51e33296, 0x389a39f3, 0x8311245c, 0xea682f39, 0xf379e7fc, + 0x9a00ec99, 0x218bf136, 0x48f2fa53, 0x8deccc29, 0xe495c74c, + 0x5f1edae3, 0x3667d186, 0x0e53b056, 0x672abb33, 0xdca1a69c, + 0xb5d8adf9, 0x70c69b83, 0x19bf90e6, 0xa2348d49, 0xcb4d862c, + 0x90171cc3, 0xf96e17a6, 0x42e50a09, 0x2b9c016c, 0xee823716, + 0x87fb3c73, 0x3c7021dc, 0x55092ab9, 0x6d3d4b69, 0x0444400c, + 0xbfcf5da3, 0xd6b656c6, 0x13a860bc, 0x7ad16bd9, 0xc15a7676, + 0xa8237d13, 0xb132b5d6, 0xd84bbeb3, 0x63c0a31c, 0x0ab9a879, + 0xcfa79e03, 0xa6de9566, 0x1d5588c9, 0x742c83ac, 0x4c18e27c, + 0x2561e919, 0x9eeaf4b6, 0xf793ffd3, 0x328dc9a9, 0x5bf4c2cc, + 0xe07fdf63, 0x8906d406, 0x56caeabd, 0x3fb3e1d8, 0x8438fc77, + 0xed41f712, 0x285fc168, 0x4126ca0d, 0xfaadd7a2, 0x93d4dcc7, + 0xabe0bd17, 0xc299b672, 0x7912abdd, 0x106ba0b8, 0xd57596c2, + 0xbc0c9da7, 0x07878008, 0x6efe8b6d, 0x77ef43a8, 0x1e9648cd, + 0xa51d5562, 0xcc645e07, 0x097a687d, 0x60036318, 0xdb887eb7, + 0xb2f175d2, 0x8ac51402, 0xe3bc1f67, 0x583702c8, 0x314e09ad, + 0xf4503fd7, 0x9d2934b2, 0x26a2291d, 0x4fdb2278, 0x1481b897, + 0x7df8b3f2, 0xc673ae5d, 0xaf0aa538, 0x6a149342, 0x036d9827, + 0xb8e68588, 0xd19f8eed, 0xe9abef3d, 0x80d2e458, 0x3b59f9f7, + 0x5220f292, 0x973ec4e8, 0xfe47cf8d, 0x45ccd222, 0x2cb5d947, + 0x35a41182, 0x5cdd1ae7, 0xe7560748, 0x8e2f0c2d, 0x4b313a57, + 0x22483132, 0x99c32c9d, 0xf0ba27f8, 0xc88e4628, 0xa1f74d4d, + 0x1a7c50e2, 0x73055b87, 0xb61b6dfd, 0xdf626698, 0x64e97b37, + 0x0d907052}, + {0x00000000, 0x7fc99b93, 0xff933726, 0x805aacb5, 0x2457680d, + 0x5b9ef39e, 0xdbc45f2b, 0xa40dc4b8, 0x48aed01a, 0x37674b89, + 0xb73de73c, 0xc8f47caf, 0x6cf9b817, 0x13302384, 0x936a8f31, + 0xeca314a2, 0x915da034, 0xee943ba7, 0x6ece9712, 0x11070c81, + 0xb50ac839, 0xcac353aa, 0x4a99ff1f, 0x3550648c, 0xd9f3702e, + 0xa63aebbd, 0x26604708, 0x59a9dc9b, 0xfda41823, 0x826d83b0, + 0x02372f05, 0x7dfeb496, 0xf9ca4629, 0x8603ddba, 0x0659710f, + 0x7990ea9c, 0xdd9d2e24, 0xa254b5b7, 0x220e1902, 0x5dc78291, + 0xb1649633, 0xcead0da0, 0x4ef7a115, 0x313e3a86, 0x9533fe3e, + 0xeafa65ad, 0x6aa0c918, 0x1569528b, 0x6897e61d, 0x175e7d8e, + 0x9704d13b, 0xe8cd4aa8, 0x4cc08e10, 0x33091583, 0xb353b936, + 0xcc9a22a5, 0x20393607, 0x5ff0ad94, 0xdfaa0121, 0xa0639ab2, + 0x046e5e0a, 0x7ba7c599, 0xfbfd692c, 0x8434f2bf, 0x28e58a13, + 0x572c1180, 0xd776bd35, 0xa8bf26a6, 0x0cb2e21e, 0x737b798d, + 0xf321d538, 0x8ce84eab, 0x604b5a09, 0x1f82c19a, 0x9fd86d2f, + 0xe011f6bc, 0x441c3204, 0x3bd5a997, 0xbb8f0522, 0xc4469eb1, + 0xb9b82a27, 0xc671b1b4, 0x462b1d01, 0x39e28692, 0x9def422a, + 0xe226d9b9, 0x627c750c, 0x1db5ee9f, 0xf116fa3d, 0x8edf61ae, + 0x0e85cd1b, 0x714c5688, 0xd5419230, 0xaa8809a3, 0x2ad2a516, + 0x551b3e85, 0xd12fcc3a, 0xaee657a9, 0x2ebcfb1c, 0x5175608f, + 0xf578a437, 0x8ab13fa4, 0x0aeb9311, 0x75220882, 0x99811c20, + 0xe64887b3, 0x66122b06, 0x19dbb095, 0xbdd6742d, 0xc21fefbe, + 0x4245430b, 0x3d8cd898, 0x40726c0e, 0x3fbbf79d, 0xbfe15b28, + 0xc028c0bb, 0x64250403, 0x1bec9f90, 0x9bb63325, 0xe47fa8b6, + 0x08dcbc14, 0x77152787, 0xf74f8b32, 0x888610a1, 0x2c8bd419, + 0x53424f8a, 0xd318e33f, 0xacd178ac, 0x51cb1426, 0x2e028fb5, + 0xae582300, 0xd191b893, 0x759c7c2b, 0x0a55e7b8, 0x8a0f4b0d, + 0xf5c6d09e, 0x1965c43c, 0x66ac5faf, 0xe6f6f31a, 0x993f6889, + 0x3d32ac31, 0x42fb37a2, 0xc2a19b17, 0xbd680084, 0xc096b412, + 0xbf5f2f81, 0x3f058334, 0x40cc18a7, 0xe4c1dc1f, 0x9b08478c, + 0x1b52eb39, 0x649b70aa, 0x88386408, 0xf7f1ff9b, 0x77ab532e, + 0x0862c8bd, 0xac6f0c05, 0xd3a69796, 0x53fc3b23, 0x2c35a0b0, + 0xa801520f, 0xd7c8c99c, 0x57926529, 0x285bfeba, 0x8c563a02, + 0xf39fa191, 0x73c50d24, 0x0c0c96b7, 0xe0af8215, 0x9f661986, + 0x1f3cb533, 0x60f52ea0, 0xc4f8ea18, 0xbb31718b, 0x3b6bdd3e, + 0x44a246ad, 0x395cf23b, 0x469569a8, 0xc6cfc51d, 0xb9065e8e, + 0x1d0b9a36, 0x62c201a5, 0xe298ad10, 0x9d513683, 0x71f22221, + 0x0e3bb9b2, 0x8e611507, 0xf1a88e94, 0x55a54a2c, 0x2a6cd1bf, + 0xaa367d0a, 0xd5ffe699, 0x792e9e35, 0x06e705a6, 0x86bda913, + 0xf9743280, 0x5d79f638, 0x22b06dab, 0xa2eac11e, 0xdd235a8d, + 0x31804e2f, 0x4e49d5bc, 0xce137909, 0xb1dae29a, 0x15d72622, + 0x6a1ebdb1, 0xea441104, 0x958d8a97, 0xe8733e01, 0x97baa592, + 0x17e00927, 0x682992b4, 0xcc24560c, 0xb3edcd9f, 0x33b7612a, + 0x4c7efab9, 0xa0ddee1b, 0xdf147588, 0x5f4ed93d, 0x208742ae, + 0x848a8616, 0xfb431d85, 0x7b19b130, 0x04d02aa3, 0x80e4d81c, + 0xff2d438f, 0x7f77ef3a, 0x00be74a9, 0xa4b3b011, 0xdb7a2b82, + 0x5b208737, 0x24e91ca4, 0xc84a0806, 0xb7839395, 0x37d93f20, + 0x4810a4b3, 0xec1d600b, 0x93d4fb98, 0x138e572d, 0x6c47ccbe, + 0x11b97828, 0x6e70e3bb, 0xee2a4f0e, 0x91e3d49d, 0x35ee1025, + 0x4a278bb6, 0xca7d2703, 0xb5b4bc90, 0x5917a832, 0x26de33a1, + 0xa6849f14, 0xd94d0487, 0x7d40c03f, 0x02895bac, 0x82d3f719, + 0xfd1a6c8a}, + {0x00000000, 0xa396284c, 0x9c5d56d9, 0x3fcb7e95, 0xe3cbabf3, + 0x405d83bf, 0x7f96fd2a, 0xdc00d566, 0x1ce651a7, 0xbf7079eb, + 0x80bb077e, 0x232d2f32, 0xff2dfa54, 0x5cbbd218, 0x6370ac8d, + 0xc0e684c1, 0x39cca34e, 0x9a5a8b02, 0xa591f597, 0x0607dddb, + 0xda0708bd, 0x799120f1, 0x465a5e64, 0xe5cc7628, 0x252af2e9, + 0x86bcdaa5, 0xb977a430, 0x1ae18c7c, 0xc6e1591a, 0x65777156, + 0x5abc0fc3, 0xf92a278f, 0x7399469c, 0xd00f6ed0, 0xefc41045, + 0x4c523809, 0x9052ed6f, 0x33c4c523, 0x0c0fbbb6, 0xaf9993fa, + 0x6f7f173b, 0xcce93f77, 0xf32241e2, 0x50b469ae, 0x8cb4bcc8, + 0x2f229484, 0x10e9ea11, 0xb37fc25d, 0x4a55e5d2, 0xe9c3cd9e, + 0xd608b30b, 0x759e9b47, 0xa99e4e21, 0x0a08666d, 0x35c318f8, + 0x965530b4, 0x56b3b475, 0xf5259c39, 0xcaeee2ac, 0x6978cae0, + 0xb5781f86, 0x16ee37ca, 0x2925495f, 0x8ab36113, 0xe7328d38, + 0x44a4a574, 0x7b6fdbe1, 0xd8f9f3ad, 0x04f926cb, 0xa76f0e87, + 0x98a47012, 0x3b32585e, 0xfbd4dc9f, 0x5842f4d3, 0x67898a46, + 0xc41fa20a, 0x181f776c, 0xbb895f20, 0x844221b5, 0x27d409f9, + 0xdefe2e76, 0x7d68063a, 0x42a378af, 0xe13550e3, 0x3d358585, + 0x9ea3adc9, 0xa168d35c, 0x02fefb10, 0xc2187fd1, 0x618e579d, + 0x5e452908, 0xfdd30144, 0x21d3d422, 0x8245fc6e, 0xbd8e82fb, + 0x1e18aab7, 0x94abcba4, 0x373de3e8, 0x08f69d7d, 0xab60b531, + 0x77606057, 0xd4f6481b, 0xeb3d368e, 0x48ab1ec2, 0x884d9a03, + 0x2bdbb24f, 0x1410ccda, 0xb786e496, 0x6b8631f0, 0xc81019bc, + 0xf7db6729, 0x544d4f65, 0xad6768ea, 0x0ef140a6, 0x313a3e33, + 0x92ac167f, 0x4eacc319, 0xed3aeb55, 0xd2f195c0, 0x7167bd8c, + 0xb181394d, 0x12171101, 0x2ddc6f94, 0x8e4a47d8, 0x524a92be, + 0xf1dcbaf2, 0xce17c467, 0x6d81ec2b, 0x15141c31, 0xb682347d, + 0x89494ae8, 0x2adf62a4, 0xf6dfb7c2, 0x55499f8e, 0x6a82e11b, + 0xc914c957, 0x09f24d96, 0xaa6465da, 0x95af1b4f, 0x36393303, + 0xea39e665, 0x49afce29, 0x7664b0bc, 0xd5f298f0, 0x2cd8bf7f, + 0x8f4e9733, 0xb085e9a6, 0x1313c1ea, 0xcf13148c, 0x6c853cc0, + 0x534e4255, 0xf0d86a19, 0x303eeed8, 0x93a8c694, 0xac63b801, + 0x0ff5904d, 0xd3f5452b, 0x70636d67, 0x4fa813f2, 0xec3e3bbe, + 0x668d5aad, 0xc51b72e1, 0xfad00c74, 0x59462438, 0x8546f15e, + 0x26d0d912, 0x191ba787, 0xba8d8fcb, 0x7a6b0b0a, 0xd9fd2346, + 0xe6365dd3, 0x45a0759f, 0x99a0a0f9, 0x3a3688b5, 0x05fdf620, + 0xa66bde6c, 0x5f41f9e3, 0xfcd7d1af, 0xc31caf3a, 0x608a8776, + 0xbc8a5210, 0x1f1c7a5c, 0x20d704c9, 0x83412c85, 0x43a7a844, + 0xe0318008, 0xdffafe9d, 0x7c6cd6d1, 0xa06c03b7, 0x03fa2bfb, + 0x3c31556e, 0x9fa77d22, 0xf2269109, 0x51b0b945, 0x6e7bc7d0, + 0xcdedef9c, 0x11ed3afa, 0xb27b12b6, 0x8db06c23, 0x2e26446f, + 0xeec0c0ae, 0x4d56e8e2, 0x729d9677, 0xd10bbe3b, 0x0d0b6b5d, + 0xae9d4311, 0x91563d84, 0x32c015c8, 0xcbea3247, 0x687c1a0b, + 0x57b7649e, 0xf4214cd2, 0x282199b4, 0x8bb7b1f8, 0xb47ccf6d, + 0x17eae721, 0xd70c63e0, 0x749a4bac, 0x4b513539, 0xe8c71d75, + 0x34c7c813, 0x9751e05f, 0xa89a9eca, 0x0b0cb686, 0x81bfd795, + 0x2229ffd9, 0x1de2814c, 0xbe74a900, 0x62747c66, 0xc1e2542a, + 0xfe292abf, 0x5dbf02f3, 0x9d598632, 0x3ecfae7e, 0x0104d0eb, + 0xa292f8a7, 0x7e922dc1, 0xdd04058d, 0xe2cf7b18, 0x41595354, + 0xb87374db, 0x1be55c97, 0x242e2202, 0x87b80a4e, 0x5bb8df28, + 0xf82ef764, 0xc7e589f1, 0x6473a1bd, 0xa495257c, 0x07030d30, + 0x38c873a5, 0x9b5e5be9, 0x475e8e8f, 0xe4c8a6c3, 0xdb03d856, + 0x7895f01a}, + {0x00000000, 0x2a283862, 0x545070c4, 0x7e7848a6, 0xa8a0e188, + 0x8288d9ea, 0xfcf0914c, 0xd6d8a92e, 0x8a30c551, 0xa018fd33, + 0xde60b595, 0xf4488df7, 0x229024d9, 0x08b81cbb, 0x76c0541d, + 0x5ce86c7f, 0xcf108ce3, 0xe538b481, 0x9b40fc27, 0xb168c445, + 0x67b06d6b, 0x4d985509, 0x33e01daf, 0x19c825cd, 0x452049b2, + 0x6f0871d0, 0x11703976, 0x3b580114, 0xed80a83a, 0xc7a89058, + 0xb9d0d8fe, 0x93f8e09c, 0x45501f87, 0x6f7827e5, 0x11006f43, + 0x3b285721, 0xedf0fe0f, 0xc7d8c66d, 0xb9a08ecb, 0x9388b6a9, + 0xcf60dad6, 0xe548e2b4, 0x9b30aa12, 0xb1189270, 0x67c03b5e, + 0x4de8033c, 0x33904b9a, 0x19b873f8, 0x8a409364, 0xa068ab06, + 0xde10e3a0, 0xf438dbc2, 0x22e072ec, 0x08c84a8e, 0x76b00228, + 0x5c983a4a, 0x00705635, 0x2a586e57, 0x542026f1, 0x7e081e93, + 0xa8d0b7bd, 0x82f88fdf, 0xfc80c779, 0xd6a8ff1b, 0x8aa03f0e, + 0xa088076c, 0xdef04fca, 0xf4d877a8, 0x2200de86, 0x0828e6e4, + 0x7650ae42, 0x5c789620, 0x0090fa5f, 0x2ab8c23d, 0x54c08a9b, + 0x7ee8b2f9, 0xa8301bd7, 0x821823b5, 0xfc606b13, 0xd6485371, + 0x45b0b3ed, 0x6f988b8f, 0x11e0c329, 0x3bc8fb4b, 0xed105265, + 0xc7386a07, 0xb94022a1, 0x93681ac3, 0xcf8076bc, 0xe5a84ede, + 0x9bd00678, 0xb1f83e1a, 0x67209734, 0x4d08af56, 0x3370e7f0, + 0x1958df92, 0xcff02089, 0xe5d818eb, 0x9ba0504d, 0xb188682f, + 0x6750c101, 0x4d78f963, 0x3300b1c5, 0x192889a7, 0x45c0e5d8, + 0x6fe8ddba, 0x1190951c, 0x3bb8ad7e, 0xed600450, 0xc7483c32, + 0xb9307494, 0x93184cf6, 0x00e0ac6a, 0x2ac89408, 0x54b0dcae, + 0x7e98e4cc, 0xa8404de2, 0x82687580, 0xfc103d26, 0xd6380544, + 0x8ad0693b, 0xa0f85159, 0xde8019ff, 0xf4a8219d, 0x227088b3, + 0x0858b0d1, 0x7620f877, 0x5c08c015, 0xce31785d, 0xe419403f, + 0x9a610899, 0xb04930fb, 0x669199d5, 0x4cb9a1b7, 0x32c1e911, + 0x18e9d173, 0x4401bd0c, 0x6e29856e, 0x1051cdc8, 0x3a79f5aa, + 0xeca15c84, 0xc68964e6, 0xb8f12c40, 0x92d91422, 0x0121f4be, + 0x2b09ccdc, 0x5571847a, 0x7f59bc18, 0xa9811536, 0x83a92d54, + 0xfdd165f2, 0xd7f95d90, 0x8b1131ef, 0xa139098d, 0xdf41412b, + 0xf5697949, 0x23b1d067, 0x0999e805, 0x77e1a0a3, 0x5dc998c1, + 0x8b6167da, 0xa1495fb8, 0xdf31171e, 0xf5192f7c, 0x23c18652, + 0x09e9be30, 0x7791f696, 0x5db9cef4, 0x0151a28b, 0x2b799ae9, + 0x5501d24f, 0x7f29ea2d, 0xa9f14303, 0x83d97b61, 0xfda133c7, + 0xd7890ba5, 0x4471eb39, 0x6e59d35b, 0x10219bfd, 0x3a09a39f, + 0xecd10ab1, 0xc6f932d3, 0xb8817a75, 0x92a94217, 0xce412e68, + 0xe469160a, 0x9a115eac, 0xb03966ce, 0x66e1cfe0, 0x4cc9f782, + 0x32b1bf24, 0x18998746, 0x44914753, 0x6eb97f31, 0x10c13797, + 0x3ae90ff5, 0xec31a6db, 0xc6199eb9, 0xb861d61f, 0x9249ee7d, + 0xcea18202, 0xe489ba60, 0x9af1f2c6, 0xb0d9caa4, 0x6601638a, + 0x4c295be8, 0x3251134e, 0x18792b2c, 0x8b81cbb0, 0xa1a9f3d2, + 0xdfd1bb74, 0xf5f98316, 0x23212a38, 0x0909125a, 0x77715afc, + 0x5d59629e, 0x01b10ee1, 0x2b993683, 0x55e17e25, 0x7fc94647, + 0xa911ef69, 0x8339d70b, 0xfd419fad, 0xd769a7cf, 0x01c158d4, + 0x2be960b6, 0x55912810, 0x7fb91072, 0xa961b95c, 0x8349813e, + 0xfd31c998, 0xd719f1fa, 0x8bf19d85, 0xa1d9a5e7, 0xdfa1ed41, + 0xf589d523, 0x23517c0d, 0x0979446f, 0x77010cc9, 0x5d2934ab, + 0xced1d437, 0xe4f9ec55, 0x9a81a4f3, 0xb0a99c91, 0x667135bf, + 0x4c590ddd, 0x3221457b, 0x18097d19, 0x44e11166, 0x6ec92904, + 0x10b161a2, 0x3a9959c0, 0xec41f0ee, 0xc669c88c, 0xb811802a, + 0x9239b848}, + {0x00000000, 0x4713f6fb, 0x8e27edf6, 0xc9341b0d, 0xc73eddad, + 0x802d2b56, 0x4919305b, 0x0e0ac6a0, 0x550cbd1b, 0x121f4be0, + 0xdb2b50ed, 0x9c38a616, 0x923260b6, 0xd521964d, 0x1c158d40, + 0x5b067bbb, 0xaa197a36, 0xed0a8ccd, 0x243e97c0, 0x632d613b, + 0x6d27a79b, 0x2a345160, 0xe3004a6d, 0xa413bc96, 0xff15c72d, + 0xb80631d6, 0x71322adb, 0x3621dc20, 0x382b1a80, 0x7f38ec7b, + 0xb60cf776, 0xf11f018d, 0x8f43f22d, 0xc85004d6, 0x01641fdb, + 0x4677e920, 0x487d2f80, 0x0f6ed97b, 0xc65ac276, 0x8149348d, + 0xda4f4f36, 0x9d5cb9cd, 0x5468a2c0, 0x137b543b, 0x1d71929b, + 0x5a626460, 0x93567f6d, 0xd4458996, 0x255a881b, 0x62497ee0, + 0xab7d65ed, 0xec6e9316, 0xe26455b6, 0xa577a34d, 0x6c43b840, + 0x2b504ebb, 0x70563500, 0x3745c3fb, 0xfe71d8f6, 0xb9622e0d, + 0xb768e8ad, 0xf07b1e56, 0x394f055b, 0x7e5cf3a0, 0xc5f6e21b, + 0x82e514e0, 0x4bd10fed, 0x0cc2f916, 0x02c83fb6, 0x45dbc94d, + 0x8cefd240, 0xcbfc24bb, 0x90fa5f00, 0xd7e9a9fb, 0x1eddb2f6, + 0x59ce440d, 0x57c482ad, 0x10d77456, 0xd9e36f5b, 0x9ef099a0, + 0x6fef982d, 0x28fc6ed6, 0xe1c875db, 0xa6db8320, 0xa8d14580, + 0xefc2b37b, 0x26f6a876, 0x61e55e8d, 0x3ae32536, 0x7df0d3cd, + 0xb4c4c8c0, 0xf3d73e3b, 0xfdddf89b, 0xbace0e60, 0x73fa156d, + 0x34e9e396, 0x4ab51036, 0x0da6e6cd, 0xc492fdc0, 0x83810b3b, + 0x8d8bcd9b, 0xca983b60, 0x03ac206d, 0x44bfd696, 0x1fb9ad2d, + 0x58aa5bd6, 0x919e40db, 0xd68db620, 0xd8877080, 0x9f94867b, + 0x56a09d76, 0x11b36b8d, 0xe0ac6a00, 0xa7bf9cfb, 0x6e8b87f6, + 0x2998710d, 0x2792b7ad, 0x60814156, 0xa9b55a5b, 0xeea6aca0, + 0xb5a0d71b, 0xf2b321e0, 0x3b873aed, 0x7c94cc16, 0x729e0ab6, + 0x358dfc4d, 0xfcb9e740, 0xbbaa11bb, 0x509cc277, 0x178f348c, + 0xdebb2f81, 0x99a8d97a, 0x97a21fda, 0xd0b1e921, 0x1985f22c, + 0x5e9604d7, 0x05907f6c, 0x42838997, 0x8bb7929a, 0xcca46461, + 0xc2aea2c1, 0x85bd543a, 0x4c894f37, 0x0b9ab9cc, 0xfa85b841, + 0xbd964eba, 0x74a255b7, 0x33b1a34c, 0x3dbb65ec, 0x7aa89317, + 0xb39c881a, 0xf48f7ee1, 0xaf89055a, 0xe89af3a1, 0x21aee8ac, + 0x66bd1e57, 0x68b7d8f7, 0x2fa42e0c, 0xe6903501, 0xa183c3fa, + 0xdfdf305a, 0x98ccc6a1, 0x51f8ddac, 0x16eb2b57, 0x18e1edf7, + 0x5ff21b0c, 0x96c60001, 0xd1d5f6fa, 0x8ad38d41, 0xcdc07bba, + 0x04f460b7, 0x43e7964c, 0x4ded50ec, 0x0afea617, 0xc3cabd1a, + 0x84d94be1, 0x75c64a6c, 0x32d5bc97, 0xfbe1a79a, 0xbcf25161, + 0xb2f897c1, 0xf5eb613a, 0x3cdf7a37, 0x7bcc8ccc, 0x20caf777, + 0x67d9018c, 0xaeed1a81, 0xe9feec7a, 0xe7f42ada, 0xa0e7dc21, + 0x69d3c72c, 0x2ec031d7, 0x956a206c, 0xd279d697, 0x1b4dcd9a, + 0x5c5e3b61, 0x5254fdc1, 0x15470b3a, 0xdc731037, 0x9b60e6cc, + 0xc0669d77, 0x87756b8c, 0x4e417081, 0x0952867a, 0x075840da, + 0x404bb621, 0x897fad2c, 0xce6c5bd7, 0x3f735a5a, 0x7860aca1, + 0xb154b7ac, 0xf6474157, 0xf84d87f7, 0xbf5e710c, 0x766a6a01, + 0x31799cfa, 0x6a7fe741, 0x2d6c11ba, 0xe4580ab7, 0xa34bfc4c, + 0xad413aec, 0xea52cc17, 0x2366d71a, 0x647521e1, 0x1a29d241, + 0x5d3a24ba, 0x940e3fb7, 0xd31dc94c, 0xdd170fec, 0x9a04f917, + 0x5330e21a, 0x142314e1, 0x4f256f5a, 0x083699a1, 0xc10282ac, + 0x86117457, 0x881bb2f7, 0xcf08440c, 0x063c5f01, 0x412fa9fa, + 0xb030a877, 0xf7235e8c, 0x3e174581, 0x7904b37a, 0x770e75da, + 0x301d8321, 0xf929982c, 0xbe3a6ed7, 0xe53c156c, 0xa22fe397, + 0x6b1bf89a, 0x2c080e61, 0x2202c8c1, 0x65113e3a, 0xac252537, + 0xeb36d3cc}, + {0x00000000, 0xa13984ee, 0x99020f9d, 0x383b8b73, 0xe975197b, + 0x484c9d95, 0x707716e6, 0xd14e9208, 0x099b34b7, 0xa8a2b059, + 0x90993b2a, 0x31a0bfc4, 0xe0ee2dcc, 0x41d7a922, 0x79ec2251, + 0xd8d5a6bf, 0x1336696e, 0xb20fed80, 0x8a3466f3, 0x2b0de21d, + 0xfa437015, 0x5b7af4fb, 0x63417f88, 0xc278fb66, 0x1aad5dd9, + 0xbb94d937, 0x83af5244, 0x2296d6aa, 0xf3d844a2, 0x52e1c04c, + 0x6ada4b3f, 0xcbe3cfd1, 0x266cd2dc, 0x87555632, 0xbf6edd41, + 0x1e5759af, 0xcf19cba7, 0x6e204f49, 0x561bc43a, 0xf72240d4, + 0x2ff7e66b, 0x8ece6285, 0xb6f5e9f6, 0x17cc6d18, 0xc682ff10, + 0x67bb7bfe, 0x5f80f08d, 0xfeb97463, 0x355abbb2, 0x94633f5c, + 0xac58b42f, 0x0d6130c1, 0xdc2fa2c9, 0x7d162627, 0x452dad54, + 0xe41429ba, 0x3cc18f05, 0x9df80beb, 0xa5c38098, 0x04fa0476, + 0xd5b4967e, 0x748d1290, 0x4cb699e3, 0xed8f1d0d, 0x4cd9a5b8, + 0xede02156, 0xd5dbaa25, 0x74e22ecb, 0xa5acbcc3, 0x0495382d, + 0x3caeb35e, 0x9d9737b0, 0x4542910f, 0xe47b15e1, 0xdc409e92, + 0x7d791a7c, 0xac378874, 0x0d0e0c9a, 0x353587e9, 0x940c0307, + 0x5fefccd6, 0xfed64838, 0xc6edc34b, 0x67d447a5, 0xb69ad5ad, + 0x17a35143, 0x2f98da30, 0x8ea15ede, 0x5674f861, 0xf74d7c8f, + 0xcf76f7fc, 0x6e4f7312, 0xbf01e11a, 0x1e3865f4, 0x2603ee87, + 0x873a6a69, 0x6ab57764, 0xcb8cf38a, 0xf3b778f9, 0x528efc17, + 0x83c06e1f, 0x22f9eaf1, 0x1ac26182, 0xbbfbe56c, 0x632e43d3, + 0xc217c73d, 0xfa2c4c4e, 0x5b15c8a0, 0x8a5b5aa8, 0x2b62de46, + 0x13595535, 0xb260d1db, 0x79831e0a, 0xd8ba9ae4, 0xe0811197, + 0x41b89579, 0x90f60771, 0x31cf839f, 0x09f408ec, 0xa8cd8c02, + 0x70182abd, 0xd121ae53, 0xe91a2520, 0x4823a1ce, 0x996d33c6, + 0x3854b728, 0x006f3c5b, 0xa156b8b5, 0x99b34b70, 0x388acf9e, + 0x00b144ed, 0xa188c003, 0x70c6520b, 0xd1ffd6e5, 0xe9c45d96, + 0x48fdd978, 0x90287fc7, 0x3111fb29, 0x092a705a, 0xa813f4b4, + 0x795d66bc, 0xd864e252, 0xe05f6921, 0x4166edcf, 0x8a85221e, + 0x2bbca6f0, 0x13872d83, 0xb2bea96d, 0x63f03b65, 0xc2c9bf8b, + 0xfaf234f8, 0x5bcbb016, 0x831e16a9, 0x22279247, 0x1a1c1934, + 0xbb259dda, 0x6a6b0fd2, 0xcb528b3c, 0xf369004f, 0x525084a1, + 0xbfdf99ac, 0x1ee61d42, 0x26dd9631, 0x87e412df, 0x56aa80d7, + 0xf7930439, 0xcfa88f4a, 0x6e910ba4, 0xb644ad1b, 0x177d29f5, + 0x2f46a286, 0x8e7f2668, 0x5f31b460, 0xfe08308e, 0xc633bbfd, + 0x670a3f13, 0xace9f0c2, 0x0dd0742c, 0x35ebff5f, 0x94d27bb1, + 0x459ce9b9, 0xe4a56d57, 0xdc9ee624, 0x7da762ca, 0xa572c475, + 0x044b409b, 0x3c70cbe8, 0x9d494f06, 0x4c07dd0e, 0xed3e59e0, + 0xd505d293, 0x743c567d, 0xd56aeec8, 0x74536a26, 0x4c68e155, + 0xed5165bb, 0x3c1ff7b3, 0x9d26735d, 0xa51df82e, 0x04247cc0, + 0xdcf1da7f, 0x7dc85e91, 0x45f3d5e2, 0xe4ca510c, 0x3584c304, + 0x94bd47ea, 0xac86cc99, 0x0dbf4877, 0xc65c87a6, 0x67650348, + 0x5f5e883b, 0xfe670cd5, 0x2f299edd, 0x8e101a33, 0xb62b9140, + 0x171215ae, 0xcfc7b311, 0x6efe37ff, 0x56c5bc8c, 0xf7fc3862, + 0x26b2aa6a, 0x878b2e84, 0xbfb0a5f7, 0x1e892119, 0xf3063c14, + 0x523fb8fa, 0x6a043389, 0xcb3db767, 0x1a73256f, 0xbb4aa181, + 0x83712af2, 0x2248ae1c, 0xfa9d08a3, 0x5ba48c4d, 0x639f073e, + 0xc2a683d0, 0x13e811d8, 0xb2d19536, 0x8aea1e45, 0x2bd39aab, + 0xe030557a, 0x4109d194, 0x79325ae7, 0xd80bde09, 0x09454c01, + 0xa87cc8ef, 0x9047439c, 0x317ec772, 0xe9ab61cd, 0x4892e523, + 0x70a96e50, 0xd190eabe, 0x00de78b6, 0xa1e7fc58, 0x99dc772b, + 0x38e5f3c5}, + {0x00000000, 0xe81790a1, 0x0b5e2703, 0xe349b7a2, 0x16bc4e06, + 0xfeabdea7, 0x1de26905, 0xf5f5f9a4, 0x2d789c0c, 0xc56f0cad, + 0x2626bb0f, 0xce312bae, 0x3bc4d20a, 0xd3d342ab, 0x309af509, + 0xd88d65a8, 0x5af13818, 0xb2e6a8b9, 0x51af1f1b, 0xb9b88fba, + 0x4c4d761e, 0xa45ae6bf, 0x4713511d, 0xaf04c1bc, 0x7789a414, + 0x9f9e34b5, 0x7cd78317, 0x94c013b6, 0x6135ea12, 0x89227ab3, + 0x6a6bcd11, 0x827c5db0, 0xb5e27030, 0x5df5e091, 0xbebc5733, + 0x56abc792, 0xa35e3e36, 0x4b49ae97, 0xa8001935, 0x40178994, + 0x989aec3c, 0x708d7c9d, 0x93c4cb3f, 0x7bd35b9e, 0x8e26a23a, + 0x6631329b, 0x85788539, 0x6d6f1598, 0xef134828, 0x0704d889, + 0xe44d6f2b, 0x0c5aff8a, 0xf9af062e, 0x11b8968f, 0xf2f1212d, + 0x1ae6b18c, 0xc26bd424, 0x2a7c4485, 0xc935f327, 0x21226386, + 0xd4d79a22, 0x3cc00a83, 0xdf89bd21, 0x379e2d80, 0xb0b5e621, + 0x58a27680, 0xbbebc122, 0x53fc5183, 0xa609a827, 0x4e1e3886, + 0xad578f24, 0x45401f85, 0x9dcd7a2d, 0x75daea8c, 0x96935d2e, + 0x7e84cd8f, 0x8b71342b, 0x6366a48a, 0x802f1328, 0x68388389, + 0xea44de39, 0x02534e98, 0xe11af93a, 0x090d699b, 0xfcf8903f, + 0x14ef009e, 0xf7a6b73c, 0x1fb1279d, 0xc73c4235, 0x2f2bd294, + 0xcc626536, 0x2475f597, 0xd1800c33, 0x39979c92, 0xdade2b30, + 0x32c9bb91, 0x05579611, 0xed4006b0, 0x0e09b112, 0xe61e21b3, + 0x13ebd817, 0xfbfc48b6, 0x18b5ff14, 0xf0a26fb5, 0x282f0a1d, + 0xc0389abc, 0x23712d1e, 0xcb66bdbf, 0x3e93441b, 0xd684d4ba, + 0x35cd6318, 0xdddaf3b9, 0x5fa6ae09, 0xb7b13ea8, 0x54f8890a, + 0xbcef19ab, 0x491ae00f, 0xa10d70ae, 0x4244c70c, 0xaa5357ad, + 0x72de3205, 0x9ac9a2a4, 0x79801506, 0x919785a7, 0x64627c03, + 0x8c75eca2, 0x6f3c5b00, 0x872bcba1, 0xba1aca03, 0x520d5aa2, + 0xb144ed00, 0x59537da1, 0xaca68405, 0x44b114a4, 0xa7f8a306, + 0x4fef33a7, 0x9762560f, 0x7f75c6ae, 0x9c3c710c, 0x742be1ad, + 0x81de1809, 0x69c988a8, 0x8a803f0a, 0x6297afab, 0xe0ebf21b, + 0x08fc62ba, 0xebb5d518, 0x03a245b9, 0xf657bc1d, 0x1e402cbc, + 0xfd099b1e, 0x151e0bbf, 0xcd936e17, 0x2584feb6, 0xc6cd4914, + 0x2edad9b5, 0xdb2f2011, 0x3338b0b0, 0xd0710712, 0x386697b3, + 0x0ff8ba33, 0xe7ef2a92, 0x04a69d30, 0xecb10d91, 0x1944f435, + 0xf1536494, 0x121ad336, 0xfa0d4397, 0x2280263f, 0xca97b69e, + 0x29de013c, 0xc1c9919d, 0x343c6839, 0xdc2bf898, 0x3f624f3a, + 0xd775df9b, 0x5509822b, 0xbd1e128a, 0x5e57a528, 0xb6403589, + 0x43b5cc2d, 0xaba25c8c, 0x48ebeb2e, 0xa0fc7b8f, 0x78711e27, + 0x90668e86, 0x732f3924, 0x9b38a985, 0x6ecd5021, 0x86dac080, + 0x65937722, 0x8d84e783, 0x0aaf2c22, 0xe2b8bc83, 0x01f10b21, + 0xe9e69b80, 0x1c136224, 0xf404f285, 0x174d4527, 0xff5ad586, + 0x27d7b02e, 0xcfc0208f, 0x2c89972d, 0xc49e078c, 0x316bfe28, + 0xd97c6e89, 0x3a35d92b, 0xd222498a, 0x505e143a, 0xb849849b, + 0x5b003339, 0xb317a398, 0x46e25a3c, 0xaef5ca9d, 0x4dbc7d3f, + 0xa5abed9e, 0x7d268836, 0x95311897, 0x7678af35, 0x9e6f3f94, + 0x6b9ac630, 0x838d5691, 0x60c4e133, 0x88d37192, 0xbf4d5c12, + 0x575accb3, 0xb4137b11, 0x5c04ebb0, 0xa9f11214, 0x41e682b5, + 0xa2af3517, 0x4ab8a5b6, 0x9235c01e, 0x7a2250bf, 0x996be71d, + 0x717c77bc, 0x84898e18, 0x6c9e1eb9, 0x8fd7a91b, 0x67c039ba, + 0xe5bc640a, 0x0dabf4ab, 0xeee24309, 0x06f5d3a8, 0xf3002a0c, + 0x1b17baad, 0xf85e0d0f, 0x10499dae, 0xc8c4f806, 0x20d368a7, + 0xc39adf05, 0x2b8d4fa4, 0xde78b600, 0x366f26a1, 0xd5269103, + 0x3d3101a2}}; + +local const z_word_t FAR crc_braid_big_table[][256] = { + {0x0000000000000000, 0xa19017e800000000, 0x03275e0b00000000, + 0xa2b749e300000000, 0x064ebc1600000000, 0xa7deabfe00000000, + 0x0569e21d00000000, 0xa4f9f5f500000000, 0x0c9c782d00000000, + 0xad0c6fc500000000, 0x0fbb262600000000, 0xae2b31ce00000000, + 0x0ad2c43b00000000, 0xab42d3d300000000, 0x09f59a3000000000, + 0xa8658dd800000000, 0x1838f15a00000000, 0xb9a8e6b200000000, + 0x1b1faf5100000000, 0xba8fb8b900000000, 0x1e764d4c00000000, + 0xbfe65aa400000000, 0x1d51134700000000, 0xbcc104af00000000, + 0x14a4897700000000, 0xb5349e9f00000000, 0x1783d77c00000000, + 0xb613c09400000000, 0x12ea356100000000, 0xb37a228900000000, + 0x11cd6b6a00000000, 0xb05d7c8200000000, 0x3070e2b500000000, + 0x91e0f55d00000000, 0x3357bcbe00000000, 0x92c7ab5600000000, + 0x363e5ea300000000, 0x97ae494b00000000, 0x351900a800000000, + 0x9489174000000000, 0x3cec9a9800000000, 0x9d7c8d7000000000, + 0x3fcbc49300000000, 0x9e5bd37b00000000, 0x3aa2268e00000000, + 0x9b32316600000000, 0x3985788500000000, 0x98156f6d00000000, + 0x284813ef00000000, 0x89d8040700000000, 0x2b6f4de400000000, + 0x8aff5a0c00000000, 0x2e06aff900000000, 0x8f96b81100000000, + 0x2d21f1f200000000, 0x8cb1e61a00000000, 0x24d46bc200000000, + 0x85447c2a00000000, 0x27f335c900000000, 0x8663222100000000, + 0x229ad7d400000000, 0x830ac03c00000000, 0x21bd89df00000000, + 0x802d9e3700000000, 0x21e6b5b000000000, 0x8076a25800000000, + 0x22c1ebbb00000000, 0x8351fc5300000000, 0x27a809a600000000, + 0x86381e4e00000000, 0x248f57ad00000000, 0x851f404500000000, + 0x2d7acd9d00000000, 0x8ceada7500000000, 0x2e5d939600000000, + 0x8fcd847e00000000, 0x2b34718b00000000, 0x8aa4666300000000, + 0x28132f8000000000, 0x8983386800000000, 0x39de44ea00000000, + 0x984e530200000000, 0x3af91ae100000000, 0x9b690d0900000000, + 0x3f90f8fc00000000, 0x9e00ef1400000000, 0x3cb7a6f700000000, + 0x9d27b11f00000000, 0x35423cc700000000, 0x94d22b2f00000000, + 0x366562cc00000000, 0x97f5752400000000, 0x330c80d100000000, + 0x929c973900000000, 0x302bdeda00000000, 0x91bbc93200000000, + 0x1196570500000000, 0xb00640ed00000000, 0x12b1090e00000000, + 0xb3211ee600000000, 0x17d8eb1300000000, 0xb648fcfb00000000, + 0x14ffb51800000000, 0xb56fa2f000000000, 0x1d0a2f2800000000, + 0xbc9a38c000000000, 0x1e2d712300000000, 0xbfbd66cb00000000, + 0x1b44933e00000000, 0xbad484d600000000, 0x1863cd3500000000, + 0xb9f3dadd00000000, 0x09aea65f00000000, 0xa83eb1b700000000, + 0x0a89f85400000000, 0xab19efbc00000000, 0x0fe01a4900000000, + 0xae700da100000000, 0x0cc7444200000000, 0xad5753aa00000000, + 0x0532de7200000000, 0xa4a2c99a00000000, 0x0615807900000000, + 0xa785979100000000, 0x037c626400000000, 0xa2ec758c00000000, + 0x005b3c6f00000000, 0xa1cb2b8700000000, 0x03ca1aba00000000, + 0xa25a0d5200000000, 0x00ed44b100000000, 0xa17d535900000000, + 0x0584a6ac00000000, 0xa414b14400000000, 0x06a3f8a700000000, + 0xa733ef4f00000000, 0x0f56629700000000, 0xaec6757f00000000, + 0x0c713c9c00000000, 0xade12b7400000000, 0x0918de8100000000, + 0xa888c96900000000, 0x0a3f808a00000000, 0xabaf976200000000, + 0x1bf2ebe000000000, 0xba62fc0800000000, 0x18d5b5eb00000000, + 0xb945a20300000000, 0x1dbc57f600000000, 0xbc2c401e00000000, + 0x1e9b09fd00000000, 0xbf0b1e1500000000, 0x176e93cd00000000, + 0xb6fe842500000000, 0x1449cdc600000000, 0xb5d9da2e00000000, + 0x11202fdb00000000, 0xb0b0383300000000, 0x120771d000000000, + 0xb397663800000000, 0x33baf80f00000000, 0x922aefe700000000, + 0x309da60400000000, 0x910db1ec00000000, 0x35f4441900000000, + 0x946453f100000000, 0x36d31a1200000000, 0x97430dfa00000000, + 0x3f26802200000000, 0x9eb697ca00000000, 0x3c01de2900000000, + 0x9d91c9c100000000, 0x39683c3400000000, 0x98f82bdc00000000, + 0x3a4f623f00000000, 0x9bdf75d700000000, 0x2b82095500000000, + 0x8a121ebd00000000, 0x28a5575e00000000, 0x893540b600000000, + 0x2dccb54300000000, 0x8c5ca2ab00000000, 0x2eebeb4800000000, + 0x8f7bfca000000000, 0x271e717800000000, 0x868e669000000000, + 0x24392f7300000000, 0x85a9389b00000000, 0x2150cd6e00000000, + 0x80c0da8600000000, 0x2277936500000000, 0x83e7848d00000000, + 0x222caf0a00000000, 0x83bcb8e200000000, 0x210bf10100000000, + 0x809be6e900000000, 0x2462131c00000000, 0x85f204f400000000, + 0x27454d1700000000, 0x86d55aff00000000, 0x2eb0d72700000000, + 0x8f20c0cf00000000, 0x2d97892c00000000, 0x8c079ec400000000, + 0x28fe6b3100000000, 0x896e7cd900000000, 0x2bd9353a00000000, + 0x8a4922d200000000, 0x3a145e5000000000, 0x9b8449b800000000, + 0x3933005b00000000, 0x98a317b300000000, 0x3c5ae24600000000, + 0x9dcaf5ae00000000, 0x3f7dbc4d00000000, 0x9eedaba500000000, + 0x3688267d00000000, 0x9718319500000000, 0x35af787600000000, + 0x943f6f9e00000000, 0x30c69a6b00000000, 0x91568d8300000000, + 0x33e1c46000000000, 0x9271d38800000000, 0x125c4dbf00000000, + 0xb3cc5a5700000000, 0x117b13b400000000, 0xb0eb045c00000000, + 0x1412f1a900000000, 0xb582e64100000000, 0x1735afa200000000, + 0xb6a5b84a00000000, 0x1ec0359200000000, 0xbf50227a00000000, + 0x1de76b9900000000, 0xbc777c7100000000, 0x188e898400000000, + 0xb91e9e6c00000000, 0x1ba9d78f00000000, 0xba39c06700000000, + 0x0a64bce500000000, 0xabf4ab0d00000000, 0x0943e2ee00000000, + 0xa8d3f50600000000, 0x0c2a00f300000000, 0xadba171b00000000, + 0x0f0d5ef800000000, 0xae9d491000000000, 0x06f8c4c800000000, + 0xa768d32000000000, 0x05df9ac300000000, 0xa44f8d2b00000000, + 0x00b678de00000000, 0xa1266f3600000000, 0x039126d500000000, + 0xa201313d00000000}, + {0x0000000000000000, 0xee8439a100000000, 0x9d0f029900000000, + 0x738b3b3800000000, 0x7b1975e900000000, 0x959d4c4800000000, + 0xe616777000000000, 0x08924ed100000000, 0xb7349b0900000000, + 0x59b0a2a800000000, 0x2a3b999000000000, 0xc4bfa03100000000, + 0xcc2deee000000000, 0x22a9d74100000000, 0x5122ec7900000000, + 0xbfa6d5d800000000, 0x6e69361300000000, 0x80ed0fb200000000, + 0xf366348a00000000, 0x1de20d2b00000000, 0x157043fa00000000, + 0xfbf47a5b00000000, 0x887f416300000000, 0x66fb78c200000000, + 0xd95dad1a00000000, 0x37d994bb00000000, 0x4452af8300000000, + 0xaad6962200000000, 0xa244d8f300000000, 0x4cc0e15200000000, + 0x3f4bda6a00000000, 0xd1cfe3cb00000000, 0xdcd26c2600000000, + 0x3256558700000000, 0x41dd6ebf00000000, 0xaf59571e00000000, + 0xa7cb19cf00000000, 0x494f206e00000000, 0x3ac41b5600000000, + 0xd44022f700000000, 0x6be6f72f00000000, 0x8562ce8e00000000, + 0xf6e9f5b600000000, 0x186dcc1700000000, 0x10ff82c600000000, + 0xfe7bbb6700000000, 0x8df0805f00000000, 0x6374b9fe00000000, + 0xb2bb5a3500000000, 0x5c3f639400000000, 0x2fb458ac00000000, + 0xc130610d00000000, 0xc9a22fdc00000000, 0x2726167d00000000, + 0x54ad2d4500000000, 0xba2914e400000000, 0x058fc13c00000000, + 0xeb0bf89d00000000, 0x9880c3a500000000, 0x7604fa0400000000, + 0x7e96b4d500000000, 0x90128d7400000000, 0xe399b64c00000000, + 0x0d1d8fed00000000, 0xb8a5d94c00000000, 0x5621e0ed00000000, + 0x25aadbd500000000, 0xcb2ee27400000000, 0xc3bcaca500000000, + 0x2d38950400000000, 0x5eb3ae3c00000000, 0xb037979d00000000, + 0x0f91424500000000, 0xe1157be400000000, 0x929e40dc00000000, + 0x7c1a797d00000000, 0x748837ac00000000, 0x9a0c0e0d00000000, + 0xe987353500000000, 0x07030c9400000000, 0xd6ccef5f00000000, + 0x3848d6fe00000000, 0x4bc3edc600000000, 0xa547d46700000000, + 0xadd59ab600000000, 0x4351a31700000000, 0x30da982f00000000, + 0xde5ea18e00000000, 0x61f8745600000000, 0x8f7c4df700000000, + 0xfcf776cf00000000, 0x12734f6e00000000, 0x1ae101bf00000000, + 0xf465381e00000000, 0x87ee032600000000, 0x696a3a8700000000, + 0x6477b56a00000000, 0x8af38ccb00000000, 0xf978b7f300000000, + 0x17fc8e5200000000, 0x1f6ec08300000000, 0xf1eaf92200000000, + 0x8261c21a00000000, 0x6ce5fbbb00000000, 0xd3432e6300000000, + 0x3dc717c200000000, 0x4e4c2cfa00000000, 0xa0c8155b00000000, + 0xa85a5b8a00000000, 0x46de622b00000000, 0x3555591300000000, + 0xdbd160b200000000, 0x0a1e837900000000, 0xe49abad800000000, + 0x971181e000000000, 0x7995b84100000000, 0x7107f69000000000, + 0x9f83cf3100000000, 0xec08f40900000000, 0x028ccda800000000, + 0xbd2a187000000000, 0x53ae21d100000000, 0x20251ae900000000, + 0xcea1234800000000, 0xc6336d9900000000, 0x28b7543800000000, + 0x5b3c6f0000000000, 0xb5b856a100000000, 0x704bb39900000000, + 0x9ecf8a3800000000, 0xed44b10000000000, 0x03c088a100000000, + 0x0b52c67000000000, 0xe5d6ffd100000000, 0x965dc4e900000000, + 0x78d9fd4800000000, 0xc77f289000000000, 0x29fb113100000000, + 0x5a702a0900000000, 0xb4f413a800000000, 0xbc665d7900000000, + 0x52e264d800000000, 0x21695fe000000000, 0xcfed664100000000, + 0x1e22858a00000000, 0xf0a6bc2b00000000, 0x832d871300000000, + 0x6da9beb200000000, 0x653bf06300000000, 0x8bbfc9c200000000, + 0xf834f2fa00000000, 0x16b0cb5b00000000, 0xa9161e8300000000, + 0x4792272200000000, 0x34191c1a00000000, 0xda9d25bb00000000, + 0xd20f6b6a00000000, 0x3c8b52cb00000000, 0x4f0069f300000000, + 0xa184505200000000, 0xac99dfbf00000000, 0x421de61e00000000, + 0x3196dd2600000000, 0xdf12e48700000000, 0xd780aa5600000000, + 0x390493f700000000, 0x4a8fa8cf00000000, 0xa40b916e00000000, + 0x1bad44b600000000, 0xf5297d1700000000, 0x86a2462f00000000, + 0x68267f8e00000000, 0x60b4315f00000000, 0x8e3008fe00000000, + 0xfdbb33c600000000, 0x133f0a6700000000, 0xc2f0e9ac00000000, + 0x2c74d00d00000000, 0x5fffeb3500000000, 0xb17bd29400000000, + 0xb9e99c4500000000, 0x576da5e400000000, 0x24e69edc00000000, + 0xca62a77d00000000, 0x75c472a500000000, 0x9b404b0400000000, + 0xe8cb703c00000000, 0x064f499d00000000, 0x0edd074c00000000, + 0xe0593eed00000000, 0x93d205d500000000, 0x7d563c7400000000, + 0xc8ee6ad500000000, 0x266a537400000000, 0x55e1684c00000000, + 0xbb6551ed00000000, 0xb3f71f3c00000000, 0x5d73269d00000000, + 0x2ef81da500000000, 0xc07c240400000000, 0x7fdaf1dc00000000, + 0x915ec87d00000000, 0xe2d5f34500000000, 0x0c51cae400000000, + 0x04c3843500000000, 0xea47bd9400000000, 0x99cc86ac00000000, + 0x7748bf0d00000000, 0xa6875cc600000000, 0x4803656700000000, + 0x3b885e5f00000000, 0xd50c67fe00000000, 0xdd9e292f00000000, + 0x331a108e00000000, 0x40912bb600000000, 0xae15121700000000, + 0x11b3c7cf00000000, 0xff37fe6e00000000, 0x8cbcc55600000000, + 0x6238fcf700000000, 0x6aaab22600000000, 0x842e8b8700000000, + 0xf7a5b0bf00000000, 0x1921891e00000000, 0x143c06f300000000, + 0xfab83f5200000000, 0x8933046a00000000, 0x67b73dcb00000000, + 0x6f25731a00000000, 0x81a14abb00000000, 0xf22a718300000000, + 0x1cae482200000000, 0xa3089dfa00000000, 0x4d8ca45b00000000, + 0x3e079f6300000000, 0xd083a6c200000000, 0xd811e81300000000, + 0x3695d1b200000000, 0x451eea8a00000000, 0xab9ad32b00000000, + 0x7a5530e000000000, 0x94d1094100000000, 0xe75a327900000000, + 0x09de0bd800000000, 0x014c450900000000, 0xefc87ca800000000, + 0x9c43479000000000, 0x72c77e3100000000, 0xcd61abe900000000, + 0x23e5924800000000, 0x506ea97000000000, 0xbeea90d100000000, + 0xb678de0000000000, 0x58fce7a100000000, 0x2b77dc9900000000, + 0xc5f3e53800000000}, + {0x0000000000000000, 0xfbf6134700000000, 0xf6ed278e00000000, + 0x0d1b34c900000000, 0xaddd3ec700000000, 0x562b2d8000000000, + 0x5b30194900000000, 0xa0c60a0e00000000, 0x1bbd0c5500000000, + 0xe04b1f1200000000, 0xed502bdb00000000, 0x16a6389c00000000, + 0xb660329200000000, 0x4d9621d500000000, 0x408d151c00000000, + 0xbb7b065b00000000, 0x367a19aa00000000, 0xcd8c0aed00000000, + 0xc0973e2400000000, 0x3b612d6300000000, 0x9ba7276d00000000, + 0x6051342a00000000, 0x6d4a00e300000000, 0x96bc13a400000000, + 0x2dc715ff00000000, 0xd63106b800000000, 0xdb2a327100000000, + 0x20dc213600000000, 0x801a2b3800000000, 0x7bec387f00000000, + 0x76f70cb600000000, 0x8d011ff100000000, 0x2df2438f00000000, + 0xd60450c800000000, 0xdb1f640100000000, 0x20e9774600000000, + 0x802f7d4800000000, 0x7bd96e0f00000000, 0x76c25ac600000000, + 0x8d34498100000000, 0x364f4fda00000000, 0xcdb95c9d00000000, + 0xc0a2685400000000, 0x3b547b1300000000, 0x9b92711d00000000, + 0x6064625a00000000, 0x6d7f569300000000, 0x968945d400000000, + 0x1b885a2500000000, 0xe07e496200000000, 0xed657dab00000000, + 0x16936eec00000000, 0xb65564e200000000, 0x4da377a500000000, + 0x40b8436c00000000, 0xbb4e502b00000000, 0x0035567000000000, + 0xfbc3453700000000, 0xf6d871fe00000000, 0x0d2e62b900000000, + 0xade868b700000000, 0x561e7bf000000000, 0x5b054f3900000000, + 0xa0f35c7e00000000, 0x1be2f6c500000000, 0xe014e58200000000, + 0xed0fd14b00000000, 0x16f9c20c00000000, 0xb63fc80200000000, + 0x4dc9db4500000000, 0x40d2ef8c00000000, 0xbb24fccb00000000, + 0x005ffa9000000000, 0xfba9e9d700000000, 0xf6b2dd1e00000000, + 0x0d44ce5900000000, 0xad82c45700000000, 0x5674d71000000000, + 0x5b6fe3d900000000, 0xa099f09e00000000, 0x2d98ef6f00000000, + 0xd66efc2800000000, 0xdb75c8e100000000, 0x2083dba600000000, + 0x8045d1a800000000, 0x7bb3c2ef00000000, 0x76a8f62600000000, + 0x8d5ee56100000000, 0x3625e33a00000000, 0xcdd3f07d00000000, + 0xc0c8c4b400000000, 0x3b3ed7f300000000, 0x9bf8ddfd00000000, + 0x600eceba00000000, 0x6d15fa7300000000, 0x96e3e93400000000, + 0x3610b54a00000000, 0xcde6a60d00000000, 0xc0fd92c400000000, + 0x3b0b818300000000, 0x9bcd8b8d00000000, 0x603b98ca00000000, + 0x6d20ac0300000000, 0x96d6bf4400000000, 0x2dadb91f00000000, + 0xd65baa5800000000, 0xdb409e9100000000, 0x20b68dd600000000, + 0x807087d800000000, 0x7b86949f00000000, 0x769da05600000000, + 0x8d6bb31100000000, 0x006aace000000000, 0xfb9cbfa700000000, + 0xf6878b6e00000000, 0x0d71982900000000, 0xadb7922700000000, + 0x5641816000000000, 0x5b5ab5a900000000, 0xa0aca6ee00000000, + 0x1bd7a0b500000000, 0xe021b3f200000000, 0xed3a873b00000000, + 0x16cc947c00000000, 0xb60a9e7200000000, 0x4dfc8d3500000000, + 0x40e7b9fc00000000, 0xbb11aabb00000000, 0x77c29c5000000000, + 0x8c348f1700000000, 0x812fbbde00000000, 0x7ad9a89900000000, + 0xda1fa29700000000, 0x21e9b1d000000000, 0x2cf2851900000000, + 0xd704965e00000000, 0x6c7f900500000000, 0x9789834200000000, + 0x9a92b78b00000000, 0x6164a4cc00000000, 0xc1a2aec200000000, + 0x3a54bd8500000000, 0x374f894c00000000, 0xccb99a0b00000000, + 0x41b885fa00000000, 0xba4e96bd00000000, 0xb755a27400000000, + 0x4ca3b13300000000, 0xec65bb3d00000000, 0x1793a87a00000000, + 0x1a889cb300000000, 0xe17e8ff400000000, 0x5a0589af00000000, + 0xa1f39ae800000000, 0xace8ae2100000000, 0x571ebd6600000000, + 0xf7d8b76800000000, 0x0c2ea42f00000000, 0x013590e600000000, + 0xfac383a100000000, 0x5a30dfdf00000000, 0xa1c6cc9800000000, + 0xacddf85100000000, 0x572beb1600000000, 0xf7ede11800000000, + 0x0c1bf25f00000000, 0x0100c69600000000, 0xfaf6d5d100000000, + 0x418dd38a00000000, 0xba7bc0cd00000000, 0xb760f40400000000, + 0x4c96e74300000000, 0xec50ed4d00000000, 0x17a6fe0a00000000, + 0x1abdcac300000000, 0xe14bd98400000000, 0x6c4ac67500000000, + 0x97bcd53200000000, 0x9aa7e1fb00000000, 0x6151f2bc00000000, + 0xc197f8b200000000, 0x3a61ebf500000000, 0x377adf3c00000000, + 0xcc8ccc7b00000000, 0x77f7ca2000000000, 0x8c01d96700000000, + 0x811aedae00000000, 0x7aecfee900000000, 0xda2af4e700000000, + 0x21dce7a000000000, 0x2cc7d36900000000, 0xd731c02e00000000, + 0x6c206a9500000000, 0x97d679d200000000, 0x9acd4d1b00000000, + 0x613b5e5c00000000, 0xc1fd545200000000, 0x3a0b471500000000, + 0x371073dc00000000, 0xcce6609b00000000, 0x779d66c000000000, + 0x8c6b758700000000, 0x8170414e00000000, 0x7a86520900000000, + 0xda40580700000000, 0x21b64b4000000000, 0x2cad7f8900000000, + 0xd75b6cce00000000, 0x5a5a733f00000000, 0xa1ac607800000000, + 0xacb754b100000000, 0x574147f600000000, 0xf7874df800000000, + 0x0c715ebf00000000, 0x016a6a7600000000, 0xfa9c793100000000, + 0x41e77f6a00000000, 0xba116c2d00000000, 0xb70a58e400000000, + 0x4cfc4ba300000000, 0xec3a41ad00000000, 0x17cc52ea00000000, + 0x1ad7662300000000, 0xe121756400000000, 0x41d2291a00000000, + 0xba243a5d00000000, 0xb73f0e9400000000, 0x4cc91dd300000000, + 0xec0f17dd00000000, 0x17f9049a00000000, 0x1ae2305300000000, + 0xe114231400000000, 0x5a6f254f00000000, 0xa199360800000000, + 0xac8202c100000000, 0x5774118600000000, 0xf7b21b8800000000, + 0x0c4408cf00000000, 0x015f3c0600000000, 0xfaa92f4100000000, + 0x77a830b000000000, 0x8c5e23f700000000, 0x8145173e00000000, + 0x7ab3047900000000, 0xda750e7700000000, 0x21831d3000000000, + 0x2c9829f900000000, 0xd76e3abe00000000, 0x6c153ce500000000, + 0x97e32fa200000000, 0x9af81b6b00000000, 0x610e082c00000000, + 0xc1c8022200000000, 0x3a3e116500000000, 0x372525ac00000000, + 0xccd336eb00000000}, + {0x0000000000000000, 0x6238282a00000000, 0xc470505400000000, + 0xa648787e00000000, 0x88e1a0a800000000, 0xead9888200000000, + 0x4c91f0fc00000000, 0x2ea9d8d600000000, 0x51c5308a00000000, + 0x33fd18a000000000, 0x95b560de00000000, 0xf78d48f400000000, + 0xd924902200000000, 0xbb1cb80800000000, 0x1d54c07600000000, + 0x7f6ce85c00000000, 0xe38c10cf00000000, 0x81b438e500000000, + 0x27fc409b00000000, 0x45c468b100000000, 0x6b6db06700000000, + 0x0955984d00000000, 0xaf1de03300000000, 0xcd25c81900000000, + 0xb249204500000000, 0xd071086f00000000, 0x7639701100000000, + 0x1401583b00000000, 0x3aa880ed00000000, 0x5890a8c700000000, + 0xfed8d0b900000000, 0x9ce0f89300000000, 0x871f504500000000, + 0xe527786f00000000, 0x436f001100000000, 0x2157283b00000000, + 0x0ffef0ed00000000, 0x6dc6d8c700000000, 0xcb8ea0b900000000, + 0xa9b6889300000000, 0xd6da60cf00000000, 0xb4e248e500000000, + 0x12aa309b00000000, 0x709218b100000000, 0x5e3bc06700000000, + 0x3c03e84d00000000, 0x9a4b903300000000, 0xf873b81900000000, + 0x6493408a00000000, 0x06ab68a000000000, 0xa0e310de00000000, + 0xc2db38f400000000, 0xec72e02200000000, 0x8e4ac80800000000, + 0x2802b07600000000, 0x4a3a985c00000000, 0x3556700000000000, + 0x576e582a00000000, 0xf126205400000000, 0x931e087e00000000, + 0xbdb7d0a800000000, 0xdf8ff88200000000, 0x79c780fc00000000, + 0x1bffa8d600000000, 0x0e3fa08a00000000, 0x6c0788a000000000, + 0xca4ff0de00000000, 0xa877d8f400000000, 0x86de002200000000, + 0xe4e6280800000000, 0x42ae507600000000, 0x2096785c00000000, + 0x5ffa900000000000, 0x3dc2b82a00000000, 0x9b8ac05400000000, + 0xf9b2e87e00000000, 0xd71b30a800000000, 0xb523188200000000, + 0x136b60fc00000000, 0x715348d600000000, 0xedb3b04500000000, + 0x8f8b986f00000000, 0x29c3e01100000000, 0x4bfbc83b00000000, + 0x655210ed00000000, 0x076a38c700000000, 0xa12240b900000000, + 0xc31a689300000000, 0xbc7680cf00000000, 0xde4ea8e500000000, + 0x7806d09b00000000, 0x1a3ef8b100000000, 0x3497206700000000, + 0x56af084d00000000, 0xf0e7703300000000, 0x92df581900000000, + 0x8920f0cf00000000, 0xeb18d8e500000000, 0x4d50a09b00000000, + 0x2f6888b100000000, 0x01c1506700000000, 0x63f9784d00000000, + 0xc5b1003300000000, 0xa789281900000000, 0xd8e5c04500000000, + 0xbadde86f00000000, 0x1c95901100000000, 0x7eadb83b00000000, + 0x500460ed00000000, 0x323c48c700000000, 0x947430b900000000, + 0xf64c189300000000, 0x6aace00000000000, 0x0894c82a00000000, + 0xaedcb05400000000, 0xcce4987e00000000, 0xe24d40a800000000, + 0x8075688200000000, 0x263d10fc00000000, 0x440538d600000000, + 0x3b69d08a00000000, 0x5951f8a000000000, 0xff1980de00000000, + 0x9d21a8f400000000, 0xb388702200000000, 0xd1b0580800000000, + 0x77f8207600000000, 0x15c0085c00000000, 0x5d7831ce00000000, + 0x3f4019e400000000, 0x9908619a00000000, 0xfb3049b000000000, + 0xd599916600000000, 0xb7a1b94c00000000, 0x11e9c13200000000, + 0x73d1e91800000000, 0x0cbd014400000000, 0x6e85296e00000000, + 0xc8cd511000000000, 0xaaf5793a00000000, 0x845ca1ec00000000, + 0xe66489c600000000, 0x402cf1b800000000, 0x2214d99200000000, + 0xbef4210100000000, 0xdccc092b00000000, 0x7a84715500000000, + 0x18bc597f00000000, 0x361581a900000000, 0x542da98300000000, + 0xf265d1fd00000000, 0x905df9d700000000, 0xef31118b00000000, + 0x8d0939a100000000, 0x2b4141df00000000, 0x497969f500000000, + 0x67d0b12300000000, 0x05e8990900000000, 0xa3a0e17700000000, + 0xc198c95d00000000, 0xda67618b00000000, 0xb85f49a100000000, + 0x1e1731df00000000, 0x7c2f19f500000000, 0x5286c12300000000, + 0x30bee90900000000, 0x96f6917700000000, 0xf4ceb95d00000000, + 0x8ba2510100000000, 0xe99a792b00000000, 0x4fd2015500000000, + 0x2dea297f00000000, 0x0343f1a900000000, 0x617bd98300000000, + 0xc733a1fd00000000, 0xa50b89d700000000, 0x39eb714400000000, + 0x5bd3596e00000000, 0xfd9b211000000000, 0x9fa3093a00000000, + 0xb10ad1ec00000000, 0xd332f9c600000000, 0x757a81b800000000, + 0x1742a99200000000, 0x682e41ce00000000, 0x0a1669e400000000, + 0xac5e119a00000000, 0xce6639b000000000, 0xe0cfe16600000000, + 0x82f7c94c00000000, 0x24bfb13200000000, 0x4687991800000000, + 0x5347914400000000, 0x317fb96e00000000, 0x9737c11000000000, + 0xf50fe93a00000000, 0xdba631ec00000000, 0xb99e19c600000000, + 0x1fd661b800000000, 0x7dee499200000000, 0x0282a1ce00000000, + 0x60ba89e400000000, 0xc6f2f19a00000000, 0xa4cad9b000000000, + 0x8a63016600000000, 0xe85b294c00000000, 0x4e13513200000000, + 0x2c2b791800000000, 0xb0cb818b00000000, 0xd2f3a9a100000000, + 0x74bbd1df00000000, 0x1683f9f500000000, 0x382a212300000000, + 0x5a12090900000000, 0xfc5a717700000000, 0x9e62595d00000000, + 0xe10eb10100000000, 0x8336992b00000000, 0x257ee15500000000, + 0x4746c97f00000000, 0x69ef11a900000000, 0x0bd7398300000000, + 0xad9f41fd00000000, 0xcfa769d700000000, 0xd458c10100000000, + 0xb660e92b00000000, 0x1028915500000000, 0x7210b97f00000000, + 0x5cb961a900000000, 0x3e81498300000000, 0x98c931fd00000000, + 0xfaf119d700000000, 0x859df18b00000000, 0xe7a5d9a100000000, + 0x41eda1df00000000, 0x23d589f500000000, 0x0d7c512300000000, + 0x6f44790900000000, 0xc90c017700000000, 0xab34295d00000000, + 0x37d4d1ce00000000, 0x55ecf9e400000000, 0xf3a4819a00000000, + 0x919ca9b000000000, 0xbf35716600000000, 0xdd0d594c00000000, + 0x7b45213200000000, 0x197d091800000000, 0x6611e14400000000, + 0x0429c96e00000000, 0xa261b11000000000, 0xc059993a00000000, + 0xeef041ec00000000, 0x8cc869c600000000, 0x2a8011b800000000, + 0x48b8399200000000}, + {0x0000000000000000, 0x4c2896a300000000, 0xd9565d9c00000000, + 0x957ecb3f00000000, 0xf3abcbe300000000, 0xbf835d4000000000, + 0x2afd967f00000000, 0x66d500dc00000000, 0xa751e61c00000000, + 0xeb7970bf00000000, 0x7e07bb8000000000, 0x322f2d2300000000, + 0x54fa2dff00000000, 0x18d2bb5c00000000, 0x8dac706300000000, + 0xc184e6c000000000, 0x4ea3cc3900000000, 0x028b5a9a00000000, + 0x97f591a500000000, 0xdbdd070600000000, 0xbd0807da00000000, + 0xf120917900000000, 0x645e5a4600000000, 0x2876cce500000000, + 0xe9f22a2500000000, 0xa5dabc8600000000, 0x30a477b900000000, + 0x7c8ce11a00000000, 0x1a59e1c600000000, 0x5671776500000000, + 0xc30fbc5a00000000, 0x8f272af900000000, 0x9c46997300000000, + 0xd06e0fd000000000, 0x4510c4ef00000000, 0x0938524c00000000, + 0x6fed529000000000, 0x23c5c43300000000, 0xb6bb0f0c00000000, + 0xfa9399af00000000, 0x3b177f6f00000000, 0x773fe9cc00000000, + 0xe24122f300000000, 0xae69b45000000000, 0xc8bcb48c00000000, + 0x8494222f00000000, 0x11eae91000000000, 0x5dc27fb300000000, + 0xd2e5554a00000000, 0x9ecdc3e900000000, 0x0bb308d600000000, + 0x479b9e7500000000, 0x214e9ea900000000, 0x6d66080a00000000, + 0xf818c33500000000, 0xb430559600000000, 0x75b4b35600000000, + 0x399c25f500000000, 0xace2eeca00000000, 0xe0ca786900000000, + 0x861f78b500000000, 0xca37ee1600000000, 0x5f49252900000000, + 0x1361b38a00000000, 0x388d32e700000000, 0x74a5a44400000000, + 0xe1db6f7b00000000, 0xadf3f9d800000000, 0xcb26f90400000000, + 0x870e6fa700000000, 0x1270a49800000000, 0x5e58323b00000000, + 0x9fdcd4fb00000000, 0xd3f4425800000000, 0x468a896700000000, + 0x0aa21fc400000000, 0x6c771f1800000000, 0x205f89bb00000000, + 0xb521428400000000, 0xf909d42700000000, 0x762efede00000000, + 0x3a06687d00000000, 0xaf78a34200000000, 0xe35035e100000000, + 0x8585353d00000000, 0xc9ada39e00000000, 0x5cd368a100000000, + 0x10fbfe0200000000, 0xd17f18c200000000, 0x9d578e6100000000, + 0x0829455e00000000, 0x4401d3fd00000000, 0x22d4d32100000000, + 0x6efc458200000000, 0xfb828ebd00000000, 0xb7aa181e00000000, + 0xa4cbab9400000000, 0xe8e33d3700000000, 0x7d9df60800000000, + 0x31b560ab00000000, 0x5760607700000000, 0x1b48f6d400000000, + 0x8e363deb00000000, 0xc21eab4800000000, 0x039a4d8800000000, + 0x4fb2db2b00000000, 0xdacc101400000000, 0x96e486b700000000, + 0xf031866b00000000, 0xbc1910c800000000, 0x2967dbf700000000, + 0x654f4d5400000000, 0xea6867ad00000000, 0xa640f10e00000000, + 0x333e3a3100000000, 0x7f16ac9200000000, 0x19c3ac4e00000000, + 0x55eb3aed00000000, 0xc095f1d200000000, 0x8cbd677100000000, + 0x4d3981b100000000, 0x0111171200000000, 0x946fdc2d00000000, + 0xd8474a8e00000000, 0xbe924a5200000000, 0xf2badcf100000000, + 0x67c417ce00000000, 0x2bec816d00000000, 0x311c141500000000, + 0x7d3482b600000000, 0xe84a498900000000, 0xa462df2a00000000, + 0xc2b7dff600000000, 0x8e9f495500000000, 0x1be1826a00000000, + 0x57c914c900000000, 0x964df20900000000, 0xda6564aa00000000, + 0x4f1baf9500000000, 0x0333393600000000, 0x65e639ea00000000, + 0x29ceaf4900000000, 0xbcb0647600000000, 0xf098f2d500000000, + 0x7fbfd82c00000000, 0x33974e8f00000000, 0xa6e985b000000000, + 0xeac1131300000000, 0x8c1413cf00000000, 0xc03c856c00000000, + 0x55424e5300000000, 0x196ad8f000000000, 0xd8ee3e3000000000, + 0x94c6a89300000000, 0x01b863ac00000000, 0x4d90f50f00000000, + 0x2b45f5d300000000, 0x676d637000000000, 0xf213a84f00000000, + 0xbe3b3eec00000000, 0xad5a8d6600000000, 0xe1721bc500000000, + 0x740cd0fa00000000, 0x3824465900000000, 0x5ef1468500000000, + 0x12d9d02600000000, 0x87a71b1900000000, 0xcb8f8dba00000000, + 0x0a0b6b7a00000000, 0x4623fdd900000000, 0xd35d36e600000000, + 0x9f75a04500000000, 0xf9a0a09900000000, 0xb588363a00000000, + 0x20f6fd0500000000, 0x6cde6ba600000000, 0xe3f9415f00000000, + 0xafd1d7fc00000000, 0x3aaf1cc300000000, 0x76878a6000000000, + 0x10528abc00000000, 0x5c7a1c1f00000000, 0xc904d72000000000, + 0x852c418300000000, 0x44a8a74300000000, 0x088031e000000000, + 0x9dfefadf00000000, 0xd1d66c7c00000000, 0xb7036ca000000000, + 0xfb2bfa0300000000, 0x6e55313c00000000, 0x227da79f00000000, + 0x099126f200000000, 0x45b9b05100000000, 0xd0c77b6e00000000, + 0x9cefedcd00000000, 0xfa3aed1100000000, 0xb6127bb200000000, + 0x236cb08d00000000, 0x6f44262e00000000, 0xaec0c0ee00000000, + 0xe2e8564d00000000, 0x77969d7200000000, 0x3bbe0bd100000000, + 0x5d6b0b0d00000000, 0x11439dae00000000, 0x843d569100000000, + 0xc815c03200000000, 0x4732eacb00000000, 0x0b1a7c6800000000, + 0x9e64b75700000000, 0xd24c21f400000000, 0xb499212800000000, + 0xf8b1b78b00000000, 0x6dcf7cb400000000, 0x21e7ea1700000000, + 0xe0630cd700000000, 0xac4b9a7400000000, 0x3935514b00000000, + 0x751dc7e800000000, 0x13c8c73400000000, 0x5fe0519700000000, + 0xca9e9aa800000000, 0x86b60c0b00000000, 0x95d7bf8100000000, + 0xd9ff292200000000, 0x4c81e21d00000000, 0x00a974be00000000, + 0x667c746200000000, 0x2a54e2c100000000, 0xbf2a29fe00000000, + 0xf302bf5d00000000, 0x3286599d00000000, 0x7eaecf3e00000000, + 0xebd0040100000000, 0xa7f892a200000000, 0xc12d927e00000000, + 0x8d0504dd00000000, 0x187bcfe200000000, 0x5453594100000000, + 0xdb7473b800000000, 0x975ce51b00000000, 0x02222e2400000000, + 0x4e0ab88700000000, 0x28dfb85b00000000, 0x64f72ef800000000, + 0xf189e5c700000000, 0xbda1736400000000, 0x7c2595a400000000, + 0x300d030700000000, 0xa573c83800000000, 0xe95b5e9b00000000, + 0x8f8e5e4700000000, 0xc3a6c8e400000000, 0x56d803db00000000, + 0x1af0957800000000}, + {0x0000000000000000, 0x939bc97f00000000, 0x263793ff00000000, + 0xb5ac5a8000000000, 0x0d68572400000000, 0x9ef39e5b00000000, + 0x2b5fc4db00000000, 0xb8c40da400000000, 0x1ad0ae4800000000, + 0x894b673700000000, 0x3ce73db700000000, 0xaf7cf4c800000000, + 0x17b8f96c00000000, 0x8423301300000000, 0x318f6a9300000000, + 0xa214a3ec00000000, 0x34a05d9100000000, 0xa73b94ee00000000, + 0x1297ce6e00000000, 0x810c071100000000, 0x39c80ab500000000, + 0xaa53c3ca00000000, 0x1fff994a00000000, 0x8c64503500000000, + 0x2e70f3d900000000, 0xbdeb3aa600000000, 0x0847602600000000, + 0x9bdca95900000000, 0x2318a4fd00000000, 0xb0836d8200000000, + 0x052f370200000000, 0x96b4fe7d00000000, 0x2946caf900000000, + 0xbadd038600000000, 0x0f71590600000000, 0x9cea907900000000, + 0x242e9ddd00000000, 0xb7b554a200000000, 0x02190e2200000000, + 0x9182c75d00000000, 0x339664b100000000, 0xa00dadce00000000, + 0x15a1f74e00000000, 0x863a3e3100000000, 0x3efe339500000000, + 0xad65faea00000000, 0x18c9a06a00000000, 0x8b52691500000000, + 0x1de6976800000000, 0x8e7d5e1700000000, 0x3bd1049700000000, + 0xa84acde800000000, 0x108ec04c00000000, 0x8315093300000000, + 0x36b953b300000000, 0xa5229acc00000000, 0x0736392000000000, + 0x94adf05f00000000, 0x2101aadf00000000, 0xb29a63a000000000, + 0x0a5e6e0400000000, 0x99c5a77b00000000, 0x2c69fdfb00000000, + 0xbff2348400000000, 0x138ae52800000000, 0x80112c5700000000, + 0x35bd76d700000000, 0xa626bfa800000000, 0x1ee2b20c00000000, + 0x8d797b7300000000, 0x38d521f300000000, 0xab4ee88c00000000, + 0x095a4b6000000000, 0x9ac1821f00000000, 0x2f6dd89f00000000, + 0xbcf611e000000000, 0x04321c4400000000, 0x97a9d53b00000000, + 0x22058fbb00000000, 0xb19e46c400000000, 0x272ab8b900000000, + 0xb4b171c600000000, 0x011d2b4600000000, 0x9286e23900000000, + 0x2a42ef9d00000000, 0xb9d926e200000000, 0x0c757c6200000000, + 0x9feeb51d00000000, 0x3dfa16f100000000, 0xae61df8e00000000, + 0x1bcd850e00000000, 0x88564c7100000000, 0x309241d500000000, + 0xa30988aa00000000, 0x16a5d22a00000000, 0x853e1b5500000000, + 0x3acc2fd100000000, 0xa957e6ae00000000, 0x1cfbbc2e00000000, + 0x8f60755100000000, 0x37a478f500000000, 0xa43fb18a00000000, + 0x1193eb0a00000000, 0x8208227500000000, 0x201c819900000000, + 0xb38748e600000000, 0x062b126600000000, 0x95b0db1900000000, + 0x2d74d6bd00000000, 0xbeef1fc200000000, 0x0b43454200000000, + 0x98d88c3d00000000, 0x0e6c724000000000, 0x9df7bb3f00000000, + 0x285be1bf00000000, 0xbbc028c000000000, 0x0304256400000000, + 0x909fec1b00000000, 0x2533b69b00000000, 0xb6a87fe400000000, + 0x14bcdc0800000000, 0x8727157700000000, 0x328b4ff700000000, + 0xa110868800000000, 0x19d48b2c00000000, 0x8a4f425300000000, + 0x3fe318d300000000, 0xac78d1ac00000000, 0x2614cb5100000000, + 0xb58f022e00000000, 0x002358ae00000000, 0x93b891d100000000, + 0x2b7c9c7500000000, 0xb8e7550a00000000, 0x0d4b0f8a00000000, + 0x9ed0c6f500000000, 0x3cc4651900000000, 0xaf5fac6600000000, + 0x1af3f6e600000000, 0x89683f9900000000, 0x31ac323d00000000, + 0xa237fb4200000000, 0x179ba1c200000000, 0x840068bd00000000, + 0x12b496c000000000, 0x812f5fbf00000000, 0x3483053f00000000, + 0xa718cc4000000000, 0x1fdcc1e400000000, 0x8c47089b00000000, + 0x39eb521b00000000, 0xaa709b6400000000, 0x0864388800000000, + 0x9bfff1f700000000, 0x2e53ab7700000000, 0xbdc8620800000000, + 0x050c6fac00000000, 0x9697a6d300000000, 0x233bfc5300000000, + 0xb0a0352c00000000, 0x0f5201a800000000, 0x9cc9c8d700000000, + 0x2965925700000000, 0xbafe5b2800000000, 0x023a568c00000000, + 0x91a19ff300000000, 0x240dc57300000000, 0xb7960c0c00000000, + 0x1582afe000000000, 0x8619669f00000000, 0x33b53c1f00000000, + 0xa02ef56000000000, 0x18eaf8c400000000, 0x8b7131bb00000000, + 0x3edd6b3b00000000, 0xad46a24400000000, 0x3bf25c3900000000, + 0xa869954600000000, 0x1dc5cfc600000000, 0x8e5e06b900000000, + 0x369a0b1d00000000, 0xa501c26200000000, 0x10ad98e200000000, + 0x8336519d00000000, 0x2122f27100000000, 0xb2b93b0e00000000, + 0x0715618e00000000, 0x948ea8f100000000, 0x2c4aa55500000000, + 0xbfd16c2a00000000, 0x0a7d36aa00000000, 0x99e6ffd500000000, + 0x359e2e7900000000, 0xa605e70600000000, 0x13a9bd8600000000, + 0x803274f900000000, 0x38f6795d00000000, 0xab6db02200000000, + 0x1ec1eaa200000000, 0x8d5a23dd00000000, 0x2f4e803100000000, + 0xbcd5494e00000000, 0x097913ce00000000, 0x9ae2dab100000000, + 0x2226d71500000000, 0xb1bd1e6a00000000, 0x041144ea00000000, + 0x978a8d9500000000, 0x013e73e800000000, 0x92a5ba9700000000, + 0x2709e01700000000, 0xb492296800000000, 0x0c5624cc00000000, + 0x9fcdedb300000000, 0x2a61b73300000000, 0xb9fa7e4c00000000, + 0x1beedda000000000, 0x887514df00000000, 0x3dd94e5f00000000, + 0xae42872000000000, 0x16868a8400000000, 0x851d43fb00000000, + 0x30b1197b00000000, 0xa32ad00400000000, 0x1cd8e48000000000, + 0x8f432dff00000000, 0x3aef777f00000000, 0xa974be0000000000, + 0x11b0b3a400000000, 0x822b7adb00000000, 0x3787205b00000000, + 0xa41ce92400000000, 0x06084ac800000000, 0x959383b700000000, + 0x203fd93700000000, 0xb3a4104800000000, 0x0b601dec00000000, + 0x98fbd49300000000, 0x2d578e1300000000, 0xbecc476c00000000, + 0x2878b91100000000, 0xbbe3706e00000000, 0x0e4f2aee00000000, + 0x9dd4e39100000000, 0x2510ee3500000000, 0xb68b274a00000000, + 0x03277dca00000000, 0x90bcb4b500000000, 0x32a8175900000000, + 0xa133de2600000000, 0x149f84a600000000, 0x87044dd900000000, + 0x3fc0407d00000000, 0xac5b890200000000, 0x19f7d38200000000, + 0x8a6c1afd00000000}, + {0x0000000000000000, 0x650b796900000000, 0xca16f2d200000000, + 0xaf1d8bbb00000000, 0xd52b957e00000000, 0xb020ec1700000000, + 0x1f3d67ac00000000, 0x7a361ec500000000, 0xaa572afd00000000, + 0xcf5c539400000000, 0x6041d82f00000000, 0x054aa14600000000, + 0x7f7cbf8300000000, 0x1a77c6ea00000000, 0xb56a4d5100000000, + 0xd061343800000000, 0x15a9252100000000, 0x70a25c4800000000, + 0xdfbfd7f300000000, 0xbab4ae9a00000000, 0xc082b05f00000000, + 0xa589c93600000000, 0x0a94428d00000000, 0x6f9f3be400000000, + 0xbffe0fdc00000000, 0xdaf576b500000000, 0x75e8fd0e00000000, + 0x10e3846700000000, 0x6ad59aa200000000, 0x0fdee3cb00000000, + 0xa0c3687000000000, 0xc5c8111900000000, 0x2a524b4200000000, + 0x4f59322b00000000, 0xe044b99000000000, 0x854fc0f900000000, + 0xff79de3c00000000, 0x9a72a75500000000, 0x356f2cee00000000, + 0x5064558700000000, 0x800561bf00000000, 0xe50e18d600000000, + 0x4a13936d00000000, 0x2f18ea0400000000, 0x552ef4c100000000, + 0x30258da800000000, 0x9f38061300000000, 0xfa337f7a00000000, + 0x3ffb6e6300000000, 0x5af0170a00000000, 0xf5ed9cb100000000, + 0x90e6e5d800000000, 0xead0fb1d00000000, 0x8fdb827400000000, + 0x20c609cf00000000, 0x45cd70a600000000, 0x95ac449e00000000, + 0xf0a73df700000000, 0x5fbab64c00000000, 0x3ab1cf2500000000, + 0x4087d1e000000000, 0x258ca88900000000, 0x8a91233200000000, + 0xef9a5a5b00000000, 0x54a4968400000000, 0x31afefed00000000, + 0x9eb2645600000000, 0xfbb91d3f00000000, 0x818f03fa00000000, + 0xe4847a9300000000, 0x4b99f12800000000, 0x2e92884100000000, + 0xfef3bc7900000000, 0x9bf8c51000000000, 0x34e54eab00000000, + 0x51ee37c200000000, 0x2bd8290700000000, 0x4ed3506e00000000, + 0xe1cedbd500000000, 0x84c5a2bc00000000, 0x410db3a500000000, + 0x2406cacc00000000, 0x8b1b417700000000, 0xee10381e00000000, + 0x942626db00000000, 0xf12d5fb200000000, 0x5e30d40900000000, + 0x3b3bad6000000000, 0xeb5a995800000000, 0x8e51e03100000000, + 0x214c6b8a00000000, 0x444712e300000000, 0x3e710c2600000000, + 0x5b7a754f00000000, 0xf467fef400000000, 0x916c879d00000000, + 0x7ef6ddc600000000, 0x1bfda4af00000000, 0xb4e02f1400000000, + 0xd1eb567d00000000, 0xabdd48b800000000, 0xced631d100000000, + 0x61cbba6a00000000, 0x04c0c30300000000, 0xd4a1f73b00000000, + 0xb1aa8e5200000000, 0x1eb705e900000000, 0x7bbc7c8000000000, + 0x018a624500000000, 0x64811b2c00000000, 0xcb9c909700000000, + 0xae97e9fe00000000, 0x6b5ff8e700000000, 0x0e54818e00000000, + 0xa1490a3500000000, 0xc442735c00000000, 0xbe746d9900000000, + 0xdb7f14f000000000, 0x74629f4b00000000, 0x1169e62200000000, + 0xc108d21a00000000, 0xa403ab7300000000, 0x0b1e20c800000000, + 0x6e1559a100000000, 0x1423476400000000, 0x71283e0d00000000, + 0xde35b5b600000000, 0xbb3eccdf00000000, 0xe94e5cd200000000, + 0x8c4525bb00000000, 0x2358ae0000000000, 0x4653d76900000000, + 0x3c65c9ac00000000, 0x596eb0c500000000, 0xf6733b7e00000000, + 0x9378421700000000, 0x4319762f00000000, 0x26120f4600000000, + 0x890f84fd00000000, 0xec04fd9400000000, 0x9632e35100000000, + 0xf3399a3800000000, 0x5c24118300000000, 0x392f68ea00000000, + 0xfce779f300000000, 0x99ec009a00000000, 0x36f18b2100000000, + 0x53faf24800000000, 0x29ccec8d00000000, 0x4cc795e400000000, + 0xe3da1e5f00000000, 0x86d1673600000000, 0x56b0530e00000000, + 0x33bb2a6700000000, 0x9ca6a1dc00000000, 0xf9add8b500000000, + 0x839bc67000000000, 0xe690bf1900000000, 0x498d34a200000000, + 0x2c864dcb00000000, 0xc31c179000000000, 0xa6176ef900000000, + 0x090ae54200000000, 0x6c019c2b00000000, 0x163782ee00000000, + 0x733cfb8700000000, 0xdc21703c00000000, 0xb92a095500000000, + 0x694b3d6d00000000, 0x0c40440400000000, 0xa35dcfbf00000000, + 0xc656b6d600000000, 0xbc60a81300000000, 0xd96bd17a00000000, + 0x76765ac100000000, 0x137d23a800000000, 0xd6b532b100000000, + 0xb3be4bd800000000, 0x1ca3c06300000000, 0x79a8b90a00000000, + 0x039ea7cf00000000, 0x6695dea600000000, 0xc988551d00000000, + 0xac832c7400000000, 0x7ce2184c00000000, 0x19e9612500000000, + 0xb6f4ea9e00000000, 0xd3ff93f700000000, 0xa9c98d3200000000, + 0xccc2f45b00000000, 0x63df7fe000000000, 0x06d4068900000000, + 0xbdeaca5600000000, 0xd8e1b33f00000000, 0x77fc388400000000, + 0x12f741ed00000000, 0x68c15f2800000000, 0x0dca264100000000, + 0xa2d7adfa00000000, 0xc7dcd49300000000, 0x17bde0ab00000000, + 0x72b699c200000000, 0xddab127900000000, 0xb8a06b1000000000, + 0xc29675d500000000, 0xa79d0cbc00000000, 0x0880870700000000, + 0x6d8bfe6e00000000, 0xa843ef7700000000, 0xcd48961e00000000, + 0x62551da500000000, 0x075e64cc00000000, 0x7d687a0900000000, + 0x1863036000000000, 0xb77e88db00000000, 0xd275f1b200000000, + 0x0214c58a00000000, 0x671fbce300000000, 0xc802375800000000, + 0xad094e3100000000, 0xd73f50f400000000, 0xb234299d00000000, + 0x1d29a22600000000, 0x7822db4f00000000, 0x97b8811400000000, + 0xf2b3f87d00000000, 0x5dae73c600000000, 0x38a50aaf00000000, + 0x4293146a00000000, 0x27986d0300000000, 0x8885e6b800000000, + 0xed8e9fd100000000, 0x3defabe900000000, 0x58e4d28000000000, + 0xf7f9593b00000000, 0x92f2205200000000, 0xe8c43e9700000000, + 0x8dcf47fe00000000, 0x22d2cc4500000000, 0x47d9b52c00000000, + 0x8211a43500000000, 0xe71add5c00000000, 0x480756e700000000, + 0x2d0c2f8e00000000, 0x573a314b00000000, 0x3231482200000000, + 0x9d2cc39900000000, 0xf827baf000000000, 0x28468ec800000000, + 0x4d4df7a100000000, 0xe2507c1a00000000, 0x875b057300000000, + 0xfd6d1bb600000000, 0x986662df00000000, 0x377be96400000000, + 0x5270900d00000000}, + {0x0000000000000000, 0xdcecb13d00000000, 0xb8d9637b00000000, + 0x6435d24600000000, 0x70b3c7f600000000, 0xac5f76cb00000000, + 0xc86aa48d00000000, 0x148615b000000000, 0xa160fe3600000000, + 0x7d8c4f0b00000000, 0x19b99d4d00000000, 0xc5552c7000000000, + 0xd1d339c000000000, 0x0d3f88fd00000000, 0x690a5abb00000000, + 0xb5e6eb8600000000, 0x42c1fc6d00000000, 0x9e2d4d5000000000, + 0xfa189f1600000000, 0x26f42e2b00000000, 0x32723b9b00000000, + 0xee9e8aa600000000, 0x8aab58e000000000, 0x5647e9dd00000000, + 0xe3a1025b00000000, 0x3f4db36600000000, 0x5b78612000000000, + 0x8794d01d00000000, 0x9312c5ad00000000, 0x4ffe749000000000, + 0x2bcba6d600000000, 0xf72717eb00000000, 0x8482f9db00000000, + 0x586e48e600000000, 0x3c5b9aa000000000, 0xe0b72b9d00000000, + 0xf4313e2d00000000, 0x28dd8f1000000000, 0x4ce85d5600000000, + 0x9004ec6b00000000, 0x25e207ed00000000, 0xf90eb6d000000000, + 0x9d3b649600000000, 0x41d7d5ab00000000, 0x5551c01b00000000, + 0x89bd712600000000, 0xed88a36000000000, 0x3164125d00000000, + 0xc64305b600000000, 0x1aafb48b00000000, 0x7e9a66cd00000000, + 0xa276d7f000000000, 0xb6f0c24000000000, 0x6a1c737d00000000, + 0x0e29a13b00000000, 0xd2c5100600000000, 0x6723fb8000000000, + 0xbbcf4abd00000000, 0xdffa98fb00000000, 0x031629c600000000, + 0x17903c7600000000, 0xcb7c8d4b00000000, 0xaf495f0d00000000, + 0x73a5ee3000000000, 0x4903826c00000000, 0x95ef335100000000, + 0xf1dae11700000000, 0x2d36502a00000000, 0x39b0459a00000000, + 0xe55cf4a700000000, 0x816926e100000000, 0x5d8597dc00000000, + 0xe8637c5a00000000, 0x348fcd6700000000, 0x50ba1f2100000000, + 0x8c56ae1c00000000, 0x98d0bbac00000000, 0x443c0a9100000000, + 0x2009d8d700000000, 0xfce569ea00000000, 0x0bc27e0100000000, + 0xd72ecf3c00000000, 0xb31b1d7a00000000, 0x6ff7ac4700000000, + 0x7b71b9f700000000, 0xa79d08ca00000000, 0xc3a8da8c00000000, + 0x1f446bb100000000, 0xaaa2803700000000, 0x764e310a00000000, + 0x127be34c00000000, 0xce97527100000000, 0xda1147c100000000, + 0x06fdf6fc00000000, 0x62c824ba00000000, 0xbe24958700000000, + 0xcd817bb700000000, 0x116dca8a00000000, 0x755818cc00000000, + 0xa9b4a9f100000000, 0xbd32bc4100000000, 0x61de0d7c00000000, + 0x05ebdf3a00000000, 0xd9076e0700000000, 0x6ce1858100000000, + 0xb00d34bc00000000, 0xd438e6fa00000000, 0x08d457c700000000, + 0x1c52427700000000, 0xc0bef34a00000000, 0xa48b210c00000000, + 0x7867903100000000, 0x8f4087da00000000, 0x53ac36e700000000, + 0x3799e4a100000000, 0xeb75559c00000000, 0xfff3402c00000000, + 0x231ff11100000000, 0x472a235700000000, 0x9bc6926a00000000, + 0x2e2079ec00000000, 0xf2ccc8d100000000, 0x96f91a9700000000, + 0x4a15abaa00000000, 0x5e93be1a00000000, 0x827f0f2700000000, + 0xe64add6100000000, 0x3aa66c5c00000000, 0x920604d900000000, + 0x4eeab5e400000000, 0x2adf67a200000000, 0xf633d69f00000000, + 0xe2b5c32f00000000, 0x3e59721200000000, 0x5a6ca05400000000, + 0x8680116900000000, 0x3366faef00000000, 0xef8a4bd200000000, + 0x8bbf999400000000, 0x575328a900000000, 0x43d53d1900000000, + 0x9f398c2400000000, 0xfb0c5e6200000000, 0x27e0ef5f00000000, + 0xd0c7f8b400000000, 0x0c2b498900000000, 0x681e9bcf00000000, + 0xb4f22af200000000, 0xa0743f4200000000, 0x7c988e7f00000000, + 0x18ad5c3900000000, 0xc441ed0400000000, 0x71a7068200000000, + 0xad4bb7bf00000000, 0xc97e65f900000000, 0x1592d4c400000000, + 0x0114c17400000000, 0xddf8704900000000, 0xb9cda20f00000000, + 0x6521133200000000, 0x1684fd0200000000, 0xca684c3f00000000, + 0xae5d9e7900000000, 0x72b12f4400000000, 0x66373af400000000, + 0xbadb8bc900000000, 0xdeee598f00000000, 0x0202e8b200000000, + 0xb7e4033400000000, 0x6b08b20900000000, 0x0f3d604f00000000, + 0xd3d1d17200000000, 0xc757c4c200000000, 0x1bbb75ff00000000, + 0x7f8ea7b900000000, 0xa362168400000000, 0x5445016f00000000, + 0x88a9b05200000000, 0xec9c621400000000, 0x3070d32900000000, + 0x24f6c69900000000, 0xf81a77a400000000, 0x9c2fa5e200000000, + 0x40c314df00000000, 0xf525ff5900000000, 0x29c94e6400000000, + 0x4dfc9c2200000000, 0x91102d1f00000000, 0x859638af00000000, + 0x597a899200000000, 0x3d4f5bd400000000, 0xe1a3eae900000000, + 0xdb0586b500000000, 0x07e9378800000000, 0x63dce5ce00000000, + 0xbf3054f300000000, 0xabb6414300000000, 0x775af07e00000000, + 0x136f223800000000, 0xcf83930500000000, 0x7a65788300000000, + 0xa689c9be00000000, 0xc2bc1bf800000000, 0x1e50aac500000000, + 0x0ad6bf7500000000, 0xd63a0e4800000000, 0xb20fdc0e00000000, + 0x6ee36d3300000000, 0x99c47ad800000000, 0x4528cbe500000000, + 0x211d19a300000000, 0xfdf1a89e00000000, 0xe977bd2e00000000, + 0x359b0c1300000000, 0x51aede5500000000, 0x8d426f6800000000, + 0x38a484ee00000000, 0xe44835d300000000, 0x807de79500000000, + 0x5c9156a800000000, 0x4817431800000000, 0x94fbf22500000000, + 0xf0ce206300000000, 0x2c22915e00000000, 0x5f877f6e00000000, + 0x836bce5300000000, 0xe75e1c1500000000, 0x3bb2ad2800000000, + 0x2f34b89800000000, 0xf3d809a500000000, 0x97eddbe300000000, + 0x4b016ade00000000, 0xfee7815800000000, 0x220b306500000000, + 0x463ee22300000000, 0x9ad2531e00000000, 0x8e5446ae00000000, + 0x52b8f79300000000, 0x368d25d500000000, 0xea6194e800000000, + 0x1d46830300000000, 0xc1aa323e00000000, 0xa59fe07800000000, + 0x7973514500000000, 0x6df544f500000000, 0xb119f5c800000000, + 0xd52c278e00000000, 0x09c096b300000000, 0xbc267d3500000000, + 0x60cacc0800000000, 0x04ff1e4e00000000, 0xd813af7300000000, + 0xcc95bac300000000, 0x10790bfe00000000, 0x744cd9b800000000, + 0xa8a0688500000000}}; + +#else /* W == 4 */ + +local const z_crc_t FAR crc_braid_table[][256] = { + {0x00000000, 0x81256527, 0xd93bcc0f, 0x581ea928, 0x69069e5f, + 0xe823fb78, 0xb03d5250, 0x31183777, 0xd20d3cbe, 0x53285999, + 0x0b36f0b1, 0x8a139596, 0xbb0ba2e1, 0x3a2ec7c6, 0x62306eee, + 0xe3150bc9, 0x7f6b7f3d, 0xfe4e1a1a, 0xa650b332, 0x2775d615, + 0x166de162, 0x97488445, 0xcf562d6d, 0x4e73484a, 0xad664383, + 0x2c4326a4, 0x745d8f8c, 0xf578eaab, 0xc460dddc, 0x4545b8fb, + 0x1d5b11d3, 0x9c7e74f4, 0xfed6fe7a, 0x7ff39b5d, 0x27ed3275, + 0xa6c85752, 0x97d06025, 0x16f50502, 0x4eebac2a, 0xcfcec90d, + 0x2cdbc2c4, 0xadfea7e3, 0xf5e00ecb, 0x74c56bec, 0x45dd5c9b, + 0xc4f839bc, 0x9ce69094, 0x1dc3f5b3, 0x81bd8147, 0x0098e460, + 0x58864d48, 0xd9a3286f, 0xe8bb1f18, 0x699e7a3f, 0x3180d317, + 0xb0a5b630, 0x53b0bdf9, 0xd295d8de, 0x8a8b71f6, 0x0bae14d1, + 0x3ab623a6, 0xbb934681, 0xe38defa9, 0x62a88a8e, 0x26dcfab5, + 0xa7f99f92, 0xffe736ba, 0x7ec2539d, 0x4fda64ea, 0xceff01cd, + 0x96e1a8e5, 0x17c4cdc2, 0xf4d1c60b, 0x75f4a32c, 0x2dea0a04, + 0xaccf6f23, 0x9dd75854, 0x1cf23d73, 0x44ec945b, 0xc5c9f17c, + 0x59b78588, 0xd892e0af, 0x808c4987, 0x01a92ca0, 0x30b11bd7, + 0xb1947ef0, 0xe98ad7d8, 0x68afb2ff, 0x8bbab936, 0x0a9fdc11, + 0x52817539, 0xd3a4101e, 0xe2bc2769, 0x6399424e, 0x3b87eb66, + 0xbaa28e41, 0xd80a04cf, 0x592f61e8, 0x0131c8c0, 0x8014ade7, + 0xb10c9a90, 0x3029ffb7, 0x6837569f, 0xe91233b8, 0x0a073871, + 0x8b225d56, 0xd33cf47e, 0x52199159, 0x6301a62e, 0xe224c309, + 0xba3a6a21, 0x3b1f0f06, 0xa7617bf2, 0x26441ed5, 0x7e5ab7fd, + 0xff7fd2da, 0xce67e5ad, 0x4f42808a, 0x175c29a2, 0x96794c85, + 0x756c474c, 0xf449226b, 0xac578b43, 0x2d72ee64, 0x1c6ad913, + 0x9d4fbc34, 0xc551151c, 0x4474703b, 0x4db9f56a, 0xcc9c904d, + 0x94823965, 0x15a75c42, 0x24bf6b35, 0xa59a0e12, 0xfd84a73a, + 0x7ca1c21d, 0x9fb4c9d4, 0x1e91acf3, 0x468f05db, 0xc7aa60fc, + 0xf6b2578b, 0x779732ac, 0x2f899b84, 0xaeacfea3, 0x32d28a57, + 0xb3f7ef70, 0xebe94658, 0x6acc237f, 0x5bd41408, 0xdaf1712f, + 0x82efd807, 0x03cabd20, 0xe0dfb6e9, 0x61fad3ce, 0x39e47ae6, + 0xb8c11fc1, 0x89d928b6, 0x08fc4d91, 0x50e2e4b9, 0xd1c7819e, + 0xb36f0b10, 0x324a6e37, 0x6a54c71f, 0xeb71a238, 0xda69954f, + 0x5b4cf068, 0x03525940, 0x82773c67, 0x616237ae, 0xe0475289, + 0xb859fba1, 0x397c9e86, 0x0864a9f1, 0x8941ccd6, 0xd15f65fe, + 0x507a00d9, 0xcc04742d, 0x4d21110a, 0x153fb822, 0x941add05, + 0xa502ea72, 0x24278f55, 0x7c39267d, 0xfd1c435a, 0x1e094893, + 0x9f2c2db4, 0xc732849c, 0x4617e1bb, 0x770fd6cc, 0xf62ab3eb, + 0xae341ac3, 0x2f117fe4, 0x6b650fdf, 0xea406af8, 0xb25ec3d0, + 0x337ba6f7, 0x02639180, 0x8346f4a7, 0xdb585d8f, 0x5a7d38a8, + 0xb9683361, 0x384d5646, 0x6053ff6e, 0xe1769a49, 0xd06ead3e, + 0x514bc819, 0x09556131, 0x88700416, 0x140e70e2, 0x952b15c5, + 0xcd35bced, 0x4c10d9ca, 0x7d08eebd, 0xfc2d8b9a, 0xa43322b2, + 0x25164795, 0xc6034c5c, 0x4726297b, 0x1f388053, 0x9e1de574, + 0xaf05d203, 0x2e20b724, 0x763e1e0c, 0xf71b7b2b, 0x95b3f1a5, + 0x14969482, 0x4c883daa, 0xcdad588d, 0xfcb56ffa, 0x7d900add, + 0x258ea3f5, 0xa4abc6d2, 0x47becd1b, 0xc69ba83c, 0x9e850114, + 0x1fa06433, 0x2eb85344, 0xaf9d3663, 0xf7839f4b, 0x76a6fa6c, + 0xead88e98, 0x6bfdebbf, 0x33e34297, 0xb2c627b0, 0x83de10c7, + 0x02fb75e0, 0x5ae5dcc8, 0xdbc0b9ef, 0x38d5b226, 0xb9f0d701, + 0xe1ee7e29, 0x60cb1b0e, 0x51d32c79, 0xd0f6495e, 0x88e8e076, + 0x09cd8551}, + {0x00000000, 0x9b73ead4, 0xed96d3e9, 0x76e5393d, 0x005ca193, + 0x9b2f4b47, 0xedca727a, 0x76b998ae, 0x00b94326, 0x9bcaa9f2, + 0xed2f90cf, 0x765c7a1b, 0x00e5e2b5, 0x9b960861, 0xed73315c, + 0x7600db88, 0x0172864c, 0x9a016c98, 0xece455a5, 0x7797bf71, + 0x012e27df, 0x9a5dcd0b, 0xecb8f436, 0x77cb1ee2, 0x01cbc56a, + 0x9ab82fbe, 0xec5d1683, 0x772efc57, 0x019764f9, 0x9ae48e2d, + 0xec01b710, 0x77725dc4, 0x02e50c98, 0x9996e64c, 0xef73df71, + 0x740035a5, 0x02b9ad0b, 0x99ca47df, 0xef2f7ee2, 0x745c9436, + 0x025c4fbe, 0x992fa56a, 0xefca9c57, 0x74b97683, 0x0200ee2d, + 0x997304f9, 0xef963dc4, 0x74e5d710, 0x03978ad4, 0x98e46000, + 0xee01593d, 0x7572b3e9, 0x03cb2b47, 0x98b8c193, 0xee5df8ae, + 0x752e127a, 0x032ec9f2, 0x985d2326, 0xeeb81a1b, 0x75cbf0cf, + 0x03726861, 0x980182b5, 0xeee4bb88, 0x7597515c, 0x05ca1930, + 0x9eb9f3e4, 0xe85ccad9, 0x732f200d, 0x0596b8a3, 0x9ee55277, + 0xe8006b4a, 0x7373819e, 0x05735a16, 0x9e00b0c2, 0xe8e589ff, + 0x7396632b, 0x052ffb85, 0x9e5c1151, 0xe8b9286c, 0x73cac2b8, + 0x04b89f7c, 0x9fcb75a8, 0xe92e4c95, 0x725da641, 0x04e43eef, + 0x9f97d43b, 0xe972ed06, 0x720107d2, 0x0401dc5a, 0x9f72368e, + 0xe9970fb3, 0x72e4e567, 0x045d7dc9, 0x9f2e971d, 0xe9cbae20, + 0x72b844f4, 0x072f15a8, 0x9c5cff7c, 0xeab9c641, 0x71ca2c95, + 0x0773b43b, 0x9c005eef, 0xeae567d2, 0x71968d06, 0x0796568e, + 0x9ce5bc5a, 0xea008567, 0x71736fb3, 0x07caf71d, 0x9cb91dc9, + 0xea5c24f4, 0x712fce20, 0x065d93e4, 0x9d2e7930, 0xebcb400d, + 0x70b8aad9, 0x06013277, 0x9d72d8a3, 0xeb97e19e, 0x70e40b4a, + 0x06e4d0c2, 0x9d973a16, 0xeb72032b, 0x7001e9ff, 0x06b87151, + 0x9dcb9b85, 0xeb2ea2b8, 0x705d486c, 0x0b943260, 0x90e7d8b4, + 0xe602e189, 0x7d710b5d, 0x0bc893f3, 0x90bb7927, 0xe65e401a, + 0x7d2daace, 0x0b2d7146, 0x905e9b92, 0xe6bba2af, 0x7dc8487b, + 0x0b71d0d5, 0x90023a01, 0xe6e7033c, 0x7d94e9e8, 0x0ae6b42c, + 0x91955ef8, 0xe77067c5, 0x7c038d11, 0x0aba15bf, 0x91c9ff6b, + 0xe72cc656, 0x7c5f2c82, 0x0a5ff70a, 0x912c1dde, 0xe7c924e3, + 0x7cbace37, 0x0a035699, 0x9170bc4d, 0xe7958570, 0x7ce66fa4, + 0x09713ef8, 0x9202d42c, 0xe4e7ed11, 0x7f9407c5, 0x092d9f6b, + 0x925e75bf, 0xe4bb4c82, 0x7fc8a656, 0x09c87dde, 0x92bb970a, + 0xe45eae37, 0x7f2d44e3, 0x0994dc4d, 0x92e73699, 0xe4020fa4, + 0x7f71e570, 0x0803b8b4, 0x93705260, 0xe5956b5d, 0x7ee68189, + 0x085f1927, 0x932cf3f3, 0xe5c9cace, 0x7eba201a, 0x08bafb92, + 0x93c91146, 0xe52c287b, 0x7e5fc2af, 0x08e65a01, 0x9395b0d5, + 0xe57089e8, 0x7e03633c, 0x0e5e2b50, 0x952dc184, 0xe3c8f8b9, + 0x78bb126d, 0x0e028ac3, 0x95716017, 0xe394592a, 0x78e7b3fe, + 0x0ee76876, 0x959482a2, 0xe371bb9f, 0x7802514b, 0x0ebbc9e5, + 0x95c82331, 0xe32d1a0c, 0x785ef0d8, 0x0f2cad1c, 0x945f47c8, + 0xe2ba7ef5, 0x79c99421, 0x0f700c8f, 0x9403e65b, 0xe2e6df66, + 0x799535b2, 0x0f95ee3a, 0x94e604ee, 0xe2033dd3, 0x7970d707, + 0x0fc94fa9, 0x94baa57d, 0xe25f9c40, 0x792c7694, 0x0cbb27c8, + 0x97c8cd1c, 0xe12df421, 0x7a5e1ef5, 0x0ce7865b, 0x97946c8f, + 0xe17155b2, 0x7a02bf66, 0x0c0264ee, 0x97718e3a, 0xe194b707, + 0x7ae75dd3, 0x0c5ec57d, 0x972d2fa9, 0xe1c81694, 0x7abbfc40, + 0x0dc9a184, 0x96ba4b50, 0xe05f726d, 0x7b2c98b9, 0x0d950017, + 0x96e6eac3, 0xe003d3fe, 0x7b70392a, 0x0d70e2a2, 0x96030876, + 0xe0e6314b, 0x7b95db9f, 0x0d2c4331, 0x965fa9e5, 0xe0ba90d8, + 0x7bc97a0c}, + {0x00000000, 0x172864c0, 0x2e50c980, 0x3978ad40, 0x5ca19300, + 0x4b89f7c0, 0x72f15a80, 0x65d93e40, 0xb9432600, 0xae6b42c0, + 0x9713ef80, 0x803b8b40, 0xe5e2b500, 0xf2cad1c0, 0xcbb27c80, + 0xdc9a1840, 0xa9f74a41, 0xbedf2e81, 0x87a783c1, 0x908fe701, + 0xf556d941, 0xe27ebd81, 0xdb0610c1, 0xcc2e7401, 0x10b46c41, + 0x079c0881, 0x3ee4a5c1, 0x29ccc101, 0x4c15ff41, 0x5b3d9b81, + 0x624536c1, 0x756d5201, 0x889f92c3, 0x9fb7f603, 0xa6cf5b43, + 0xb1e73f83, 0xd43e01c3, 0xc3166503, 0xfa6ec843, 0xed46ac83, + 0x31dcb4c3, 0x26f4d003, 0x1f8c7d43, 0x08a41983, 0x6d7d27c3, + 0x7a554303, 0x432dee43, 0x54058a83, 0x2168d882, 0x3640bc42, + 0x0f381102, 0x181075c2, 0x7dc94b82, 0x6ae12f42, 0x53998202, + 0x44b1e6c2, 0x982bfe82, 0x8f039a42, 0xb67b3702, 0xa15353c2, + 0xc48a6d82, 0xd3a20942, 0xeadaa402, 0xfdf2c0c2, 0xca4e23c7, + 0xdd664707, 0xe41eea47, 0xf3368e87, 0x96efb0c7, 0x81c7d407, + 0xb8bf7947, 0xaf971d87, 0x730d05c7, 0x64256107, 0x5d5dcc47, + 0x4a75a887, 0x2fac96c7, 0x3884f207, 0x01fc5f47, 0x16d43b87, + 0x63b96986, 0x74910d46, 0x4de9a006, 0x5ac1c4c6, 0x3f18fa86, + 0x28309e46, 0x11483306, 0x066057c6, 0xdafa4f86, 0xcdd22b46, + 0xf4aa8606, 0xe382e2c6, 0x865bdc86, 0x9173b846, 0xa80b1506, + 0xbf2371c6, 0x42d1b104, 0x55f9d5c4, 0x6c817884, 0x7ba91c44, + 0x1e702204, 0x095846c4, 0x3020eb84, 0x27088f44, 0xfb929704, + 0xecbaf3c4, 0xd5c25e84, 0xc2ea3a44, 0xa7330404, 0xb01b60c4, + 0x8963cd84, 0x9e4ba944, 0xeb26fb45, 0xfc0e9f85, 0xc57632c5, + 0xd25e5605, 0xb7876845, 0xa0af0c85, 0x99d7a1c5, 0x8effc505, + 0x5265dd45, 0x454db985, 0x7c3514c5, 0x6b1d7005, 0x0ec44e45, + 0x19ec2a85, 0x209487c5, 0x37bce305, 0x4fed41cf, 0x58c5250f, + 0x61bd884f, 0x7695ec8f, 0x134cd2cf, 0x0464b60f, 0x3d1c1b4f, + 0x2a347f8f, 0xf6ae67cf, 0xe186030f, 0xd8feae4f, 0xcfd6ca8f, + 0xaa0ff4cf, 0xbd27900f, 0x845f3d4f, 0x9377598f, 0xe61a0b8e, + 0xf1326f4e, 0xc84ac20e, 0xdf62a6ce, 0xbabb988e, 0xad93fc4e, + 0x94eb510e, 0x83c335ce, 0x5f592d8e, 0x4871494e, 0x7109e40e, + 0x662180ce, 0x03f8be8e, 0x14d0da4e, 0x2da8770e, 0x3a8013ce, + 0xc772d30c, 0xd05ab7cc, 0xe9221a8c, 0xfe0a7e4c, 0x9bd3400c, + 0x8cfb24cc, 0xb583898c, 0xa2abed4c, 0x7e31f50c, 0x691991cc, + 0x50613c8c, 0x4749584c, 0x2290660c, 0x35b802cc, 0x0cc0af8c, + 0x1be8cb4c, 0x6e85994d, 0x79adfd8d, 0x40d550cd, 0x57fd340d, + 0x32240a4d, 0x250c6e8d, 0x1c74c3cd, 0x0b5ca70d, 0xd7c6bf4d, + 0xc0eedb8d, 0xf99676cd, 0xeebe120d, 0x8b672c4d, 0x9c4f488d, + 0xa537e5cd, 0xb21f810d, 0x85a36208, 0x928b06c8, 0xabf3ab88, + 0xbcdbcf48, 0xd902f108, 0xce2a95c8, 0xf7523888, 0xe07a5c48, + 0x3ce04408, 0x2bc820c8, 0x12b08d88, 0x0598e948, 0x6041d708, + 0x7769b3c8, 0x4e111e88, 0x59397a48, 0x2c542849, 0x3b7c4c89, + 0x0204e1c9, 0x152c8509, 0x70f5bb49, 0x67dddf89, 0x5ea572c9, + 0x498d1609, 0x95170e49, 0x823f6a89, 0xbb47c7c9, 0xac6fa309, + 0xc9b69d49, 0xde9ef989, 0xe7e654c9, 0xf0ce3009, 0x0d3cf0cb, + 0x1a14940b, 0x236c394b, 0x34445d8b, 0x519d63cb, 0x46b5070b, + 0x7fcdaa4b, 0x68e5ce8b, 0xb47fd6cb, 0xa357b20b, 0x9a2f1f4b, + 0x8d077b8b, 0xe8de45cb, 0xfff6210b, 0xc68e8c4b, 0xd1a6e88b, + 0xa4cbba8a, 0xb3e3de4a, 0x8a9b730a, 0x9db317ca, 0xf86a298a, + 0xef424d4a, 0xd63ae00a, 0xc11284ca, 0x1d889c8a, 0x0aa0f84a, + 0x33d8550a, 0x24f031ca, 0x41290f8a, 0x56016b4a, 0x6f79c60a, + 0x7851a2ca}, + {0x00000000, 0x9fda839e, 0xe4c4017d, 0x7b1e82e3, 0x12f904bb, + 0x8d238725, 0xf63d05c6, 0x69e78658, 0x25f20976, 0xba288ae8, + 0xc136080b, 0x5eec8b95, 0x370b0dcd, 0xa8d18e53, 0xd3cf0cb0, + 0x4c158f2e, 0x4be412ec, 0xd43e9172, 0xaf201391, 0x30fa900f, + 0x591d1657, 0xc6c795c9, 0xbdd9172a, 0x220394b4, 0x6e161b9a, + 0xf1cc9804, 0x8ad21ae7, 0x15089979, 0x7cef1f21, 0xe3359cbf, + 0x982b1e5c, 0x07f19dc2, 0x97c825d8, 0x0812a646, 0x730c24a5, + 0xecd6a73b, 0x85312163, 0x1aeba2fd, 0x61f5201e, 0xfe2fa380, + 0xb23a2cae, 0x2de0af30, 0x56fe2dd3, 0xc924ae4d, 0xa0c32815, + 0x3f19ab8b, 0x44072968, 0xdbddaaf6, 0xdc2c3734, 0x43f6b4aa, + 0x38e83649, 0xa732b5d7, 0xced5338f, 0x510fb011, 0x2a1132f2, + 0xb5cbb16c, 0xf9de3e42, 0x6604bddc, 0x1d1a3f3f, 0x82c0bca1, + 0xeb273af9, 0x74fdb967, 0x0fe33b84, 0x9039b81a, 0xf4e14df1, + 0x6b3bce6f, 0x10254c8c, 0x8fffcf12, 0xe618494a, 0x79c2cad4, + 0x02dc4837, 0x9d06cba9, 0xd1134487, 0x4ec9c719, 0x35d745fa, + 0xaa0dc664, 0xc3ea403c, 0x5c30c3a2, 0x272e4141, 0xb8f4c2df, + 0xbf055f1d, 0x20dfdc83, 0x5bc15e60, 0xc41bddfe, 0xadfc5ba6, + 0x3226d838, 0x49385adb, 0xd6e2d945, 0x9af7566b, 0x052dd5f5, + 0x7e335716, 0xe1e9d488, 0x880e52d0, 0x17d4d14e, 0x6cca53ad, + 0xf310d033, 0x63296829, 0xfcf3ebb7, 0x87ed6954, 0x1837eaca, + 0x71d06c92, 0xee0aef0c, 0x95146def, 0x0aceee71, 0x46db615f, + 0xd901e2c1, 0xa21f6022, 0x3dc5e3bc, 0x542265e4, 0xcbf8e67a, + 0xb0e66499, 0x2f3ce707, 0x28cd7ac5, 0xb717f95b, 0xcc097bb8, + 0x53d3f826, 0x3a347e7e, 0xa5eefde0, 0xdef07f03, 0x412afc9d, + 0x0d3f73b3, 0x92e5f02d, 0xe9fb72ce, 0x7621f150, 0x1fc67708, + 0x801cf496, 0xfb027675, 0x64d8f5eb, 0x32b39da3, 0xad691e3d, + 0xd6779cde, 0x49ad1f40, 0x204a9918, 0xbf901a86, 0xc48e9865, + 0x5b541bfb, 0x174194d5, 0x889b174b, 0xf38595a8, 0x6c5f1636, + 0x05b8906e, 0x9a6213f0, 0xe17c9113, 0x7ea6128d, 0x79578f4f, + 0xe68d0cd1, 0x9d938e32, 0x02490dac, 0x6bae8bf4, 0xf474086a, + 0x8f6a8a89, 0x10b00917, 0x5ca58639, 0xc37f05a7, 0xb8618744, + 0x27bb04da, 0x4e5c8282, 0xd186011c, 0xaa9883ff, 0x35420061, + 0xa57bb87b, 0x3aa13be5, 0x41bfb906, 0xde653a98, 0xb782bcc0, + 0x28583f5e, 0x5346bdbd, 0xcc9c3e23, 0x8089b10d, 0x1f533293, + 0x644db070, 0xfb9733ee, 0x9270b5b6, 0x0daa3628, 0x76b4b4cb, + 0xe96e3755, 0xee9faa97, 0x71452909, 0x0a5babea, 0x95812874, + 0xfc66ae2c, 0x63bc2db2, 0x18a2af51, 0x87782ccf, 0xcb6da3e1, + 0x54b7207f, 0x2fa9a29c, 0xb0732102, 0xd994a75a, 0x464e24c4, + 0x3d50a627, 0xa28a25b9, 0xc652d052, 0x598853cc, 0x2296d12f, + 0xbd4c52b1, 0xd4abd4e9, 0x4b715777, 0x306fd594, 0xafb5560a, + 0xe3a0d924, 0x7c7a5aba, 0x0764d859, 0x98be5bc7, 0xf159dd9f, + 0x6e835e01, 0x159ddce2, 0x8a475f7c, 0x8db6c2be, 0x126c4120, + 0x6972c3c3, 0xf6a8405d, 0x9f4fc605, 0x0095459b, 0x7b8bc778, + 0xe45144e6, 0xa844cbc8, 0x379e4856, 0x4c80cab5, 0xd35a492b, + 0xbabdcf73, 0x25674ced, 0x5e79ce0e, 0xc1a34d90, 0x519af58a, + 0xce407614, 0xb55ef4f7, 0x2a847769, 0x4363f131, 0xdcb972af, + 0xa7a7f04c, 0x387d73d2, 0x7468fcfc, 0xebb27f62, 0x90acfd81, + 0x0f767e1f, 0x6691f847, 0xf94b7bd9, 0x8255f93a, 0x1d8f7aa4, + 0x1a7ee766, 0x85a464f8, 0xfebae61b, 0x61606585, 0x0887e3dd, + 0x975d6043, 0xec43e2a0, 0x7399613e, 0x3f8cee10, 0xa0566d8e, + 0xdb48ef6d, 0x44926cf3, 0x2d75eaab, 0xb2af6935, 0xc9b1ebd6, + 0x566b6848}}; + +local const z_word_t FAR crc_braid_big_table[][256] = { + {0x00000000, 0x9e83da9f, 0x7d01c4e4, 0xe3821e7b, 0xbb04f912, + 0x2587238d, 0xc6053df6, 0x5886e769, 0x7609f225, 0xe88a28ba, + 0x0b0836c1, 0x958bec5e, 0xcd0d0b37, 0x538ed1a8, 0xb00ccfd3, + 0x2e8f154c, 0xec12e44b, 0x72913ed4, 0x911320af, 0x0f90fa30, + 0x57161d59, 0xc995c7c6, 0x2a17d9bd, 0xb4940322, 0x9a1b166e, + 0x0498ccf1, 0xe71ad28a, 0x79990815, 0x211fef7c, 0xbf9c35e3, + 0x5c1e2b98, 0xc29df107, 0xd825c897, 0x46a61208, 0xa5240c73, + 0x3ba7d6ec, 0x63213185, 0xfda2eb1a, 0x1e20f561, 0x80a32ffe, + 0xae2c3ab2, 0x30afe02d, 0xd32dfe56, 0x4dae24c9, 0x1528c3a0, + 0x8bab193f, 0x68290744, 0xf6aadddb, 0x34372cdc, 0xaab4f643, + 0x4936e838, 0xd7b532a7, 0x8f33d5ce, 0x11b00f51, 0xf232112a, + 0x6cb1cbb5, 0x423edef9, 0xdcbd0466, 0x3f3f1a1d, 0xa1bcc082, + 0xf93a27eb, 0x67b9fd74, 0x843be30f, 0x1ab83990, 0xf14de1f4, + 0x6fce3b6b, 0x8c4c2510, 0x12cfff8f, 0x4a4918e6, 0xd4cac279, + 0x3748dc02, 0xa9cb069d, 0x874413d1, 0x19c7c94e, 0xfa45d735, + 0x64c60daa, 0x3c40eac3, 0xa2c3305c, 0x41412e27, 0xdfc2f4b8, + 0x1d5f05bf, 0x83dcdf20, 0x605ec15b, 0xfedd1bc4, 0xa65bfcad, + 0x38d82632, 0xdb5a3849, 0x45d9e2d6, 0x6b56f79a, 0xf5d52d05, + 0x1657337e, 0x88d4e9e1, 0xd0520e88, 0x4ed1d417, 0xad53ca6c, + 0x33d010f3, 0x29682963, 0xb7ebf3fc, 0x5469ed87, 0xcaea3718, + 0x926cd071, 0x0cef0aee, 0xef6d1495, 0x71eece0a, 0x5f61db46, + 0xc1e201d9, 0x22601fa2, 0xbce3c53d, 0xe4652254, 0x7ae6f8cb, + 0x9964e6b0, 0x07e73c2f, 0xc57acd28, 0x5bf917b7, 0xb87b09cc, + 0x26f8d353, 0x7e7e343a, 0xe0fdeea5, 0x037ff0de, 0x9dfc2a41, + 0xb3733f0d, 0x2df0e592, 0xce72fbe9, 0x50f12176, 0x0877c61f, + 0x96f41c80, 0x757602fb, 0xebf5d864, 0xa39db332, 0x3d1e69ad, + 0xde9c77d6, 0x401fad49, 0x18994a20, 0x861a90bf, 0x65988ec4, + 0xfb1b545b, 0xd5944117, 0x4b179b88, 0xa89585f3, 0x36165f6c, + 0x6e90b805, 0xf013629a, 0x13917ce1, 0x8d12a67e, 0x4f8f5779, + 0xd10c8de6, 0x328e939d, 0xac0d4902, 0xf48bae6b, 0x6a0874f4, + 0x898a6a8f, 0x1709b010, 0x3986a55c, 0xa7057fc3, 0x448761b8, + 0xda04bb27, 0x82825c4e, 0x1c0186d1, 0xff8398aa, 0x61004235, + 0x7bb87ba5, 0xe53ba13a, 0x06b9bf41, 0x983a65de, 0xc0bc82b7, + 0x5e3f5828, 0xbdbd4653, 0x233e9ccc, 0x0db18980, 0x9332531f, + 0x70b04d64, 0xee3397fb, 0xb6b57092, 0x2836aa0d, 0xcbb4b476, + 0x55376ee9, 0x97aa9fee, 0x09294571, 0xeaab5b0a, 0x74288195, + 0x2cae66fc, 0xb22dbc63, 0x51afa218, 0xcf2c7887, 0xe1a36dcb, + 0x7f20b754, 0x9ca2a92f, 0x022173b0, 0x5aa794d9, 0xc4244e46, + 0x27a6503d, 0xb9258aa2, 0x52d052c6, 0xcc538859, 0x2fd19622, + 0xb1524cbd, 0xe9d4abd4, 0x7757714b, 0x94d56f30, 0x0a56b5af, + 0x24d9a0e3, 0xba5a7a7c, 0x59d86407, 0xc75bbe98, 0x9fdd59f1, + 0x015e836e, 0xe2dc9d15, 0x7c5f478a, 0xbec2b68d, 0x20416c12, + 0xc3c37269, 0x5d40a8f6, 0x05c64f9f, 0x9b459500, 0x78c78b7b, + 0xe64451e4, 0xc8cb44a8, 0x56489e37, 0xb5ca804c, 0x2b495ad3, + 0x73cfbdba, 0xed4c6725, 0x0ece795e, 0x904da3c1, 0x8af59a51, + 0x147640ce, 0xf7f45eb5, 0x6977842a, 0x31f16343, 0xaf72b9dc, + 0x4cf0a7a7, 0xd2737d38, 0xfcfc6874, 0x627fb2eb, 0x81fdac90, + 0x1f7e760f, 0x47f89166, 0xd97b4bf9, 0x3af95582, 0xa47a8f1d, + 0x66e77e1a, 0xf864a485, 0x1be6bafe, 0x85656061, 0xdde38708, + 0x43605d97, 0xa0e243ec, 0x3e619973, 0x10ee8c3f, 0x8e6d56a0, + 0x6def48db, 0xf36c9244, 0xabea752d, 0x3569afb2, 0xd6ebb1c9, + 0x48686b56}, + {0x00000000, 0xc0642817, 0x80c9502e, 0x40ad7839, 0x0093a15c, + 0xc0f7894b, 0x805af172, 0x403ed965, 0x002643b9, 0xc0426bae, + 0x80ef1397, 0x408b3b80, 0x00b5e2e5, 0xc0d1caf2, 0x807cb2cb, + 0x40189adc, 0x414af7a9, 0x812edfbe, 0xc183a787, 0x01e78f90, + 0x41d956f5, 0x81bd7ee2, 0xc11006db, 0x01742ecc, 0x416cb410, + 0x81089c07, 0xc1a5e43e, 0x01c1cc29, 0x41ff154c, 0x819b3d5b, + 0xc1364562, 0x01526d75, 0xc3929f88, 0x03f6b79f, 0x435bcfa6, + 0x833fe7b1, 0xc3013ed4, 0x036516c3, 0x43c86efa, 0x83ac46ed, + 0xc3b4dc31, 0x03d0f426, 0x437d8c1f, 0x8319a408, 0xc3277d6d, + 0x0343557a, 0x43ee2d43, 0x838a0554, 0x82d86821, 0x42bc4036, + 0x0211380f, 0xc2751018, 0x824bc97d, 0x422fe16a, 0x02829953, + 0xc2e6b144, 0x82fe2b98, 0x429a038f, 0x02377bb6, 0xc25353a1, + 0x826d8ac4, 0x4209a2d3, 0x02a4daea, 0xc2c0f2fd, 0xc7234eca, + 0x074766dd, 0x47ea1ee4, 0x878e36f3, 0xc7b0ef96, 0x07d4c781, + 0x4779bfb8, 0x871d97af, 0xc7050d73, 0x07612564, 0x47cc5d5d, + 0x87a8754a, 0xc796ac2f, 0x07f28438, 0x475ffc01, 0x873bd416, + 0x8669b963, 0x460d9174, 0x06a0e94d, 0xc6c4c15a, 0x86fa183f, + 0x469e3028, 0x06334811, 0xc6576006, 0x864ffada, 0x462bd2cd, + 0x0686aaf4, 0xc6e282e3, 0x86dc5b86, 0x46b87391, 0x06150ba8, + 0xc67123bf, 0x04b1d142, 0xc4d5f955, 0x8478816c, 0x441ca97b, + 0x0422701e, 0xc4465809, 0x84eb2030, 0x448f0827, 0x049792fb, + 0xc4f3baec, 0x845ec2d5, 0x443aeac2, 0x040433a7, 0xc4601bb0, + 0x84cd6389, 0x44a94b9e, 0x45fb26eb, 0x859f0efc, 0xc53276c5, + 0x05565ed2, 0x456887b7, 0x850cafa0, 0xc5a1d799, 0x05c5ff8e, + 0x45dd6552, 0x85b94d45, 0xc514357c, 0x05701d6b, 0x454ec40e, + 0x852aec19, 0xc5879420, 0x05e3bc37, 0xcf41ed4f, 0x0f25c558, + 0x4f88bd61, 0x8fec9576, 0xcfd24c13, 0x0fb66404, 0x4f1b1c3d, + 0x8f7f342a, 0xcf67aef6, 0x0f0386e1, 0x4faefed8, 0x8fcad6cf, + 0xcff40faa, 0x0f9027bd, 0x4f3d5f84, 0x8f597793, 0x8e0b1ae6, + 0x4e6f32f1, 0x0ec24ac8, 0xcea662df, 0x8e98bbba, 0x4efc93ad, + 0x0e51eb94, 0xce35c383, 0x8e2d595f, 0x4e497148, 0x0ee40971, + 0xce802166, 0x8ebef803, 0x4edad014, 0x0e77a82d, 0xce13803a, + 0x0cd372c7, 0xccb75ad0, 0x8c1a22e9, 0x4c7e0afe, 0x0c40d39b, + 0xcc24fb8c, 0x8c8983b5, 0x4cedaba2, 0x0cf5317e, 0xcc911969, + 0x8c3c6150, 0x4c584947, 0x0c669022, 0xcc02b835, 0x8cafc00c, + 0x4ccbe81b, 0x4d99856e, 0x8dfdad79, 0xcd50d540, 0x0d34fd57, + 0x4d0a2432, 0x8d6e0c25, 0xcdc3741c, 0x0da75c0b, 0x4dbfc6d7, + 0x8ddbeec0, 0xcd7696f9, 0x0d12beee, 0x4d2c678b, 0x8d484f9c, + 0xcde537a5, 0x0d811fb2, 0x0862a385, 0xc8068b92, 0x88abf3ab, + 0x48cfdbbc, 0x08f102d9, 0xc8952ace, 0x883852f7, 0x485c7ae0, + 0x0844e03c, 0xc820c82b, 0x888db012, 0x48e99805, 0x08d74160, + 0xc8b36977, 0x881e114e, 0x487a3959, 0x4928542c, 0x894c7c3b, + 0xc9e10402, 0x09852c15, 0x49bbf570, 0x89dfdd67, 0xc972a55e, + 0x09168d49, 0x490e1795, 0x896a3f82, 0xc9c747bb, 0x09a36fac, + 0x499db6c9, 0x89f99ede, 0xc954e6e7, 0x0930cef0, 0xcbf03c0d, + 0x0b94141a, 0x4b396c23, 0x8b5d4434, 0xcb639d51, 0x0b07b546, + 0x4baacd7f, 0x8bcee568, 0xcbd67fb4, 0x0bb257a3, 0x4b1f2f9a, + 0x8b7b078d, 0xcb45dee8, 0x0b21f6ff, 0x4b8c8ec6, 0x8be8a6d1, + 0x8abacba4, 0x4adee3b3, 0x0a739b8a, 0xca17b39d, 0x8a296af8, + 0x4a4d42ef, 0x0ae03ad6, 0xca8412c1, 0x8a9c881d, 0x4af8a00a, + 0x0a55d833, 0xca31f024, 0x8a0f2941, 0x4a6b0156, 0x0ac6796f, + 0xcaa25178}, + {0x00000000, 0xd4ea739b, 0xe9d396ed, 0x3d39e576, 0x93a15c00, + 0x474b2f9b, 0x7a72caed, 0xae98b976, 0x2643b900, 0xf2a9ca9b, + 0xcf902fed, 0x1b7a5c76, 0xb5e2e500, 0x6108969b, 0x5c3173ed, + 0x88db0076, 0x4c867201, 0x986c019a, 0xa555e4ec, 0x71bf9777, + 0xdf272e01, 0x0bcd5d9a, 0x36f4b8ec, 0xe21ecb77, 0x6ac5cb01, + 0xbe2fb89a, 0x83165dec, 0x57fc2e77, 0xf9649701, 0x2d8ee49a, + 0x10b701ec, 0xc45d7277, 0x980ce502, 0x4ce69699, 0x71df73ef, + 0xa5350074, 0x0badb902, 0xdf47ca99, 0xe27e2fef, 0x36945c74, + 0xbe4f5c02, 0x6aa52f99, 0x579ccaef, 0x8376b974, 0x2dee0002, + 0xf9047399, 0xc43d96ef, 0x10d7e574, 0xd48a9703, 0x0060e498, + 0x3d5901ee, 0xe9b37275, 0x472bcb03, 0x93c1b898, 0xaef85dee, + 0x7a122e75, 0xf2c92e03, 0x26235d98, 0x1b1ab8ee, 0xcff0cb75, + 0x61687203, 0xb5820198, 0x88bbe4ee, 0x5c519775, 0x3019ca05, + 0xe4f3b99e, 0xd9ca5ce8, 0x0d202f73, 0xa3b89605, 0x7752e59e, + 0x4a6b00e8, 0x9e817373, 0x165a7305, 0xc2b0009e, 0xff89e5e8, + 0x2b639673, 0x85fb2f05, 0x51115c9e, 0x6c28b9e8, 0xb8c2ca73, + 0x7c9fb804, 0xa875cb9f, 0x954c2ee9, 0x41a65d72, 0xef3ee404, + 0x3bd4979f, 0x06ed72e9, 0xd2070172, 0x5adc0104, 0x8e36729f, + 0xb30f97e9, 0x67e5e472, 0xc97d5d04, 0x1d972e9f, 0x20aecbe9, + 0xf444b872, 0xa8152f07, 0x7cff5c9c, 0x41c6b9ea, 0x952cca71, + 0x3bb47307, 0xef5e009c, 0xd267e5ea, 0x068d9671, 0x8e569607, + 0x5abce59c, 0x678500ea, 0xb36f7371, 0x1df7ca07, 0xc91db99c, + 0xf4245cea, 0x20ce2f71, 0xe4935d06, 0x30792e9d, 0x0d40cbeb, + 0xd9aab870, 0x77320106, 0xa3d8729d, 0x9ee197eb, 0x4a0be470, + 0xc2d0e406, 0x163a979d, 0x2b0372eb, 0xffe90170, 0x5171b806, + 0x859bcb9d, 0xb8a22eeb, 0x6c485d70, 0x6032940b, 0xb4d8e790, + 0x89e102e6, 0x5d0b717d, 0xf393c80b, 0x2779bb90, 0x1a405ee6, + 0xceaa2d7d, 0x46712d0b, 0x929b5e90, 0xafa2bbe6, 0x7b48c87d, + 0xd5d0710b, 0x013a0290, 0x3c03e7e6, 0xe8e9947d, 0x2cb4e60a, + 0xf85e9591, 0xc56770e7, 0x118d037c, 0xbf15ba0a, 0x6bffc991, + 0x56c62ce7, 0x822c5f7c, 0x0af75f0a, 0xde1d2c91, 0xe324c9e7, + 0x37ceba7c, 0x9956030a, 0x4dbc7091, 0x708595e7, 0xa46fe67c, + 0xf83e7109, 0x2cd40292, 0x11ede7e4, 0xc507947f, 0x6b9f2d09, + 0xbf755e92, 0x824cbbe4, 0x56a6c87f, 0xde7dc809, 0x0a97bb92, + 0x37ae5ee4, 0xe3442d7f, 0x4ddc9409, 0x9936e792, 0xa40f02e4, + 0x70e5717f, 0xb4b80308, 0x60527093, 0x5d6b95e5, 0x8981e67e, + 0x27195f08, 0xf3f32c93, 0xcecac9e5, 0x1a20ba7e, 0x92fbba08, + 0x4611c993, 0x7b282ce5, 0xafc25f7e, 0x015ae608, 0xd5b09593, + 0xe88970e5, 0x3c63037e, 0x502b5e0e, 0x84c12d95, 0xb9f8c8e3, + 0x6d12bb78, 0xc38a020e, 0x17607195, 0x2a5994e3, 0xfeb3e778, + 0x7668e70e, 0xa2829495, 0x9fbb71e3, 0x4b510278, 0xe5c9bb0e, + 0x3123c895, 0x0c1a2de3, 0xd8f05e78, 0x1cad2c0f, 0xc8475f94, + 0xf57ebae2, 0x2194c979, 0x8f0c700f, 0x5be60394, 0x66dfe6e2, + 0xb2359579, 0x3aee950f, 0xee04e694, 0xd33d03e2, 0x07d77079, + 0xa94fc90f, 0x7da5ba94, 0x409c5fe2, 0x94762c79, 0xc827bb0c, + 0x1ccdc897, 0x21f42de1, 0xf51e5e7a, 0x5b86e70c, 0x8f6c9497, + 0xb25571e1, 0x66bf027a, 0xee64020c, 0x3a8e7197, 0x07b794e1, + 0xd35de77a, 0x7dc55e0c, 0xa92f2d97, 0x9416c8e1, 0x40fcbb7a, + 0x84a1c90d, 0x504bba96, 0x6d725fe0, 0xb9982c7b, 0x1700950d, + 0xc3eae696, 0xfed303e0, 0x2a39707b, 0xa2e2700d, 0x76080396, + 0x4b31e6e0, 0x9fdb957b, 0x31432c0d, 0xe5a95f96, 0xd890bae0, + 0x0c7ac97b}, + {0x00000000, 0x27652581, 0x0fcc3bd9, 0x28a91e58, 0x5f9e0669, + 0x78fb23e8, 0x50523db0, 0x77371831, 0xbe3c0dd2, 0x99592853, + 0xb1f0360b, 0x9695138a, 0xe1a20bbb, 0xc6c72e3a, 0xee6e3062, + 0xc90b15e3, 0x3d7f6b7f, 0x1a1a4efe, 0x32b350a6, 0x15d67527, + 0x62e16d16, 0x45844897, 0x6d2d56cf, 0x4a48734e, 0x834366ad, + 0xa426432c, 0x8c8f5d74, 0xabea78f5, 0xdcdd60c4, 0xfbb84545, + 0xd3115b1d, 0xf4747e9c, 0x7afed6fe, 0x5d9bf37f, 0x7532ed27, + 0x5257c8a6, 0x2560d097, 0x0205f516, 0x2aaceb4e, 0x0dc9cecf, + 0xc4c2db2c, 0xe3a7fead, 0xcb0ee0f5, 0xec6bc574, 0x9b5cdd45, + 0xbc39f8c4, 0x9490e69c, 0xb3f5c31d, 0x4781bd81, 0x60e49800, + 0x484d8658, 0x6f28a3d9, 0x181fbbe8, 0x3f7a9e69, 0x17d38031, + 0x30b6a5b0, 0xf9bdb053, 0xded895d2, 0xf6718b8a, 0xd114ae0b, + 0xa623b63a, 0x814693bb, 0xa9ef8de3, 0x8e8aa862, 0xb5fadc26, + 0x929ff9a7, 0xba36e7ff, 0x9d53c27e, 0xea64da4f, 0xcd01ffce, + 0xe5a8e196, 0xc2cdc417, 0x0bc6d1f4, 0x2ca3f475, 0x040aea2d, + 0x236fcfac, 0x5458d79d, 0x733df21c, 0x5b94ec44, 0x7cf1c9c5, + 0x8885b759, 0xafe092d8, 0x87498c80, 0xa02ca901, 0xd71bb130, + 0xf07e94b1, 0xd8d78ae9, 0xffb2af68, 0x36b9ba8b, 0x11dc9f0a, + 0x39758152, 0x1e10a4d3, 0x6927bce2, 0x4e429963, 0x66eb873b, + 0x418ea2ba, 0xcf040ad8, 0xe8612f59, 0xc0c83101, 0xe7ad1480, + 0x909a0cb1, 0xb7ff2930, 0x9f563768, 0xb83312e9, 0x7138070a, + 0x565d228b, 0x7ef43cd3, 0x59911952, 0x2ea60163, 0x09c324e2, + 0x216a3aba, 0x060f1f3b, 0xf27b61a7, 0xd51e4426, 0xfdb75a7e, + 0xdad27fff, 0xade567ce, 0x8a80424f, 0xa2295c17, 0x854c7996, + 0x4c476c75, 0x6b2249f4, 0x438b57ac, 0x64ee722d, 0x13d96a1c, + 0x34bc4f9d, 0x1c1551c5, 0x3b707444, 0x6af5b94d, 0x4d909ccc, + 0x65398294, 0x425ca715, 0x356bbf24, 0x120e9aa5, 0x3aa784fd, + 0x1dc2a17c, 0xd4c9b49f, 0xf3ac911e, 0xdb058f46, 0xfc60aac7, + 0x8b57b2f6, 0xac329777, 0x849b892f, 0xa3feacae, 0x578ad232, + 0x70eff7b3, 0x5846e9eb, 0x7f23cc6a, 0x0814d45b, 0x2f71f1da, + 0x07d8ef82, 0x20bdca03, 0xe9b6dfe0, 0xced3fa61, 0xe67ae439, + 0xc11fc1b8, 0xb628d989, 0x914dfc08, 0xb9e4e250, 0x9e81c7d1, + 0x100b6fb3, 0x376e4a32, 0x1fc7546a, 0x38a271eb, 0x4f9569da, + 0x68f04c5b, 0x40595203, 0x673c7782, 0xae376261, 0x895247e0, + 0xa1fb59b8, 0x869e7c39, 0xf1a96408, 0xd6cc4189, 0xfe655fd1, + 0xd9007a50, 0x2d7404cc, 0x0a11214d, 0x22b83f15, 0x05dd1a94, + 0x72ea02a5, 0x558f2724, 0x7d26397c, 0x5a431cfd, 0x9348091e, + 0xb42d2c9f, 0x9c8432c7, 0xbbe11746, 0xccd60f77, 0xebb32af6, + 0xc31a34ae, 0xe47f112f, 0xdf0f656b, 0xf86a40ea, 0xd0c35eb2, + 0xf7a67b33, 0x80916302, 0xa7f44683, 0x8f5d58db, 0xa8387d5a, + 0x613368b9, 0x46564d38, 0x6eff5360, 0x499a76e1, 0x3ead6ed0, + 0x19c84b51, 0x31615509, 0x16047088, 0xe2700e14, 0xc5152b95, + 0xedbc35cd, 0xcad9104c, 0xbdee087d, 0x9a8b2dfc, 0xb22233a4, + 0x95471625, 0x5c4c03c6, 0x7b292647, 0x5380381f, 0x74e51d9e, + 0x03d205af, 0x24b7202e, 0x0c1e3e76, 0x2b7b1bf7, 0xa5f1b395, + 0x82949614, 0xaa3d884c, 0x8d58adcd, 0xfa6fb5fc, 0xdd0a907d, + 0xf5a38e25, 0xd2c6aba4, 0x1bcdbe47, 0x3ca89bc6, 0x1401859e, + 0x3364a01f, 0x4453b82e, 0x63369daf, 0x4b9f83f7, 0x6cfaa676, + 0x988ed8ea, 0xbfebfd6b, 0x9742e333, 0xb027c6b2, 0xc710de83, + 0xe075fb02, 0xc8dce55a, 0xefb9c0db, 0x26b2d538, 0x01d7f0b9, + 0x297eeee1, 0x0e1bcb60, 0x792cd351, 0x5e49f6d0, 0x76e0e888, + 0x5185cd09}}; + +#endif + +#endif + +#endif + +local const z_crc_t FAR x2n_table[] = { + 0x40000000, 0x20000000, 0x08000000, 0x00800000, 0x00008000, + 0xedb88320, 0xb1e6b092, 0xa06a2517, 0xed627dae, 0x88d14467, + 0xd7bbfe6a, 0xec447f11, 0x8e7ea170, 0x6427800e, 0x4d47bae0, + 0x09fe548f, 0x83852d0f, 0x30362f1a, 0x7b5a9cc3, 0x31fec169, + 0x9fec022a, 0x6c8dedc4, 0x15d6874d, 0x5fde7a4e, 0xbad90e37, + 0x2e4e5eef, 0x4eaba214, 0xa8a472c0, 0x429a969e, 0x148d302a, + 0xc40ba6d0, 0xc4e22c3c}; diff --git a/common/zlib/deflate.c b/common/zlib/deflate.c new file mode 100644 index 0000000..012ea81 --- /dev/null +++ b/common/zlib/deflate.c @@ -0,0 +1,2139 @@ +/* deflate.c -- compress data using the deflation algorithm + * Copyright (C) 1995-2024 Jean-loup Gailly and Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * ALGORITHM + * + * The "deflation" process depends on being able to identify portions + * of the input text which are identical to earlier input (within a + * sliding window trailing behind the input currently being processed). + * + * The most straightforward technique turns out to be the fastest for + * most input files: try all possible matches and select the longest. + * The key feature of this algorithm is that insertions into the string + * dictionary are very simple and thus fast, and deletions are avoided + * completely. Insertions are performed at each input character, whereas + * string matches are performed only when the previous match ends. So it + * is preferable to spend more time in matches to allow very fast string + * insertions and avoid deletions. The matching algorithm for small + * strings is inspired from that of Rabin & Karp. A brute force approach + * is used to find longer strings when a small match has been found. + * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze + * (by Leonid Broukhis). + * A previous version of this file used a more sophisticated algorithm + * (by Fiala and Greene) which is guaranteed to run in linear amortized + * time, but has a larger average cost, uses more memory and is patented. + * However the F&G algorithm may be faster for some highly redundant + * files if the parameter max_chain_length (described below) is too large. + * + * ACKNOWLEDGEMENTS + * + * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and + * I found it in 'freeze' written by Leonid Broukhis. + * Thanks to many people for bug reports and testing. + * + * REFERENCES + * + * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification". + * Available in http://tools.ietf.org/html/rfc1951 + * + * A description of the Rabin and Karp algorithm is given in the book + * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. + * + * Fiala,E.R., and Greene,D.H. + * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 + * + */ + +/* @(#) $Id$ */ + +#include "deflate.h" + +const char deflate_copyright[] = + " deflate 1.3.1 Copyright 1995-2024 Jean-loup Gailly and Mark Adler "; +/* + If you use the zlib library in a product, an acknowledgment is welcome + in the documentation of your product. If for some reason you cannot + include such an acknowledgment, I would appreciate that you keep this + copyright string in the executable of your product. + */ + +typedef enum { + need_more, /* block not completed, need more input or more output */ + block_done, /* block flush performed */ + finish_started, /* finish started, need only more output at next deflate */ + finish_done /* finish done, accept no more input or output */ +} block_state; + +typedef block_state (*compress_func)(deflate_state *s, int flush); +/* Compression function. Returns the block state after the call. */ + +local block_state deflate_stored(deflate_state *s, int flush); +local block_state deflate_fast(deflate_state *s, int flush); +#ifndef FASTEST +local block_state deflate_slow(deflate_state *s, int flush); +#endif +local block_state deflate_rle(deflate_state *s, int flush); +local block_state deflate_huff(deflate_state *s, int flush); + +/* =========================================================================== + * Local data + */ + +#define NIL 0 +/* Tail of hash chains */ + +#ifndef TOO_FAR +# define TOO_FAR 4096 +#endif +/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ + +/* Values for max_lazy_match, good_match and max_chain_length, depending on + * the desired pack level (0..9). The values given below have been tuned to + * exclude worst case performance for pathological files. Better values may be + * found for specific files. + */ +typedef struct config_s { + ush good_length; /* reduce lazy search above this match length */ + ush max_lazy; /* do not perform lazy search above this match length */ + ush nice_length; /* quit search above this match length */ + ush max_chain; + compress_func func; +} config; + +#ifdef FASTEST +local const config configuration_table[2] = { +/* good lazy nice chain */ +/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ +/* 1 */ {4, 4, 8, 4, deflate_fast}}; /* max speed, no lazy matches */ +#else +local const config configuration_table[10] = { +/* good lazy nice chain */ +/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ +/* 1 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */ +/* 2 */ {4, 5, 16, 8, deflate_fast}, +/* 3 */ {4, 6, 32, 32, deflate_fast}, + +/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */ +/* 5 */ {8, 16, 32, 32, deflate_slow}, +/* 6 */ {8, 16, 128, 128, deflate_slow}, +/* 7 */ {8, 32, 128, 256, deflate_slow}, +/* 8 */ {32, 128, 258, 1024, deflate_slow}, +/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */ +#endif + +/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 + * For deflate_fast() (levels <= 3) good is ignored and lazy has a different + * meaning. + */ + +/* rank Z_BLOCK between Z_NO_FLUSH and Z_PARTIAL_FLUSH */ +#define RANK(f) (((f) * 2) - ((f) > 4 ? 9 : 0)) + +/* =========================================================================== + * Update a hash value with the given input byte + * IN assertion: all calls to UPDATE_HASH are made with consecutive input + * characters, so that a running hash key can be computed from the previous + * key instead of complete recalculation each time. + */ +#define UPDATE_HASH(s,h,c) (h = (((h) << s->hash_shift) ^ (c)) & s->hash_mask) + + +/* =========================================================================== + * Insert string str in the dictionary and set match_head to the previous head + * of the hash chain (the most recent string with same hash key). Return + * the previous length of the hash chain. + * If this file is compiled with -DFASTEST, the compression level is forced + * to 1, and no hash chains are maintained. + * IN assertion: all calls to INSERT_STRING are made with consecutive input + * characters and the first MIN_MATCH bytes of str are valid (except for + * the last MIN_MATCH-1 bytes of the input file). + */ +#ifdef FASTEST +#define INSERT_STRING(s, str, match_head) \ + (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ + match_head = s->head[s->ins_h], \ + s->head[s->ins_h] = (Pos)(str)) +#else +#define INSERT_STRING(s, str, match_head) \ + (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ + match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \ + s->head[s->ins_h] = (Pos)(str)) +#endif + +/* =========================================================================== + * Initialize the hash table (avoiding 64K overflow for 16 bit systems). + * prev[] will be initialized on the fly. + */ +#define CLEAR_HASH(s) \ + do { \ + s->head[s->hash_size - 1] = NIL; \ + zmemzero((Bytef *)s->head, \ + (unsigned)(s->hash_size - 1)*sizeof(*s->head)); \ + } while (0) + +/* =========================================================================== + * Slide the hash table when sliding the window down (could be avoided with 32 + * bit values at the expense of memory usage). We slide even when level == 0 to + * keep the hash table consistent if we switch back to level > 0 later. + */ +#if defined(__has_feature) +# if __has_feature(memory_sanitizer) + __attribute__((no_sanitize("memory"))) +# endif +#endif +local void slide_hash(deflate_state *s) { + unsigned n, m; + Posf *p; + uInt wsize = s->w_size; + + n = s->hash_size; + p = &s->head[n]; + do { + m = *--p; + *p = (Pos)(m >= wsize ? m - wsize : NIL); + } while (--n); + n = wsize; +#ifndef FASTEST + p = &s->prev[n]; + do { + m = *--p; + *p = (Pos)(m >= wsize ? m - wsize : NIL); + /* If n is not on any hash chain, prev[n] is garbage but + * its value will never be used. + */ + } while (--n); +#endif +} + +/* =========================================================================== + * Read a new buffer from the current input stream, update the adler32 + * and total number of bytes read. All deflate() input goes through + * this function so some applications may wish to modify it to avoid + * allocating a large strm->next_in buffer and copying from it. + * (See also flush_pending()). + */ +local unsigned read_buf(z_streamp strm, Bytef *buf, unsigned size) { + unsigned len = strm->avail_in; + + if (len > size) len = size; + if (len == 0) return 0; + + strm->avail_in -= len; + + zmemcpy(buf, strm->next_in, len); + if (strm->state->wrap == 1) { + strm->adler = adler32(strm->adler, buf, len); + } +#ifdef GZIP + else if (strm->state->wrap == 2) { + strm->adler = crc32(strm->adler, buf, len); + } +#endif + strm->next_in += len; + strm->total_in += len; + + return len; +} + +/* =========================================================================== + * Fill the window when the lookahead becomes insufficient. + * Updates strstart and lookahead. + * + * IN assertion: lookahead < MIN_LOOKAHEAD + * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD + * At least one byte has been read, or avail_in == 0; reads are + * performed for at least two bytes (required for the zip translate_eol + * option -- not supported here). + */ +local void fill_window(deflate_state *s) { + unsigned n; + unsigned more; /* Amount of free space at the end of the window. */ + uInt wsize = s->w_size; + + Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead"); + + do { + more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); + + /* Deal with !@#$% 64K limit: */ + if (sizeof(int) <= 2) { + if (more == 0 && s->strstart == 0 && s->lookahead == 0) { + more = wsize; + + } else if (more == (unsigned)(-1)) { + /* Very unlikely, but possible on 16 bit machine if + * strstart == 0 && lookahead == 1 (input done a byte at time) + */ + more--; + } + } + + /* If the window is almost full and there is insufficient lookahead, + * move the upper half to the lower one to make room in the upper half. + */ + if (s->strstart >= wsize + MAX_DIST(s)) { + + zmemcpy(s->window, s->window + wsize, (unsigned)wsize - more); + s->match_start -= wsize; + s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ + s->block_start -= (long) wsize; + if (s->insert > s->strstart) + s->insert = s->strstart; + slide_hash(s); + more += wsize; + } + if (s->strm->avail_in == 0) break; + + /* If there was no sliding: + * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && + * more == window_size - lookahead - strstart + * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) + * => more >= window_size - 2*WSIZE + 2 + * In the BIG_MEM or MMAP case (not yet supported), + * window_size == input_size + MIN_LOOKAHEAD && + * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. + * Otherwise, window_size == 2*WSIZE so more >= 2. + * If there was sliding, more >= WSIZE. So in all cases, more >= 2. + */ + Assert(more >= 2, "more < 2"); + + n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more); + s->lookahead += n; + + /* Initialize the hash value now that we have some input: */ + if (s->lookahead + s->insert >= MIN_MATCH) { + uInt str = s->strstart - s->insert; + s->ins_h = s->window[str]; + UPDATE_HASH(s, s->ins_h, s->window[str + 1]); +#if MIN_MATCH != 3 + Call UPDATE_HASH() MIN_MATCH-3 more times +#endif + while (s->insert) { + UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); +#ifndef FASTEST + s->prev[str & s->w_mask] = s->head[s->ins_h]; +#endif + s->head[s->ins_h] = (Pos)str; + str++; + s->insert--; + if (s->lookahead + s->insert < MIN_MATCH) + break; + } + } + /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, + * but this is not important since only literal bytes will be emitted. + */ + + } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); + + /* If the WIN_INIT bytes after the end of the current data have never been + * written, then zero those bytes in order to avoid memory check reports of + * the use of uninitialized (or uninitialised as Julian writes) bytes by + * the longest match routines. Update the high water mark for the next + * time through here. WIN_INIT is set to MAX_MATCH since the longest match + * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead. + */ + if (s->high_water < s->window_size) { + ulg curr = s->strstart + (ulg)(s->lookahead); + ulg init; + + if (s->high_water < curr) { + /* Previous high water mark below current data -- zero WIN_INIT + * bytes or up to end of window, whichever is less. + */ + init = s->window_size - curr; + if (init > WIN_INIT) + init = WIN_INIT; + zmemzero(s->window + curr, (unsigned)init); + s->high_water = curr + init; + } + else if (s->high_water < (ulg)curr + WIN_INIT) { + /* High water mark at or above current data, but below current data + * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up + * to end of window, whichever is less. + */ + init = (ulg)curr + WIN_INIT - s->high_water; + if (init > s->window_size - s->high_water) + init = s->window_size - s->high_water; + zmemzero(s->window + s->high_water, (unsigned)init); + s->high_water += init; + } + } + + Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD, + "not enough room for search"); +} + +/* ========================================================================= */ +int ZEXPORT deflateInit_(z_streamp strm, int level, const char *version, + int stream_size) { + return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, + Z_DEFAULT_STRATEGY, version, stream_size); + /* To do: ignore strm->next_in if we use it as window */ +} + +/* ========================================================================= */ +int ZEXPORT deflateInit2_(z_streamp strm, int level, int method, + int windowBits, int memLevel, int strategy, + const char *version, int stream_size) { + deflate_state *s; + int wrap = 1; + static const char my_version[] = ZLIB_VERSION; + + if (version == Z_NULL || version[0] != my_version[0] || + stream_size != sizeof(z_stream)) { + return Z_VERSION_ERROR; + } + if (strm == Z_NULL) return Z_STREAM_ERROR; + + strm->msg = Z_NULL; + if (strm->zalloc == (alloc_func)0) { +#ifdef Z_SOLO + return Z_STREAM_ERROR; +#else + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; +#endif + } + if (strm->zfree == (free_func)0) +#ifdef Z_SOLO + return Z_STREAM_ERROR; +#else + strm->zfree = zcfree; +#endif + +#ifdef FASTEST + if (level != 0) level = 1; +#else + if (level == Z_DEFAULT_COMPRESSION) level = 6; +#endif + + if (windowBits < 0) { /* suppress zlib wrapper */ + wrap = 0; + if (windowBits < -15) + return Z_STREAM_ERROR; + windowBits = -windowBits; + } +#ifdef GZIP + else if (windowBits > 15) { + wrap = 2; /* write gzip wrapper instead */ + windowBits -= 16; + } +#endif + if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || + windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || + strategy < 0 || strategy > Z_FIXED || (windowBits == 8 && wrap != 1)) { + return Z_STREAM_ERROR; + } + if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */ + s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); + if (s == Z_NULL) return Z_MEM_ERROR; + strm->state = (struct internal_state FAR *)s; + s->strm = strm; + s->status = INIT_STATE; /* to pass state test in deflateReset() */ + + s->wrap = wrap; + s->gzhead = Z_NULL; + s->w_bits = (uInt)windowBits; + s->w_size = 1 << s->w_bits; + s->w_mask = s->w_size - 1; + + s->hash_bits = (uInt)memLevel + 7; + s->hash_size = 1 << s->hash_bits; + s->hash_mask = s->hash_size - 1; + s->hash_shift = ((s->hash_bits + MIN_MATCH-1) / MIN_MATCH); + + s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte)); + s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); + s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); + + s->high_water = 0; /* nothing written to s->window yet */ + + s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ + + /* We overlay pending_buf and sym_buf. This works since the average size + * for length/distance pairs over any compressed block is assured to be 31 + * bits or less. + * + * Analysis: The longest fixed codes are a length code of 8 bits plus 5 + * extra bits, for lengths 131 to 257. The longest fixed distance codes are + * 5 bits plus 13 extra bits, for distances 16385 to 32768. The longest + * possible fixed-codes length/distance pair is then 31 bits total. + * + * sym_buf starts one-fourth of the way into pending_buf. So there are + * three bytes in sym_buf for every four bytes in pending_buf. Each symbol + * in sym_buf is three bytes -- two for the distance and one for the + * literal/length. As each symbol is consumed, the pointer to the next + * sym_buf value to read moves forward three bytes. From that symbol, up to + * 31 bits are written to pending_buf. The closest the written pending_buf + * bits gets to the next sym_buf symbol to read is just before the last + * code is written. At that time, 31*(n - 2) bits have been written, just + * after 24*(n - 2) bits have been consumed from sym_buf. sym_buf starts at + * 8*n bits into pending_buf. (Note that the symbol buffer fills when n - 1 + * symbols are written.) The closest the writing gets to what is unread is + * then n + 14 bits. Here n is lit_bufsize, which is 16384 by default, and + * can range from 128 to 32768. + * + * Therefore, at a minimum, there are 142 bits of space between what is + * written and what is read in the overlain buffers, so the symbols cannot + * be overwritten by the compressed data. That space is actually 139 bits, + * due to the three-bit fixed-code block header. + * + * That covers the case where either Z_FIXED is specified, forcing fixed + * codes, or when the use of fixed codes is chosen, because that choice + * results in a smaller compressed block than dynamic codes. That latter + * condition then assures that the above analysis also covers all dynamic + * blocks. A dynamic-code block will only be chosen to be emitted if it has + * fewer bits than a fixed-code block would for the same set of symbols. + * Therefore its average symbol length is assured to be less than 31. So + * the compressed data for a dynamic block also cannot overwrite the + * symbols from which it is being constructed. + */ + + s->pending_buf = (uchf *) ZALLOC(strm, s->lit_bufsize, LIT_BUFS); + s->pending_buf_size = (ulg)s->lit_bufsize * 4; + + if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || + s->pending_buf == Z_NULL) { + s->status = FINISH_STATE; + strm->msg = ERR_MSG(Z_MEM_ERROR); + deflateEnd (strm); + return Z_MEM_ERROR; + } +#ifdef LIT_MEM + s->d_buf = (ushf *)(s->pending_buf + (s->lit_bufsize << 1)); + s->l_buf = s->pending_buf + (s->lit_bufsize << 2); + s->sym_end = s->lit_bufsize - 1; +#else + s->sym_buf = s->pending_buf + s->lit_bufsize; + s->sym_end = (s->lit_bufsize - 1) * 3; +#endif + /* We avoid equality with lit_bufsize*3 because of wraparound at 64K + * on 16 bit machines and because stored blocks are restricted to + * 64K-1 bytes. + */ + + s->level = level; + s->strategy = strategy; + s->method = (Byte)method; + + return deflateReset(strm); +} + +/* ========================================================================= + * Check for a valid deflate stream state. Return 0 if ok, 1 if not. + */ +local int deflateStateCheck(z_streamp strm) { + deflate_state *s; + if (strm == Z_NULL || + strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) + return 1; + s = strm->state; + if (s == Z_NULL || s->strm != strm || (s->status != INIT_STATE && +#ifdef GZIP + s->status != GZIP_STATE && +#endif + s->status != EXTRA_STATE && + s->status != NAME_STATE && + s->status != COMMENT_STATE && + s->status != HCRC_STATE && + s->status != BUSY_STATE && + s->status != FINISH_STATE)) + return 1; + return 0; +} + +/* ========================================================================= */ +int ZEXPORT deflateSetDictionary(z_streamp strm, const Bytef *dictionary, + uInt dictLength) { + deflate_state *s; + uInt str, n; + int wrap; + unsigned avail; + z_const unsigned char *next; + + if (deflateStateCheck(strm) || dictionary == Z_NULL) + return Z_STREAM_ERROR; + s = strm->state; + wrap = s->wrap; + if (wrap == 2 || (wrap == 1 && s->status != INIT_STATE) || s->lookahead) + return Z_STREAM_ERROR; + + /* when using zlib wrappers, compute Adler-32 for provided dictionary */ + if (wrap == 1) + strm->adler = adler32(strm->adler, dictionary, dictLength); + s->wrap = 0; /* avoid computing Adler-32 in read_buf */ + + /* if dictionary would fill window, just replace the history */ + if (dictLength >= s->w_size) { + if (wrap == 0) { /* already empty otherwise */ + CLEAR_HASH(s); + s->strstart = 0; + s->block_start = 0L; + s->insert = 0; + } + dictionary += dictLength - s->w_size; /* use the tail */ + dictLength = s->w_size; + } + + /* insert dictionary into window and hash */ + avail = strm->avail_in; + next = strm->next_in; + strm->avail_in = dictLength; + strm->next_in = (z_const Bytef *)dictionary; + fill_window(s); + while (s->lookahead >= MIN_MATCH) { + str = s->strstart; + n = s->lookahead - (MIN_MATCH-1); + do { + UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); +#ifndef FASTEST + s->prev[str & s->w_mask] = s->head[s->ins_h]; +#endif + s->head[s->ins_h] = (Pos)str; + str++; + } while (--n); + s->strstart = str; + s->lookahead = MIN_MATCH-1; + fill_window(s); + } + s->strstart += s->lookahead; + s->block_start = (long)s->strstart; + s->insert = s->lookahead; + s->lookahead = 0; + s->match_length = s->prev_length = MIN_MATCH-1; + s->match_available = 0; + strm->next_in = next; + strm->avail_in = avail; + s->wrap = wrap; + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateGetDictionary(z_streamp strm, Bytef *dictionary, + uInt *dictLength) { + deflate_state *s; + uInt len; + + if (deflateStateCheck(strm)) + return Z_STREAM_ERROR; + s = strm->state; + len = s->strstart + s->lookahead; + if (len > s->w_size) + len = s->w_size; + if (dictionary != Z_NULL && len) + zmemcpy(dictionary, s->window + s->strstart + s->lookahead - len, len); + if (dictLength != Z_NULL) + *dictLength = len; + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateResetKeep(z_streamp strm) { + deflate_state *s; + + if (deflateStateCheck(strm)) { + return Z_STREAM_ERROR; + } + + strm->total_in = strm->total_out = 0; + strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */ + strm->data_type = Z_UNKNOWN; + + s = (deflate_state *)strm->state; + s->pending = 0; + s->pending_out = s->pending_buf; + + if (s->wrap < 0) { + s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */ + } + s->status = +#ifdef GZIP + s->wrap == 2 ? GZIP_STATE : +#endif + INIT_STATE; + strm->adler = +#ifdef GZIP + s->wrap == 2 ? crc32(0L, Z_NULL, 0) : +#endif + adler32(0L, Z_NULL, 0); + s->last_flush = -2; + + _tr_init(s); + + return Z_OK; +} + +/* =========================================================================== + * Initialize the "longest match" routines for a new zlib stream + */ +local void lm_init(deflate_state *s) { + s->window_size = (ulg)2L*s->w_size; + + CLEAR_HASH(s); + + /* Set the default configuration parameters: + */ + s->max_lazy_match = configuration_table[s->level].max_lazy; + s->good_match = configuration_table[s->level].good_length; + s->nice_match = configuration_table[s->level].nice_length; + s->max_chain_length = configuration_table[s->level].max_chain; + + s->strstart = 0; + s->block_start = 0L; + s->lookahead = 0; + s->insert = 0; + s->match_length = s->prev_length = MIN_MATCH-1; + s->match_available = 0; + s->ins_h = 0; +} + +/* ========================================================================= */ +int ZEXPORT deflateReset(z_streamp strm) { + int ret; + + ret = deflateResetKeep(strm); + if (ret == Z_OK) + lm_init(strm->state); + return ret; +} + +/* ========================================================================= */ +int ZEXPORT deflateSetHeader(z_streamp strm, gz_headerp head) { + if (deflateStateCheck(strm) || strm->state->wrap != 2) + return Z_STREAM_ERROR; + strm->state->gzhead = head; + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflatePending(z_streamp strm, unsigned *pending, int *bits) { + if (deflateStateCheck(strm)) return Z_STREAM_ERROR; + if (pending != Z_NULL) + *pending = strm->state->pending; + if (bits != Z_NULL) + *bits = strm->state->bi_valid; + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflatePrime(z_streamp strm, int bits, int value) { + deflate_state *s; + int put; + + if (deflateStateCheck(strm)) return Z_STREAM_ERROR; + s = strm->state; +#ifdef LIT_MEM + if (bits < 0 || bits > 16 || + (uchf *)s->d_buf < s->pending_out + ((Buf_size + 7) >> 3)) + return Z_BUF_ERROR; +#else + if (bits < 0 || bits > 16 || + s->sym_buf < s->pending_out + ((Buf_size + 7) >> 3)) + return Z_BUF_ERROR; +#endif + do { + put = Buf_size - s->bi_valid; + if (put > bits) + put = bits; + s->bi_buf |= (ush)((value & ((1 << put) - 1)) << s->bi_valid); + s->bi_valid += put; + _tr_flush_bits(s); + value >>= put; + bits -= put; + } while (bits); + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateParams(z_streamp strm, int level, int strategy) { + deflate_state *s; + compress_func func; + + if (deflateStateCheck(strm)) return Z_STREAM_ERROR; + s = strm->state; + +#ifdef FASTEST + if (level != 0) level = 1; +#else + if (level == Z_DEFAULT_COMPRESSION) level = 6; +#endif + if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) { + return Z_STREAM_ERROR; + } + func = configuration_table[s->level].func; + + if ((strategy != s->strategy || func != configuration_table[level].func) && + s->last_flush != -2) { + /* Flush the last buffer: */ + int err = deflate(strm, Z_BLOCK); + if (err == Z_STREAM_ERROR) + return err; + if (strm->avail_in || (s->strstart - s->block_start) + s->lookahead) + return Z_BUF_ERROR; + } + if (s->level != level) { + if (s->level == 0 && s->matches != 0) { + if (s->matches == 1) + slide_hash(s); + else + CLEAR_HASH(s); + s->matches = 0; + } + s->level = level; + s->max_lazy_match = configuration_table[level].max_lazy; + s->good_match = configuration_table[level].good_length; + s->nice_match = configuration_table[level].nice_length; + s->max_chain_length = configuration_table[level].max_chain; + } + s->strategy = strategy; + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateTune(z_streamp strm, int good_length, int max_lazy, + int nice_length, int max_chain) { + deflate_state *s; + + if (deflateStateCheck(strm)) return Z_STREAM_ERROR; + s = strm->state; + s->good_match = (uInt)good_length; + s->max_lazy_match = (uInt)max_lazy; + s->nice_match = nice_length; + s->max_chain_length = (uInt)max_chain; + return Z_OK; +} + +/* ========================================================================= + * For the default windowBits of 15 and memLevel of 8, this function returns a + * close to exact, as well as small, upper bound on the compressed size. This + * is an expansion of ~0.03%, plus a small constant. + * + * For any setting other than those defaults for windowBits and memLevel, one + * of two worst case bounds is returned. This is at most an expansion of ~4% or + * ~13%, plus a small constant. + * + * Both the 0.03% and 4% derive from the overhead of stored blocks. The first + * one is for stored blocks of 16383 bytes (memLevel == 8), whereas the second + * is for stored blocks of 127 bytes (the worst case memLevel == 1). The + * expansion results from five bytes of header for each stored block. + * + * The larger expansion of 13% results from a window size less than or equal to + * the symbols buffer size (windowBits <= memLevel + 7). In that case some of + * the data being compressed may have slid out of the sliding window, impeding + * a stored block from being emitted. Then the only choice is a fixed or + * dynamic block, where a fixed block limits the maximum expansion to 9 bits + * per 8-bit byte, plus 10 bits for every block. The smallest block size for + * which this can occur is 255 (memLevel == 2). + * + * Shifts are used to approximate divisions, for speed. + */ +uLong ZEXPORT deflateBound(z_streamp strm, uLong sourceLen) { + deflate_state *s; + uLong fixedlen, storelen, wraplen; + + /* upper bound for fixed blocks with 9-bit literals and length 255 + (memLevel == 2, which is the lowest that may not use stored blocks) -- + ~13% overhead plus a small constant */ + fixedlen = sourceLen + (sourceLen >> 3) + (sourceLen >> 8) + + (sourceLen >> 9) + 4; + + /* upper bound for stored blocks with length 127 (memLevel == 1) -- + ~4% overhead plus a small constant */ + storelen = sourceLen + (sourceLen >> 5) + (sourceLen >> 7) + + (sourceLen >> 11) + 7; + + /* if can't get parameters, return larger bound plus a zlib wrapper */ + if (deflateStateCheck(strm)) + return (fixedlen > storelen ? fixedlen : storelen) + 6; + + /* compute wrapper length */ + s = strm->state; + switch (s->wrap) { + case 0: /* raw deflate */ + wraplen = 0; + break; + case 1: /* zlib wrapper */ + wraplen = 6 + (s->strstart ? 4 : 0); + break; +#ifdef GZIP + case 2: /* gzip wrapper */ + wraplen = 18; + if (s->gzhead != Z_NULL) { /* user-supplied gzip header */ + Bytef *str; + if (s->gzhead->extra != Z_NULL) + wraplen += 2 + s->gzhead->extra_len; + str = s->gzhead->name; + if (str != Z_NULL) + do { + wraplen++; + } while (*str++); + str = s->gzhead->comment; + if (str != Z_NULL) + do { + wraplen++; + } while (*str++); + if (s->gzhead->hcrc) + wraplen += 2; + } + break; +#endif + default: /* for compiler happiness */ + wraplen = 6; + } + + /* if not default parameters, return one of the conservative bounds */ + if (s->w_bits != 15 || s->hash_bits != 8 + 7) + return (s->w_bits <= s->hash_bits && s->level ? fixedlen : storelen) + + wraplen; + + /* default settings: return tight bound for that case -- ~0.03% overhead + plus a small constant */ + return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + + (sourceLen >> 25) + 13 - 6 + wraplen; +} + +/* ========================================================================= + * Put a short in the pending buffer. The 16-bit value is put in MSB order. + * IN assertion: the stream state is correct and there is enough room in + * pending_buf. + */ +local void putShortMSB(deflate_state *s, uInt b) { + put_byte(s, (Byte)(b >> 8)); + put_byte(s, (Byte)(b & 0xff)); +} + +/* ========================================================================= + * Flush as much pending output as possible. All deflate() output, except for + * some deflate_stored() output, goes through this function so some + * applications may wish to modify it to avoid allocating a large + * strm->next_out buffer and copying into it. (See also read_buf()). + */ +local void flush_pending(z_streamp strm) { + unsigned len; + deflate_state *s = strm->state; + + _tr_flush_bits(s); + len = s->pending; + if (len > strm->avail_out) len = strm->avail_out; + if (len == 0) return; + + zmemcpy(strm->next_out, s->pending_out, len); + strm->next_out += len; + s->pending_out += len; + strm->total_out += len; + strm->avail_out -= len; + s->pending -= len; + if (s->pending == 0) { + s->pending_out = s->pending_buf; + } +} + +/* =========================================================================== + * Update the header CRC with the bytes s->pending_buf[beg..s->pending - 1]. + */ +#define HCRC_UPDATE(beg) \ + do { \ + if (s->gzhead->hcrc && s->pending > (beg)) \ + strm->adler = crc32(strm->adler, s->pending_buf + (beg), \ + s->pending - (beg)); \ + } while (0) + +/* ========================================================================= */ +int ZEXPORT deflate(z_streamp strm, int flush) { + int old_flush; /* value of flush param for previous deflate call */ + deflate_state *s; + + if (deflateStateCheck(strm) || flush > Z_BLOCK || flush < 0) { + return Z_STREAM_ERROR; + } + s = strm->state; + + if (strm->next_out == Z_NULL || + (strm->avail_in != 0 && strm->next_in == Z_NULL) || + (s->status == FINISH_STATE && flush != Z_FINISH)) { + ERR_RETURN(strm, Z_STREAM_ERROR); + } + if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); + + old_flush = s->last_flush; + s->last_flush = flush; + + /* Flush as much pending output as possible */ + if (s->pending != 0) { + flush_pending(strm); + if (strm->avail_out == 0) { + /* Since avail_out is 0, deflate will be called again with + * more output space, but possibly with both pending and + * avail_in equal to zero. There won't be anything to do, + * but this is not an error situation so make sure we + * return OK instead of BUF_ERROR at next call of deflate: + */ + s->last_flush = -1; + return Z_OK; + } + + /* Make sure there is something to do and avoid duplicate consecutive + * flushes. For repeated and useless calls with Z_FINISH, we keep + * returning Z_STREAM_END instead of Z_BUF_ERROR. + */ + } else if (strm->avail_in == 0 && RANK(flush) <= RANK(old_flush) && + flush != Z_FINISH) { + ERR_RETURN(strm, Z_BUF_ERROR); + } + + /* User must not provide more input after the first FINISH: */ + if (s->status == FINISH_STATE && strm->avail_in != 0) { + ERR_RETURN(strm, Z_BUF_ERROR); + } + + /* Write the header */ + if (s->status == INIT_STATE && s->wrap == 0) + s->status = BUSY_STATE; + if (s->status == INIT_STATE) { + /* zlib header */ + uInt header = (Z_DEFLATED + ((s->w_bits - 8) << 4)) << 8; + uInt level_flags; + + if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2) + level_flags = 0; + else if (s->level < 6) + level_flags = 1; + else if (s->level == 6) + level_flags = 2; + else + level_flags = 3; + header |= (level_flags << 6); + if (s->strstart != 0) header |= PRESET_DICT; + header += 31 - (header % 31); + + putShortMSB(s, header); + + /* Save the adler32 of the preset dictionary: */ + if (s->strstart != 0) { + putShortMSB(s, (uInt)(strm->adler >> 16)); + putShortMSB(s, (uInt)(strm->adler & 0xffff)); + } + strm->adler = adler32(0L, Z_NULL, 0); + s->status = BUSY_STATE; + + /* Compression must start with an empty pending buffer */ + flush_pending(strm); + if (s->pending != 0) { + s->last_flush = -1; + return Z_OK; + } + } +#ifdef GZIP + if (s->status == GZIP_STATE) { + /* gzip header */ + strm->adler = crc32(0L, Z_NULL, 0); + put_byte(s, 31); + put_byte(s, 139); + put_byte(s, 8); + if (s->gzhead == Z_NULL) { + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, s->level == 9 ? 2 : + (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? + 4 : 0)); + put_byte(s, OS_CODE); + s->status = BUSY_STATE; + + /* Compression must start with an empty pending buffer */ + flush_pending(strm); + if (s->pending != 0) { + s->last_flush = -1; + return Z_OK; + } + } + else { + put_byte(s, (s->gzhead->text ? 1 : 0) + + (s->gzhead->hcrc ? 2 : 0) + + (s->gzhead->extra == Z_NULL ? 0 : 4) + + (s->gzhead->name == Z_NULL ? 0 : 8) + + (s->gzhead->comment == Z_NULL ? 0 : 16) + ); + put_byte(s, (Byte)(s->gzhead->time & 0xff)); + put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff)); + put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff)); + put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff)); + put_byte(s, s->level == 9 ? 2 : + (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? + 4 : 0)); + put_byte(s, s->gzhead->os & 0xff); + if (s->gzhead->extra != Z_NULL) { + put_byte(s, s->gzhead->extra_len & 0xff); + put_byte(s, (s->gzhead->extra_len >> 8) & 0xff); + } + if (s->gzhead->hcrc) + strm->adler = crc32(strm->adler, s->pending_buf, + s->pending); + s->gzindex = 0; + s->status = EXTRA_STATE; + } + } + if (s->status == EXTRA_STATE) { + if (s->gzhead->extra != Z_NULL) { + ulg beg = s->pending; /* start of bytes to update crc */ + uInt left = (s->gzhead->extra_len & 0xffff) - s->gzindex; + while (s->pending + left > s->pending_buf_size) { + uInt copy = s->pending_buf_size - s->pending; + zmemcpy(s->pending_buf + s->pending, + s->gzhead->extra + s->gzindex, copy); + s->pending = s->pending_buf_size; + HCRC_UPDATE(beg); + s->gzindex += copy; + flush_pending(strm); + if (s->pending != 0) { + s->last_flush = -1; + return Z_OK; + } + beg = 0; + left -= copy; + } + zmemcpy(s->pending_buf + s->pending, + s->gzhead->extra + s->gzindex, left); + s->pending += left; + HCRC_UPDATE(beg); + s->gzindex = 0; + } + s->status = NAME_STATE; + } + if (s->status == NAME_STATE) { + if (s->gzhead->name != Z_NULL) { + ulg beg = s->pending; /* start of bytes to update crc */ + int val; + do { + if (s->pending == s->pending_buf_size) { + HCRC_UPDATE(beg); + flush_pending(strm); + if (s->pending != 0) { + s->last_flush = -1; + return Z_OK; + } + beg = 0; + } + val = s->gzhead->name[s->gzindex++]; + put_byte(s, val); + } while (val != 0); + HCRC_UPDATE(beg); + s->gzindex = 0; + } + s->status = COMMENT_STATE; + } + if (s->status == COMMENT_STATE) { + if (s->gzhead->comment != Z_NULL) { + ulg beg = s->pending; /* start of bytes to update crc */ + int val; + do { + if (s->pending == s->pending_buf_size) { + HCRC_UPDATE(beg); + flush_pending(strm); + if (s->pending != 0) { + s->last_flush = -1; + return Z_OK; + } + beg = 0; + } + val = s->gzhead->comment[s->gzindex++]; + put_byte(s, val); + } while (val != 0); + HCRC_UPDATE(beg); + } + s->status = HCRC_STATE; + } + if (s->status == HCRC_STATE) { + if (s->gzhead->hcrc) { + if (s->pending + 2 > s->pending_buf_size) { + flush_pending(strm); + if (s->pending != 0) { + s->last_flush = -1; + return Z_OK; + } + } + put_byte(s, (Byte)(strm->adler & 0xff)); + put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); + strm->adler = crc32(0L, Z_NULL, 0); + } + s->status = BUSY_STATE; + + /* Compression must start with an empty pending buffer */ + flush_pending(strm); + if (s->pending != 0) { + s->last_flush = -1; + return Z_OK; + } + } +#endif + + /* Start a new block or continue the current one. + */ + if (strm->avail_in != 0 || s->lookahead != 0 || + (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { + block_state bstate; + + bstate = s->level == 0 ? deflate_stored(s, flush) : + s->strategy == Z_HUFFMAN_ONLY ? deflate_huff(s, flush) : + s->strategy == Z_RLE ? deflate_rle(s, flush) : + (*(configuration_table[s->level].func))(s, flush); + + if (bstate == finish_started || bstate == finish_done) { + s->status = FINISH_STATE; + } + if (bstate == need_more || bstate == finish_started) { + if (strm->avail_out == 0) { + s->last_flush = -1; /* avoid BUF_ERROR next call, see above */ + } + return Z_OK; + /* If flush != Z_NO_FLUSH && avail_out == 0, the next call + * of deflate should use the same flush parameter to make sure + * that the flush is complete. So we don't have to output an + * empty block here, this will be done at next call. This also + * ensures that for a very small output buffer, we emit at most + * one empty block. + */ + } + if (bstate == block_done) { + if (flush == Z_PARTIAL_FLUSH) { + _tr_align(s); + } else if (flush != Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */ + _tr_stored_block(s, (char*)0, 0L, 0); + /* For a full flush, this empty block will be recognized + * as a special marker by inflate_sync(). + */ + if (flush == Z_FULL_FLUSH) { + CLEAR_HASH(s); /* forget history */ + if (s->lookahead == 0) { + s->strstart = 0; + s->block_start = 0L; + s->insert = 0; + } + } + } + flush_pending(strm); + if (strm->avail_out == 0) { + s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */ + return Z_OK; + } + } + } + + if (flush != Z_FINISH) return Z_OK; + if (s->wrap <= 0) return Z_STREAM_END; + + /* Write the trailer */ +#ifdef GZIP + if (s->wrap == 2) { + put_byte(s, (Byte)(strm->adler & 0xff)); + put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); + put_byte(s, (Byte)((strm->adler >> 16) & 0xff)); + put_byte(s, (Byte)((strm->adler >> 24) & 0xff)); + put_byte(s, (Byte)(strm->total_in & 0xff)); + put_byte(s, (Byte)((strm->total_in >> 8) & 0xff)); + put_byte(s, (Byte)((strm->total_in >> 16) & 0xff)); + put_byte(s, (Byte)((strm->total_in >> 24) & 0xff)); + } + else +#endif + { + putShortMSB(s, (uInt)(strm->adler >> 16)); + putShortMSB(s, (uInt)(strm->adler & 0xffff)); + } + flush_pending(strm); + /* If avail_out is zero, the application will call deflate again + * to flush the rest. + */ + if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */ + return s->pending != 0 ? Z_OK : Z_STREAM_END; +} + +/* ========================================================================= */ +int ZEXPORT deflateEnd(z_streamp strm) { + int status; + + if (deflateStateCheck(strm)) return Z_STREAM_ERROR; + + status = strm->state->status; + + /* Deallocate in reverse order of allocations: */ + TRY_FREE(strm, strm->state->pending_buf); + TRY_FREE(strm, strm->state->head); + TRY_FREE(strm, strm->state->prev); + TRY_FREE(strm, strm->state->window); + + ZFREE(strm, strm->state); + strm->state = Z_NULL; + + return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; +} + +/* ========================================================================= + * Copy the source state to the destination state. + * To simplify the source, this is not supported for 16-bit MSDOS (which + * doesn't have enough memory anyway to duplicate compression states). + */ +int ZEXPORT deflateCopy(z_streamp dest, z_streamp source) { +#ifdef MAXSEG_64K + (void)dest; + (void)source; + return Z_STREAM_ERROR; +#else + deflate_state *ds; + deflate_state *ss; + + + if (deflateStateCheck(source) || dest == Z_NULL) { + return Z_STREAM_ERROR; + } + + ss = source->state; + + zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream)); + + ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state)); + if (ds == Z_NULL) return Z_MEM_ERROR; + dest->state = (struct internal_state FAR *) ds; + zmemcpy((voidpf)ds, (voidpf)ss, sizeof(deflate_state)); + ds->strm = dest; + + ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); + ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos)); + ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos)); + ds->pending_buf = (uchf *) ZALLOC(dest, ds->lit_bufsize, LIT_BUFS); + + if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL || + ds->pending_buf == Z_NULL) { + deflateEnd (dest); + return Z_MEM_ERROR; + } + /* following zmemcpy do not work for 16-bit MSDOS */ + zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte)); + zmemcpy((voidpf)ds->prev, (voidpf)ss->prev, ds->w_size * sizeof(Pos)); + zmemcpy((voidpf)ds->head, (voidpf)ss->head, ds->hash_size * sizeof(Pos)); + zmemcpy(ds->pending_buf, ss->pending_buf, ds->lit_bufsize * LIT_BUFS); + + ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); +#ifdef LIT_MEM + ds->d_buf = (ushf *)(ds->pending_buf + (ds->lit_bufsize << 1)); + ds->l_buf = ds->pending_buf + (ds->lit_bufsize << 2); +#else + ds->sym_buf = ds->pending_buf + ds->lit_bufsize; +#endif + + ds->l_desc.dyn_tree = ds->dyn_ltree; + ds->d_desc.dyn_tree = ds->dyn_dtree; + ds->bl_desc.dyn_tree = ds->bl_tree; + + return Z_OK; +#endif /* MAXSEG_64K */ +} + +#ifndef FASTEST +/* =========================================================================== + * Set match_start to the longest match starting at the given string and + * return its length. Matches shorter or equal to prev_length are discarded, + * in which case the result is equal to prev_length and match_start is + * garbage. + * IN assertions: cur_match is the head of the hash chain for the current + * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 + * OUT assertion: the match length is not greater than s->lookahead. + */ +local uInt longest_match(deflate_state *s, IPos cur_match) { + unsigned chain_length = s->max_chain_length;/* max hash chain length */ + register Bytef *scan = s->window + s->strstart; /* current string */ + register Bytef *match; /* matched string */ + register int len; /* length of current match */ + int best_len = (int)s->prev_length; /* best match length so far */ + int nice_match = s->nice_match; /* stop if match long enough */ + IPos limit = s->strstart > (IPos)MAX_DIST(s) ? + s->strstart - (IPos)MAX_DIST(s) : NIL; + /* Stop when cur_match becomes <= limit. To simplify the code, + * we prevent matches with the string of window index 0. + */ + Posf *prev = s->prev; + uInt wmask = s->w_mask; + +#ifdef UNALIGNED_OK + /* Compare two bytes at a time. Note: this is not always beneficial. + * Try with and without -DUNALIGNED_OK to check. + */ + register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; + register ush scan_start = *(ushf*)scan; + register ush scan_end = *(ushf*)(scan + best_len - 1); +#else + register Bytef *strend = s->window + s->strstart + MAX_MATCH; + register Byte scan_end1 = scan[best_len - 1]; + register Byte scan_end = scan[best_len]; +#endif + + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + * It is easy to get rid of this optimization if necessary. + */ + Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); + + /* Do not waste too much time if we already have a good match: */ + if (s->prev_length >= s->good_match) { + chain_length >>= 2; + } + /* Do not look for matches beyond the end of the input. This is necessary + * to make deflate deterministic. + */ + if ((uInt)nice_match > s->lookahead) nice_match = (int)s->lookahead; + + Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD, + "need lookahead"); + + do { + Assert(cur_match < s->strstart, "no future"); + match = s->window + cur_match; + + /* Skip to next match if the match length cannot increase + * or if the match length is less than 2. Note that the checks below + * for insufficient lookahead only occur occasionally for performance + * reasons. Therefore uninitialized memory will be accessed, and + * conditional jumps will be made that depend on those values. + * However the length of the match is limited to the lookahead, so + * the output of deflate is not affected by the uninitialized values. + */ +#if (defined(UNALIGNED_OK) && MAX_MATCH == 258) + /* This code assumes sizeof(unsigned short) == 2. Do not use + * UNALIGNED_OK if your compiler uses a different size. + */ + if (*(ushf*)(match + best_len - 1) != scan_end || + *(ushf*)match != scan_start) continue; + + /* It is not necessary to compare scan[2] and match[2] since they are + * always equal when the other bytes match, given that the hash keys + * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at + * strstart + 3, + 5, up to strstart + 257. We check for insufficient + * lookahead only every 4th comparison; the 128th check will be made + * at strstart + 257. If MAX_MATCH-2 is not a multiple of 8, it is + * necessary to put more guard bytes at the end of the window, or + * to check more often for insufficient lookahead. + */ + Assert(scan[2] == match[2], "scan[2]?"); + scan++, match++; + do { + } while (*(ushf*)(scan += 2) == *(ushf*)(match += 2) && + *(ushf*)(scan += 2) == *(ushf*)(match += 2) && + *(ushf*)(scan += 2) == *(ushf*)(match += 2) && + *(ushf*)(scan += 2) == *(ushf*)(match += 2) && + scan < strend); + /* The funny "do {}" generates better code on most compilers */ + + /* Here, scan <= window + strstart + 257 */ + Assert(scan <= s->window + (unsigned)(s->window_size - 1), + "wild scan"); + if (*scan == *match) scan++; + + len = (MAX_MATCH - 1) - (int)(strend - scan); + scan = strend - (MAX_MATCH-1); + +#else /* UNALIGNED_OK */ + + if (match[best_len] != scan_end || + match[best_len - 1] != scan_end1 || + *match != *scan || + *++match != scan[1]) continue; + + /* The check at best_len - 1 can be removed because it will be made + * again later. (This heuristic is not always a win.) + * It is not necessary to compare scan[2] and match[2] since they + * are always equal when the other bytes match, given that + * the hash keys are equal and that HASH_BITS >= 8. + */ + scan += 2, match++; + Assert(*scan == *match, "match[2]?"); + + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart + 258. + */ + do { + } while (*++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + scan < strend); + + Assert(scan <= s->window + (unsigned)(s->window_size - 1), + "wild scan"); + + len = MAX_MATCH - (int)(strend - scan); + scan = strend - MAX_MATCH; + +#endif /* UNALIGNED_OK */ + + if (len > best_len) { + s->match_start = cur_match; + best_len = len; + if (len >= nice_match) break; +#ifdef UNALIGNED_OK + scan_end = *(ushf*)(scan + best_len - 1); +#else + scan_end1 = scan[best_len - 1]; + scan_end = scan[best_len]; +#endif + } + } while ((cur_match = prev[cur_match & wmask]) > limit + && --chain_length != 0); + + if ((uInt)best_len <= s->lookahead) return (uInt)best_len; + return s->lookahead; +} + +#else /* FASTEST */ + +/* --------------------------------------------------------------------------- + * Optimized version for FASTEST only + */ +local uInt longest_match(deflate_state *s, IPos cur_match) { + register Bytef *scan = s->window + s->strstart; /* current string */ + register Bytef *match; /* matched string */ + register int len; /* length of current match */ + register Bytef *strend = s->window + s->strstart + MAX_MATCH; + + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + * It is easy to get rid of this optimization if necessary. + */ + Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); + + Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD, + "need lookahead"); + + Assert(cur_match < s->strstart, "no future"); + + match = s->window + cur_match; + + /* Return failure if the match length is less than 2: + */ + if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1; + + /* The check at best_len - 1 can be removed because it will be made + * again later. (This heuristic is not always a win.) + * It is not necessary to compare scan[2] and match[2] since they + * are always equal when the other bytes match, given that + * the hash keys are equal and that HASH_BITS >= 8. + */ + scan += 2, match += 2; + Assert(*scan == *match, "match[2]?"); + + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart + 258. + */ + do { + } while (*++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + scan < strend); + + Assert(scan <= s->window + (unsigned)(s->window_size - 1), "wild scan"); + + len = MAX_MATCH - (int)(strend - scan); + + if (len < MIN_MATCH) return MIN_MATCH - 1; + + s->match_start = cur_match; + return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead; +} + +#endif /* FASTEST */ + +#ifdef ZLIB_DEBUG + +#define EQUAL 0 +/* result of memcmp for equal strings */ + +/* =========================================================================== + * Check that the match at match_start is indeed a match. + */ +local void check_match(deflate_state *s, IPos start, IPos match, int length) { + /* check that the match is indeed a match */ + Bytef *back = s->window + (int)match, *here = s->window + start; + IPos len = length; + if (match == (IPos)-1) { + /* match starts one byte before the current window -- just compare the + subsequent length-1 bytes */ + back++; + here++; + len--; + } + if (zmemcmp(back, here, len) != EQUAL) { + fprintf(stderr, " start %u, match %d, length %d\n", + start, (int)match, length); + do { + fprintf(stderr, "(%02x %02x)", *back++, *here++); + } while (--len != 0); + z_error("invalid match"); + } + if (z_verbose > 1) { + fprintf(stderr,"\\[%d,%d]", start - match, length); + do { putc(s->window[start++], stderr); } while (--length != 0); + } +} +#else +# define check_match(s, start, match, length) +#endif /* ZLIB_DEBUG */ + +/* =========================================================================== + * Flush the current block, with given end-of-file flag. + * IN assertion: strstart is set to the end of the current match. + */ +#define FLUSH_BLOCK_ONLY(s, last) { \ + _tr_flush_block(s, (s->block_start >= 0L ? \ + (charf *)&s->window[(unsigned)s->block_start] : \ + (charf *)Z_NULL), \ + (ulg)((long)s->strstart - s->block_start), \ + (last)); \ + s->block_start = s->strstart; \ + flush_pending(s->strm); \ + Tracev((stderr,"[FLUSH]")); \ +} + +/* Same but force premature exit if necessary. */ +#define FLUSH_BLOCK(s, last) { \ + FLUSH_BLOCK_ONLY(s, last); \ + if (s->strm->avail_out == 0) return (last) ? finish_started : need_more; \ +} + +/* Maximum stored block length in deflate format (not including header). */ +#define MAX_STORED 65535 + +/* Minimum of a and b. */ +#define MIN(a, b) ((a) > (b) ? (b) : (a)) + +/* =========================================================================== + * Copy without compression as much as possible from the input stream, return + * the current block state. + * + * In case deflateParams() is used to later switch to a non-zero compression + * level, s->matches (otherwise unused when storing) keeps track of the number + * of hash table slides to perform. If s->matches is 1, then one hash table + * slide will be done when switching. If s->matches is 2, the maximum value + * allowed here, then the hash table will be cleared, since two or more slides + * is the same as a clear. + * + * deflate_stored() is written to minimize the number of times an input byte is + * copied. It is most efficient with large input and output buffers, which + * maximizes the opportunities to have a single copy from next_in to next_out. + */ +local block_state deflate_stored(deflate_state *s, int flush) { + /* Smallest worthy block size when not flushing or finishing. By default + * this is 32K. This can be as small as 507 bytes for memLevel == 1. For + * large input and output buffers, the stored block size will be larger. + */ + unsigned min_block = MIN(s->pending_buf_size - 5, s->w_size); + + /* Copy as many min_block or larger stored blocks directly to next_out as + * possible. If flushing, copy the remaining available input to next_out as + * stored blocks, if there is enough space. + */ + unsigned len, left, have, last = 0; + unsigned used = s->strm->avail_in; + do { + /* Set len to the maximum size block that we can copy directly with the + * available input data and output space. Set left to how much of that + * would be copied from what's left in the window. + */ + len = MAX_STORED; /* maximum deflate stored block length */ + have = (s->bi_valid + 42) >> 3; /* number of header bytes */ + if (s->strm->avail_out < have) /* need room for header */ + break; + /* maximum stored block length that will fit in avail_out: */ + have = s->strm->avail_out - have; + left = s->strstart - s->block_start; /* bytes left in window */ + if (len > (ulg)left + s->strm->avail_in) + len = left + s->strm->avail_in; /* limit len to the input */ + if (len > have) + len = have; /* limit len to the output */ + + /* If the stored block would be less than min_block in length, or if + * unable to copy all of the available input when flushing, then try + * copying to the window and the pending buffer instead. Also don't + * write an empty block when flushing -- deflate() does that. + */ + if (len < min_block && ((len == 0 && flush != Z_FINISH) || + flush == Z_NO_FLUSH || + len != left + s->strm->avail_in)) + break; + + /* Make a dummy stored block in pending to get the header bytes, + * including any pending bits. This also updates the debugging counts. + */ + last = flush == Z_FINISH && len == left + s->strm->avail_in ? 1 : 0; + _tr_stored_block(s, (char *)0, 0L, last); + + /* Replace the lengths in the dummy stored block with len. */ + s->pending_buf[s->pending - 4] = len; + s->pending_buf[s->pending - 3] = len >> 8; + s->pending_buf[s->pending - 2] = ~len; + s->pending_buf[s->pending - 1] = ~len >> 8; + + /* Write the stored block header bytes. */ + flush_pending(s->strm); + +#ifdef ZLIB_DEBUG + /* Update debugging counts for the data about to be copied. */ + s->compressed_len += len << 3; + s->bits_sent += len << 3; +#endif + + /* Copy uncompressed bytes from the window to next_out. */ + if (left) { + if (left > len) + left = len; + zmemcpy(s->strm->next_out, s->window + s->block_start, left); + s->strm->next_out += left; + s->strm->avail_out -= left; + s->strm->total_out += left; + s->block_start += left; + len -= left; + } + + /* Copy uncompressed bytes directly from next_in to next_out, updating + * the check value. + */ + if (len) { + read_buf(s->strm, s->strm->next_out, len); + s->strm->next_out += len; + s->strm->avail_out -= len; + s->strm->total_out += len; + } + } while (last == 0); + + /* Update the sliding window with the last s->w_size bytes of the copied + * data, or append all of the copied data to the existing window if less + * than s->w_size bytes were copied. Also update the number of bytes to + * insert in the hash tables, in the event that deflateParams() switches to + * a non-zero compression level. + */ + used -= s->strm->avail_in; /* number of input bytes directly copied */ + if (used) { + /* If any input was used, then no unused input remains in the window, + * therefore s->block_start == s->strstart. + */ + if (used >= s->w_size) { /* supplant the previous history */ + s->matches = 2; /* clear hash */ + zmemcpy(s->window, s->strm->next_in - s->w_size, s->w_size); + s->strstart = s->w_size; + s->insert = s->strstart; + } + else { + if (s->window_size - s->strstart <= used) { + /* Slide the window down. */ + s->strstart -= s->w_size; + zmemcpy(s->window, s->window + s->w_size, s->strstart); + if (s->matches < 2) + s->matches++; /* add a pending slide_hash() */ + if (s->insert > s->strstart) + s->insert = s->strstart; + } + zmemcpy(s->window + s->strstart, s->strm->next_in - used, used); + s->strstart += used; + s->insert += MIN(used, s->w_size - s->insert); + } + s->block_start = s->strstart; + } + if (s->high_water < s->strstart) + s->high_water = s->strstart; + + /* If the last block was written to next_out, then done. */ + if (last) + return finish_done; + + /* If flushing and all input has been consumed, then done. */ + if (flush != Z_NO_FLUSH && flush != Z_FINISH && + s->strm->avail_in == 0 && (long)s->strstart == s->block_start) + return block_done; + + /* Fill the window with any remaining input. */ + have = s->window_size - s->strstart; + if (s->strm->avail_in > have && s->block_start >= (long)s->w_size) { + /* Slide the window down. */ + s->block_start -= s->w_size; + s->strstart -= s->w_size; + zmemcpy(s->window, s->window + s->w_size, s->strstart); + if (s->matches < 2) + s->matches++; /* add a pending slide_hash() */ + have += s->w_size; /* more space now */ + if (s->insert > s->strstart) + s->insert = s->strstart; + } + if (have > s->strm->avail_in) + have = s->strm->avail_in; + if (have) { + read_buf(s->strm, s->window + s->strstart, have); + s->strstart += have; + s->insert += MIN(have, s->w_size - s->insert); + } + if (s->high_water < s->strstart) + s->high_water = s->strstart; + + /* There was not enough avail_out to write a complete worthy or flushed + * stored block to next_out. Write a stored block to pending instead, if we + * have enough input for a worthy block, or if flushing and there is enough + * room for the remaining input as a stored block in the pending buffer. + */ + have = (s->bi_valid + 42) >> 3; /* number of header bytes */ + /* maximum stored block length that will fit in pending: */ + have = MIN(s->pending_buf_size - have, MAX_STORED); + min_block = MIN(have, s->w_size); + left = s->strstart - s->block_start; + if (left >= min_block || + ((left || flush == Z_FINISH) && flush != Z_NO_FLUSH && + s->strm->avail_in == 0 && left <= have)) { + len = MIN(left, have); + last = flush == Z_FINISH && s->strm->avail_in == 0 && + len == left ? 1 : 0; + _tr_stored_block(s, (charf *)s->window + s->block_start, len, last); + s->block_start += len; + flush_pending(s->strm); + } + + /* We've done all we can with the available input and output. */ + return last ? finish_started : need_more; +} + +/* =========================================================================== + * Compress as much as possible from the input stream, return the current + * block state. + * This function does not perform lazy evaluation of matches and inserts + * new strings in the dictionary only for unmatched strings or for short + * matches. It is used only for the fast compression options. + */ +local block_state deflate_fast(deflate_state *s, int flush) { + IPos hash_head; /* head of the hash chain */ + int bflush; /* set if current block must be flushed */ + + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s->lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* Insert the string window[strstart .. strstart + 2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + hash_head = NIL; + if (s->lookahead >= MIN_MATCH) { + INSERT_STRING(s, s->strstart, hash_head); + } + + /* Find the longest match, discarding those <= prev_length. + * At this point we have always match_length < MIN_MATCH + */ + if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + s->match_length = longest_match (s, hash_head); + /* longest_match() sets match_start */ + } + if (s->match_length >= MIN_MATCH) { + check_match(s, s->strstart, s->match_start, s->match_length); + + _tr_tally_dist(s, s->strstart - s->match_start, + s->match_length - MIN_MATCH, bflush); + + s->lookahead -= s->match_length; + + /* Insert new strings in the hash table only if the match length + * is not too large. This saves time but degrades compression. + */ +#ifndef FASTEST + if (s->match_length <= s->max_insert_length && + s->lookahead >= MIN_MATCH) { + s->match_length--; /* string at strstart already in table */ + do { + s->strstart++; + INSERT_STRING(s, s->strstart, hash_head); + /* strstart never exceeds WSIZE-MAX_MATCH, so there are + * always MIN_MATCH bytes ahead. + */ + } while (--s->match_length != 0); + s->strstart++; + } else +#endif + { + s->strstart += s->match_length; + s->match_length = 0; + s->ins_h = s->window[s->strstart]; + UPDATE_HASH(s, s->ins_h, s->window[s->strstart + 1]); +#if MIN_MATCH != 3 + Call UPDATE_HASH() MIN_MATCH-3 more times +#endif + /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not + * matter since it will be recomputed at next deflate call. + */ + } + } else { + /* No match, output a literal byte */ + Tracevv((stderr,"%c", s->window[s->strstart])); + _tr_tally_lit(s, s->window[s->strstart], bflush); + s->lookahead--; + s->strstart++; + } + if (bflush) FLUSH_BLOCK(s, 0); + } + s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1; + if (flush == Z_FINISH) { + FLUSH_BLOCK(s, 1); + return finish_done; + } + if (s->sym_next) + FLUSH_BLOCK(s, 0); + return block_done; +} + +#ifndef FASTEST +/* =========================================================================== + * Same as above, but achieves better compression. We use a lazy + * evaluation for matches: a match is finally adopted only if there is + * no better match at the next window position. + */ +local block_state deflate_slow(deflate_state *s, int flush) { + IPos hash_head; /* head of hash chain */ + int bflush; /* set if current block must be flushed */ + + /* Process the input block. */ + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s->lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* Insert the string window[strstart .. strstart + 2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + hash_head = NIL; + if (s->lookahead >= MIN_MATCH) { + INSERT_STRING(s, s->strstart, hash_head); + } + + /* Find the longest match, discarding those <= prev_length. + */ + s->prev_length = s->match_length, s->prev_match = s->match_start; + s->match_length = MIN_MATCH-1; + + if (hash_head != NIL && s->prev_length < s->max_lazy_match && + s->strstart - hash_head <= MAX_DIST(s)) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + s->match_length = longest_match (s, hash_head); + /* longest_match() sets match_start */ + + if (s->match_length <= 5 && (s->strategy == Z_FILTERED +#if TOO_FAR <= 32767 + || (s->match_length == MIN_MATCH && + s->strstart - s->match_start > TOO_FAR) +#endif + )) { + + /* If prev_match is also MIN_MATCH, match_start is garbage + * but we will ignore the current match anyway. + */ + s->match_length = MIN_MATCH-1; + } + } + /* If there was a match at the previous step and the current + * match is not better, output the previous match: + */ + if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) { + uInt max_insert = s->strstart + s->lookahead - MIN_MATCH; + /* Do not insert strings in hash table beyond this. */ + + check_match(s, s->strstart - 1, s->prev_match, s->prev_length); + + _tr_tally_dist(s, s->strstart - 1 - s->prev_match, + s->prev_length - MIN_MATCH, bflush); + + /* Insert in hash table all strings up to the end of the match. + * strstart - 1 and strstart are already inserted. If there is not + * enough lookahead, the last two strings are not inserted in + * the hash table. + */ + s->lookahead -= s->prev_length - 1; + s->prev_length -= 2; + do { + if (++s->strstart <= max_insert) { + INSERT_STRING(s, s->strstart, hash_head); + } + } while (--s->prev_length != 0); + s->match_available = 0; + s->match_length = MIN_MATCH-1; + s->strstart++; + + if (bflush) FLUSH_BLOCK(s, 0); + + } else if (s->match_available) { + /* If there was no match at the previous position, output a + * single literal. If there was a match but the current match + * is longer, truncate the previous match to a single literal. + */ + Tracevv((stderr,"%c", s->window[s->strstart - 1])); + _tr_tally_lit(s, s->window[s->strstart - 1], bflush); + if (bflush) { + FLUSH_BLOCK_ONLY(s, 0); + } + s->strstart++; + s->lookahead--; + if (s->strm->avail_out == 0) return need_more; + } else { + /* There is no previous match to compare with, wait for + * the next step to decide. + */ + s->match_available = 1; + s->strstart++; + s->lookahead--; + } + } + Assert (flush != Z_NO_FLUSH, "no flush?"); + if (s->match_available) { + Tracevv((stderr,"%c", s->window[s->strstart - 1])); + _tr_tally_lit(s, s->window[s->strstart - 1], bflush); + s->match_available = 0; + } + s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1; + if (flush == Z_FINISH) { + FLUSH_BLOCK(s, 1); + return finish_done; + } + if (s->sym_next) + FLUSH_BLOCK(s, 0); + return block_done; +} +#endif /* FASTEST */ + +/* =========================================================================== + * For Z_RLE, simply look for runs of bytes, generate matches only of distance + * one. Do not maintain a hash table. (It will be regenerated if this run of + * deflate switches away from Z_RLE.) + */ +local block_state deflate_rle(deflate_state *s, int flush) { + int bflush; /* set if current block must be flushed */ + uInt prev; /* byte at distance one to match */ + Bytef *scan, *strend; /* scan goes up to strend for length of run */ + + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the longest run, plus one for the unrolled loop. + */ + if (s->lookahead <= MAX_MATCH) { + fill_window(s); + if (s->lookahead <= MAX_MATCH && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* See how many times the previous byte repeats */ + s->match_length = 0; + if (s->lookahead >= MIN_MATCH && s->strstart > 0) { + scan = s->window + s->strstart - 1; + prev = *scan; + if (prev == *++scan && prev == *++scan && prev == *++scan) { + strend = s->window + s->strstart + MAX_MATCH; + do { + } while (prev == *++scan && prev == *++scan && + prev == *++scan && prev == *++scan && + prev == *++scan && prev == *++scan && + prev == *++scan && prev == *++scan && + scan < strend); + s->match_length = MAX_MATCH - (uInt)(strend - scan); + if (s->match_length > s->lookahead) + s->match_length = s->lookahead; + } + Assert(scan <= s->window + (uInt)(s->window_size - 1), + "wild scan"); + } + + /* Emit match if have run of MIN_MATCH or longer, else emit literal */ + if (s->match_length >= MIN_MATCH) { + check_match(s, s->strstart, s->strstart - 1, s->match_length); + + _tr_tally_dist(s, 1, s->match_length - MIN_MATCH, bflush); + + s->lookahead -= s->match_length; + s->strstart += s->match_length; + s->match_length = 0; + } else { + /* No match, output a literal byte */ + Tracevv((stderr,"%c", s->window[s->strstart])); + _tr_tally_lit(s, s->window[s->strstart], bflush); + s->lookahead--; + s->strstart++; + } + if (bflush) FLUSH_BLOCK(s, 0); + } + s->insert = 0; + if (flush == Z_FINISH) { + FLUSH_BLOCK(s, 1); + return finish_done; + } + if (s->sym_next) + FLUSH_BLOCK(s, 0); + return block_done; +} + +/* =========================================================================== + * For Z_HUFFMAN_ONLY, do not look for matches. Do not maintain a hash table. + * (It will be regenerated if this run of deflate switches away from Huffman.) + */ +local block_state deflate_huff(deflate_state *s, int flush) { + int bflush; /* set if current block must be flushed */ + + for (;;) { + /* Make sure that we have a literal to write. */ + if (s->lookahead == 0) { + fill_window(s); + if (s->lookahead == 0) { + if (flush == Z_NO_FLUSH) + return need_more; + break; /* flush the current block */ + } + } + + /* Output a literal byte */ + s->match_length = 0; + Tracevv((stderr,"%c", s->window[s->strstart])); + _tr_tally_lit(s, s->window[s->strstart], bflush); + s->lookahead--; + s->strstart++; + if (bflush) FLUSH_BLOCK(s, 0); + } + s->insert = 0; + if (flush == Z_FINISH) { + FLUSH_BLOCK(s, 1); + return finish_done; + } + if (s->sym_next) + FLUSH_BLOCK(s, 0); + return block_done; +} diff --git a/common/zlib/deflate.h b/common/zlib/deflate.h new file mode 100644 index 0000000..300c6ad --- /dev/null +++ b/common/zlib/deflate.h @@ -0,0 +1,377 @@ +/* deflate.h -- internal compression state + * Copyright (C) 1995-2024 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* @(#) $Id$ */ + +#ifndef DEFLATE_H +#define DEFLATE_H + +#include "zutil.h" + +/* define NO_GZIP when compiling if you want to disable gzip header and + trailer creation by deflate(). NO_GZIP would be used to avoid linking in + the crc code when it is not needed. For shared libraries, gzip encoding + should be left enabled. */ +#ifndef NO_GZIP +# define GZIP +#endif + +/* define LIT_MEM to slightly increase the speed of deflate (order 1% to 2%) at + the cost of a larger memory footprint */ +/* #define LIT_MEM */ + +/* =========================================================================== + * Internal compression state. + */ + +#define LENGTH_CODES 29 +/* number of length codes, not counting the special END_BLOCK code */ + +#define LITERALS 256 +/* number of literal bytes 0..255 */ + +#define L_CODES (LITERALS+1+LENGTH_CODES) +/* number of Literal or Length codes, including the END_BLOCK code */ + +#define D_CODES 30 +/* number of distance codes */ + +#define BL_CODES 19 +/* number of codes used to transfer the bit lengths */ + +#define HEAP_SIZE (2*L_CODES+1) +/* maximum heap size */ + +#define MAX_BITS 15 +/* All codes must not exceed MAX_BITS bits */ + +#define Buf_size 16 +/* size of bit buffer in bi_buf */ + +#define INIT_STATE 42 /* zlib header -> BUSY_STATE */ +#ifdef GZIP +# define GZIP_STATE 57 /* gzip header -> BUSY_STATE | EXTRA_STATE */ +#endif +#define EXTRA_STATE 69 /* gzip extra block -> NAME_STATE */ +#define NAME_STATE 73 /* gzip file name -> COMMENT_STATE */ +#define COMMENT_STATE 91 /* gzip comment -> HCRC_STATE */ +#define HCRC_STATE 103 /* gzip header CRC -> BUSY_STATE */ +#define BUSY_STATE 113 /* deflate -> FINISH_STATE */ +#define FINISH_STATE 666 /* stream complete */ +/* Stream status */ + + +/* Data structure describing a single value and its code string. */ +typedef struct ct_data_s { + union { + ush freq; /* frequency count */ + ush code; /* bit string */ + } fc; + union { + ush dad; /* father node in Huffman tree */ + ush len; /* length of bit string */ + } dl; +} FAR ct_data; + +#define Freq fc.freq +#define Code fc.code +#define Dad dl.dad +#define Len dl.len + +typedef struct static_tree_desc_s static_tree_desc; + +typedef struct tree_desc_s { + ct_data *dyn_tree; /* the dynamic tree */ + int max_code; /* largest code with non zero frequency */ + const static_tree_desc *stat_desc; /* the corresponding static tree */ +} FAR tree_desc; + +typedef ush Pos; +typedef Pos FAR Posf; +typedef unsigned IPos; + +/* A Pos is an index in the character window. We use short instead of int to + * save space in the various tables. IPos is used only for parameter passing. + */ + +typedef struct internal_state { + z_streamp strm; /* pointer back to this zlib stream */ + int status; /* as the name implies */ + Bytef *pending_buf; /* output still pending */ + ulg pending_buf_size; /* size of pending_buf */ + Bytef *pending_out; /* next pending byte to output to the stream */ + ulg pending; /* nb of bytes in the pending buffer */ + int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ + gz_headerp gzhead; /* gzip header information to write */ + ulg gzindex; /* where in extra, name, or comment */ + Byte method; /* can only be DEFLATED */ + int last_flush; /* value of flush param for previous deflate call */ + + /* used by deflate.c: */ + + uInt w_size; /* LZ77 window size (32K by default) */ + uInt w_bits; /* log2(w_size) (8..16) */ + uInt w_mask; /* w_size - 1 */ + + Bytef *window; + /* Sliding window. Input bytes are read into the second half of the window, + * and move to the first half later to keep a dictionary of at least wSize + * bytes. With this organization, matches are limited to a distance of + * wSize-MAX_MATCH bytes, but this ensures that IO is always + * performed with a length multiple of the block size. Also, it limits + * the window size to 64K, which is quite useful on MSDOS. + * To do: use the user input buffer as sliding window. + */ + + ulg window_size; + /* Actual size of window: 2*wSize, except when the user input buffer + * is directly used as sliding window. + */ + + Posf *prev; + /* Link to older string with same hash index. To limit the size of this + * array to 64K, this link is maintained only for the last 32K strings. + * An index in this array is thus a window index modulo 32K. + */ + + Posf *head; /* Heads of the hash chains or NIL. */ + + uInt ins_h; /* hash index of string to be inserted */ + uInt hash_size; /* number of elements in hash table */ + uInt hash_bits; /* log2(hash_size) */ + uInt hash_mask; /* hash_size-1 */ + + uInt hash_shift; + /* Number of bits by which ins_h must be shifted at each input + * step. It must be such that after MIN_MATCH steps, the oldest + * byte no longer takes part in the hash key, that is: + * hash_shift * MIN_MATCH >= hash_bits + */ + + long block_start; + /* Window position at the beginning of the current output block. Gets + * negative when the window is moved backwards. + */ + + uInt match_length; /* length of best match */ + IPos prev_match; /* previous match */ + int match_available; /* set if previous match exists */ + uInt strstart; /* start of string to insert */ + uInt match_start; /* start of matching string */ + uInt lookahead; /* number of valid bytes ahead in window */ + + uInt prev_length; + /* Length of the best match at previous step. Matches not greater than this + * are discarded. This is used in the lazy match evaluation. + */ + + uInt max_chain_length; + /* To speed up deflation, hash chains are never searched beyond this + * length. A higher limit improves compression ratio but degrades the + * speed. + */ + + uInt max_lazy_match; + /* Attempt to find a better match only when the current match is strictly + * smaller than this value. This mechanism is used only for compression + * levels >= 4. + */ +# define max_insert_length max_lazy_match + /* Insert new strings in the hash table only if the match length is not + * greater than this length. This saves time but degrades compression. + * max_insert_length is used only for compression levels <= 3. + */ + + int level; /* compression level (1..9) */ + int strategy; /* favor or force Huffman coding*/ + + uInt good_match; + /* Use a faster search when the previous match is longer than this */ + + int nice_match; /* Stop searching when current match exceeds this */ + + /* used by trees.c: */ + /* Didn't use ct_data typedef below to suppress compiler warning */ + struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ + struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ + struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ + + struct tree_desc_s l_desc; /* desc. for literal tree */ + struct tree_desc_s d_desc; /* desc. for distance tree */ + struct tree_desc_s bl_desc; /* desc. for bit length tree */ + + ush bl_count[MAX_BITS+1]; + /* number of codes at each bit length for an optimal tree */ + + int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ + int heap_len; /* number of elements in the heap */ + int heap_max; /* element of largest frequency */ + /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. + * The same heap array is used to build all trees. + */ + + uch depth[2*L_CODES+1]; + /* Depth of each subtree used as tie breaker for trees of equal frequency + */ + +#ifdef LIT_MEM +# define LIT_BUFS 5 + ushf *d_buf; /* buffer for distances */ + uchf *l_buf; /* buffer for literals/lengths */ +#else +# define LIT_BUFS 4 + uchf *sym_buf; /* buffer for distances and literals/lengths */ +#endif + + uInt lit_bufsize; + /* Size of match buffer for literals/lengths. There are 4 reasons for + * limiting lit_bufsize to 64K: + * - frequencies can be kept in 16 bit counters + * - if compression is not successful for the first block, all input + * data is still in the window so we can still emit a stored block even + * when input comes from standard input. (This can also be done for + * all blocks if lit_bufsize is not greater than 32K.) + * - if compression is not successful for a file smaller than 64K, we can + * even emit a stored file instead of a stored block (saving 5 bytes). + * This is applicable only for zip (not gzip or zlib). + * - creating new Huffman trees less frequently may not provide fast + * adaptation to changes in the input data statistics. (Take for + * example a binary file with poorly compressible code followed by + * a highly compressible string table.) Smaller buffer sizes give + * fast adaptation but have of course the overhead of transmitting + * trees more frequently. + * - I can't count above 4 + */ + + uInt sym_next; /* running index in symbol buffer */ + uInt sym_end; /* symbol table full when sym_next reaches this */ + + ulg opt_len; /* bit length of current block with optimal trees */ + ulg static_len; /* bit length of current block with static trees */ + uInt matches; /* number of string matches in current block */ + uInt insert; /* bytes at end of window left to insert */ + +#ifdef ZLIB_DEBUG + ulg compressed_len; /* total bit length of compressed file mod 2^32 */ + ulg bits_sent; /* bit length of compressed data sent mod 2^32 */ +#endif + + ush bi_buf; + /* Output buffer. bits are inserted starting at the bottom (least + * significant bits). + */ + int bi_valid; + /* Number of valid bits in bi_buf. All bits above the last valid bit + * are always zero. + */ + + ulg high_water; + /* High water mark offset in window for initialized bytes -- bytes above + * this are set to zero in order to avoid memory check warnings when + * longest match routines access bytes past the input. This is then + * updated to the new high water mark. + */ + +} FAR deflate_state; + +/* Output a byte on the stream. + * IN assertion: there is enough room in pending_buf. + */ +#define put_byte(s, c) {s->pending_buf[s->pending++] = (Bytef)(c);} + + +#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) +/* Minimum amount of lookahead, except at the end of the input file. + * See deflate.c for comments about the MIN_MATCH+1. + */ + +#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD) +/* In order to simplify the code, particularly on 16 bit machines, match + * distances are limited to MAX_DIST instead of WSIZE. + */ + +#define WIN_INIT MAX_MATCH +/* Number of bytes after end of data in window to initialize in order to avoid + memory checker errors from longest match routines */ + + /* in trees.c */ +void ZLIB_INTERNAL _tr_init(deflate_state *s); +int ZLIB_INTERNAL _tr_tally(deflate_state *s, unsigned dist, unsigned lc); +void ZLIB_INTERNAL _tr_flush_block(deflate_state *s, charf *buf, + ulg stored_len, int last); +void ZLIB_INTERNAL _tr_flush_bits(deflate_state *s); +void ZLIB_INTERNAL _tr_align(deflate_state *s); +void ZLIB_INTERNAL _tr_stored_block(deflate_state *s, charf *buf, + ulg stored_len, int last); + +#define d_code(dist) \ + ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)]) +/* Mapping from a distance to a distance code. dist is the distance - 1 and + * must not have side effects. _dist_code[256] and _dist_code[257] are never + * used. + */ + +#ifndef ZLIB_DEBUG +/* Inline versions of _tr_tally for speed: */ + +#if defined(GEN_TREES_H) || !defined(STDC) + extern uch ZLIB_INTERNAL _length_code[]; + extern uch ZLIB_INTERNAL _dist_code[]; +#else + extern const uch ZLIB_INTERNAL _length_code[]; + extern const uch ZLIB_INTERNAL _dist_code[]; +#endif + +#ifdef LIT_MEM +# define _tr_tally_lit(s, c, flush) \ + { uch cc = (c); \ + s->d_buf[s->sym_next] = 0; \ + s->l_buf[s->sym_next++] = cc; \ + s->dyn_ltree[cc].Freq++; \ + flush = (s->sym_next == s->sym_end); \ + } +# define _tr_tally_dist(s, distance, length, flush) \ + { uch len = (uch)(length); \ + ush dist = (ush)(distance); \ + s->d_buf[s->sym_next] = dist; \ + s->l_buf[s->sym_next++] = len; \ + dist--; \ + s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ + s->dyn_dtree[d_code(dist)].Freq++; \ + flush = (s->sym_next == s->sym_end); \ + } +#else +# define _tr_tally_lit(s, c, flush) \ + { uch cc = (c); \ + s->sym_buf[s->sym_next++] = 0; \ + s->sym_buf[s->sym_next++] = 0; \ + s->sym_buf[s->sym_next++] = cc; \ + s->dyn_ltree[cc].Freq++; \ + flush = (s->sym_next == s->sym_end); \ + } +# define _tr_tally_dist(s, distance, length, flush) \ + { uch len = (uch)(length); \ + ush dist = (ush)(distance); \ + s->sym_buf[s->sym_next++] = (uch)dist; \ + s->sym_buf[s->sym_next++] = (uch)(dist >> 8); \ + s->sym_buf[s->sym_next++] = len; \ + dist--; \ + s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ + s->dyn_dtree[d_code(dist)].Freq++; \ + flush = (s->sym_next == s->sym_end); \ + } +#endif +#else +# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c) +# define _tr_tally_dist(s, distance, length, flush) \ + flush = _tr_tally(s, distance, length) +#endif + +#endif /* DEFLATE_H */ diff --git a/common/zlib/gzclose.c b/common/zlib/gzclose.c new file mode 100644 index 0000000..48d6a86 --- /dev/null +++ b/common/zlib/gzclose.c @@ -0,0 +1,23 @@ +/* gzclose.c -- zlib gzclose() function + * Copyright (C) 2004, 2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "gzguts.h" + +/* gzclose() is in a separate file so that it is linked in only if it is used. + That way the other gzclose functions can be used instead to avoid linking in + unneeded compression or decompression routines. */ +int ZEXPORT gzclose(gzFile file) { +#ifndef NO_GZCOMPRESS + gz_statep state; + + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + + return state->mode == GZ_READ ? gzclose_r(file) : gzclose_w(file); +#else + return gzclose_r(file); +#endif +} diff --git a/common/zlib/gzguts.h b/common/zlib/gzguts.h new file mode 100644 index 0000000..23229ca --- /dev/null +++ b/common/zlib/gzguts.h @@ -0,0 +1,219 @@ +/* gzguts.h -- zlib internal header definitions for gz* operations + * Copyright (C) 2004-2024 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +// UEFITool: required for macOS +#ifndef _WIN32 + #include +#endif + +#ifdef _LARGEFILE64_SOURCE +# ifndef _LARGEFILE_SOURCE +# define _LARGEFILE_SOURCE 1 +# endif +# undef _FILE_OFFSET_BITS +# undef _TIME_BITS +#endif + +#ifdef HAVE_HIDDEN +# define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) +#else +# define ZLIB_INTERNAL +#endif + +#include +#include "zlib.h" +#ifdef STDC +# include +# include +# include +#endif + +#ifndef _POSIX_SOURCE +# define _POSIX_SOURCE +#endif +#include + +#ifdef _WIN32 +# include +#endif + +#if defined(__TURBOC__) || defined(_MSC_VER) || defined(_WIN32) +# include +#endif + +#if defined(_WIN32) +# define WIDECHAR +#endif + +#ifdef WINAPI_FAMILY +# define open _open +# define read _read +# define write _write +# define close _close +#endif + +#ifdef NO_DEFLATE /* for compatibility with old definition */ +# define NO_GZCOMPRESS +#endif + +#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550) +# ifndef HAVE_VSNPRINTF +# define HAVE_VSNPRINTF +# endif +#endif + +#if defined(__CYGWIN__) +# ifndef HAVE_VSNPRINTF +# define HAVE_VSNPRINTF +# endif +#endif + +#if defined(MSDOS) && defined(__BORLANDC__) && (BORLANDC > 0x410) +# ifndef HAVE_VSNPRINTF +# define HAVE_VSNPRINTF +# endif +#endif + +#ifndef HAVE_VSNPRINTF +# ifdef MSDOS +/* vsnprintf may exist on some MS-DOS compilers (DJGPP?), + but for now we just assume it doesn't. */ +# define NO_vsnprintf +# endif +# ifdef __TURBOC__ +# define NO_vsnprintf +# endif +# ifdef WIN32 +/* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */ +# if !defined(vsnprintf) && !defined(NO_vsnprintf) +# if !defined(_MSC_VER) || ( defined(_MSC_VER) && _MSC_VER < 1500 ) +# define vsnprintf _vsnprintf +# endif +# endif +# endif +# ifdef __SASC +# define NO_vsnprintf +# endif +# ifdef VMS +# define NO_vsnprintf +# endif +# ifdef __OS400__ +# define NO_vsnprintf +# endif +# ifdef __MVS__ +# define NO_vsnprintf +# endif +#endif + +/* unlike snprintf (which is required in C99), _snprintf does not guarantee + null termination of the result -- however this is only used in gzlib.c where + the result is assured to fit in the space provided */ +#if defined(_MSC_VER) && _MSC_VER < 1900 +# define snprintf _snprintf +#endif + +#ifndef local +# define local static +#endif +/* since "static" is used to mean two completely different things in C, we + define "local" for the non-static meaning of "static", for readability + (compile with -Dlocal if your debugger can't find static symbols) */ + +/* gz* functions always use library allocation functions */ +#ifndef STDC + extern voidp malloc(uInt size); + extern void free(voidpf ptr); +#endif + +/* get errno and strerror definition */ +#if defined UNDER_CE +# include +# define zstrerror() gz_strwinerror((DWORD)GetLastError()) +#else +# ifndef NO_STRERROR +# include +# define zstrerror() strerror(errno) +# else +# define zstrerror() "stdio error (consult errno)" +# endif +#endif + +/* provide prototypes for these when building zlib without LFS */ +#if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0 + ZEXTERN gzFile ZEXPORT gzopen64(const char *, const char *); + ZEXTERN z_off64_t ZEXPORT gzseek64(gzFile, z_off64_t, int); + ZEXTERN z_off64_t ZEXPORT gztell64(gzFile); + ZEXTERN z_off64_t ZEXPORT gzoffset64(gzFile); +#endif + +/* default memLevel */ +#if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +#else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#endif + +/* default i/o buffer size -- double this for output when reading (this and + twice this must be able to fit in an unsigned type) */ +#define GZBUFSIZE 8192 + +/* gzip modes, also provide a little integrity check on the passed structure */ +#define GZ_NONE 0 +#define GZ_READ 7247 +#define GZ_WRITE 31153 +#define GZ_APPEND 1 /* mode set to GZ_WRITE after the file is opened */ + +/* values for gz_state how */ +#define LOOK 0 /* look for a gzip header */ +#define COPY 1 /* copy input directly */ +#define GZIP 2 /* decompress a gzip stream */ + +/* internal gzip file state data structure */ +typedef struct { + /* exposed contents for gzgetc() macro */ + struct gzFile_s x; /* "x" for exposed */ + /* x.have: number of bytes available at x.next */ + /* x.next: next output data to deliver or write */ + /* x.pos: current position in uncompressed data */ + /* used for both reading and writing */ + int mode; /* see gzip modes above */ + int fd; /* file descriptor */ + char *path; /* path or fd for error messages */ + unsigned size; /* buffer size, zero if not allocated yet */ + unsigned want; /* requested buffer size, default is GZBUFSIZE */ + unsigned char *in; /* input buffer (double-sized when writing) */ + unsigned char *out; /* output buffer (double-sized when reading) */ + int direct; /* 0 if processing gzip, 1 if transparent */ + /* just for reading */ + int how; /* 0: get header, 1: copy, 2: decompress */ + z_off64_t start; /* where the gzip data started, for rewinding */ + int eof; /* true if end of input file reached */ + int past; /* true if read requested past end */ + /* just for writing */ + int level; /* compression level */ + int strategy; /* compression strategy */ + int reset; /* true if a reset is pending after a Z_FINISH */ + /* seek request */ + z_off64_t skip; /* amount to skip (already rewound if backwards) */ + int seek; /* true if seek request pending */ + /* error information */ + int err; /* error code */ + char *msg; /* error message */ + /* zlib inflate or deflate stream */ + z_stream strm; /* stream structure in-place (not a pointer) */ +} gz_state; +typedef gz_state FAR *gz_statep; + +/* shared functions */ +void ZLIB_INTERNAL gz_error(gz_statep, int, const char *); +#if defined UNDER_CE +char ZLIB_INTERNAL *gz_strwinerror(DWORD error); +#endif + +/* GT_OFF(x), where x is an unsigned value, is true if x > maximum z_off64_t + value -- needed when comparing unsigned to z_off64_t, which is signed + (possible z_off64_t types off_t, off64_t, and long are all signed) */ +unsigned ZLIB_INTERNAL gz_intmax(void); +#define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax()) diff --git a/common/zlib/gzlib.c b/common/zlib/gzlib.c new file mode 100644 index 0000000..983153c --- /dev/null +++ b/common/zlib/gzlib.c @@ -0,0 +1,582 @@ +/* gzlib.c -- zlib functions common to reading and writing gzip files + * Copyright (C) 2004-2024 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "gzguts.h" + +#if defined(_WIN32) && !defined(__BORLANDC__) +# define LSEEK _lseeki64 +#else +#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 +# define LSEEK lseek64 +#else +# define LSEEK lseek +#endif +#endif + +#if defined UNDER_CE + +/* Map the Windows error number in ERROR to a locale-dependent error message + string and return a pointer to it. Typically, the values for ERROR come + from GetLastError. + + The string pointed to shall not be modified by the application, but may be + overwritten by a subsequent call to gz_strwinerror + + The gz_strwinerror function does not change the current setting of + GetLastError. */ +char ZLIB_INTERNAL *gz_strwinerror(DWORD error) { + static char buf[1024]; + + wchar_t *msgbuf; + DWORD lasterr = GetLastError(); + DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM + | FORMAT_MESSAGE_ALLOCATE_BUFFER, + NULL, + error, + 0, /* Default language */ + (LPVOID)&msgbuf, + 0, + NULL); + if (chars != 0) { + /* If there is an \r\n appended, zap it. */ + if (chars >= 2 + && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') { + chars -= 2; + msgbuf[chars] = 0; + } + + if (chars > sizeof (buf) - 1) { + chars = sizeof (buf) - 1; + msgbuf[chars] = 0; + } + + wcstombs(buf, msgbuf, chars + 1); + LocalFree(msgbuf); + } + else { + sprintf(buf, "unknown win32 error (%ld)", error); + } + + SetLastError(lasterr); + return buf; +} + +#endif /* UNDER_CE */ + +/* Reset gzip file state */ +local void gz_reset(gz_statep state) { + state->x.have = 0; /* no output data available */ + if (state->mode == GZ_READ) { /* for reading ... */ + state->eof = 0; /* not at end of file */ + state->past = 0; /* have not read past end yet */ + state->how = LOOK; /* look for gzip header */ + } + else /* for writing ... */ + state->reset = 0; /* no deflateReset pending */ + state->seek = 0; /* no seek request pending */ + gz_error(state, Z_OK, NULL); /* clear error */ + state->x.pos = 0; /* no uncompressed data yet */ + state->strm.avail_in = 0; /* no input data yet */ +} + +/* Open a gzip file either by name or file descriptor. */ +local gzFile gz_open(const void *path, int fd, const char *mode) { + gz_statep state; + z_size_t len; + int oflag; +#ifdef O_CLOEXEC + int cloexec = 0; +#endif +#ifdef O_EXCL + int exclusive = 0; +#endif + + /* check input */ + if (path == NULL) + return NULL; + + /* allocate gzFile structure to return */ + state = (gz_statep)malloc(sizeof(gz_state)); + if (state == NULL) + return NULL; + state->size = 0; /* no buffers allocated yet */ + state->want = GZBUFSIZE; /* requested buffer size */ + state->msg = NULL; /* no error message yet */ + + /* interpret mode */ + state->mode = GZ_NONE; + state->level = Z_DEFAULT_COMPRESSION; + state->strategy = Z_DEFAULT_STRATEGY; + state->direct = 0; + while (*mode) { + if (*mode >= '0' && *mode <= '9') + state->level = *mode - '0'; + else + switch (*mode) { + case 'r': + state->mode = GZ_READ; + break; +#ifndef NO_GZCOMPRESS + case 'w': + state->mode = GZ_WRITE; + break; + case 'a': + state->mode = GZ_APPEND; + break; +#endif + case '+': /* can't read and write at the same time */ + free(state); + return NULL; + case 'b': /* ignore -- will request binary anyway */ + break; +#ifdef O_CLOEXEC + case 'e': + cloexec = 1; + break; +#endif +#ifdef O_EXCL + case 'x': + exclusive = 1; + break; +#endif + case 'f': + state->strategy = Z_FILTERED; + break; + case 'h': + state->strategy = Z_HUFFMAN_ONLY; + break; + case 'R': + state->strategy = Z_RLE; + break; + case 'F': + state->strategy = Z_FIXED; + break; + case 'T': + state->direct = 1; + break; + default: /* could consider as an error, but just ignore */ + ; + } + mode++; + } + + /* must provide an "r", "w", or "a" */ + if (state->mode == GZ_NONE) { + free(state); + return NULL; + } + + /* can't force transparent read */ + if (state->mode == GZ_READ) { + if (state->direct) { + free(state); + return NULL; + } + state->direct = 1; /* for empty file */ + } + + /* save the path name for error messages */ +#ifdef WIDECHAR + if (fd == -2) { + len = wcstombs(NULL, path, 0); + if (len == (z_size_t)-1) + len = 0; + } + else +#endif + len = strlen((const char *)path); + state->path = (char *)malloc(len + 1); + if (state->path == NULL) { + free(state); + return NULL; + } +#ifdef WIDECHAR + if (fd == -2) + if (len) + wcstombs(state->path, path, len + 1); + else + *(state->path) = 0; + else +#endif +#if !defined(NO_snprintf) && !defined(NO_vsnprintf) + (void)snprintf(state->path, len + 1, "%s", (const char *)path); +#else + strcpy(state->path, path); +#endif + + /* compute the flags for open() */ + oflag = +#ifdef O_LARGEFILE + O_LARGEFILE | +#endif +#ifdef O_BINARY + O_BINARY | +#endif +#ifdef O_CLOEXEC + (cloexec ? O_CLOEXEC : 0) | +#endif + (state->mode == GZ_READ ? + O_RDONLY : + (O_WRONLY | O_CREAT | +#ifdef O_EXCL + (exclusive ? O_EXCL : 0) | +#endif + (state->mode == GZ_WRITE ? + O_TRUNC : + O_APPEND))); + + /* open the file with the appropriate flags (or just use fd) */ + state->fd = fd > -1 ? fd : ( +#ifdef WIDECHAR + fd == -2 ? _wopen(path, oflag, 0666) : +#endif + open((const char *)path, oflag, 0666)); + if (state->fd == -1) { + free(state->path); + free(state); + return NULL; + } + if (state->mode == GZ_APPEND) { + LSEEK(state->fd, 0, SEEK_END); /* so gzoffset() is correct */ + state->mode = GZ_WRITE; /* simplify later checks */ + } + + /* save the current position for rewinding (only if reading) */ + if (state->mode == GZ_READ) { + state->start = LSEEK(state->fd, 0, SEEK_CUR); + if (state->start == -1) state->start = 0; + } + + /* initialize stream */ + gz_reset(state); + + /* return stream */ + return (gzFile)state; +} + +/* -- see zlib.h -- */ +gzFile ZEXPORT gzopen(const char *path, const char *mode) { + return gz_open(path, -1, mode); +} + +/* -- see zlib.h -- */ +gzFile ZEXPORT gzopen64(const char *path, const char *mode) { + return gz_open(path, -1, mode); +} + +/* -- see zlib.h -- */ +gzFile ZEXPORT gzdopen(int fd, const char *mode) { + char *path; /* identifier for error messages */ + gzFile gz; + + if (fd == -1 || (path = (char *)malloc(7 + 3 * sizeof(int))) == NULL) + return NULL; +#if !defined(NO_snprintf) && !defined(NO_vsnprintf) + (void)snprintf(path, 7 + 3 * sizeof(int), "", fd); +#else + sprintf(path, "", fd); /* for debugging */ +#endif + gz = gz_open(path, fd, mode); + free(path); + return gz; +} + +/* -- see zlib.h -- */ +#ifdef WIDECHAR +gzFile ZEXPORT gzopen_w(const wchar_t *path, const char *mode) { + return gz_open(path, -2, mode); +} +#endif + +/* -- see zlib.h -- */ +int ZEXPORT gzbuffer(gzFile file, unsigned size) { + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* make sure we haven't already allocated memory */ + if (state->size != 0) + return -1; + + /* check and set requested size */ + if ((size << 1) < size) + return -1; /* need to be able to double it */ + if (size < 8) + size = 8; /* needed to behave well with flushing */ + state->want = size; + return 0; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzrewind(gzFile file) { + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + + /* check that we're reading and that there's no error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return -1; + + /* back up and start over */ + if (LSEEK(state->fd, state->start, SEEK_SET) == -1) + return -1; + gz_reset(state); + return 0; +} + +/* -- see zlib.h -- */ +z_off64_t ZEXPORT gzseek64(gzFile file, z_off64_t offset, int whence) { + unsigned n; + z_off64_t ret; + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* check that there's no error */ + if (state->err != Z_OK && state->err != Z_BUF_ERROR) + return -1; + + /* can only seek from start or relative to current position */ + if (whence != SEEK_SET && whence != SEEK_CUR) + return -1; + + /* normalize offset to a SEEK_CUR specification */ + if (whence == SEEK_SET) + offset -= state->x.pos; + else if (state->seek) + offset += state->skip; + state->seek = 0; + + /* if within raw area while reading, just go there */ + if (state->mode == GZ_READ && state->how == COPY && + state->x.pos + offset >= 0) { + ret = LSEEK(state->fd, offset - (z_off64_t)state->x.have, SEEK_CUR); + if (ret == -1) + return -1; + state->x.have = 0; + state->eof = 0; + state->past = 0; + state->seek = 0; + gz_error(state, Z_OK, NULL); + state->strm.avail_in = 0; + state->x.pos += offset; + return state->x.pos; + } + + /* calculate skip amount, rewinding if needed for back seek when reading */ + if (offset < 0) { + if (state->mode != GZ_READ) /* writing -- can't go backwards */ + return -1; + offset += state->x.pos; + if (offset < 0) /* before start of file! */ + return -1; + if (gzrewind(file) == -1) /* rewind, then skip to offset */ + return -1; + } + + /* if reading, skip what's in output buffer (one less gzgetc() check) */ + if (state->mode == GZ_READ) { + n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > offset ? + (unsigned)offset : state->x.have; + state->x.have -= n; + state->x.next += n; + state->x.pos += n; + offset -= n; + } + + /* request skip (if not zero) */ + if (offset) { + state->seek = 1; + state->skip = offset; + } + return state->x.pos + offset; +} + +/* -- see zlib.h -- */ +z_off_t ZEXPORT gzseek(gzFile file, z_off_t offset, int whence) { + z_off64_t ret; + + ret = gzseek64(file, (z_off64_t)offset, whence); + return ret == (z_off_t)ret ? (z_off_t)ret : -1; +} + +/* -- see zlib.h -- */ +z_off64_t ZEXPORT gztell64(gzFile file) { + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* return position */ + return state->x.pos + (state->seek ? state->skip : 0); +} + +/* -- see zlib.h -- */ +z_off_t ZEXPORT gztell(gzFile file) { + z_off64_t ret; + + ret = gztell64(file); + return ret == (z_off_t)ret ? (z_off_t)ret : -1; +} + +/* -- see zlib.h -- */ +z_off64_t ZEXPORT gzoffset64(gzFile file) { + z_off64_t offset; + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* compute and return effective offset in file */ + offset = LSEEK(state->fd, 0, SEEK_CUR); + if (offset == -1) + return -1; + if (state->mode == GZ_READ) /* reading */ + offset -= state->strm.avail_in; /* don't count buffered input */ + return offset; +} + +/* -- see zlib.h -- */ +z_off_t ZEXPORT gzoffset(gzFile file) { + z_off64_t ret; + + ret = gzoffset64(file); + return ret == (z_off_t)ret ? (z_off_t)ret : -1; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzeof(gzFile file) { + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return 0; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return 0; + + /* return end-of-file state */ + return state->mode == GZ_READ ? state->past : 0; +} + +/* -- see zlib.h -- */ +const char * ZEXPORT gzerror(gzFile file, int *errnum) { + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return NULL; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return NULL; + + /* return error information */ + if (errnum != NULL) + *errnum = state->err; + return state->err == Z_MEM_ERROR ? "out of memory" : + (state->msg == NULL ? "" : state->msg); +} + +/* -- see zlib.h -- */ +void ZEXPORT gzclearerr(gzFile file) { + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return; + + /* clear error and end-of-file */ + if (state->mode == GZ_READ) { + state->eof = 0; + state->past = 0; + } + gz_error(state, Z_OK, NULL); +} + +/* Create an error message in allocated memory and set state->err and + state->msg accordingly. Free any previous error message already there. Do + not try to free or allocate space if the error is Z_MEM_ERROR (out of + memory). Simply save the error message as a static string. If there is an + allocation failure constructing the error message, then convert the error to + out of memory. */ +void ZLIB_INTERNAL gz_error(gz_statep state, int err, const char *msg) { + /* free previously allocated message and clear */ + if (state->msg != NULL) { + if (state->err != Z_MEM_ERROR) + free(state->msg); + state->msg = NULL; + } + + /* if fatal, set state->x.have to 0 so that the gzgetc() macro fails */ + if (err != Z_OK && err != Z_BUF_ERROR) + state->x.have = 0; + + /* set error code, and if no message, then done */ + state->err = err; + if (msg == NULL) + return; + + /* for an out of memory error, return literal string when requested */ + if (err == Z_MEM_ERROR) + return; + + /* construct error message with path */ + if ((state->msg = (char *)malloc(strlen(state->path) + strlen(msg) + 3)) == + NULL) { + state->err = Z_MEM_ERROR; + return; + } +#if !defined(NO_snprintf) && !defined(NO_vsnprintf) + (void)snprintf(state->msg, strlen(state->path) + strlen(msg) + 3, + "%s%s%s", state->path, ": ", msg); +#else + strcpy(state->msg, state->path); + strcat(state->msg, ": "); + strcat(state->msg, msg); +#endif +} + +/* portably return maximum value for an int (when limits.h presumed not + available) -- we need to do this to cover cases where 2's complement not + used, since C standard permits 1's complement and sign-bit representations, + otherwise we could just use ((unsigned)-1) >> 1 */ +unsigned ZLIB_INTERNAL gz_intmax(void) { +#ifdef INT_MAX + return INT_MAX; +#else + unsigned p = 1, q; + do { + q = p; + p <<= 1; + p++; + } while (p > q); + return q >> 1; +#endif +} diff --git a/common/zlib/gzread.c b/common/zlib/gzread.c new file mode 100644 index 0000000..4168cbc --- /dev/null +++ b/common/zlib/gzread.c @@ -0,0 +1,602 @@ +/* gzread.c -- zlib functions for reading gzip files + * Copyright (C) 2004-2017 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "gzguts.h" + +/* Use read() to load a buffer -- return -1 on error, otherwise 0. Read from + state->fd, and update state->eof, state->err, and state->msg as appropriate. + This function needs to loop on read(), since read() is not guaranteed to + read the number of bytes requested, depending on the type of descriptor. */ +local int gz_load(gz_statep state, unsigned char *buf, unsigned len, + unsigned *have) { + int ret; + unsigned get, max = ((unsigned)-1 >> 2) + 1; + + *have = 0; + do { + get = len - *have; + if (get > max) + get = max; + ret = read(state->fd, buf + *have, get); + if (ret <= 0) + break; + *have += (unsigned)ret; + } while (*have < len); + if (ret < 0) { + gz_error(state, Z_ERRNO, zstrerror()); + return -1; + } + if (ret == 0) + state->eof = 1; + return 0; +} + +/* Load up input buffer and set eof flag if last data loaded -- return -1 on + error, 0 otherwise. Note that the eof flag is set when the end of the input + file is reached, even though there may be unused data in the buffer. Once + that data has been used, no more attempts will be made to read the file. + If strm->avail_in != 0, then the current data is moved to the beginning of + the input buffer, and then the remainder of the buffer is loaded with the + available data from the input file. */ +local int gz_avail(gz_statep state) { + unsigned got; + z_streamp strm = &(state->strm); + + if (state->err != Z_OK && state->err != Z_BUF_ERROR) + return -1; + if (state->eof == 0) { + if (strm->avail_in) { /* copy what's there to the start */ + unsigned char *p = state->in; + unsigned const char *q = strm->next_in; + unsigned n = strm->avail_in; + do { + *p++ = *q++; + } while (--n); + } + if (gz_load(state, state->in + strm->avail_in, + state->size - strm->avail_in, &got) == -1) + return -1; + strm->avail_in += got; + strm->next_in = state->in; + } + return 0; +} + +/* Look for gzip header, set up for inflate or copy. state->x.have must be 0. + If this is the first time in, allocate required memory. state->how will be + left unchanged if there is no more input data available, will be set to COPY + if there is no gzip header and direct copying will be performed, or it will + be set to GZIP for decompression. If direct copying, then leftover input + data from the input buffer will be copied to the output buffer. In that + case, all further file reads will be directly to either the output buffer or + a user buffer. If decompressing, the inflate state will be initialized. + gz_look() will return 0 on success or -1 on failure. */ +local int gz_look(gz_statep state) { + z_streamp strm = &(state->strm); + + /* allocate read buffers and inflate memory */ + if (state->size == 0) { + /* allocate buffers */ + state->in = (unsigned char *)malloc(state->want); + state->out = (unsigned char *)malloc(state->want << 1); + if (state->in == NULL || state->out == NULL) { + free(state->out); + free(state->in); + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + state->size = state->want; + + /* allocate inflate memory */ + state->strm.zalloc = Z_NULL; + state->strm.zfree = Z_NULL; + state->strm.opaque = Z_NULL; + state->strm.avail_in = 0; + state->strm.next_in = Z_NULL; + if (inflateInit2(&(state->strm), 15 + 16) != Z_OK) { /* gunzip */ + free(state->out); + free(state->in); + state->size = 0; + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + } + + /* get at least the magic bytes in the input buffer */ + if (strm->avail_in < 2) { + if (gz_avail(state) == -1) + return -1; + if (strm->avail_in == 0) + return 0; + } + + /* look for gzip magic bytes -- if there, do gzip decoding (note: there is + a logical dilemma here when considering the case of a partially written + gzip file, to wit, if a single 31 byte is written, then we cannot tell + whether this is a single-byte file, or just a partially written gzip + file -- for here we assume that if a gzip file is being written, then + the header will be written in a single operation, so that reading a + single byte is sufficient indication that it is not a gzip file) */ + if (strm->avail_in > 1 && + strm->next_in[0] == 31 && strm->next_in[1] == 139) { + inflateReset(strm); + state->how = GZIP; + state->direct = 0; + return 0; + } + + /* no gzip header -- if we were decoding gzip before, then this is trailing + garbage. Ignore the trailing garbage and finish. */ + if (state->direct == 0) { + strm->avail_in = 0; + state->eof = 1; + state->x.have = 0; + return 0; + } + + /* doing raw i/o, copy any leftover input to output -- this assumes that + the output buffer is larger than the input buffer, which also assures + space for gzungetc() */ + state->x.next = state->out; + memcpy(state->x.next, strm->next_in, strm->avail_in); + state->x.have = strm->avail_in; + strm->avail_in = 0; + state->how = COPY; + state->direct = 1; + return 0; +} + +/* Decompress from input to the provided next_out and avail_out in the state. + On return, state->x.have and state->x.next point to the just decompressed + data. If the gzip stream completes, state->how is reset to LOOK to look for + the next gzip stream or raw data, once state->x.have is depleted. Returns 0 + on success, -1 on failure. */ +local int gz_decomp(gz_statep state) { + int ret = Z_OK; + unsigned had; + z_streamp strm = &(state->strm); + + /* fill output buffer up to end of deflate stream */ + had = strm->avail_out; + do { + /* get more input for inflate() */ + if (strm->avail_in == 0 && gz_avail(state) == -1) + return -1; + if (strm->avail_in == 0) { + gz_error(state, Z_BUF_ERROR, "unexpected end of file"); + break; + } + + /* decompress and handle errors */ + ret = inflate(strm, Z_NO_FLUSH); + if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT) { + gz_error(state, Z_STREAM_ERROR, + "internal error: inflate stream corrupt"); + return -1; + } + if (ret == Z_MEM_ERROR) { + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + if (ret == Z_DATA_ERROR) { /* deflate stream invalid */ + gz_error(state, Z_DATA_ERROR, + strm->msg == NULL ? "compressed data error" : strm->msg); + return -1; + } + } while (strm->avail_out && ret != Z_STREAM_END); + + /* update available output */ + state->x.have = had - strm->avail_out; + state->x.next = strm->next_out - state->x.have; + + /* if the gzip stream completed successfully, look for another */ + if (ret == Z_STREAM_END) + state->how = LOOK; + + /* good decompression */ + return 0; +} + +/* Fetch data and put it in the output buffer. Assumes state->x.have is 0. + Data is either copied from the input file or decompressed from the input + file depending on state->how. If state->how is LOOK, then a gzip header is + looked for to determine whether to copy or decompress. Returns -1 on error, + otherwise 0. gz_fetch() will leave state->how as COPY or GZIP unless the + end of the input file has been reached and all data has been processed. */ +local int gz_fetch(gz_statep state) { + z_streamp strm = &(state->strm); + + do { + switch(state->how) { + case LOOK: /* -> LOOK, COPY (only if never GZIP), or GZIP */ + if (gz_look(state) == -1) + return -1; + if (state->how == LOOK) + return 0; + break; + case COPY: /* -> COPY */ + if (gz_load(state, state->out, state->size << 1, &(state->x.have)) + == -1) + return -1; + state->x.next = state->out; + return 0; + case GZIP: /* -> GZIP or LOOK (if end of gzip stream) */ + strm->avail_out = state->size << 1; + strm->next_out = state->out; + if (gz_decomp(state) == -1) + return -1; + } + } while (state->x.have == 0 && (!state->eof || strm->avail_in)); + return 0; +} + +/* Skip len uncompressed bytes of output. Return -1 on error, 0 on success. */ +local int gz_skip(gz_statep state, z_off64_t len) { + unsigned n; + + /* skip over len bytes or reach end-of-file, whichever comes first */ + while (len) + /* skip over whatever is in output buffer */ + if (state->x.have) { + n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > len ? + (unsigned)len : state->x.have; + state->x.have -= n; + state->x.next += n; + state->x.pos += n; + len -= n; + } + + /* output buffer empty -- return if we're at the end of the input */ + else if (state->eof && state->strm.avail_in == 0) + break; + + /* need more data to skip -- load up output buffer */ + else { + /* get more output, looking for header if required */ + if (gz_fetch(state) == -1) + return -1; + } + return 0; +} + +/* Read len bytes into buf from file, or less than len up to the end of the + input. Return the number of bytes read. If zero is returned, either the + end of file was reached, or there was an error. state->err must be + consulted in that case to determine which. */ +local z_size_t gz_read(gz_statep state, voidp buf, z_size_t len) { + z_size_t got; + unsigned n; + + /* if len is zero, avoid unnecessary operations */ + if (len == 0) + return 0; + + /* process a skip request */ + if (state->seek) { + state->seek = 0; + if (gz_skip(state, state->skip) == -1) + return 0; + } + + /* get len bytes to buf, or less than len if at the end */ + got = 0; + do { + /* set n to the maximum amount of len that fits in an unsigned int */ + n = (unsigned)-1; + if (n > len) + n = (unsigned)len; + + /* first just try copying data from the output buffer */ + if (state->x.have) { + if (state->x.have < n) + n = state->x.have; + memcpy(buf, state->x.next, n); + state->x.next += n; + state->x.have -= n; + } + + /* output buffer empty -- return if we're at the end of the input */ + else if (state->eof && state->strm.avail_in == 0) { + state->past = 1; /* tried to read past end */ + break; + } + + /* need output data -- for small len or new stream load up our output + buffer */ + else if (state->how == LOOK || n < (state->size << 1)) { + /* get more output, looking for header if required */ + if (gz_fetch(state) == -1) + return 0; + continue; /* no progress yet -- go back to copy above */ + /* the copy above assures that we will leave with space in the + output buffer, allowing at least one gzungetc() to succeed */ + } + + /* large len -- read directly into user buffer */ + else if (state->how == COPY) { /* read directly */ + if (gz_load(state, (unsigned char *)buf, n, &n) == -1) + return 0; + } + + /* large len -- decompress directly into user buffer */ + else { /* state->how == GZIP */ + state->strm.avail_out = n; + state->strm.next_out = (unsigned char *)buf; + if (gz_decomp(state) == -1) + return 0; + n = state->x.have; + state->x.have = 0; + } + + /* update progress */ + len -= n; + buf = (char *)buf + n; + got += n; + state->x.pos += n; + } while (len); + + /* return number of bytes read into user buffer */ + return got; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzread(gzFile file, voidp buf, unsigned len) { + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return -1; + + /* since an int is returned, make sure len fits in one, otherwise return + with an error (this avoids a flaw in the interface) */ + if ((int)len < 0) { + gz_error(state, Z_STREAM_ERROR, "request does not fit in an int"); + return -1; + } + + /* read len or fewer bytes to buf */ + len = (unsigned)gz_read(state, buf, len); + + /* check for an error */ + if (len == 0 && state->err != Z_OK && state->err != Z_BUF_ERROR) + return -1; + + /* return the number of bytes read (this is assured to fit in an int) */ + return (int)len; +} + +/* -- see zlib.h -- */ +z_size_t ZEXPORT gzfread(voidp buf, z_size_t size, z_size_t nitems, gzFile file) { + z_size_t len; + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return 0; + state = (gz_statep)file; + + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return 0; + + /* compute bytes to read -- error on overflow */ + len = nitems * size; + if (size && len / size != nitems) { + gz_error(state, Z_STREAM_ERROR, "request does not fit in a size_t"); + return 0; + } + + /* read len or fewer bytes to buf, return the number of full items read */ + return len ? gz_read(state, buf, len) / size : 0; +} + +/* -- see zlib.h -- */ +#ifdef Z_PREFIX_SET +# undef z_gzgetc +#else +# undef gzgetc +#endif +int ZEXPORT gzgetc(gzFile file) { + unsigned char buf[1]; + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return -1; + + /* try output buffer (no need to check for skip request) */ + if (state->x.have) { + state->x.have--; + state->x.pos++; + return *(state->x.next)++; + } + + /* nothing there -- try gz_read() */ + return gz_read(state, buf, 1) < 1 ? -1 : buf[0]; +} + +int ZEXPORT gzgetc_(gzFile file) { + return gzgetc(file); +} + +/* -- see zlib.h -- */ +int ZEXPORT gzungetc(int c, gzFile file) { + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + + /* in case this was just opened, set up the input buffer */ + if (state->mode == GZ_READ && state->how == LOOK && state->x.have == 0) + (void)gz_look(state); + + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return -1; + + /* process a skip request */ + if (state->seek) { + state->seek = 0; + if (gz_skip(state, state->skip) == -1) + return -1; + } + + /* can't push EOF */ + if (c < 0) + return -1; + + /* if output buffer empty, put byte at end (allows more pushing) */ + if (state->x.have == 0) { + state->x.have = 1; + state->x.next = state->out + (state->size << 1) - 1; + state->x.next[0] = (unsigned char)c; + state->x.pos--; + state->past = 0; + return c; + } + + /* if no room, give up (must have already done a gzungetc()) */ + if (state->x.have == (state->size << 1)) { + gz_error(state, Z_DATA_ERROR, "out of room to push characters"); + return -1; + } + + /* slide output data if needed and insert byte before existing data */ + if (state->x.next == state->out) { + unsigned char *src = state->out + state->x.have; + unsigned char *dest = state->out + (state->size << 1); + while (src > state->out) + *--dest = *--src; + state->x.next = dest; + } + state->x.have++; + state->x.next--; + state->x.next[0] = (unsigned char)c; + state->x.pos--; + state->past = 0; + return c; +} + +/* -- see zlib.h -- */ +char * ZEXPORT gzgets(gzFile file, char *buf, int len) { + unsigned left, n; + char *str; + unsigned char *eol; + gz_statep state; + + /* check parameters and get internal structure */ + if (file == NULL || buf == NULL || len < 1) + return NULL; + state = (gz_statep)file; + + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return NULL; + + /* process a skip request */ + if (state->seek) { + state->seek = 0; + if (gz_skip(state, state->skip) == -1) + return NULL; + } + + /* copy output bytes up to new line or len - 1, whichever comes first -- + append a terminating zero to the string (we don't check for a zero in + the contents, let the user worry about that) */ + str = buf; + left = (unsigned)len - 1; + if (left) do { + /* assure that something is in the output buffer */ + if (state->x.have == 0 && gz_fetch(state) == -1) + return NULL; /* error */ + if (state->x.have == 0) { /* end of file */ + state->past = 1; /* read past end */ + break; /* return what we have */ + } + + /* look for end-of-line in current output buffer */ + n = state->x.have > left ? left : state->x.have; + eol = (unsigned char *)memchr(state->x.next, '\n', n); + if (eol != NULL) + n = (unsigned)(eol - state->x.next) + 1; + + /* copy through end-of-line, or remainder if not found */ + memcpy(buf, state->x.next, n); + state->x.have -= n; + state->x.next += n; + state->x.pos += n; + left -= n; + buf += n; + } while (left && eol == NULL); + + /* return terminated string, or if nothing, end of file */ + if (buf == str) + return NULL; + buf[0] = 0; + return str; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzdirect(gzFile file) { + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return 0; + state = (gz_statep)file; + + /* if the state is not known, but we can find out, then do so (this is + mainly for right after a gzopen() or gzdopen()) */ + if (state->mode == GZ_READ && state->how == LOOK && state->x.have == 0) + (void)gz_look(state); + + /* return 1 if transparent, 0 if processing a gzip stream */ + return state->direct; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzclose_r(gzFile file) { + int ret, err; + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + + /* check that we're reading */ + if (state->mode != GZ_READ) + return Z_STREAM_ERROR; + + /* free memory and close file */ + if (state->size) { + inflateEnd(&(state->strm)); + free(state->out); + free(state->in); + } + err = state->err == Z_BUF_ERROR ? Z_BUF_ERROR : Z_OK; + gz_error(state, Z_OK, NULL); + free(state->path); + ret = close(state->fd); + free(state); + return ret ? Z_ERRNO : err; +} diff --git a/common/zlib/gzwrite.c b/common/zlib/gzwrite.c new file mode 100644 index 0000000..435b462 --- /dev/null +++ b/common/zlib/gzwrite.c @@ -0,0 +1,631 @@ +/* gzwrite.c -- zlib functions for writing gzip files + * Copyright (C) 2004-2019 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "gzguts.h" + +/* Initialize state for writing a gzip file. Mark initialization by setting + state->size to non-zero. Return -1 on a memory allocation failure, or 0 on + success. */ +local int gz_init(gz_statep state) { + int ret; + z_streamp strm = &(state->strm); + + /* allocate input buffer (double size for gzprintf) */ + state->in = (unsigned char *)malloc(state->want << 1); + if (state->in == NULL) { + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + + /* only need output buffer and deflate state if compressing */ + if (!state->direct) { + /* allocate output buffer */ + state->out = (unsigned char *)malloc(state->want); + if (state->out == NULL) { + free(state->in); + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + + /* allocate deflate memory, set up for gzip compression */ + strm->zalloc = Z_NULL; + strm->zfree = Z_NULL; + strm->opaque = Z_NULL; + ret = deflateInit2(strm, state->level, Z_DEFLATED, + MAX_WBITS + 16, DEF_MEM_LEVEL, state->strategy); + if (ret != Z_OK) { + free(state->out); + free(state->in); + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + strm->next_in = NULL; + } + + /* mark state as initialized */ + state->size = state->want; + + /* initialize write buffer if compressing */ + if (!state->direct) { + strm->avail_out = state->size; + strm->next_out = state->out; + state->x.next = strm->next_out; + } + return 0; +} + +/* Compress whatever is at avail_in and next_in and write to the output file. + Return -1 if there is an error writing to the output file or if gz_init() + fails to allocate memory, otherwise 0. flush is assumed to be a valid + deflate() flush value. If flush is Z_FINISH, then the deflate() state is + reset to start a new gzip stream. If gz->direct is true, then simply write + to the output file without compressing, and ignore flush. */ +local int gz_comp(gz_statep state, int flush) { + int ret, writ; + unsigned have, put, max = ((unsigned)-1 >> 2) + 1; + z_streamp strm = &(state->strm); + + /* allocate memory if this is the first time through */ + if (state->size == 0 && gz_init(state) == -1) + return -1; + + /* write directly if requested */ + if (state->direct) { + while (strm->avail_in) { + put = strm->avail_in > max ? max : strm->avail_in; + writ = write(state->fd, strm->next_in, put); + if (writ < 0) { + gz_error(state, Z_ERRNO, zstrerror()); + return -1; + } + strm->avail_in -= (unsigned)writ; + strm->next_in += writ; + } + return 0; + } + + /* check for a pending reset */ + if (state->reset) { + /* don't start a new gzip member unless there is data to write */ + if (strm->avail_in == 0) + return 0; + deflateReset(strm); + state->reset = 0; + } + + /* run deflate() on provided input until it produces no more output */ + ret = Z_OK; + do { + /* write out current buffer contents if full, or if flushing, but if + doing Z_FINISH then don't write until we get to Z_STREAM_END */ + if (strm->avail_out == 0 || (flush != Z_NO_FLUSH && + (flush != Z_FINISH || ret == Z_STREAM_END))) { + while (strm->next_out > state->x.next) { + put = strm->next_out - state->x.next > (int)max ? max : + (unsigned)(strm->next_out - state->x.next); + writ = write(state->fd, state->x.next, put); + if (writ < 0) { + gz_error(state, Z_ERRNO, zstrerror()); + return -1; + } + state->x.next += writ; + } + if (strm->avail_out == 0) { + strm->avail_out = state->size; + strm->next_out = state->out; + state->x.next = state->out; + } + } + + /* compress */ + have = strm->avail_out; + ret = deflate(strm, flush); + if (ret == Z_STREAM_ERROR) { + gz_error(state, Z_STREAM_ERROR, + "internal error: deflate stream corrupt"); + return -1; + } + have -= strm->avail_out; + } while (have); + + /* if that completed a deflate stream, allow another to start */ + if (flush == Z_FINISH) + state->reset = 1; + + /* all done, no errors */ + return 0; +} + +/* Compress len zeros to output. Return -1 on a write error or memory + allocation failure by gz_comp(), or 0 on success. */ +local int gz_zero(gz_statep state, z_off64_t len) { + int first; + unsigned n; + z_streamp strm = &(state->strm); + + /* consume whatever's left in the input buffer */ + if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) + return -1; + + /* compress len zeros (len guaranteed > 0) */ + first = 1; + while (len) { + n = GT_OFF(state->size) || (z_off64_t)state->size > len ? + (unsigned)len : state->size; + if (first) { + memset(state->in, 0, n); + first = 0; + } + strm->avail_in = n; + strm->next_in = state->in; + state->x.pos += n; + if (gz_comp(state, Z_NO_FLUSH) == -1) + return -1; + len -= n; + } + return 0; +} + +/* Write len bytes from buf to file. Return the number of bytes written. If + the returned value is less than len, then there was an error. */ +local z_size_t gz_write(gz_statep state, voidpc buf, z_size_t len) { + z_size_t put = len; + + /* if len is zero, avoid unnecessary operations */ + if (len == 0) + return 0; + + /* allocate memory if this is the first time through */ + if (state->size == 0 && gz_init(state) == -1) + return 0; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return 0; + } + + /* for small len, copy to input buffer, otherwise compress directly */ + if (len < state->size) { + /* copy to input buffer, compress when full */ + do { + unsigned have, copy; + + if (state->strm.avail_in == 0) + state->strm.next_in = state->in; + have = (unsigned)((state->strm.next_in + state->strm.avail_in) - + state->in); + copy = state->size - have; + if (copy > len) + copy = (unsigned)len; + memcpy(state->in + have, buf, copy); + state->strm.avail_in += copy; + state->x.pos += copy; + buf = (const char *)buf + copy; + len -= copy; + if (len && gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + } while (len); + } + else { + /* consume whatever's left in the input buffer */ + if (state->strm.avail_in && gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + + /* directly compress user buffer to file */ + state->strm.next_in = (z_const Bytef *)buf; + do { + unsigned n = (unsigned)-1; + if (n > len) + n = (unsigned)len; + state->strm.avail_in = n; + state->x.pos += n; + if (gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + len -= n; + } while (len); + } + + /* input was all buffered or compressed */ + return put; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzwrite(gzFile file, voidpc buf, unsigned len) { + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return 0; + state = (gz_statep)file; + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return 0; + + /* since an int is returned, make sure len fits in one, otherwise return + with an error (this avoids a flaw in the interface) */ + if ((int)len < 0) { + gz_error(state, Z_DATA_ERROR, "requested length does not fit in int"); + return 0; + } + + /* write len bytes from buf (the return value will fit in an int) */ + return (int)gz_write(state, buf, len); +} + +/* -- see zlib.h -- */ +z_size_t ZEXPORT gzfwrite(voidpc buf, z_size_t size, z_size_t nitems, + gzFile file) { + z_size_t len; + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return 0; + state = (gz_statep)file; + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return 0; + + /* compute bytes to read -- error on overflow */ + len = nitems * size; + if (size && len / size != nitems) { + gz_error(state, Z_STREAM_ERROR, "request does not fit in a size_t"); + return 0; + } + + /* write len bytes to buf, return the number of full items written */ + return len ? gz_write(state, buf, len) / size : 0; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzputc(gzFile file, int c) { + unsigned have; + unsigned char buf[1]; + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return -1; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return -1; + } + + /* try writing to input buffer for speed (state->size == 0 if buffer not + initialized) */ + if (state->size) { + if (strm->avail_in == 0) + strm->next_in = state->in; + have = (unsigned)((strm->next_in + strm->avail_in) - state->in); + if (have < state->size) { + state->in[have] = (unsigned char)c; + strm->avail_in++; + state->x.pos++; + return c & 0xff; + } + } + + /* no room in buffer or not initialized, use gz_write() */ + buf[0] = (unsigned char)c; + if (gz_write(state, buf, 1) != 1) + return -1; + return c & 0xff; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzputs(gzFile file, const char *s) { + z_size_t len, put; + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return -1; + + /* write string */ + len = strlen(s); + if ((int)len < 0 || (unsigned)len != len) { + gz_error(state, Z_STREAM_ERROR, "string length does not fit in int"); + return -1; + } + put = gz_write(state, s, len); + return put < len ? -1 : (int)len; +} + +#if defined(STDC) || defined(Z_HAVE_STDARG_H) +#include + +/* -- see zlib.h -- */ +int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va) { + int len; + unsigned left; + char *next; + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return Z_STREAM_ERROR; + + /* make sure we have some buffer space */ + if (state->size == 0 && gz_init(state) == -1) + return state->err; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return state->err; + } + + /* do the printf() into the input buffer, put length in len -- the input + buffer is double-sized just for this function, so there is guaranteed to + be state->size bytes available after the current contents */ + if (strm->avail_in == 0) + strm->next_in = state->in; + next = (char *)(state->in + (strm->next_in - state->in) + strm->avail_in); + next[state->size - 1] = 0; +#ifdef NO_vsnprintf +# ifdef HAS_vsprintf_void + (void)vsprintf(next, format, va); + for (len = 0; len < state->size; len++) + if (next[len] == 0) break; +# else + len = vsprintf(next, format, va); +# endif +#else +# ifdef HAS_vsnprintf_void + (void)vsnprintf(next, state->size, format, va); + len = strlen(next); +# else + len = vsnprintf(next, state->size, format, va); +# endif +#endif + + /* check that printf() results fit in buffer */ + if (len == 0 || (unsigned)len >= state->size || next[state->size - 1] != 0) + return 0; + + /* update buffer and position, compress first half if past that */ + strm->avail_in += (unsigned)len; + state->x.pos += len; + if (strm->avail_in >= state->size) { + left = strm->avail_in - state->size; + strm->avail_in = state->size; + if (gz_comp(state, Z_NO_FLUSH) == -1) + return state->err; + memmove(state->in, state->in + state->size, left); + strm->next_in = state->in; + strm->avail_in = left; + } + return len; +} + +int ZEXPORTVA gzprintf(gzFile file, const char *format, ...) { + va_list va; + int ret; + + va_start(va, format); + ret = gzvprintf(file, format, va); + va_end(va); + return ret; +} + +#else /* !STDC && !Z_HAVE_STDARG_H */ + +/* -- see zlib.h -- */ +int ZEXPORTVA gzprintf(gzFile file, const char *format, int a1, int a2, int a3, + int a4, int a5, int a6, int a7, int a8, int a9, int a10, + int a11, int a12, int a13, int a14, int a15, int a16, + int a17, int a18, int a19, int a20) { + unsigned len, left; + char *next; + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that can really pass pointer in ints */ + if (sizeof(int) != sizeof(void *)) + return Z_STREAM_ERROR; + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return Z_STREAM_ERROR; + + /* make sure we have some buffer space */ + if (state->size == 0 && gz_init(state) == -1) + return state->error; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return state->error; + } + + /* do the printf() into the input buffer, put length in len -- the input + buffer is double-sized just for this function, so there is guaranteed to + be state->size bytes available after the current contents */ + if (strm->avail_in == 0) + strm->next_in = state->in; + next = (char *)(strm->next_in + strm->avail_in); + next[state->size - 1] = 0; +#ifdef NO_snprintf +# ifdef HAS_sprintf_void + sprintf(next, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, + a13, a14, a15, a16, a17, a18, a19, a20); + for (len = 0; len < size; len++) + if (next[len] == 0) + break; +# else + len = sprintf(next, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, + a12, a13, a14, a15, a16, a17, a18, a19, a20); +# endif +#else +# ifdef HAS_snprintf_void + snprintf(next, state->size, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, + a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); + len = strlen(next); +# else + len = snprintf(next, state->size, format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); +# endif +#endif + + /* check that printf() results fit in buffer */ + if (len == 0 || len >= state->size || next[state->size - 1] != 0) + return 0; + + /* update buffer and position, compress first half if past that */ + strm->avail_in += len; + state->x.pos += len; + if (strm->avail_in >= state->size) { + left = strm->avail_in - state->size; + strm->avail_in = state->size; + if (gz_comp(state, Z_NO_FLUSH) == -1) + return state->err; + memmove(state->in, state->in + state->size, left); + strm->next_in = state->in; + strm->avail_in = left; + } + return (int)len; +} + +#endif + +/* -- see zlib.h -- */ +int ZEXPORT gzflush(gzFile file, int flush) { + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return Z_STREAM_ERROR; + + /* check flush parameter */ + if (flush < 0 || flush > Z_FINISH) + return Z_STREAM_ERROR; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return state->err; + } + + /* compress remaining data with requested flush */ + (void)gz_comp(state, flush); + return state->err; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzsetparams(gzFile file, int level, int strategy) { + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK || state->direct) + return Z_STREAM_ERROR; + + /* if no change is requested, then do nothing */ + if (level == state->level && strategy == state->strategy) + return Z_OK; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return state->err; + } + + /* change compression parameters for subsequent input */ + if (state->size) { + /* flush previous input with previous parameters before changing */ + if (strm->avail_in && gz_comp(state, Z_BLOCK) == -1) + return state->err; + deflateParams(strm, level, strategy); + } + state->level = level; + state->strategy = strategy; + return Z_OK; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzclose_w(gzFile file) { + int ret = Z_OK; + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + + /* check that we're writing */ + if (state->mode != GZ_WRITE) + return Z_STREAM_ERROR; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + ret = state->err; + } + + /* flush, free memory, and close file */ + if (gz_comp(state, Z_FINISH) == -1) + ret = state->err; + if (state->size) { + if (!state->direct) { + (void)deflateEnd(&(state->strm)); + free(state->out); + } + free(state->in); + } + gz_error(state, Z_OK, NULL); + free(state->path); + if (close(state->fd) == -1) + ret = Z_ERRNO; + free(state); + return ret; +} diff --git a/common/zlib/infback.c b/common/zlib/infback.c new file mode 100644 index 0000000..e7b25b3 --- /dev/null +++ b/common/zlib/infback.c @@ -0,0 +1,628 @@ +/* infback.c -- inflate using a call-back interface + * Copyright (C) 1995-2022 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + This code is largely copied from inflate.c. Normally either infback.o or + inflate.o would be linked into an application--not both. The interface + with inffast.c is retained so that optimized assembler-coded versions of + inflate_fast() can be used with either inflate.c or infback.c. + */ + +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inffast.h" + +/* + strm provides memory allocation functions in zalloc and zfree, or + Z_NULL to use the library memory allocation functions. + + windowBits is in the range 8..15, and window is a user-supplied + window and output buffer that is 2**windowBits bytes. + */ +int ZEXPORT inflateBackInit_(z_streamp strm, int windowBits, + unsigned char FAR *window, const char *version, + int stream_size) { + struct inflate_state FAR *state; + + if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || + stream_size != (int)(sizeof(z_stream))) + return Z_VERSION_ERROR; + if (strm == Z_NULL || window == Z_NULL || + windowBits < 8 || windowBits > 15) + return Z_STREAM_ERROR; + strm->msg = Z_NULL; /* in case we return an error */ + if (strm->zalloc == (alloc_func)0) { +#ifdef Z_SOLO + return Z_STREAM_ERROR; +#else + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; +#endif + } + if (strm->zfree == (free_func)0) +#ifdef Z_SOLO + return Z_STREAM_ERROR; +#else + strm->zfree = zcfree; +#endif + state = (struct inflate_state FAR *)ZALLOC(strm, 1, + sizeof(struct inflate_state)); + if (state == Z_NULL) return Z_MEM_ERROR; + Tracev((stderr, "inflate: allocated\n")); + strm->state = (struct internal_state FAR *)state; + state->dmax = 32768U; + state->wbits = (uInt)windowBits; + state->wsize = 1U << windowBits; + state->window = window; + state->wnext = 0; + state->whave = 0; + state->sane = 1; + return Z_OK; +} + +/* + Return state with length and distance decoding tables and index sizes set to + fixed code decoding. Normally this returns fixed tables from inffixed.h. + If BUILDFIXED is defined, then instead this routine builds the tables the + first time it's called, and returns those tables the first time and + thereafter. This reduces the size of the code by about 2K bytes, in + exchange for a little execution time. However, BUILDFIXED should not be + used for threaded applications, since the rewriting of the tables and virgin + may not be thread-safe. + */ +local void fixedtables(struct inflate_state FAR *state) { +#ifdef BUILDFIXED + static int virgin = 1; + static code *lenfix, *distfix; + static code fixed[544]; + + /* build fixed huffman tables if first call (may not be thread safe) */ + if (virgin) { + unsigned sym, bits; + static code *next; + + /* literal/length table */ + sym = 0; + while (sym < 144) state->lens[sym++] = 8; + while (sym < 256) state->lens[sym++] = 9; + while (sym < 280) state->lens[sym++] = 7; + while (sym < 288) state->lens[sym++] = 8; + next = fixed; + lenfix = next; + bits = 9; + inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); + + /* distance table */ + sym = 0; + while (sym < 32) state->lens[sym++] = 5; + distfix = next; + bits = 5; + inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); + + /* do this just once */ + virgin = 0; + } +#else /* !BUILDFIXED */ +# include "inffixed.h" +#endif /* BUILDFIXED */ + state->lencode = lenfix; + state->lenbits = 9; + state->distcode = distfix; + state->distbits = 5; +} + +/* Macros for inflateBack(): */ + +/* Load returned state from inflate_fast() */ +#define LOAD() \ + do { \ + put = strm->next_out; \ + left = strm->avail_out; \ + next = strm->next_in; \ + have = strm->avail_in; \ + hold = state->hold; \ + bits = state->bits; \ + } while (0) + +/* Set state from registers for inflate_fast() */ +#define RESTORE() \ + do { \ + strm->next_out = put; \ + strm->avail_out = left; \ + strm->next_in = next; \ + strm->avail_in = have; \ + state->hold = hold; \ + state->bits = bits; \ + } while (0) + +/* Clear the input bit accumulator */ +#define INITBITS() \ + do { \ + hold = 0; \ + bits = 0; \ + } while (0) + +/* Assure that some input is available. If input is requested, but denied, + then return a Z_BUF_ERROR from inflateBack(). */ +#define PULL() \ + do { \ + if (have == 0) { \ + have = in(in_desc, &next); \ + if (have == 0) { \ + next = Z_NULL; \ + ret = Z_BUF_ERROR; \ + goto inf_leave; \ + } \ + } \ + } while (0) + +/* Get a byte of input into the bit accumulator, or return from inflateBack() + with an error if there is no input available. */ +#define PULLBYTE() \ + do { \ + PULL(); \ + have--; \ + hold += (unsigned long)(*next++) << bits; \ + bits += 8; \ + } while (0) + +/* Assure that there are at least n bits in the bit accumulator. If there is + not enough available input to do that, then return from inflateBack() with + an error. */ +#define NEEDBITS(n) \ + do { \ + while (bits < (unsigned)(n)) \ + PULLBYTE(); \ + } while (0) + +/* Return the low n bits of the bit accumulator (n < 16) */ +#define BITS(n) \ + ((unsigned)hold & ((1U << (n)) - 1)) + +/* Remove n bits from the bit accumulator */ +#define DROPBITS(n) \ + do { \ + hold >>= (n); \ + bits -= (unsigned)(n); \ + } while (0) + +/* Remove zero to seven bits as needed to go to a byte boundary */ +#define BYTEBITS() \ + do { \ + hold >>= bits & 7; \ + bits -= bits & 7; \ + } while (0) + +/* Assure that some output space is available, by writing out the window + if it's full. If the write fails, return from inflateBack() with a + Z_BUF_ERROR. */ +#define ROOM() \ + do { \ + if (left == 0) { \ + put = state->window; \ + left = state->wsize; \ + state->whave = left; \ + if (out(out_desc, put, left)) { \ + ret = Z_BUF_ERROR; \ + goto inf_leave; \ + } \ + } \ + } while (0) + +/* + strm provides the memory allocation functions and window buffer on input, + and provides information on the unused input on return. For Z_DATA_ERROR + returns, strm will also provide an error message. + + in() and out() are the call-back input and output functions. When + inflateBack() needs more input, it calls in(). When inflateBack() has + filled the window with output, or when it completes with data in the + window, it calls out() to write out the data. The application must not + change the provided input until in() is called again or inflateBack() + returns. The application must not change the window/output buffer until + inflateBack() returns. + + in() and out() are called with a descriptor parameter provided in the + inflateBack() call. This parameter can be a structure that provides the + information required to do the read or write, as well as accumulated + information on the input and output such as totals and check values. + + in() should return zero on failure. out() should return non-zero on + failure. If either in() or out() fails, than inflateBack() returns a + Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it + was in() or out() that caused in the error. Otherwise, inflateBack() + returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format + error, or Z_MEM_ERROR if it could not allocate memory for the state. + inflateBack() can also return Z_STREAM_ERROR if the input parameters + are not correct, i.e. strm is Z_NULL or the state was not initialized. + */ +int ZEXPORT inflateBack(z_streamp strm, in_func in, void FAR *in_desc, + out_func out, void FAR *out_desc) { + struct inflate_state FAR *state; + z_const unsigned char FAR *next; /* next input */ + unsigned char FAR *put; /* next output */ + unsigned have, left; /* available input and output */ + unsigned long hold; /* bit buffer */ + unsigned bits; /* bits in bit buffer */ + unsigned copy; /* number of stored or match bytes to copy */ + unsigned char FAR *from; /* where to copy match bytes from */ + code here; /* current decoding table entry */ + code last; /* parent table entry */ + unsigned len; /* length to copy for repeats, bits to drop */ + int ret; /* return code */ + static const unsigned short order[19] = /* permutation of code lengths */ + {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + + /* Check that the strm exists and that the state was initialized */ + if (strm == Z_NULL || strm->state == Z_NULL) + return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + + /* Reset the state */ + strm->msg = Z_NULL; + state->mode = TYPE; + state->last = 0; + state->whave = 0; + next = strm->next_in; + have = next != Z_NULL ? strm->avail_in : 0; + hold = 0; + bits = 0; + put = state->window; + left = state->wsize; + + /* Inflate until end of block marked as last */ + for (;;) + switch (state->mode) { + case TYPE: + /* determine and dispatch block type */ + if (state->last) { + BYTEBITS(); + state->mode = DONE; + break; + } + NEEDBITS(3); + state->last = BITS(1); + DROPBITS(1); + switch (BITS(2)) { + case 0: /* stored block */ + Tracev((stderr, "inflate: stored block%s\n", + state->last ? " (last)" : "")); + state->mode = STORED; + break; + case 1: /* fixed block */ + fixedtables(state); + Tracev((stderr, "inflate: fixed codes block%s\n", + state->last ? " (last)" : "")); + state->mode = LEN; /* decode codes */ + break; + case 2: /* dynamic block */ + Tracev((stderr, "inflate: dynamic codes block%s\n", + state->last ? " (last)" : "")); + state->mode = TABLE; + break; + case 3: + strm->msg = (char *)"invalid block type"; + state->mode = BAD; + } + DROPBITS(2); + break; + + case STORED: + /* get and verify stored block length */ + BYTEBITS(); /* go to byte boundary */ + NEEDBITS(32); + if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { + strm->msg = (char *)"invalid stored block lengths"; + state->mode = BAD; + break; + } + state->length = (unsigned)hold & 0xffff; + Tracev((stderr, "inflate: stored length %u\n", + state->length)); + INITBITS(); + + /* copy stored block from input to output */ + while (state->length != 0) { + copy = state->length; + PULL(); + ROOM(); + if (copy > have) copy = have; + if (copy > left) copy = left; + zmemcpy(put, next, copy); + have -= copy; + next += copy; + left -= copy; + put += copy; + state->length -= copy; + } + Tracev((stderr, "inflate: stored end\n")); + state->mode = TYPE; + break; + + case TABLE: + /* get dynamic table entries descriptor */ + NEEDBITS(14); + state->nlen = BITS(5) + 257; + DROPBITS(5); + state->ndist = BITS(5) + 1; + DROPBITS(5); + state->ncode = BITS(4) + 4; + DROPBITS(4); +#ifndef PKZIP_BUG_WORKAROUND + if (state->nlen > 286 || state->ndist > 30) { + strm->msg = (char *)"too many length or distance symbols"; + state->mode = BAD; + break; + } +#endif + Tracev((stderr, "inflate: table sizes ok\n")); + + /* get code length code lengths (not a typo) */ + state->have = 0; + while (state->have < state->ncode) { + NEEDBITS(3); + state->lens[order[state->have++]] = (unsigned short)BITS(3); + DROPBITS(3); + } + while (state->have < 19) + state->lens[order[state->have++]] = 0; + state->next = state->codes; + state->lencode = (code const FAR *)(state->next); + state->lenbits = 7; + ret = inflate_table(CODES, state->lens, 19, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid code lengths set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: code lengths ok\n")); + + /* get length and distance code code lengths */ + state->have = 0; + while (state->have < state->nlen + state->ndist) { + for (;;) { + here = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if (here.val < 16) { + DROPBITS(here.bits); + state->lens[state->have++] = here.val; + } + else { + if (here.val == 16) { + NEEDBITS(here.bits + 2); + DROPBITS(here.bits); + if (state->have == 0) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + len = (unsigned)(state->lens[state->have - 1]); + copy = 3 + BITS(2); + DROPBITS(2); + } + else if (here.val == 17) { + NEEDBITS(here.bits + 3); + DROPBITS(here.bits); + len = 0; + copy = 3 + BITS(3); + DROPBITS(3); + } + else { + NEEDBITS(here.bits + 7); + DROPBITS(here.bits); + len = 0; + copy = 11 + BITS(7); + DROPBITS(7); + } + if (state->have + copy > state->nlen + state->ndist) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + while (copy--) + state->lens[state->have++] = (unsigned short)len; + } + } + + /* handle error breaks in while */ + if (state->mode == BAD) break; + + /* check for end-of-block code (better have one) */ + if (state->lens[256] == 0) { + strm->msg = (char *)"invalid code -- missing end-of-block"; + state->mode = BAD; + break; + } + + /* build code tables -- note: do not change the lenbits or distbits + values here (9 and 6) without reading the comments in inftrees.h + concerning the ENOUGH constants, which depend on those values */ + state->next = state->codes; + state->lencode = (code const FAR *)(state->next); + state->lenbits = 9; + ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid literal/lengths set"; + state->mode = BAD; + break; + } + state->distcode = (code const FAR *)(state->next); + state->distbits = 6; + ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, + &(state->next), &(state->distbits), state->work); + if (ret) { + strm->msg = (char *)"invalid distances set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: codes ok\n")); + state->mode = LEN; + /* fallthrough */ + + case LEN: + /* use inflate_fast() if we have enough input and output */ + if (have >= 6 && left >= 258) { + RESTORE(); + if (state->whave < state->wsize) + state->whave = state->wsize - left; + inflate_fast(strm, state->wsize); + LOAD(); + break; + } + + /* get a literal, length, or end-of-block code */ + for (;;) { + here = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if (here.op && (here.op & 0xf0) == 0) { + last = here; + for (;;) { + here = state->lencode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + here.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + } + DROPBITS(here.bits); + state->length = (unsigned)here.val; + + /* process literal */ + if (here.op == 0) { + Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", here.val)); + ROOM(); + *put++ = (unsigned char)(state->length); + left--; + state->mode = LEN; + break; + } + + /* process end of block */ + if (here.op & 32) { + Tracevv((stderr, "inflate: end of block\n")); + state->mode = TYPE; + break; + } + + /* invalid code */ + if (here.op & 64) { + strm->msg = (char *)"invalid literal/length code"; + state->mode = BAD; + break; + } + + /* length code -- get extra bits, if any */ + state->extra = (unsigned)(here.op) & 15; + if (state->extra != 0) { + NEEDBITS(state->extra); + state->length += BITS(state->extra); + DROPBITS(state->extra); + } + Tracevv((stderr, "inflate: length %u\n", state->length)); + + /* get distance code */ + for (;;) { + here = state->distcode[BITS(state->distbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if ((here.op & 0xf0) == 0) { + last = here; + for (;;) { + here = state->distcode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + here.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + } + DROPBITS(here.bits); + if (here.op & 64) { + strm->msg = (char *)"invalid distance code"; + state->mode = BAD; + break; + } + state->offset = (unsigned)here.val; + + /* get distance extra bits, if any */ + state->extra = (unsigned)(here.op) & 15; + if (state->extra != 0) { + NEEDBITS(state->extra); + state->offset += BITS(state->extra); + DROPBITS(state->extra); + } + if (state->offset > state->wsize - (state->whave < state->wsize ? + left : 0)) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } + Tracevv((stderr, "inflate: distance %u\n", state->offset)); + + /* copy match from window to output */ + do { + ROOM(); + copy = state->wsize - state->offset; + if (copy < left) { + from = put + copy; + copy = left - copy; + } + else { + from = put - state->offset; + copy = left; + } + if (copy > state->length) copy = state->length; + state->length -= copy; + left -= copy; + do { + *put++ = *from++; + } while (--copy); + } while (state->length != 0); + break; + + case DONE: + /* inflate stream terminated properly */ + ret = Z_STREAM_END; + goto inf_leave; + + case BAD: + ret = Z_DATA_ERROR; + goto inf_leave; + + default: + /* can't happen, but makes compilers happy */ + ret = Z_STREAM_ERROR; + goto inf_leave; + } + + /* Write leftover output and return unused input */ + inf_leave: + if (left < state->wsize) { + if (out(out_desc, state->window, state->wsize - left) && + ret == Z_STREAM_END) + ret = Z_BUF_ERROR; + } + strm->next_in = next; + strm->avail_in = have; + return ret; +} + +int ZEXPORT inflateBackEnd(z_streamp strm) { + if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) + return Z_STREAM_ERROR; + ZFREE(strm, strm->state); + strm->state = Z_NULL; + Tracev((stderr, "inflate: end\n")); + return Z_OK; +} diff --git a/common/zlib/inffast.c b/common/zlib/inffast.c new file mode 100644 index 0000000..9354676 --- /dev/null +++ b/common/zlib/inffast.c @@ -0,0 +1,320 @@ +/* inffast.c -- fast decoding + * Copyright (C) 1995-2017 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inffast.h" + +#ifdef ASMINF +# pragma message("Assembler code may have bugs -- use at your own risk") +#else + +/* + Decode literal, length, and distance codes and write out the resulting + literal and match bytes until either not enough input or output is + available, an end-of-block is encountered, or a data error is encountered. + When large enough input and output buffers are supplied to inflate(), for + example, a 16K input buffer and a 64K output buffer, more than 95% of the + inflate execution time is spent in this routine. + + Entry assumptions: + + state->mode == LEN + strm->avail_in >= 6 + strm->avail_out >= 258 + start >= strm->avail_out + state->bits < 8 + + On return, state->mode is one of: + + LEN -- ran out of enough output space or enough available input + TYPE -- reached end of block code, inflate() to interpret next block + BAD -- error in block data + + Notes: + + - The maximum input bits used by a length/distance pair is 15 bits for the + length code, 5 bits for the length extra, 15 bits for the distance code, + and 13 bits for the distance extra. This totals 48 bits, or six bytes. + Therefore if strm->avail_in >= 6, then there is enough input to avoid + checking for available input while decoding. + + - The maximum bytes that a single length/distance pair can output is 258 + bytes, which is the maximum length that can be coded. inflate_fast() + requires strm->avail_out >= 258 for each loop to avoid checking for + output space. + */ +void ZLIB_INTERNAL inflate_fast(z_streamp strm, unsigned start) { + struct inflate_state FAR *state; + z_const unsigned char FAR *in; /* local strm->next_in */ + z_const unsigned char FAR *last; /* have enough input while in < last */ + unsigned char FAR *out; /* local strm->next_out */ + unsigned char FAR *beg; /* inflate()'s initial strm->next_out */ + unsigned char FAR *end; /* while out < end, enough space available */ +#ifdef INFLATE_STRICT + unsigned dmax; /* maximum distance from zlib header */ +#endif + unsigned wsize; /* window size or zero if not using window */ + unsigned whave; /* valid bytes in the window */ + unsigned wnext; /* window write index */ + unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */ + unsigned long hold; /* local strm->hold */ + unsigned bits; /* local strm->bits */ + code const FAR *lcode; /* local strm->lencode */ + code const FAR *dcode; /* local strm->distcode */ + unsigned lmask; /* mask for first level of length codes */ + unsigned dmask; /* mask for first level of distance codes */ + code const *here; /* retrieved table entry */ + unsigned op; /* code bits, operation, extra bits, or */ + /* window position, window bytes to copy */ + unsigned len; /* match length, unused bytes */ + unsigned dist; /* match distance */ + unsigned char FAR *from; /* where to copy match from */ + + /* copy state to local variables */ + state = (struct inflate_state FAR *)strm->state; + in = strm->next_in; + last = in + (strm->avail_in - 5); + out = strm->next_out; + beg = out - (start - strm->avail_out); + end = out + (strm->avail_out - 257); +#ifdef INFLATE_STRICT + dmax = state->dmax; +#endif + wsize = state->wsize; + whave = state->whave; + wnext = state->wnext; + window = state->window; + hold = state->hold; + bits = state->bits; + lcode = state->lencode; + dcode = state->distcode; + lmask = (1U << state->lenbits) - 1; + dmask = (1U << state->distbits) - 1; + + /* decode literals and length/distances until end-of-block or not enough + input data or output space */ + do { + if (bits < 15) { + hold += (unsigned long)(*in++) << bits; + bits += 8; + hold += (unsigned long)(*in++) << bits; + bits += 8; + } + here = lcode + (hold & lmask); + dolen: + op = (unsigned)(here->bits); + hold >>= op; + bits -= op; + op = (unsigned)(here->op); + if (op == 0) { /* literal */ + Tracevv((stderr, here->val >= 0x20 && here->val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", here->val)); + *out++ = (unsigned char)(here->val); + } + else if (op & 16) { /* length base */ + len = (unsigned)(here->val); + op &= 15; /* number of extra bits */ + if (op) { + if (bits < op) { + hold += (unsigned long)(*in++) << bits; + bits += 8; + } + len += (unsigned)hold & ((1U << op) - 1); + hold >>= op; + bits -= op; + } + Tracevv((stderr, "inflate: length %u\n", len)); + if (bits < 15) { + hold += (unsigned long)(*in++) << bits; + bits += 8; + hold += (unsigned long)(*in++) << bits; + bits += 8; + } + here = dcode + (hold & dmask); + dodist: + op = (unsigned)(here->bits); + hold >>= op; + bits -= op; + op = (unsigned)(here->op); + if (op & 16) { /* distance base */ + dist = (unsigned)(here->val); + op &= 15; /* number of extra bits */ + if (bits < op) { + hold += (unsigned long)(*in++) << bits; + bits += 8; + if (bits < op) { + hold += (unsigned long)(*in++) << bits; + bits += 8; + } + } + dist += (unsigned)hold & ((1U << op) - 1); +#ifdef INFLATE_STRICT + if (dist > dmax) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#endif + hold >>= op; + bits -= op; + Tracevv((stderr, "inflate: distance %u\n", dist)); + op = (unsigned)(out - beg); /* max distance in output */ + if (dist > op) { /* see if copy from window */ + op = dist - op; /* distance back in window */ + if (op > whave) { + if (state->sane) { + strm->msg = + (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + if (len <= op - whave) { + do { + *out++ = 0; + } while (--len); + continue; + } + len -= op - whave; + do { + *out++ = 0; + } while (--op > whave); + if (op == 0) { + from = out - dist; + do { + *out++ = *from++; + } while (--len); + continue; + } +#endif + } + from = window; + if (wnext == 0) { /* very common case */ + from += wsize - op; + if (op < len) { /* some from window */ + len -= op; + do { + *out++ = *from++; + } while (--op); + from = out - dist; /* rest from output */ + } + } + else if (wnext < op) { /* wrap around window */ + from += wsize + wnext - op; + op -= wnext; + if (op < len) { /* some from end of window */ + len -= op; + do { + *out++ = *from++; + } while (--op); + from = window; + if (wnext < len) { /* some from start of window */ + op = wnext; + len -= op; + do { + *out++ = *from++; + } while (--op); + from = out - dist; /* rest from output */ + } + } + } + else { /* contiguous in window */ + from += wnext - op; + if (op < len) { /* some from window */ + len -= op; + do { + *out++ = *from++; + } while (--op); + from = out - dist; /* rest from output */ + } + } + while (len > 2) { + *out++ = *from++; + *out++ = *from++; + *out++ = *from++; + len -= 3; + } + if (len) { + *out++ = *from++; + if (len > 1) + *out++ = *from++; + } + } + else { + from = out - dist; /* copy direct from output */ + do { /* minimum length is three */ + *out++ = *from++; + *out++ = *from++; + *out++ = *from++; + len -= 3; + } while (len > 2); + if (len) { + *out++ = *from++; + if (len > 1) + *out++ = *from++; + } + } + } + else if ((op & 64) == 0) { /* 2nd level distance code */ + here = dcode + here->val + (hold & ((1U << op) - 1)); + goto dodist; + } + else { + strm->msg = (char *)"invalid distance code"; + state->mode = BAD; + break; + } + } + else if ((op & 64) == 0) { /* 2nd level length code */ + here = lcode + here->val + (hold & ((1U << op) - 1)); + goto dolen; + } + else if (op & 32) { /* end-of-block */ + Tracevv((stderr, "inflate: end of block\n")); + state->mode = TYPE; + break; + } + else { + strm->msg = (char *)"invalid literal/length code"; + state->mode = BAD; + break; + } + } while (in < last && out < end); + + /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ + len = bits >> 3; + in -= len; + bits -= len << 3; + hold &= (1U << bits) - 1; + + /* update state and return */ + strm->next_in = in; + strm->next_out = out; + strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last)); + strm->avail_out = (unsigned)(out < end ? + 257 + (end - out) : 257 - (out - end)); + state->hold = hold; + state->bits = bits; + return; +} + +/* + inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe): + - Using bit fields for code structure + - Different op definition to avoid & for extra bits (do & for table bits) + - Three separate decoding do-loops for direct, window, and wnext == 0 + - Special case for distance > 1 copies to do overlapped load and store copy + - Explicit branch predictions (based on measured branch probabilities) + - Deferring match copy and interspersed it with decoding subsequent codes + - Swapping literal/length else + - Swapping window/direct else + - Larger unrolled copy loops (three is about right) + - Moving len -= 3 statement into middle of loop + */ + +#endif /* !ASMINF */ diff --git a/common/zlib/inffast.h b/common/zlib/inffast.h new file mode 100644 index 0000000..49c6d15 --- /dev/null +++ b/common/zlib/inffast.h @@ -0,0 +1,11 @@ +/* inffast.h -- header to use inffast.c + * Copyright (C) 1995-2003, 2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +void ZLIB_INTERNAL inflate_fast(z_streamp strm, unsigned start); diff --git a/common/zlib/inffixed.h b/common/zlib/inffixed.h new file mode 100644 index 0000000..d628327 --- /dev/null +++ b/common/zlib/inffixed.h @@ -0,0 +1,94 @@ + /* inffixed.h -- table for decoding fixed codes + * Generated automatically by makefixed(). + */ + + /* WARNING: this file should *not* be used by applications. + It is part of the implementation of this library and is + subject to change. Applications should only use zlib.h. + */ + + static const code lenfix[512] = { + {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48}, + {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128}, + {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59}, + {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176}, + {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20}, + {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100}, + {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8}, + {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216}, + {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76}, + {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114}, + {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2}, + {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148}, + {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42}, + {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86}, + {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15}, + {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236}, + {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62}, + {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142}, + {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31}, + {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162}, + {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25}, + {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105}, + {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4}, + {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202}, + {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69}, + {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125}, + {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13}, + {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195}, + {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35}, + {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91}, + {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19}, + {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246}, + {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55}, + {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135}, + {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99}, + {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190}, + {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16}, + {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96}, + {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6}, + {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209}, + {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72}, + {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116}, + {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4}, + {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153}, + {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44}, + {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82}, + {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11}, + {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229}, + {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58}, + {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138}, + {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51}, + {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173}, + {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30}, + {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110}, + {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0}, + {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195}, + {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65}, + {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121}, + {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9}, + {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258}, + {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37}, + {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93}, + {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23}, + {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251}, + {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51}, + {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131}, + {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67}, + {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183}, + {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23}, + {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103}, + {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9}, + {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223}, + {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79}, + {0,9,255} + }; + + static const code distfix[32] = { + {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025}, + {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193}, + {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385}, + {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577}, + {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073}, + {22,5,193},{64,5,0} + }; diff --git a/common/zlib/inflate.c b/common/zlib/inflate.c new file mode 100644 index 0000000..94ecff0 --- /dev/null +++ b/common/zlib/inflate.c @@ -0,0 +1,1526 @@ +/* inflate.c -- zlib decompression + * Copyright (C) 1995-2022 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * Change history: + * + * 1.2.beta0 24 Nov 2002 + * - First version -- complete rewrite of inflate to simplify code, avoid + * creation of window when not needed, minimize use of window when it is + * needed, make inffast.c even faster, implement gzip decoding, and to + * improve code readability and style over the previous zlib inflate code + * + * 1.2.beta1 25 Nov 2002 + * - Use pointers for available input and output checking in inffast.c + * - Remove input and output counters in inffast.c + * - Change inffast.c entry and loop from avail_in >= 7 to >= 6 + * - Remove unnecessary second byte pull from length extra in inffast.c + * - Unroll direct copy to three copies per loop in inffast.c + * + * 1.2.beta2 4 Dec 2002 + * - Change external routine names to reduce potential conflicts + * - Correct filename to inffixed.h for fixed tables in inflate.c + * - Make hbuf[] unsigned char to match parameter type in inflate.c + * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset) + * to avoid negation problem on Alphas (64 bit) in inflate.c + * + * 1.2.beta3 22 Dec 2002 + * - Add comments on state->bits assertion in inffast.c + * - Add comments on op field in inftrees.h + * - Fix bug in reuse of allocated window after inflateReset() + * - Remove bit fields--back to byte structure for speed + * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths + * - Change post-increments to pre-increments in inflate_fast(), PPC biased? + * - Add compile time option, POSTINC, to use post-increments instead (Intel?) + * - Make MATCH copy in inflate() much faster for when inflate_fast() not used + * - Use local copies of stream next and avail values, as well as local bit + * buffer and bit count in inflate()--for speed when inflate_fast() not used + * + * 1.2.beta4 1 Jan 2003 + * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings + * - Move a comment on output buffer sizes from inffast.c to inflate.c + * - Add comments in inffast.c to introduce the inflate_fast() routine + * - Rearrange window copies in inflate_fast() for speed and simplification + * - Unroll last copy for window match in inflate_fast() + * - Use local copies of window variables in inflate_fast() for speed + * - Pull out common wnext == 0 case for speed in inflate_fast() + * - Make op and len in inflate_fast() unsigned for consistency + * - Add FAR to lcode and dcode declarations in inflate_fast() + * - Simplified bad distance check in inflate_fast() + * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new + * source file infback.c to provide a call-back interface to inflate for + * programs like gzip and unzip -- uses window as output buffer to avoid + * window copying + * + * 1.2.beta5 1 Jan 2003 + * - Improved inflateBack() interface to allow the caller to provide initial + * input in strm. + * - Fixed stored blocks bug in inflateBack() + * + * 1.2.beta6 4 Jan 2003 + * - Added comments in inffast.c on effectiveness of POSTINC + * - Typecasting all around to reduce compiler warnings + * - Changed loops from while (1) or do {} while (1) to for (;;), again to + * make compilers happy + * - Changed type of window in inflateBackInit() to unsigned char * + * + * 1.2.beta7 27 Jan 2003 + * - Changed many types to unsigned or unsigned short to avoid warnings + * - Added inflateCopy() function + * + * 1.2.0 9 Mar 2003 + * - Changed inflateBack() interface to provide separate opaque descriptors + * for the in() and out() functions + * - Changed inflateBack() argument and in_func typedef to swap the length + * and buffer address return values for the input function + * - Check next_in and next_out for Z_NULL on entry to inflate() + * + * The history for versions after 1.2.0 are in ChangeLog in zlib distribution. + */ + +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inffast.h" + +#ifdef MAKEFIXED +# ifndef BUILDFIXED +# define BUILDFIXED +# endif +#endif + +local int inflateStateCheck(z_streamp strm) { + struct inflate_state FAR *state; + if (strm == Z_NULL || + strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) + return 1; + state = (struct inflate_state FAR *)strm->state; + if (state == Z_NULL || state->strm != strm || + state->mode < HEAD || state->mode > SYNC) + return 1; + return 0; +} + +int ZEXPORT inflateResetKeep(z_streamp strm) { + struct inflate_state FAR *state; + + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + strm->total_in = strm->total_out = state->total = 0; + strm->msg = Z_NULL; + if (state->wrap) /* to support ill-conceived Java test suite */ + strm->adler = state->wrap & 1; + state->mode = HEAD; + state->last = 0; + state->havedict = 0; + state->flags = -1; + state->dmax = 32768U; + state->head = Z_NULL; + state->hold = 0; + state->bits = 0; + state->lencode = state->distcode = state->next = state->codes; + state->sane = 1; + state->back = -1; + Tracev((stderr, "inflate: reset\n")); + return Z_OK; +} + +int ZEXPORT inflateReset(z_streamp strm) { + struct inflate_state FAR *state; + + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + state->wsize = 0; + state->whave = 0; + state->wnext = 0; + return inflateResetKeep(strm); +} + +int ZEXPORT inflateReset2(z_streamp strm, int windowBits) { + int wrap; + struct inflate_state FAR *state; + + /* get the state */ + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + + /* extract wrap request from windowBits parameter */ + if (windowBits < 0) { + if (windowBits < -15) + return Z_STREAM_ERROR; + wrap = 0; + windowBits = -windowBits; + } + else { + wrap = (windowBits >> 4) + 5; +#ifdef GUNZIP + if (windowBits < 48) + windowBits &= 15; +#endif + } + + /* set number of window bits, free window if different */ + if (windowBits && (windowBits < 8 || windowBits > 15)) + return Z_STREAM_ERROR; + if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) { + ZFREE(strm, state->window); + state->window = Z_NULL; + } + + /* update state and reset the rest of it */ + state->wrap = wrap; + state->wbits = (unsigned)windowBits; + return inflateReset(strm); +} + +int ZEXPORT inflateInit2_(z_streamp strm, int windowBits, + const char *version, int stream_size) { + int ret; + struct inflate_state FAR *state; + + if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || + stream_size != (int)(sizeof(z_stream))) + return Z_VERSION_ERROR; + if (strm == Z_NULL) return Z_STREAM_ERROR; + strm->msg = Z_NULL; /* in case we return an error */ + if (strm->zalloc == (alloc_func)0) { +#ifdef Z_SOLO + return Z_STREAM_ERROR; +#else + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; +#endif + } + if (strm->zfree == (free_func)0) +#ifdef Z_SOLO + return Z_STREAM_ERROR; +#else + strm->zfree = zcfree; +#endif + state = (struct inflate_state FAR *) + ZALLOC(strm, 1, sizeof(struct inflate_state)); + if (state == Z_NULL) return Z_MEM_ERROR; + Tracev((stderr, "inflate: allocated\n")); + strm->state = (struct internal_state FAR *)state; + state->strm = strm; + state->window = Z_NULL; + state->mode = HEAD; /* to pass state test in inflateReset2() */ + ret = inflateReset2(strm, windowBits); + if (ret != Z_OK) { + ZFREE(strm, state); + strm->state = Z_NULL; + } + return ret; +} + +int ZEXPORT inflateInit_(z_streamp strm, const char *version, + int stream_size) { + return inflateInit2_(strm, DEF_WBITS, version, stream_size); +} + +int ZEXPORT inflatePrime(z_streamp strm, int bits, int value) { + struct inflate_state FAR *state; + + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + if (bits == 0) + return Z_OK; + state = (struct inflate_state FAR *)strm->state; + if (bits < 0) { + state->hold = 0; + state->bits = 0; + return Z_OK; + } + if (bits > 16 || state->bits + (uInt)bits > 32) return Z_STREAM_ERROR; + value &= (1L << bits) - 1; + state->hold += (unsigned)value << state->bits; + state->bits += (uInt)bits; + return Z_OK; +} + +/* + Return state with length and distance decoding tables and index sizes set to + fixed code decoding. Normally this returns fixed tables from inffixed.h. + If BUILDFIXED is defined, then instead this routine builds the tables the + first time it's called, and returns those tables the first time and + thereafter. This reduces the size of the code by about 2K bytes, in + exchange for a little execution time. However, BUILDFIXED should not be + used for threaded applications, since the rewriting of the tables and virgin + may not be thread-safe. + */ +local void fixedtables(struct inflate_state FAR *state) { +#ifdef BUILDFIXED + static int virgin = 1; + static code *lenfix, *distfix; + static code fixed[544]; + + /* build fixed huffman tables if first call (may not be thread safe) */ + if (virgin) { + unsigned sym, bits; + static code *next; + + /* literal/length table */ + sym = 0; + while (sym < 144) state->lens[sym++] = 8; + while (sym < 256) state->lens[sym++] = 9; + while (sym < 280) state->lens[sym++] = 7; + while (sym < 288) state->lens[sym++] = 8; + next = fixed; + lenfix = next; + bits = 9; + inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); + + /* distance table */ + sym = 0; + while (sym < 32) state->lens[sym++] = 5; + distfix = next; + bits = 5; + inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); + + /* do this just once */ + virgin = 0; + } +#else /* !BUILDFIXED */ +# include "inffixed.h" +#endif /* BUILDFIXED */ + state->lencode = lenfix; + state->lenbits = 9; + state->distcode = distfix; + state->distbits = 5; +} + +#ifdef MAKEFIXED +#include + +/* + Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also + defines BUILDFIXED, so the tables are built on the fly. makefixed() writes + those tables to stdout, which would be piped to inffixed.h. A small program + can simply call makefixed to do this: + + void makefixed(void); + + int main(void) + { + makefixed(); + return 0; + } + + Then that can be linked with zlib built with MAKEFIXED defined and run: + + a.out > inffixed.h + */ +void makefixed(void) +{ + unsigned low, size; + struct inflate_state state; + + fixedtables(&state); + puts(" /* inffixed.h -- table for decoding fixed codes"); + puts(" * Generated automatically by makefixed()."); + puts(" */"); + puts(""); + puts(" /* WARNING: this file should *not* be used by applications."); + puts(" It is part of the implementation of this library and is"); + puts(" subject to change. Applications should only use zlib.h."); + puts(" */"); + puts(""); + size = 1U << 9; + printf(" static const code lenfix[%u] = {", size); + low = 0; + for (;;) { + if ((low % 7) == 0) printf("\n "); + printf("{%u,%u,%d}", (low & 127) == 99 ? 64 : state.lencode[low].op, + state.lencode[low].bits, state.lencode[low].val); + if (++low == size) break; + putchar(','); + } + puts("\n };"); + size = 1U << 5; + printf("\n static const code distfix[%u] = {", size); + low = 0; + for (;;) { + if ((low % 6) == 0) printf("\n "); + printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits, + state.distcode[low].val); + if (++low == size) break; + putchar(','); + } + puts("\n };"); +} +#endif /* MAKEFIXED */ + +/* + Update the window with the last wsize (normally 32K) bytes written before + returning. If window does not exist yet, create it. This is only called + when a window is already in use, or when output has been written during this + inflate call, but the end of the deflate stream has not been reached yet. + It is also called to create a window for dictionary data when a dictionary + is loaded. + + Providing output buffers larger than 32K to inflate() should provide a speed + advantage, since only the last 32K of output is copied to the sliding window + upon return from inflate(), and since all distances after the first 32K of + output will fall in the output data, making match copies simpler and faster. + The advantage may be dependent on the size of the processor's data caches. + */ +local int updatewindow(z_streamp strm, const Bytef *end, unsigned copy) { + struct inflate_state FAR *state; + unsigned dist; + + state = (struct inflate_state FAR *)strm->state; + + /* if it hasn't been done already, allocate space for the window */ + if (state->window == Z_NULL) { + state->window = (unsigned char FAR *) + ZALLOC(strm, 1U << state->wbits, + sizeof(unsigned char)); + if (state->window == Z_NULL) return 1; + } + + /* if window not in use yet, initialize */ + if (state->wsize == 0) { + state->wsize = 1U << state->wbits; + state->wnext = 0; + state->whave = 0; + } + + /* copy state->wsize or less output bytes into the circular window */ + if (copy >= state->wsize) { + zmemcpy(state->window, end - state->wsize, state->wsize); + state->wnext = 0; + state->whave = state->wsize; + } + else { + dist = state->wsize - state->wnext; + if (dist > copy) dist = copy; + zmemcpy(state->window + state->wnext, end - copy, dist); + copy -= dist; + if (copy) { + zmemcpy(state->window, end - copy, copy); + state->wnext = copy; + state->whave = state->wsize; + } + else { + state->wnext += dist; + if (state->wnext == state->wsize) state->wnext = 0; + if (state->whave < state->wsize) state->whave += dist; + } + } + return 0; +} + +/* Macros for inflate(): */ + +/* check function to use adler32() for zlib or crc32() for gzip */ +#ifdef GUNZIP +# define UPDATE_CHECK(check, buf, len) \ + (state->flags ? crc32(check, buf, len) : adler32(check, buf, len)) +#else +# define UPDATE_CHECK(check, buf, len) adler32(check, buf, len) +#endif + +/* check macros for header crc */ +#ifdef GUNZIP +# define CRC2(check, word) \ + do { \ + hbuf[0] = (unsigned char)(word); \ + hbuf[1] = (unsigned char)((word) >> 8); \ + check = crc32(check, hbuf, 2); \ + } while (0) + +# define CRC4(check, word) \ + do { \ + hbuf[0] = (unsigned char)(word); \ + hbuf[1] = (unsigned char)((word) >> 8); \ + hbuf[2] = (unsigned char)((word) >> 16); \ + hbuf[3] = (unsigned char)((word) >> 24); \ + check = crc32(check, hbuf, 4); \ + } while (0) +#endif + +/* Load registers with state in inflate() for speed */ +#define LOAD() \ + do { \ + put = strm->next_out; \ + left = strm->avail_out; \ + next = strm->next_in; \ + have = strm->avail_in; \ + hold = state->hold; \ + bits = state->bits; \ + } while (0) + +/* Restore state from registers in inflate() */ +#define RESTORE() \ + do { \ + strm->next_out = put; \ + strm->avail_out = left; \ + strm->next_in = next; \ + strm->avail_in = have; \ + state->hold = hold; \ + state->bits = bits; \ + } while (0) + +/* Clear the input bit accumulator */ +#define INITBITS() \ + do { \ + hold = 0; \ + bits = 0; \ + } while (0) + +/* Get a byte of input into the bit accumulator, or return from inflate() + if there is no input available. */ +#define PULLBYTE() \ + do { \ + if (have == 0) goto inf_leave; \ + have--; \ + hold += (unsigned long)(*next++) << bits; \ + bits += 8; \ + } while (0) + +/* Assure that there are at least n bits in the bit accumulator. If there is + not enough available input to do that, then return from inflate(). */ +#define NEEDBITS(n) \ + do { \ + while (bits < (unsigned)(n)) \ + PULLBYTE(); \ + } while (0) + +/* Return the low n bits of the bit accumulator (n < 16) */ +#define BITS(n) \ + ((unsigned)hold & ((1U << (n)) - 1)) + +/* Remove n bits from the bit accumulator */ +#define DROPBITS(n) \ + do { \ + hold >>= (n); \ + bits -= (unsigned)(n); \ + } while (0) + +/* Remove zero to seven bits as needed to go to a byte boundary */ +#define BYTEBITS() \ + do { \ + hold >>= bits & 7; \ + bits -= bits & 7; \ + } while (0) + +/* + inflate() uses a state machine to process as much input data and generate as + much output data as possible before returning. The state machine is + structured roughly as follows: + + for (;;) switch (state) { + ... + case STATEn: + if (not enough input data or output space to make progress) + return; + ... make progress ... + state = STATEm; + break; + ... + } + + so when inflate() is called again, the same case is attempted again, and + if the appropriate resources are provided, the machine proceeds to the + next state. The NEEDBITS() macro is usually the way the state evaluates + whether it can proceed or should return. NEEDBITS() does the return if + the requested bits are not available. The typical use of the BITS macros + is: + + NEEDBITS(n); + ... do something with BITS(n) ... + DROPBITS(n); + + where NEEDBITS(n) either returns from inflate() if there isn't enough + input left to load n bits into the accumulator, or it continues. BITS(n) + gives the low n bits in the accumulator. When done, DROPBITS(n) drops + the low n bits off the accumulator. INITBITS() clears the accumulator + and sets the number of available bits to zero. BYTEBITS() discards just + enough bits to put the accumulator on a byte boundary. After BYTEBITS() + and a NEEDBITS(8), then BITS(8) would return the next byte in the stream. + + NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return + if there is no input available. The decoding of variable length codes uses + PULLBYTE() directly in order to pull just enough bytes to decode the next + code, and no more. + + Some states loop until they get enough input, making sure that enough + state information is maintained to continue the loop where it left off + if NEEDBITS() returns in the loop. For example, want, need, and keep + would all have to actually be part of the saved state in case NEEDBITS() + returns: + + case STATEw: + while (want < need) { + NEEDBITS(n); + keep[want++] = BITS(n); + DROPBITS(n); + } + state = STATEx; + case STATEx: + + As shown above, if the next state is also the next case, then the break + is omitted. + + A state may also return if there is not enough output space available to + complete that state. Those states are copying stored data, writing a + literal byte, and copying a matching string. + + When returning, a "goto inf_leave" is used to update the total counters, + update the check value, and determine whether any progress has been made + during that inflate() call in order to return the proper return code. + Progress is defined as a change in either strm->avail_in or strm->avail_out. + When there is a window, goto inf_leave will update the window with the last + output written. If a goto inf_leave occurs in the middle of decompression + and there is no window currently, goto inf_leave will create one and copy + output to the window for the next call of inflate(). + + In this implementation, the flush parameter of inflate() only affects the + return code (per zlib.h). inflate() always writes as much as possible to + strm->next_out, given the space available and the provided input--the effect + documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers + the allocation of and copying into a sliding window until necessary, which + provides the effect documented in zlib.h for Z_FINISH when the entire input + stream available. So the only thing the flush parameter actually does is: + when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it + will return Z_BUF_ERROR if it has not reached the end of the stream. + */ + +int ZEXPORT inflate(z_streamp strm, int flush) { + struct inflate_state FAR *state; + z_const unsigned char FAR *next; /* next input */ + unsigned char FAR *put; /* next output */ + unsigned have, left; /* available input and output */ + unsigned long hold; /* bit buffer */ + unsigned bits; /* bits in bit buffer */ + unsigned in, out; /* save starting available input and output */ + unsigned copy; /* number of stored or match bytes to copy */ + unsigned char FAR *from; /* where to copy match bytes from */ + code here; /* current decoding table entry */ + code last; /* parent table entry */ + unsigned len; /* length to copy for repeats, bits to drop */ + int ret; /* return code */ +#ifdef GUNZIP + unsigned char hbuf[4]; /* buffer for gzip header crc calculation */ +#endif + static const unsigned short order[19] = /* permutation of code lengths */ + {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + + if (inflateStateCheck(strm) || strm->next_out == Z_NULL || + (strm->next_in == Z_NULL && strm->avail_in != 0)) + return Z_STREAM_ERROR; + + state = (struct inflate_state FAR *)strm->state; + if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */ + LOAD(); + in = have; + out = left; + ret = Z_OK; + for (;;) + switch (state->mode) { + case HEAD: + if (state->wrap == 0) { + state->mode = TYPEDO; + break; + } + NEEDBITS(16); +#ifdef GUNZIP + if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */ + if (state->wbits == 0) + state->wbits = 15; + state->check = crc32(0L, Z_NULL, 0); + CRC2(state->check, hold); + INITBITS(); + state->mode = FLAGS; + break; + } + if (state->head != Z_NULL) + state->head->done = -1; + if (!(state->wrap & 1) || /* check if zlib header allowed */ +#else + if ( +#endif + ((BITS(8) << 8) + (hold >> 8)) % 31) { + strm->msg = (char *)"incorrect header check"; + state->mode = BAD; + break; + } + if (BITS(4) != Z_DEFLATED) { + strm->msg = (char *)"unknown compression method"; + state->mode = BAD; + break; + } + DROPBITS(4); + len = BITS(4) + 8; + if (state->wbits == 0) + state->wbits = len; + if (len > 15 || len > state->wbits) { + strm->msg = (char *)"invalid window size"; + state->mode = BAD; + break; + } + state->dmax = 1U << len; + state->flags = 0; /* indicate zlib header */ + Tracev((stderr, "inflate: zlib header ok\n")); + strm->adler = state->check = adler32(0L, Z_NULL, 0); + state->mode = hold & 0x200 ? DICTID : TYPE; + INITBITS(); + break; +#ifdef GUNZIP + case FLAGS: + NEEDBITS(16); + state->flags = (int)(hold); + if ((state->flags & 0xff) != Z_DEFLATED) { + strm->msg = (char *)"unknown compression method"; + state->mode = BAD; + break; + } + if (state->flags & 0xe000) { + strm->msg = (char *)"unknown header flags set"; + state->mode = BAD; + break; + } + if (state->head != Z_NULL) + state->head->text = (int)((hold >> 8) & 1); + if ((state->flags & 0x0200) && (state->wrap & 4)) + CRC2(state->check, hold); + INITBITS(); + state->mode = TIME; + /* fallthrough */ + case TIME: + NEEDBITS(32); + if (state->head != Z_NULL) + state->head->time = hold; + if ((state->flags & 0x0200) && (state->wrap & 4)) + CRC4(state->check, hold); + INITBITS(); + state->mode = OS; + /* fallthrough */ + case OS: + NEEDBITS(16); + if (state->head != Z_NULL) { + state->head->xflags = (int)(hold & 0xff); + state->head->os = (int)(hold >> 8); + } + if ((state->flags & 0x0200) && (state->wrap & 4)) + CRC2(state->check, hold); + INITBITS(); + state->mode = EXLEN; + /* fallthrough */ + case EXLEN: + if (state->flags & 0x0400) { + NEEDBITS(16); + state->length = (unsigned)(hold); + if (state->head != Z_NULL) + state->head->extra_len = (unsigned)hold; + if ((state->flags & 0x0200) && (state->wrap & 4)) + CRC2(state->check, hold); + INITBITS(); + } + else if (state->head != Z_NULL) + state->head->extra = Z_NULL; + state->mode = EXTRA; + /* fallthrough */ + case EXTRA: + if (state->flags & 0x0400) { + copy = state->length; + if (copy > have) copy = have; + if (copy) { + if (state->head != Z_NULL && + state->head->extra != Z_NULL && + (len = state->head->extra_len - state->length) < + state->head->extra_max) { + zmemcpy(state->head->extra + len, next, + len + copy > state->head->extra_max ? + state->head->extra_max - len : copy); + } + if ((state->flags & 0x0200) && (state->wrap & 4)) + state->check = crc32(state->check, next, copy); + have -= copy; + next += copy; + state->length -= copy; + } + if (state->length) goto inf_leave; + } + state->length = 0; + state->mode = NAME; + /* fallthrough */ + case NAME: + if (state->flags & 0x0800) { + if (have == 0) goto inf_leave; + copy = 0; + do { + len = (unsigned)(next[copy++]); + if (state->head != Z_NULL && + state->head->name != Z_NULL && + state->length < state->head->name_max) + state->head->name[state->length++] = (Bytef)len; + } while (len && copy < have); + if ((state->flags & 0x0200) && (state->wrap & 4)) + state->check = crc32(state->check, next, copy); + have -= copy; + next += copy; + if (len) goto inf_leave; + } + else if (state->head != Z_NULL) + state->head->name = Z_NULL; + state->length = 0; + state->mode = COMMENT; + /* fallthrough */ + case COMMENT: + if (state->flags & 0x1000) { + if (have == 0) goto inf_leave; + copy = 0; + do { + len = (unsigned)(next[copy++]); + if (state->head != Z_NULL && + state->head->comment != Z_NULL && + state->length < state->head->comm_max) + state->head->comment[state->length++] = (Bytef)len; + } while (len && copy < have); + if ((state->flags & 0x0200) && (state->wrap & 4)) + state->check = crc32(state->check, next, copy); + have -= copy; + next += copy; + if (len) goto inf_leave; + } + else if (state->head != Z_NULL) + state->head->comment = Z_NULL; + state->mode = HCRC; + /* fallthrough */ + case HCRC: + if (state->flags & 0x0200) { + NEEDBITS(16); + if ((state->wrap & 4) && hold != (state->check & 0xffff)) { + strm->msg = (char *)"header crc mismatch"; + state->mode = BAD; + break; + } + INITBITS(); + } + if (state->head != Z_NULL) { + state->head->hcrc = (int)((state->flags >> 9) & 1); + state->head->done = 1; + } + strm->adler = state->check = crc32(0L, Z_NULL, 0); + state->mode = TYPE; + break; +#endif + case DICTID: + NEEDBITS(32); + strm->adler = state->check = ZSWAP32(hold); + INITBITS(); + state->mode = DICT; + /* fallthrough */ + case DICT: + if (state->havedict == 0) { + RESTORE(); + return Z_NEED_DICT; + } + strm->adler = state->check = adler32(0L, Z_NULL, 0); + state->mode = TYPE; + /* fallthrough */ + case TYPE: + if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave; + /* fallthrough */ + case TYPEDO: + if (state->last) { + BYTEBITS(); + state->mode = CHECK; + break; + } + NEEDBITS(3); + state->last = BITS(1); + DROPBITS(1); + switch (BITS(2)) { + case 0: /* stored block */ + Tracev((stderr, "inflate: stored block%s\n", + state->last ? " (last)" : "")); + state->mode = STORED; + break; + case 1: /* fixed block */ + fixedtables(state); + Tracev((stderr, "inflate: fixed codes block%s\n", + state->last ? " (last)" : "")); + state->mode = LEN_; /* decode codes */ + if (flush == Z_TREES) { + DROPBITS(2); + goto inf_leave; + } + break; + case 2: /* dynamic block */ + Tracev((stderr, "inflate: dynamic codes block%s\n", + state->last ? " (last)" : "")); + state->mode = TABLE; + break; + case 3: + strm->msg = (char *)"invalid block type"; + state->mode = BAD; + } + DROPBITS(2); + break; + case STORED: + BYTEBITS(); /* go to byte boundary */ + NEEDBITS(32); + if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { + strm->msg = (char *)"invalid stored block lengths"; + state->mode = BAD; + break; + } + state->length = (unsigned)hold & 0xffff; + Tracev((stderr, "inflate: stored length %u\n", + state->length)); + INITBITS(); + state->mode = COPY_; + if (flush == Z_TREES) goto inf_leave; + /* fallthrough */ + case COPY_: + state->mode = COPY; + /* fallthrough */ + case COPY: + copy = state->length; + if (copy) { + if (copy > have) copy = have; + if (copy > left) copy = left; + if (copy == 0) goto inf_leave; + zmemcpy(put, next, copy); + have -= copy; + next += copy; + left -= copy; + put += copy; + state->length -= copy; + break; + } + Tracev((stderr, "inflate: stored end\n")); + state->mode = TYPE; + break; + case TABLE: + NEEDBITS(14); + state->nlen = BITS(5) + 257; + DROPBITS(5); + state->ndist = BITS(5) + 1; + DROPBITS(5); + state->ncode = BITS(4) + 4; + DROPBITS(4); +#ifndef PKZIP_BUG_WORKAROUND + if (state->nlen > 286 || state->ndist > 30) { + strm->msg = (char *)"too many length or distance symbols"; + state->mode = BAD; + break; + } +#endif + Tracev((stderr, "inflate: table sizes ok\n")); + state->have = 0; + state->mode = LENLENS; + /* fallthrough */ + case LENLENS: + while (state->have < state->ncode) { + NEEDBITS(3); + state->lens[order[state->have++]] = (unsigned short)BITS(3); + DROPBITS(3); + } + while (state->have < 19) + state->lens[order[state->have++]] = 0; + state->next = state->codes; + state->lencode = (const code FAR *)(state->next); + state->lenbits = 7; + ret = inflate_table(CODES, state->lens, 19, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid code lengths set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: code lengths ok\n")); + state->have = 0; + state->mode = CODELENS; + /* fallthrough */ + case CODELENS: + while (state->have < state->nlen + state->ndist) { + for (;;) { + here = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if (here.val < 16) { + DROPBITS(here.bits); + state->lens[state->have++] = here.val; + } + else { + if (here.val == 16) { + NEEDBITS(here.bits + 2); + DROPBITS(here.bits); + if (state->have == 0) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + len = state->lens[state->have - 1]; + copy = 3 + BITS(2); + DROPBITS(2); + } + else if (here.val == 17) { + NEEDBITS(here.bits + 3); + DROPBITS(here.bits); + len = 0; + copy = 3 + BITS(3); + DROPBITS(3); + } + else { + NEEDBITS(here.bits + 7); + DROPBITS(here.bits); + len = 0; + copy = 11 + BITS(7); + DROPBITS(7); + } + if (state->have + copy > state->nlen + state->ndist) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + while (copy--) + state->lens[state->have++] = (unsigned short)len; + } + } + + /* handle error breaks in while */ + if (state->mode == BAD) break; + + /* check for end-of-block code (better have one) */ + if (state->lens[256] == 0) { + strm->msg = (char *)"invalid code -- missing end-of-block"; + state->mode = BAD; + break; + } + + /* build code tables -- note: do not change the lenbits or distbits + values here (9 and 6) without reading the comments in inftrees.h + concerning the ENOUGH constants, which depend on those values */ + state->next = state->codes; + state->lencode = (const code FAR *)(state->next); + state->lenbits = 9; + ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid literal/lengths set"; + state->mode = BAD; + break; + } + state->distcode = (const code FAR *)(state->next); + state->distbits = 6; + ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, + &(state->next), &(state->distbits), state->work); + if (ret) { + strm->msg = (char *)"invalid distances set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: codes ok\n")); + state->mode = LEN_; + if (flush == Z_TREES) goto inf_leave; + /* fallthrough */ + case LEN_: + state->mode = LEN; + /* fallthrough */ + case LEN: + if (have >= 6 && left >= 258) { + RESTORE(); + inflate_fast(strm, out); + LOAD(); + if (state->mode == TYPE) + state->back = -1; + break; + } + state->back = 0; + for (;;) { + here = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if (here.op && (here.op & 0xf0) == 0) { + last = here; + for (;;) { + here = state->lencode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + here.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + state->back += last.bits; + } + DROPBITS(here.bits); + state->back += here.bits; + state->length = (unsigned)here.val; + if ((int)(here.op) == 0) { + Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", here.val)); + state->mode = LIT; + break; + } + if (here.op & 32) { + Tracevv((stderr, "inflate: end of block\n")); + state->back = -1; + state->mode = TYPE; + break; + } + if (here.op & 64) { + strm->msg = (char *)"invalid literal/length code"; + state->mode = BAD; + break; + } + state->extra = (unsigned)(here.op) & 15; + state->mode = LENEXT; + /* fallthrough */ + case LENEXT: + if (state->extra) { + NEEDBITS(state->extra); + state->length += BITS(state->extra); + DROPBITS(state->extra); + state->back += state->extra; + } + Tracevv((stderr, "inflate: length %u\n", state->length)); + state->was = state->length; + state->mode = DIST; + /* fallthrough */ + case DIST: + for (;;) { + here = state->distcode[BITS(state->distbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if ((here.op & 0xf0) == 0) { + last = here; + for (;;) { + here = state->distcode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + here.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + state->back += last.bits; + } + DROPBITS(here.bits); + state->back += here.bits; + if (here.op & 64) { + strm->msg = (char *)"invalid distance code"; + state->mode = BAD; + break; + } + state->offset = (unsigned)here.val; + state->extra = (unsigned)(here.op) & 15; + state->mode = DISTEXT; + /* fallthrough */ + case DISTEXT: + if (state->extra) { + NEEDBITS(state->extra); + state->offset += BITS(state->extra); + DROPBITS(state->extra); + state->back += state->extra; + } +#ifdef INFLATE_STRICT + if (state->offset > state->dmax) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#endif + Tracevv((stderr, "inflate: distance %u\n", state->offset)); + state->mode = MATCH; + /* fallthrough */ + case MATCH: + if (left == 0) goto inf_leave; + copy = out - left; + if (state->offset > copy) { /* copy from window */ + copy = state->offset - copy; + if (copy > state->whave) { + if (state->sane) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + Trace((stderr, "inflate.c too far\n")); + copy -= state->whave; + if (copy > state->length) copy = state->length; + if (copy > left) copy = left; + left -= copy; + state->length -= copy; + do { + *put++ = 0; + } while (--copy); + if (state->length == 0) state->mode = LEN; + break; +#endif + } + if (copy > state->wnext) { + copy -= state->wnext; + from = state->window + (state->wsize - copy); + } + else + from = state->window + (state->wnext - copy); + if (copy > state->length) copy = state->length; + } + else { /* copy from output */ + from = put - state->offset; + copy = state->length; + } + if (copy > left) copy = left; + left -= copy; + state->length -= copy; + do { + *put++ = *from++; + } while (--copy); + if (state->length == 0) state->mode = LEN; + break; + case LIT: + if (left == 0) goto inf_leave; + *put++ = (unsigned char)(state->length); + left--; + state->mode = LEN; + break; + case CHECK: + if (state->wrap) { + NEEDBITS(32); + out -= left; + strm->total_out += out; + state->total += out; + if ((state->wrap & 4) && out) + strm->adler = state->check = + UPDATE_CHECK(state->check, put - out, out); + out = left; + if ((state->wrap & 4) && ( +#ifdef GUNZIP + state->flags ? hold : +#endif + ZSWAP32(hold)) != state->check) { + strm->msg = (char *)"incorrect data check"; + state->mode = BAD; + break; + } + INITBITS(); + Tracev((stderr, "inflate: check matches trailer\n")); + } +#ifdef GUNZIP + state->mode = LENGTH; + /* fallthrough */ + case LENGTH: + if (state->wrap && state->flags) { + NEEDBITS(32); + if ((state->wrap & 4) && hold != (state->total & 0xffffffff)) { + strm->msg = (char *)"incorrect length check"; + state->mode = BAD; + break; + } + INITBITS(); + Tracev((stderr, "inflate: length matches trailer\n")); + } +#endif + state->mode = DONE; + /* fallthrough */ + case DONE: + ret = Z_STREAM_END; + goto inf_leave; + case BAD: + ret = Z_DATA_ERROR; + goto inf_leave; + case MEM: + return Z_MEM_ERROR; + case SYNC: + /* fallthrough */ + default: + return Z_STREAM_ERROR; + } + + /* + Return from inflate(), updating the total counts and the check value. + If there was no progress during the inflate() call, return a buffer + error. Call updatewindow() to create and/or update the window state. + Note: a memory error from inflate() is non-recoverable. + */ + inf_leave: + RESTORE(); + if (state->wsize || (out != strm->avail_out && state->mode < BAD && + (state->mode < CHECK || flush != Z_FINISH))) + if (updatewindow(strm, strm->next_out, out - strm->avail_out)) { + state->mode = MEM; + return Z_MEM_ERROR; + } + in -= strm->avail_in; + out -= strm->avail_out; + strm->total_in += in; + strm->total_out += out; + state->total += out; + if ((state->wrap & 4) && out) + strm->adler = state->check = + UPDATE_CHECK(state->check, strm->next_out - out, out); + strm->data_type = (int)state->bits + (state->last ? 64 : 0) + + (state->mode == TYPE ? 128 : 0) + + (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0); + if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) + ret = Z_BUF_ERROR; + return ret; +} + +int ZEXPORT inflateEnd(z_streamp strm) { + struct inflate_state FAR *state; + if (inflateStateCheck(strm)) + return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (state->window != Z_NULL) ZFREE(strm, state->window); + ZFREE(strm, strm->state); + strm->state = Z_NULL; + Tracev((stderr, "inflate: end\n")); + return Z_OK; +} + +int ZEXPORT inflateGetDictionary(z_streamp strm, Bytef *dictionary, + uInt *dictLength) { + struct inflate_state FAR *state; + + /* check state */ + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + + /* copy dictionary */ + if (state->whave && dictionary != Z_NULL) { + zmemcpy(dictionary, state->window + state->wnext, + state->whave - state->wnext); + zmemcpy(dictionary + state->whave - state->wnext, + state->window, state->wnext); + } + if (dictLength != Z_NULL) + *dictLength = state->whave; + return Z_OK; +} + +int ZEXPORT inflateSetDictionary(z_streamp strm, const Bytef *dictionary, + uInt dictLength) { + struct inflate_state FAR *state; + unsigned long dictid; + int ret; + + /* check state */ + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (state->wrap != 0 && state->mode != DICT) + return Z_STREAM_ERROR; + + /* check for correct dictionary identifier */ + if (state->mode == DICT) { + dictid = adler32(0L, Z_NULL, 0); + dictid = adler32(dictid, dictionary, dictLength); + if (dictid != state->check) + return Z_DATA_ERROR; + } + + /* copy dictionary to window using updatewindow(), which will amend the + existing dictionary if appropriate */ + ret = updatewindow(strm, dictionary + dictLength, dictLength); + if (ret) { + state->mode = MEM; + return Z_MEM_ERROR; + } + state->havedict = 1; + Tracev((stderr, "inflate: dictionary set\n")); + return Z_OK; +} + +int ZEXPORT inflateGetHeader(z_streamp strm, gz_headerp head) { + struct inflate_state FAR *state; + + /* check state */ + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if ((state->wrap & 2) == 0) return Z_STREAM_ERROR; + + /* save header structure */ + state->head = head; + head->done = 0; + return Z_OK; +} + +/* + Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found + or when out of input. When called, *have is the number of pattern bytes + found in order so far, in 0..3. On return *have is updated to the new + state. If on return *have equals four, then the pattern was found and the + return value is how many bytes were read including the last byte of the + pattern. If *have is less than four, then the pattern has not been found + yet and the return value is len. In the latter case, syncsearch() can be + called again with more data and the *have state. *have is initialized to + zero for the first call. + */ +local unsigned syncsearch(unsigned FAR *have, const unsigned char FAR *buf, + unsigned len) { + unsigned got; + unsigned next; + + got = *have; + next = 0; + while (next < len && got < 4) { + if ((int)(buf[next]) == (got < 2 ? 0 : 0xff)) + got++; + else if (buf[next]) + got = 0; + else + got = 4 - got; + next++; + } + *have = got; + return next; +} + +int ZEXPORT inflateSync(z_streamp strm) { + unsigned len; /* number of bytes to look at or looked at */ + int flags; /* temporary to save header status */ + unsigned long in, out; /* temporary to save total_in and total_out */ + unsigned char buf[4]; /* to restore bit buffer to byte string */ + struct inflate_state FAR *state; + + /* check parameters */ + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR; + + /* if first time, start search in bit buffer */ + if (state->mode != SYNC) { + state->mode = SYNC; + state->hold >>= state->bits & 7; + state->bits -= state->bits & 7; + len = 0; + while (state->bits >= 8) { + buf[len++] = (unsigned char)(state->hold); + state->hold >>= 8; + state->bits -= 8; + } + state->have = 0; + syncsearch(&(state->have), buf, len); + } + + /* search available input */ + len = syncsearch(&(state->have), strm->next_in, strm->avail_in); + strm->avail_in -= len; + strm->next_in += len; + strm->total_in += len; + + /* return no joy or set up to restart inflate() on a new block */ + if (state->have != 4) return Z_DATA_ERROR; + if (state->flags == -1) + state->wrap = 0; /* if no header yet, treat as raw */ + else + state->wrap &= ~4; /* no point in computing a check value now */ + flags = state->flags; + in = strm->total_in; out = strm->total_out; + inflateReset(strm); + strm->total_in = in; strm->total_out = out; + state->flags = flags; + state->mode = TYPE; + return Z_OK; +} + +/* + Returns true if inflate is currently at the end of a block generated by + Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP + implementation to provide an additional safety check. PPP uses + Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored + block. When decompressing, PPP checks that at the end of input packet, + inflate is waiting for these length bytes. + */ +int ZEXPORT inflateSyncPoint(z_streamp strm) { + struct inflate_state FAR *state; + + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + return state->mode == STORED && state->bits == 0; +} + +int ZEXPORT inflateCopy(z_streamp dest, z_streamp source) { + struct inflate_state FAR *state; + struct inflate_state FAR *copy; + unsigned char FAR *window; + unsigned wsize; + + /* check input */ + if (inflateStateCheck(source) || dest == Z_NULL) + return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)source->state; + + /* allocate space */ + copy = (struct inflate_state FAR *) + ZALLOC(source, 1, sizeof(struct inflate_state)); + if (copy == Z_NULL) return Z_MEM_ERROR; + window = Z_NULL; + if (state->window != Z_NULL) { + window = (unsigned char FAR *) + ZALLOC(source, 1U << state->wbits, sizeof(unsigned char)); + if (window == Z_NULL) { + ZFREE(source, copy); + return Z_MEM_ERROR; + } + } + + /* copy state */ + zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream)); + zmemcpy((voidpf)copy, (voidpf)state, sizeof(struct inflate_state)); + copy->strm = dest; + if (state->lencode >= state->codes && + state->lencode <= state->codes + ENOUGH - 1) { + copy->lencode = copy->codes + (state->lencode - state->codes); + copy->distcode = copy->codes + (state->distcode - state->codes); + } + copy->next = copy->codes + (state->next - state->codes); + if (window != Z_NULL) { + wsize = 1U << state->wbits; + zmemcpy(window, state->window, wsize); + } + copy->window = window; + dest->state = (struct internal_state FAR *)copy; + return Z_OK; +} + +int ZEXPORT inflateUndermine(z_streamp strm, int subvert) { + struct inflate_state FAR *state; + + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; +#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + state->sane = !subvert; + return Z_OK; +#else + (void)subvert; + state->sane = 1; + return Z_DATA_ERROR; +#endif +} + +int ZEXPORT inflateValidate(z_streamp strm, int check) { + struct inflate_state FAR *state; + + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (check && state->wrap) + state->wrap |= 4; + else + state->wrap &= ~4; + return Z_OK; +} + +long ZEXPORT inflateMark(z_streamp strm) { + struct inflate_state FAR *state; + + if (inflateStateCheck(strm)) + return -(1L << 16); + state = (struct inflate_state FAR *)strm->state; + return (long)(((unsigned long)((long)state->back)) << 16) + + (state->mode == COPY ? state->length : + (state->mode == MATCH ? state->was - state->length : 0)); +} + +unsigned long ZEXPORT inflateCodesUsed(z_streamp strm) { + struct inflate_state FAR *state; + if (inflateStateCheck(strm)) return (unsigned long)-1; + state = (struct inflate_state FAR *)strm->state; + return (unsigned long)(state->next - state->codes); +} diff --git a/common/zlib/inflate.h b/common/zlib/inflate.h new file mode 100644 index 0000000..f127b6b --- /dev/null +++ b/common/zlib/inflate.h @@ -0,0 +1,126 @@ +/* inflate.h -- internal inflate state definition + * Copyright (C) 1995-2019 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* define NO_GZIP when compiling if you want to disable gzip header and + trailer decoding by inflate(). NO_GZIP would be used to avoid linking in + the crc code when it is not needed. For shared libraries, gzip decoding + should be left enabled. */ +#ifndef NO_GZIP +# define GUNZIP +#endif + +/* Possible inflate modes between inflate() calls */ +typedef enum { + HEAD = 16180, /* i: waiting for magic header */ + FLAGS, /* i: waiting for method and flags (gzip) */ + TIME, /* i: waiting for modification time (gzip) */ + OS, /* i: waiting for extra flags and operating system (gzip) */ + EXLEN, /* i: waiting for extra length (gzip) */ + EXTRA, /* i: waiting for extra bytes (gzip) */ + NAME, /* i: waiting for end of file name (gzip) */ + COMMENT, /* i: waiting for end of comment (gzip) */ + HCRC, /* i: waiting for header crc (gzip) */ + DICTID, /* i: waiting for dictionary check value */ + DICT, /* waiting for inflateSetDictionary() call */ + TYPE, /* i: waiting for type bits, including last-flag bit */ + TYPEDO, /* i: same, but skip check to exit inflate on new block */ + STORED, /* i: waiting for stored size (length and complement) */ + COPY_, /* i/o: same as COPY below, but only first time in */ + COPY, /* i/o: waiting for input or output to copy stored block */ + TABLE, /* i: waiting for dynamic block table lengths */ + LENLENS, /* i: waiting for code length code lengths */ + CODELENS, /* i: waiting for length/lit and distance code lengths */ + LEN_, /* i: same as LEN below, but only first time in */ + LEN, /* i: waiting for length/lit/eob code */ + LENEXT, /* i: waiting for length extra bits */ + DIST, /* i: waiting for distance code */ + DISTEXT, /* i: waiting for distance extra bits */ + MATCH, /* o: waiting for output space to copy string */ + LIT, /* o: waiting for output space to write literal */ + CHECK, /* i: waiting for 32-bit check value */ + LENGTH, /* i: waiting for 32-bit length (gzip) */ + DONE, /* finished check, done -- remain here until reset */ + BAD, /* got a data error -- remain here until reset */ + MEM, /* got an inflate() memory error -- remain here until reset */ + SYNC /* looking for synchronization bytes to restart inflate() */ +} inflate_mode; + +/* + State transitions between above modes - + + (most modes can go to BAD or MEM on error -- not shown for clarity) + + Process header: + HEAD -> (gzip) or (zlib) or (raw) + (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME -> COMMENT -> + HCRC -> TYPE + (zlib) -> DICTID or TYPE + DICTID -> DICT -> TYPE + (raw) -> TYPEDO + Read deflate blocks: + TYPE -> TYPEDO -> STORED or TABLE or LEN_ or CHECK + STORED -> COPY_ -> COPY -> TYPE + TABLE -> LENLENS -> CODELENS -> LEN_ + LEN_ -> LEN + Read deflate codes in fixed or dynamic block: + LEN -> LENEXT or LIT or TYPE + LENEXT -> DIST -> DISTEXT -> MATCH -> LEN + LIT -> LEN + Process trailer: + CHECK -> LENGTH -> DONE + */ + +/* State maintained between inflate() calls -- approximately 7K bytes, not + including the allocated sliding window, which is up to 32K bytes. */ +struct inflate_state { + z_streamp strm; /* pointer back to this zlib stream */ + inflate_mode mode; /* current inflate mode */ + int last; /* true if processing last block */ + int wrap; /* bit 0 true for zlib, bit 1 true for gzip, + bit 2 true to validate check value */ + int havedict; /* true if dictionary provided */ + int flags; /* gzip header method and flags, 0 if zlib, or + -1 if raw or no header yet */ + unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */ + unsigned long check; /* protected copy of check value */ + unsigned long total; /* protected copy of output count */ + gz_headerp head; /* where to save gzip header information */ + /* sliding window */ + unsigned wbits; /* log base 2 of requested window size */ + unsigned wsize; /* window size or zero if not using window */ + unsigned whave; /* valid bytes in the window */ + unsigned wnext; /* window write index */ + unsigned char FAR *window; /* allocated sliding window, if needed */ + /* bit accumulator */ + unsigned long hold; /* input bit accumulator */ + unsigned bits; /* number of bits in "in" */ + /* for string and stored block copying */ + unsigned length; /* literal or length of data to copy */ + unsigned offset; /* distance back to copy string from */ + /* for table and code decoding */ + unsigned extra; /* extra bits needed */ + /* fixed and dynamic code tables */ + code const FAR *lencode; /* starting table for length/literal codes */ + code const FAR *distcode; /* starting table for distance codes */ + unsigned lenbits; /* index bits for lencode */ + unsigned distbits; /* index bits for distcode */ + /* dynamic table building */ + unsigned ncode; /* number of code length code lengths */ + unsigned nlen; /* number of length code lengths */ + unsigned ndist; /* number of distance code lengths */ + unsigned have; /* number of code lengths in lens[] */ + code FAR *next; /* next available space in codes[] */ + unsigned short lens[320]; /* temporary storage for code lengths */ + unsigned short work[288]; /* work area for code table building */ + code codes[ENOUGH]; /* space for code tables */ + int sane; /* if false, allow invalid distance too far */ + int back; /* bits back of last unprocessed length/lit */ + unsigned was; /* initial length of match */ +}; diff --git a/common/zlib/inftrees.c b/common/zlib/inftrees.c new file mode 100644 index 0000000..98cfe16 --- /dev/null +++ b/common/zlib/inftrees.c @@ -0,0 +1,299 @@ +/* inftrees.c -- generate Huffman trees for efficient decoding + * Copyright (C) 1995-2024 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftrees.h" + +#define MAXBITS 15 + +const char inflate_copyright[] = + " inflate 1.3.1 Copyright 1995-2024 Mark Adler "; +/* + If you use the zlib library in a product, an acknowledgment is welcome + in the documentation of your product. If for some reason you cannot + include such an acknowledgment, I would appreciate that you keep this + copyright string in the executable of your product. + */ + +/* + Build a set of tables to decode the provided canonical Huffman code. + The code lengths are lens[0..codes-1]. The result starts at *table, + whose indices are 0..2^bits-1. work is a writable array of at least + lens shorts, which is used as a work area. type is the type of code + to be generated, CODES, LENS, or DISTS. On return, zero is success, + -1 is an invalid code, and +1 means that ENOUGH isn't enough. table + on return points to the next available entry's address. bits is the + requested root table index bits, and on return it is the actual root + table index bits. It will differ if the request is greater than the + longest code or if it is less than the shortest code. + */ +int ZLIB_INTERNAL inflate_table(codetype type, unsigned short FAR *lens, + unsigned codes, code FAR * FAR *table, + unsigned FAR *bits, unsigned short FAR *work) { + unsigned len; /* a code's length in bits */ + unsigned sym; /* index of code symbols */ + unsigned min, max; /* minimum and maximum code lengths */ + unsigned root; /* number of index bits for root table */ + unsigned curr; /* number of index bits for current table */ + unsigned drop; /* code bits to drop for sub-table */ + int left; /* number of prefix codes available */ + unsigned used; /* code entries in table used */ + unsigned huff; /* Huffman code */ + unsigned incr; /* for incrementing code, index */ + unsigned fill; /* index for replicating entries */ + unsigned low; /* low bits for current root entry */ + unsigned mask; /* mask for low root bits */ + code here; /* table entry for duplication */ + code FAR *next; /* next available space in table */ + const unsigned short FAR *base; /* base value table to use */ + const unsigned short FAR *extra; /* extra bits table to use */ + unsigned match; /* use base and extra for symbol >= match */ + unsigned short count[MAXBITS+1]; /* number of codes of each length */ + unsigned short offs[MAXBITS+1]; /* offsets in table for each length */ + static const unsigned short lbase[31] = { /* Length codes 257..285 base */ + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; + static const unsigned short lext[31] = { /* Length codes 257..285 extra */ + 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, + 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 203, 77}; + static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, + 8193, 12289, 16385, 24577, 0, 0}; + static const unsigned short dext[32] = { /* Distance codes 0..29 extra */ + 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, + 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, + 28, 28, 29, 29, 64, 64}; + + /* + Process a set of code lengths to create a canonical Huffman code. The + code lengths are lens[0..codes-1]. Each length corresponds to the + symbols 0..codes-1. The Huffman code is generated by first sorting the + symbols by length from short to long, and retaining the symbol order + for codes with equal lengths. Then the code starts with all zero bits + for the first code of the shortest length, and the codes are integer + increments for the same length, and zeros are appended as the length + increases. For the deflate format, these bits are stored backwards + from their more natural integer increment ordering, and so when the + decoding tables are built in the large loop below, the integer codes + are incremented backwards. + + This routine assumes, but does not check, that all of the entries in + lens[] are in the range 0..MAXBITS. The caller must assure this. + 1..MAXBITS is interpreted as that code length. zero means that that + symbol does not occur in this code. + + The codes are sorted by computing a count of codes for each length, + creating from that a table of starting indices for each length in the + sorted table, and then entering the symbols in order in the sorted + table. The sorted table is work[], with that space being provided by + the caller. + + The length counts are used for other purposes as well, i.e. finding + the minimum and maximum length codes, determining if there are any + codes at all, checking for a valid set of lengths, and looking ahead + at length counts to determine sub-table sizes when building the + decoding tables. + */ + + /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ + for (len = 0; len <= MAXBITS; len++) + count[len] = 0; + for (sym = 0; sym < codes; sym++) + count[lens[sym]]++; + + /* bound code lengths, force root to be within code lengths */ + root = *bits; + for (max = MAXBITS; max >= 1; max--) + if (count[max] != 0) break; + if (root > max) root = max; + if (max == 0) { /* no symbols to code at all */ + here.op = (unsigned char)64; /* invalid code marker */ + here.bits = (unsigned char)1; + here.val = (unsigned short)0; + *(*table)++ = here; /* make a table to force an error */ + *(*table)++ = here; + *bits = 1; + return 0; /* no symbols, but wait for decoding to report error */ + } + for (min = 1; min < max; min++) + if (count[min] != 0) break; + if (root < min) root = min; + + /* check for an over-subscribed or incomplete set of lengths */ + left = 1; + for (len = 1; len <= MAXBITS; len++) { + left <<= 1; + left -= count[len]; + if (left < 0) return -1; /* over-subscribed */ + } + if (left > 0 && (type == CODES || max != 1)) + return -1; /* incomplete set */ + + /* generate offsets into symbol table for each length for sorting */ + offs[1] = 0; + for (len = 1; len < MAXBITS; len++) + offs[len + 1] = offs[len] + count[len]; + + /* sort symbols by length, by symbol order within each length */ + for (sym = 0; sym < codes; sym++) + if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym; + + /* + Create and fill in decoding tables. In this loop, the table being + filled is at next and has curr index bits. The code being used is huff + with length len. That code is converted to an index by dropping drop + bits off of the bottom. For codes where len is less than drop + curr, + those top drop + curr - len bits are incremented through all values to + fill the table with replicated entries. + + root is the number of index bits for the root table. When len exceeds + root, sub-tables are created pointed to by the root entry with an index + of the low root bits of huff. This is saved in low to check for when a + new sub-table should be started. drop is zero when the root table is + being filled, and drop is root when sub-tables are being filled. + + When a new sub-table is needed, it is necessary to look ahead in the + code lengths to determine what size sub-table is needed. The length + counts are used for this, and so count[] is decremented as codes are + entered in the tables. + + used keeps track of how many table entries have been allocated from the + provided *table space. It is checked for LENS and DIST tables against + the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in + the initial root table size constants. See the comments in inftrees.h + for more information. + + sym increments through all symbols, and the loop terminates when + all codes of length max, i.e. all codes, have been processed. This + routine permits incomplete codes, so another loop after this one fills + in the rest of the decoding tables with invalid code markers. + */ + + /* set up for code type */ + switch (type) { + case CODES: + base = extra = work; /* dummy value--not used */ + match = 20; + break; + case LENS: + base = lbase; + extra = lext; + match = 257; + break; + default: /* DISTS */ + base = dbase; + extra = dext; + match = 0; + } + + /* initialize state for loop */ + huff = 0; /* starting code */ + sym = 0; /* starting code symbol */ + len = min; /* starting code length */ + next = *table; /* current table to fill in */ + curr = root; /* current table index bits */ + drop = 0; /* current bits to drop from code for index */ + low = (unsigned)(-1); /* trigger new sub-table when len > root */ + used = 1U << root; /* use root table entries */ + mask = used - 1; /* mask for comparing low */ + + /* check available table space */ + if ((type == LENS && used > ENOUGH_LENS) || + (type == DISTS && used > ENOUGH_DISTS)) + return 1; + + /* process all codes and make table entries */ + for (;;) { + /* create table entry */ + here.bits = (unsigned char)(len - drop); + if (work[sym] + 1U < match) { + here.op = (unsigned char)0; + here.val = work[sym]; + } + else if (work[sym] >= match) { + here.op = (unsigned char)(extra[work[sym] - match]); + here.val = base[work[sym] - match]; + } + else { + here.op = (unsigned char)(32 + 64); /* end of block */ + here.val = 0; + } + + /* replicate for those indices with low len bits equal to huff */ + incr = 1U << (len - drop); + fill = 1U << curr; + min = fill; /* save offset to next table */ + do { + fill -= incr; + next[(huff >> drop) + fill] = here; + } while (fill != 0); + + /* backwards increment the len-bit code huff */ + incr = 1U << (len - 1); + while (huff & incr) + incr >>= 1; + if (incr != 0) { + huff &= incr - 1; + huff += incr; + } + else + huff = 0; + + /* go to next symbol, update count, len */ + sym++; + if (--(count[len]) == 0) { + if (len == max) break; + len = lens[work[sym]]; + } + + /* create new sub-table if needed */ + if (len > root && (huff & mask) != low) { + /* if first time, transition to sub-tables */ + if (drop == 0) + drop = root; + + /* increment past last table */ + next += min; /* here min is 1 << curr */ + + /* determine length of next table */ + curr = len - drop; + left = (int)(1 << curr); + while (curr + drop < max) { + left -= count[curr + drop]; + if (left <= 0) break; + curr++; + left <<= 1; + } + + /* check for enough space */ + used += 1U << curr; + if ((type == LENS && used > ENOUGH_LENS) || + (type == DISTS && used > ENOUGH_DISTS)) + return 1; + + /* point entry in root table to sub-table */ + low = huff & mask; + (*table)[low].op = (unsigned char)curr; + (*table)[low].bits = (unsigned char)root; + (*table)[low].val = (unsigned short)(next - *table); + } + } + + /* fill in remaining table entry if code is incomplete (guaranteed to have + at most one remaining entry, since if the code is incomplete, the + maximum code length that was allowed to get this far is one bit) */ + if (huff != 0) { + here.op = (unsigned char)64; /* invalid code marker */ + here.bits = (unsigned char)(len - drop); + here.val = (unsigned short)0; + next[huff] = here; + } + + /* set return parameters */ + *table += used; + *bits = root; + return 0; +} diff --git a/common/zlib/inftrees.h b/common/zlib/inftrees.h new file mode 100644 index 0000000..396f74b --- /dev/null +++ b/common/zlib/inftrees.h @@ -0,0 +1,62 @@ +/* inftrees.h -- header to use inftrees.c + * Copyright (C) 1995-2005, 2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* Structure for decoding tables. Each entry provides either the + information needed to do the operation requested by the code that + indexed that table entry, or it provides a pointer to another + table that indexes more bits of the code. op indicates whether + the entry is a pointer to another table, a literal, a length or + distance, an end-of-block, or an invalid code. For a table + pointer, the low four bits of op is the number of index bits of + that table. For a length or distance, the low four bits of op + is the number of extra bits to get after the code. bits is + the number of bits in this code or part of the code to drop off + of the bit buffer. val is the actual byte to output in the case + of a literal, the base length or distance, or the offset from + the current table to the next table. Each entry is four bytes. */ +typedef struct { + unsigned char op; /* operation, extra bits, table bits */ + unsigned char bits; /* bits in this part of the code */ + unsigned short val; /* offset in table or code value */ +} code; + +/* op values as set by inflate_table(): + 00000000 - literal + 0000tttt - table link, tttt != 0 is the number of table index bits + 0001eeee - length or distance, eeee is the number of extra bits + 01100000 - end of block + 01000000 - invalid code + */ + +/* Maximum size of the dynamic table. The maximum number of code structures is + 1444, which is the sum of 852 for literal/length codes and 592 for distance + codes. These values were found by exhaustive searches using the program + examples/enough.c found in the zlib distribution. The arguments to that + program are the number of symbols, the initial root table size, and the + maximum bit length of a code. "enough 286 9 15" for literal/length codes + returns 852, and "enough 30 6 15" for distance codes returns 592. The + initial root table size (9 or 6) is found in the fifth argument of the + inflate_table() calls in inflate.c and infback.c. If the root table size is + changed, then these maximum sizes would be need to be recalculated and + updated. */ +#define ENOUGH_LENS 852 +#define ENOUGH_DISTS 592 +#define ENOUGH (ENOUGH_LENS+ENOUGH_DISTS) + +/* Type of code to build for inflate_table() */ +typedef enum { + CODES, + LENS, + DISTS +} codetype; + +int ZLIB_INTERNAL inflate_table(codetype type, unsigned short FAR *lens, + unsigned codes, code FAR * FAR *table, + unsigned FAR *bits, unsigned short FAR *work); diff --git a/common/zlib/trees.c b/common/zlib/trees.c new file mode 100644 index 0000000..6a523ef --- /dev/null +++ b/common/zlib/trees.c @@ -0,0 +1,1117 @@ +/* trees.c -- output deflated data using Huffman coding + * Copyright (C) 1995-2024 Jean-loup Gailly + * detect_data_type() function provided freely by Cosmin Truta, 2006 + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * ALGORITHM + * + * The "deflation" process uses several Huffman trees. The more + * common source values are represented by shorter bit sequences. + * + * Each code tree is stored in a compressed form which is itself + * a Huffman encoding of the lengths of all the code strings (in + * ascending order by source values). The actual code strings are + * reconstructed from the lengths in the inflate process, as described + * in the deflate specification. + * + * REFERENCES + * + * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". + * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc + * + * Storer, James A. + * Data Compression: Methods and Theory, pp. 49-50. + * Computer Science Press, 1988. ISBN 0-7167-8156-5. + * + * Sedgewick, R. + * Algorithms, p290. + * Addison-Wesley, 1983. ISBN 0-201-06672-6. + */ + +/* @(#) $Id$ */ + +/* #define GEN_TREES_H */ + +#include "deflate.h" + +#ifdef ZLIB_DEBUG +# include +#endif + +/* =========================================================================== + * Constants + */ + +#define MAX_BL_BITS 7 +/* Bit length codes must not exceed MAX_BL_BITS bits */ + +#define END_BLOCK 256 +/* end of block literal code */ + +#define REP_3_6 16 +/* repeat previous bit length 3-6 times (2 bits of repeat count) */ + +#define REPZ_3_10 17 +/* repeat a zero length 3-10 times (3 bits of repeat count) */ + +#define REPZ_11_138 18 +/* repeat a zero length 11-138 times (7 bits of repeat count) */ + +local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */ + = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}; + +local const int extra_dbits[D_CODES] /* extra bits for each distance code */ + = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; + +local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */ + = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; + +local const uch bl_order[BL_CODES] + = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; +/* The lengths of the bit length codes are sent in order of decreasing + * probability, to avoid transmitting the lengths for unused bit length codes. + */ + +/* =========================================================================== + * Local data. These are initialized only once. + */ + +#define DIST_CODE_LEN 512 /* see definition of array dist_code below */ + +#if defined(GEN_TREES_H) || !defined(STDC) +/* non ANSI compilers may not accept trees.h */ + +local ct_data static_ltree[L_CODES+2]; +/* The static literal tree. Since the bit lengths are imposed, there is no + * need for the L_CODES extra codes used during heap construction. However + * The codes 286 and 287 are needed to build a canonical tree (see _tr_init + * below). + */ + +local ct_data static_dtree[D_CODES]; +/* The static distance tree. (Actually a trivial tree since all codes use + * 5 bits.) + */ + +uch _dist_code[DIST_CODE_LEN]; +/* Distance codes. The first 256 values correspond to the distances + * 3 .. 258, the last 256 values correspond to the top 8 bits of + * the 15 bit distances. + */ + +uch _length_code[MAX_MATCH-MIN_MATCH+1]; +/* length code for each normalized match length (0 == MIN_MATCH) */ + +local int base_length[LENGTH_CODES]; +/* First normalized length for each code (0 = MIN_MATCH) */ + +local int base_dist[D_CODES]; +/* First normalized distance for each code (0 = distance of 1) */ + +#else +# include "trees.h" +#endif /* GEN_TREES_H */ + +struct static_tree_desc_s { + const ct_data *static_tree; /* static tree or NULL */ + const intf *extra_bits; /* extra bits for each code or NULL */ + int extra_base; /* base index for extra_bits */ + int elems; /* max number of elements in the tree */ + int max_length; /* max bit length for the codes */ +}; + +#ifdef NO_INIT_GLOBAL_POINTERS +# define TCONST +#else +# define TCONST const +#endif + +local TCONST static_tree_desc static_l_desc = +{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; + +local TCONST static_tree_desc static_d_desc = +{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; + +local TCONST static_tree_desc static_bl_desc = +{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; + +/* =========================================================================== + * Output a short LSB first on the stream. + * IN assertion: there is enough room in pendingBuf. + */ +#define put_short(s, w) { \ + put_byte(s, (uch)((w) & 0xff)); \ + put_byte(s, (uch)((ush)(w) >> 8)); \ +} + +/* =========================================================================== + * Reverse the first len bits of a code, using straightforward code (a faster + * method would use a table) + * IN assertion: 1 <= len <= 15 + */ +local unsigned bi_reverse(unsigned code, int len) { + register unsigned res = 0; + do { + res |= code & 1; + code >>= 1, res <<= 1; + } while (--len > 0); + return res >> 1; +} + +/* =========================================================================== + * Flush the bit buffer, keeping at most 7 bits in it. + */ +local void bi_flush(deflate_state *s) { + if (s->bi_valid == 16) { + put_short(s, s->bi_buf); + s->bi_buf = 0; + s->bi_valid = 0; + } else if (s->bi_valid >= 8) { + put_byte(s, (Byte)s->bi_buf); + s->bi_buf >>= 8; + s->bi_valid -= 8; + } +} + +/* =========================================================================== + * Flush the bit buffer and align the output on a byte boundary + */ +local void bi_windup(deflate_state *s) { + if (s->bi_valid > 8) { + put_short(s, s->bi_buf); + } else if (s->bi_valid > 0) { + put_byte(s, (Byte)s->bi_buf); + } + s->bi_buf = 0; + s->bi_valid = 0; +#ifdef ZLIB_DEBUG + s->bits_sent = (s->bits_sent + 7) & ~7; +#endif +} + +/* =========================================================================== + * Generate the codes for a given tree and bit counts (which need not be + * optimal). + * IN assertion: the array bl_count contains the bit length statistics for + * the given tree and the field len is set for all tree elements. + * OUT assertion: the field code is set for all tree elements of non + * zero code length. + */ +local void gen_codes(ct_data *tree, int max_code, ushf *bl_count) { + ush next_code[MAX_BITS+1]; /* next code value for each bit length */ + unsigned code = 0; /* running code value */ + int bits; /* bit index */ + int n; /* code index */ + + /* The distribution counts are first used to generate the code values + * without bit reversal. + */ + for (bits = 1; bits <= MAX_BITS; bits++) { + code = (code + bl_count[bits - 1]) << 1; + next_code[bits] = (ush)code; + } + /* Check that the bit counts in bl_count are consistent. The last code + * must be all ones. + */ + Assert (code + bl_count[MAX_BITS] - 1 == (1 << MAX_BITS) - 1, + "inconsistent bit counts"); + Tracev((stderr,"\ngen_codes: max_code %d ", max_code)); + + for (n = 0; n <= max_code; n++) { + int len = tree[n].Len; + if (len == 0) continue; + /* Now reverse the bits */ + tree[n].Code = (ush)bi_reverse(next_code[len]++, len); + + Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ", + n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len] - 1)); + } +} + +#ifdef GEN_TREES_H +local void gen_trees_header(void); +#endif + +#ifndef ZLIB_DEBUG +# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len) + /* Send a code of the given tree. c and tree must not have side effects */ + +#else /* !ZLIB_DEBUG */ +# define send_code(s, c, tree) \ + { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \ + send_bits(s, tree[c].Code, tree[c].Len); } +#endif + +/* =========================================================================== + * Send a value on a given number of bits. + * IN assertion: length <= 16 and value fits in length bits. + */ +#ifdef ZLIB_DEBUG +local void send_bits(deflate_state *s, int value, int length) { + Tracevv((stderr," l %2d v %4x ", length, value)); + Assert(length > 0 && length <= 15, "invalid length"); + s->bits_sent += (ulg)length; + + /* If not enough room in bi_buf, use (valid) bits from bi_buf and + * (16 - bi_valid) bits from value, leaving (width - (16 - bi_valid)) + * unused bits in value. + */ + if (s->bi_valid > (int)Buf_size - length) { + s->bi_buf |= (ush)value << s->bi_valid; + put_short(s, s->bi_buf); + s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); + s->bi_valid += length - Buf_size; + } else { + s->bi_buf |= (ush)value << s->bi_valid; + s->bi_valid += length; + } +} +#else /* !ZLIB_DEBUG */ + +#define send_bits(s, value, length) \ +{ int len = length;\ + if (s->bi_valid > (int)Buf_size - len) {\ + int val = (int)value;\ + s->bi_buf |= (ush)val << s->bi_valid;\ + put_short(s, s->bi_buf);\ + s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ + s->bi_valid += len - Buf_size;\ + } else {\ + s->bi_buf |= (ush)(value) << s->bi_valid;\ + s->bi_valid += len;\ + }\ +} +#endif /* ZLIB_DEBUG */ + + +/* the arguments must not have side effects */ + +/* =========================================================================== + * Initialize the various 'constant' tables. + */ +local void tr_static_init(void) { +#if defined(GEN_TREES_H) || !defined(STDC) + static int static_init_done = 0; + int n; /* iterates over tree elements */ + int bits; /* bit counter */ + int length; /* length value */ + int code; /* code value */ + int dist; /* distance index */ + ush bl_count[MAX_BITS+1]; + /* number of codes at each bit length for an optimal tree */ + + if (static_init_done) return; + + /* For some embedded targets, global variables are not initialized: */ +#ifdef NO_INIT_GLOBAL_POINTERS + static_l_desc.static_tree = static_ltree; + static_l_desc.extra_bits = extra_lbits; + static_d_desc.static_tree = static_dtree; + static_d_desc.extra_bits = extra_dbits; + static_bl_desc.extra_bits = extra_blbits; +#endif + + /* Initialize the mapping length (0..255) -> length code (0..28) */ + length = 0; + for (code = 0; code < LENGTH_CODES-1; code++) { + base_length[code] = length; + for (n = 0; n < (1 << extra_lbits[code]); n++) { + _length_code[length++] = (uch)code; + } + } + Assert (length == 256, "tr_static_init: length != 256"); + /* Note that the length 255 (match length 258) can be represented + * in two different ways: code 284 + 5 bits or code 285, so we + * overwrite length_code[255] to use the best encoding: + */ + _length_code[length - 1] = (uch)code; + + /* Initialize the mapping dist (0..32K) -> dist code (0..29) */ + dist = 0; + for (code = 0 ; code < 16; code++) { + base_dist[code] = dist; + for (n = 0; n < (1 << extra_dbits[code]); n++) { + _dist_code[dist++] = (uch)code; + } + } + Assert (dist == 256, "tr_static_init: dist != 256"); + dist >>= 7; /* from now on, all distances are divided by 128 */ + for ( ; code < D_CODES; code++) { + base_dist[code] = dist << 7; + for (n = 0; n < (1 << (extra_dbits[code] - 7)); n++) { + _dist_code[256 + dist++] = (uch)code; + } + } + Assert (dist == 256, "tr_static_init: 256 + dist != 512"); + + /* Construct the codes of the static literal tree */ + for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; + n = 0; + while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; + while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; + while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; + while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; + /* Codes 286 and 287 do not exist, but we must include them in the + * tree construction to get a canonical Huffman tree (longest code + * all ones) + */ + gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); + + /* The static distance tree is trivial: */ + for (n = 0; n < D_CODES; n++) { + static_dtree[n].Len = 5; + static_dtree[n].Code = bi_reverse((unsigned)n, 5); + } + static_init_done = 1; + +# ifdef GEN_TREES_H + gen_trees_header(); +# endif +#endif /* defined(GEN_TREES_H) || !defined(STDC) */ +} + +/* =========================================================================== + * Generate the file trees.h describing the static trees. + */ +#ifdef GEN_TREES_H +# ifndef ZLIB_DEBUG +# include +# endif + +# define SEPARATOR(i, last, width) \ + ((i) == (last)? "\n};\n\n" : \ + ((i) % (width) == (width) - 1 ? ",\n" : ", ")) + +void gen_trees_header(void) { + FILE *header = fopen("trees.h", "w"); + int i; + + Assert (header != NULL, "Can't open trees.h"); + fprintf(header, + "/* header created automatically with -DGEN_TREES_H */\n\n"); + + fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n"); + for (i = 0; i < L_CODES+2; i++) { + fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code, + static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5)); + } + + fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n"); + for (i = 0; i < D_CODES; i++) { + fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code, + static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5)); + } + + fprintf(header, "const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = {\n"); + for (i = 0; i < DIST_CODE_LEN; i++) { + fprintf(header, "%2u%s", _dist_code[i], + SEPARATOR(i, DIST_CODE_LEN-1, 20)); + } + + fprintf(header, + "const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= {\n"); + for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) { + fprintf(header, "%2u%s", _length_code[i], + SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20)); + } + + fprintf(header, "local const int base_length[LENGTH_CODES] = {\n"); + for (i = 0; i < LENGTH_CODES; i++) { + fprintf(header, "%1u%s", base_length[i], + SEPARATOR(i, LENGTH_CODES-1, 20)); + } + + fprintf(header, "local const int base_dist[D_CODES] = {\n"); + for (i = 0; i < D_CODES; i++) { + fprintf(header, "%5u%s", base_dist[i], + SEPARATOR(i, D_CODES-1, 10)); + } + + fclose(header); +} +#endif /* GEN_TREES_H */ + +/* =========================================================================== + * Initialize a new block. + */ +local void init_block(deflate_state *s) { + int n; /* iterates over tree elements */ + + /* Initialize the trees. */ + for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0; + for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0; + for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; + + s->dyn_ltree[END_BLOCK].Freq = 1; + s->opt_len = s->static_len = 0L; + s->sym_next = s->matches = 0; +} + +/* =========================================================================== + * Initialize the tree data structures for a new zlib stream. + */ +void ZLIB_INTERNAL _tr_init(deflate_state *s) { + tr_static_init(); + + s->l_desc.dyn_tree = s->dyn_ltree; + s->l_desc.stat_desc = &static_l_desc; + + s->d_desc.dyn_tree = s->dyn_dtree; + s->d_desc.stat_desc = &static_d_desc; + + s->bl_desc.dyn_tree = s->bl_tree; + s->bl_desc.stat_desc = &static_bl_desc; + + s->bi_buf = 0; + s->bi_valid = 0; +#ifdef ZLIB_DEBUG + s->compressed_len = 0L; + s->bits_sent = 0L; +#endif + + /* Initialize the first block of the first file: */ + init_block(s); +} + +#define SMALLEST 1 +/* Index within the heap array of least frequent node in the Huffman tree */ + + +/* =========================================================================== + * Remove the smallest element from the heap and recreate the heap with + * one less element. Updates heap and heap_len. + */ +#define pqremove(s, tree, top) \ +{\ + top = s->heap[SMALLEST]; \ + s->heap[SMALLEST] = s->heap[s->heap_len--]; \ + pqdownheap(s, tree, SMALLEST); \ +} + +/* =========================================================================== + * Compares to subtrees, using the tree depth as tie breaker when + * the subtrees have equal frequency. This minimizes the worst case length. + */ +#define smaller(tree, n, m, depth) \ + (tree[n].Freq < tree[m].Freq || \ + (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) + +/* =========================================================================== + * Restore the heap property by moving down the tree starting at node k, + * exchanging a node with the smallest of its two sons if necessary, stopping + * when the heap property is re-established (each father smaller than its + * two sons). + */ +local void pqdownheap(deflate_state *s, ct_data *tree, int k) { + int v = s->heap[k]; + int j = k << 1; /* left son of k */ + while (j <= s->heap_len) { + /* Set j to the smallest of the two sons: */ + if (j < s->heap_len && + smaller(tree, s->heap[j + 1], s->heap[j], s->depth)) { + j++; + } + /* Exit if v is smaller than both sons */ + if (smaller(tree, v, s->heap[j], s->depth)) break; + + /* Exchange v with the smallest son */ + s->heap[k] = s->heap[j]; k = j; + + /* And continue down the tree, setting j to the left son of k */ + j <<= 1; + } + s->heap[k] = v; +} + +/* =========================================================================== + * Compute the optimal bit lengths for a tree and update the total bit length + * for the current block. + * IN assertion: the fields freq and dad are set, heap[heap_max] and + * above are the tree nodes sorted by increasing frequency. + * OUT assertions: the field len is set to the optimal bit length, the + * array bl_count contains the frequencies for each bit length. + * The length opt_len is updated; static_len is also updated if stree is + * not null. + */ +local void gen_bitlen(deflate_state *s, tree_desc *desc) { + ct_data *tree = desc->dyn_tree; + int max_code = desc->max_code; + const ct_data *stree = desc->stat_desc->static_tree; + const intf *extra = desc->stat_desc->extra_bits; + int base = desc->stat_desc->extra_base; + int max_length = desc->stat_desc->max_length; + int h; /* heap index */ + int n, m; /* iterate over the tree elements */ + int bits; /* bit length */ + int xbits; /* extra bits */ + ush f; /* frequency */ + int overflow = 0; /* number of elements with bit length too large */ + + for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0; + + /* In a first pass, compute the optimal bit lengths (which may + * overflow in the case of the bit length tree). + */ + tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ + + for (h = s->heap_max + 1; h < HEAP_SIZE; h++) { + n = s->heap[h]; + bits = tree[tree[n].Dad].Len + 1; + if (bits > max_length) bits = max_length, overflow++; + tree[n].Len = (ush)bits; + /* We overwrite tree[n].Dad which is no longer needed */ + + if (n > max_code) continue; /* not a leaf node */ + + s->bl_count[bits]++; + xbits = 0; + if (n >= base) xbits = extra[n - base]; + f = tree[n].Freq; + s->opt_len += (ulg)f * (unsigned)(bits + xbits); + if (stree) s->static_len += (ulg)f * (unsigned)(stree[n].Len + xbits); + } + if (overflow == 0) return; + + Tracev((stderr,"\nbit length overflow\n")); + /* This happens for example on obj2 and pic of the Calgary corpus */ + + /* Find the first bit length which could increase: */ + do { + bits = max_length - 1; + while (s->bl_count[bits] == 0) bits--; + s->bl_count[bits]--; /* move one leaf down the tree */ + s->bl_count[bits + 1] += 2; /* move one overflow item as its brother */ + s->bl_count[max_length]--; + /* The brother of the overflow item also moves one step up, + * but this does not affect bl_count[max_length] + */ + overflow -= 2; + } while (overflow > 0); + + /* Now recompute all bit lengths, scanning in increasing frequency. + * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all + * lengths instead of fixing only the wrong ones. This idea is taken + * from 'ar' written by Haruhiko Okumura.) + */ + for (bits = max_length; bits != 0; bits--) { + n = s->bl_count[bits]; + while (n != 0) { + m = s->heap[--h]; + if (m > max_code) continue; + if ((unsigned) tree[m].Len != (unsigned) bits) { + Tracev((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); + s->opt_len += ((ulg)bits - tree[m].Len) * tree[m].Freq; + tree[m].Len = (ush)bits; + } + n--; + } + } +} + +#ifdef DUMP_BL_TREE +# include +#endif + +/* =========================================================================== + * Construct one Huffman tree and assigns the code bit strings and lengths. + * Update the total bit length for the current block. + * IN assertion: the field freq is set for all tree elements. + * OUT assertions: the fields len and code are set to the optimal bit length + * and corresponding code. The length opt_len is updated; static_len is + * also updated if stree is not null. The field max_code is set. + */ +local void build_tree(deflate_state *s, tree_desc *desc) { + ct_data *tree = desc->dyn_tree; + const ct_data *stree = desc->stat_desc->static_tree; + int elems = desc->stat_desc->elems; + int n, m; /* iterate over heap elements */ + int max_code = -1; /* largest code with non zero frequency */ + int node; /* new node being created */ + + /* Construct the initial heap, with least frequent element in + * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n + 1]. + * heap[0] is not used. + */ + s->heap_len = 0, s->heap_max = HEAP_SIZE; + + for (n = 0; n < elems; n++) { + if (tree[n].Freq != 0) { + s->heap[++(s->heap_len)] = max_code = n; + s->depth[n] = 0; + } else { + tree[n].Len = 0; + } + } + + /* The pkzip format requires that at least one distance code exists, + * and that at least one bit should be sent even if there is only one + * possible code. So to avoid special checks later on we force at least + * two codes of non zero frequency. + */ + while (s->heap_len < 2) { + node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0); + tree[node].Freq = 1; + s->depth[node] = 0; + s->opt_len--; if (stree) s->static_len -= stree[node].Len; + /* node is 0 or 1 so it does not have extra bits */ + } + desc->max_code = max_code; + + /* The elements heap[heap_len/2 + 1 .. heap_len] are leaves of the tree, + * establish sub-heaps of increasing lengths: + */ + for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n); + + /* Construct the Huffman tree by repeatedly combining the least two + * frequent nodes. + */ + node = elems; /* next internal node of the tree */ + do { + pqremove(s, tree, n); /* n = node of least frequency */ + m = s->heap[SMALLEST]; /* m = node of next least frequency */ + + s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */ + s->heap[--(s->heap_max)] = m; + + /* Create a new node father of n and m */ + tree[node].Freq = tree[n].Freq + tree[m].Freq; + s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ? + s->depth[n] : s->depth[m]) + 1); + tree[n].Dad = tree[m].Dad = (ush)node; +#ifdef DUMP_BL_TREE + if (tree == s->bl_tree) { + fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)", + node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); + } +#endif + /* and insert the new node in the heap */ + s->heap[SMALLEST] = node++; + pqdownheap(s, tree, SMALLEST); + + } while (s->heap_len >= 2); + + s->heap[--(s->heap_max)] = s->heap[SMALLEST]; + + /* At this point, the fields freq and dad are set. We can now + * generate the bit lengths. + */ + gen_bitlen(s, (tree_desc *)desc); + + /* The field len is now set, we can generate the bit codes */ + gen_codes ((ct_data *)tree, max_code, s->bl_count); +} + +/* =========================================================================== + * Scan a literal or distance tree to determine the frequencies of the codes + * in the bit length tree. + */ +local void scan_tree(deflate_state *s, ct_data *tree, int max_code) { + int n; /* iterates over all tree elements */ + int prevlen = -1; /* last emitted length */ + int curlen; /* length of current code */ + int nextlen = tree[0].Len; /* length of next code */ + int count = 0; /* repeat count of the current code */ + int max_count = 7; /* max repeat count */ + int min_count = 4; /* min repeat count */ + + if (nextlen == 0) max_count = 138, min_count = 3; + tree[max_code + 1].Len = (ush)0xffff; /* guard */ + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; nextlen = tree[n + 1].Len; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + s->bl_tree[curlen].Freq += count; + } else if (curlen != 0) { + if (curlen != prevlen) s->bl_tree[curlen].Freq++; + s->bl_tree[REP_3_6].Freq++; + } else if (count <= 10) { + s->bl_tree[REPZ_3_10].Freq++; + } else { + s->bl_tree[REPZ_11_138].Freq++; + } + count = 0; prevlen = curlen; + if (nextlen == 0) { + max_count = 138, min_count = 3; + } else if (curlen == nextlen) { + max_count = 6, min_count = 3; + } else { + max_count = 7, min_count = 4; + } + } +} + +/* =========================================================================== + * Send a literal or distance tree in compressed form, using the codes in + * bl_tree. + */ +local void send_tree(deflate_state *s, ct_data *tree, int max_code) { + int n; /* iterates over all tree elements */ + int prevlen = -1; /* last emitted length */ + int curlen; /* length of current code */ + int nextlen = tree[0].Len; /* length of next code */ + int count = 0; /* repeat count of the current code */ + int max_count = 7; /* max repeat count */ + int min_count = 4; /* min repeat count */ + + /* tree[max_code + 1].Len = -1; */ /* guard already set */ + if (nextlen == 0) max_count = 138, min_count = 3; + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; nextlen = tree[n + 1].Len; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + do { send_code(s, curlen, s->bl_tree); } while (--count != 0); + + } else if (curlen != 0) { + if (curlen != prevlen) { + send_code(s, curlen, s->bl_tree); count--; + } + Assert(count >= 3 && count <= 6, " 3_6?"); + send_code(s, REP_3_6, s->bl_tree); send_bits(s, count - 3, 2); + + } else if (count <= 10) { + send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count - 3, 3); + + } else { + send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count - 11, 7); + } + count = 0; prevlen = curlen; + if (nextlen == 0) { + max_count = 138, min_count = 3; + } else if (curlen == nextlen) { + max_count = 6, min_count = 3; + } else { + max_count = 7, min_count = 4; + } + } +} + +/* =========================================================================== + * Construct the Huffman tree for the bit lengths and return the index in + * bl_order of the last bit length code to send. + */ +local int build_bl_tree(deflate_state *s) { + int max_blindex; /* index of last bit length code of non zero freq */ + + /* Determine the bit length frequencies for literal and distance trees */ + scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code); + scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code); + + /* Build the bit length tree: */ + build_tree(s, (tree_desc *)(&(s->bl_desc))); + /* opt_len now includes the length of the tree representations, except the + * lengths of the bit lengths codes and the 5 + 5 + 4 bits for the counts. + */ + + /* Determine the number of bit length codes to send. The pkzip format + * requires that at least 4 bit length codes be sent. (appnote.txt says + * 3 but the actual value used is 4.) + */ + for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { + if (s->bl_tree[bl_order[max_blindex]].Len != 0) break; + } + /* Update opt_len to include the bit length tree and counts */ + s->opt_len += 3*((ulg)max_blindex + 1) + 5 + 5 + 4; + Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", + s->opt_len, s->static_len)); + + return max_blindex; +} + +/* =========================================================================== + * Send the header for a block using dynamic Huffman trees: the counts, the + * lengths of the bit length codes, the literal tree and the distance tree. + * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. + */ +local void send_all_trees(deflate_state *s, int lcodes, int dcodes, + int blcodes) { + int rank; /* index in bl_order */ + + Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); + Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, + "too many codes"); + Tracev((stderr, "\nbl counts: ")); + send_bits(s, lcodes - 257, 5); /* not +255 as stated in appnote.txt */ + send_bits(s, dcodes - 1, 5); + send_bits(s, blcodes - 4, 4); /* not -3 as stated in appnote.txt */ + for (rank = 0; rank < blcodes; rank++) { + Tracev((stderr, "\nbl code %2d ", bl_order[rank])); + send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); + } + Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); + + send_tree(s, (ct_data *)s->dyn_ltree, lcodes - 1); /* literal tree */ + Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); + + send_tree(s, (ct_data *)s->dyn_dtree, dcodes - 1); /* distance tree */ + Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); +} + +/* =========================================================================== + * Send a stored block + */ +void ZLIB_INTERNAL _tr_stored_block(deflate_state *s, charf *buf, + ulg stored_len, int last) { + send_bits(s, (STORED_BLOCK<<1) + last, 3); /* send block type */ + bi_windup(s); /* align on byte boundary */ + put_short(s, (ush)stored_len); + put_short(s, (ush)~stored_len); + if (stored_len) + zmemcpy(s->pending_buf + s->pending, (Bytef *)buf, stored_len); + s->pending += stored_len; +#ifdef ZLIB_DEBUG + s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; + s->compressed_len += (stored_len + 4) << 3; + s->bits_sent += 2*16; + s->bits_sent += stored_len << 3; +#endif +} + +/* =========================================================================== + * Flush the bits in the bit buffer to pending output (leaves at most 7 bits) + */ +void ZLIB_INTERNAL _tr_flush_bits(deflate_state *s) { + bi_flush(s); +} + +/* =========================================================================== + * Send one empty static block to give enough lookahead for inflate. + * This takes 10 bits, of which 7 may remain in the bit buffer. + */ +void ZLIB_INTERNAL _tr_align(deflate_state *s) { + send_bits(s, STATIC_TREES<<1, 3); + send_code(s, END_BLOCK, static_ltree); +#ifdef ZLIB_DEBUG + s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ +#endif + bi_flush(s); +} + +/* =========================================================================== + * Send the block data compressed using the given Huffman trees + */ +local void compress_block(deflate_state *s, const ct_data *ltree, + const ct_data *dtree) { + unsigned dist; /* distance of matched string */ + int lc; /* match length or unmatched char (if dist == 0) */ + unsigned sx = 0; /* running index in symbol buffers */ + unsigned code; /* the code to send */ + int extra; /* number of extra bits to send */ + + if (s->sym_next != 0) do { +#ifdef LIT_MEM + dist = s->d_buf[sx]; + lc = s->l_buf[sx++]; +#else + dist = s->sym_buf[sx++] & 0xff; + dist += (unsigned)(s->sym_buf[sx++] & 0xff) << 8; + lc = s->sym_buf[sx++]; +#endif + if (dist == 0) { + send_code(s, lc, ltree); /* send a literal byte */ + Tracecv(isgraph(lc), (stderr," '%c' ", lc)); + } else { + /* Here, lc is the match length - MIN_MATCH */ + code = _length_code[lc]; + send_code(s, code + LITERALS + 1, ltree); /* send length code */ + extra = extra_lbits[code]; + if (extra != 0) { + lc -= base_length[code]; + send_bits(s, lc, extra); /* send the extra length bits */ + } + dist--; /* dist is now the match distance - 1 */ + code = d_code(dist); + Assert (code < D_CODES, "bad d_code"); + + send_code(s, code, dtree); /* send the distance code */ + extra = extra_dbits[code]; + if (extra != 0) { + dist -= (unsigned)base_dist[code]; + send_bits(s, dist, extra); /* send the extra distance bits */ + } + } /* literal or match pair ? */ + + /* Check for no overlay of pending_buf on needed symbols */ +#ifdef LIT_MEM + Assert(s->pending < 2 * (s->lit_bufsize + sx), "pendingBuf overflow"); +#else + Assert(s->pending < s->lit_bufsize + sx, "pendingBuf overflow"); +#endif + + } while (sx < s->sym_next); + + send_code(s, END_BLOCK, ltree); +} + +/* =========================================================================== + * Check if the data type is TEXT or BINARY, using the following algorithm: + * - TEXT if the two conditions below are satisfied: + * a) There are no non-portable control characters belonging to the + * "block list" (0..6, 14..25, 28..31). + * b) There is at least one printable character belonging to the + * "allow list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255). + * - BINARY otherwise. + * - The following partially-portable control characters form a + * "gray list" that is ignored in this detection algorithm: + * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}). + * IN assertion: the fields Freq of dyn_ltree are set. + */ +local int detect_data_type(deflate_state *s) { + /* block_mask is the bit mask of block-listed bytes + * set bits 0..6, 14..25, and 28..31 + * 0xf3ffc07f = binary 11110011111111111100000001111111 + */ + unsigned long block_mask = 0xf3ffc07fUL; + int n; + + /* Check for non-textual ("block-listed") bytes. */ + for (n = 0; n <= 31; n++, block_mask >>= 1) + if ((block_mask & 1) && (s->dyn_ltree[n].Freq != 0)) + return Z_BINARY; + + /* Check for textual ("allow-listed") bytes. */ + if (s->dyn_ltree[9].Freq != 0 || s->dyn_ltree[10].Freq != 0 + || s->dyn_ltree[13].Freq != 0) + return Z_TEXT; + for (n = 32; n < LITERALS; n++) + if (s->dyn_ltree[n].Freq != 0) + return Z_TEXT; + + /* There are no "block-listed" or "allow-listed" bytes: + * this stream either is empty or has tolerated ("gray-listed") bytes only. + */ + return Z_BINARY; +} + +/* =========================================================================== + * Determine the best encoding for the current block: dynamic trees, static + * trees or store, and write out the encoded block. + */ +void ZLIB_INTERNAL _tr_flush_block(deflate_state *s, charf *buf, + ulg stored_len, int last) { + ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ + int max_blindex = 0; /* index of last bit length code of non zero freq */ + + /* Build the Huffman trees unless a stored block is forced */ + if (s->level > 0) { + + /* Check if the file is binary or text */ + if (s->strm->data_type == Z_UNKNOWN) + s->strm->data_type = detect_data_type(s); + + /* Construct the literal and distance trees */ + build_tree(s, (tree_desc *)(&(s->l_desc))); + Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, + s->static_len)); + + build_tree(s, (tree_desc *)(&(s->d_desc))); + Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, + s->static_len)); + /* At this point, opt_len and static_len are the total bit lengths of + * the compressed block data, excluding the tree representations. + */ + + /* Build the bit length tree for the above two trees, and get the index + * in bl_order of the last bit length code to send. + */ + max_blindex = build_bl_tree(s); + + /* Determine the best encoding. Compute the block lengths in bytes. */ + opt_lenb = (s->opt_len + 3 + 7) >> 3; + static_lenb = (s->static_len + 3 + 7) >> 3; + + Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", + opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, + s->sym_next / 3)); + +#ifndef FORCE_STATIC + if (static_lenb <= opt_lenb || s->strategy == Z_FIXED) +#endif + opt_lenb = static_lenb; + + } else { + Assert(buf != (char*)0, "lost buf"); + opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ + } + +#ifdef FORCE_STORED + if (buf != (char*)0) { /* force stored block */ +#else + if (stored_len + 4 <= opt_lenb && buf != (char*)0) { + /* 4: two words for the lengths */ +#endif + /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. + * Otherwise we can't have processed more than WSIZE input bytes since + * the last block flush, because compression would have been + * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to + * transform a block into a stored block. + */ + _tr_stored_block(s, buf, stored_len, last); + + } else if (static_lenb == opt_lenb) { + send_bits(s, (STATIC_TREES<<1) + last, 3); + compress_block(s, (const ct_data *)static_ltree, + (const ct_data *)static_dtree); +#ifdef ZLIB_DEBUG + s->compressed_len += 3 + s->static_len; +#endif + } else { + send_bits(s, (DYN_TREES<<1) + last, 3); + send_all_trees(s, s->l_desc.max_code + 1, s->d_desc.max_code + 1, + max_blindex + 1); + compress_block(s, (const ct_data *)s->dyn_ltree, + (const ct_data *)s->dyn_dtree); +#ifdef ZLIB_DEBUG + s->compressed_len += 3 + s->opt_len; +#endif + } + Assert (s->compressed_len == s->bits_sent, "bad compressed size"); + /* The above check is made mod 2^32, for files larger than 512 MB + * and uLong implemented on 32 bits. + */ + init_block(s); + + if (last) { + bi_windup(s); +#ifdef ZLIB_DEBUG + s->compressed_len += 7; /* align on byte boundary */ +#endif + } + Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len >> 3, + s->compressed_len - 7*last)); +} + +/* =========================================================================== + * Save the match info and tally the frequency counts. Return true if + * the current block must be flushed. + */ +int ZLIB_INTERNAL _tr_tally(deflate_state *s, unsigned dist, unsigned lc) { +#ifdef LIT_MEM + s->d_buf[s->sym_next] = (ush)dist; + s->l_buf[s->sym_next++] = (uch)lc; +#else + s->sym_buf[s->sym_next++] = (uch)dist; + s->sym_buf[s->sym_next++] = (uch)(dist >> 8); + s->sym_buf[s->sym_next++] = (uch)lc; +#endif + if (dist == 0) { + /* lc is the unmatched char */ + s->dyn_ltree[lc].Freq++; + } else { + s->matches++; + /* Here, lc is the match length - MIN_MATCH */ + dist--; /* dist = match distance - 1 */ + Assert((ush)dist < (ush)MAX_DIST(s) && + (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && + (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); + + s->dyn_ltree[_length_code[lc] + LITERALS + 1].Freq++; + s->dyn_dtree[d_code(dist)].Freq++; + } + return (s->sym_next == s->sym_end); +} diff --git a/common/zlib/trees.h b/common/zlib/trees.h new file mode 100644 index 0000000..d35639d --- /dev/null +++ b/common/zlib/trees.h @@ -0,0 +1,128 @@ +/* header created automatically with -DGEN_TREES_H */ + +local const ct_data static_ltree[L_CODES+2] = { +{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}}, +{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}}, +{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}}, +{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}}, +{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}}, +{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}}, +{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}}, +{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}}, +{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}}, +{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}}, +{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}}, +{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}}, +{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}}, +{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}}, +{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}}, +{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}}, +{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}}, +{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}}, +{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}}, +{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}}, +{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}}, +{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}}, +{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}}, +{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}}, +{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}}, +{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}}, +{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}}, +{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}}, +{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}}, +{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}}, +{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}}, +{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}}, +{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}}, +{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}}, +{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}}, +{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}}, +{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}}, +{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}}, +{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}}, +{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}}, +{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}}, +{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}}, +{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}}, +{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}}, +{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}}, +{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}}, +{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}}, +{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}}, +{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}}, +{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}}, +{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}}, +{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}}, +{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}}, +{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}}, +{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}}, +{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}}, +{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}}, +{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}} +}; + +local const ct_data static_dtree[D_CODES] = { +{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}}, +{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}}, +{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}}, +{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}}, +{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}}, +{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}} +}; + +const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = { + 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, + 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, +10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, +11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, +13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, +13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, +18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 +}; + +const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, +13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, +17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, +19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, +21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, +22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 +}; + +local const int base_length[LENGTH_CODES] = { +0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, +64, 80, 96, 112, 128, 160, 192, 224, 0 +}; + +local const int base_dist[D_CODES] = { + 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, + 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, + 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 +}; + diff --git a/common/zlib/uncompr.c b/common/zlib/uncompr.c new file mode 100644 index 0000000..5e25666 --- /dev/null +++ b/common/zlib/uncompr.c @@ -0,0 +1,85 @@ +/* uncompr.c -- decompress a memory buffer + * Copyright (C) 1995-2003, 2010, 2014, 2016 Jean-loup Gailly, Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#define ZLIB_INTERNAL +#include "zlib.h" + +/* =========================================================================== + Decompresses the source buffer into the destination buffer. *sourceLen is + the byte length of the source buffer. Upon entry, *destLen is the total size + of the destination buffer, which must be large enough to hold the entire + uncompressed data. (The size of the uncompressed data must have been saved + previously by the compressor and transmitted to the decompressor by some + mechanism outside the scope of this compression library.) Upon exit, + *destLen is the size of the decompressed data and *sourceLen is the number + of source bytes consumed. Upon return, source + *sourceLen points to the + first unused input byte. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, or + Z_DATA_ERROR if the input data was corrupted, including if the input data is + an incomplete zlib stream. +*/ +int ZEXPORT uncompress2(Bytef *dest, uLongf *destLen, const Bytef *source, + uLong *sourceLen) { + z_stream stream; + int err; + const uInt max = (uInt)-1; + uLong len, left; + Byte buf[1]; /* for detection of incomplete stream when *destLen == 0 */ + + len = *sourceLen; + if (*destLen) { + left = *destLen; + *destLen = 0; + } + else { + left = 1; + dest = buf; + } + + stream.next_in = (z_const Bytef *)source; + stream.avail_in = 0; + stream.zalloc = (alloc_func)0; + stream.zfree = (free_func)0; + stream.opaque = (voidpf)0; + + err = inflateInit(&stream); + if (err != Z_OK) return err; + + stream.next_out = dest; + stream.avail_out = 0; + + do { + if (stream.avail_out == 0) { + stream.avail_out = left > (uLong)max ? max : (uInt)left; + left -= stream.avail_out; + } + if (stream.avail_in == 0) { + stream.avail_in = len > (uLong)max ? max : (uInt)len; + len -= stream.avail_in; + } + err = inflate(&stream, Z_NO_FLUSH); + } while (err == Z_OK); + + *sourceLen -= len + stream.avail_in; + if (dest != buf) + *destLen = stream.total_out; + else if (stream.total_out && err == Z_BUF_ERROR) + left = 1; + + inflateEnd(&stream); + return err == Z_STREAM_END ? Z_OK : + err == Z_NEED_DICT ? Z_DATA_ERROR : + err == Z_BUF_ERROR && left + stream.avail_out ? Z_DATA_ERROR : + err; +} + +int ZEXPORT uncompress(Bytef *dest, uLongf *destLen, const Bytef *source, + uLong sourceLen) { + return uncompress2(dest, destLen, source, &sourceLen); +} diff --git a/common/zlib/zconf.h b/common/zlib/zconf.h new file mode 100644 index 0000000..62adc8d --- /dev/null +++ b/common/zlib/zconf.h @@ -0,0 +1,543 @@ +/* zconf.h -- configuration of the zlib compression library + * Copyright (C) 1995-2024 Jean-loup Gailly, Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#ifndef ZCONF_H +#define ZCONF_H + +/* + * If you *really* need a unique prefix for all types and library functions, + * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. + * Even better than compiling with -DZ_PREFIX would be to use configure to set + * this permanently in zconf.h using "./configure --zprefix". + */ +#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */ +# define Z_PREFIX_SET + +/* all linked symbols and init macros */ +# define _dist_code z__dist_code +# define _length_code z__length_code +# define _tr_align z__tr_align +# define _tr_flush_bits z__tr_flush_bits +# define _tr_flush_block z__tr_flush_block +# define _tr_init z__tr_init +# define _tr_stored_block z__tr_stored_block +# define _tr_tally z__tr_tally +# define adler32 z_adler32 +# define adler32_combine z_adler32_combine +# define adler32_combine64 z_adler32_combine64 +# define adler32_z z_adler32_z +# ifndef Z_SOLO +# define compress z_compress +# define compress2 z_compress2 +# define compressBound z_compressBound +# endif +# define crc32 z_crc32 +# define crc32_combine z_crc32_combine +# define crc32_combine64 z_crc32_combine64 +# define crc32_combine_gen z_crc32_combine_gen +# define crc32_combine_gen64 z_crc32_combine_gen64 +# define crc32_combine_op z_crc32_combine_op +# define crc32_z z_crc32_z +# define deflate z_deflate +# define deflateBound z_deflateBound +# define deflateCopy z_deflateCopy +# define deflateEnd z_deflateEnd +# define deflateGetDictionary z_deflateGetDictionary +# define deflateInit z_deflateInit +# define deflateInit2 z_deflateInit2 +# define deflateInit2_ z_deflateInit2_ +# define deflateInit_ z_deflateInit_ +# define deflateParams z_deflateParams +# define deflatePending z_deflatePending +# define deflatePrime z_deflatePrime +# define deflateReset z_deflateReset +# define deflateResetKeep z_deflateResetKeep +# define deflateSetDictionary z_deflateSetDictionary +# define deflateSetHeader z_deflateSetHeader +# define deflateTune z_deflateTune +# define deflate_copyright z_deflate_copyright +# define get_crc_table z_get_crc_table +# ifndef Z_SOLO +# define gz_error z_gz_error +# define gz_intmax z_gz_intmax +# define gz_strwinerror z_gz_strwinerror +# define gzbuffer z_gzbuffer +# define gzclearerr z_gzclearerr +# define gzclose z_gzclose +# define gzclose_r z_gzclose_r +# define gzclose_w z_gzclose_w +# define gzdirect z_gzdirect +# define gzdopen z_gzdopen +# define gzeof z_gzeof +# define gzerror z_gzerror +# define gzflush z_gzflush +# define gzfread z_gzfread +# define gzfwrite z_gzfwrite +# define gzgetc z_gzgetc +# define gzgetc_ z_gzgetc_ +# define gzgets z_gzgets +# define gzoffset z_gzoffset +# define gzoffset64 z_gzoffset64 +# define gzopen z_gzopen +# define gzopen64 z_gzopen64 +# ifdef _WIN32 +# define gzopen_w z_gzopen_w +# endif +# define gzprintf z_gzprintf +# define gzputc z_gzputc +# define gzputs z_gzputs +# define gzread z_gzread +# define gzrewind z_gzrewind +# define gzseek z_gzseek +# define gzseek64 z_gzseek64 +# define gzsetparams z_gzsetparams +# define gztell z_gztell +# define gztell64 z_gztell64 +# define gzungetc z_gzungetc +# define gzvprintf z_gzvprintf +# define gzwrite z_gzwrite +# endif +# define inflate z_inflate +# define inflateBack z_inflateBack +# define inflateBackEnd z_inflateBackEnd +# define inflateBackInit z_inflateBackInit +# define inflateBackInit_ z_inflateBackInit_ +# define inflateCodesUsed z_inflateCodesUsed +# define inflateCopy z_inflateCopy +# define inflateEnd z_inflateEnd +# define inflateGetDictionary z_inflateGetDictionary +# define inflateGetHeader z_inflateGetHeader +# define inflateInit z_inflateInit +# define inflateInit2 z_inflateInit2 +# define inflateInit2_ z_inflateInit2_ +# define inflateInit_ z_inflateInit_ +# define inflateMark z_inflateMark +# define inflatePrime z_inflatePrime +# define inflateReset z_inflateReset +# define inflateReset2 z_inflateReset2 +# define inflateResetKeep z_inflateResetKeep +# define inflateSetDictionary z_inflateSetDictionary +# define inflateSync z_inflateSync +# define inflateSyncPoint z_inflateSyncPoint +# define inflateUndermine z_inflateUndermine +# define inflateValidate z_inflateValidate +# define inflate_copyright z_inflate_copyright +# define inflate_fast z_inflate_fast +# define inflate_table z_inflate_table +# ifndef Z_SOLO +# define uncompress z_uncompress +# define uncompress2 z_uncompress2 +# endif +# define zError z_zError +# ifndef Z_SOLO +# define zcalloc z_zcalloc +# define zcfree z_zcfree +# endif +# define zlibCompileFlags z_zlibCompileFlags +# define zlibVersion z_zlibVersion + +/* all zlib typedefs in zlib.h and zconf.h */ +# define Byte z_Byte +# define Bytef z_Bytef +# define alloc_func z_alloc_func +# define charf z_charf +# define free_func z_free_func +# ifndef Z_SOLO +# define gzFile z_gzFile +# endif +# define gz_header z_gz_header +# define gz_headerp z_gz_headerp +# define in_func z_in_func +# define intf z_intf +# define out_func z_out_func +# define uInt z_uInt +# define uIntf z_uIntf +# define uLong z_uLong +# define uLongf z_uLongf +# define voidp z_voidp +# define voidpc z_voidpc +# define voidpf z_voidpf + +/* all zlib structs in zlib.h and zconf.h */ +# define gz_header_s z_gz_header_s +# define internal_state z_internal_state + +#endif + +#if defined(__MSDOS__) && !defined(MSDOS) +# define MSDOS +#endif +#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) +# define OS2 +#endif +#if defined(_WINDOWS) && !defined(WINDOWS) +# define WINDOWS +#endif +#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) +# ifndef WIN32 +# define WIN32 +# endif +#endif +#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) +# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) +# ifndef SYS16BIT +# define SYS16BIT +# endif +# endif +#endif + +/* + * Compile with -DMAXSEG_64K if the alloc function cannot allocate more + * than 64k bytes at a time (needed on systems with 16-bit int). + */ +#ifdef SYS16BIT +# define MAXSEG_64K +#endif +#ifdef MSDOS +# define UNALIGNED_OK +#endif + +#ifdef __STDC_VERSION__ +# ifndef STDC +# define STDC +# endif +# if __STDC_VERSION__ >= 199901L +# ifndef STDC99 +# define STDC99 +# endif +# endif +#endif +#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) +# define STDC +#endif +#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) +# define STDC +#endif +#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) +# define STDC +#endif +#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) +# define STDC +#endif + +#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ +# define STDC +#endif + +#ifndef STDC +# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ +# define const /* note: need a more gentle solution here */ +# endif +#endif + +#if defined(ZLIB_CONST) && !defined(z_const) +# define z_const const +#else +# define z_const +#endif + +#ifdef Z_SOLO +# ifdef _WIN64 + typedef unsigned long long z_size_t; +# else + typedef unsigned long z_size_t; +# endif +#else +# define z_longlong long long +# if defined(NO_SIZE_T) + typedef unsigned NO_SIZE_T z_size_t; +# elif defined(STDC) +# include + typedef size_t z_size_t; +# else + typedef unsigned long z_size_t; +# endif +# undef z_longlong +#endif + +/* Maximum value for memLevel in deflateInit2 */ +#ifndef MAX_MEM_LEVEL +# ifdef MAXSEG_64K +# define MAX_MEM_LEVEL 8 +# else +# define MAX_MEM_LEVEL 9 +# endif +#endif + +/* Maximum value for windowBits in deflateInit2 and inflateInit2. + * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files + * created by gzip. (Files created by minigzip can still be extracted by + * gzip.) + */ +#ifndef MAX_WBITS +# define MAX_WBITS 15 /* 32K LZ77 window */ +#endif + +/* The memory requirements for deflate are (in bytes): + (1 << (windowBits+2)) + (1 << (memLevel+9)) + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) + plus a few kilobytes for small objects. For example, if you want to reduce + the default memory requirements from 256K to 128K, compile with + make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" + Of course this will generally degrade compression (there's no free lunch). + + The memory requirements for inflate are (in bytes) 1 << windowBits + that is, 32K for windowBits=15 (default value) plus about 7 kilobytes + for small objects. +*/ + + /* Type declarations */ + +#ifndef OF /* function prototypes */ +# ifdef STDC +# define OF(args) args +# else +# define OF(args) () +# endif +#endif + +/* The following definitions for FAR are needed only for MSDOS mixed + * model programming (small or medium model with some far allocations). + * This was tested only with MSC; for other MSDOS compilers you may have + * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, + * just define FAR to be empty. + */ +#ifdef SYS16BIT +# if defined(M_I86SM) || defined(M_I86MM) + /* MSC small or medium model */ +# define SMALL_MEDIUM +# ifdef _MSC_VER +# define FAR _far +# else +# define FAR far +# endif +# endif +# if (defined(__SMALL__) || defined(__MEDIUM__)) + /* Turbo C small or medium model */ +# define SMALL_MEDIUM +# ifdef __BORLANDC__ +# define FAR _far +# else +# define FAR far +# endif +# endif +#endif + +#if defined(WINDOWS) || defined(WIN32) + /* If building or using zlib as a DLL, define ZLIB_DLL. + * This is not mandatory, but it offers a little performance increase. + */ +# ifdef ZLIB_DLL +# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) +# ifdef ZLIB_INTERNAL +# define ZEXTERN extern __declspec(dllexport) +# else +# define ZEXTERN extern __declspec(dllimport) +# endif +# endif +# endif /* ZLIB_DLL */ + /* If building or using zlib with the WINAPI/WINAPIV calling convention, + * define ZLIB_WINAPI. + * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. + */ +# ifdef ZLIB_WINAPI +# ifdef FAR +# undef FAR +# endif +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +# endif +# include + /* No need for _export, use ZLIB.DEF instead. */ + /* For complete Windows compatibility, use WINAPI, not __stdcall. */ +# define ZEXPORT WINAPI +# ifdef WIN32 +# define ZEXPORTVA WINAPIV +# else +# define ZEXPORTVA FAR CDECL +# endif +# endif +#endif + +#if defined (__BEOS__) +# ifdef ZLIB_DLL +# ifdef ZLIB_INTERNAL +# define ZEXPORT __declspec(dllexport) +# define ZEXPORTVA __declspec(dllexport) +# else +# define ZEXPORT __declspec(dllimport) +# define ZEXPORTVA __declspec(dllimport) +# endif +# endif +#endif + +#ifndef ZEXTERN +# define ZEXTERN extern +#endif +#ifndef ZEXPORT +# define ZEXPORT +#endif +#ifndef ZEXPORTVA +# define ZEXPORTVA +#endif + +#ifndef FAR +# define FAR +#endif + +#if !defined(__MACTYPES__) +typedef unsigned char Byte; /* 8 bits */ +#endif +typedef unsigned int uInt; /* 16 bits or more */ +typedef unsigned long uLong; /* 32 bits or more */ + +#ifdef SMALL_MEDIUM + /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ +# define Bytef Byte FAR +#else + typedef Byte FAR Bytef; +#endif +typedef char FAR charf; +typedef int FAR intf; +typedef uInt FAR uIntf; +typedef uLong FAR uLongf; + +#ifdef STDC + typedef void const *voidpc; + typedef void FAR *voidpf; + typedef void *voidp; +#else + typedef Byte const *voidpc; + typedef Byte FAR *voidpf; + typedef Byte *voidp; +#endif + +#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC) +# include +# if (UINT_MAX == 0xffffffffUL) +# define Z_U4 unsigned +# elif (ULONG_MAX == 0xffffffffUL) +# define Z_U4 unsigned long +# elif (USHRT_MAX == 0xffffffffUL) +# define Z_U4 unsigned short +# endif +#endif + +#ifdef Z_U4 + typedef Z_U4 z_crc_t; +#else + typedef unsigned long z_crc_t; +#endif + +#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */ +# define Z_HAVE_UNISTD_H +#endif + +#ifdef HAVE_STDARG_H /* may be set to #if 1 by ./configure */ +# define Z_HAVE_STDARG_H +#endif + +#ifdef STDC +# ifndef Z_SOLO +# include /* for off_t */ +# endif +#endif + +#if defined(STDC) || defined(Z_HAVE_STDARG_H) +# ifndef Z_SOLO +# include /* for va_list */ +# endif +#endif + +#ifdef _WIN32 +# ifndef Z_SOLO +# include /* for wchar_t */ +# endif +#endif + +/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and + * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even + * though the former does not conform to the LFS document), but considering + * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as + * equivalently requesting no 64-bit operations + */ +#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1 +# undef _LARGEFILE64_SOURCE +#endif + +#ifndef Z_HAVE_UNISTD_H +# ifdef __WATCOMC__ +# define Z_HAVE_UNISTD_H +# endif +#endif +#ifndef Z_HAVE_UNISTD_H +# if defined(_LARGEFILE64_SOURCE) && !defined(_WIN32) +# define Z_HAVE_UNISTD_H +# endif +#endif +#ifndef Z_SOLO +# if defined(Z_HAVE_UNISTD_H) +# include /* for SEEK_*, off_t, and _LFS64_LARGEFILE */ +# ifdef VMS +# include /* for off_t */ +# endif +# ifndef z_off_t +# define z_off_t off_t +# endif +# endif +#endif + +#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0 +# define Z_LFS64 +#endif + +#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64) +# define Z_LARGE64 +#endif + +#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64) +# define Z_WANT64 +#endif + +#if !defined(SEEK_SET) && !defined(Z_SOLO) +# define SEEK_SET 0 /* Seek from beginning of file. */ +# define SEEK_CUR 1 /* Seek from current position. */ +# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ +#endif + +#ifndef z_off_t +# define z_off_t long +#endif + +#if !defined(_WIN32) && defined(Z_LARGE64) +# define z_off64_t off64_t +#else +# if defined(_WIN32) && !defined(__GNUC__) +# define z_off64_t __int64 +# else +# define z_off64_t z_off_t +# endif +#endif + +/* MVS linker does not support external names larger than 8 bytes */ +#if defined(__MVS__) + #pragma map(deflateInit_,"DEIN") + #pragma map(deflateInit2_,"DEIN2") + #pragma map(deflateEnd,"DEEND") + #pragma map(deflateBound,"DEBND") + #pragma map(inflateInit_,"ININ") + #pragma map(inflateInit2_,"ININ2") + #pragma map(inflateEnd,"INEND") + #pragma map(inflateSync,"INSY") + #pragma map(inflateSetDictionary,"INSEDI") + #pragma map(compressBound,"CMBND") + #pragma map(inflate_table,"INTABL") + #pragma map(inflate_fast,"INFA") + #pragma map(inflate_copyright,"INCOPY") +#endif + +#endif /* ZCONF_H */ diff --git a/common/zlib/zlib.h b/common/zlib/zlib.h new file mode 100644 index 0000000..8d4b932 --- /dev/null +++ b/common/zlib/zlib.h @@ -0,0 +1,1938 @@ +/* zlib.h -- interface of the 'zlib' general purpose compression library + version 1.3.1, January 22nd, 2024 + + Copyright (C) 1995-2024 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + + + The data format used by the zlib library is described by RFCs (Request for + Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950 + (zlib format), rfc1951 (deflate format) and rfc1952 (gzip format). +*/ + +#ifndef ZLIB_H +#define ZLIB_H + +#include "zconf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ZLIB_VERSION "1.3.1" +#define ZLIB_VERNUM 0x1310 +#define ZLIB_VER_MAJOR 1 +#define ZLIB_VER_MINOR 3 +#define ZLIB_VER_REVISION 1 +#define ZLIB_VER_SUBREVISION 0 + +/* + The 'zlib' compression library provides in-memory compression and + decompression functions, including integrity checks of the uncompressed data. + This version of the library supports only one compression method (deflation) + but other algorithms will be added later and will have the same stream + interface. + + Compression can be done in a single step if the buffers are large enough, + or can be done by repeated calls of the compression function. In the latter + case, the application must provide more input and/or consume the output + (providing more output space) before each call. + + The compressed data format used by default by the in-memory functions is + the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped + around a deflate stream, which is itself documented in RFC 1951. + + The library also supports reading and writing files in gzip (.gz) format + with an interface similar to that of stdio using the functions that start + with "gz". The gzip format is different from the zlib format. gzip is a + gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. + + This library can optionally read and write gzip and raw deflate streams in + memory as well. + + The zlib format was designed to be compact and fast for use in memory + and on communications channels. The gzip format was designed for single- + file compression on file systems, has a larger header than zlib to maintain + directory information, and uses a different, slower check method than zlib. + + The library does not install any signal handler. The decoder checks + the consistency of the compressed data, so the library should never crash + even in the case of corrupted input. +*/ + +typedef voidpf (*alloc_func)(voidpf opaque, uInt items, uInt size); +typedef void (*free_func)(voidpf opaque, voidpf address); + +struct internal_state; + +typedef struct z_stream_s { + z_const Bytef *next_in; /* next input byte */ + uInt avail_in; /* number of bytes available at next_in */ + uLong total_in; /* total number of input bytes read so far */ + + Bytef *next_out; /* next output byte will go here */ + uInt avail_out; /* remaining free space at next_out */ + uLong total_out; /* total number of bytes output so far */ + + z_const char *msg; /* last error message, NULL if no error */ + struct internal_state FAR *state; /* not visible by applications */ + + alloc_func zalloc; /* used to allocate the internal state */ + free_func zfree; /* used to free the internal state */ + voidpf opaque; /* private data object passed to zalloc and zfree */ + + int data_type; /* best guess about the data type: binary or text + for deflate, or the decoding state for inflate */ + uLong adler; /* Adler-32 or CRC-32 value of the uncompressed data */ + uLong reserved; /* reserved for future use */ +} z_stream; + +typedef z_stream FAR *z_streamp; + +/* + gzip header information passed to and from zlib routines. See RFC 1952 + for more details on the meanings of these fields. +*/ +typedef struct gz_header_s { + int text; /* true if compressed data believed to be text */ + uLong time; /* modification time */ + int xflags; /* extra flags (not used when writing a gzip file) */ + int os; /* operating system */ + Bytef *extra; /* pointer to extra field or Z_NULL if none */ + uInt extra_len; /* extra field length (valid if extra != Z_NULL) */ + uInt extra_max; /* space at extra (only when reading header) */ + Bytef *name; /* pointer to zero-terminated file name or Z_NULL */ + uInt name_max; /* space at name (only when reading header) */ + Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */ + uInt comm_max; /* space at comment (only when reading header) */ + int hcrc; /* true if there was or will be a header crc */ + int done; /* true when done reading gzip header (not used + when writing a gzip file) */ +} gz_header; + +typedef gz_header FAR *gz_headerp; + +/* + The application must update next_in and avail_in when avail_in has dropped + to zero. It must update next_out and avail_out when avail_out has dropped + to zero. The application must initialize zalloc, zfree and opaque before + calling the init function. All other fields are set by the compression + library and must not be updated by the application. + + The opaque value provided by the application will be passed as the first + parameter for calls of zalloc and zfree. This can be useful for custom + memory management. The compression library attaches no meaning to the + opaque value. + + zalloc must return Z_NULL if there is not enough memory for the object. + If zlib is used in a multi-threaded application, zalloc and zfree must be + thread safe. In that case, zlib is thread-safe. When zalloc and zfree are + Z_NULL on entry to the initialization function, they are set to internal + routines that use the standard library functions malloc() and free(). + + On 16-bit systems, the functions zalloc and zfree must be able to allocate + exactly 65536 bytes, but will not be required to allocate more than this if + the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, pointers + returned by zalloc for objects of exactly 65536 bytes *must* have their + offset normalized to zero. The default allocation function provided by this + library ensures this (see zutil.c). To reduce memory requirements and avoid + any allocation of 64K objects, at the expense of compression ratio, compile + the library with -DMAX_WBITS=14 (see zconf.h). + + The fields total_in and total_out can be used for statistics or progress + reports. After compression, total_in holds the total size of the + uncompressed data and may be saved for use by the decompressor (particularly + if the decompressor wants to decompress everything in a single step). +*/ + + /* constants */ + +#define Z_NO_FLUSH 0 +#define Z_PARTIAL_FLUSH 1 +#define Z_SYNC_FLUSH 2 +#define Z_FULL_FLUSH 3 +#define Z_FINISH 4 +#define Z_BLOCK 5 +#define Z_TREES 6 +/* Allowed flush values; see deflate() and inflate() below for details */ + +#define Z_OK 0 +#define Z_STREAM_END 1 +#define Z_NEED_DICT 2 +#define Z_ERRNO (-1) +#define Z_STREAM_ERROR (-2) +#define Z_DATA_ERROR (-3) +#define Z_MEM_ERROR (-4) +#define Z_BUF_ERROR (-5) +#define Z_VERSION_ERROR (-6) +/* Return codes for the compression/decompression functions. Negative values + * are errors, positive values are used for special but normal events. + */ + +#define Z_NO_COMPRESSION 0 +#define Z_BEST_SPEED 1 +#define Z_BEST_COMPRESSION 9 +#define Z_DEFAULT_COMPRESSION (-1) +/* compression levels */ + +#define Z_FILTERED 1 +#define Z_HUFFMAN_ONLY 2 +#define Z_RLE 3 +#define Z_FIXED 4 +#define Z_DEFAULT_STRATEGY 0 +/* compression strategy; see deflateInit2() below for details */ + +#define Z_BINARY 0 +#define Z_TEXT 1 +#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */ +#define Z_UNKNOWN 2 +/* Possible values of the data_type field for deflate() */ + +#define Z_DEFLATED 8 +/* The deflate compression method (the only one supported in this version) */ + +#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ + +#define zlib_version zlibVersion() +/* for compatibility with versions < 1.0.2 */ + + + /* basic functions */ + +ZEXTERN const char * ZEXPORT zlibVersion(void); +/* The application can compare zlibVersion and ZLIB_VERSION for consistency. + If the first character differs, the library code actually used is not + compatible with the zlib.h header file used by the application. This check + is automatically made by deflateInit and inflateInit. + */ + +/* +ZEXTERN int ZEXPORT deflateInit(z_streamp strm, int level); + + Initializes the internal stream state for compression. The fields + zalloc, zfree and opaque must be initialized before by the caller. If + zalloc and zfree are set to Z_NULL, deflateInit updates them to use default + allocation functions. total_in, total_out, adler, and msg are initialized. + + The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: + 1 gives best speed, 9 gives best compression, 0 gives no compression at all + (the input data is simply copied a block at a time). Z_DEFAULT_COMPRESSION + requests a default compromise between speed and compression (currently + equivalent to level 6). + + deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if level is not a valid compression level, or + Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible + with the version assumed by the caller (ZLIB_VERSION). msg is set to null + if there is no error message. deflateInit does not perform any compression: + this will be done by deflate(). +*/ + + +ZEXTERN int ZEXPORT deflate(z_streamp strm, int flush); +/* + deflate compresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce + some output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. deflate performs one or both of the + following actions: + + - Compress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in and avail_in are updated and + processing will resume at this point for the next call of deflate(). + + - Generate more output starting at next_out and update next_out and avail_out + accordingly. This action is forced if the parameter flush is non zero. + Forcing flush frequently degrades the compression ratio, so this parameter + should be set only when necessary. Some output may be provided even if + flush is zero. + + Before the call of deflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming more + output, and updating avail_in or avail_out accordingly; avail_out should + never be zero before the call. The application can consume the compressed + output when it wants, for example when the output buffer is full (avail_out + == 0), or after each call of deflate(). If deflate returns Z_OK and with + zero avail_out, it must be called again after making room in the output + buffer because there might be more output pending. See deflatePending(), + which can be used if desired to determine whether or not there is more output + in that case. + + Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to + decide how much data to accumulate before producing output, in order to + maximize compression. + + If the parameter flush is set to Z_SYNC_FLUSH, all pending output is + flushed to the output buffer and the output is aligned on a byte boundary, so + that the decompressor can get all input data available so far. (In + particular avail_in is zero after the call if enough output space has been + provided before the call.) Flushing may degrade compression for some + compression algorithms and so it should be used only when necessary. This + completes the current deflate block and follows it with an empty stored block + that is three bits plus filler bits to the next byte, followed by four bytes + (00 00 ff ff). + + If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the + output buffer, but the output is not aligned to a byte boundary. All of the + input data so far will be available to the decompressor, as for Z_SYNC_FLUSH. + This completes the current deflate block and follows it with an empty fixed + codes block that is 10 bits long. This assures that enough bytes are output + in order for the decompressor to finish the block before the empty fixed + codes block. + + If flush is set to Z_BLOCK, a deflate block is completed and emitted, as + for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to + seven bits of the current block are held to be written as the next byte after + the next deflate block is completed. In this case, the decompressor may not + be provided enough bits at this point in order to complete decompression of + the data provided so far to the compressor. It may need to wait for the next + block to be emitted. This is for advanced applications that need to control + the emission of deflate blocks. + + If flush is set to Z_FULL_FLUSH, all output is flushed as with + Z_SYNC_FLUSH, and the compression state is reset so that decompression can + restart from this point if previous compressed data has been damaged or if + random access is desired. Using Z_FULL_FLUSH too often can seriously degrade + compression. + + If deflate returns with avail_out == 0, this function must be called again + with the same value of the flush parameter and more output space (updated + avail_out), until the flush is complete (deflate returns with non-zero + avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that + avail_out is greater than six when the flush marker begins, in order to avoid + repeated flush markers upon calling deflate() again when avail_out == 0. + + If the parameter flush is set to Z_FINISH, pending input is processed, + pending output is flushed and deflate returns with Z_STREAM_END if there was + enough output space. If deflate returns with Z_OK or Z_BUF_ERROR, this + function must be called again with Z_FINISH and more output space (updated + avail_out) but no more input data, until it returns with Z_STREAM_END or an + error. After deflate has returned Z_STREAM_END, the only possible operations + on the stream are deflateReset or deflateEnd. + + Z_FINISH can be used in the first deflate call after deflateInit if all the + compression is to be done in a single step. In order to complete in one + call, avail_out must be at least the value returned by deflateBound (see + below). Then deflate is guaranteed to return Z_STREAM_END. If not enough + output space is provided, deflate will not return Z_STREAM_END, and it must + be called again as described above. + + deflate() sets strm->adler to the Adler-32 checksum of all input read + so far (that is, total_in bytes). If a gzip stream is being generated, then + strm->adler will be the CRC-32 checksum of the input read so far. (See + deflateInit2 below.) + + deflate() may update strm->data_type if it can make a good guess about + the input data type (Z_BINARY or Z_TEXT). If in doubt, the data is + considered binary. This field is only for information purposes and does not + affect the compression algorithm in any manner. + + deflate() returns Z_OK if some progress has been made (more input + processed or more output produced), Z_STREAM_END if all input has been + consumed and all output has been produced (only when flush is set to + Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example + if next_in or next_out was Z_NULL or the state was inadvertently written over + by the application), or Z_BUF_ERROR if no progress is possible (for example + avail_in or avail_out was zero). Note that Z_BUF_ERROR is not fatal, and + deflate() can be called again with more input and more output space to + continue compressing. +*/ + + +ZEXTERN int ZEXPORT deflateEnd(z_streamp strm); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any pending + output. + + deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the + stream state was inconsistent, Z_DATA_ERROR if the stream was freed + prematurely (some input or output was discarded). In the error case, msg + may be set but then points to a static string (which must not be + deallocated). +*/ + + +/* +ZEXTERN int ZEXPORT inflateInit(z_streamp strm); + + Initializes the internal stream state for decompression. The fields + next_in, avail_in, zalloc, zfree and opaque must be initialized before by + the caller. In the current version of inflate, the provided input is not + read or consumed. The allocation of a sliding window will be deferred to + the first call of inflate (if the decompression does not complete on the + first call). If zalloc and zfree are set to Z_NULL, inflateInit updates + them to use default allocation functions. total_in, total_out, adler, and + msg are initialized. + + inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller, or Z_STREAM_ERROR if the parameters are + invalid, such as a null pointer to the structure. msg is set to null if + there is no error message. inflateInit does not perform any decompression. + Actual decompression will be done by inflate(). So next_in, and avail_in, + next_out, and avail_out are unused and unchanged. The current + implementation of inflateInit() does not process any header information -- + that is deferred until inflate() is called. +*/ + + +ZEXTERN int ZEXPORT inflate(z_streamp strm, int flush); +/* + inflate decompresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce + some output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. inflate performs one or both of the + following actions: + + - Decompress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), then next_in and avail_in are updated + accordingly, and processing will resume at this point for the next call of + inflate(). + + - Generate more output starting at next_out and update next_out and avail_out + accordingly. inflate() provides as much output as possible, until there is + no more input data or no more space in the output buffer (see below about + the flush parameter). + + Before the call of inflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming more + output, and updating the next_* and avail_* values accordingly. If the + caller of inflate() does not provide both available input and available + output space, it is possible that there will be no progress made. The + application can consume the uncompressed output when it wants, for example + when the output buffer is full (avail_out == 0), or after each call of + inflate(). If inflate returns Z_OK and with zero avail_out, it must be + called again after making room in the output buffer because there might be + more output pending. + + The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH, + Z_BLOCK, or Z_TREES. Z_SYNC_FLUSH requests that inflate() flush as much + output as possible to the output buffer. Z_BLOCK requests that inflate() + stop if and when it gets to the next deflate block boundary. When decoding + the zlib or gzip format, this will cause inflate() to return immediately + after the header and before the first block. When doing a raw inflate, + inflate() will go ahead and process the first block, and will return when it + gets to the end of that block, or when it runs out of data. + + The Z_BLOCK option assists in appending to or combining deflate streams. + To assist in this, on return inflate() always sets strm->data_type to the + number of unused bits in the last byte taken from strm->next_in, plus 64 if + inflate() is currently decoding the last block in the deflate stream, plus + 128 if inflate() returned immediately after decoding an end-of-block code or + decoding the complete header up to just before the first byte of the deflate + stream. The end-of-block will not be indicated until all of the uncompressed + data from that block has been written to strm->next_out. The number of + unused bits may in general be greater than seven, except when bit 7 of + data_type is set, in which case the number of unused bits will be less than + eight. data_type is set as noted here every time inflate() returns for all + flush options, and so can be used to determine the amount of currently + consumed input in bits. + + The Z_TREES option behaves as Z_BLOCK does, but it also returns when the + end of each deflate block header is reached, before any actual data in that + block is decoded. This allows the caller to determine the length of the + deflate block header for later use in random access within a deflate block. + 256 is added to the value of strm->data_type when inflate() returns + immediately after reaching the end of the deflate block header. + + inflate() should normally be called until it returns Z_STREAM_END or an + error. However if all decompression is to be performed in a single step (a + single call of inflate), the parameter flush should be set to Z_FINISH. In + this case all pending input is processed and all pending output is flushed; + avail_out must be large enough to hold all of the uncompressed data for the + operation to complete. (The size of the uncompressed data may have been + saved by the compressor for this purpose.) The use of Z_FINISH is not + required to perform an inflation in one step. However it may be used to + inform inflate that a faster approach can be used for the single inflate() + call. Z_FINISH also informs inflate to not maintain a sliding window if the + stream completes, which reduces inflate's memory footprint. If the stream + does not complete, either because not all of the stream is provided or not + enough output space is provided, then a sliding window will be allocated and + inflate() can be called again to continue the operation as if Z_NO_FLUSH had + been used. + + In this implementation, inflate() always flushes as much output as + possible to the output buffer, and always uses the faster approach on the + first call. So the effects of the flush parameter in this implementation are + on the return value of inflate() as noted below, when inflate() returns early + when Z_BLOCK or Z_TREES is used, and when inflate() avoids the allocation of + memory for a sliding window when Z_FINISH is used. + + If a preset dictionary is needed after this call (see inflateSetDictionary + below), inflate sets strm->adler to the Adler-32 checksum of the dictionary + chosen by the compressor and returns Z_NEED_DICT; otherwise it sets + strm->adler to the Adler-32 checksum of all output produced so far (that is, + total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described + below. At the end of the stream, inflate() checks that its computed Adler-32 + checksum is equal to that saved by the compressor and returns Z_STREAM_END + only if the checksum is correct. + + inflate() can decompress and check either zlib-wrapped or gzip-wrapped + deflate data. The header type is detected automatically, if requested when + initializing with inflateInit2(). Any information contained in the gzip + header is not retained unless inflateGetHeader() is used. When processing + gzip-wrapped deflate data, strm->adler32 is set to the CRC-32 of the output + produced so far. The CRC-32 is checked against the gzip trailer, as is the + uncompressed length, modulo 2^32. + + inflate() returns Z_OK if some progress has been made (more input processed + or more output produced), Z_STREAM_END if the end of the compressed data has + been reached and all uncompressed output has been produced, Z_NEED_DICT if a + preset dictionary is needed at this point, Z_DATA_ERROR if the input data was + corrupted (input stream not conforming to the zlib format or incorrect check + value, in which case strm->msg points to a string with a more specific + error), Z_STREAM_ERROR if the stream structure was inconsistent (for example + next_in or next_out was Z_NULL, or the state was inadvertently written over + by the application), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR + if no progress was possible or if there was not enough room in the output + buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and + inflate() can be called again with more input and more output space to + continue decompressing. If Z_DATA_ERROR is returned, the application may + then call inflateSync() to look for a good compression block if a partial + recovery of the data is to be attempted. +*/ + + +ZEXTERN int ZEXPORT inflateEnd(z_streamp strm); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any pending + output. + + inflateEnd returns Z_OK if success, or Z_STREAM_ERROR if the stream state + was inconsistent. +*/ + + + /* Advanced functions */ + +/* + The following functions are needed only in some special applications. +*/ + +/* +ZEXTERN int ZEXPORT deflateInit2(z_streamp strm, + int level, + int method, + int windowBits, + int memLevel, + int strategy); + + This is another version of deflateInit with more compression options. The + fields zalloc, zfree and opaque must be initialized before by the caller. + + The method parameter is the compression method. It must be Z_DEFLATED in + this version of the library. + + The windowBits parameter is the base two logarithm of the window size + (the size of the history buffer). It should be in the range 8..15 for this + version of the library. Larger values of this parameter result in better + compression at the expense of memory usage. The default value is 15 if + deflateInit is used instead. + + For the current implementation of deflate(), a windowBits value of 8 (a + window size of 256 bytes) is not supported. As a result, a request for 8 + will result in 9 (a 512-byte window). In that case, providing 8 to + inflateInit2() will result in an error when the zlib header with 9 is + checked against the initialization of inflate(). The remedy is to not use 8 + with deflateInit2() with this initialization, or at least in that case use 9 + with inflateInit2(). + + windowBits can also be -8..-15 for raw deflate. In this case, -windowBits + determines the window size. deflate() will then generate raw deflate data + with no zlib header or trailer, and will not compute a check value. + + windowBits can also be greater than 15 for optional gzip encoding. Add + 16 to windowBits to write a simple gzip header and trailer around the + compressed data instead of a zlib wrapper. The gzip header will have no + file name, no extra data, no comment, no modification time (set to zero), no + header crc, and the operating system will be set to the appropriate value, + if the operating system was determined at compile time. If a gzip stream is + being written, strm->adler is a CRC-32 instead of an Adler-32. + + For raw deflate or gzip encoding, a request for a 256-byte window is + rejected as invalid, since only the zlib header provides a means of + transmitting the window size to the decompressor. + + The memLevel parameter specifies how much memory should be allocated + for the internal compression state. memLevel=1 uses minimum memory but is + slow and reduces compression ratio; memLevel=9 uses maximum memory for + optimal speed. The default value is 8. See zconf.h for total memory usage + as a function of windowBits and memLevel. + + The strategy parameter is used to tune the compression algorithm. Use the + value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a + filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no + string match), or Z_RLE to limit match distances to one (run-length + encoding). Filtered data consists mostly of small values with a somewhat + random distribution. In this case, the compression algorithm is tuned to + compress them better. The effect of Z_FILTERED is to force more Huffman + coding and less string matching; it is somewhat intermediate between + Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as + fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data. The + strategy parameter only affects the compression ratio but not the + correctness of the compressed output even if it is not set appropriately. + Z_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler + decoder for special applications. + + deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if any parameter is invalid (such as an invalid + method), or Z_VERSION_ERROR if the zlib library version (zlib_version) is + incompatible with the version assumed by the caller (ZLIB_VERSION). msg is + set to null if there is no error message. deflateInit2 does not perform any + compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateSetDictionary(z_streamp strm, + const Bytef *dictionary, + uInt dictLength); +/* + Initializes the compression dictionary from the given byte sequence + without producing any compressed output. When using the zlib format, this + function must be called immediately after deflateInit, deflateInit2 or + deflateReset, and before any call of deflate. When doing raw deflate, this + function must be called either before any call of deflate, or immediately + after the completion of a deflate block, i.e. after all input has been + consumed and all output has been delivered when using any of the flush + options Z_BLOCK, Z_PARTIAL_FLUSH, Z_SYNC_FLUSH, or Z_FULL_FLUSH. The + compressor and decompressor must use exactly the same dictionary (see + inflateSetDictionary). + + The dictionary should consist of strings (byte sequences) that are likely + to be encountered later in the data to be compressed, with the most commonly + used strings preferably put towards the end of the dictionary. Using a + dictionary is most useful when the data to be compressed is short and can be + predicted with good accuracy; the data can then be compressed better than + with the default empty dictionary. + + Depending on the size of the compression data structures selected by + deflateInit or deflateInit2, a part of the dictionary may in effect be + discarded, for example if the dictionary is larger than the window size + provided in deflateInit or deflateInit2. Thus the strings most likely to be + useful should be put at the end of the dictionary, not at the front. In + addition, the current implementation of deflate will use at most the window + size minus 262 bytes of the provided dictionary. + + Upon return of this function, strm->adler is set to the Adler-32 value + of the dictionary; the decompressor may later use this value to determine + which dictionary has been used by the compressor. (The Adler-32 value + applies to the whole dictionary even if only a subset of the dictionary is + actually used by the compressor.) If a raw deflate was requested, then the + Adler-32 value is not computed and strm->adler is not set. + + deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a + parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is + inconsistent (for example if deflate has already been called for this stream + or if not at a block boundary for raw deflate). deflateSetDictionary does + not perform any compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateGetDictionary(z_streamp strm, + Bytef *dictionary, + uInt *dictLength); +/* + Returns the sliding dictionary being maintained by deflate. dictLength is + set to the number of bytes in the dictionary, and that many bytes are copied + to dictionary. dictionary must have enough space, where 32768 bytes is + always enough. If deflateGetDictionary() is called with dictionary equal to + Z_NULL, then only the dictionary length is returned, and nothing is copied. + Similarly, if dictLength is Z_NULL, then it is not set. + + deflateGetDictionary() may return a length less than the window size, even + when more than the window size in input has been provided. It may return up + to 258 bytes less in that case, due to how zlib's implementation of deflate + manages the sliding window and lookahead for matches, where matches can be + up to 258 bytes long. If the application needs the last window-size bytes of + input, then that would need to be saved by the application outside of zlib. + + deflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the + stream state is inconsistent. +*/ + +ZEXTERN int ZEXPORT deflateCopy(z_streamp dest, + z_streamp source); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when several compression strategies will be + tried, for example when there are several ways of pre-processing the input + data with a filter. The streams that will be discarded should then be freed + by calling deflateEnd. Note that deflateCopy duplicates the internal + compression state which can be quite large, so this strategy is slow and can + consume lots of memory. + + deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being Z_NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT deflateReset(z_streamp strm); +/* + This function is equivalent to deflateEnd followed by deflateInit, but + does not free and reallocate the internal compression state. The stream + will leave the compression level and any other attributes that may have been + set unchanged. total_in, total_out, adler, and msg are initialized. + + deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being Z_NULL). +*/ + +ZEXTERN int ZEXPORT deflateParams(z_streamp strm, + int level, + int strategy); +/* + Dynamically update the compression level and compression strategy. The + interpretation of level and strategy is as in deflateInit2(). This can be + used to switch between compression and straight copy of the input data, or + to switch to a different kind of input data requiring a different strategy. + If the compression approach (which is a function of the level) or the + strategy is changed, and if there have been any deflate() calls since the + state was initialized or reset, then the input available so far is + compressed with the old level and strategy using deflate(strm, Z_BLOCK). + There are three approaches for the compression levels 0, 1..3, and 4..9 + respectively. The new level and strategy will take effect at the next call + of deflate(). + + If a deflate(strm, Z_BLOCK) is performed by deflateParams(), and it does + not have enough output space to complete, then the parameter change will not + take effect. In this case, deflateParams() can be called again with the + same parameters and more output space to try again. + + In order to assure a change in the parameters on the first try, the + deflate stream should be flushed using deflate() with Z_BLOCK or other flush + request until strm.avail_out is not zero, before calling deflateParams(). + Then no more input data should be provided before the deflateParams() call. + If this is done, the old level and strategy will be applied to the data + compressed before deflateParams(), and the new level and strategy will be + applied to the data compressed after deflateParams(). + + deflateParams returns Z_OK on success, Z_STREAM_ERROR if the source stream + state was inconsistent or if a parameter was invalid, or Z_BUF_ERROR if + there was not enough output space to complete the compression of the + available input data before a change in the strategy or approach. Note that + in the case of a Z_BUF_ERROR, the parameters are not changed. A return + value of Z_BUF_ERROR is not fatal, in which case deflateParams() can be + retried with more output space. +*/ + +ZEXTERN int ZEXPORT deflateTune(z_streamp strm, + int good_length, + int max_lazy, + int nice_length, + int max_chain); +/* + Fine tune deflate's internal compression parameters. This should only be + used by someone who understands the algorithm used by zlib's deflate for + searching for the best matching string, and even then only by the most + fanatic optimizer trying to squeeze out the last compressed bit for their + specific input data. Read the deflate.c source code for the meaning of the + max_lazy, good_length, nice_length, and max_chain parameters. + + deflateTune() can be called after deflateInit() or deflateInit2(), and + returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. + */ + +ZEXTERN uLong ZEXPORT deflateBound(z_streamp strm, + uLong sourceLen); +/* + deflateBound() returns an upper bound on the compressed size after + deflation of sourceLen bytes. It must be called after deflateInit() or + deflateInit2(), and after deflateSetHeader(), if used. This would be used + to allocate an output buffer for deflation in a single pass, and so would be + called before deflate(). If that first deflate() call is provided the + sourceLen input bytes, an output buffer allocated to the size returned by + deflateBound(), and the flush value Z_FINISH, then deflate() is guaranteed + to return Z_STREAM_END. Note that it is possible for the compressed size to + be larger than the value returned by deflateBound() if flush options other + than Z_FINISH or Z_NO_FLUSH are used. +*/ + +ZEXTERN int ZEXPORT deflatePending(z_streamp strm, + unsigned *pending, + int *bits); +/* + deflatePending() returns the number of bytes and bits of output that have + been generated, but not yet provided in the available output. The bytes not + provided would be due to the available output space having being consumed. + The number of bits of output not provided are between 0 and 7, where they + await more bits to join them in order to fill out a full byte. If pending + or bits are Z_NULL, then those values are not set. + + deflatePending returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. + */ + +ZEXTERN int ZEXPORT deflatePrime(z_streamp strm, + int bits, + int value); +/* + deflatePrime() inserts bits in the deflate output stream. The intent + is that this function is used to start off the deflate output with the bits + leftover from a previous deflate stream when appending to it. As such, this + function can only be used for raw deflate, and must be used before the first + deflate() call after a deflateInit2() or deflateReset(). bits must be less + than or equal to 16, and that many of the least significant bits of value + will be inserted in the output. + + deflatePrime returns Z_OK if success, Z_BUF_ERROR if there was not enough + room in the internal buffer to insert the bits, or Z_STREAM_ERROR if the + source stream state was inconsistent. +*/ + +ZEXTERN int ZEXPORT deflateSetHeader(z_streamp strm, + gz_headerp head); +/* + deflateSetHeader() provides gzip header information for when a gzip + stream is requested by deflateInit2(). deflateSetHeader() may be called + after deflateInit2() or deflateReset() and before the first call of + deflate(). The text, time, os, extra field, name, and comment information + in the provided gz_header structure are written to the gzip header (xflag is + ignored -- the extra flags are set according to the compression level). The + caller must assure that, if not Z_NULL, name and comment are terminated with + a zero byte, and that if extra is not Z_NULL, that extra_len bytes are + available there. If hcrc is true, a gzip header crc is included. Note that + the current versions of the command-line version of gzip (up through version + 1.3.x) do not support header crc's, and will report that it is a "multi-part + gzip file" and give up. + + If deflateSetHeader is not used, the default gzip header has text false, + the time set to zero, and os set to the current operating system, with no + extra, name, or comment fields. The gzip header is returned to the default + state by deflateReset(). + + deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +/* +ZEXTERN int ZEXPORT inflateInit2(z_streamp strm, + int windowBits); + + This is another version of inflateInit with an extra parameter. The + fields next_in, avail_in, zalloc, zfree and opaque must be initialized + before by the caller. + + The windowBits parameter is the base two logarithm of the maximum window + size (the size of the history buffer). It should be in the range 8..15 for + this version of the library. The default value is 15 if inflateInit is used + instead. windowBits must be greater than or equal to the windowBits value + provided to deflateInit2() while compressing, or it must be equal to 15 if + deflateInit2() was not used. If a compressed stream with a larger window + size is given as input, inflate() will return with the error code + Z_DATA_ERROR instead of trying to allocate a larger window. + + windowBits can also be zero to request that inflate use the window size in + the zlib header of the compressed stream. + + windowBits can also be -8..-15 for raw inflate. In this case, -windowBits + determines the window size. inflate() will then process raw deflate data, + not looking for a zlib or gzip header, not generating a check value, and not + looking for any check values for comparison at the end of the stream. This + is for use with other formats that use the deflate compressed data format + such as zip. Those formats provide their own check values. If a custom + format is developed using the raw deflate format for compressed data, it is + recommended that a check value such as an Adler-32 or a CRC-32 be applied to + the uncompressed data as is done in the zlib, gzip, and zip formats. For + most applications, the zlib format should be used as is. Note that comments + above on the use in deflateInit2() applies to the magnitude of windowBits. + + windowBits can also be greater than 15 for optional gzip decoding. Add + 32 to windowBits to enable zlib and gzip decoding with automatic header + detection, or add 16 to decode only the gzip format (the zlib format will + return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is a + CRC-32 instead of an Adler-32. Unlike the gunzip utility and gzread() (see + below), inflate() will *not* automatically decode concatenated gzip members. + inflate() will return Z_STREAM_END at the end of the gzip member. The state + would need to be reset to continue decoding a subsequent gzip member. This + *must* be done if there is more data after a gzip member, in order for the + decompression to be compliant with the gzip standard (RFC 1952). + + inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller, or Z_STREAM_ERROR if the parameters are + invalid, such as a null pointer to the structure. msg is set to null if + there is no error message. inflateInit2 does not perform any decompression + apart from possibly reading the zlib header if present: actual decompression + will be done by inflate(). (So next_in and avail_in may be modified, but + next_out and avail_out are unused and unchanged.) The current implementation + of inflateInit2() does not process any header information -- that is + deferred until inflate() is called. +*/ + +ZEXTERN int ZEXPORT inflateSetDictionary(z_streamp strm, + const Bytef *dictionary, + uInt dictLength); +/* + Initializes the decompression dictionary from the given uncompressed byte + sequence. This function must be called immediately after a call of inflate, + if that call returned Z_NEED_DICT. The dictionary chosen by the compressor + can be determined from the Adler-32 value returned by that call of inflate. + The compressor and decompressor must use exactly the same dictionary (see + deflateSetDictionary). For raw inflate, this function can be called at any + time to set the dictionary. If the provided dictionary is smaller than the + window and there is already data in the window, then the provided dictionary + will amend what's there. The application must insure that the dictionary + that was used for compression is provided. + + inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a + parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is + inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the + expected one (incorrect Adler-32 value). inflateSetDictionary does not + perform any decompression: this will be done by subsequent calls of + inflate(). +*/ + +ZEXTERN int ZEXPORT inflateGetDictionary(z_streamp strm, + Bytef *dictionary, + uInt *dictLength); +/* + Returns the sliding dictionary being maintained by inflate. dictLength is + set to the number of bytes in the dictionary, and that many bytes are copied + to dictionary. dictionary must have enough space, where 32768 bytes is + always enough. If inflateGetDictionary() is called with dictionary equal to + Z_NULL, then only the dictionary length is returned, and nothing is copied. + Similarly, if dictLength is Z_NULL, then it is not set. + + inflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the + stream state is inconsistent. +*/ + +ZEXTERN int ZEXPORT inflateSync(z_streamp strm); +/* + Skips invalid compressed data until a possible full flush point (see above + for the description of deflate with Z_FULL_FLUSH) can be found, or until all + available input is skipped. No output is provided. + + inflateSync searches for a 00 00 FF FF pattern in the compressed data. + All full flush points have this pattern, but not all occurrences of this + pattern are full flush points. + + inflateSync returns Z_OK if a possible full flush point has been found, + Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point + has been found, or Z_STREAM_ERROR if the stream structure was inconsistent. + In the success case, the application may save the current value of total_in + which indicates where valid compressed data was found. In the error case, + the application may repeatedly call inflateSync, providing more input each + time, until success or end of the input data. +*/ + +ZEXTERN int ZEXPORT inflateCopy(z_streamp dest, + z_streamp source); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when randomly accessing a large stream. The + first pass through the stream can periodically record the inflate state, + allowing restarting inflate at those points when randomly accessing the + stream. + + inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being Z_NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT inflateReset(z_streamp strm); +/* + This function is equivalent to inflateEnd followed by inflateInit, + but does not free and reallocate the internal decompression state. The + stream will keep attributes that may have been set by inflateInit2. + total_in, total_out, adler, and msg are initialized. + + inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being Z_NULL). +*/ + +ZEXTERN int ZEXPORT inflateReset2(z_streamp strm, + int windowBits); +/* + This function is the same as inflateReset, but it also permits changing + the wrap and window size requests. The windowBits parameter is interpreted + the same as it is for inflateInit2. If the window size is changed, then the + memory allocated for the window is freed, and the window will be reallocated + by inflate() if needed. + + inflateReset2 returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being Z_NULL), or if + the windowBits parameter is invalid. +*/ + +ZEXTERN int ZEXPORT inflatePrime(z_streamp strm, + int bits, + int value); +/* + This function inserts bits in the inflate input stream. The intent is + that this function is used to start inflating at a bit position in the + middle of a byte. The provided bits will be used before any bytes are used + from next_in. This function should only be used with raw inflate, and + should be used before the first inflate() call after inflateInit2() or + inflateReset(). bits must be less than or equal to 16, and that many of the + least significant bits of value will be inserted in the input. + + If bits is negative, then the input stream bit buffer is emptied. Then + inflatePrime() can be called again to put bits in the buffer. This is used + to clear out bits leftover after feeding inflate a block description prior + to feeding inflate codes. + + inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +ZEXTERN long ZEXPORT inflateMark(z_streamp strm); +/* + This function returns two values, one in the lower 16 bits of the return + value, and the other in the remaining upper bits, obtained by shifting the + return value down 16 bits. If the upper value is -1 and the lower value is + zero, then inflate() is currently decoding information outside of a block. + If the upper value is -1 and the lower value is non-zero, then inflate is in + the middle of a stored block, with the lower value equaling the number of + bytes from the input remaining to copy. If the upper value is not -1, then + it is the number of bits back from the current bit position in the input of + the code (literal or length/distance pair) currently being processed. In + that case the lower value is the number of bytes already emitted for that + code. + + A code is being processed if inflate is waiting for more input to complete + decoding of the code, or if it has completed decoding but is waiting for + more output space to write the literal or match data. + + inflateMark() is used to mark locations in the input data for random + access, which may be at bit positions, and to note those cases where the + output of a code may span boundaries of random access blocks. The current + location in the input stream can be determined from avail_in and data_type + as noted in the description for the Z_BLOCK flush parameter for inflate. + + inflateMark returns the value noted above, or -65536 if the provided + source stream state was inconsistent. +*/ + +ZEXTERN int ZEXPORT inflateGetHeader(z_streamp strm, + gz_headerp head); +/* + inflateGetHeader() requests that gzip header information be stored in the + provided gz_header structure. inflateGetHeader() may be called after + inflateInit2() or inflateReset(), and before the first call of inflate(). + As inflate() processes the gzip stream, head->done is zero until the header + is completed, at which time head->done is set to one. If a zlib stream is + being decoded, then head->done is set to -1 to indicate that there will be + no gzip header information forthcoming. Note that Z_BLOCK or Z_TREES can be + used to force inflate() to return immediately after header processing is + complete and before any actual data is decompressed. + + The text, time, xflags, and os fields are filled in with the gzip header + contents. hcrc is set to true if there is a header CRC. (The header CRC + was valid if done is set to one.) If extra is not Z_NULL, then extra_max + contains the maximum number of bytes to write to extra. Once done is true, + extra_len contains the actual extra field length, and extra contains the + extra field, or that field truncated if extra_max is less than extra_len. + If name is not Z_NULL, then up to name_max characters are written there, + terminated with a zero unless the length is greater than name_max. If + comment is not Z_NULL, then up to comm_max characters are written there, + terminated with a zero unless the length is greater than comm_max. When any + of extra, name, or comment are not Z_NULL and the respective field is not + present in the header, then that field is set to Z_NULL to signal its + absence. This allows the use of deflateSetHeader() with the returned + structure to duplicate the header. However if those fields are set to + allocated memory, then the application will need to save those pointers + elsewhere so that they can be eventually freed. + + If inflateGetHeader is not used, then the header information is simply + discarded. The header is always checked for validity, including the header + CRC if present. inflateReset() will reset the process to discard the header + information. The application would need to call inflateGetHeader() again to + retrieve the header from the next gzip stream. + + inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +/* +ZEXTERN int ZEXPORT inflateBackInit(z_streamp strm, int windowBits, + unsigned char FAR *window); + + Initialize the internal stream state for decompression using inflateBack() + calls. The fields zalloc, zfree and opaque in strm must be initialized + before the call. If zalloc and zfree are Z_NULL, then the default library- + derived memory allocation routines are used. windowBits is the base two + logarithm of the window size, in the range 8..15. window is a caller + supplied buffer of that size. Except for special applications where it is + assured that deflate was used with small window sizes, windowBits must be 15 + and a 32K byte window must be supplied to be able to decompress general + deflate streams. + + See inflateBack() for the usage of these routines. + + inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of + the parameters are invalid, Z_MEM_ERROR if the internal state could not be + allocated, or Z_VERSION_ERROR if the version of the library does not match + the version of the header file. +*/ + +typedef unsigned (*in_func)(void FAR *, + z_const unsigned char FAR * FAR *); +typedef int (*out_func)(void FAR *, unsigned char FAR *, unsigned); + +ZEXTERN int ZEXPORT inflateBack(z_streamp strm, + in_func in, void FAR *in_desc, + out_func out, void FAR *out_desc); +/* + inflateBack() does a raw inflate with a single call using a call-back + interface for input and output. This is potentially more efficient than + inflate() for file i/o applications, in that it avoids copying between the + output and the sliding window by simply making the window itself the output + buffer. inflate() can be faster on modern CPUs when used with large + buffers. inflateBack() trusts the application to not change the output + buffer passed by the output function, at least until inflateBack() returns. + + inflateBackInit() must be called first to allocate the internal state + and to initialize the state with the user-provided window buffer. + inflateBack() may then be used multiple times to inflate a complete, raw + deflate stream with each call. inflateBackEnd() is then called to free the + allocated state. + + A raw deflate stream is one with no zlib or gzip header or trailer. + This routine would normally be used in a utility that reads zip or gzip + files and writes out uncompressed files. The utility would decode the + header and process the trailer on its own, hence this routine expects only + the raw deflate stream to decompress. This is different from the default + behavior of inflate(), which expects a zlib header and trailer around the + deflate stream. + + inflateBack() uses two subroutines supplied by the caller that are then + called by inflateBack() for input and output. inflateBack() calls those + routines until it reads a complete deflate stream and writes out all of the + uncompressed data, or until it encounters an error. The function's + parameters and return types are defined above in the in_func and out_func + typedefs. inflateBack() will call in(in_desc, &buf) which should return the + number of bytes of provided input, and a pointer to that input in buf. If + there is no input available, in() must return zero -- buf is ignored in that + case -- and inflateBack() will return a buffer error. inflateBack() will + call out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. + out() should return zero on success, or non-zero on failure. If out() + returns non-zero, inflateBack() will return with an error. Neither in() nor + out() are permitted to change the contents of the window provided to + inflateBackInit(), which is also the buffer that out() uses to write from. + The length written by out() will be at most the window size. Any non-zero + amount of input may be provided by in(). + + For convenience, inflateBack() can be provided input on the first call by + setting strm->next_in and strm->avail_in. If that input is exhausted, then + in() will be called. Therefore strm->next_in must be initialized before + calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called + immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in + must also be initialized, and then if strm->avail_in is not zero, input will + initially be taken from strm->next_in[0 .. strm->avail_in - 1]. + + The in_desc and out_desc parameters of inflateBack() is passed as the + first parameter of in() and out() respectively when they are called. These + descriptors can be optionally used to pass any information that the caller- + supplied in() and out() functions need to do their job. + + On return, inflateBack() will set strm->next_in and strm->avail_in to + pass back any unused input that was provided by the last in() call. The + return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR + if in() or out() returned an error, Z_DATA_ERROR if there was a format error + in the deflate stream (in which case strm->msg is set to indicate the nature + of the error), or Z_STREAM_ERROR if the stream was not properly initialized. + In the case of Z_BUF_ERROR, an input or output error can be distinguished + using strm->next_in which will be Z_NULL only if in() returned an error. If + strm->next_in is not Z_NULL, then the Z_BUF_ERROR was due to out() returning + non-zero. (in() will always be called before out(), so strm->next_in is + assured to be defined if out() returns non-zero.) Note that inflateBack() + cannot return Z_OK. +*/ + +ZEXTERN int ZEXPORT inflateBackEnd(z_streamp strm); +/* + All memory allocated by inflateBackInit() is freed. + + inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream + state was inconsistent. +*/ + +ZEXTERN uLong ZEXPORT zlibCompileFlags(void); +/* Return flags indicating compile-time options. + + Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: + 1.0: size of uInt + 3.2: size of uLong + 5.4: size of voidpf (pointer) + 7.6: size of z_off_t + + Compiler, assembler, and debug options: + 8: ZLIB_DEBUG + 9: ASMV or ASMINF -- use ASM code + 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention + 11: 0 (reserved) + + One-time table building (smaller code, but not thread-safe if true): + 12: BUILDFIXED -- build static block decoding tables when needed + 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed + 14,15: 0 (reserved) + + Library content (indicates missing functionality): + 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking + deflate code when not needed) + 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect + and decode gzip streams (to avoid linking crc code) + 18-19: 0 (reserved) + + Operation variations (changes in library functionality): + 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate + 21: FASTEST -- deflate algorithm with only one, lowest compression level + 22,23: 0 (reserved) + + The sprintf variant used by gzprintf (zero is best): + 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format + 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure! + 26: 0 = returns value, 1 = void -- 1 means inferred string length returned + + Remainder: + 27-31: 0 (reserved) + */ + +#ifndef Z_SOLO + + /* utility functions */ + +/* + The following utility functions are implemented on top of the basic + stream-oriented functions. To simplify the interface, some default options + are assumed (compression level and memory usage, standard memory allocation + functions). The source code of these utility functions can be modified if + you need special options. +*/ + +ZEXTERN int ZEXPORT compress(Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen); +/* + Compresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total size + of the destination buffer, which must be at least the value returned by + compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed data. compress() is equivalent to compress2() with a level + parameter of Z_DEFAULT_COMPRESSION. + + compress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer. +*/ + +ZEXTERN int ZEXPORT compress2(Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen, + int level); +/* + Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least the value returned by + compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed data. + + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, + Z_STREAM_ERROR if the level parameter is invalid. +*/ + +ZEXTERN uLong ZEXPORT compressBound(uLong sourceLen); +/* + compressBound() returns an upper bound on the compressed size after + compress() or compress2() on sourceLen bytes. It would be used before a + compress() or compress2() call to allocate the destination buffer. +*/ + +ZEXTERN int ZEXPORT uncompress(Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen); +/* + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total size + of the destination buffer, which must be large enough to hold the entire + uncompressed data. (The size of the uncompressed data must have been saved + previously by the compressor and transmitted to the decompressor by some + mechanism outside the scope of this compression library.) Upon exit, destLen + is the actual size of the uncompressed data. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. In + the case where there is not enough room, uncompress() will fill the output + buffer with the uncompressed data up to that point. +*/ + +ZEXTERN int ZEXPORT uncompress2(Bytef *dest, uLongf *destLen, + const Bytef *source, uLong *sourceLen); +/* + Same as uncompress, except that sourceLen is a pointer, where the + length of the source is *sourceLen. On return, *sourceLen is the number of + source bytes consumed. +*/ + + /* gzip file access functions */ + +/* + This library supports reading and writing files in gzip (.gz) format with + an interface similar to that of stdio, using the functions that start with + "gz". The gzip format is different from the zlib format. gzip is a gzip + wrapper, documented in RFC 1952, wrapped around a deflate stream. +*/ + +typedef struct gzFile_s *gzFile; /* semi-opaque gzip file descriptor */ + +/* +ZEXTERN gzFile ZEXPORT gzopen(const char *path, const char *mode); + + Open the gzip (.gz) file at path for reading and decompressing, or + compressing and writing. The mode parameter is as in fopen ("rb" or "wb") + but can also include a compression level ("wb9") or a strategy: 'f' for + filtered data as in "wb6f", 'h' for Huffman-only compression as in "wb1h", + 'R' for run-length encoding as in "wb1R", or 'F' for fixed code compression + as in "wb9F". (See the description of deflateInit2 for more information + about the strategy parameter.) 'T' will request transparent writing or + appending with no compression and not using the gzip format. + + "a" can be used instead of "w" to request that the gzip stream that will + be written be appended to the file. "+" will result in an error, since + reading and writing to the same gzip file is not supported. The addition of + "x" when writing will create the file exclusively, which fails if the file + already exists. On systems that support it, the addition of "e" when + reading or writing will set the flag to close the file on an execve() call. + + These functions, as well as gzip, will read and decode a sequence of gzip + streams in a file. The append function of gzopen() can be used to create + such a file. (Also see gzflush() for another way to do this.) When + appending, gzopen does not test whether the file begins with a gzip stream, + nor does it look for the end of the gzip streams to begin appending. gzopen + will simply append a gzip stream to the existing file. + + gzopen can be used to read a file which is not in gzip format; in this + case gzread will directly read from the file without decompression. When + reading, this will be detected automatically by looking for the magic two- + byte gzip header. + + gzopen returns NULL if the file could not be opened, if there was + insufficient memory to allocate the gzFile state, or if an invalid mode was + specified (an 'r', 'w', or 'a' was not provided, or '+' was provided). + errno can be checked to determine if the reason gzopen failed was that the + file could not be opened. +*/ + +ZEXTERN gzFile ZEXPORT gzdopen(int fd, const char *mode); +/* + Associate a gzFile with the file descriptor fd. File descriptors are + obtained from calls like open, dup, creat, pipe or fileno (if the file has + been previously opened with fopen). The mode parameter is as in gzopen. + + The next call of gzclose on the returned gzFile will also close the file + descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor + fd. If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd, + mode);. The duplicated descriptor should be saved to avoid a leak, since + gzdopen does not close fd if it fails. If you are using fileno() to get the + file descriptor from a FILE *, then you will have to use dup() to avoid + double-close()ing the file descriptor. Both gzclose() and fclose() will + close the associated file descriptor, so they need to have different file + descriptors. + + gzdopen returns NULL if there was insufficient memory to allocate the + gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not + provided, or '+' was provided), or if fd is -1. The file descriptor is not + used until the next gz* read, write, seek, or close operation, so gzdopen + will not detect if fd is invalid (unless fd is -1). +*/ + +ZEXTERN int ZEXPORT gzbuffer(gzFile file, unsigned size); +/* + Set the internal buffer size used by this library's functions for file to + size. The default buffer size is 8192 bytes. This function must be called + after gzopen() or gzdopen(), and before any other calls that read or write + the file. The buffer memory allocation is always deferred to the first read + or write. Three times that size in buffer space is allocated. A larger + buffer size of, for example, 64K or 128K bytes will noticeably increase the + speed of decompression (reading). + + The new buffer size also affects the maximum length for gzprintf(). + + gzbuffer() returns 0 on success, or -1 on failure, such as being called + too late. +*/ + +ZEXTERN int ZEXPORT gzsetparams(gzFile file, int level, int strategy); +/* + Dynamically update the compression level and strategy for file. See the + description of deflateInit2 for the meaning of these parameters. Previously + provided data is flushed before applying the parameter changes. + + gzsetparams returns Z_OK if success, Z_STREAM_ERROR if the file was not + opened for writing, Z_ERRNO if there is an error writing the flushed data, + or Z_MEM_ERROR if there is a memory allocation error. +*/ + +ZEXTERN int ZEXPORT gzread(gzFile file, voidp buf, unsigned len); +/* + Read and decompress up to len uncompressed bytes from file into buf. If + the input file is not in gzip format, gzread copies the given number of + bytes into the buffer directly from the file. + + After reaching the end of a gzip stream in the input, gzread will continue + to read, looking for another gzip stream. Any number of gzip streams may be + concatenated in the input file, and will all be decompressed by gzread(). + If something other than a gzip stream is encountered after a gzip stream, + that remaining trailing garbage is ignored (and no error is returned). + + gzread can be used to read a gzip file that is being concurrently written. + Upon reaching the end of the input, gzread will return with the available + data. If the error code returned by gzerror is Z_OK or Z_BUF_ERROR, then + gzclearerr can be used to clear the end of file indicator in order to permit + gzread to be tried again. Z_OK indicates that a gzip stream was completed + on the last gzread. Z_BUF_ERROR indicates that the input file ended in the + middle of a gzip stream. Note that gzread does not return -1 in the event + of an incomplete gzip stream. This error is deferred until gzclose(), which + will return Z_BUF_ERROR if the last gzread ended in the middle of a gzip + stream. Alternatively, gzerror can be used before gzclose to detect this + case. + + gzread returns the number of uncompressed bytes actually read, less than + len for end of file, or -1 for error. If len is too large to fit in an int, + then nothing is read, -1 is returned, and the error state is set to + Z_STREAM_ERROR. +*/ + +ZEXTERN z_size_t ZEXPORT gzfread(voidp buf, z_size_t size, z_size_t nitems, + gzFile file); +/* + Read and decompress up to nitems items of size size from file into buf, + otherwise operating as gzread() does. This duplicates the interface of + stdio's fread(), with size_t request and return types. If the library + defines size_t, then z_size_t is identical to size_t. If not, then z_size_t + is an unsigned integer type that can contain a pointer. + + gzfread() returns the number of full items read of size size, or zero if + the end of the file was reached and a full item could not be read, or if + there was an error. gzerror() must be consulted if zero is returned in + order to determine if there was an error. If the multiplication of size and + nitems overflows, i.e. the product does not fit in a z_size_t, then nothing + is read, zero is returned, and the error state is set to Z_STREAM_ERROR. + + In the event that the end of file is reached and only a partial item is + available at the end, i.e. the remaining uncompressed data length is not a + multiple of size, then the final partial item is nevertheless read into buf + and the end-of-file flag is set. The length of the partial item read is not + provided, but could be inferred from the result of gztell(). This behavior + is the same as the behavior of fread() implementations in common libraries, + but it prevents the direct use of gzfread() to read a concurrently written + file, resetting and retrying on end-of-file, when size is not 1. +*/ + +ZEXTERN int ZEXPORT gzwrite(gzFile file, voidpc buf, unsigned len); +/* + Compress and write the len uncompressed bytes at buf to file. gzwrite + returns the number of uncompressed bytes written or 0 in case of error. +*/ + +ZEXTERN z_size_t ZEXPORT gzfwrite(voidpc buf, z_size_t size, + z_size_t nitems, gzFile file); +/* + Compress and write nitems items of size size from buf to file, duplicating + the interface of stdio's fwrite(), with size_t request and return types. If + the library defines size_t, then z_size_t is identical to size_t. If not, + then z_size_t is an unsigned integer type that can contain a pointer. + + gzfwrite() returns the number of full items written of size size, or zero + if there was an error. If the multiplication of size and nitems overflows, + i.e. the product does not fit in a z_size_t, then nothing is written, zero + is returned, and the error state is set to Z_STREAM_ERROR. +*/ + +ZEXTERN int ZEXPORTVA gzprintf(gzFile file, const char *format, ...); +/* + Convert, format, compress, and write the arguments (...) to file under + control of the string format, as in fprintf. gzprintf returns the number of + uncompressed bytes actually written, or a negative zlib error code in case + of error. The number of uncompressed bytes written is limited to 8191, or + one less than the buffer size given to gzbuffer(). The caller should assure + that this limit is not exceeded. If it is exceeded, then gzprintf() will + return an error (0) with nothing written. In this case, there may also be a + buffer overflow with unpredictable consequences, which is possible only if + zlib was compiled with the insecure functions sprintf() or vsprintf(), + because the secure snprintf() or vsnprintf() functions were not available. + This can be determined using zlibCompileFlags(). +*/ + +ZEXTERN int ZEXPORT gzputs(gzFile file, const char *s); +/* + Compress and write the given null-terminated string s to file, excluding + the terminating null character. + + gzputs returns the number of characters written, or -1 in case of error. +*/ + +ZEXTERN char * ZEXPORT gzgets(gzFile file, char *buf, int len); +/* + Read and decompress bytes from file into buf, until len-1 characters are + read, or until a newline character is read and transferred to buf, or an + end-of-file condition is encountered. If any characters are read or if len + is one, the string is terminated with a null character. If no characters + are read due to an end-of-file or len is less than one, then the buffer is + left untouched. + + gzgets returns buf which is a null-terminated string, or it returns NULL + for end-of-file or in case of error. If there was an error, the contents at + buf are indeterminate. +*/ + +ZEXTERN int ZEXPORT gzputc(gzFile file, int c); +/* + Compress and write c, converted to an unsigned char, into file. gzputc + returns the value that was written, or -1 in case of error. +*/ + +ZEXTERN int ZEXPORT gzgetc(gzFile file); +/* + Read and decompress one byte from file. gzgetc returns this byte or -1 + in case of end of file or error. This is implemented as a macro for speed. + As such, it does not do all of the checking the other functions do. I.e. + it does not check to see if file is NULL, nor whether the structure file + points to has been clobbered or not. +*/ + +ZEXTERN int ZEXPORT gzungetc(int c, gzFile file); +/* + Push c back onto the stream for file to be read as the first character on + the next read. At least one character of push-back is always allowed. + gzungetc() returns the character pushed, or -1 on failure. gzungetc() will + fail if c is -1, and may fail if a character has been pushed but not read + yet. If gzungetc is used immediately after gzopen or gzdopen, at least the + output buffer size of pushed characters is allowed. (See gzbuffer above.) + The pushed character will be discarded if the stream is repositioned with + gzseek() or gzrewind(). +*/ + +ZEXTERN int ZEXPORT gzflush(gzFile file, int flush); +/* + Flush all pending output to file. The parameter flush is as in the + deflate() function. The return value is the zlib error number (see function + gzerror below). gzflush is only permitted when writing. + + If the flush parameter is Z_FINISH, the remaining data is written and the + gzip stream is completed in the output. If gzwrite() is called again, a new + gzip stream will be started in the output. gzread() is able to read such + concatenated gzip streams. + + gzflush should be called only when strictly necessary because it will + degrade compression if called too often. +*/ + +/* +ZEXTERN z_off_t ZEXPORT gzseek(gzFile file, + z_off_t offset, int whence); + + Set the starting position to offset relative to whence for the next gzread + or gzwrite on file. The offset represents a number of bytes in the + uncompressed data stream. The whence parameter is defined as in lseek(2); + the value SEEK_END is not supported. + + If the file is opened for reading, this function is emulated but can be + extremely slow. If the file is opened for writing, only forward seeks are + supported; gzseek then compresses a sequence of zeroes up to the new + starting position. + + gzseek returns the resulting offset location as measured in bytes from + the beginning of the uncompressed stream, or -1 in case of error, in + particular if the file is opened for writing and the new starting position + would be before the current position. +*/ + +ZEXTERN int ZEXPORT gzrewind(gzFile file); +/* + Rewind file. This function is supported only for reading. + + gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET). +*/ + +/* +ZEXTERN z_off_t ZEXPORT gztell(gzFile file); + + Return the starting position for the next gzread or gzwrite on file. + This position represents a number of bytes in the uncompressed data stream, + and is zero when starting, even if appending or reading a gzip stream from + the middle of a file using gzdopen(). + + gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) +*/ + +/* +ZEXTERN z_off_t ZEXPORT gzoffset(gzFile file); + + Return the current compressed (actual) read or write offset of file. This + offset includes the count of bytes that precede the gzip stream, for example + when appending or when using gzdopen() for reading. When reading, the + offset does not include as yet unused buffered input. This information can + be used for a progress indicator. On error, gzoffset() returns -1. +*/ + +ZEXTERN int ZEXPORT gzeof(gzFile file); +/* + Return true (1) if the end-of-file indicator for file has been set while + reading, false (0) otherwise. Note that the end-of-file indicator is set + only if the read tried to go past the end of the input, but came up short. + Therefore, just like feof(), gzeof() may return false even if there is no + more data to read, in the event that the last read request was for the exact + number of bytes remaining in the input file. This will happen if the input + file size is an exact multiple of the buffer size. + + If gzeof() returns true, then the read functions will return no more data, + unless the end-of-file indicator is reset by gzclearerr() and the input file + has grown since the previous end of file was detected. +*/ + +ZEXTERN int ZEXPORT gzdirect(gzFile file); +/* + Return true (1) if file is being copied directly while reading, or false + (0) if file is a gzip stream being decompressed. + + If the input file is empty, gzdirect() will return true, since the input + does not contain a gzip stream. + + If gzdirect() is used immediately after gzopen() or gzdopen() it will + cause buffers to be allocated to allow reading the file to determine if it + is a gzip file. Therefore if gzbuffer() is used, it should be called before + gzdirect(). + + When writing, gzdirect() returns true (1) if transparent writing was + requested ("wT" for the gzopen() mode), or false (0) otherwise. (Note: + gzdirect() is not needed when writing. Transparent writing must be + explicitly requested, so the application already knows the answer. When + linking statically, using gzdirect() will include all of the zlib code for + gzip file reading and decompression, which may not be desired.) +*/ + +ZEXTERN int ZEXPORT gzclose(gzFile file); +/* + Flush all pending output for file, if necessary, close file and + deallocate the (de)compression state. Note that once file is closed, you + cannot call gzerror with file, since its structures have been deallocated. + gzclose must not be called more than once on the same file, just as free + must not be called more than once on the same allocation. + + gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a + file operation error, Z_MEM_ERROR if out of memory, Z_BUF_ERROR if the + last read ended in the middle of a gzip stream, or Z_OK on success. +*/ + +ZEXTERN int ZEXPORT gzclose_r(gzFile file); +ZEXTERN int ZEXPORT gzclose_w(gzFile file); +/* + Same as gzclose(), but gzclose_r() is only for use when reading, and + gzclose_w() is only for use when writing or appending. The advantage to + using these instead of gzclose() is that they avoid linking in zlib + compression or decompression code that is not used when only reading or only + writing respectively. If gzclose() is used, then both compression and + decompression code will be included the application when linking to a static + zlib library. +*/ + +ZEXTERN const char * ZEXPORT gzerror(gzFile file, int *errnum); +/* + Return the error message for the last error which occurred on file. + errnum is set to zlib error number. If an error occurred in the file system + and not in the compression library, errnum is set to Z_ERRNO and the + application may consult errno to get the exact error code. + + The application must not modify the returned string. Future calls to + this function may invalidate the previously returned string. If file is + closed, then the string previously returned by gzerror will no longer be + available. + + gzerror() should be used to distinguish errors from end-of-file for those + functions above that do not distinguish those cases in their return values. +*/ + +ZEXTERN void ZEXPORT gzclearerr(gzFile file); +/* + Clear the error and end-of-file flags for file. This is analogous to the + clearerr() function in stdio. This is useful for continuing to read a gzip + file that is being written concurrently. +*/ + +#endif /* !Z_SOLO */ + + /* checksum functions */ + +/* + These functions are not related to compression but are exported + anyway because they might be useful in applications using the compression + library. +*/ + +ZEXTERN uLong ZEXPORT adler32(uLong adler, const Bytef *buf, uInt len); +/* + Update a running Adler-32 checksum with the bytes buf[0..len-1] and + return the updated checksum. An Adler-32 value is in the range of a 32-bit + unsigned integer. If buf is Z_NULL, this function returns the required + initial value for the checksum. + + An Adler-32 checksum is almost as reliable as a CRC-32 but can be computed + much faster. + + Usage example: + + uLong adler = adler32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + adler = adler32(adler, buffer, length); + } + if (adler != original_adler) error(); +*/ + +ZEXTERN uLong ZEXPORT adler32_z(uLong adler, const Bytef *buf, + z_size_t len); +/* + Same as adler32(), but with a size_t length. +*/ + +/* +ZEXTERN uLong ZEXPORT adler32_combine(uLong adler1, uLong adler2, + z_off_t len2); + + Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 + and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for + each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of + seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. Note + that the z_off_t type (like off_t) is a signed integer. If len2 is + negative, the result has no meaning or utility. +*/ + +ZEXTERN uLong ZEXPORT crc32(uLong crc, const Bytef *buf, uInt len); +/* + Update a running CRC-32 with the bytes buf[0..len-1] and return the + updated CRC-32. A CRC-32 value is in the range of a 32-bit unsigned integer. + If buf is Z_NULL, this function returns the required initial value for the + crc. Pre- and post-conditioning (one's complement) is performed within this + function so it shouldn't be done by the application. + + Usage example: + + uLong crc = crc32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + crc = crc32(crc, buffer, length); + } + if (crc != original_crc) error(); +*/ + +ZEXTERN uLong ZEXPORT crc32_z(uLong crc, const Bytef *buf, + z_size_t len); +/* + Same as crc32(), but with a size_t length. +*/ + +/* +ZEXTERN uLong ZEXPORT crc32_combine(uLong crc1, uLong crc2, z_off_t len2); + + Combine two CRC-32 check values into one. For two sequences of bytes, + seq1 and seq2 with lengths len1 and len2, CRC-32 check values were + calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 + check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and + len2. len2 must be non-negative. +*/ + +/* +ZEXTERN uLong ZEXPORT crc32_combine_gen(z_off_t len2); + + Return the operator corresponding to length len2, to be used with + crc32_combine_op(). len2 must be non-negative. +*/ + +ZEXTERN uLong ZEXPORT crc32_combine_op(uLong crc1, uLong crc2, uLong op); +/* + Give the same result as crc32_combine(), using op in place of len2. op is + is generated from len2 by crc32_combine_gen(). This will be faster than + crc32_combine() if the generated op is used more than once. +*/ + + + /* various hacks, don't look :) */ + +/* deflateInit and inflateInit are macros to allow checking the zlib version + * and the compiler's view of z_stream: + */ +ZEXTERN int ZEXPORT deflateInit_(z_streamp strm, int level, + const char *version, int stream_size); +ZEXTERN int ZEXPORT inflateInit_(z_streamp strm, + const char *version, int stream_size); +ZEXTERN int ZEXPORT deflateInit2_(z_streamp strm, int level, int method, + int windowBits, int memLevel, + int strategy, const char *version, + int stream_size); +ZEXTERN int ZEXPORT inflateInit2_(z_streamp strm, int windowBits, + const char *version, int stream_size); +ZEXTERN int ZEXPORT inflateBackInit_(z_streamp strm, int windowBits, + unsigned char FAR *window, + const char *version, + int stream_size); +#ifdef Z_PREFIX_SET +# define z_deflateInit(strm, level) \ + deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream)) +# define z_inflateInit(strm) \ + inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream)) +# define z_deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ + deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ + (strategy), ZLIB_VERSION, (int)sizeof(z_stream)) +# define z_inflateInit2(strm, windowBits) \ + inflateInit2_((strm), (windowBits), ZLIB_VERSION, \ + (int)sizeof(z_stream)) +# define z_inflateBackInit(strm, windowBits, window) \ + inflateBackInit_((strm), (windowBits), (window), \ + ZLIB_VERSION, (int)sizeof(z_stream)) +#else +# define deflateInit(strm, level) \ + deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream)) +# define inflateInit(strm) \ + inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream)) +# define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ + deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ + (strategy), ZLIB_VERSION, (int)sizeof(z_stream)) +# define inflateInit2(strm, windowBits) \ + inflateInit2_((strm), (windowBits), ZLIB_VERSION, \ + (int)sizeof(z_stream)) +# define inflateBackInit(strm, windowBits, window) \ + inflateBackInit_((strm), (windowBits), (window), \ + ZLIB_VERSION, (int)sizeof(z_stream)) +#endif + +#ifndef Z_SOLO + +/* gzgetc() macro and its supporting function and exposed data structure. Note + * that the real internal state is much larger than the exposed structure. + * This abbreviated structure exposes just enough for the gzgetc() macro. The + * user should not mess with these exposed elements, since their names or + * behavior could change in the future, perhaps even capriciously. They can + * only be used by the gzgetc() macro. You have been warned. + */ +struct gzFile_s { + unsigned have; + unsigned char *next; + z_off64_t pos; +}; +ZEXTERN int ZEXPORT gzgetc_(gzFile file); /* backward compatibility */ +#ifdef Z_PREFIX_SET +# undef z_gzgetc +# define z_gzgetc(g) \ + ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : (gzgetc)(g)) +#else +# define gzgetc(g) \ + ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : (gzgetc)(g)) +#endif + +/* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or + * change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if + * both are true, the application gets the *64 functions, and the regular + * functions are changed to 64 bits) -- in case these are set on systems + * without large file support, _LFS64_LARGEFILE must also be true + */ +#ifdef Z_LARGE64 + ZEXTERN gzFile ZEXPORT gzopen64(const char *, const char *); + ZEXTERN z_off64_t ZEXPORT gzseek64(gzFile, z_off64_t, int); + ZEXTERN z_off64_t ZEXPORT gztell64(gzFile); + ZEXTERN z_off64_t ZEXPORT gzoffset64(gzFile); + ZEXTERN uLong ZEXPORT adler32_combine64(uLong, uLong, z_off64_t); + ZEXTERN uLong ZEXPORT crc32_combine64(uLong, uLong, z_off64_t); + ZEXTERN uLong ZEXPORT crc32_combine_gen64(z_off64_t); +#endif + +#if !defined(ZLIB_INTERNAL) && defined(Z_WANT64) +# ifdef Z_PREFIX_SET +# define z_gzopen z_gzopen64 +# define z_gzseek z_gzseek64 +# define z_gztell z_gztell64 +# define z_gzoffset z_gzoffset64 +# define z_adler32_combine z_adler32_combine64 +# define z_crc32_combine z_crc32_combine64 +# define z_crc32_combine_gen z_crc32_combine_gen64 +# else +# define gzopen gzopen64 +# define gzseek gzseek64 +# define gztell gztell64 +# define gzoffset gzoffset64 +# define adler32_combine adler32_combine64 +# define crc32_combine crc32_combine64 +# define crc32_combine_gen crc32_combine_gen64 +# endif +# ifndef Z_LARGE64 + ZEXTERN gzFile ZEXPORT gzopen64(const char *, const char *); + ZEXTERN z_off_t ZEXPORT gzseek64(gzFile, z_off_t, int); + ZEXTERN z_off_t ZEXPORT gztell64(gzFile); + ZEXTERN z_off_t ZEXPORT gzoffset64(gzFile); + ZEXTERN uLong ZEXPORT adler32_combine64(uLong, uLong, z_off_t); + ZEXTERN uLong ZEXPORT crc32_combine64(uLong, uLong, z_off_t); + ZEXTERN uLong ZEXPORT crc32_combine_gen64(z_off_t); +# endif +#else + ZEXTERN gzFile ZEXPORT gzopen(const char *, const char *); + ZEXTERN z_off_t ZEXPORT gzseek(gzFile, z_off_t, int); + ZEXTERN z_off_t ZEXPORT gztell(gzFile); + ZEXTERN z_off_t ZEXPORT gzoffset(gzFile); + ZEXTERN uLong ZEXPORT adler32_combine(uLong, uLong, z_off_t); + ZEXTERN uLong ZEXPORT crc32_combine(uLong, uLong, z_off_t); + ZEXTERN uLong ZEXPORT crc32_combine_gen(z_off_t); +#endif + +#else /* Z_SOLO */ + + ZEXTERN uLong ZEXPORT adler32_combine(uLong, uLong, z_off_t); + ZEXTERN uLong ZEXPORT crc32_combine(uLong, uLong, z_off_t); + ZEXTERN uLong ZEXPORT crc32_combine_gen(z_off_t); + +#endif /* !Z_SOLO */ + +/* undocumented functions */ +ZEXTERN const char * ZEXPORT zError(int); +ZEXTERN int ZEXPORT inflateSyncPoint(z_streamp); +ZEXTERN const z_crc_t FAR * ZEXPORT get_crc_table(void); +ZEXTERN int ZEXPORT inflateUndermine(z_streamp, int); +ZEXTERN int ZEXPORT inflateValidate(z_streamp, int); +ZEXTERN unsigned long ZEXPORT inflateCodesUsed(z_streamp); +ZEXTERN int ZEXPORT inflateResetKeep(z_streamp); +ZEXTERN int ZEXPORT deflateResetKeep(z_streamp); +#if defined(_WIN32) && !defined(Z_SOLO) +ZEXTERN gzFile ZEXPORT gzopen_w(const wchar_t *path, + const char *mode); +#endif +#if defined(STDC) || defined(Z_HAVE_STDARG_H) +# ifndef Z_SOLO +ZEXTERN int ZEXPORTVA gzvprintf(gzFile file, + const char *format, + va_list va); +# endif +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* ZLIB_H */ diff --git a/common/zlib/zutil.c b/common/zlib/zutil.c new file mode 100644 index 0000000..b1c5d2d --- /dev/null +++ b/common/zlib/zutil.c @@ -0,0 +1,299 @@ +/* zutil.c -- target dependent utility functions for the compression library + * Copyright (C) 1995-2017 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#include "zutil.h" +#ifndef Z_SOLO +# include "gzguts.h" +#endif + +z_const char * const z_errmsg[10] = { + (z_const char *)"need dictionary", /* Z_NEED_DICT 2 */ + (z_const char *)"stream end", /* Z_STREAM_END 1 */ + (z_const char *)"", /* Z_OK 0 */ + (z_const char *)"file error", /* Z_ERRNO (-1) */ + (z_const char *)"stream error", /* Z_STREAM_ERROR (-2) */ + (z_const char *)"data error", /* Z_DATA_ERROR (-3) */ + (z_const char *)"insufficient memory", /* Z_MEM_ERROR (-4) */ + (z_const char *)"buffer error", /* Z_BUF_ERROR (-5) */ + (z_const char *)"incompatible version",/* Z_VERSION_ERROR (-6) */ + (z_const char *)"" +}; + + +const char * ZEXPORT zlibVersion(void) { + return ZLIB_VERSION; +} + +uLong ZEXPORT zlibCompileFlags(void) { + uLong flags; + + flags = 0; + switch ((int)(sizeof(uInt))) { + case 2: break; + case 4: flags += 1; break; + case 8: flags += 2; break; + default: flags += 3; + } + switch ((int)(sizeof(uLong))) { + case 2: break; + case 4: flags += 1 << 2; break; + case 8: flags += 2 << 2; break; + default: flags += 3 << 2; + } + switch ((int)(sizeof(voidpf))) { + case 2: break; + case 4: flags += 1 << 4; break; + case 8: flags += 2 << 4; break; + default: flags += 3 << 4; + } + switch ((int)(sizeof(z_off_t))) { + case 2: break; + case 4: flags += 1 << 6; break; + case 8: flags += 2 << 6; break; + default: flags += 3 << 6; + } +#ifdef ZLIB_DEBUG + flags += 1 << 8; +#endif + /* +#if defined(ASMV) || defined(ASMINF) + flags += 1 << 9; +#endif + */ +#ifdef ZLIB_WINAPI + flags += 1 << 10; +#endif +#ifdef BUILDFIXED + flags += 1 << 12; +#endif +#ifdef DYNAMIC_CRC_TABLE + flags += 1 << 13; +#endif +#ifdef NO_GZCOMPRESS + flags += 1L << 16; +#endif +#ifdef NO_GZIP + flags += 1L << 17; +#endif +#ifdef PKZIP_BUG_WORKAROUND + flags += 1L << 20; +#endif +#ifdef FASTEST + flags += 1L << 21; +#endif +#if defined(STDC) || defined(Z_HAVE_STDARG_H) +# ifdef NO_vsnprintf + flags += 1L << 25; +# ifdef HAS_vsprintf_void + flags += 1L << 26; +# endif +# else +# ifdef HAS_vsnprintf_void + flags += 1L << 26; +# endif +# endif +#else + flags += 1L << 24; +# ifdef NO_snprintf + flags += 1L << 25; +# ifdef HAS_sprintf_void + flags += 1L << 26; +# endif +# else +# ifdef HAS_snprintf_void + flags += 1L << 26; +# endif +# endif +#endif + return flags; +} + +#ifdef ZLIB_DEBUG +#include +# ifndef verbose +# define verbose 0 +# endif +int ZLIB_INTERNAL z_verbose = verbose; + +void ZLIB_INTERNAL z_error(char *m) { + fprintf(stderr, "%s\n", m); + exit(1); +} +#endif + +/* exported to allow conversion of error code to string for compress() and + * uncompress() + */ +const char * ZEXPORT zError(int err) { + return ERR_MSG(err); +} + +#if defined(_WIN32_WCE) && _WIN32_WCE < 0x800 + /* The older Microsoft C Run-Time Library for Windows CE doesn't have + * errno. We define it as a global variable to simplify porting. + * Its value is always 0 and should not be used. + */ + int errno = 0; +#endif + +#ifndef HAVE_MEMCPY + +void ZLIB_INTERNAL zmemcpy(Bytef* dest, const Bytef* source, uInt len) { + if (len == 0) return; + do { + *dest++ = *source++; /* ??? to be unrolled */ + } while (--len != 0); +} + +int ZLIB_INTERNAL zmemcmp(const Bytef* s1, const Bytef* s2, uInt len) { + uInt j; + + for (j = 0; j < len; j++) { + if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1; + } + return 0; +} + +void ZLIB_INTERNAL zmemzero(Bytef* dest, uInt len) { + if (len == 0) return; + do { + *dest++ = 0; /* ??? to be unrolled */ + } while (--len != 0); +} +#endif + +#ifndef Z_SOLO + +#ifdef SYS16BIT + +#ifdef __TURBOC__ +/* Turbo C in 16-bit mode */ + +# define MY_ZCALLOC + +/* Turbo C malloc() does not allow dynamic allocation of 64K bytes + * and farmalloc(64K) returns a pointer with an offset of 8, so we + * must fix the pointer. Warning: the pointer must be put back to its + * original form in order to free it, use zcfree(). + */ + +#define MAX_PTR 10 +/* 10*64K = 640K */ + +local int next_ptr = 0; + +typedef struct ptr_table_s { + voidpf org_ptr; + voidpf new_ptr; +} ptr_table; + +local ptr_table table[MAX_PTR]; +/* This table is used to remember the original form of pointers + * to large buffers (64K). Such pointers are normalized with a zero offset. + * Since MSDOS is not a preemptive multitasking OS, this table is not + * protected from concurrent access. This hack doesn't work anyway on + * a protected system like OS/2. Use Microsoft C instead. + */ + +voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, unsigned items, unsigned size) { + voidpf buf; + ulg bsize = (ulg)items*size; + + (void)opaque; + + /* If we allocate less than 65520 bytes, we assume that farmalloc + * will return a usable pointer which doesn't have to be normalized. + */ + if (bsize < 65520L) { + buf = farmalloc(bsize); + if (*(ush*)&buf != 0) return buf; + } else { + buf = farmalloc(bsize + 16L); + } + if (buf == NULL || next_ptr >= MAX_PTR) return NULL; + table[next_ptr].org_ptr = buf; + + /* Normalize the pointer to seg:0 */ + *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4; + *(ush*)&buf = 0; + table[next_ptr++].new_ptr = buf; + return buf; +} + +void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) { + int n; + + (void)opaque; + + if (*(ush*)&ptr != 0) { /* object < 64K */ + farfree(ptr); + return; + } + /* Find the original pointer */ + for (n = 0; n < next_ptr; n++) { + if (ptr != table[n].new_ptr) continue; + + farfree(table[n].org_ptr); + while (++n < next_ptr) { + table[n-1] = table[n]; + } + next_ptr--; + return; + } + Assert(0, "zcfree: ptr not found"); +} + +#endif /* __TURBOC__ */ + + +#ifdef M_I86 +/* Microsoft C in 16-bit mode */ + +# define MY_ZCALLOC + +#if (!defined(_MSC_VER) || (_MSC_VER <= 600)) +# define _halloc halloc +# define _hfree hfree +#endif + +voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, uInt items, uInt size) { + (void)opaque; + return _halloc((long)items, size); +} + +void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) { + (void)opaque; + _hfree(ptr); +} + +#endif /* M_I86 */ + +#endif /* SYS16BIT */ + + +#ifndef MY_ZCALLOC /* Any system without a special alloc function */ + +#ifndef STDC +extern voidp malloc(uInt size); +extern voidp calloc(uInt items, uInt size); +extern void free(voidpf ptr); +#endif + +voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, unsigned items, unsigned size) { + (void)opaque; + return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) : + (voidpf)calloc(items, size); +} + +void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) { + (void)opaque; + free(ptr); +} + +#endif /* MY_ZCALLOC */ + +#endif /* !Z_SOLO */ diff --git a/common/zlib/zutil.h b/common/zlib/zutil.h new file mode 100644 index 0000000..48dd7fe --- /dev/null +++ b/common/zlib/zutil.h @@ -0,0 +1,254 @@ +/* zutil.h -- internal interface and configuration of the compression library + * Copyright (C) 1995-2024 Jean-loup Gailly, Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* @(#) $Id$ */ + +#ifndef ZUTIL_H +#define ZUTIL_H + +#ifdef HAVE_HIDDEN +# define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) +#else +# define ZLIB_INTERNAL +#endif + +#include "zlib.h" + +#if defined(STDC) && !defined(Z_SOLO) +# if !(defined(_WIN32_WCE) && defined(_MSC_VER)) +# include +# endif +# include +# include +#endif + +#ifndef local +# define local static +#endif +/* since "static" is used to mean two completely different things in C, we + define "local" for the non-static meaning of "static", for readability + (compile with -Dlocal if your debugger can't find static symbols) */ + +typedef unsigned char uch; +typedef uch FAR uchf; +typedef unsigned short ush; +typedef ush FAR ushf; +typedef unsigned long ulg; + +#if !defined(Z_U8) && !defined(Z_SOLO) && defined(STDC) +# include +# if (ULONG_MAX == 0xffffffffffffffff) +# define Z_U8 unsigned long +# elif (ULLONG_MAX == 0xffffffffffffffff) +# define Z_U8 unsigned long long +# elif (UINT_MAX == 0xffffffffffffffff) +# define Z_U8 unsigned +# endif +#endif + +extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ +/* (size given to avoid silly warnings with Visual C++) */ + +#define ERR_MSG(err) z_errmsg[(err) < -6 || (err) > 2 ? 9 : 2 - (err)] + +#define ERR_RETURN(strm,err) \ + return (strm->msg = ERR_MSG(err), (err)) +/* To be used only when the state is known to be valid */ + + /* common constants */ + +#ifndef DEF_WBITS +# define DEF_WBITS MAX_WBITS +#endif +/* default windowBits for decompression. MAX_WBITS is for compression only */ + +#if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +#else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#endif +/* default memLevel */ + +#define STORED_BLOCK 0 +#define STATIC_TREES 1 +#define DYN_TREES 2 +/* The three kinds of block type */ + +#define MIN_MATCH 3 +#define MAX_MATCH 258 +/* The minimum and maximum match lengths */ + +#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ + + /* target dependencies */ + +#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32)) +# define OS_CODE 0x00 +# ifndef Z_SOLO +# if defined(__TURBOC__) || defined(__BORLANDC__) +# if (__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) + /* Allow compilation with ANSI keywords only enabled */ + void _Cdecl farfree( void *block ); + void *_Cdecl farmalloc( unsigned long nbytes ); +# else +# include +# endif +# else /* MSC or DJGPP */ +# include +# endif +# endif +#endif + +#ifdef AMIGA +# define OS_CODE 1 +#endif + +#if defined(VAXC) || defined(VMS) +# define OS_CODE 2 +# define F_OPEN(name, mode) \ + fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") +#endif + +#ifdef __370__ +# if __TARGET_LIB__ < 0x20000000 +# define OS_CODE 4 +# elif __TARGET_LIB__ < 0x40000000 +# define OS_CODE 11 +# else +# define OS_CODE 8 +# endif +#endif + +#if defined(ATARI) || defined(atarist) +# define OS_CODE 5 +#endif + +#ifdef OS2 +# define OS_CODE 6 +# if defined(M_I86) && !defined(Z_SOLO) +# include +# endif +#endif + +#if defined(MACOS) +# define OS_CODE 7 +#endif + +#ifdef __acorn +# define OS_CODE 13 +#endif + +#if defined(WIN32) && !defined(__CYGWIN__) +# define OS_CODE 10 +#endif + +#ifdef _BEOS_ +# define OS_CODE 16 +#endif + +#ifdef __TOS_OS400__ +# define OS_CODE 18 +#endif + +#ifdef __APPLE__ +# define OS_CODE 19 +#endif + +#if defined(__BORLANDC__) && !defined(MSDOS) + #pragma warn -8004 + #pragma warn -8008 + #pragma warn -8066 +#endif + +/* provide prototypes for these when building zlib without LFS */ +#if !defined(_WIN32) && \ + (!defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0) + ZEXTERN uLong ZEXPORT adler32_combine64(uLong, uLong, z_off_t); + ZEXTERN uLong ZEXPORT crc32_combine64(uLong, uLong, z_off_t); + ZEXTERN uLong ZEXPORT crc32_combine_gen64(z_off_t); +#endif + + /* common defaults */ + +#ifndef OS_CODE +# define OS_CODE 3 /* assume Unix */ +#endif + +#ifndef F_OPEN +# define F_OPEN(name, mode) fopen((name), (mode)) +#endif + + /* functions */ + +#if defined(pyr) || defined(Z_SOLO) +# define NO_MEMCPY +#endif +#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__) + /* Use our own functions for small and medium model with MSC <= 5.0. + * You may have to use the same strategy for Borland C (untested). + * The __SC__ check is for Symantec. + */ +# define NO_MEMCPY +#endif +#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY) +# define HAVE_MEMCPY +#endif +#ifdef HAVE_MEMCPY +# ifdef SMALL_MEDIUM /* MSDOS small or medium model */ +# define zmemcpy _fmemcpy +# define zmemcmp _fmemcmp +# define zmemzero(dest, len) _fmemset(dest, 0, len) +# else +# define zmemcpy memcpy +# define zmemcmp memcmp +# define zmemzero(dest, len) memset(dest, 0, len) +# endif +#else + void ZLIB_INTERNAL zmemcpy(Bytef* dest, const Bytef* source, uInt len); + int ZLIB_INTERNAL zmemcmp(const Bytef* s1, const Bytef* s2, uInt len); + void ZLIB_INTERNAL zmemzero(Bytef* dest, uInt len); +#endif + +/* Diagnostic functions */ +#ifdef ZLIB_DEBUG +# include + extern int ZLIB_INTERNAL z_verbose; + extern void ZLIB_INTERNAL z_error(char *m); +# define Assert(cond,msg) {if(!(cond)) z_error(msg);} +# define Trace(x) {if (z_verbose>=0) fprintf x ;} +# define Tracev(x) {if (z_verbose>0) fprintf x ;} +# define Tracevv(x) {if (z_verbose>1) fprintf x ;} +# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;} +# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;} +#else +# define Assert(cond,msg) +# define Trace(x) +# define Tracev(x) +# define Tracevv(x) +# define Tracec(c,x) +# define Tracecv(c,x) +#endif + +#ifndef Z_SOLO + voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, unsigned items, + unsigned size); + void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr); +#endif + +#define ZALLOC(strm, items, size) \ + (*((strm)->zalloc))((strm)->opaque, (items), (size)) +#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) +#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} + +/* Reverse the bytes in a 32-bit value */ +#define ZSWAP32(q) ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \ + (((q) & 0xff00) << 8) + (((q) & 0xff) << 24)) + +#endif /* ZUTIL_H */ diff --git a/fuzzing/CMakeLists.txt b/fuzzing/CMakeLists.txt new file mode 100644 index 0000000..245aa6b --- /dev/null +++ b/fuzzing/CMakeLists.txt @@ -0,0 +1,111 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) + +PROJECT(ffsparser_fuzzer LANGUAGES C CXX) + +OPTION(USE_QT "Link against Qt" OFF) +OPTION(USE_AFL "Build in AFL-compatible mode" OFF) + +SET(CMAKE_CXX_STANDARD 11) +SET(CMAKE_CXX_STANDARD_REQUIRED ON) +SET(CMAKE_CXX_EXTENSIONS OFF) + +SET(PROJECT_SOURCES + ffsparser_fuzzer.cpp + ../common/types.cpp + ../common/descriptor.cpp + ../common/guiddatabase.cpp + ../common/ffs.cpp + ../common/nvram.cpp + ../common/nvramparser.cpp + ../common/meparser.cpp + ../common/ffsparser.cpp + ../common/fitparser.cpp + ../common/peimage.cpp + ../common/treeitem.cpp + ../common/treemodel.cpp + ../common/utility.cpp + ../common/LZMA/LzmaDecompress.c + ../common/LZMA/SDK/C/Bra.c + ../common/LZMA/SDK/C/Bra86.c + ../common/LZMA/SDK/C/CpuArch.c + ../common/LZMA/SDK/C/LzmaDec.c + ../common/Tiano/EfiTianoDecompress.c + ../common/ustring.cpp + ../common/generated/ami_nvar.cpp + ../common/generated/apple_sysf.cpp + ../common/generated/dell_dvar.cpp + ../common/generated/edk2_vss.cpp + ../common/generated/edk2_vss2.cpp + ../common/generated/edk2_ftw.cpp + ../common/generated/insyde_fdc.cpp + ../common/generated/insyde_fdm.cpp + ../common/generated/ms_slic_marker.cpp + ../common/generated/ms_slic_pubkey.cpp + ../common/generated/phoenix_flm.cpp + ../common/generated/phoenix_evsa.cpp + ../common/generated/intel_acbp_v1.cpp + ../common/generated/intel_acbp_v2.cpp + ../common/generated/intel_keym_v1.cpp + ../common/generated/intel_keym_v2.cpp + ../common/generated/intel_acm.cpp + ../common/kaitai/kaitaistream.cpp + ../common/digest/sha1.c + ../common/digest/sha256.c + ../common/digest/sha512.c + ../common/digest/sm3.c + ../common/zlib/adler32.c + ../common/zlib/compress.c + ../common/zlib/crc32.c + ../common/zlib/deflate.c + ../common/zlib/gzclose.c + ../common/zlib/gzlib.c + ../common/zlib/gzread.c + ../common/zlib/gzwrite.c + ../common/zlib/inflate.c + ../common/zlib/infback.c + ../common/zlib/inftrees.c + ../common/zlib/inffast.c + ../common/zlib/trees.c + ../common/zlib/uncompr.c + ../common/zlib/zutil.c +) + +IF(USE_AFL) + SET(PROJECT_SOURCES ${PROJECT_SOURCES} afl_driver.cpp) + MESSAGE("-- Building in AFL-compatible mode") +ELSE() + MESSAGE("-- Building in libFuzzer mode") +ENDIF() + +IF(NOT USE_QT) + SET(PROJECT_SOURCES ${PROJECT_SOURCES} + ../common/bstrlib/bstrlib.c + ../common/bstrlib/bstrwrap.cpp + ) + MESSAGE("-- Using non-Qt implementations") +ELSE() + FIND_PACKAGE(Qt6 REQUIRED COMPONENTS Core) + MESSAGE("-- Using Qt version: ${Qt6_VERSION}") +ENDIF() + +ADD_DEFINITIONS( + -DU_ENABLE_NVRAM_PARSING_SUPPORT + -DU_ENABLE_ME_PARSING_SUPPORT + -DU_ENABLE_FIT_PARSING_SUPPORT + -DU_ENABLE_GUID_DATABASE_SUPPORT +) + +ADD_EXECUTABLE(ffsparser_fuzzer ${PROJECT_SOURCES}) + + +IF(NOT USE_AFL_DRIVER) +TARGET_COMPILE_OPTIONS(ffsparser_fuzzer PRIVATE -O1 -fno-omit-frame-pointer -g -ggdb3 -fsanitize=fuzzer,address,undefined -fsanitize-address-use-after-scope -fno-sanitize-recover=undefined) +TARGET_LINK_LIBRARIES(ffsparser_fuzzer PRIVATE -fsanitize=fuzzer,address,undefined) +ELSE() +TARGET_COMPILE_OPTIONS(ffsparser_fuzzer PRIVATE -O1 -fno-omit-frame-pointer -g -ggdb3 -fsanitize=address,undefined -fsanitize-coverage=trace-pc-guard -fsanitize-address-use-after-scope -fno-sanitize-recover=undefined) +TARGET_LINK_LIBRARIES(ffsparser_fuzzer PRIVATE -fsanitize=address,undefined) +ENDIF() + +IF(USE_QT) + TARGET_LINK_LIBRARIES(ffsparser_fuzzer PRIVATE Qt6::Core) +ENDIF() diff --git a/fuzzing/afl_driver.cpp b/fuzzing/afl_driver.cpp new file mode 100644 index 0000000..f21dfc5 --- /dev/null +++ b/fuzzing/afl_driver.cpp @@ -0,0 +1,276 @@ +//===- afl_driver.cpp - a glue between AFL and libFuzzer --------*- C++ -* ===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +//===----------------------------------------------------------------------===// + +/* This file allows to fuzz libFuzzer-style target functions + (LLVMFuzzerTestOneInput) with AFL using AFL's persistent (in-process) mode. + +Usage: +################################################################################ +cat << EOF > test_fuzzer.cc +#include +#include +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + if (size > 0 && data[0] == 'H') + if (size > 1 && data[1] == 'I') + if (size > 2 && data[2] == '!') + __builtin_trap(); + return 0; +} +EOF +# Build your target with -fsanitize-coverage=trace-pc-guard using fresh clang. +clang -g -fsanitize-coverage=trace-pc-guard test_fuzzer.cc -c +# Build afl-llvm-rt.o.c from the AFL distribution. +clang -c -w $AFL_HOME/llvm_mode/afl-llvm-rt.o.c +# Build this file, link it with afl-llvm-rt.o.o and the target code. +clang++ afl_driver.cpp test_fuzzer.o afl-llvm-rt.o.o +# Run AFL: +rm -rf IN OUT; mkdir IN OUT; echo z > IN/z; +$AFL_HOME/afl-fuzz -i IN -o OUT ./a.out +################################################################################ +AFL_DRIVER_STDERR_DUPLICATE_FILENAME: Setting this *appends* stderr to the file +specified. If the file does not exist, it is created. This is useful for getting +stack traces (when using ASAN for example) or original error messages on hard +to reproduce bugs. Note that any content written to stderr will be written to +this file instead of stderr's usual location. + +AFL_DRIVER_CLOSE_FD_MASK: Similar to libFuzzer's -close_fd_mask behavior option. +If 1, close stdout at startup. If 2 close stderr; if 3 close both. + +*/ +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +// Platform detection. Copied from FuzzerInternal.h +#ifdef __linux__ +#define LIBFUZZER_LINUX 1 +#define LIBFUZZER_APPLE 0 +#define LIBFUZZER_NETBSD 0 +#define LIBFUZZER_FREEBSD 0 +#define LIBFUZZER_OPENBSD 0 +#elif __APPLE__ +#define LIBFUZZER_LINUX 0 +#define LIBFUZZER_APPLE 1 +#define LIBFUZZER_NETBSD 0 +#define LIBFUZZER_FREEBSD 0 +#define LIBFUZZER_OPENBSD 0 +#elif __NetBSD__ +#define LIBFUZZER_LINUX 0 +#define LIBFUZZER_APPLE 0 +#define LIBFUZZER_NETBSD 1 +#define LIBFUZZER_FREEBSD 0 +#define LIBFUZZER_OPENBSD 0 +#elif __FreeBSD__ +#define LIBFUZZER_LINUX 0 +#define LIBFUZZER_APPLE 0 +#define LIBFUZZER_NETBSD 0 +#define LIBFUZZER_FREEBSD 1 +#define LIBFUZZER_OPENBSD 0 +#elif __OpenBSD__ +#define LIBFUZZER_LINUX 0 +#define LIBFUZZER_APPLE 0 +#define LIBFUZZER_NETBSD 0 +#define LIBFUZZER_FREEBSD 0 +#define LIBFUZZER_OPENBSD 1 +#else +#error "Support for your platform has not been implemented" +#endif + +// libFuzzer interface is thin, so we don't include any libFuzzer headers. +extern "C" { +int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size); +__attribute__((weak)) int LLVMFuzzerInitialize(int *argc, char ***argv); +} + +// Notify AFL about persistent mode. +static volatile char AFL_PERSISTENT[] = "##SIG_AFL_PERSISTENT##"; +extern "C" int __afl_persistent_loop(unsigned int); +static volatile char suppress_warning2 = AFL_PERSISTENT[0]; + +// Notify AFL about deferred forkserver. +static volatile char AFL_DEFER_FORKSVR[] = "##SIG_AFL_DEFER_FORKSRV##"; +extern "C" void __afl_manual_init(); +static volatile char suppress_warning1 = AFL_DEFER_FORKSVR[0]; + +// Input buffer. +static const size_t kMaxAflInputSize = 1 << 20; +static uint8_t AflInputBuf[kMaxAflInputSize]; + +// Use this optionally defined function to output sanitizer messages even if +// user asks to close stderr. +__attribute__((weak)) extern "C" void __sanitizer_set_report_fd(void *); + +// Keep track of where stderr content is being written to, so that +// dup_and_close_stderr can use the correct one. +static FILE *output_file = stderr; + +// Experimental feature to use afl_driver without AFL's deferred mode. +// Needs to run before __afl_auto_init. +__attribute__((constructor(0))) static void __decide_deferred_forkserver(void) { + if (getenv("AFL_DRIVER_DONT_DEFER")) { + if (unsetenv("__AFL_DEFER_FORKSRV")) { + perror("Failed to unset __AFL_DEFER_FORKSRV"); + abort(); + } + } +} + +// If the user asks us to duplicate stderr, then do it. +static void maybe_duplicate_stderr() { + char *stderr_duplicate_filename = + getenv("AFL_DRIVER_STDERR_DUPLICATE_FILENAME"); + + if (!stderr_duplicate_filename) + return; + + FILE *stderr_duplicate_stream = + freopen(stderr_duplicate_filename, "a+", stderr); + + if (!stderr_duplicate_stream) { + fprintf( + stderr, + "Failed to duplicate stderr to AFL_DRIVER_STDERR_DUPLICATE_FILENAME"); + abort(); + } + output_file = stderr_duplicate_stream; +} + +// Most of these I/O functions were inspired by/copied from libFuzzer's code. +static void discard_output(int fd) { + FILE *temp = fopen("/dev/null", "w"); + if (!temp) + abort(); + dup2(fileno(temp), fd); + fclose(temp); +} + +static void close_stdout() { discard_output(STDOUT_FILENO); } + +// Prevent the targeted code from writing to "stderr" but allow sanitizers and +// this driver to do so. +static void dup_and_close_stderr() { + int output_fileno = fileno(output_file); + int output_fd = dup(output_fileno); + if (output_fd <= 0) + abort(); + FILE *new_output_file = fdopen(output_fd, "w"); + if (!new_output_file) + abort(); + if (!__sanitizer_set_report_fd) + return; + __sanitizer_set_report_fd(reinterpret_cast(output_fd)); + discard_output(output_fileno); +} + +static void Printf(const char *Fmt, ...) { + va_list ap; + va_start(ap, Fmt); + vfprintf(output_file, Fmt, ap); + va_end(ap); + fflush(output_file); +} + +// Close stdout and/or stderr if user asks for it. +static void maybe_close_fd_mask() { + char *fd_mask_str = getenv("AFL_DRIVER_CLOSE_FD_MASK"); + if (!fd_mask_str) + return; + int fd_mask = atoi(fd_mask_str); + if (fd_mask & 2) + dup_and_close_stderr(); + if (fd_mask & 1) + close_stdout(); +} + +// Define LLVMFuzzerMutate to avoid link failures for targets that use it +// with libFuzzer's LLVMFuzzerCustomMutator. +extern "C" size_t LLVMFuzzerMutate(uint8_t *Data, size_t Size, size_t MaxSize) { + assert(false && "LLVMFuzzerMutate should not be called from afl_driver"); + return 0; +} + +// Execute any files provided as parameters. +static int ExecuteFilesOnyByOne(int argc, char **argv) { + for (int i = 1; i < argc; i++) { + std::ifstream in(argv[i], std::ios::binary); + in.seekg(0, in.end); + size_t length = in.tellg(); + in.seekg (0, in.beg); + std::cout << "Reading " << length << " bytes from " << argv[i] << std::endl; + // Allocate exactly length bytes so that we reliably catch buffer overflows. + std::vector bytes(length); + in.read(bytes.data(), bytes.size()); + assert(in); + LLVMFuzzerTestOneInput(reinterpret_cast(bytes.data()), + bytes.size()); + std::cout << "Execution successful" << std::endl; + } + return 0; +} + +int main(int argc, char **argv) { + Printf( + "======================= INFO =========================\n" + "This binary is built for AFL-fuzz.\n" + "To run the target function on individual input(s) execute this:\n" + " %s < INPUT_FILE\n" + "or\n" + " %s INPUT_FILE1 [INPUT_FILE2 ... ]\n" + "To fuzz with afl-fuzz execute this:\n" + " afl-fuzz [afl-flags] %s [-N]\n" + "afl-fuzz will run N iterations before " + "re-spawning the process (default: 1000)\n" + "======================================================\n", + argv[0], argv[0], argv[0]); + + maybe_duplicate_stderr(); + maybe_close_fd_mask(); + if (LLVMFuzzerInitialize) + LLVMFuzzerInitialize(&argc, &argv); + // Do any other expensive one-time initialization here. + + if (!getenv("AFL_DRIVER_DONT_DEFER")) + __afl_manual_init(); + + int N = 1000; + if (argc == 2 && argv[1][0] == '-') + N = atoi(argv[1] + 1); + else if(argc == 2 && (N = atoi(argv[1])) > 0) + Printf("WARNING: using the deprecated call style `%s %d`\n", argv[0], N); + else if (argc > 1) + return ExecuteFilesOnyByOne(argc, argv); + + assert(N > 0); + + // Call LLVMFuzzerTestOneInput here so that coverage caused by initialization + // on the first execution of LLVMFuzzerTestOneInput is ignored. + uint8_t dummy_input[1] = {0}; + LLVMFuzzerTestOneInput(dummy_input, 1); + + int num_runs = 0; + while (__afl_persistent_loop(N)) { + ssize_t n_read = read(0, AflInputBuf, kMaxAflInputSize); + if (n_read > 0) { + // Copy AflInputBuf into a separate buffer to let asan find buffer + // overflows. Don't use unique_ptr/etc to avoid extra dependencies. + uint8_t *copy = new uint8_t[n_read]; + memcpy(copy, AflInputBuf, n_read); + num_runs++; + LLVMFuzzerTestOneInput(copy, n_read); + delete[] copy; + } + } + Printf("%s: successfully executed %d input(s)\n", argv[0], num_runs); +} diff --git a/fuzzing/ffsparser_fuzzer.cpp b/fuzzing/ffsparser_fuzzer.cpp new file mode 100644 index 0000000..c6b446c --- /dev/null +++ b/fuzzing/ffsparser_fuzzer.cpp @@ -0,0 +1,34 @@ +/* ffsparser_fuzzer.cpp + + Copyright (c) 2023, Nikolaj Schlej. All rights reserved. + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + */ + +#include "../common/ffsparser.h" + +#define FUZZING_MIN_INPUT_SIZE 16 +#define FUZZING_MAX_INPUT_SIZE (128 * 1024 * 1024) + +extern "C" int LLVMFuzzerTestOneInput(const char *Data, long long Size) { + // Do not overblow the inout file size, won't change much in practical sense + if (Size > FUZZING_MAX_INPUT_SIZE || Size < FUZZING_MIN_INPUT_SIZE) return 0; + + // Create the FFS parser + TreeModel* model = new TreeModel(); + FfsParser* ffsParser = new FfsParser(model); + + // Parse the image + (void)ffsParser->parse(UByteArray(Data, (uint32_t)Size)); + + delete model; + delete ffsParser; + + return 0; +} diff --git a/kaitai_regenerate.sh b/kaitai_regenerate.sh new file mode 100755 index 0000000..c97e003 --- /dev/null +++ b/kaitai_regenerate.sh @@ -0,0 +1,66 @@ +#!/bin/bash + +UTARGET=$(uname) + +# Determine platform +if [ "$UTARGET" = "Darwin" ]; then + export UPLATFORM="mac" + export UFIND="find -E" + export UFINDOPT="" +elif [ "$UTARGET" = "Linux" ]; then + export UPLATFORM="linux_$(uname -m)" + export UFIND="find" + export UFINDOPT="-regextype posix-extended" +else + export UPLATFORM="$UTARGET" + echo "Please run this script on Linux or macOS" +fi + +# Generate +echo "Attempting to to generate parsers from Kaitai KSY files on ${UPLATFORM}..." +kaitai-struct-compiler --target cpp_stl --cpp-standard 11 --outdir common/generated common/ksy/* || exit 1 + +# Show generated files +${UFIND} common/generated ${UFINDOPT} \ + -regex '.*\.(cpp|h)' \ + -print || exit 1 + +# Replace global includes for kaitai with local ones (<> -> "") +${UFIND} common/generated ${UFINDOPT} \ + -regex '.*\.(cpp|h)' \ + -exec sed -i.bak '/^#include ]/\"/g' {} + || exit 1 + +# Add .. to the include path for kaitai includes +${UFIND} common/generated ${UFINDOPT} \ + -regex '.*\.(cpp|h)' \ + -exec sed -i.bak '/^#include \"kaitai\//s/kaitai\//..\/kaitai\//g' {} + || exit 1 + +# Suppress "p__root - unused parameter" warning +${UFIND} common/generated ${UFINDOPT} \ + -regex '.*\.(cpp)' \ + -exec sed -i.bak '/^ m__root = this;/s/;/; (void)p__root;/g' {} + || exit 1 + +# Add uint64_t to enum structure_ids_t +${UFIND} common/generated ${UFINDOPT} \ + -regex '.*\.(h)' \ + -exec sed -i.bak '/^ enum structure_ids_t {/s/{/: uint64_t {/g' {} + || exit 1 + +# Suppress type downcast warning in ami_nvar.cpp +${UFIND} common/generated ${UFINDOPT} \ + -name 'ami_nvar.cpp' \ + -exec sed -i.bak 's/_offset = _io()->pos();/_offset = (int32_t)_io()->pos();/g' {} + || exit 1 + +# Suppress type downcast warning in edk2_vss2.cpp +${UFIND} common/generated ${UFINDOPT} \ + -name 'edk2_vss2.cpp' \ + -exec sed -i.bak 's/_offset = _io()->pos();/_offset = (int32_t)_io()->pos();/g' {} + || exit 1 +${UFIND} common/generated ${UFINDOPT} \ + -name 'edk2_vss2.cpp' \ + -exec sed -i.bak 's/_offset_auth = _io()->pos();/_offset_auth = (int32_t)_io()->pos();/g' {} + || exit 1 + +# Remove backup files +${UFIND} common/generated ${UFINDOPT} \ + -regex '.*\.(bak)' \ + -exec rm {} + || exit 1 + +exit 0 diff --git a/meson.build b/meson.build new file mode 100644 index 0000000..36455a6 --- /dev/null +++ b/meson.build @@ -0,0 +1,12 @@ +project('UEFITool', ['c', 'cpp'], + version: 'A71', + license: 'BSD-2-Clause', + meson_version: '>=0.45.0', + default_options : ['c_std=c11', 'cpp_std=c++11'], +) + +zlib = dependency('zlib') + +subdir('common') +subdir('UEFIExtract') +subdir('UEFIFind') diff --git a/qhexedit2/chunks.cpp b/qhexedit2/chunks.cpp deleted file mode 100644 index 7ff3c50..0000000 --- a/qhexedit2/chunks.cpp +++ /dev/null @@ -1,323 +0,0 @@ -#include "chunks.h" -#include - -#define NORMAL 0 -#define HIGHLIGHTED 1 - -#define BUFFER_SIZE 0x10000 -#define CHUNK_SIZE 0x1000 -#define READ_CHUNK_MASK Q_INT64_C(0xfffffffffffff000) - -// ***************************************** Constructors and file settings - -Chunks::Chunks() -{ - QBuffer *buf = new QBuffer(); - setIODevice(*buf); -} - -Chunks::Chunks(QIODevice &ioDevice) -{ - setIODevice(ioDevice); -} - -bool Chunks::setIODevice(QIODevice &ioDevice) -{ - _ioDevice = &ioDevice; - bool ok = _ioDevice->open(QIODevice::ReadOnly); - if (ok) // Try to open IODevice - { - _size = _ioDevice->size(); - _ioDevice->close(); - } - else // Fallback is an empty buffer - { - QBuffer *buf = new QBuffer(); - _ioDevice = buf; - _size = 0; - } - _chunks.clear(); - _pos = 0; - return ok; -} - - -// ***************************************** Getting data out of Chunks - -QByteArray Chunks::data(qint64 pos, qint64 maxSize, QByteArray *highlighted) -{ - qint64 ioDelta = 0; - int chunkIdx = 0; - - Chunk chunk; - QByteArray buffer; - - // Do some checks and some arrangements - if (highlighted) - highlighted->clear(); - - if (pos >= _size) - return buffer; - - if (maxSize < 0) - maxSize = _size; - else - if ((pos + maxSize) > _size) - maxSize = _size - pos; - - _ioDevice->open(QIODevice::ReadOnly); - - while (maxSize > 0) - { - chunk.absPos = LLONG_MAX; - bool chunksLoopOngoing = true; - while ((chunkIdx < _chunks.count()) && chunksLoopOngoing) - { - // In this section, we track changes before our required data and - // we take the editdet data, if availible. ioDelta is a difference - // counter to justify the read pointer to the original data, if - // data in between was deleted or inserted. - - chunk = _chunks[chunkIdx]; - if (chunk.absPos > pos) - chunksLoopOngoing = false; - else - { - chunkIdx += 1; - qint64 count; - qint64 chunkOfs = pos - chunk.absPos; - if (maxSize > ((qint64)chunk.data.size() - chunkOfs)) - { - count = (qint64)chunk.data.size() - chunkOfs; - ioDelta += CHUNK_SIZE - chunk.data.size(); - } - else - count = maxSize; - if (count > 0) - { - buffer += chunk.data.mid(chunkOfs, (int)count); - maxSize -= count; - pos += count; - if (highlighted) - *highlighted += chunk.dataChanged.mid(chunkOfs, (int)count); - } - } - } - - if ((maxSize > 0) && (pos < chunk.absPos)) - { - // In this section, we read data from the original source. This only will - // happen, whe no copied data is available - - qint64 byteCount; - QByteArray readBuffer; - if ((chunk.absPos - pos) > maxSize) - byteCount = maxSize; - else - byteCount = chunk.absPos - pos; - - maxSize -= byteCount; - _ioDevice->seek(pos + ioDelta); - readBuffer = _ioDevice->read(byteCount); - buffer += readBuffer; - if (highlighted) - *highlighted += QByteArray(readBuffer.size(), NORMAL); - pos += readBuffer.size(); - } - } - _ioDevice->close(); - return buffer; -} - -bool Chunks::write(QIODevice &iODevice, qint64 pos, qint64 count) -{ - if (count == -1) - count = _size; - bool ok = iODevice.open(QIODevice::WriteOnly); - if (ok) - { - for (qint64 idx=pos; idx < count; idx += BUFFER_SIZE) - { - QByteArray ba = data(idx, BUFFER_SIZE); - iODevice.write(ba); - } - iODevice.close(); - } - return ok; -} - - -// ***************************************** Set and get highlighting infos - -void Chunks::setDataChanged(qint64 pos, bool dataChanged) -{ - if ((pos < 0) || (pos >= _size)) - return; - int chunkIdx = getChunkIndex(pos); - qint64 posInBa = pos - _chunks[chunkIdx].absPos; - _chunks[chunkIdx].dataChanged[(int)posInBa] = char(dataChanged); -} - -bool Chunks::dataChanged(qint64 pos) -{ - QByteArray highlighted; - data(pos, 1, &highlighted); - return bool(highlighted.at(0)); -} - - -// ***************************************** Search API - -qint64 Chunks::indexOf(const QByteArray &ba, qint64 from) -{ - qint64 result = -1; - QByteArray buffer; - - for (qint64 pos=from; (pos < _size) && (result < 0); pos += BUFFER_SIZE) - { - buffer = data(pos, BUFFER_SIZE + ba.size() - 1); - int findPos = buffer.indexOf(ba); - if (findPos >= 0) - result = pos + (qint64)findPos; - } - return result; -} - -qint64 Chunks::lastIndexOf(const QByteArray &ba, qint64 from) -{ - qint64 result = -1; - QByteArray buffer; - - for (qint64 pos=from; (pos > 0) && (result < 0); pos -= BUFFER_SIZE) - { - qint64 sPos = pos - BUFFER_SIZE - (qint64)ba.size() + 1; - if (sPos < 0) - sPos = 0; - buffer = data(sPos, pos - sPos); - int findPos = buffer.lastIndexOf(ba); - if (findPos >= 0) - result = sPos + (qint64)findPos; - } - return result; -} - - -// ***************************************** Char manipulations - -bool Chunks::insert(qint64 pos, char b) -{ - if ((pos < 0) || (pos > _size)) - return false; - int chunkIdx; - if (pos == _size) - chunkIdx = getChunkIndex(pos-1); - else - chunkIdx = getChunkIndex(pos); - qint64 posInBa = pos - _chunks[chunkIdx].absPos; - _chunks[chunkIdx].data.insert(posInBa, b); - _chunks[chunkIdx].dataChanged.insert(posInBa, char(1)); - for (int idx=chunkIdx+1; idx < _chunks.size(); idx++) - _chunks[idx].absPos += 1; - _size += 1; - _pos = pos; - return true; -} - -bool Chunks::overwrite(qint64 pos, char b) -{ - if ((pos < 0) || (pos >= _size)) - return false; - int chunkIdx = getChunkIndex(pos); - qint64 posInBa = pos - _chunks[chunkIdx].absPos; - _chunks[chunkIdx].data[(int)posInBa] = b; - _chunks[chunkIdx].dataChanged[(int)posInBa] = char(1); - _pos = pos; - return true; -} - -bool Chunks::removeAt(qint64 pos) -{ - if ((pos < 0) || (pos >= _size)) - return false; - int chunkIdx = getChunkIndex(pos); - qint64 posInBa = pos - _chunks[chunkIdx].absPos; - _chunks[chunkIdx].data.remove(posInBa, 1); - _chunks[chunkIdx].dataChanged.remove(posInBa, 1); - for (int idx=chunkIdx+1; idx < _chunks.size(); idx++) - _chunks[idx].absPos -= 1; - _size -= 1; - _pos = pos; - return true; -} - - -// ***************************************** Utility functions - -char Chunks::operator[](qint64 pos) -{ - return data(pos, 1)[0]; -} - -qint64 Chunks::pos() -{ - return _pos; -} - -qint64 Chunks::size() -{ - return _size; -} - -int Chunks::getChunkIndex(qint64 absPos) -{ - // This routine checks, if there is already a copied chunk available. If os, it - // returns a reference to it. If there is no copied chunk available, original - // data will be copied into a new chunk. - - int foundIdx = -1; - int insertIdx = 0; - qint64 ioDelta = 0; - - - for (int idx=0; idx < _chunks.size(); idx++) - { - Chunk chunk = _chunks[idx]; - if ((absPos >= chunk.absPos) && (absPos < (chunk.absPos + chunk.data.size()))) - { - foundIdx = idx; - break; - } - if (absPos < chunk.absPos) - { - insertIdx = idx; - break; - } - ioDelta += chunk.data.size() - CHUNK_SIZE; - insertIdx = idx + 1; - } - - if (foundIdx == -1) - { - Chunk newChunk; - qint64 readAbsPos = absPos - ioDelta; - qint64 readPos = (readAbsPos & READ_CHUNK_MASK); - _ioDevice->open(QIODevice::ReadOnly); - _ioDevice->seek(readPos); - newChunk.data = _ioDevice->read(CHUNK_SIZE); - _ioDevice->close(); - newChunk.absPos = absPos - (readAbsPos - readPos); - newChunk.dataChanged = QByteArray(newChunk.data.size(), char(0)); - _chunks.insert(insertIdx, newChunk); - foundIdx = insertIdx; - } - return foundIdx; -} - - -#ifdef MODUL_TEST -int Chunks::chunkSize() -{ - return _chunks.size(); -} - -#endif diff --git a/qhexedit2/chunks.h b/qhexedit2/chunks.h deleted file mode 100644 index f01cd02..0000000 --- a/qhexedit2/chunks.h +++ /dev/null @@ -1,76 +0,0 @@ -#ifndef CHUNKS_H -#define CHUNKS_H - -/** \cond docNever */ - -/*! The Chunks class is the storage backend for QHexEdit. - * - * When QHexEdit loads data, Chunks access them using a QIODevice interface. When the app uses - * a QByteArray interface, QBuffer is used to provide again a QIODevice like interface. No data - * will be changed, therefore Chunks opens the QIODevice in QIODevice::ReadOnly mode. After every - * access Chunks closes the QIODevice, that's why external applications can overwrite files while - * QHexEdit shows them. - * - * When the the user starts to edit the data, Chunks creates a local copy of a chunk of data (4 - * kilobytes) and notes all changes there. Parallel to that chunk, there is a second chunk, - * which keep track of which bytes are changed and which not. - * - */ - -#include - -struct Chunk -{ - QByteArray data; - QByteArray dataChanged; - qint64 absPos; -}; - -class Chunks -{ -public: - // Constructors and file settings - Chunks(); - Chunks(QIODevice &ioDevice); - bool setIODevice(QIODevice &ioDevice); - - // Getting data out of Chunks - QByteArray data(qint64 pos=0, qint64 count=-1, QByteArray *highlighted=0); - bool write(QIODevice &iODevice, qint64 pos=0, qint64 count=-1); - - // Set and get highlighting infos - void setDataChanged(qint64 pos, bool dataChanged); - bool dataChanged(qint64 pos); - - // Search API - qint64 indexOf(const QByteArray &ba, qint64 from); - qint64 lastIndexOf(const QByteArray &ba, qint64 from); - - // Char manipulations - bool insert(qint64 pos, char b); - bool overwrite(qint64 pos, char b); - bool removeAt(qint64 pos); - - // Utility functions - char operator[](qint64 pos); - qint64 pos(); - qint64 size(); - - -private: - int getChunkIndex(qint64 absPos); - - QIODevice * _ioDevice; - qint64 _pos; - qint64 _size; - QList _chunks; - -#ifdef MODUL_TEST -public: - int chunkSize(); -#endif -}; - -/** \endcond docNever */ - -#endif // CHUNKS_H diff --git a/qhexedit2/commands.cpp b/qhexedit2/commands.cpp deleted file mode 100644 index e9530d5..0000000 --- a/qhexedit2/commands.cpp +++ /dev/null @@ -1,165 +0,0 @@ -#include "commands.h" -#include - - -// Helper class to store single byte commands -class CharCommand : public QUndoCommand -{ -public: - enum CCmd {insert, removeAt, overwrite}; - - CharCommand(Chunks * chunks, CCmd cmd, qint64 charPos, char newChar, - QUndoCommand *parent=0); - - void undo(); - void redo(); - bool mergeWith(const QUndoCommand *command); - int id() const { return 1234; } - -private: - Chunks * _chunks; - qint64 _charPos; - bool _wasChanged; - char _newChar; - char _oldChar; - CCmd _cmd; -}; - -CharCommand::CharCommand(Chunks * chunks, CCmd cmd, qint64 charPos, char newChar, QUndoCommand *parent) - : QUndoCommand(parent) -{ - _chunks = chunks; - _charPos = charPos; - _newChar = newChar; - _cmd = cmd; -} - -bool CharCommand::mergeWith(const QUndoCommand *command) -{ - const CharCommand *nextCommand = static_cast(command); - bool result = false; - - if (_cmd != CharCommand::removeAt) - { - if (nextCommand->_cmd == overwrite) - if (nextCommand->_charPos == _charPos) - { - _newChar = nextCommand->_newChar; - result = true; - } - } - return result; -} - -void CharCommand::undo() -{ - switch (_cmd) - { - case insert: - _chunks->removeAt(_charPos); - break; - case overwrite: - _chunks->overwrite(_charPos, _oldChar); - _chunks->setDataChanged(_charPos, _wasChanged); - break; - case removeAt: - _chunks->insert(_charPos, _oldChar); - _chunks->setDataChanged(_charPos, _wasChanged); - break; - } -} - -void CharCommand::redo() -{ - switch (_cmd) - { - case insert: - _chunks->insert(_charPos, _newChar); - break; - case overwrite: - _oldChar = (*_chunks)[_charPos]; - _wasChanged = _chunks->dataChanged(_charPos); - _chunks->overwrite(_charPos, _newChar); - break; - case removeAt: - _oldChar = (*_chunks)[_charPos]; - _wasChanged = _chunks->dataChanged(_charPos); - _chunks->removeAt(_charPos); - break; - } -} - -UndoStack::UndoStack(Chunks * chunks, QObject * parent) - : QUndoStack(parent) -{ - _chunks = chunks; - _parent = parent; -} - -void UndoStack::insert(qint64 pos, char c) -{ - if ((pos >= 0) && (pos <= _chunks->size())) - { - QUndoCommand *cc = new CharCommand(_chunks, CharCommand::insert, pos, c); - this->push(cc); - } -} - -void UndoStack::insert(qint64 pos, const QByteArray &ba) -{ - if ((pos >= 0) && (pos <= _chunks->size())) - { - QString txt = QString(tr("Inserting %1 bytes")).arg(ba.size()); - beginMacro(txt); - for (int idx=0; idx < ba.size(); idx++) - { - QUndoCommand *cc = new CharCommand(_chunks, CharCommand::insert, pos + idx, ba.at(idx)); - this->push(cc); - } - endMacro(); - } -} - -void UndoStack::removeAt(qint64 pos, qint64 len) -{ - if ((pos >= 0) && (pos < _chunks->size())) - { - if (len==1) - { - QUndoCommand *cc = new CharCommand(_chunks, CharCommand::removeAt, pos, char(0)); - this->push(cc); - } - else - { - QString txt = QString(tr("Delete %1 chars")).arg(len); - beginMacro(txt); - for (qint64 cnt=0; cnt= 0) && (pos < _chunks->size())) - { - QUndoCommand *cc = new CharCommand(_chunks, CharCommand::overwrite, pos, c); - this->push(cc); - } -} - -void UndoStack::overwrite(qint64 pos, int len, const QByteArray &ba) -{ - if ((pos >= 0) && (pos < _chunks->size())) - { - QString txt = QString(tr("Overwrite %1 chars")).arg(len); - beginMacro(txt); - removeAt(pos, len); - insert(pos, ba); - endMacro(); - } -} diff --git a/qhexedit2/commands.h b/qhexedit2/commands.h deleted file mode 100644 index 9c34683..0000000 --- a/qhexedit2/commands.h +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef COMMANDS_H -#define COMMANDS_H - -/** \cond docNever */ - -#include - -#include "chunks.h" - -/*! CharCommand is a class to provid undo/redo functionality in QHexEdit. -A QUndoCommand represents a single editing action on a document. CharCommand -is responsable for manipulations on single chars. It can insert. overwrite and -remove characters. A manipulation stores allways two actions -1. redo (or do) action -2. undo action. - -CharCommand also supports command compression via mergeWidht(). This allows -the user to execute a undo command contation e.g. 3 steps in a single command. -If you for example insert a new byt "34" this means for the editor doing 3 -steps: insert a "00", overwrite it with "03" and the overwrite it with "34". These -3 steps are combined into a single step, insert a "34". - -The byte array oriented commands are just put into a set of single byte commands, -which are pooled together with the macroBegin() and macroEnd() functionality of -Qt's QUndoStack. -*/ - -class UndoStack : public QUndoStack -{ - Q_OBJECT - -public: - UndoStack(Chunks *chunks, QObject * parent=0); - void insert(qint64 pos, char c); - void insert(qint64 pos, const QByteArray &ba); - void removeAt(qint64 pos, qint64 len=1); - void overwrite(qint64 pos, char c); - void overwrite(qint64 pos, int len, const QByteArray &ba); - -private: - Chunks * _chunks; - QObject * _parent; -}; - -/** \endcond docNever */ - -#endif // COMMANDS_H diff --git a/qhexedit2/license.txt b/qhexedit2/license.txt deleted file mode 100644 index f166cc5..0000000 --- a/qhexedit2/license.txt +++ /dev/null @@ -1,502 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -strategy to use in any particular case, based on the explanations below. - - When we speak of free software, we are referring to freedom of use, -not price. Our General Public Licenses are designed to make sure that -you have the freedom to distribute copies of free software (and charge -for this service if you wish); that you receive source code or can get -it if you want it; that you can change the software and use pieces of -it in new free programs; and that you are informed that you can do -these things. - - To protect your rights, we need to make restrictions that forbid -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -complete object files to the recipients, so that they can relink them -with the library after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - We protect your rights with a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -introduced by others. - - Finally, software patents pose a constant threat to the existence of -any free program. We wish to make sure that a company cannot -effectively restrict the users of a free program by obtaining a -restrictive license from a patent holder. Therefore, we insist that -any patent license obtained for a version of the library must be -consistent with the full freedom of use specified in this license. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -this license for certain libraries in order to permit linking those -libraries into non-free programs. - - When a program is linked with a library, whether statically or using -a shared library, the combination of the two is legally speaking a -combined work, a derivative of the original library. The ordinary -General Public License therefore permits such linking only if the -entire combination fits its criteria of freedom. The Lesser General -Public License permits more lax criteria for linking other code with -the library. - - We call this license the "Lesser" General Public License because it -does Less to protect the user's freedom than the ordinary General -Public License. It also provides other free software developers Less -of an advantage over competing non-free programs. These disadvantages -are the reason we use the ordinary General Public License for many -libraries. However, the Lesser license provides advantages in certain -special circumstances. - - For example, on rare occasions, there may be a special need to -encourage the widest possible use of a certain library, so that it becomes -a de-facto standard. To achieve this, non-free programs must be -allowed to use the library. A more frequent case is that a free -library does the same job as widely used non-free libraries. In this -case, there is little to gain by limiting the free library to free -software only, so we use the Lesser General Public License. - - In other cases, permission to use a particular library in non-free -programs enables a greater number of people to use a large body of -free software. For example, permission to use the GNU C Library in -non-free programs enables many more people to use the whole GNU -operating system, as well as its variant, the GNU/Linux operating -system. - - Although the Lesser General Public License is Less protective of the -users' freedom, it does ensure that the user of a program that is -linked with the Library has the freedom and the wherewithal to run -that program using a modified version of the Library. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, whereas the latter must -be combined with the library in order to run. - - GNU LESSER GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also combine or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (1) uses at run time a - copy of the library already present on the user's computer system, - rather than copying library functions into the executable, and (2) - will operate properly with a modified version of the library, if - the user installs one, as long as the modified version is - interface-compatible with the version that the work was made with. - - c) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - d) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - e) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the materials to be distributed need not include anything that is -normally distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties with -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! \ No newline at end of file diff --git a/qhexedit2/qhexedit.cpp b/qhexedit2/qhexedit.cpp deleted file mode 100644 index 8f101ed..0000000 --- a/qhexedit2/qhexedit.cpp +++ /dev/null @@ -1,995 +0,0 @@ -#include -#include -#include -#include -#include - -#include "qhexedit.h" - -const int HEXCHARS_IN_LINE = 47; -const int BYTES_PER_LINE = 16; - - -// ********************************************************************** Constructor, destructor - -QHexEdit::QHexEdit(QWidget *parent) : QAbstractScrollArea(parent) -{ - _chunks = new Chunks(); - _undoStack = new UndoStack(_chunks, this); -#ifdef Q_OS_WIN32 - setFont(QFont("Courier", 10)); -#else - setFont(QFont("Monospace", 10)); -#endif - setAddressAreaColor(this->palette().alternateBase().color()); - setHighlightingColor(QColor(0xff, 0xff, 0x99, 0xff)); - setSelectionColor(this->palette().highlight().color()); - - connect(&_cursorTimer, SIGNAL(timeout()), this, SLOT(updateCursor())); - connect(verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(adjust())); - connect(horizontalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(adjust())); - connect(_undoStack, SIGNAL(indexChanged(int)), this, SLOT(dataChangedPrivate(int))); - - _cursorTimer.setInterval(500); - _cursorTimer.start(); - - setAddressWidth(4); - setAddressArea(true); - setAsciiArea(true); - setOverwriteMode(true); - setHighlighting(true); - setReadOnly(false); - - init(); - -} - -QHexEdit::~QHexEdit() -{ -} - -// ********************************************************************** Properties - -void QHexEdit::setAddressArea(bool addressArea) -{ - _addressArea = addressArea; - adjust(); - setCursorPosition(_cursorPosition); - viewport()->update(); -} - -bool QHexEdit::addressArea() -{ - return _addressArea; -} - -void QHexEdit::setAddressAreaColor(const QColor &color) -{ - _addressAreaColor = color; - viewport()->update(); -} - -QColor QHexEdit::addressAreaColor() -{ - return _addressAreaColor; -} - -void QHexEdit::setAddressOffset(qint64 addressOffset) -{ - _addressOffset = addressOffset; - adjust(); - setCursorPosition(_cursorPosition); - viewport()->update(); -} - -qint64 QHexEdit::addressOffset() -{ - return _addressOffset; -} - -void QHexEdit::setAddressWidth(int addressWidth) -{ - _addressWidth = addressWidth; - adjust(); - setCursorPosition(_cursorPosition); - viewport()->update(); -} - -int QHexEdit::addressWidth() -{ - qint64 size = _chunks->size(); - int n = 1; - if (size > Q_INT64_C(0x100000000)){ n += 8; size /= Q_INT64_C(0x100000000);} - if (size > 0x10000){ n += 4; size /= 0x10000;} - if (size > 0x100){ n += 2; size /= 0x100;} - if (size > 0x10){ n += 1; size /= 0x10;} - - if (n > _addressWidth) - return n; - else - return _addressWidth; -} - -void QHexEdit::setAsciiArea(bool asciiArea) -{ - _asciiArea = asciiArea; - viewport()->update(); -} - -bool QHexEdit::asciiArea() -{ - return _asciiArea; -} - -void QHexEdit::setCursorPosition(qint64 position) -{ - // 1. delete old cursor - _blink = false; - viewport()->update(_cursorRect); - - // 2. Check, if cursor in range? - if (_overwriteMode && (position > (_chunks->size() * 2 - 1))) - position = _chunks->size() * 2 - 1; - if (!_overwriteMode && (position > (_chunks->size() * 2))) - position = _chunks->size() * 2; - if (position < 0) - position = 0; - - // 3. Calc new position of curser - _cursorPosition = position; - _bPosCurrent = position / 2; - _pxCursorY = ((position/2 - _bPosFirst) / BYTES_PER_LINE + 1) * _pxCharHeight; - int x = (position % (2 * BYTES_PER_LINE)); - _pxCursorX = (((x / 2) * 3) + (x % 2)) * _pxCharWidth + _pxPosHexX; - - if (_overwriteMode) - _cursorRect = QRect(_pxCursorX - horizontalScrollBar()->value(), _pxCursorY + _pxCursorWidth, _pxCharWidth, _pxCursorWidth); - else - _cursorRect = QRect(_pxCursorX - horizontalScrollBar()->value(), _pxCursorY - _pxCharHeight + 4, _pxCursorWidth, _pxCharHeight); - - // 4. Immiadately draw new cursor - _blink = true; - viewport()->update(_cursorRect); - emit currentAddressChanged(_bPosCurrent); -} - -qint64 QHexEdit::cursorPosition(QPoint pos) -{ - // Calc cursorposition depending on a graphical position - qint64 result = -1; - int posX = pos.x() + horizontalScrollBar()->value(); - int posY = pos.y() - 3; - if ((posX >= _pxPosHexX) && (posX < (_pxPosHexX + (1 + HEXCHARS_IN_LINE) * _pxCharWidth))) - { - int x = (posX - _pxPosHexX - _pxCharWidth / 2) / _pxCharWidth; - x = (x / 3) * 2 + x % 3; - int y = (posY / _pxCharHeight) * 2 * BYTES_PER_LINE; - result = _bPosFirst * 2 + x + y; - } - return result; -} - -qint64 QHexEdit::cursorPosition() -{ - return _cursorPosition; -} - -void QHexEdit::setData(const QByteArray &ba) -{ - _data = ba; - _bData.setData(_data); - setData(_bData); -} - -QByteArray QHexEdit::data() -{ - return _chunks->data(0, -1); -} - -void QHexEdit::setHighlighting(bool highlighting) -{ - _highlighting = highlighting; - viewport()->update(); -} - -bool QHexEdit::highlighting() -{ - return _highlighting; -} - -void QHexEdit::setHighlightingColor(const QColor &color) -{ - _brushHighlighted = QBrush(color); - _penHighlighted = QPen(viewport()->palette().color(QPalette::WindowText)); - viewport()->update(); -} - -QColor QHexEdit::highlightingColor() -{ - return _brushHighlighted.color(); -} - -void QHexEdit::setOverwriteMode(bool overwriteMode) -{ - _overwriteMode = overwriteMode; - emit overwriteModeChanged(overwriteMode); -} - -bool QHexEdit::overwriteMode() -{ - return _overwriteMode; -} - -void QHexEdit::setSelectionColor(const QColor &color) -{ - _brushSelection = QBrush(color); - _penSelection = QPen(Qt::white); - viewport()->update(); -} - -QColor QHexEdit::selectionColor() -{ - return _brushSelection.color(); -} - -bool QHexEdit::isReadOnly() -{ - return _readOnly; -} - -void QHexEdit::setReadOnly(bool readOnly) -{ - _readOnly = readOnly; -} - -bool QHexEdit::isUpperCase() -{ - return _upperCase; -} - -void QHexEdit::setUpperCase(bool upperCase) -{ - _upperCase = upperCase; -} - -// ********************************************************************** Access to data of qhexedit -bool QHexEdit::setData(QIODevice &iODevice) -{ - bool ok = _chunks->setIODevice(iODevice); - init(); - dataChangedPrivate(); - return ok; -} - -QByteArray QHexEdit::dataAt(qint64 pos, qint64 count) -{ - return _chunks->data(pos, count); -} - -bool QHexEdit::write(QIODevice &iODevice, qint64 pos, qint64 count) -{ - return _chunks->write(iODevice, pos, count); -} - -// ********************************************************************** Char handling -void QHexEdit::insert(qint64 index, char ch) -{ - _undoStack->insert(index, ch); - refresh(); -} - -void QHexEdit::remove(qint64 index, qint64 len) -{ - _undoStack->removeAt(index, len); - refresh(); -} - -void QHexEdit::replace(qint64 index, char ch) -{ - _undoStack->overwrite(index, ch); - refresh(); -} - -// ********************************************************************** ByteArray handling -void QHexEdit::insert(qint64 pos, const QByteArray &ba) -{ - _undoStack->insert(pos, ba); - refresh(); -} - -void QHexEdit::replace(qint64 pos, qint64 len, const QByteArray &ba) -{ - _undoStack->overwrite(pos, len, ba); - refresh(); -} - -// ********************************************************************** Utility functions -void QHexEdit::ensureVisible() -{ - if (_cursorPosition < (_bPosFirst * 2)) - verticalScrollBar()->setValue((int)(_cursorPosition / 2 / BYTES_PER_LINE)); - if (_cursorPosition > ((_bPosFirst + (_rowsShown - 1)*BYTES_PER_LINE) * 2)) - verticalScrollBar()->setValue((int)(_cursorPosition / 2 / BYTES_PER_LINE) - _rowsShown + 1); - if (_pxCursorX < horizontalScrollBar()->value()) - horizontalScrollBar()->setValue(_pxCursorX); - if ((_pxCursorX + _pxCharWidth) > (horizontalScrollBar()->value() + viewport()->width())) - horizontalScrollBar()->setValue(_pxCursorX + _pxCharWidth - viewport()->width()); - viewport()->update(); -} - -qint64 QHexEdit::indexOf(const QByteArray &ba, qint64 from) -{ - qint64 pos = _chunks->indexOf(ba, from); - if (pos > -1) - { - qint64 curPos = pos*2; - setCursorPosition(curPos + ba.length()*2); - resetSelection(curPos); - setSelection(curPos + ba.length()*2); - ensureVisible(); - } - return pos; -} - -bool QHexEdit::isModified() -{ - return _modified; -} - -qint64 QHexEdit::lastIndexOf(const QByteArray &ba, qint64 from) -{ - qint64 pos = _chunks->lastIndexOf(ba, from); - if (pos > -1) - { - qint64 curPos = pos*2; - setCursorPosition(curPos - 1); - resetSelection(curPos); - setSelection(curPos + ba.length()*2); - ensureVisible(); - } - return pos; -} - -void QHexEdit::redo() -{ - _undoStack->redo(); - setCursorPosition(_chunks->pos()*2); - refresh(); -} - -QString QHexEdit::selectionToReadableString() -{ - QByteArray ba = _chunks->data(getSelectionBegin(), getSelectionEnd() - getSelectionBegin()); - return toReadable(ba); -} - -void QHexEdit::setFont(const QFont &font) -{ - QWidget::setFont(font); - _pxCharWidth = fontMetrics().width(QLatin1Char('2')); - _pxCharHeight = fontMetrics().height(); - _pxGapAdr = _pxCharWidth / 2; - _pxGapAdrHex = _pxCharWidth; - _pxGapHexAscii = 2 * _pxCharWidth; - _pxCursorWidth = _pxCharHeight / 7; - _pxSelectionSub = _pxCharHeight / 5; - viewport()->update(); -} - -QString QHexEdit::toReadableString() -{ - QByteArray ba = _chunks->data(); - return toReadable(ba); -} - -void QHexEdit::undo() -{ - _undoStack->undo(); - setCursorPosition(_chunks->pos()*2); - refresh(); -} - -// ********************************************************************** Handle events -void QHexEdit::keyPressEvent(QKeyEvent *event) -{ - // Cursor movements - if (event->matches(QKeySequence::MoveToNextChar)) - { - setCursorPosition(_cursorPosition + 1); - resetSelection(_cursorPosition); - } - if (event->matches(QKeySequence::MoveToPreviousChar)) - { - setCursorPosition(_cursorPosition - 1); - resetSelection(_cursorPosition); - } - if (event->matches(QKeySequence::MoveToEndOfLine)) - { - setCursorPosition(_cursorPosition | (2 * BYTES_PER_LINE -1)); - resetSelection(_cursorPosition); - } - if (event->matches(QKeySequence::MoveToStartOfLine)) - { - setCursorPosition(_cursorPosition - (_cursorPosition % (2 * BYTES_PER_LINE))); - resetSelection(_cursorPosition); - } - if (event->matches(QKeySequence::MoveToPreviousLine)) - { - setCursorPosition(_cursorPosition - (2 * BYTES_PER_LINE)); - resetSelection(_cursorPosition); - } - if (event->matches(QKeySequence::MoveToNextLine)) - { - setCursorPosition(_cursorPosition + (2 * BYTES_PER_LINE)); - resetSelection(_cursorPosition); - } - if (event->matches(QKeySequence::MoveToNextPage)) - { - setCursorPosition(_cursorPosition + (((_rowsShown - 1) * 2 * BYTES_PER_LINE))); - resetSelection(_cursorPosition); - } - if (event->matches(QKeySequence::MoveToPreviousPage)) - { - setCursorPosition(_cursorPosition - (((_rowsShown - 1) * 2 * BYTES_PER_LINE))); - resetSelection(_cursorPosition); - } - if (event->matches(QKeySequence::MoveToEndOfDocument)) - { - setCursorPosition(_chunks->size() * 2); - resetSelection(_cursorPosition); - } - if (event->matches(QKeySequence::MoveToStartOfDocument)) - { - setCursorPosition(0); - resetSelection(_cursorPosition); - } - - // Select commands - if (event->matches(QKeySequence::SelectAll)) - { - resetSelection(0); - setSelection(2*_chunks->size() + 1); - } - if (event->matches(QKeySequence::SelectNextChar)) - { - qint64 pos = _cursorPosition + 1; - setCursorPosition(pos); - setSelection(pos); - } - if (event->matches(QKeySequence::SelectPreviousChar)) - { - qint64 pos = _cursorPosition - 1; - setSelection(pos); - setCursorPosition(pos); - } - if (event->matches(QKeySequence::SelectEndOfLine)) - { - qint64 pos = _cursorPosition - (_cursorPosition % (2 * BYTES_PER_LINE)) + (2 * BYTES_PER_LINE); - setCursorPosition(pos); - setSelection(pos); - } - if (event->matches(QKeySequence::SelectStartOfLine)) - { - qint64 pos = _cursorPosition - (_cursorPosition % (2 * BYTES_PER_LINE)); - setCursorPosition(pos); - setSelection(pos); - } - if (event->matches(QKeySequence::SelectPreviousLine)) - { - qint64 pos = _cursorPosition - (2 * BYTES_PER_LINE); - setCursorPosition(pos); - setSelection(pos); - } - if (event->matches(QKeySequence::SelectNextLine)) - { - qint64 pos = _cursorPosition + (2 * BYTES_PER_LINE); - setCursorPosition(pos); - setSelection(pos); - } - if (event->matches(QKeySequence::SelectNextPage)) - { - qint64 pos = _cursorPosition + (((viewport()->height() / _pxCharHeight) - 1) * 2 * BYTES_PER_LINE); - setCursorPosition(pos); - setSelection(pos); - } - if (event->matches(QKeySequence::SelectPreviousPage)) - { - qint64 pos = _cursorPosition - (((viewport()->height() / _pxCharHeight) - 1) * 2 * BYTES_PER_LINE); - setCursorPosition(pos); - setSelection(pos); - } - if (event->matches(QKeySequence::SelectEndOfDocument)) - { - qint64 pos = _chunks->size() * 2; - setCursorPosition(pos); - setSelection(pos); - } - if (event->matches(QKeySequence::SelectStartOfDocument)) - { - qint64 pos = 0; - setCursorPosition(pos); - setSelection(pos); - } - - // Edit Commands - if (!_readOnly) - { - if ((QApplication::keyboardModifiers() == Qt::NoModifier) || - (QApplication::keyboardModifiers() == Qt::KeypadModifier)) - { - /* Hex input */ - int key = int(event->text()[0].toLatin1()); - if ((key>='0' && key<='9') || (key>='a' && key <= 'f')) - { - if (getSelectionBegin() != getSelectionEnd()) - { - if (_overwriteMode) - { - qint64 len = getSelectionEnd() - getSelectionBegin(); - replace(getSelectionBegin(), (int)len, QByteArray((int)len, char(0))); - } - else - { - remove(getSelectionBegin(), getSelectionEnd() - getSelectionBegin()); - _bPosCurrent = getSelectionBegin(); - } - setCursorPosition(2*_bPosCurrent); - resetSelection(2*_bPosCurrent); - } - - // If insert mode, then insert a byte - if (_overwriteMode == false) - if ((_cursorPosition % 2) == 0) - insert(_bPosCurrent, char(0)); - - // Change content - if (_chunks->size() > 0) - { - QByteArray hexValue = _chunks->data(_bPosCurrent, 1).toHex(); - if ((_cursorPosition % 2) == 0) - hexValue[0] = key; - else - hexValue[1] = key; - - replace(_bPosCurrent, QByteArray().fromHex(hexValue)[0]); - - setCursorPosition(_cursorPosition + 1); - resetSelection(_cursorPosition); - } - } - } - - /* Cut */ - if (event->matches(QKeySequence::Cut)) - { - QByteArray ba = _chunks->data(getSelectionBegin(), getSelectionEnd() - getSelectionBegin()).toHex(); - for (qint64 idx = 32; idx < ba.size(); idx +=33) - ba.insert(idx, "\n"); - QClipboard *clipboard = QApplication::clipboard(); - clipboard->setText(ba); - if (_overwriteMode) - { - qint64 len = getSelectionEnd() - getSelectionBegin(); - replace(getSelectionBegin(), (int)len, QByteArray((int)len, char(0))); - } - else - { - remove(getSelectionBegin(), getSelectionEnd() - getSelectionBegin()); - } - setCursorPosition(2*getSelectionBegin()); - resetSelection(2*getSelectionBegin()); - } - - /* Paste */ - if (event->matches(QKeySequence::Paste)) - { - QClipboard *clipboard = QApplication::clipboard(); - QByteArray ba = QByteArray().fromHex(clipboard->text().toLatin1()); - if (_overwriteMode) - replace(_bPosCurrent, ba.size(), ba); - else - insert(_bPosCurrent, ba); - setCursorPosition(_cursorPosition + 2 * ba.size()); - resetSelection(getSelectionBegin()); - } - - /* Delete char */ - if (event->matches(QKeySequence::Delete)) - { - if (getSelectionBegin() != getSelectionEnd()) - { - _bPosCurrent = getSelectionBegin(); - if (_overwriteMode) - { - QByteArray ba = QByteArray(getSelectionEnd() - getSelectionBegin(), char(0)); - replace(_bPosCurrent, ba.size(), ba); - } - else - { - remove(_bPosCurrent, getSelectionEnd() - getSelectionBegin()); - } - } - else - { - if (_overwriteMode) - replace(_bPosCurrent, char(0)); - else - remove(_bPosCurrent, 1); - } - setCursorPosition(2 * _bPosCurrent); - resetSelection(2 * _bPosCurrent); - } - - /* Backspace */ - if ((event->key() == Qt::Key_Backspace) && (event->modifiers() == Qt::NoModifier)) - { - if (getSelectionBegin() != getSelectionEnd()) - { - _bPosCurrent = getSelectionBegin(); - setCursorPosition(2 * _bPosCurrent); - if (_overwriteMode) - { - QByteArray ba = QByteArray(getSelectionEnd() - getSelectionBegin(), char(0)); - replace(_bPosCurrent, ba.size(), ba); - } - else - { - remove(_bPosCurrent, getSelectionEnd() - getSelectionBegin()); - } - resetSelection(2 * _bPosCurrent); - } - else - { - bool behindLastByte = false; - if ((_cursorPosition / 2) == _chunks->size()) - behindLastByte = true; - - _bPosCurrent -= 1; - if (_overwriteMode) - replace(_bPosCurrent, char(0)); - else - remove(_bPosCurrent, 1); - - if (!behindLastByte) - _bPosCurrent -= 1; - - setCursorPosition(2 * _bPosCurrent); - resetSelection(2 * _bPosCurrent); - } - } - - /* undo */ - if (event->matches(QKeySequence::Undo)) - { - undo(); - } - - /* redo */ - if (event->matches(QKeySequence::Redo)) - { - redo(); - } - - } - - /* Copy */ - if (event->matches(QKeySequence::Copy)) - { - QByteArray ba = _chunks->data(getSelectionBegin(), getSelectionEnd() - getSelectionBegin()).toHex(); - for (qint64 idx = 32; idx < ba.size(); idx +=33) - ba.insert(idx, "\n"); - QClipboard *clipboard = QApplication::clipboard(); - clipboard->setText(ba); - } - - // Switch between insert/overwrite mode - if ((event->key() == Qt::Key_Insert) && (event->modifiers() == Qt::NoModifier)) - { - setOverwriteMode(!overwriteMode()); - setCursorPosition(_cursorPosition); - } - - // ESC handler - if (event->key() == Qt::Key_Escape && parentWidget() != NULL) - { - parentWidget()->close(); - } - - refresh(); -} - -void QHexEdit::mouseMoveEvent(QMouseEvent * event) -{ - _blink = false; - viewport()->update(); - qint64 actPos = cursorPosition(event->pos()); - if (actPos >= 0) - { - setCursorPosition(actPos); - setSelection(actPos); - } -} - -void QHexEdit::mousePressEvent(QMouseEvent * event) -{ - _blink = false; - viewport()->update(); - qint64 cPos = cursorPosition(event->pos()); - if (cPos >= 0) - { - resetSelection(cPos); - setCursorPosition(cPos); - } -} - -void QHexEdit::paintEvent(QPaintEvent *event) -{ - QPainter painter(viewport()); - - if (event->rect() != _cursorRect) - { - // process some useful calculations - int pxOfsX = horizontalScrollBar()->value(); - int pxPosStartY = _pxCharHeight; - - // draw some patterns if needed - painter.fillRect(event->rect(), viewport()->palette().color(QPalette::Base)); - if (_addressArea) - painter.fillRect(QRect(-pxOfsX, event->rect().top(), _pxPosHexX - _pxGapAdrHex/2 - pxOfsX, height()), _addressAreaColor); - if (_asciiArea) - { - int linePos = _pxPosAsciiX - (_pxGapHexAscii / 2); - painter.setPen(Qt::gray); - painter.drawLine(linePos - pxOfsX, event->rect().top(), linePos - pxOfsX, height()); - } - - painter.setPen(viewport()->palette().color(QPalette::WindowText)); - - // paint address area - if (_addressArea) - { - QString address; - for (int row=0, pxPosY = _pxCharHeight; row <= (_dataShown.size()/BYTES_PER_LINE); row++, pxPosY +=_pxCharHeight) - { - address = QString("%1").arg(_bPosFirst + row*BYTES_PER_LINE + _addressOffset, _addrDigits, 16, QChar('0')); - // upper or lower case - if (_upperCase) - address = address.toUpper(); - - painter.drawText(_pxPosAdrX - pxOfsX, pxPosY, address); - } - } - - // paint hex and ascii area - QPen colStandard = QPen(viewport()->palette().color(QPalette::WindowText)); - - painter.setBackgroundMode(Qt::TransparentMode); - - for (int row = 0, pxPosY = pxPosStartY; row <= _rowsShown; row++, pxPosY +=_pxCharHeight) - { - QByteArray hex; - int pxPosX = _pxPosHexX - pxOfsX; - int pxPosAsciiX2 = _pxPosAsciiX - pxOfsX; - qint64 bPosLine = row * BYTES_PER_LINE; - for (int colIdx = 0; ((bPosLine + colIdx) < _dataShown.size() && (colIdx < BYTES_PER_LINE)); colIdx++) - { - QColor c = viewport()->palette().color(QPalette::Base); - painter.setPen(colStandard); - - qint64 posBa = _bPosFirst + bPosLine + colIdx; - if ((getSelectionBegin() <= posBa) && (getSelectionEnd() > posBa)) - { - c = _brushSelection.color(); - painter.setPen(_penSelection); - } - else - { - if (_highlighting) - if (_markedShown.at((int)(posBa - _bPosFirst))) - { - c = _brushHighlighted.color(); - painter.setPen(_penHighlighted); - } - } - - // render hex value - QRect r; - if (colIdx == 0) - r.setRect(pxPosX, pxPosY - _pxCharHeight + _pxSelectionSub, 2*_pxCharWidth, _pxCharHeight); - else - r.setRect(pxPosX - _pxCharWidth, pxPosY - _pxCharHeight + _pxSelectionSub, 3*_pxCharWidth, _pxCharHeight); - painter.fillRect(r, c); - hex = _hexDataShown.mid((bPosLine + colIdx) * 2, 2); - - // upper or lower case - if (_upperCase) - hex = hex.toUpper(); - - painter.drawText(pxPosX, pxPosY, hex); - pxPosX += 3*_pxCharWidth; - - // render ascii value - if (_asciiArea) - { - char ch = _dataShown.at(bPosLine + colIdx); - if ((ch < 0x20) || (ch > 0x7e)) - ch = '.'; - r.setRect(pxPosAsciiX2, pxPosY - _pxCharHeight + _pxSelectionSub, _pxCharWidth, _pxCharHeight); - painter.fillRect(r, c); - painter.drawText(pxPosAsciiX2, pxPosY, QChar(ch)); - pxPosAsciiX2 += _pxCharWidth; - } - } - } - painter.setBackgroundMode(Qt::TransparentMode); - painter.setPen(viewport()->palette().color(QPalette::WindowText)); - } - - // paint cursor - if (_blink && !_readOnly && hasFocus()) - painter.fillRect(_cursorRect, this->palette().color(QPalette::WindowText)); - else - painter.drawText(_pxCursorX, _pxCursorY, _hexDataShown.mid(_cursorPosition - _bPosFirst * 2, 1)); - - // emit event, if size has changed - if (_lastEventSize != _chunks->size()) - { - _lastEventSize = _chunks->size(); - emit currentSizeChanged(_lastEventSize); - } -} - -void QHexEdit::resizeEvent(QResizeEvent *) -{ - adjust(); -} - -// ********************************************************************** Handle selections -void QHexEdit::resetSelection() -{ - _bSelectionBegin = _bSelectionInit; - _bSelectionEnd = _bSelectionInit; -} - -void QHexEdit::resetSelection(qint64 pos) -{ - pos = pos / 2; - if (pos < 0) - pos = 0; - if (pos > _chunks->size()) - pos = _chunks->size(); - - _bSelectionInit = pos; - _bSelectionBegin = pos; - _bSelectionEnd = pos; -} - -void QHexEdit::setSelection(qint64 pos) -{ - pos = pos / 2; - if (pos < 0) - pos = 0; - if (pos > _chunks->size()) - pos = _chunks->size(); - - if (pos >= _bSelectionInit) - { - _bSelectionEnd = pos; - _bSelectionBegin = _bSelectionInit; - } - else - { - _bSelectionBegin = pos; - _bSelectionEnd = _bSelectionInit; - } -} - -int QHexEdit::getSelectionBegin() -{ - return _bSelectionBegin; -} - -int QHexEdit::getSelectionEnd() -{ - return _bSelectionEnd; -} - -// ********************************************************************** Private utility functions -void QHexEdit::init() -{ - _undoStack->clear(); - setAddressOffset(0); - resetSelection(0); - setCursorPosition(0); - verticalScrollBar()->setValue(0); - _modified = false; -} - -void QHexEdit::adjust() -{ - // recalc Graphics - if (_addressArea) - { - _addrDigits = addressWidth(); - _pxPosHexX = _pxGapAdr + _addrDigits*_pxCharWidth + _pxGapAdrHex; - } - else - _pxPosHexX = _pxGapAdrHex; - _pxPosAdrX = _pxGapAdr; - _pxPosAsciiX = _pxPosHexX + HEXCHARS_IN_LINE * _pxCharWidth + _pxGapHexAscii; - - // set horizontalScrollBar() - int pxWidth = _pxPosAsciiX; - if (_asciiArea) - pxWidth += BYTES_PER_LINE*_pxCharWidth; - horizontalScrollBar()->setRange(0, pxWidth - viewport()->width()); - horizontalScrollBar()->setPageStep(viewport()->width()); - - // set verticalScrollbar() - _rowsShown = ((viewport()->height()-4)/_pxCharHeight); - int lineCount = (int)(_chunks->size() / (qint64)BYTES_PER_LINE) + 1; - verticalScrollBar()->setRange(0, lineCount - _rowsShown); - verticalScrollBar()->setPageStep(_rowsShown); - - int value = verticalScrollBar()->value(); - _bPosFirst = (qint64)value * BYTES_PER_LINE; - _bPosLast = _bPosFirst + (qint64)(_rowsShown * BYTES_PER_LINE) - 1; - if (_bPosLast >= _chunks->size()) - _bPosLast = _chunks->size() - 1; - readBuffers(); - setCursorPosition(_cursorPosition); -} - -void QHexEdit::dataChangedPrivate(int) -{ - _modified = _undoStack->index() != 0; - adjust(); - emit dataChanged(); -} - -void QHexEdit::refresh() -{ - ensureVisible(); - readBuffers(); -} - -void QHexEdit::readBuffers() -{ - _dataShown = _chunks->data(_bPosFirst, _bPosLast - _bPosFirst + BYTES_PER_LINE + 1, &_markedShown); - _hexDataShown = QByteArray(_dataShown.toHex()); -} - -QString QHexEdit::toReadable(const QByteArray &ba) -{ - QString result; - - for (int i=0; i < ba.size(); i += 16) - { - QString addrStr = QString("%1").arg(_addressOffset + i, addressWidth(), 16, QChar('0')); - QString hexStr; - QString ascStr; - for (int j=0; j<16; j++) - { - if ((i + j) < ba.size()) - { - hexStr.append(" ").append(ba.mid(i+j, 1).toHex()); - char ch = ba[i + j]; - if ((ch < 0x20) || (ch > 0x7e)) - ch = '.'; - ascStr.append(QChar(ch)); - } - } - result += addrStr + " " + QString("%1").arg(hexStr, -48) + " " + QString("%1").arg(ascStr, -17) + "\n"; - } - return result; -} - -void QHexEdit::updateCursor() -{ - if (_blink) - _blink = false; - else - _blink = true; - viewport()->update(_cursorRect); -} - diff --git a/qhexedit2/qhexedit.h b/qhexedit2/qhexedit.h deleted file mode 100644 index 0c6659a..0000000 --- a/qhexedit2/qhexedit.h +++ /dev/null @@ -1,394 +0,0 @@ -#ifndef QHEXEDIT_H -#define QHEXEDIT_H - -#include -#include -#include - -#include "chunks.h" -#include "commands.h" - -/** \mainpage -QHexEdit is a binary editor widget for Qt. - -\version Version 0.7.7 -\image html qhexedit.png -*/ - - -/** QHexEdit is a hex editor widget written in C++ for the Qt (Qt4, Qt5) framework. -It is a simple editor for binary data, just like QPlainTextEdit is for text -data. There are sip configuration files included, so it is easy to create -bindings for PyQt and you can use this widget also in python 2 and 3. - -QHexEdit takes the data of a QByteArray (setData()) and shows it. You can use -the mouse or the keyboard to navigate inside the widget. If you hit the keys -(0..9, a..f) you will change the data. Changed data is highlighted and can be -accessed via data(). - -Normaly QHexEdit works in the overwrite Mode. You can set overwriteMode(false) -and insert data. In this case the size of data() increases. It is also possible -to delete bytes (del or backspace), here the size of data decreases. - -You can select data with keyboard hits or mouse movements. The copy-key will -copy the selected data into the clipboard. The cut-key copies also but delets -it afterwards. In overwrite mode, the paste function overwrites the content of -the (does not change the length) data. In insert mode, clipboard data will be -inserted. The clipboard content is expected in ASCII Hex notation. Unknown -characters will be ignored. - -QHexEdit comes with undo/redo functionality. All changes can be undone, by -pressing the undo-key (usually ctr-z). They can also be redone afterwards. -The undo/redo framework is cleared, when setData() sets up a new -content for the editor. You can search data inside the content with indexOf() -and lastIndexOf(). The replace() function is to change located subdata. This -'replaced' data can also be undone by the undo/redo framework. - -QHexEdit is based on QIODevice, that's why QHexEdit can handle big amounts of -data. The size of edited data can be more then two gigabytes without any -restrictions. -*/ -class QHexEdit : public QAbstractScrollArea -{ - Q_OBJECT - - /*! Property address area switch the address area on or off. Set addressArea true - (show it), false (hide it). - */ - Q_PROPERTY(bool addressArea READ addressArea WRITE setAddressArea) - - /*! Property address area color sets (setAddressAreaColor()) the backgorund - color of address areas. You can also read the color (addressaAreaColor()). - */ - Q_PROPERTY(QColor addressAreaColor READ addressAreaColor WRITE setAddressAreaColor) - - /*! Property addressOffset is added to the Numbers of the Address Area. - A offset in the address area (left side) is sometimes usefull, whe you show - only a segment of a complete memory picture. With setAddressOffset() you set - this property - with addressOffset() you get the current value. - */ - Q_PROPERTY(qint64 addressOffset READ addressOffset WRITE setAddressOffset) - - /*! Set and get the minimum width of the address area, width in characters. - */ - Q_PROPERTY(int addressWidth READ addressWidth WRITE setAddressWidth) - - /*! Switch the ascii area on (true, show it) or off (false, hide it). - */ - Q_PROPERTY(bool asciiArea READ asciiArea WRITE setAsciiArea) - - /*! Porperty cursorPosition sets or gets the position of the editor cursor - in QHexEdit. Every byte in data has to cursor positions: the lower and upper - Nibble. Maximum cursor position is factor two of data.size(). - */ - Q_PROPERTY(qint64 cursorPosition READ cursorPosition WRITE setCursorPosition) - - /*! Property data holds the content of QHexEdit. Call setData() to set the - content of QHexEdit, data() returns the actual content. When calling setData() - with a QByteArray as argument, QHexEdit creates a internal copy of the data - If you want to edit big files please use setData(), based on QIODevice. - */ - Q_PROPERTY(QByteArray data READ data WRITE setData NOTIFY dataChanged) - - /*! Switch the highlighting feature on or of: true (show it), false (hide it). - */ - Q_PROPERTY(bool highlighting READ highlighting WRITE setHighlighting) - - /*! Property highlighting color sets (setHighlightingColor()) the backgorund - color of highlighted text areas. You can also read the color - (highlightingColor()). - */ - Q_PROPERTY(QColor highlightingColor READ highlightingColor WRITE setHighlightingColor) - - /*! Porperty overwrite mode sets (setOverwriteMode()) or gets (overwriteMode()) the mode - in which the editor works. In overwrite mode the user will overwrite existing data. The - size of data will be constant. In insert mode the size will grow, when inserting - new data. - */ - Q_PROPERTY(bool overwriteMode READ overwriteMode WRITE setOverwriteMode) - - /*! Property selection color sets (setSelectionColor()) the backgorund - color of selected text areas. You can also read the color - (selectionColor()). - */ - Q_PROPERTY(QColor selectionColor READ selectionColor WRITE setSelectionColor) - - /*! Property readOnly sets (setReadOnly()) or gets (isReadOnly) the mode - in which the editor works. In readonly mode the the user can only navigate - through the data and select data; modifying is not possible. This - property's default is false. - */ - Q_PROPERTY(bool readOnly READ isReadOnly WRITE setReadOnly) - - /*! Property upperCase sets (setUpperCase()) or gets (isUpperCase) the case of hex - data. Default is lowercase. - */ - Q_PROPERTY(bool upperCase READ isUpperCase WRITE setUpperCase) - - /*! Set the font of the widget. Please use fixed width fonts like Mono or Courier.*/ - Q_PROPERTY(QFont font READ font WRITE setFont) - -public: - /*! Creates an instance of QHexEdit. - \param parent Parent widget of QHexEdit. - */ - QHexEdit(QWidget *parent=0); - - // Access to data of qhexedit - - /*! Sets the data of QHexEdit. The QIODevice will be opend just before reading - and closed immediately afterwards. This is to allow other programs to rewrite - the file while editing it. - */ - bool setData(QIODevice &iODevice); - - /*! Givs back the data as a QByteArray starting at position \param pos and - delivering \param count bytes. - */ - QByteArray dataAt(qint64 pos, qint64 count=-1); - - /*! Givs back the data into a \param iODevice starting at position \param pos - and delivering \param count bytes. - */ - bool write(QIODevice &iODevice, qint64 pos=0, qint64 count=-1); - - - // Char handling - - /*! Inserts a char. - \param pos Index position, where to insert - \param ch Char, which is to insert - The char will be inserted and size of data grows. - */ - void insert(qint64 pos, char ch); - - /*! Removes len bytes from the content. - \param pos Index position, where to remove - \param len Amount of bytes to remove - */ - void remove(qint64 pos, qint64 len=1); - - /*! Replaces a char. - \param pos Index position, where to overwrite - \param ch Char, which is to insert - The char will be overwritten and size remains constant. - */ - void replace(qint64 pos, char ch); - - - // ByteArray handling - - /*! Inserts a byte array. - \param pos Index position, where to insert - \param ba QByteArray, which is to insert - The QByteArray will be inserted and size of data grows. - */ - void insert(qint64 pos, const QByteArray &ba); - - /*! Replaces \param len bytes with a byte array \param ba - \param pos Index position, where to overwrite - \param ba QByteArray, which is inserted - \param len count of bytes to overwrite - The data is overwritten and size of data may change. - */ - void replace(qint64 pos, qint64 len, const QByteArray &ba); - - - // Utility functioins - /*! Calc cursor position from graphics position - * \param point from where the cursor position should be calculated - * \return Cursor postioin - */ - qint64 cursorPosition(QPoint point); - - /*! Ensure the cursor to be visble - */ - void ensureVisible(); - - /*! Find first occurence of ba in QHexEdit data - * \param ba Data to find - * \param from Point where the search starts - * \return pos if fond, else -1 - */ - qint64 indexOf(const QByteArray &ba, qint64 from); - - /*! Returns if any changes where done on document - * \return true when document is modified else false - */ - bool isModified(); - - /*! Find last occurence of ba in QHexEdit data - * \param ba Data to find - * \param from Point where the search starts - * \return pos if fond, else -1 - */ - qint64 lastIndexOf(const QByteArray &ba, qint64 from); - - /*! Gives back a formatted image of the selected content of QHexEdit - */ - QString selectionToReadableString(); - - /*! Set Font of QHexEdit - * \param font - */ - virtual void setFont(const QFont &font); - - /*! Gives back a formatted image of the content of QHexEdit - */ - QString toReadableString(); - - -public slots: - /*! Redoes the last operation. If there is no operation to redo, i.e. - there is no redo step in the undo/redo history, nothing happens. - */ - void redo(); - - /*! Undoes the last operation. If there is no operation to undo, i.e. - there is no undo step in the undo/redo history, nothing happens. - */ - void undo(); - -signals: - - /*! Contains the address, where the cursor is located. */ - void currentAddressChanged(qint64 address); - - /*! Contains the size of the data to edit. */ - void currentSizeChanged(qint64 size); - - /*! The signal is emitted every time, the data is changed. */ - void dataChanged(); - - /*! The signal is emitted every time, the overwrite mode is changed. */ - void overwriteModeChanged(bool state); - - -/*! \cond docNever */ -public: - ~QHexEdit(); - - // Properties - bool addressArea(); - void setAddressArea(bool addressArea); - - QColor addressAreaColor(); - void setAddressAreaColor(const QColor &color); - - qint64 addressOffset(); - void setAddressOffset(qint64 addressArea); - - int addressWidth(); - void setAddressWidth(int addressWidth); - - bool asciiArea(); - void setAsciiArea(bool asciiArea); - - qint64 cursorPosition(); - void setCursorPosition(qint64 position); - - QByteArray data(); - void setData(const QByteArray &ba); - - bool highlighting(); - void setHighlighting(bool mode); - - QColor highlightingColor(); - void setHighlightingColor(const QColor &color); - - bool overwriteMode(); - void setOverwriteMode(bool overwriteMode); - - bool isReadOnly(); - void setReadOnly(bool readOnly); - - bool isUpperCase(); - void setUpperCase(bool upperCase); - - QColor selectionColor(); - void setSelectionColor(const QColor &color); - -protected: - // Handle events - void keyPressEvent(QKeyEvent *event); - void mouseMoveEvent(QMouseEvent * event); - void mousePressEvent(QMouseEvent * event); - void paintEvent(QPaintEvent *event); - void resizeEvent(QResizeEvent *); - -private: - // Handle selections - void resetSelection(qint64 pos); // set selectionStart and selectionEnd to pos - void resetSelection(); // set selectionEnd to selectionStart - void setSelection(qint64 pos); // set min (if below init) or max (if greater init) - int getSelectionBegin(); - int getSelectionEnd(); - - // Private utility functions - void init(); - void readBuffers(); - QString toReadable(const QByteArray &ba); - -private slots: - void adjust(); // recalc pixel positions - void dataChangedPrivate(int idx=0); // emit dataChanged() signal - void refresh(); // ensureVisible() and readBuffers() - void updateCursor(); // update blinking cursor - -private: - // Name convention: pixel positions start with _px - int _pxCharWidth, _pxCharHeight; // char dimensions (dpendend on font) - int _pxPosHexX; // X-Pos of HeaxArea - int _pxPosAdrX; // X-Pos of Address Area - int _pxPosAsciiX; // X-Pos of Ascii Area - int _pxGapAdr; // gap left from AddressArea - int _pxGapAdrHex; // gap between AddressArea and HexAerea - int _pxGapHexAscii; // gap between HexArea and AsciiArea - int _pxCursorWidth; // cursor width - int _pxSelectionSub; // offset selection rect - int _pxCursorX; // current cursor pos - int _pxCursorY; // current cursor pos - - // Name convention: absolute byte positions in chunks start with _b - qint64 _bSelectionBegin; // first position of Selection - qint64 _bSelectionEnd; // end of Selection - qint64 _bSelectionInit; // memory position of Selection - qint64 _bPosFirst; // position of first byte shown - qint64 _bPosLast; // position of last byte shown - qint64 _bPosCurrent; // current position - - // variables to store the property values - bool _addressArea; // left area of QHexEdit - QColor _addressAreaColor; - int _addressWidth; - bool _asciiArea; - qint64 _addressOffset; - bool _highlighting; - bool _overwriteMode; - QBrush _brushSelection; - QPen _penSelection; - QBrush _brushHighlighted; - QPen _penHighlighted; - bool _readOnly; - bool _upperCase; - - // other variables - int _addrDigits; // real no of addressdigits, may be > addressWidth - bool _blink; // help get cursor blinking - QBuffer _bData; // buffer, when setup with QByteArray - Chunks *_chunks; // IODevice based access to data - QTimer _cursorTimer; // for blinking cursor - qint64 _cursorPosition; // absolute positioin of cursor, 1 Byte == 2 tics - QRect _cursorRect; // physical dimensions of cursor - QByteArray _data; // QHexEdit's data, when setup with QByteArray - QByteArray _dataShown; // data in the current View - QByteArray _hexDataShown; // data in view, transformed to hex - qint64 _lastEventSize; // size, which was emitted last time - QByteArray _markedShown; // marked data in view - bool _modified; // Is any data in editor modified? - int _rowsShown; // lines of text shown - UndoStack * _undoStack; // Stack to store edit actions for undo/redo - /*! \endcond docNever */ -}; - -#endif // QHEXEDIT_H diff --git a/sonar-project.properties b/sonar-project.properties new file mode 100644 index 0000000..13934f3 --- /dev/null +++ b/sonar-project.properties @@ -0,0 +1,2 @@ +sonar.projectKey=LongSoft_UEFITool +sonar.organization=longsoft \ No newline at end of file diff --git a/version.h b/version.h new file mode 100644 index 0000000..3829888 --- /dev/null +++ b/version.h @@ -0,0 +1,19 @@ +/* version.h + +Copyright (c) 2019, Nikolaj Schlej. All rights reserved. +This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +*/ + +#ifndef VERSION_H +#define VERSION_H + +#define PROGRAM_VERSION "NE alpha 71" " (" __DATE__ ")" + +#endif // VERSION_H